diff options
Diffstat (limited to 'src')
159 files changed, 12826 insertions, 7114 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 40787fa17d0..be1fefa8db3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,17 +9,17 @@  #  # 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 +# 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 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  ## Process this file with automake to produce Makefile.in  ## Sub-directories to parse -SUBDIRS = framework shared trinityrealm game bindings trinitycore +SUBDIRS = tools framework shared realmd game bindings mangosd  ## Additional files to include when running 'make dist'  #  Nothing yet. diff --git a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp index 73c3f6121db..f26209d4340 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/boss_illidan.cpp @@ -137,6 +137,9 @@ EndScriptData */  #define FLAME_ENRAGE_DISTANCE   30  #define FLAME_CHARGE_DISTANCE   50 +#define ITEM_ID_MAIN_HAND   32837 +#define ITEM_ID_OFF_HAND    32838 +  /**** Creature Summon and Recognition IDs ****/  enum CreatureEntry  { @@ -454,7 +457,7 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI          {              GameObject* Door = GameObject::GetGameObject((*m_creature), pInstance->GetData64(i));              if(Door) -                Door->SetUInt32Value(GAMEOBJECT_STATE, 0); // Open Doors +                Door->SetGoState(0); // Open Doors          }      } @@ -487,10 +490,10 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI      {          if(spell->Id == SPELL_GLAIVE_RETURNS) // Re-equip our warblades!          { -            if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY)) -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); +            if(!m_creature->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID)) +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479);              else -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);              m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );          }      } @@ -567,8 +570,8 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI              Timer[EVENT_FLIGHT_SEQUENCE] = 700;              break;          case 4://throw another -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);              {                  uint8 i=0;                  Creature* Glaive = m_creature->SummonCreature(BLADE_OF_AZZINOTH, GlaivePosition[i].x, GlaivePosition[i].y, GlaivePosition[i].z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); @@ -653,14 +656,14 @@ struct TRINITY_DLL_DECL boss_illidan_stormrageAI : public ScriptedAI          if(DemonTransformation[TransformCount].equip)          { -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Requip warglaives if needed -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Requip warglaives if needed +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);              m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );          }          else          { -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); // Unequip warglaives if needed -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+0, 0); // Unequip warglaives if needed +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);          }          switch(TransformCount) @@ -1006,10 +1009,10 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI              DoorGUID[1] = pInstance->GetData64(DATA_GAMEOBJECT_ILLIDAN_DOOR_L);              if(GETGO(Gate, GateGUID)) -                Gate->SetUInt32Value(GAMEOBJECT_STATE, 1); +                Gate->SetGoState(1);              for(uint8 i = 0; i < 2; i++)                  if(GETGO(Door, DoorGUID[i])) -                    Door->SetUInt32Value(GAMEOBJECT_STATE, 1); +                    Door->SetGoState(1);          }          else          { @@ -1079,7 +1082,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI          for(uint8 i = 0; i < 2; i++)              if(GETGO(Door, DoorGUID[i])) -                Door->SetUInt32Value(GAMEOBJECT_STATE, 1); +                Door->SetGoState(1);          if(GETCRE(Illidan, IllidanGUID))          { @@ -1245,7 +1248,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI              Spirit[0]->InterruptNonMeleeSpells(true);              Spirit[1]->InterruptNonMeleeSpells(true);              if(GETGO(Gate, GateGUID)) -                Gate->SetUInt32Value(GAMEOBJECT_STATE, 0); +                Gate->SetGoState(0);              Timer = 2000;              break;          case 4: @@ -1276,7 +1279,7 @@ struct TRINITY_DLL_DECL npc_akama_illidanAI : public ScriptedAI          case 6:              for(uint8 i = 0; i < 2; i++)                  if(GETGO(Door, DoorGUID[i])) -                    Door->SetUInt32Value(GAMEOBJECT_STATE, 0); +                    Door->SetGoState(0);              break;          case 8:              if(Phase == PHASE_WALK) @@ -1386,9 +1389,9 @@ struct TRINITY_DLL_DECL boss_maievAI : public ScriptedAI          Timer[EVENT_MAIEV_STEALTH] = 0;          Timer[EVENT_MAIEV_TAUNT] = 22000 + rand()%21 * 1000;          Timer[EVENT_MAIEV_SHADOW_STRIKE] = 30000; -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 44850); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 2, 45738); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 44850); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, 45738);      }      void Aggro(Unit *who) {} @@ -1674,7 +1677,7 @@ bool GOHello_cage_trap(Player* plr, GameObject* go)      cell_lock->Visit(cell_lock, cSearcher, *(plr->GetMap()));      ((cage_trap_triggerAI*)trigger->AI())->Active = true; -    go->SetUInt32Value(GAMEOBJECT_STATE, 0); +    go->SetGoState(0);      return true;  } @@ -1859,8 +1862,8 @@ void boss_illidan_stormrageAI::Reset()      m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2);      m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);      m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); -    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); +    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); +    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);      m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING + MOVEMENTFLAG_ONTRANSPORT);      m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true); @@ -1907,8 +1910,8 @@ void boss_illidan_stormrageAI::HandleTalkSequence()          m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);          break;      case 8: -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 45479); // Equip our warglaives! -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 45481); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 45479); // Equip our warglaives! +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 45481);          m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );          m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE);          break; diff --git a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp index 645a70df9f5..30a74c2da15 100644 --- a/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp +++ b/src/bindings/scripts/scripts/zone/black_temple/instance_black_temple.cpp @@ -118,13 +118,13 @@ struct TRINITY_DLL_DECL instance_black_temple : public ScriptedInstance      void OpenDoor(uint64 DoorGUID, bool open)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); +            Door->SetGoState(open ? 0 : 1);      }      void CloseDoor(uint64 DoorGUID, bool close)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, close ? 1 : 0); +            Door->SetGoState(close ? 1 : 0);      }      void OnCreatureCreate(Creature *creature, uint32 creature_entry) diff --git a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp index 301301c27c2..aa89d902573 100644 --- a/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp +++ b/src/bindings/scripts/scripts/zone/blackrock_depths/instance_blackrock_depths.cpp @@ -88,13 +88,13 @@ struct TRINITY_DLL_DECL instance_blackrock_depths : public ScriptedInstance  	void OpenGO(uint64 DoorGUID, bool open)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); +            Door->SetGoState(open ? 0 : 1);      }      void CloseGO(uint64 DoorGUID, bool close)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, close ? 1 : 0); +            Door->SetGoState(close ? 1 : 0);      }  	uint32 GetData(uint32 type) @@ -145,13 +145,13 @@ struct TRINITY_DLL_DECL instance_blackrock_depths : public ScriptedInstance  	{  		switch(go->GetEntry())  		{ -		case 170561: SupplyRoomGate = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break;  -		case 170562: GateDughal = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE);	break; -		case 170566: GateTobias = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE);	break; -		case 170567: GateCrest = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; -		case 170568: GateJaz = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; -		case 170569: GateShill = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; -		case 166872: SupplyCrate = go->GetGUID(); state = go->GetUInt32Value(GAMEOBJECT_STATE); break; +		case 170561: SupplyRoomGate = go->GetGUID(); state = go->GetGoState(); break;  +		case 170562: GateDughal = go->GetGUID(); state = go->GetGoState();	break; +		case 170566: GateTobias = go->GetGUID(); state = go->GetGoState();	break; +		case 170567: GateCrest = go->GetGUID(); state = go->GetGoState(); break; +		case 170568: GateJaz = go->GetGUID(); state = go->GetGoState(); break; +		case 170569: GateShill = go->GetGUID(); state = go->GetGoState(); break; +		case 166872: SupplyCrate = go->GetGUID(); state = go->GetGoState(); break;  		}  	} diff --git a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp index e442d067bc4..401651ae221 100644 --- a/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp +++ b/src/bindings/scripts/scripts/zone/caverns_of_time/old_hillsbrad/old_hillsbrad.cpp @@ -235,12 +235,12 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI              case 9:                  DoScriptText(SAY_TH_ARMORY, m_creature);  				m_creature->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, THRALL_WEAPON_MODEL); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, THRALL_SHIELD_MODEL); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, THRALL_WEAPON_MODEL); +                //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, THRALL_WEAPON_INFO); +                //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 781); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, THRALL_SHIELD_MODEL); +                //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, THRALL_SHIELD_INFO); +                //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 1038);                  break;              case 10:                  m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_EQUIPPED); @@ -399,12 +399,8 @@ struct TRINITY_DLL_DECL npc_thrall_old_hillsbradAI : public npc_escortAI          {              DoUnmount();              HadMount = false; -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+1, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+3, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);              m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, THRALL_MODEL_UNEQUIPPED);          }          if( IsBeingEscorted ) diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp index ffa9094b439..833bb03bce2 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/boss_leotheras_the_blind.cpp @@ -198,8 +198,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI  		m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);  		m_creature->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);  		m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_NIGHTELF); -		m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); +		m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID  , 0); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);  		m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);  		m_creature->SetCorpseDelay(1000*60*60);  		if(pInstance) @@ -305,8 +305,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI              m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);  			// and removing weapons -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID  , 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);  		}  	} @@ -469,8 +469,8 @@ struct TRINITY_DLL_DECL boss_leotheras_the_blindAI : public ScriptedAI  					m_creature->RemoveAurasDueToSpell(SPELL_WHIRLWIND,0);  					m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID, MODEL_DEMON);  					DoScriptText(SAY_SWITCH_TO_DEMON, m_creature); -					m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY  , 0); -				    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); +					m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID  , 0); +				    m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);  					DemonForm = true;  					NeedThreatReset = true;                      SwitchToDemon_Timer = 45000; diff --git a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp index aaf6abdd3b0..4e7f3d1989c 100644 --- a/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp +++ b/src/bindings/scripts/scripts/zone/coilfang_resevoir/serpent_shrine/instance_serpent_shrine.cpp @@ -137,7 +137,7 @@ struct TRINITY_DLL_DECL instance_serpentshrine_cavern : public ScriptedInstance  	void OpenDoor(uint64 DoorGUID, bool open)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); +            Door->SetGoState(open ? 0 : 1);      }      void OnCreatureCreate(Creature *creature, uint32 creature_entry) diff --git a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp index 23d65ce42f7..df7ea54efb0 100644 --- a/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp +++ b/src/bindings/scripts/scripts/zone/deadmines/deadmines.cpp @@ -120,13 +120,13 @@ struct TRINITY_DLL_DECL instance_deadmines : public ScriptedInstance      void ShootCannon()      { -        DefiasCannon->SetUInt32Value(GAMEOBJECT_STATE, 0); +        DefiasCannon->SetGoState(0);          DoPlaySound(DefiasCannon, SOUND_CANNONFIRE);      }      void BlastOutDoor()      { -        IronCladDoor->SetUInt32Value(GAMEOBJECT_STATE, 2); +        IronCladDoor->SetGoState(2);          DoPlaySound(IronCladDoor, SOUND_DESTROYDOOR);      } diff --git a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp index cf1ff7c1eeb..d31df82df58 100644 --- a/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp +++ b/src/bindings/scripts/scripts/zone/gruuls_lair/boss_high_king_maulgar.cpp @@ -238,8 +238,8 @@ struct TRINITY_DLL_DECL boss_high_king_maulgarAI : public ScriptedAI  			DoScriptText(SAY_ENRAGE, m_creature);  			m_creature->CastSpell(m_creature, SPELL_DUAL_WIELD, true);			 -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0);                 +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0);                          }          if(Phase2) diff --git a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp index f20ad6c69a5..08ee10967a1 100644 --- a/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp +++ b/src/bindings/scripts/scripts/zone/karazhan/boss_prince_malchezaar.cpp @@ -289,11 +289,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI      void ClearWeapons()      { -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); +        //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 0); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, 0); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, 0); +        //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, 0);          //damage          const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); @@ -433,11 +433,11 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI                  m_creature->CastSpell(m_creature, SPELL_THRASH_AURA, true);                  //models -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL); +                //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY+1, AXE_EQUIP_MODEL); -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID+1, AXE_EQUIP_MODEL); +                //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO+2, AXE_EQUIP_INFO);                  //damage                  const CreatureInfo *cinfo = m_creature->GetCreatureInfo(); @@ -475,8 +475,8 @@ struct TRINITY_DLL_DECL boss_malchezaarAI : public ScriptedAI                      Creature *axe = m_creature->SummonCreature(MALCHEZARS_AXE, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 1000);                      if(axe)                      { -                        axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, AXE_EQUIP_MODEL); -                        axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO); +                        axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, AXE_EQUIP_MODEL); +                        //axe->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, AXE_EQUIP_INFO);                          axe->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                          axe->setFaction(m_creature->getFaction()); diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp index f66e20ed5cd..d546c5b2d6f 100644 --- a/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp +++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/boss_headless_horseman.cpp @@ -736,7 +736,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI  		sprouted = false;  		DoCast(m_creature,SPELL_PUMPKIN_AURA,true);  		DoCast(m_creature,SPELL_SPROUTING); -		m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE); +		m_creature->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED);  	}  	void Aggro(Unit *who){} @@ -747,7 +747,7 @@ struct TRINITY_DLL_DECL mob_pulsing_pumpkinAI : public ScriptedAI  		{  			sprouted = true;  			m_creature->RemoveAllAuras(); -			m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISABLE_ROTATE); +			m_creature->RemoveFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_STUNNED);  			DoCast(m_creature,SPELL_SPROUT_BODY,true);  			m_creature->UpdateEntry(PUMPKIN_FIEND);  			DoStartMovement(m_creature->getVictim()); diff --git a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp index 86051831fb5..0db9f283374 100644 --- a/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp +++ b/src/bindings/scripts/scripts/zone/scarlet_monastery/instance_scarlet_monastery.cpp @@ -92,7 +92,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance  			{  			GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);  			if(Shrine) -				Shrine->SetUInt32Value(GAMEOBJECT_STATE,1); +				Shrine->SetGoState(1);  			}break;  		case DATA_HORSEMAN_EVENT:  			if (data == DONE) @@ -106,7 +106,7 @@ struct TRINITY_DLL_DECL instance_scarlet_monastery : public ScriptedInstance  				HorsemanAdds.clear();  				GameObject *Shrine = instance->GetGameObjectInMap(PumpkinShrineGUID);  				if(Shrine) -					Shrine->SetUInt32Value(GAMEOBJECT_STATE,1); +					Shrine->SetGoState(1);  			}  			break;          } diff --git a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp index e9454d713ed..61aca9df2e3 100644 --- a/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp +++ b/src/bindings/scripts/scripts/zone/shadowfang_keep/instance_shadowfang_keep.cpp @@ -59,7 +59,7 @@ struct TRINITY_DLL_DECL instance_shadowfang_keep : public ScriptedInstance  	void OpenDoor(uint64 DoorGUID, bool open)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); +            Door->SetGoState(open ? 0 : 1);      }      void SetData(uint32 type, uint32 data) diff --git a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp index c564088be76..ca231a6bd12 100644 --- a/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp +++ b/src/bindings/scripts/scripts/zone/uldaman/instance_uldaman.cpp @@ -70,7 +70,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance              break;              case ANCIENT_VAULT_DOOR:          -                go->SetUInt32Value(GAMEOBJECT_STATE,1); +                go->SetGoState(1);                  go->SetUInt32Value(GAMEOBJECT_FLAGS, 33);                  ancientVaultDoor = go->GetGUID();              break; @@ -93,7 +93,7 @@ struct TRINITY_DLL_DECL instance_uldaman : public ScriptedInstance              return;          go->SetUInt32Value(GAMEOBJECT_FLAGS, 33); -        go->SetUInt32Value(GAMEOBJECT_STATE, 0); +        go->SetGoState(0);      }      void ActivateStoneKeepers() diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp index 82a993c3894..4c56d230263 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_hexlord.cpp @@ -237,8 +237,7 @@ struct TRINITY_DLL_DECL boss_hex_lord_malacrassAI : public ScriptedAI          SpawnAdds(); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 46916); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 50268674); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916);          m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE );      } diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp index 844e4a6c0ce..3ebb0931d4d 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp @@ -149,7 +149,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI          TankGUID = 0;          inBearForm = false; -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);      }      void SendAttacker(Unit* target) @@ -388,7 +388,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI          {              if(inBearForm)              { -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 5122); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122);                  DoYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, NULL);                  DoPlaySoundToSet(m_creature, SOUND_YELL_TOTROLL);                  m_creature->RemoveAurasDueToSpell(SPELL_BEARFORM); @@ -400,7 +400,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI              }              else              { -                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + 1, 0); +                m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0);                  DoYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, NULL);                  DoPlaySoundToSet(m_creature, SOUND_YELL_TOBEAR);                  DoCast(m_creature, SPELL_BEARFORM, true); diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp index 2c50875e4ad..3ace2e79e22 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_zuljin.cpp @@ -207,9 +207,9 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI          Summons.DespawnAll(); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 47174); -        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674); -        m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); +        m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 47174); +        //m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674); +        //m_creature->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);      }      void Aggro(Unit *who) @@ -341,7 +341,7 @@ struct TRINITY_DLL_DECL boss_zuljinAI : public ScriptedAI              m_creature->Relocate(CENTER_X, CENTER_Y, CENTER_Z,0);              m_creature->SendMonsterMove(CENTER_X, CENTER_Y, CENTER_Z,0,0,100);              DoResetThreat(); -            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); +            m_creature->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0);              m_creature->RemoveAurasDueToSpell(Transform[Phase].unaura);              DoCast(m_creature, Transform[Phase].spell);              DoYell(Transform[Phase].text, LANG_UNIVERSAL, NULL); diff --git a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp index 95e62063e26..b510f74bb67 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/instance_zulaman.cpp @@ -140,7 +140,7 @@ struct TRINITY_DLL_DECL instance_zulaman : public ScriptedInstance      void OpenDoor(uint64 DoorGUID, bool open)      {          if(GameObject *Door = instance->GetGameObjectInMap(DoorGUID)) -            Door->SetUInt32Value(GAMEOBJECT_STATE, open ? 0 : 1); +            Door->SetGoState(open ? 0 : 1);      }      void SummonHostage(uint8 num) diff --git a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp index f79247bbfc0..8b993815c00 100644 --- a/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp +++ b/src/bindings/scripts/scripts/zone/zulgurub/boss_renataki.cpp @@ -65,9 +65,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI          if (Invisible_Timer < diff)          {              m_creature->InterruptSpell(CURRENT_GENERIC_SPELL); -            m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 0); -            m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); -            m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO  + 1, 3); +            m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 0); +            //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); +            //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO  + 1, 3);              m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);              m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,11686);              Invisible = true; @@ -100,9 +100,9 @@ struct TRINITY_DLL_DECL boss_renatakiAI : public ScriptedAI                  m_creature->InterruptSpell(CURRENT_GENERIC_SPELL);                  m_creature->SetUInt32Value(UNIT_FIELD_DISPLAYID,15268);                  m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); -                m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, 31818); -                m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); -                m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO  + 1, 3); +                m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_ID, 31818); +                //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO , 218171138); +                //m_creature->SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO  + 1, 3);                  m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);                  Invisible = false; diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp new file mode 100644 index 00000000000..e4e26dec111 --- /dev/null +++ b/src/game/AchievementMgr.cpp @@ -0,0 +1,910 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 "AchievementMgr.h" +#include "Common.h" +#include "Player.h" +#include "WorldPacket.h" +#include "Database/DBCEnums.h" +#include "ObjectMgr.h" +#include "Guild.h" +#include "Database/DatabaseEnv.h" +#include "GameEvent.h" +#include "World.h" +#include "SpellMgr.h" + +const CriteriaCastSpellRequirement AchievementMgr::criteriaCastSpellRequirements[CRITERIA_CAST_SPELL_REQ_COUNT] = +    { +        {5272, 3057, 0, 0}, +        {5273, 2784, 0, 0}, +        {5752, 9099, 0, 0}, +        {5753, 8403, 0, 0}, +        {5772, 0, 0, RACE_GNOME}, +        {5774, 0, 0, RACE_BLOODELF}, +        {5775, 0, 0, RACE_DRAENEI}, +        {5776, 0, 0, RACE_DWARF}, +        {5777, 0, 0, RACE_HUMAN}, +        {5778, 0, 0, RACE_NIGHTELF}, +        {5779, 0, 0, RACE_ORC}, +        {5780, 0, 0, RACE_TAUREN}, +        {5781, 0, 0, RACE_TROLL}, +        {5782, 0, 0, RACE_UNDEAD_PLAYER}, +        {6225, 5661, 0, 0}, +        {6226, 26044, 0, 0}, +        {6228, 739, 0, 0}, +        {6229, 927, 0, 0}, +        {6230, 1444, 0, 0}, +        {6231, 8140, 0, 0}, +        {6232, 5489, 0, 0}, +        {6233,12336, 0, 0}, +        {6234, 1351, 0, 0}, +        {6235, 5484, 0, 0}, +        {6236, 1182, 0, 0}, +        {6237, 0, CLASS_DEATH_KNIGHT, RACE_ORC}, +        {6238, 0, CLASS_WARRIOR, RACE_HUMAN}, +        {6239, 0, CLASS_SHAMAN, RACE_TAUREN}, +        {6240, 0, CLASS_DRUID, RACE_NIGHTELF}, +        {6241, 0, CLASS_ROGUE, RACE_UNDEAD_PLAYER}, +        {6242, 0, CLASS_HUNTER, RACE_TROLL}, +        {6243, 0, CLASS_MAGE, RACE_GNOME}, +        {6244, 0, CLASS_PALADIN, RACE_DWARF}, +        {6245, 0, CLASS_WARLOCK, RACE_BLOODELF}, +        {6246, 0, CLASS_PRIEST, RACE_DRAENEI}, +        {6312, 0, CLASS_WARLOCK, RACE_GNOME}, +        {6313, 0, CLASS_DEATH_KNIGHT, RACE_HUMAN}, +        {6314, 0, CLASS_PRIEST, RACE_NIGHTELF}, +        {6315, 0, CLASS_SHAMAN, RACE_ORC}, +        {6316, 0, CLASS_DRUID, RACE_TAUREN}, +        {6317, 0, CLASS_ROGUE, RACE_TROLL}, +        {6318, 0, CLASS_WARRIOR, RACE_UNDEAD_PLAYER}, +        {6319, 0, CLASS_MAGE, RACE_BLOODELF}, +        {6320, 0, CLASS_PALADIN, RACE_DRAENEI}, +        {6321, 0, CLASS_HUNTER, RACE_DWARF}, +        {6662, 31261, 0, 0} +        }; + +const AchievementReward AchievementMgr::achievementRewards[ACHIEVEMENT_REWARD_COUNT] = +    { +        // achievementId, horde titleid, alliance titleid, itemid  +        {45, 0, 0, 43348}, +        {46, 78, 78, 0}, +        {230, 72, 72, 0}, +        {456, 139, 139, 0}, +        {614, 0, 0, 44223}, +        {619, 0, 0, 44224}, +        {714, 47, 47, 0}, +        {762, 130, 130, 0}, +        {870, 127, 126, 0}, +        {871, 144, 144, 0}, +        {876, 0, 0, 43349}, +        {907, 48, 48, 0}, +        {913, 74, 74, 0}, +        {942, 79, 79, 0}, +        {943, 79, 79, 0}, +        {945, 131, 131, 0}, +        {948, 130, 130, 0}, +        {953, 132, 132, 0}, +        {978, 81, 81, 0}, +        {1015, 77, 77, 0}, +        {1021, 0, 0, 40643}, +        {1038, 75, 75, 0}, +        {1039, 76, 76, 0}, +        {1163, 128, 128, 0}, +        {1174, 82, 82, 0}, +        {1175, 72, 72, 0}, +        {1250, 0, 0, 40653}, +        {1400, 120, 120, 0}, +        {1402, 122, 122, 0}, +        {1516, 83, 83, 0}, +        {1563, 84, 84, 0}, +        {1656, 124, 124, 0}, +        {1657, 124, 124, 0}, +        {1658, 129, 129, 0}, +        {1681, 125, 125, 43300}, +        {1682, 125, 125, 43300}, +        {1683, 133, 133, 0}, +        {1684, 133, 133, 0}, +        {1691, 134, 134, 0}, +        {1692, 134, 134, 0}, +        {1693, 135, 135, 0}, +        {1707, 135, 135, 0}, +        {1784, 84, 84, 0}, +        {1793, 137, 137, 0}, +        {1956, 0, 0, 43824}, +        {2051, 140, 140, 0}, +        {2054, 121, 121, 0}, +        {2096, 0, 0, 44430}, +        {2136, 0, 0, 0},// <- TODO: find item for spell 59961 +        {2137, 0, 0, 0},// <- TODO: find item for spell 60021 +        {2138, 0, 0, 0},// <- TODO: find item for spell 59976 +        {2143, 0, 0, 44178}, +        {2144, 0, 0, 0},// <- TODO: find item for spell 60024 +        {2145, 0, 0, 0},// <- TODO: find item for spell 60024 +        {2186, 141, 141, 0}, +        {2187, 142, 142, 0}, +        {2188, 143, 143, 0} +    }; + +AchievementMgr::AchievementMgr(Player *player) +{ +    m_player = player; +} + +AchievementMgr::~AchievementMgr() +{ +} + +void AchievementMgr::SaveToDB() +{ +    if(!m_completedAchievements.empty()) +    { +        bool need_execute = false; +        std::ostringstream ssdel; +        std::ostringstream ssins; +        for(CompletedAchievementMap::iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); iter++) +        { +            if(!iter->second.changed) +                continue; + +            /// first new/changed record prefix +            if(!need_execute) +            { +                ssdel << "DELETE FROM character_achievement WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND achievement IN ("; +                ssins << "INSERT INTO character_achievement (guid, achievement, date) VALUES "; +                need_execute = true; +            } +            /// next new/changed record prefix +            else +            { +                ssdel << ", "; +                ssins << ", "; +            } + +            // new/changed record data +            ssdel << iter->first; +            ssins << "("<<GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << uint64(iter->second.date) << ")"; + +            /// mark as saved in db +            iter->second.changed = false; +        } + +        if(need_execute) +            ssdel << ")"; + +        if(need_execute) +        { +            CharacterDatabase.BeginTransaction (); +            CharacterDatabase.Execute( ssdel.str().c_str() ); +            CharacterDatabase.Execute( ssins.str().c_str() ); +            CharacterDatabase.CommitTransaction (); +        } +    } + +    if(!m_criteriaProgress.empty()) +    { +        /// prepare deleting and insert +        bool need_execute = false; +        std::ostringstream ssdel; +        std::ostringstream ssins; +        for(CriteriaProgressMap::iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) +        { +            if(!iter->second.changed) +                continue; + +            /// first new/changed record prefix +            if(!need_execute) +            { +                ssdel << "DELETE FROM character_achievement_progress WHERE guid = " << GetPlayer()->GetGUIDLow() << " AND criteria IN ("; +                ssins << "INSERT INTO character_achievement_progress (guid, criteria, counter, date) VALUES "; +                need_execute = true; +            } +            /// next new/changed record prefix +            else +            { +                ssdel << ", "; +                ssins << ", "; +            } + +            // new/changed record data +            ssdel << iter->first; +            ssins << "(" << GetPlayer()->GetGUIDLow() << ", " << iter->first << ", " << iter->second.counter << ", " << iter->second.date << ")"; + +            /// mark as saved in db +            iter->second.changed = false; +        } + +        if(need_execute) +            ssdel << ")"; + +        if(need_execute) +        { +            CharacterDatabase.BeginTransaction (); +            CharacterDatabase.Execute( ssdel.str().c_str() ); +            CharacterDatabase.Execute( ssins.str().c_str() ); +            CharacterDatabase.CommitTransaction (); +        } +    } +} + +void AchievementMgr::LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult) +{ +    if(achievementResult) +    { +        do +        { +            Field *fields = achievementResult->Fetch(); +            CompletedAchievementData& ca = m_completedAchievements[fields[0].GetUInt32()]; +            ca.date = time_t(fields[1].GetUInt64()); +            ca.changed = false; +        } while(achievementResult->NextRow()); +        delete achievementResult; +    } + +    if(criteriaResult) +    { +        do +        { +            Field *fields = criteriaResult->Fetch(); + +            uint32 id      = fields[0].GetUInt32(); +            uint32 counter = fields[1].GetUInt32(); +            time_t date    = time_t(fields[2].GetUInt64()); + +            AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(id); +            if(!criteria || criteria->timeLimit && date + criteria->timeLimit < time(NULL)) +                continue; + +            CriteriaProgress& progress = m_criteriaProgress[id]; +            progress.counter = counter; +            progress.date    = date; +            progress.changed = false; +        } while(criteriaResult->NextRow()); +        delete criteriaResult; +    } + +} + +void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) +{ +    sLog.outString("AchievementMgr::SendAchievementEarned(%u)", achievement->ID); + +    const char *msg = "|Hplayer:$N|h[$N]|h has earned the achievement $a!"; +    if(Guild* guild = objmgr.GetGuildById(GetPlayer()->GetGuildId())) +    { +        WorldPacket data(SMSG_MESSAGECHAT, 200); +        data << uint8(CHAT_MSG_ACHIEVEMENT); +        data << uint8(CHAT_MSG_GUILD_ACHIEVEMENT); +        data << uint32(LANG_UNIVERSAL); +        data << uint64(GetPlayer()->GetGUID()); +        data << uint32(5); +        data << uint64(GetPlayer()->GetGUID()); +        data << uint32(strlen(msg)+1); +        data << msg; +        data << uint8(0); +        data << uint32(achievement->ID); +        guild->BroadcastPacket(&data); +    } +    if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_KILL|ACHIEVEMENT_FLAG_REALM_FIRST_REACH)) +    { +        // broadcast realm first reached +        WorldPacket data(SMSG_SERVER_FIRST_ACHIEVEMENT, strlen(GetPlayer()->GetName())+1+8+4+4); +        data << GetPlayer()->GetName(); +        data << uint64(GetPlayer()->GetGUID()); +        data << uint32(achievement->ID); +        data << uint32(0);  // 1=link supplied string as player name, 0=display plain string +        sWorld.SendGlobalMessage(&data); +    } +    else +    { +        WorldPacket data(SMSG_MESSAGECHAT, 200); +        data << uint8(CHAT_MSG_ACHIEVEMENT); +        data << uint32(LANG_UNIVERSAL); +        data << uint64(GetPlayer()->GetGUID()); +        data << uint32(5); +        data << uint64(GetPlayer()->GetGUID()); +        data << uint32(strlen(msg)+1); +        data << msg; +        data << uint8(0); +        data << uint32(achievement->ID); +        GetPlayer()->SendMessageToSet(&data, true); + +    } +    WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); +    data.append(GetPlayer()->GetPackGUID()); +    data << uint32(achievement->ID); +    data << uint32(secsToTimeBitFields(time(NULL))); +    data << uint32(0); +    GetPlayer()->SendMessageToSet(&data, true); +} + +void AchievementMgr::SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress) +{ +    WorldPacket data(SMSG_CRITERIA_UPDATE, 8+4+8); +    data << uint32(id); + +    // the counter is packed like a packed Guid +    data.appendPackGUID(progress->counter); + +    data.append(GetPlayer()->GetPackGUID()); +    data << uint32(0); +    data << uint32(secsToTimeBitFields(progress->date)); +    data << uint32(0);  // timer 1 +    data << uint32(0);  // timer 2 +    GetPlayer()->SendMessageToSet(&data, true); +} + +/** + * called at player login. The player might have fulfilled some achievements when the achievement system wasn't working yet + */ +void AchievementMgr::CheckAllAchievementCriteria() +{ +    // suppress sending packets +    for(uint32 i=0; i<ACHIEVEMENT_CRITERIA_TYPE_TOTAL; i++) +        UpdateAchievementCriteria(AchievementCriteriaTypes(i)); +} + +/** + * this function will be called whenever the user might have done a criteria relevant action + */ +void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1, uint32 miscvalue2, Unit *unit, uint32 time) +{ +    sLog.outString("AchievementMgr::UpdateAchievementCriteria(%u, %u, %u, %u)", type, miscvalue1, miscvalue2, time); +    AchievementCriteriaEntryList const& achievementCriteriaList = objmgr.GetAchievementCriteriaByType(type); +    for(AchievementCriteriaEntryList::const_iterator i = achievementCriteriaList.begin(); i!=achievementCriteriaList.end(); ++i) +    { +        AchievementCriteriaEntry const *achievementCriteria = (*i); + +        // don't update already completed criteria +        if(IsCompletedCriteria(achievementCriteria)) +            continue; + +        if(achievementCriteria->groupFlag & ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP && GetPlayer()->GetGroup()) +            continue; + +        AchievementEntry const *achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); +        if(!achievement) +            continue; + +        if(achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_HORDE && GetPlayer()->GetTeam() != HORDE || +            achievement->factionFlag == ACHIEVEMENT_FACTION_FLAG_ALLIANCE && GetPlayer()->GetTeam() != ALLIANCE) +            continue; + +        switch (type) +        { +            case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: +                SetCriteriaProgress(achievementCriteria, GetPlayer()->getLevel()); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: +                SetCriteriaProgress(achievementCriteria, GetPlayer()->GetByteValue(PLAYER_BYTES_2, 2)+1); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                if(achievementCriteria->kill_creature.creatureID != miscvalue1) +                    continue; +                SetCriteriaProgress(achievementCriteria, miscvalue2, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: +                if(uint32 skillvalue = GetPlayer()->GetBaseSkillValue(achievementCriteria->reach_skill_level.skillID)) +                    SetCriteriaProgress(achievementCriteria, skillvalue); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: +            { +                uint32 counter =0; +                for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++) +                    if(itr->second.m_rewarded) +                        counter++; +                SetCriteriaProgress(achievementCriteria, counter); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: +            { +                uint32 counter =0; +                for(QuestStatusMap::iterator itr = GetPlayer()->getQuestStatusMap().begin(); itr!=GetPlayer()->getQuestStatusMap().end(); itr++) +                { +                    Quest const* quest = objmgr.GetQuestTemplate(itr->first); +                    if(itr->second.m_rewarded && quest->GetZoneOrSort() == achievementCriteria->complete_quests_in_zone.zoneID) +                        counter++; +                } +                SetCriteriaProgress(achievementCriteria, counter); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                SetCriteriaProgress(achievementCriteria, miscvalue1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                if(GetPlayer()->GetMapId() != achievementCriteria->complete_battleground.mapID) +                    continue; +                SetCriteriaProgress(achievementCriteria, miscvalue1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: +                if(GetPlayer()->HasSpell(achievementCriteria->learn_spell.spellID)) +                    SetCriteriaProgress(achievementCriteria, 1); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                if(GetPlayer()->GetMapId() != achievementCriteria->death_at_map.mapID) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                if(miscvalue1 != achievementCriteria->killed_by_creature.creatureEntry) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: +            { +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                if(achievement->ID == 1260) +                { +                    if(Player::GetDrunkenstateByValue(GetPlayer()->GetDrunkValue()) != DRUNKEN_SMASHED) +                        continue; +                    // TODO: hardcoding eventid is bad, it can differ from DB to DB - maye implement something using HolidayNames.dbc? +                    if(!gameeventmgr.IsActiveEvent(26)) +                        continue; +                } +                // miscvalue1 is the ingame fallheight*100 as stored in dbc +                SetCriteriaProgress(achievementCriteria, miscvalue1); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: +                if(GetPlayer()->GetQuestRewardStatus(achievementCriteria->complete_quest.questID)) +                    SetCriteriaProgress(achievementCriteria, 1); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: +                // AchievementMgr::UpdateAchievementCriteria might also be called on login - skip in this case +                if(!miscvalue1) +                    continue; +                if(achievementCriteria->use_item.itemID != miscvalue1) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: +                // speedup for non-login case +                if(miscvalue1 && achievementCriteria->own_item.itemID!=miscvalue1) +                    continue; +                SetCriteriaProgress(achievementCriteria, GetPlayer()->GetItemCount(achievementCriteria->own_item.itemID, true)); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: +                // You _have_ to loot that item, just owning it when logging in does _not_ count! +                if(!miscvalue1) +                    continue; +                if(miscvalue1 != achievementCriteria->own_item.itemID) +                    continue; +                SetCriteriaProgress(achievementCriteria, miscvalue2, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: +            case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: +                if (!miscvalue1 || miscvalue1 != achievementCriteria->be_spell_target.spellID) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: +                if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: +            { +                if (!miscvalue1 || miscvalue1 != achievementCriteria->cast_spell.spellID) +                    continue; +                // those requirements couldn't be found in the dbc + +                const CriteriaCastSpellRequirement *requirement = NULL; +                for (uint32 i=0; i<CRITERIA_CAST_SPELL_REQ_COUNT; i++) +                { +                    if (criteriaCastSpellRequirements[i].achievementCriteriaId == achievementCriteria->ID) +                    { +                        requirement = &criteriaCastSpellRequirements[i]; +                        break; +                    } +                } + +                if (requirement) +                { +                    if (!unit) +                        continue; + +                    if (requirement->creatureEntry && unit->GetEntry() != requirement->creatureEntry) +                        continue; + +                    if (requirement->playerRace && (unit->GetTypeId() != TYPEID_PLAYER || unit->getRace()!=requirement->playerRace)) +                        continue; + +                    if (requirement->playerClass && (unit->GetTypeId() != TYPEID_PLAYER || unit->getClass()!=requirement->playerClass)) +                        continue; +                } +                SetCriteriaProgress(achievementCriteria, 1, true); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: +            { +                uint32 spellCount = 0; +                for (PlayerSpellMap::const_iterator spellIter = GetPlayer()->GetSpellMap().begin(); +                        spellIter != GetPlayer()->GetSpellMap().end(); +                        spellIter++) +                { +                    for(SkillLineAbilityMap::const_iterator skillIter = spellmgr.GetBeginSkillLineAbilityMap(spellIter->first); +                            skillIter != spellmgr.GetEndSkillLineAbilityMap(spellIter->first); +                            skillIter++) +                    { +                        if(skillIter->second->skillId == achievementCriteria->learn_skilline_spell.skillLine) +                            spellCount++; +                    } +                } +                SetCriteriaProgress(achievementCriteria, spellCount); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: +            { +                // skip for login case +                if(!miscvalue1) +                    continue; +                SetCriteriaProgress(achievementCriteria, 1); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: +            { +                int32 reputation = GetPlayer()->GetReputation(achievementCriteria->gain_reputation.factionID); +                if (reputation > 0) +                    SetCriteriaProgress(achievementCriteria, reputation); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: +            { +                uint32 counter = 0; +                const FactionStateList factionStateList = GetPlayer()->GetFactionStateList(); +                for (FactionStateList::const_iterator iter = factionStateList.begin(); iter!= factionStateList.end(); iter++) +                { +                    if(GetPlayer()->ReputationToRank(iter->second.Standing) >= REP_EXALTED) +                        ++counter; +                } +                SetCriteriaProgress(achievementCriteria, counter); +                break; +            } +            case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: +            { +                WorldMapOverlayEntry const* worldOverlayEntry = sWorldMapOverlayStore.LookupEntry(achievementCriteria->explore_area.areaReference); +                if(!worldOverlayEntry) +                    break; + +                int32 exploreFlag = GetAreaFlagByAreaID(worldOverlayEntry->areatableID); +                if(exploreFlag < 0) +                    break; + +                uint32 playerIndexOffset = uint32(exploreFlag) / 32; +                uint32 mask = 1<< (uint32(exploreFlag) % 32); + +                if(GetPlayer()->GetUInt32Value(PLAYER_EXPLORED_ZONES_1 + playerIndexOffset) & mask) +                    SetCriteriaProgress(achievementCriteria, 1); +                break; +            } + +        } +        if(IsCompletedCriteria(achievementCriteria)) +            CompletedCriteria(achievementCriteria); +    } +} + +bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achievementCriteria) +{ +    AchievementEntry const* achievement = sAchievementStore.LookupEntry(achievementCriteria->referredAchievement); +    if(!achievement) +        return false; + +    // counter can never complete +    if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) +        return false; + +    if(achievement->flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) +    { +        // someone on this realm has already completed that achievement +        if(objmgr.allCompletedAchievements.find(achievement->ID)!=objmgr.allCompletedAchievements.end()) +            return false; +    } + +    CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID); +    if(itr == m_criteriaProgress.end()) +        return false; + +    CriteriaProgress const* progress = &itr->second; + +    switch(achievementCriteria->requiredType) +    { +        case ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL: +            if(achievement->ID == 467 && GetPlayer()->getClass() != CLASS_SHAMAN || +                    achievement->ID == 466 && GetPlayer()->getClass() != CLASS_DRUID || +                    achievement->ID == 465 && GetPlayer()->getClass() != CLASS_PALADIN || +                    achievement->ID == 464 && GetPlayer()->getClass() != CLASS_PRIEST || +                    achievement->ID == 463 && GetPlayer()->getClass() != CLASS_WARLOCK || +                    achievement->ID == 462 && GetPlayer()->getClass() != CLASS_HUNTER || +                    achievement->ID == 461 && GetPlayer()->getClass() != CLASS_DEATH_KNIGHT || +                    achievement->ID == 460 && GetPlayer()->getClass() != CLASS_MAGE || +                    achievement->ID == 459 && GetPlayer()->getClass() != CLASS_WARRIOR || +                    achievement->ID == 458 && GetPlayer()->getClass() != CLASS_ROGUE || + +                    achievement->ID == 1404 && GetPlayer()->getRace() != RACE_GNOME || +                    achievement->ID == 1405 && GetPlayer()->getRace() != RACE_BLOODELF || +                    achievement->ID == 1406 && GetPlayer()->getRace() != RACE_DRAENEI || +                    achievement->ID == 1407 && GetPlayer()->getRace() != RACE_DWARF || +                    achievement->ID == 1408 && GetPlayer()->getRace() != RACE_HUMAN || +                    achievement->ID == 1409 && GetPlayer()->getRace() != RACE_NIGHTELF || +                    achievement->ID == 1410 && GetPlayer()->getRace() != RACE_ORC || +                    achievement->ID == 1411 && GetPlayer()->getRace() != RACE_TAUREN || +                    achievement->ID == 1412 && GetPlayer()->getRace() != RACE_TROLL || +                    achievement->ID == 1413 && GetPlayer()->getRace() != RACE_UNDEAD_PLAYER ) +                return false; +            return progress->counter >= achievementCriteria->reach_level.level; +        case ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT: +            return progress->counter >= achievementCriteria->buy_bank_slot.numberOfSlots; +        case ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE: +            return progress->counter >= achievementCriteria->kill_creature.creatureCount; +        case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT: +            return m_completedAchievements.find(achievementCriteria->complete_achievement.linkedAchievement) != m_completedAchievements.end(); +        case ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL: +            return progress->counter >= achievementCriteria->reach_skill_level.skillLevel; +        case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: +            return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount; +        case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST: +            return progress->counter >= achievementCriteria->complete_daily_quest.questCount; +        case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL: +            return progress->counter >= 1; +        case ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING: +            return progress->counter >= achievementCriteria->fall_without_dying.fallHeight; +        case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST: +            return progress->counter >= 1; +        case ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM: +            return progress->counter >= achievementCriteria->use_item.itemCount; +        case ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM: +            return progress->counter >= achievementCriteria->own_item.itemCount; +        case ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM: +            return progress->counter >= achievementCriteria->loot_item.itemCount; +        case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET: +        case ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2: +            return progress->counter >= achievementCriteria->be_spell_target.spellCount; +        case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL: +        case ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2: +            return progress->counter >= achievementCriteria->cast_spell.castCount; +        case ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS: +            return progress->counter >= achievementCriteria->learn_skilline_spell.spellCount; +        case ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP: +            return progress->counter >= achievementCriteria->visit_barber.numberOfVisits; +        case ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION: +            return progress->counter >= achievementCriteria->gain_reputation.reputationAmount; +        case ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION: +            return progress->counter >= achievementCriteria->gain_exalted_reputation.numberOfExaltedFactions; +        case ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA: +            return progress->counter >= 1; + +        // handle all statistic-only criteria here +        case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND: +        case ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP: +        case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE: +        case ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER: +            return false; +    } +    return false; +} + +void AchievementMgr::CompletedCriteria(AchievementCriteriaEntry const* criteria) +{ +    AchievementEntry const* achievement = sAchievementStore.LookupEntry(criteria->referredAchievement); +    if(!achievement) +        return; +    // counter can never complete +    if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER) +        return; + +    if(criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL || GetAchievementCompletionState(achievement)==ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED) +    { +        CompletedAchievement(achievement); +    } +} + +// TODO: achievement 705 requires 4 criteria to be fulfilled +AchievementCompletionState AchievementMgr::GetAchievementCompletionState(AchievementEntry const* entry) +{ +    if(m_completedAchievements.find(entry->ID)!=m_completedAchievements.end()) +        return ACHIEVEMENT_COMPLETED_COMPLETED_STORED; + +    bool foundOutstanding = false; +    for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++) +    { +         AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); +         if(!criteria || criteria->referredAchievement!= entry->ID) +             continue; + +         if(IsCompletedCriteria(criteria) && criteria->completionFlag & ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL) +             return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED; + +         // found an umcompleted criteria, but DONT return false yet - there might be a completed criteria with ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL +         if(!IsCompletedCriteria(criteria)) +             foundOutstanding = true; +    } +    if(foundOutstanding) +        return ACHIEVEMENT_COMPLETED_NONE; +    else +        return ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED; +} + +void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative) +{ +    sLog.outString("AchievementMgr::SetCriteriaProgress(%u, %u)", entry->ID, newValue); +    CriteriaProgress *progress = NULL; + +    CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); + +    if(iter == m_criteriaProgress.end()) +    { +        progress = &m_criteriaProgress[entry->ID]; +        progress->counter = 0; +        progress->date = time(NULL); +    } +    else +    { +        progress = &iter->second; +        if(relative) +            newValue += progress->counter; +        if(progress->counter == newValue) +            return; +        progress->counter = newValue; +    } + +    progress->changed = true; + +    if(entry->timeLimit) +    { +        time_t now = time(NULL); +        if(progress->date + entry->timeLimit < now) +        { +            progress->counter = 1; +        } +        // also it seems illogical, the timeframe will be extended at every criteria update +        progress->date = now; +    } +    SendCriteriaUpdate(entry->ID,progress); +} + +void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) +{ +    sLog.outString("AchievementMgr::CompletedAchievement(%u)", achievement->ID); +    if(achievement->flags & ACHIEVEMENT_FLAG_COUNTER || m_completedAchievements.find(achievement->ID)!=m_completedAchievements.end()) +        return; + +    SendAchievementEarned(achievement); +    CompletedAchievementData& ca =  m_completedAchievements[achievement->ID]; +    ca.date = time(NULL); +    ca.changed = true; + +    // don't insert for ACHIEVEMENT_FLAG_REALM_FIRST_KILL since otherwise only the first group member would reach that achievement +    // TODO: where do set this instead? +    if(!(achievement->flags & ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) +        objmgr.allCompletedAchievements.insert(achievement->ID); + +    UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT); + +    // reward items and titles +    AchievementReward const* reward = NULL; +    for (uint32 i=0; i<ACHIEVEMENT_REWARD_COUNT; i++) +    { +        if (achievementRewards[i].achievementId == achievement->ID) +        { +            reward = &achievementRewards[i]; +            break; +        } +    } + +    if (reward) +    { +        sLog.outString("achiev %u, title= %u, %u", reward->achievementId, reward->titleId[0], reward->titleId[1]); +        uint32 titleId = reward->titleId[GetPlayer()->GetTeam() == HORDE?0:1]; +        if(CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(titleId)) +            GetPlayer()->SetTitle(titleEntry); + +        if (reward->itemId) +        { +            ItemPrototype const *pProto = objmgr.GetItemPrototype( reward->itemId ); + +            if(!pProto) +            { +                GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); +                return; +            } + +            ItemPosCountVec dest; +            uint32 no_space = 0; +            uint8 msg = GetPlayer()->CanStoreNewItem( NULL_BAG, NULL_SLOT, dest, reward->itemId, 1, &no_space ); + +            if( msg != EQUIP_ERR_OK ) +            { +                GetPlayer()->SendEquipError( msg, NULL, NULL ); +                return; +            } +            Item* pItem = GetPlayer()->StoreNewItem( dest, reward->itemId, true); + +            if(!pItem) +            { +                GetPlayer()->SendEquipError( EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL ); +                return; +            } +        } +    } +} + +void AchievementMgr::SendAllAchievementData() +{ +    // since we don't know the exact size of the packed GUIDs this is just an approximation +    WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, 4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); +    BuildAllDataPacket(&data); +    GetPlayer()->GetSession()->SendPacket(&data); +} + +void AchievementMgr::SendRespondInspectAchievements(Player* player) +{ +    // since we don't know the exact size of the packed GUIDs this is just an approximation +    WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 4+4*2+m_completedAchievements.size()*4*2+m_completedAchievements.size()*7*4); +    data.append(GetPlayer()->GetPackGUID()); +    BuildAllDataPacket(&data); +    player->GetSession()->SendPacket(&data); +} + +/** + * used by both SMSG_ALL_ACHIEVEMENT_DATA  and SMSG_RESPOND_INSPECT_ACHIEVEMENT + */ +void AchievementMgr::BuildAllDataPacket(WorldPacket *data) +{ +    for(CompletedAchievementMap::const_iterator iter = m_completedAchievements.begin(); iter!=m_completedAchievements.end(); ++iter) +    { +        *data << uint32(iter->first); +        *data << uint32(secsToTimeBitFields(iter->second.date)); +    } +    *data << int32(-1); + +    for(CriteriaProgressMap::const_iterator iter = m_criteriaProgress.begin(); iter!=m_criteriaProgress.end(); ++iter) +    { +        *data << uint32(iter->first); +        data->appendPackGUID(iter->second.counter); +        data->append(GetPlayer()->GetPackGUID()); +        *data << uint32(0); +        *data << uint32(secsToTimeBitFields(iter->second.date)); +        *data << uint32(0); +        *data << uint32(0); +    } + +    *data << int32(-1); +} diff --git a/src/game/AchievementMgr.h b/src/game/AchievementMgr.h new file mode 100644 index 00000000000..6392a9fc647 --- /dev/null +++ b/src/game/AchievementMgr.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 + */ +#ifndef __MANGOS_ACHIEVEMENTMGR_H +#define __MANGOS_ACHIEVEMENTMGR_H + +#include "Common.h" +#include "Database/DBCEnums.h" +#include "Database/DBCStores.h" +#include "Database/DatabaseEnv.h" + +#define CRITERIA_CAST_SPELL_REQ_COUNT 46 +#define ACHIEVEMENT_REWARD_COUNT 57 + +struct CriteriaProgress +{ +    uint32 counter; +    time_t date; +    bool changed; +}; + +struct CriteriaCastSpellRequirement +{ +    uint32 achievementCriteriaId; +    uint32 creatureEntry; +    uint8 playerClass; +    uint8 playerRace; +}; + +struct AchievementReward +{ +    uint32 achievementId; +    uint32 titleId[2]; +    uint32 itemId; +}; + +struct CompletedAchievementData +{ +    time_t date; +    bool changed; +}; + +typedef UNORDERED_MAP<uint32, CriteriaProgress> CriteriaProgressMap; +typedef UNORDERED_MAP<uint32, CompletedAchievementData> CompletedAchievementMap; + +class Unit; +class Player; +class WorldPacket; + +enum AchievementCompletionState +{ +    ACHIEVEMENT_COMPLETED_NONE, +    ACHIEVEMENT_COMPLETED_COMPLETED_NOT_STORED, +    ACHIEVEMENT_COMPLETED_COMPLETED_STORED, +}; + +class AchievementMgr +{ +    public: +        AchievementMgr(Player* pl); +        ~AchievementMgr(); + +        void LoadFromDB(QueryResult *achievementResult, QueryResult *criteriaResult); +        void SaveToDB(); +        void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscvalue1=0, uint32 miscvalue2=0, Unit *unit=NULL, uint32 time=0); +        void CheckAllAchievementCriteria(); +        void SendAllAchievementData(); +        void SendRespondInspectAchievements(Player* player); +        Player* GetPlayer() { return m_player;} + +    private: +        void SendAchievementEarned(AchievementEntry const* achievement); +        void SendCriteriaUpdate(uint32 id, CriteriaProgress const* progress); +        void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 newValue, bool relative=false); +        void CompletedCriteria(AchievementCriteriaEntry const* entry); +        void CompletedAchievement(AchievementEntry const* entry); +        bool IsCompletedCriteria(AchievementCriteriaEntry const* entry); +        AchievementCompletionState GetAchievementCompletionState(AchievementEntry const* entry); +        void BuildAllDataPacket(WorldPacket *data); + +        Player* m_player; +        CriteriaProgressMap m_criteriaProgress; +        CompletedAchievementMap m_completedAchievements; +        static const CriteriaCastSpellRequirement criteriaCastSpellRequirements[]; +        static const AchievementReward achievementRewards[]; +}; +#endif diff --git a/src/game/ArenaTeamHandler.cpp b/src/game/ArenaTeamHandler.cpp index d2c9f54d04b..f48529a3f77 100644 --- a/src/game/ArenaTeamHandler.cpp +++ b/src/game/ArenaTeamHandler.cpp @@ -173,7 +173,7 @@ void WorldSession::HandleArenaTeamInviteAcceptOpcode(WorldPacket & /*recv_data*/      if(!at)          return; -    if(_player->GetArenaTeamIdFromDB(_player->GetGUIDLow(), at->GetType())) +    if(_player->GetArenaTeamId(at->GetType()))      {          SendArenaTeamCommandResult(ERR_ARENA_TEAM_CREATE_S,"","",ERR_ALREADY_IN_ARENA_TEAM);   // already in arena team that size          return; diff --git a/src/game/AuctionHouse.cpp b/src/game/AuctionHouse.cpp index 71a8bb495b4..a12e8a8f238 100644 --- a/src/game/AuctionHouse.cpp +++ b/src/game/AuctionHouse.cpp @@ -752,3 +752,23 @@ void WorldSession::HandleAuctionListItems( WorldPacket & recv_data )      data << (uint32) 300;                                   // unk 2.3.0 const?      SendPacket(&data);  } + +void WorldSession::HandleAuctionListPendingSales( WorldPacket & recv_data ) +{ +    sLog.outDebug("CMSG_AUCTION_LIST_PENDING_SALES"); +    recv_data.hexlike(); + +    uint32 count = 0; + +    WorldPacket data(SMSG_AUCTION_LIST_PENDING_SALES, 4); +    data << uint32(count);                                  // count +    /*for(uint32 i = 0; i < count; ++i) +    { +        data << "";                                         // string +        data << "";                                         // string +        data << uint32(0); +        data << uint32(0); +        data << float(0); +    }*/ +    SendPacket(&data); +} diff --git a/src/game/Bag.cpp b/src/game/Bag.cpp index 765d40f3962..5c870bdb2b7 100644 --- a/src/game/Bag.cpp +++ b/src/game/Bag.cpp @@ -34,7 +34,7 @@ Bag::Bag( ): Item()      m_valuesCount = CONTAINER_END; -    memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);    // Maximum 20 Slots +    memset(m_bagslot, 0, sizeof(Item *) * MAX_BAG_SIZE);  }  Bag::~Bag() diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index d392f074600..b562517dc08 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -576,6 +576,7 @@ void BattleGround::EndBattleGround(uint32 winner)          uint32 bgQueueTypeId = sBattleGroundMgr.BGQueueTypeId(GetTypeID(), GetArenaType());          sBattleGroundMgr.BuildBattleGroundStatusPacket(&data, this, plr->GetTeam(), plr->GetBattleGroundQueueIndex(bgQueueTypeId), STATUS_IN_PROGRESS, TIME_TO_AUTOREMOVE, GetStartTime());          plr->GetSession()->SendPacket(&data); +        plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND, 1);      }      if(isArena() && isRated() && winner_arena_team && loser_arena_team) @@ -1405,10 +1406,10 @@ bool BattleGround::AddSpiritGuide(uint32 type, float x, float y, float z, float      pCreature->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, pCreature->GetGUID());      // aura -    pCreature->SetUInt32Value(UNIT_FIELD_AURA, SPELL_SPIRIT_HEAL_CHANNEL); -    pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009); -    pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); -    pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF); +    pCreature->SetVisibleAura(0, SPELL_SPIRIT_HEAL_CHANNEL); +    //pCreature->SetUInt32Value(UNIT_FIELD_AURAFLAGS, 0x00000009); +    //pCreature->SetUInt32Value(UNIT_FIELD_AURALEVELS, 0x0000003C); +    //pCreature->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS, 0x000000FF);      // casting visual effect      pCreature->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SPIRIT_HEAL_CHANNEL);      // correct cast speed diff --git a/src/game/BattleGround.h b/src/game/BattleGround.h index 3c98afe6d17..7b93adb7dfb 100644 --- a/src/game/BattleGround.h +++ b/src/game/BattleGround.h @@ -132,8 +132,6 @@ struct BattleGroundObjectInfo      uint32      spellid;  }; -#define MAX_QUEUED_PLAYERS_MAP 7 -  enum BattleGroundTypeId  {      BATTLEGROUND_AV     = 1, @@ -143,7 +141,10 @@ enum BattleGroundTypeId      BATTLEGROUND_BE     = 5,      BATTLEGROUND_AA     = 6,      BATTLEGROUND_EY     = 7, -    BATTLEGROUND_RL     = 8 +    BATTLEGROUND_RL     = 8, +    BATTLEGROUND_SA     = 9, +    BATTLEGROUND_DS     = 10, +    BATTLEGROUND_RV     = 11  };  // handle the queue types and bg types separately to enable joining queue for different sized arenas at the same time diff --git a/src/game/BattleGroundHandler.cpp b/src/game/BattleGroundHandler.cpp index fc99fe3f1fe..4cdef6eebac 100644 --- a/src/game/BattleGroundHandler.cpp +++ b/src/game/BattleGroundHandler.cpp @@ -180,6 +180,8 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )          }          sLog.outDebug("Battleground: group end");          sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); +        if(!ginfo->IsInvitedToBGInstanceGUID) +            sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);      }      else      { @@ -196,6 +198,8 @@ void WorldSession::HandleBattleGroundJoinOpcode( WorldPacket & recv_data )          GroupQueueInfo * ginfo = sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddGroup(_player, bgTypeId, 0, false, 0);          sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AddPlayer(_player, ginfo);          sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel()); +        if(!ginfo->IsInvitedToBGInstanceGUID) +            sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);          sLog.outDebug("Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s",bgQueueTypeId,bgTypeId,_player->GetGUIDLow(), _player->GetName());      }  } @@ -784,6 +788,8 @@ void WorldSession::HandleBattleGroundArenaJoin( WorldPacket & recv_data )          }          sLog.outDebug("Battleground: arena join as group end");          sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].Update(bgTypeId, _player->GetBattleGroundQueueIdFromLevel(), arenatype, isRated, arenaRating); +        if(isRated) +            sBattleGroundMgr.m_BattleGroundQueues[bgQueueTypeId].AnnounceWorld(ginfo, _player->GetGUID(), true);      }      else      { diff --git a/src/game/BattleGroundMgr.cpp b/src/game/BattleGroundMgr.cpp index 4be2320be6a..2b904ba6850 100644 --- a/src/game/BattleGroundMgr.cpp +++ b/src/game/BattleGroundMgr.cpp @@ -243,38 +243,6 @@ void BattleGroundQueue::AddPlayer(Player *plr, GroupQueueInfo *ginfo)      // add the pinfo to ginfo's list      ginfo->Players[plr->GetGUID()]  = &info; -/* -    if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) ) -    { -        BattleGround* bg = sBattleGroundMgr.GetBattleGround(bgTypeId); -        char const* bgName = bg->GetName(); - -        uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id); -        uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id); - -        // replace hardcoded max level by player max level for nice output -        if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) -            q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); - -        int8 MinPlayers = bg->GetMinPlayersPerTeam(); - -        uint8 qHorde = m_QueuedPlayers[queue_id].Horde; -        uint8 qAlliance = m_QueuedPlayers[queue_id].Alliance; - -        // Show queue status to player only (when joining queue) -        if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) -        { -            ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, -                bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0); -        } -        // System message -        else -        { -            sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, -                bgName, q_min_level, q_max_level, qAlliance, (MinPlayers > qAlliance) ? (MinPlayers - qAlliance) : 0, qHorde, (MinPlayers > qHorde) ? (MinPlayers - qHorde) : 0); -        } - -    }*/  }  void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount) @@ -360,6 +328,11 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)          // remove player queue info          m_QueuedPlayers[queue_id].erase(itr);          // remove group queue info if needed + +        //if we left BG queue(not porting) OR if arena team left queue for rated match +        if((decreaseInvitedCount && !group->ArenaType) || (group->ArenaType && group->IsRated && group->Players.empty())) +            AnnounceWorld(group, guid, false); +          if(group->Players.empty())          {              m_QueuedGroups[queue_id].erase(group_itr); @@ -388,6 +361,85 @@ void BattleGroundQueue::RemovePlayer(uint64 guid, bool decreaseInvitedCount)      }  } +void BattleGroundQueue::AnnounceWorld(GroupQueueInfo *ginfo, uint64 playerGUID, bool isAddedToQueue) +{ + +    if(ginfo->ArenaType) //if Arena +    { +        if( sWorld.getConfig(CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE) && ginfo->IsRated) +        { +            BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId); +            if(!bg) +                return; + +            char const* bgName = bg->GetName(); +            if(isAddedToQueue) +                sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating); +            else +                sWorld.SendWorldText(LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT, bgName, ginfo->ArenaType, ginfo->ArenaType, ginfo->ArenaTeamRating); +        } +    } +    else //if BG +    { +        if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) ) +        { +            Player *plr = objmgr.GetPlayer(playerGUID); +            if(!plr) +                return; + +            BattleGround* bg = sBattleGroundMgr.GetBattleGroundTemplate(ginfo->BgTypeId); +            if(!bg) +                return; + +            uint32 queue_id = plr->GetBattleGroundQueueIdFromLevel(); +            char const* bgName = bg->GetName(); + +            uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id); +            uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id); + +            // replace hardcoded max level by player max level for nice output +            if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) +                q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); + +            int8 MinPlayers = bg->GetMinPlayersPerTeam(); + +            uint8 qHorde = 0; +            uint8 qAlliance = 0; + +            uint32 bgTypeId = ginfo->BgTypeId; +            QueuedPlayersMap::iterator itr; +            for(itr = m_QueuedPlayers[queue_id].begin(); itr!= m_QueuedPlayers[queue_id].end(); ++itr) +            { +                if(itr->second.GroupInfo->BgTypeId == bgTypeId) +                { +                    switch(itr->second.GroupInfo->Team) +                    { +                        case HORDE: +                            qHorde++; break; +                        case ALLIANCE: +                            qAlliance++; break; +                        default: +                            break; +                    } +                } +            } + +            // Show queue status to player only (when joining queue) +            if(sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY)) +            { +                ChatHandler(plr).PSendSysMessage(LANG_BG_QUEUE_ANNOUNCE_SELF, +                    bgName, q_min_level, q_max_level, qAlliance, MinPlayers, qHorde, MinPlayers); +            } +            // System message +            else +            { +                sWorld.SendWorldText(LANG_BG_QUEUE_ANNOUNCE_WORLD, +                    bgName, q_min_level, q_max_level, qAlliance, MinPlayers, qHorde, MinPlayers); +            } +        } +    } +} +  bool BattleGroundQueue::InviteGroupToBG(GroupQueueInfo * ginfo, BattleGround * bg, uint32 side)  {      // set side if needed @@ -715,6 +767,15 @@ void BattleGroundQueue::Update(uint32 bgTypeId, uint32 queue_id, uint8 arenatype          {              // create new battleground              bg2 = sBattleGroundMgr.CreateNewBattleGround(bgTypeId); +            if( sWorld.getConfig(CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE) ) +            { +                char const* bgName = bg2->GetName(); +                uint32 q_min_level = Player::GetMinLevelForBattleGroundQueueId(queue_id); +                uint32 q_max_level = Player::GetMaxLevelForBattleGroundQueueId(queue_id); +                if(q_max_level > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) +                    q_max_level = sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL); +                sWorld.SendWorldText(LANG_BG_STARTED_ANNOUNCE_WORLD, bgName, q_min_level, q_max_level); +            }          }          if(!bg2) @@ -1267,13 +1328,16 @@ void BattleGroundMgr::BuildPvpLogDataPacket(WorldPacket *data, BattleGround *bg)                  *data << (uint32)((BattleGroundABScore*)itr->second)->BasesDefended;        // bases defended                  break;              case BATTLEGROUND_EY: -                *data << (uint32)0x00000001;                 // count of next fields +                *data << (uint32)0x00000001;                // count of next fields                  *data << (uint32)((BattleGroundEYScore*)itr->second)->FlagCaptures;         // flag captures                  break;              case BATTLEGROUND_NA:              case BATTLEGROUND_BE:              case BATTLEGROUND_AA:              case BATTLEGROUND_RL: +            case BATTLEGROUND_SA:                           // wotlk +            case BATTLEGROUND_DS:                           // wotlk +            case BATTLEGROUND_RV:                           // wotlk                  *data << (int32)0;                          // 0                  break;              default: diff --git a/src/game/BattleGroundMgr.h b/src/game/BattleGroundMgr.h index b217c1d692e..faf6196979d 100644 --- a/src/game/BattleGroundMgr.h +++ b/src/game/BattleGroundMgr.h @@ -32,9 +32,9 @@ typedef std::map<uint32, BattleGround*> BattleGroundSet;  //typedef std::map<uint32, BattleGroundQueue*> BattleGroundQueueSet;  typedef std::deque<BattleGround*> BGFreeSlotQueueType; -#define MAX_BATTLEGROUND_QUEUES 7                           // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70+ +#define MAX_BATTLEGROUND_QUEUES 8                           // for level ranges 10-19, 20-29, 30-39, 40-49, 50-59, 60-69, 70-79, 80+ -#define MAX_BATTLEGROUND_TYPES 9                            // each BG type will be in array +#define MAX_BATTLEGROUND_TYPES 12                           // each BG type will be in array  #define MAX_BATTLEGROUND_QUEUE_TYPES 8 @@ -77,6 +77,7 @@ class BattleGroundQueue          void RemovePlayer(uint64 guid, bool decreaseInvitedCount);          void DecreaseGroupLength(uint32 queueId, uint32 AsGroup);          void BGEndedRemoveInvites(BattleGround * bg); +        void AnnounceWorld(GroupQueueInfo *ginfo, uint64 playerGUID, bool isAddedToQueue);          typedef std::map<uint64, PlayerQueueInfo> QueuedPlayersMap;          QueuedPlayersMap m_QueuedPlayers[MAX_BATTLEGROUND_QUEUES]; diff --git a/src/game/Calendar.cpp b/src/game/Calendar.cpp new file mode 100644 index 00000000000..cebf7252e78 --- /dev/null +++ b/src/game/Calendar.cpp @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 + */ diff --git a/src/game/Tools.h b/src/game/Calendar.h index 03b48a7e9a3..94e4ff103f5 100644 --- a/src/game/Tools.h +++ b/src/game/Calendar.h @@ -1,7 +1,5 @@  /* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> - * - * Copyright (C) 2008 Trinity <http://www.trinitycore.org/> + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/>   *   * 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 @@ -10,19 +8,19 @@   *   * 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 + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */ -#ifndef TRINITY_TOOLS_H -#define TRINITY_TOOLS_H -#include "Common.h" -#include "WorldPacket.h" +#ifndef MANGOS_CALENDAR_H +#define MANGOS_CALENDAR_H + +class Calendar +{ -bool readGUID(WorldPacket & data, uint64& guid); -void    writeGUID(WorldPacket & data, uint64 & guid); +};  #endif diff --git a/src/game/CalendarHandler.cpp b/src/game/CalendarHandler.cpp new file mode 100644 index 00000000000..9c69e3a91f6 --- /dev/null +++ b/src/game/CalendarHandler.cpp @@ -0,0 +1,118 @@ +/*  + * Copyright (C) 2005-2008 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 "Common.h" +#include "Log.h" +#include "Player.h" +#include "WorldPacket.h" +#include "WorldSession.h" +#include "Opcodes.h" + +void WorldSession::HandleCalendarGetCalendar(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_GET_CALENDAR"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarGetEvent(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_GET_EVENT"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarGuildFilter(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_GUILD_FILTER"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarArenaTeam(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_ARENA_TEAM"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarAddEvent(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_ADD_EVENT"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarUpdateEvent(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_UPDATE_EVENT"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarRemoveEvent(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_REMOVE_EVENT"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarCopyEvent(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_COPY_EVENT"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarEventInvite(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_INVITE"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarEventRsvp(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_RSVP"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarEventRemoveInvite(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_REMOVE_INVITE"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarEventStatus(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_STATUS"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarEventModeratorStatus(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_EVENT_MODERATOR_STATUS"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarComplain(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_COMPLAIN"); +    recv_data.hexlike(); +} + +void WorldSession::HandleCalendarGetNumPending(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: CMSG_CALENDAR_GET_NUM_PENDING"); +    recv_data.hexlike(); + +    WorldPacket data(SMSG_CALENDAR_SEND_NUM_PENDING, 4); +    data << uint32(0);                                      // 0 - no pending invites, 1 - some pending invites +    SendPacket(&data); +} diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index aa884ddd2df..121a9b0d98d 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -82,7 +82,9 @@ bool LoginQueryHolder::Initialize()          res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES,   "SELECT genitive, dative, accusative, instrumental, prepositional FROM character_declinedname WHERE guid = '%u'",GUID_LOPART(m_guid));      // in other case still be dummy query      res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADGUILD,           "SELECT guildid,rank FROM guild_member WHERE guid = '%u'", GUID_LOPART(m_guid)); -    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO,       "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid)); +    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADARENAINFO,       "SELECT arenateamid, played_week, played_season, personal_rating FROM arena_team_member WHERE guid='%u'", GUID_LOPART(m_guid));     +    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS,    "SELECT achievement, date FROM character_achievement WHERE guid = '%u'", GUID_LOPART(m_guid)); +    res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS,"SELECT criteria, counter, date FROM character_achievement_progress WHERE guid = '%u'", GUID_LOPART(m_guid));      return res;  } @@ -232,17 +234,16 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )      if (raceEntry->addon > Expansion())      {          data << (uint8)CHAR_CREATE_EXPANSION; -        sLog.outError("Not Expansion 1 account:[%d] but tried to Create character with expansion 1 race (%u)",GetAccountId(),race_); +        sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u race (%u)",Expansion(),GetAccountId(),raceEntry->addon,race_);          SendPacket( &data );          return;      }      // prevent character creating Expansion class without Expansion account -    // TODO: use possible addon field in ChrClassesEntry in next dbc version -    if (Expansion() < 2 && class_ == CLASS_DEATH_KNIGHT) +    if (classEntry->addon > Expansion())      { -        data << (uint8)CHAR_CREATE_EXPANSION; -        sLog.outError("Not Expansion 2 account:[%d] but tried to Create character with expansion 2 class (%u)",GetAccountId(),class_); +        data << (uint8)CHAR_CREATE_EXPANSION_CLASS; +        sLog.outError("Expansion %u account:[%d] tried to Create character with expansion %u class (%u)",Expansion(),GetAccountId(),classEntry->addon,class_);          SendPacket( &data );          return;      } @@ -309,29 +310,77 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )          }      } +    // speedup check for heroic class disabled case +    uint32 heroic_free_slots = sWorld.getConfig(CONFIG_HEROIC_CHARACTERS_PER_REALM); +    if(heroic_free_slots==0 && GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) +    { +        data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; +        SendPacket( &data ); +        return; +    } + +    // speedup check for heroic class disabled case +    uint32 req_level_for_heroic = sWorld.getConfig(CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING); +    if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && req_level_for_heroic > sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)) +    { +        data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; +        SendPacket( &data ); +        return; +    } +      bool AllowTwoSideAccounts = !sWorld.IsPvPRealm() || sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_ACCOUNTS) || GetSecurity() > SEC_PLAYER;      uint32 skipCinematics = sWorld.getConfig(CONFIG_SKIP_CINEMATICS);      bool have_same_race = false; -    if(!AllowTwoSideAccounts || skipCinematics == 1) + +    // if 0 then allowed creating without any characters +    bool have_req_level_for_heroic = (req_level_for_heroic==0); + +    if(!AllowTwoSideAccounts || skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT)      { -        QueryResult *result2 = CharacterDatabase.PQuery("SELECT DISTINCT race FROM characters WHERE account = '%u' %s", GetAccountId(),skipCinematics == 1 ? "" : "LIMIT 1"); +        QueryResult *result2 = CharacterDatabase.PQuery("SELECT guid,race,class FROM characters WHERE account = '%u' %s", +            GetAccountId(), (skipCinematics == 1 || class_ == CLASS_DEATH_KNIGHT) ? "" : "LIMIT 1");          if(result2)          {              uint32 team_= Player::TeamForRace(race_);              Field* field = result2->Fetch(); -            uint8 race = field[0].GetUInt32(); +            uint8 acc_race  = field[1].GetUInt32(); + +            if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT) +            { +                uint8 acc_class = field[2].GetUInt32(); +                if(acc_class == CLASS_DEATH_KNIGHT) +                { +                    if(heroic_free_slots > 0) +                        --heroic_free_slots; + +                    if(heroic_free_slots==0) +                    { +                        data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; +                        SendPacket( &data ); +                        return; +                    } +                } + +                if(!have_req_level_for_heroic) +                { +                    uint32 acc_guid = field[0].GetUInt32(); +                    uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid); +                    if(acc_level >= req_level_for_heroic) +                        have_req_level_for_heroic = true; +                } +            }              // need to check team only for first character              // TODO: what to if account already has characters of both races?              if (!AllowTwoSideAccounts)              { -                uint32 team=0; -                if(race > 0) -                    team = Player::TeamForRace(race); +                uint32 acc_team=0; +                if(acc_race > 0) +                    acc_team = Player::TeamForRace(acc_race); -                if(team != team_) +                if(acc_team != team_)                  {                      data << (uint8)CHAR_CREATE_PVP_TEAMS_VIOLATION;                      SendPacket( &data ); @@ -340,20 +389,55 @@ void WorldSession::HandleCharCreateOpcode( WorldPacket & recv_data )                  }              } -            if (skipCinematics == 1) +            // search same race for cinematic or same class if need +            // TODO: check if cinematic already shown? (already logged in?; cinematic field) +            while ((skipCinematics == 1 && !have_same_race) || class_ == CLASS_DEATH_KNIGHT)              { -                // TODO: check if cinematic already shown? (already logged in?; cinematic field) -                while (race_ != race && result2->NextRow()) +                if(!result2->NextRow()) +                    break; + +                field = result2->Fetch(); +                acc_race = field[1].GetUInt32(); + +                if(!have_same_race) +                    have_same_race = race_ == acc_race; + +                if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT)                  { -                    field = result2->Fetch(); -                    race = field[0].GetUInt32(); +                    uint8 acc_class = field[2].GetUInt32(); +                    if(acc_class == CLASS_DEATH_KNIGHT) +                    { +                        if(heroic_free_slots > 0) +                            --heroic_free_slots; + +                        if(heroic_free_slots==0) +                        { +                            data << (uint8)CHAR_CREATE_UNIQUE_CLASS_LIMIT; +                            SendPacket( &data ); +                            return; +                        } +                    } + +                    if(!have_req_level_for_heroic) +                    { +                        uint32 acc_guid = field[0].GetUInt32(); +                        uint32 acc_level = Player::GetUInt32ValueFromDB(UNIT_FIELD_LEVEL,acc_guid); +                        if(acc_level >= req_level_for_heroic) +                            have_req_level_for_heroic = true; +                    }                  } -                have_same_race = race_ == race;              }              delete result2;          }      } +    if(GetSecurity()==SEC_PLAYER && class_ == CLASS_DEATH_KNIGHT && !have_req_level_for_heroic) +    { +        data << (uint8)CHAR_CREATE_LEVEL_REQUIREMENT; +        SendPacket( &data ); +        return; +    } +      // extract other data required for player creating      uint8 gender, skin, face, hairStyle, hairColor, facialHair, outfitId;      recv_data >> gender >> skin >> face; @@ -510,9 +594,11 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)      data << pCurrChar->GetOrientation();      SendPacket(&data); -    data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 128 ); -    for(int i = 0; i < 32; i++) -        data << uint32(0); +    data.Initialize( SMSG_ACCOUNT_DATA_TIMES, 4+1+8*4 );    // changed in WotLK +    data << uint32(time(NULL));                             // unix time of something +    data << uint8(1); +    for(int i = 0; i < NUM_ACCOUNT_DATA_TYPES; i++) +        data << uint32(GetAccountData(i)->Time);            // also unix time      SendPacket(&data);      data.Initialize(SMSG_FEATURE_SYSTEM_STATUS, 2);         // added in 2.2.0 @@ -609,12 +695,20 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)      {          pCurrChar->setCinematic(1); -        ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace()); -        if(rEntry) +        if(ChrClassesEntry const* cEntry = sChrClassesStore.LookupEntry(pCurrChar->getClass()))          { -            data.Initialize( SMSG_TRIGGER_CINEMATIC,4 ); -            data << uint32(rEntry->startmovie); -            SendPacket( &data ); +            if(cEntry->CinematicSequence) +            { +                data.Initialize(SMSG_TRIGGER_CINEMATIC, 4); +                data << uint32(cEntry->CinematicSequence); +                SendPacket( &data ); +            } +            else if(ChrRacesEntry const* rEntry = sChrRacesStore.LookupEntry(pCurrChar->getRace())) +            { +                data.Initialize(SMSG_TRIGGER_CINEMATIC, 4); +                data << uint32(rEntry->CinematicSequence); +                SendPacket( &data ); +            }          }      } @@ -658,22 +752,6 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder)              pCurrChar->CastSpell(pCurrChar, 20584, true, 0);// auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)          pCurrChar->CastSpell(pCurrChar, 8326, true, 0);     // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) -        //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+41, 8326); -        //pCurrChar->SetUInt32Value(UNIT_FIELD_AURA+42, 20584); -        //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAFLAGS+6, 238); -        //pCurrChar->SetUInt32Value(UNIT_FIELD_AURALEVELS+11, 514); -        //pCurrChar->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS+11, 65535); -        //pCurrChar->SetUInt32Value(UNIT_FIELD_DISPLAYID, 1825); -        //if (pCurrChar->getRace() == RACE_NIGHTELF) -        //{ -        //    pCurrChar->SetSpeed(MOVE_RUN,  1.5f*1.2f, true); -        //    pCurrChar->SetSpeed(MOVE_SWIM, 1.5f*1.2f, true); -        //} -        //else -        //{ -        //    pCurrChar->SetSpeed(MOVE_RUN,  1.5f, true); -        //    pCurrChar->SetSpeed(MOVE_SWIM, 1.5f, true); -        //}          pCurrChar->SetMovement(MOVE_WATER_WALK);      } @@ -903,11 +981,11 @@ void WorldSession::HandleToggleCloakOpcode( WorldPacket & /*recv_data*/ )  void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)  { +    CHECK_PACKET_SIZE(recv_data, 8+1); +      uint64 guid;      std::string newname; -    CHECK_PACKET_SIZE(recv_data, 8+1); -      recv_data >> guid;      recv_data >> newname; @@ -915,15 +993,15 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)      if(!normalizePlayerName(newname))      {          WorldPacket data(SMSG_CHAR_RENAME, 1); -        data << (uint8)CHAR_NAME_NO_NAME; +        data << uint8(CHAR_NAME_NO_NAME);          SendPacket( &data );          return;      } -    if(!ObjectMgr::IsValidName(newname,true)) +    if(!ObjectMgr::IsValidName(newname, true))      {          WorldPacket data(SMSG_CHAR_RENAME, 1); -        data << (uint8)CHAR_NAME_INVALID_CHARACTER; +        data << uint8(CHAR_NAME_INVALID_CHARACTER);          SendPacket( &data );          return;      } @@ -932,7 +1010,7 @@ void WorldSession::HandleChangePlayerNameOpcode(WorldPacket& recv_data)      if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname))      {          WorldPacket data(SMSG_CHAR_RENAME, 1); -        data << (uint8)CHAR_NAME_RESERVED; +        data << uint8(CHAR_NAME_RESERVED);          SendPacket( &data );          return;      } @@ -961,7 +1039,7 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin      if (!result)      {          WorldPacket data(SMSG_CHAR_RENAME, 1); -        data << (uint8)CHAR_CREATE_ERROR; +        data << uint8(CHAR_CREATE_ERROR);          session->SendPacket( &data );          return;      } @@ -975,11 +1053,11 @@ void WorldSession::HandleChangePlayerNameOpcodeCallBack(QueryResult *result, uin      CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_RENAME), guidLow);      CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", guidLow); -    sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s",session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str()); +    sLog.outChar("Account: %d (IP: %s) Character:[%s] (guid:%u) Changed name to: %s", session->GetAccountId(), session->GetRemoteAddress().c_str(), oldname.c_str(), guidLow, newname.c_str()); -    WorldPacket data(SMSG_CHAR_RENAME,1+8+(newname.size()+1)); -    data << (uint8)RESPONSE_SUCCESS; -    data << guid; +    WorldPacket data(SMSG_CHAR_RENAME, 1+8+(newname.size()+1)); +    data << uint8(RESPONSE_SUCCESS); +    data << uint64(guid);      data << newname;      session->SendPacket(&data);  } @@ -1073,3 +1151,166 @@ void WorldSession::HandleDeclinedPlayerNameOpcode(WorldPacket& recv_data)      data << uint64(guid);      SendPacket(&data);  } + +void WorldSession::HandleAlterAppearance( WorldPacket & recv_data ) +{ +    sLog.outDebug("CMSG_ALTER_APPEARANCE"); + +    CHECK_PACKET_SIZE(recv_data, 4+4+4); + +    uint32 Hair, Color, FacialHair; +    recv_data >> Hair >> Color >> FacialHair; + +    BarberShopStyleEntry const* bs_hair = sBarberShopStyleStore.LookupEntry(Hair); + +    if(!bs_hair || bs_hair->type != 0 || bs_hair->race != _player->getRace() || bs_hair->gender != _player->getGender()) +        return; + +    BarberShopStyleEntry const* bs_facialHair = sBarberShopStyleStore.LookupEntry(FacialHair); + +    if(!bs_facialHair || bs_facialHair->type != 2 || bs_facialHair->race != _player->getRace() || bs_facialHair->gender != _player->getGender()) +        return; + +    uint32 Cost = _player->GetBarberShopCost(bs_hair->hair_id, Color, bs_facialHair->hair_id); + +    // 0 - ok +    // 1,3 - not enough money +    // 2 - you have to seat on barber chair +    if(_player->GetMoney() < Cost) +    { +        WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); +        data << uint32(1);                                  // no money +        SendPacket(&data); +        return; +    } +    else +    { +        WorldPacket data(SMSG_BARBER_SHOP_RESULT, 4); +        data << uint32(0);                                  // ok +        SendPacket(&data); +    } + +    _player->SetMoney(_player->GetMoney() - Cost);          // it isn't free + +    _player->SetByteValue(PLAYER_BYTES, 2, uint8(bs_hair->hair_id)); +    _player->SetByteValue(PLAYER_BYTES, 3, uint8(Color)); +    _player->SetByteValue(PLAYER_BYTES_2, 0, uint8(bs_facialHair->hair_id)); + +    _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP, 1); + +    _player->SetStandState(0);                              // stand up +} + +void WorldSession::HandleRemoveGlyph( WorldPacket & recv_data ) +{ +    CHECK_PACKET_SIZE(recv_data, 4); + +    uint32 slot; +    recv_data >> slot; + +    if(slot > 5) +    { +        sLog.outDebug("Client sent wrong glyph slot number in opcode CMSG_REMOVE_GLYPH %u", slot); +        return; +    } + +    if(uint32 glyph = _player->GetGlyph(slot)) +    { +        if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) +        { +            _player->RemoveAurasDueToSpell(gp->SpellId); +            _player->SetGlyph(slot, 0); +        } +    } +} + +void WorldSession::HandleCharCustomize(WorldPacket& recv_data) +{ +    CHECK_PACKET_SIZE(recv_data, 8+1); + +    uint64 guid; +    std::string newname; + +    recv_data >> guid; +    recv_data >> newname; + +    CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+1+1+1+1+1+1); + +    uint8 gender, skin, face, hairStyle, hairColor, facialHair; +    recv_data >> gender >> skin >> face >> hairStyle >> hairColor >> facialHair; + +    QueryResult *result = CharacterDatabase.PQuery("SELECT at_login FROM characters WHERE guid ='%u'", GUID_LOPART(guid)); +    if (!result) +    { +        WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); +        data << uint8(CHAR_CREATE_ERROR); +        SendPacket( &data ); +        return; +    } + +    Field *fields = result->Fetch(); +    uint32 at_loginFlags = fields[0].GetUInt32(); +    delete result; + +    if (!(at_loginFlags & AT_LOGIN_CUSTOMIZE)) +    { +        WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); +        data << uint8(CHAR_CREATE_ERROR); +        SendPacket( &data ); +        return; +    } + +    // prevent character rename to invalid name +    if(!normalizePlayerName(newname)) +    { +        WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); +        data << uint8(CHAR_NAME_NO_NAME); +        SendPacket( &data ); +        return; +    } + +    if(!ObjectMgr::IsValidName(newname,true)) +    { +        WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); +        data << uint8(CHAR_NAME_INVALID_CHARACTER); +        SendPacket( &data ); +        return; +    } + +    // check name limitations +    if(GetSecurity() == SEC_PLAYER && objmgr.IsReservedName(newname)) +    { +        WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); +        data << uint8(CHAR_NAME_RESERVED); +        SendPacket( &data ); +        return; +    } + +    if(objmgr.GetPlayerGUIDByName(newname))                 // character with this name already exist +    { +        WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1); +        data << uint8(CHAR_CREATE_NAME_IN_USE); +        SendPacket( &data ); +        return; +    } + +    CharacterDatabase.escape_string(newname); +    Player::Customize(guid, gender, skin, face, hairStyle, hairColor, facialHair); +    CharacterDatabase.PExecute("UPDATE characters set name = '%s', at_login = at_login & ~ %u WHERE guid ='%u'", newname.c_str(), uint32(AT_LOGIN_CUSTOMIZE), GUID_LOPART(guid)); +    CharacterDatabase.PExecute("DELETE FROM character_declinedname WHERE guid ='%u'", GUID_LOPART(guid)); + +    std::string IP_str = GetRemoteAddress(); +    sLog.outChar("Account: %d (IP: %s), Character guid: %u Customized to: %s", GetAccountId(), IP_str.c_str(), GUID_LOPART(guid), newname.c_str()); + +    WorldPacket data(SMSG_CHAR_CUSTOMIZE, 1+8+(newname.size()+1)+6); +    data << uint8(RESPONSE_SUCCESS); +    data << uint64(guid); +    data << newname; +    data << uint8(gender); +    data << uint8(skin); +    data << uint8(face); +    data << uint8(hairStyle); +    data << uint8(hairColor); +    data << uint8(facialHair); +    SendPacket(&data); +} diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index d86e941c3f5..fe7949fc700 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -110,6 +110,7 @@ ChatCommand * ChatHandler::getCommandTable()          { "hp",             SEC_MODERATOR,      false, &ChatHandler::HandleModifyHPCommand,            "", NULL },          { "mana",           SEC_MODERATOR,      false, &ChatHandler::HandleModifyManaCommand,          "", NULL },          { "rage",           SEC_MODERATOR,      false, &ChatHandler::HandleModifyRageCommand,          "", NULL }, +        { "runicpower",     SEC_MODERATOR,      false, &ChatHandler::HandleModifyRunicPowerCommand,    "", NULL },          { "energy",         SEC_MODERATOR,      false, &ChatHandler::HandleModifyEnergyCommand,        "", NULL },          { "money",          SEC_MODERATOR,      false, &ChatHandler::HandleModifyMoneyCommand,         "", NULL },          { "speed",          SEC_MODERATOR,      false, &ChatHandler::HandleModifySpeedCommand,         "", NULL }, @@ -190,6 +191,7 @@ ChatCommand * ChatHandler::getCommandTable()          { "sellerr",        SEC_ADMINISTRATOR,  false, &ChatHandler::HandleSellErrorCommand,           "", NULL },          { "buyerr",         SEC_ADMINISTRATOR,  false, &ChatHandler::HandleBuyErrorCommand,            "", NULL },          { "sendopcode",     SEC_ADMINISTRATOR,  false, &ChatHandler::HandleSendOpcodeCommand,          "", NULL }, +        { "spawnvehicle",   SEC_ADMINISTRATOR,  false, &ChatHandler::HandleSpawnVehicle,               "", NULL },          { "uws",            SEC_ADMINISTRATOR,  false, &ChatHandler::HandleUpdateWorldStateCommand,    "", NULL },          { "ps",             SEC_ADMINISTRATOR,  false, &ChatHandler::HandlePlaySound2Command,          "", NULL },          { "scn",            SEC_ADMINISTRATOR,  false, &ChatHandler::HandleSendChannelNotifyCommand,   "", NULL }, @@ -263,6 +265,7 @@ ChatCommand * ChatHandler::getCommandTable()          { "item_enchantment_template",   SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadItemEnchantementsCommand,       "", NULL },          { "item_loot_template",          SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadLootTemplatesItemCommand,       "", NULL },          { "trinity_string",              SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadTrinityStringCommand,           "", NULL }, +        { "milling_loot_template",       SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadLootTemplatesMillingCommand,    "", NULL },          { "npc_gossip",                  SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadNpcGossipCommand,               "", NULL },          { "npc_option",                  SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadNpcOptionCommand,               "", NULL },          { "npc_trainer",                 SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadNpcTrainerCommand,              "", NULL }, @@ -299,7 +302,6 @@ ChatCommand * ChatHandler::getCommandTable()          { "locales_quest",               SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadLocalesQuestCommand,            "", NULL },  		{ "waypoint_scripts",            SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadWpScriptsCommand,				 "", NULL }, -        { "",                            SEC_ADMINISTRATOR, true,  &ChatHandler::HandleReloadCommand,                        "", NULL },          { NULL,                          0,                 false, NULL,                                                     "", NULL }      }; @@ -589,6 +591,7 @@ ChatCommand * ChatHandler::getCommandTable()          { "sendmail",       SEC_MODERATOR,      true,  &ChatHandler::HandleSendMailCommand,            "", NULL },          { "sendmoney",      SEC_ADMINISTRATOR,  true,  &ChatHandler::HandleSendMoneyCommand,           "", NULL },          { "rename",         SEC_GAMEMASTER,     true,  &ChatHandler::HandleRenameCommand,              "", NULL }, +        { "customize",      SEC_GAMEMASTER,     true,  &ChatHandler::HandleCustomizeCommand,           "", NULL },          { "loadscripts",    SEC_ADMINISTRATOR,  true,  &ChatHandler::HandleLoadScriptsCommand,         "", NULL },          { "mute",           SEC_GAMEMASTER,     true,  &ChatHandler::HandleMuteCommand,                "", NULL },          { "unmute",         SEC_GAMEMASTER,     true,  &ChatHandler::HandleUnmuteCommand,              "", NULL }, @@ -750,9 +753,9 @@ void ChatHandler::PSendSysMessage(int32 entry, ...)  {      const char *format = GetTrinityString(entry);      va_list ap; -    char str [1024]; +    char str [2048];      va_start(ap, entry); -    vsnprintf(str,1024,format, ap ); +    vsnprintf(str,2048,format, ap );      va_end(ap);      SendSysMessage(str);  } @@ -760,9 +763,9 @@ void ChatHandler::PSendSysMessage(int32 entry, ...)  void ChatHandler::PSendSysMessage(const char *format, ...)  {      va_list ap; -    char str [1024]; +    char str [2048];      va_start(ap, format); -    vsnprintf(str,1024,format, ap ); +    vsnprintf(str,2048,format, ap );      va_end(ap);      SendSysMessage(str);  } diff --git a/src/game/Chat.h b/src/game/Chat.h index 16f764366ac..b5d9de4faf7 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -163,6 +163,7 @@ class ChatHandler          bool HandleModifyHPCommand(const char* args);          bool HandleModifyManaCommand(const char* args);          bool HandleModifyRageCommand(const char* args); +        bool HandleModifyRunicPowerCommand(const char* args);          bool HandleModifyEnergyCommand(const char* args);          bool HandleModifyMoneyCommand(const char* args);          bool HandleModifyASpeedCommand(const char* args); @@ -202,7 +203,6 @@ class ChatHandler          bool HandleNpcWhisperCommand(const char* args);          bool HandleNpcYellCommand(const char* args); -        bool HandleReloadCommand(const char* args);          bool HandleReloadAllCommand(const char* args);          bool HandleReloadAllAreaCommand(const char* args);          bool HandleReloadAllItemCommand(const char* args); @@ -233,6 +233,7 @@ class ChatHandler          bool HandleReloadLootTemplatesFishingCommand(const char* args);          bool HandleReloadLootTemplatesGameobjectCommand(const char* args);          bool HandleReloadLootTemplatesItemCommand(const char* args); +        bool HandleReloadLootTemplatesMillingCommand(const char* args);          bool HandleReloadLootTemplatesPickpocketingCommand(const char* args);          bool HandleReloadLootTemplatesProspectingCommand(const char* args);          bool HandleReloadLootTemplatesReferenceCommand(const char* args); @@ -434,6 +435,7 @@ class ChatHandler          bool HandleSendChannelNotifyCommand(const char* args);          bool HandleSendChatMsgCommand(const char* args);          bool HandleRenameCommand(const char * args); +        bool HandleCustomizeCommand(const char * args);          bool HandleLoadPDumpCommand(const char *args);          bool HandleWritePDumpCommand(const char *args);          bool HandleCastCommand(const char *args); @@ -467,6 +469,7 @@ class ChatHandler          bool HandleUnPossessCommand(const char* args);          bool HandleBindSightCommand(const char* args);          bool HandleUnbindSightCommand(const char* args); +        bool HandleSpawnVehicle(const char * args);          Player*   getSelectedPlayer();          Creature* getSelectedCreature(); diff --git a/src/game/Corpse.cpp b/src/game/Corpse.cpp index 989ccd61151..77b553f6856 100644 --- a/src/game/Corpse.cpp +++ b/src/game/Corpse.cpp @@ -36,7 +36,7 @@ Corpse::Corpse(CorpseType type) : WorldObject()      m_objectType |= TYPEMASK_CORPSE;      m_objectTypeId = TYPEID_CORPSE;                                                              // 2.3.2 - 0x58 -    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); +    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);      m_valuesCount = CORPSE_END; diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 629b5ec6d43..5c5ccef3897 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -145,11 +145,12 @@ Unit(), i_AI(NULL), i_AI_possessed(NULL),  lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),  m_lootMoney(0), m_lootRecipient(0),  m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f), -m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_reactState(REACT_AGGRESSIVE), -m_regenTimer(2000), m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0), +m_gossipOptionLoaded(false), m_emoteState(0), m_isPet(false), m_isTotem(false), m_isVehicle(false), m_reactState(REACT_AGGRESSIVE), +m_defaultMovementType(IDLE_MOTION_TYPE), m_equipmentId(0),  m_AlreadyCallAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false),  m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),m_creatureInfo(NULL), m_DBTableGuid(0), m_formationID(0)  { +    m_regenTimer = 200;      m_valuesCount = UNIT_END;      for(int i =0; i<4; ++i) @@ -316,7 +317,6 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data )      // creatures always have melee weapon ready if any      SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); -    SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_AURAS );      SelectLevel(GetCreatureInfo());      if (team == HORDE) @@ -766,8 +766,11 @@ bool Creature::isCanInteractWithBattleMaster(Player* pPlayer, bool msg) const              case BATTLEGROUND_NA:              case BATTLEGROUND_BE:              case BATTLEGROUND_AA: -            case BATTLEGROUND_RL:  pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break; -            break; +            case BATTLEGROUND_RL: +            case BATTLEGROUND_SA: +            case BATTLEGROUND_DS: +            case BATTLEGROUND_RV: pPlayer->PlayerTalkClass->SendGossipMenu(10024,GetGUID()); break; +            default: break;          }          return false;      } @@ -1460,11 +1463,7 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)          if (force)          {              for (uint8 i = 0; i < 3; i++) -            { -                SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, 0); -                SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), 0); -                SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, 0); -            } +                SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);              m_equipmentId = 0;          }          return; @@ -1476,11 +1475,7 @@ void Creature::LoadEquipment(uint32 equip_entry, bool force)      m_equipmentId = equip_entry;      for (uint8 i = 0; i < 3; i++) -    { -        SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY + i, einfo->equipmodel[i]); -        SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2), einfo->equipinfo[i]); -        SetUInt32Value( UNIT_VIRTUAL_ITEM_INFO + (i * 2) + 1, einfo->equipslot[i]); -    } +        SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, einfo->equipentry[i]);  }  bool Creature::hasQuest(uint32 quest_id) const diff --git a/src/game/Creature.h b/src/game/Creature.h index 1ae41b86776..ff512fb5da0 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -244,9 +244,7 @@ struct NpcOptionLocale  struct EquipmentInfo  {      uint32  entry; -    uint32  equipmodel[3]; -    uint32  equipinfo[3]; -    uint32  equipslot[3]; +    uint32  equipentry[3];  };  // from `creature` table @@ -423,6 +421,7 @@ class TRINITY_DLL_SPEC Creature : public Unit          uint32 GetEquipmentId() const { return m_equipmentId; }          bool isPet() const { return m_isPet; } +        bool isVehicle() const { return m_isVehicle; }          void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }          bool isTotem() const { return m_isTotem; }          bool isRacialLeader() const { return GetCreatureInfo()->RacialLeader; } @@ -657,11 +656,11 @@ class TRINITY_DLL_SPEC Creature : public Unit          uint8 m_emoteState;          bool m_isPet;                                       // set only in Pet::Pet +        bool m_isVehicle;                                   // set only in Vehicle::Vehicle          bool m_isTotem;                                     // set only in Totem::Totem          ReactStates m_reactState;                           // for AI, not charmInfo          void RegenerateMana();          void RegenerateHealth(); -        uint32 m_regenTimer;          MovementGeneratorType m_defaultMovementType;          Cell m_currentCell;                                 // store current cell where creature listed          uint32 m_DBTableGuid;                               ///< For new or temporary creatures is 0 for saved it is lowguid diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp index d7badd57892..0dc69829728 100644 --- a/src/game/DynamicObject.cpp +++ b/src/game/DynamicObject.cpp @@ -38,7 +38,7 @@ DynamicObject::DynamicObject() : WorldObject()      m_objectType |= TYPEMASK_DYNAMICOBJECT;      m_objectTypeId = TYPEID_DYNAMICOBJECT;                                                              // 2.3.2 - 0x58 -    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); +    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);      m_valuesCount = DYNAMICOBJECT_END;  } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 28c39ee5bbe..53a7d36aef4 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -46,7 +46,7 @@ GameObject::GameObject() : WorldObject()      m_objectType |= TYPEMASK_GAMEOBJECT;      m_objectTypeId = TYPEID_GAMEOBJECT;                                                              // 2.3.2 - 0x58 -    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); +    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);      m_valuesCount = GAMEOBJECT_END;      m_respawnTime = 0; @@ -127,17 +127,33 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float      SetFloatValue(GAMEOBJECT_POS_Z, z);      SetFloatValue(GAMEOBJECT_FACING, ang);                  //this is not facing angle -    SetFloatValue (GAMEOBJECT_ROTATION, rotation0); -    SetFloatValue (GAMEOBJECT_ROTATION+1, rotation1); -    SetFloatValue (GAMEOBJECT_ROTATION+2, rotation2); -    SetFloatValue (GAMEOBJECT_ROTATION+3, rotation3); +    int64 rotation = 0; + +    float f_rot1 = sin(ang / 2.0f); +    int64 i_rot1 = f_rot1 / atan(pow(2.0f, -20.0f)); +    rotation |= (i_rot1 << 43 >> 43) & 0x00000000001FFFFF; + +    //float f_rot2 = sin(0.0f / 2.0f); +    //int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f)); +    //rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000; + +    //float f_rot3 = sin(0.0f / 2.0f); +    //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f)); +    //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000; + +    SetUInt64Value(GAMEOBJECT_ROTATION, rotation); + +    SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0); +    SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1); +    SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2); +    SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);      SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);      SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction);      SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); -    SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id); +    SetEntry(goinfo->id);      SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); @@ -146,8 +162,6 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float      SetGoAnimProgress(animprogress); -    SetUInt32Value (GAMEOBJECT_ARTKIT, ArtKit); -      // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)      if (goinfo->type == GAMEOBJECT_TYPE_SPELLCASTER)          m_charges = goinfo->spellcaster.charges; @@ -264,7 +278,7 @@ void GameObject::Update(uint32 /*p_time*/)                                  return;                              }                                                              // respawn timer -                            MapManager::Instance().GetMap(GetMapId(), this)->Add(this); +                            GetMap()->Add(this);                              break;                      }                  } @@ -414,7 +428,7 @@ void GameObject::Update(uint32 /*p_time*/)              //burning flags in some battlegrounds, if you find better condition, just add it              if (GetGoAnimProgress() > 0)              { -                SendObjectDeSpawnAnim(this->GetGUID()); +                SendObjectDeSpawnAnim(GetGUID());                  //reset flags                  SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);              } @@ -451,7 +465,7 @@ void GameObject::Refresh()          return;      if(isSpawned()) -        MapManager::Instance().GetMap(GetMapId(), this)->Add(this); +        GetMap()->Add(this);  }  void GameObject::AddUniqueUse(Player* player) @@ -504,7 +518,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)      if (!goI)          return; -     +      if (!m_DBTableGuid)          m_DBTableGuid = GetGUIDLow();      // update in loaded data (changing data only in this place) @@ -517,34 +531,33 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)      data.posY = GetFloatValue(GAMEOBJECT_POS_Y);      data.posZ = GetFloatValue(GAMEOBJECT_POS_Z);      data.orientation = GetFloatValue(GAMEOBJECT_FACING); -    data.rotation0 = GetFloatValue(GAMEOBJECT_ROTATION+0); -    data.rotation1 = GetFloatValue(GAMEOBJECT_ROTATION+1); -    data.rotation2 = GetFloatValue(GAMEOBJECT_ROTATION+2); -    data.rotation3 = GetFloatValue(GAMEOBJECT_ROTATION+3); +    data.rotation0 = GetFloatValue(GAMEOBJECT_PARENTROTATION+0); +    data.rotation1 = GetFloatValue(GAMEOBJECT_PARENTROTATION+1); +    data.rotation2 = GetFloatValue(GAMEOBJECT_PARENTROTATION+2); +    data.rotation3 = GetFloatValue(GAMEOBJECT_PARENTROTATION+3);      data.spawntimesecs = m_spawnedByDefault ? m_respawnDelayTime : -(int32)m_respawnDelayTime;      data.animprogress = GetGoAnimProgress();      data.go_state = GetGoState();      data.spawnMask = spawnMask; -    data.ArtKit = GetUInt32Value (GAMEOBJECT_ARTKIT);      // updated in DB      std::ostringstream ss;      ss << "INSERT INTO gameobject VALUES ( "          << m_DBTableGuid << ", " -        << GetUInt32Value (OBJECT_FIELD_ENTRY) << ", " +        << GetEntry() << ", "          << mapid << ", "          << (uint32)spawnMask << ", "          << GetFloatValue(GAMEOBJECT_POS_X) << ", "          << GetFloatValue(GAMEOBJECT_POS_Y) << ", "          << GetFloatValue(GAMEOBJECT_POS_Z) << ", "          << GetFloatValue(GAMEOBJECT_FACING) << ", " -        << GetFloatValue(GAMEOBJECT_ROTATION) << ", " -        << GetFloatValue(GAMEOBJECT_ROTATION+1) << ", " -        << GetFloatValue(GAMEOBJECT_ROTATION+2) << ", " -        << GetFloatValue(GAMEOBJECT_ROTATION+3) << ", " +        << GetFloatValue(GAMEOBJECT_PARENTROTATION) << ", " +        << GetFloatValue(GAMEOBJECT_PARENTROTATION+1) << ", " +        << GetFloatValue(GAMEOBJECT_PARENTROTATION+2) << ", " +        << GetFloatValue(GAMEOBJECT_PARENTROTATION+3) << ", "          << m_respawnDelayTime << ", " -        << GetGoAnimProgress() << ", " -        << GetGoState() << ")"; +        << (uint32)GetGoAnimProgress() << ", " +        << (uint32)GetGoState() << ")";      WorldDatabase.BeginTransaction();      WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); @@ -563,7 +576,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)      }      uint32 entry = data->id; -    uint32 map_id = data->mapid; +    //uint32 map_id = data->mapid;                          // already used before call      float x = data->posX;      float y = data->posY;      float z = data->posZ; @@ -576,12 +589,11 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)      uint32 animprogress = data->animprogress;      uint32 go_state = data->go_state; -    uint32 ArtKit = data->ArtKit;      m_DBTableGuid = guid;      if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); -    if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) ) +    if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) )          return false;      switch(GetGOInfo()->type) @@ -846,14 +858,6 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore)  } -void GameObject::SetGoArtKit(uint32 kit) -{ -    SetUInt32Value(GAMEOBJECT_ARTKIT, kit); -    GameObjectData *data = const_cast<GameObjectData*>(objmgr.GetGOData(m_DBTableGuid)); -    if(data) -        data->ArtKit = kit; -} -  void GameObject::SwitchDoorOrButton(bool activate)  {      if(activate) @@ -1209,7 +1213,7 @@ void GameObject::Use(Unit* user)              Player* player = (Player*)user; -            if( player->isAllowUseBattleGroundObject() )      +            if( player->isAllowUseBattleGroundObject() )              {                  // in battleground check                  BattleGround *bg = player->GetBattleGround(); @@ -1247,6 +1251,26 @@ void GameObject::Use(Unit* user)              }              break;          } +        case GAMEOBJECT_TYPE_BARBER_CHAIR:                  //32 +        { +            GameObjectInfo const* info = GetGOInfo(); +            if(!info) +                return; + +            if(user->GetTypeId()!=TYPEID_PLAYER) +                return; + +            Player* player = (Player*)user; + +            // fallback, will always work +            player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); + +            WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0); +            player->GetSession()->SendPacket(&data); + +            player->SetStandState(PLAYER_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight); +            return; +        }          default:              sLog.outDebug("Unknown Object Type %u", GetGoType());              break; diff --git a/src/game/GameObject.h b/src/game/GameObject.h index afeaba98cc9..9a570eb54da 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -336,12 +336,12 @@ struct GameObjectInfo              uint32 mapID;                                   //0              uint32 difficulty;                              //1          } dungeonDifficulty; -        //32 GAMEOBJECT_TYPE_DO_NOT_USE_YET +        //32 GAMEOBJECT_TYPE_BARBER_CHAIR          struct          { -            uint32 mapID;                                   //0 -            uint32 difficulty;                              //1 -        } doNotUseYet; +            uint32 chairheight;                             //0 +            uint32 heightOffset;                            //1 +        } barberChair;          //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING          struct          { @@ -350,6 +350,13 @@ struct GameObjectInfo              uint32 state1Name;                              //2              uint32 state2Name;                              //3          } destructibleBuilding; +        //34 GAMEOBJECT_TYPE_TRAPDOOR +        struct   +        { +            uint32 whenToPause;                             // 0 +            uint32 startOpen;                               // 1 +            uint32 autoClose;                               // 2 +        } trapDoor;          // not use for specific field access (only for output with loop by all filed), also this determinate max union size          struct                                              // GAMEOBJECT_TYPE_SPELLCASTER @@ -504,14 +511,14 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject          void SetSpellId(uint32 id) { m_spellId = id;}          uint32 GetSpellId() const { return m_spellId;}          void getFishLoot(Loot *loot); -        GameobjectTypes GetGoType() const { return GameobjectTypes(GetUInt32Value(GAMEOBJECT_TYPE_ID)); } -        void SetGoType(GameobjectTypes type) { SetUInt32Value(GAMEOBJECT_TYPE_ID, type); } -        uint32 GetGoState() const { return GetUInt32Value(GAMEOBJECT_STATE); } -        void SetGoState(uint32 state) { SetUInt32Value(GAMEOBJECT_STATE, state); } -        uint32 GetGoArtKit() const { return GetUInt32Value(GAMEOBJECT_ARTKIT); } -        void SetGoArtKit(uint32 artkit); -        uint32 GetGoAnimProgress() const { return GetUInt32Value(GAMEOBJECT_ANIMPROGRESS); } -        void SetGoAnimProgress(uint32 animprogress) { SetUInt32Value(GAMEOBJECT_ANIMPROGRESS, animprogress); } +        GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); } +        void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); } +        uint8 GetGoState() const { return GetByteValue(GAMEOBJECT_BYTES_1, 0); } +        void SetGoState(uint8 state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); } +        uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); } +        void SetGoArtKit(uint8 artkit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, artkit); } +        uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); } +        void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }          void Use(Unit* user); diff --git a/src/game/GossipDef.cpp b/src/game/GossipDef.cpp index 85414fa3372..90aa7304c90 100644 --- a/src/game/GossipDef.cpp +++ b/src/game/GossipDef.cpp @@ -417,10 +417,14 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID      }      data << uint64(npcGUID); +    data << uint64(0);                                      // wotlk, something todo with quest sharing?      data << uint32(pQuest->GetQuestId()); -    data << Title << Details << Objectives; +    data << Title; +    data << Details; +    data << Objectives;      data << uint32(ActivateAccept);      data << uint32(pQuest->GetSuggestedPlayers()); +    data << uint8(0);                                       // new wotlk      if (pQuest->HasFlag(QUEST_FLAGS_HIDDEN_REWARDS))      { @@ -466,6 +470,7 @@ void PlayerMenu::SendQuestGiverQuestDetails( Quest const *pQuest, uint64 npcGUID      data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)      data << uint32(pQuest->GetRewSpellCast());              // casted spell      data << uint32(pQuest->GetCharTitleId());               // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) +    data << uint32(pQuest->GetBonusTalents());              // bonus talents      data << uint32(QUEST_EMOTE_COUNT);      for (uint32 i=0; i < QUEST_EMOTE_COUNT; i++) @@ -542,6 +547,8 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )      data << uint32(pQuest->GetSrcItemId());      data << uint32(pQuest->GetFlags() & 0xFFFF);      data << uint32(pQuest->GetCharTitleId());               // CharTitleId, new 2.4.0, player gets this title (id from CharTitles) +    data << uint32(pQuest->GetPlayersSlain());              // players slain +    data << uint32(pQuest->GetBonusTalents());              // bonus talents      int iI; @@ -590,13 +597,14 @@ void PlayerMenu::SendQuestQueryResponse( Quest const *pQuest )          data << uint32(pQuest->ReqCreatureOrGOCount[iI]);          data << uint32(pQuest->ReqItemId[iI]);          data << uint32(pQuest->ReqItemCount[iI]); +        data << uint32(0);                                  // added in WotLK, dunno if offset if correct      }      for (iI = 0; iI < QUEST_OBJECTIVES_COUNT; iI++)          data << ObjectiveText[iI];      pSession->SendPacket( &data ); -    sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u",pQuest->GetQuestId() ); +    sLog.outDebug( "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid=%u", pQuest->GetQuestId() );  }  void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID, bool EnbleNext ) @@ -678,9 +686,10 @@ void PlayerMenu::SendQuestGiverOfferReward( Quest const* pQuest, uint64 npcGUID,      data << uint32(0x08);                                   // unused by client?      data << uint32(pQuest->GetRewSpell());                  // reward spell, this spell will display (icon) (casted if RewSpellCast==0)      data << uint32(pQuest->GetRewSpellCast());              // casted spell -    data << uint32(0x00);                                   // unk, NOT honor +    data << uint32(0);                                      // unknown +    data << uint32(pQuest->GetBonusTalents());              // bonus talents      pSession->SendPacket( &data ); -    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u",GUID_LOPART(npcGUID),pQuest->GetQuestId() ); +    sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPCGuid=%u, questid=%u", GUID_LOPART(npcGUID), pQuest->GetQuestId() );  }  void PlayerMenu::SendQuestGiverRequestItems( Quest const *pQuest, uint64 npcGUID, bool Completable, bool CloseOnCancel ) diff --git a/src/game/GridNotifiers.cpp b/src/game/GridNotifiers.cpp index 0c952f69649..b69e185c171 100644 --- a/src/game/GridNotifiers.cpp +++ b/src/game/GridNotifiers.cpp @@ -140,7 +140,7 @@ VisibleNotifier::Notify()      // send data at target visibility change (adding to client)      for(std::set<WorldObject*>::const_iterator vItr = i_visibleNow.begin(); vItr != i_visibleNow.end(); ++vItr)          if((*vItr)!=&i_player && (*vItr)->isType(TYPEMASK_UNIT)) -            i_player.SendAuraDurationsForTarget((Unit*)(*vItr)); +            i_player.SendAurasForTarget((Unit*)(*vItr));  }  void  diff --git a/src/game/Group.h b/src/game/Group.h index 8417a145268..5edc99f8c0c 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -66,24 +66,25 @@ enum GroupUpdateFlags  {      GROUP_UPDATE_FLAG_NONE              = 0x00000000,       // nothing      GROUP_UPDATE_FLAG_STATUS            = 0x00000001,       // uint16, flags -    GROUP_UPDATE_FLAG_CUR_HP            = 0x00000002,       // uint16 -    GROUP_UPDATE_FLAG_MAX_HP            = 0x00000004,       // uint16 +    GROUP_UPDATE_FLAG_CUR_HP            = 0x00000002,       // uint32 +    GROUP_UPDATE_FLAG_MAX_HP            = 0x00000004,       // uint32      GROUP_UPDATE_FLAG_POWER_TYPE        = 0x00000008,       // uint8      GROUP_UPDATE_FLAG_CUR_POWER         = 0x00000010,       // uint16      GROUP_UPDATE_FLAG_MAX_POWER         = 0x00000020,       // uint16      GROUP_UPDATE_FLAG_LEVEL             = 0x00000040,       // uint16      GROUP_UPDATE_FLAG_ZONE              = 0x00000080,       // uint16      GROUP_UPDATE_FLAG_POSITION          = 0x00000100,       // uint16, uint16 -    GROUP_UPDATE_FLAG_AURAS             = 0x00000200,       // uint64 mask, for each bit set uint16 spellid + uint8 unk +    GROUP_UPDATE_FLAG_AURAS             = 0x00000200,       // uint64 mask, for each bit set uint32 spellid + uint8 unk      GROUP_UPDATE_FLAG_PET_GUID          = 0x00000400,       // uint64 pet guid      GROUP_UPDATE_FLAG_PET_NAME          = 0x00000800,       // pet name, NULL terminated string      GROUP_UPDATE_FLAG_PET_MODEL_ID      = 0x00001000,       // uint16, model id -    GROUP_UPDATE_FLAG_PET_CUR_HP        = 0x00002000,       // uint16 pet cur health -    GROUP_UPDATE_FLAG_PET_MAX_HP        = 0x00004000,       // uint16 pet max health +    GROUP_UPDATE_FLAG_PET_CUR_HP        = 0x00002000,       // uint32 pet cur health +    GROUP_UPDATE_FLAG_PET_MAX_HP        = 0x00004000,       // uint32 pet max health      GROUP_UPDATE_FLAG_PET_POWER_TYPE    = 0x00008000,       // uint8 pet power type      GROUP_UPDATE_FLAG_PET_CUR_POWER     = 0x00010000,       // uint16 pet cur power      GROUP_UPDATE_FLAG_PET_MAX_POWER     = 0x00020000,       // uint16 pet max power -    GROUP_UPDATE_FLAG_PET_AURAS         = 0x00040000,       // uint64 mask, for each bit set uint16 spellid + uint8 unk, pet auras... +    GROUP_UPDATE_FLAG_PET_AURAS         = 0x00040000,       // uint64 mask, for each bit set uint32 spellid + uint8 unk, pet auras... +    GROUP_UPDATE_FLAG_VEHICLE_SEAT      = 0x00080000,       // uint32 vehicle_seat_id (index from VehicleSeat.dbc)      GROUP_UPDATE_PET                    = 0x0007FC00,       // all pet flags      GROUP_UPDATE_FULL                   = 0x0007FFFF,       // all known flags  }; diff --git a/src/game/GroupHandler.cpp b/src/game/GroupHandler.cpp index 3890a9f77a6..9f807c2b525 100644 --- a/src/game/GroupHandler.cpp +++ b/src/game/GroupHandler.cpp @@ -162,6 +162,7 @@ void WorldSession::HandleGroupInviteOpcode( WorldPacket & recv_data )      // ok, we do it      WorldPacket data(SMSG_GROUP_INVITE, 10);                // guess size +    data << uint8(1);                                       // ok      data << GetPlayer()->GetName();      player->GetSession()->SendPacket(&data); @@ -688,10 +689,10 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke      }      if (mask & GROUP_UPDATE_FLAG_CUR_HP) -        *data << (uint16) player->GetHealth(); +        *data << (uint32) player->GetHealth();      if (mask & GROUP_UPDATE_FLAG_MAX_HP) -        *data << (uint16) player->GetMaxHealth(); +        *data << (uint32) player->GetMaxHealth();      Powers powerType = player->getPowerType();      if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) @@ -720,7 +721,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke          {              if(auramask & (uint64(1) << i))              { -                *data << uint16(player->GetUInt32Value(UNIT_FIELD_AURA + i)); +                *data << uint32(player->GetVisibleAura(i));                  *data << uint8(1);              }          } @@ -754,17 +755,17 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke      if (mask & GROUP_UPDATE_FLAG_PET_CUR_HP)      {          if(pet) -            *data << (uint16) pet->GetHealth(); +            *data << (uint32) pet->GetHealth();          else -            *data << (uint16) 0; +            *data << (uint32) 0;      }      if (mask & GROUP_UPDATE_FLAG_PET_MAX_HP)      {          if(pet) -            *data << (uint16) pet->GetMaxHealth(); +            *data << (uint32) pet->GetMaxHealth();          else -            *data << (uint16) 0; +            *data << (uint32) 0;      }      if (mask & GROUP_UPDATE_FLAG_PET_POWER_TYPE) @@ -801,7 +802,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player *player, WorldPacke              {                  if(auramask & (uint64(1) << i))                  { -                    *data << uint16(pet->GetUInt32Value(UNIT_FIELD_AURA + i)); +                    *data << uint32(pet->GetVisibleAura(i));                      *data << uint8(1);                  }              } @@ -824,6 +825,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )      if(!player)      {          WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 3+4+2); +        data << uint8(0);                                   // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related          data.appendPackGUID(Guid);          data << (uint32) GROUP_UPDATE_FLAG_STATUS;          data << (uint16) MEMBER_STATUS_OFFLINE; @@ -834,6 +836,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )      Pet *pet = player->GetPet();      WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); +    data << uint8(0);                                       // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related      data.append(player->GetPackGUID());      uint32 mask1 = 0x00040BFF;                              // common mask, real flags used 0x000040BFF @@ -843,8 +846,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )      Powers powerType = player->getPowerType();      data << (uint32) mask1;                                 // group update mask      data << (uint16) MEMBER_STATUS_ONLINE;                  // member's online status -    data << (uint16) player->GetHealth();                   // GROUP_UPDATE_FLAG_CUR_HP -    data << (uint16) player->GetMaxHealth();                // GROUP_UPDATE_FLAG_MAX_HP +    data << (uint32) player->GetHealth();                   // GROUP_UPDATE_FLAG_CUR_HP +    data << (uint32) player->GetMaxHealth();                // GROUP_UPDATE_FLAG_MAX_HP      data << (uint8)  powerType;                             // GROUP_UPDATE_FLAG_POWER_TYPE      data << (uint16) player->GetPower(powerType);           // GROUP_UPDATE_FLAG_CUR_POWER      data << (uint16) player->GetMaxPower(powerType);        // GROUP_UPDATE_FLAG_MAX_POWER @@ -858,11 +861,11 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )      data << (uint64) auramask;                              // placeholder      for(uint8 i = 0; i < MAX_AURAS; ++i)      { -        if(uint32 aura = player->GetUInt32Value(UNIT_FIELD_AURA + i)) +        if(uint32 aura = player->GetVisibleAura(i))          {              auramask |= (uint64(1) << i); -            data << uint16(aura); -            data << uint8(1); +            data << (uint32) aura; +            data << (uint8)  1;          }      }      data.put<uint64>(maskPos,auramask);                     // GROUP_UPDATE_FLAG_AURAS @@ -873,8 +876,8 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )          data << (uint64) pet->GetGUID();                    // GROUP_UPDATE_FLAG_PET_GUID          data << pet->GetName();                             // GROUP_UPDATE_FLAG_PET_NAME          data << (uint16) pet->GetDisplayId();               // GROUP_UPDATE_FLAG_PET_MODEL_ID -        data << (uint16) pet->GetHealth();                  // GROUP_UPDATE_FLAG_PET_CUR_HP -        data << (uint16) pet->GetMaxHealth();               // GROUP_UPDATE_FLAG_PET_MAX_HP +        data << (uint32) pet->GetHealth();                  // GROUP_UPDATE_FLAG_PET_CUR_HP +        data << (uint32) pet->GetMaxHealth();               // GROUP_UPDATE_FLAG_PET_MAX_HP          data << (uint8)  petpowertype;                      // GROUP_UPDATE_FLAG_PET_POWER_TYPE          data << (uint16) pet->GetPower(petpowertype);       // GROUP_UPDATE_FLAG_PET_CUR_POWER          data << (uint16) pet->GetMaxPower(petpowertype);    // GROUP_UPDATE_FLAG_PET_MAX_POWER @@ -884,10 +887,10 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode( WorldPacket &recv_data )          data << (uint64) petauramask;                       // placeholder          for(uint8 i = 0; i < MAX_AURAS; ++i)          { -            if(uint32 petaura = pet->GetUInt32Value(UNIT_FIELD_AURA + i)) +            if(uint32 petaura = pet->GetVisibleAura(i))              {                  petauramask |= (uint64(1) << i); -                data << (uint16) petaura; +                data << (uint32) petaura;                  data << (uint8)  1;              }          } diff --git a/src/game/Guild.cpp b/src/game/Guild.cpp index 897110afe55..a34d4bee524 100644 --- a/src/game/Guild.cpp +++ b/src/game/Guild.cpp @@ -785,6 +785,7 @@ void Guild::Query(WorldSession *session)      data << uint32(BorderStyle);      data << uint32(BorderColor);      data << uint32(BackgroundColor); +    data << uint32(0);                                      // something new in WotLK      session->SendPacket( &data );      sLog.outDebug( "WORLD: Sent (SMSG_GUILD_QUERY_RESPONSE)" ); @@ -1212,18 +1213,19 @@ void Guild::LoadGuildBankFromDB()      delete result; -    //                                        0      1       2          3 -    result = CharacterDatabase.PQuery("SELECT TabId, SlotId, item_guid, item_entry FROM guild_bank_item WHERE guildid='%u' ORDER BY TabId", Id); +    // data needs to be at first place for Item::LoadFromDB +    //                                        0     1      2       3          4 +    result = CharacterDatabase.PQuery("SELECT data, TabId, SlotId, item_guid, item_entry FROM guild_bank_item JOIN item_instance ON item_guid = guid WHERE guildid='%u' ORDER BY TabId", Id);      if(!result)          return;      do      {          Field *fields = result->Fetch(); -        uint8 TabId = fields[0].GetUInt8(); -        uint8 SlotId = fields[1].GetUInt8(); -        uint32 ItemGuid = fields[2].GetUInt32(); -        uint32 ItemEntry = fields[3].GetUInt32(); +        uint8 TabId = fields[1].GetUInt8(); +        uint8 SlotId = fields[2].GetUInt8(); +        uint32 ItemGuid = fields[3].GetUInt32(); +        uint32 ItemEntry = fields[4].GetUInt32();          if (TabId >= purchased_tabs || TabId >= GUILD_BANK_MAX_TABS)          { @@ -1246,7 +1248,7 @@ void Guild::LoadGuildBankFromDB()          }          Item *pItem = NewItemOrBag(proto); -        if(!pItem->LoadFromDB(ItemGuid, 0)) +        if(!pItem->LoadFromDB(ItemGuid, 0, result))          {              CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE guildid='%u' AND TabId='%u' AND SlotId='%u'", Id, uint32(TabId), uint32(SlotId));              sLog.outError("Item GUID %u not found in item_instance, deleting from Guild Bank!", ItemGuid); @@ -1602,7 +1604,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)          {              data << uint8((*itr)->LogEntry);              data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); -            data << uint32((*itr)->ItemOrMoney); +            if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||  +                (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || +                (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || +                (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 || +                (*itr)->LogEntry == GUILD_BANK_LOG_UNK2) +            { +                data << uint32((*itr)->ItemOrMoney); +            } +            else +            { +                data << uint32((*itr)->ItemOrMoney); +                data << uint32((*itr)->ItemStackCount); +                if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) +                    data << uint8((*itr)->DestTabId);       // moved tab +            }              data << uint32(time(NULL)-(*itr)->TimeStamp);          }          session->SendPacket(&data); @@ -1618,10 +1634,21 @@ void Guild::DisplayGuildBankLogs(WorldSession *session, uint8 TabId)          {              data << uint8((*itr)->LogEntry);              data << uint64(MAKE_NEW_GUID((*itr)->PlayerGuid,0,HIGHGUID_PLAYER)); -            data << uint32((*itr)->ItemOrMoney); -            data << uint8((*itr)->ItemStackCount); -            if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) -                data << uint8((*itr)->DestTabId);           // moved tab +            if ((*itr)->LogEntry == GUILD_BANK_LOG_DEPOSIT_MONEY ||  +                (*itr)->LogEntry == GUILD_BANK_LOG_WITHDRAW_MONEY || +                (*itr)->LogEntry == GUILD_BANK_LOG_REPAIR_MONEY || +                (*itr)->LogEntry == GUILD_BANK_LOG_UNK1 || +                (*itr)->LogEntry == GUILD_BANK_LOG_UNK2) +            { +                data << uint32((*itr)->ItemOrMoney); +            } +            else +            { +                data << uint32((*itr)->ItemOrMoney); +                data << uint32((*itr)->ItemStackCount); +                if ((*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM || (*itr)->LogEntry == GUILD_BANK_LOG_MOVE_ITEM2) +                    data << uint8((*itr)->DestTabId);       // moved tab +            }              data << uint32(time(NULL)-(*itr)->TimeStamp);          }          session->SendPacket(&data); @@ -1703,7 +1730,7 @@ void Guild::AppendDisplayGuildBankSlot( WorldPacket& data, GuildBankTab const *t              // SuffixFactor +4              data << (uint32) pItem->GetItemSuffixFactor();          // +12 // ITEM_FIELD_STACK_COUNT -        data << uint8(pItem->GetCount()); +        data << uint32(pItem->GetCount());          data << uint32(0);                                  // +16 // Unknown value          data << uint8(0);                                   // unknown 2.4.2          if (uint32 Enchant0 = pItem->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)) diff --git a/src/game/Guild.h b/src/game/Guild.h index 683ff980e3a..f51ba5a6d27 100644 --- a/src/game/Guild.h +++ b/src/game/Guild.h @@ -56,7 +56,8 @@ enum GuildRankRights      GR_RIGHT_REPAIR_FROM_GUILD  = 0x00020000,               // unused in 2.4.x?, Remove money withdraw capacity      GR_RIGHT_WITHDRAW_REPAIR    = 0x00040000,               // withdraw for repair      GR_RIGHT_WITHDRAW_GOLD      = 0x00080000,               // withdraw gold -    GR_RIGHT_ALL                = 0x000FF1FF +    GR_RIGHT_CREATE_GUILD_EVENT = 0x00100000,               // wotlk +    GR_RIGHT_ALL                = 0x001FF1FF  };  enum Typecommand @@ -156,6 +157,8 @@ enum GuildBankLogEntries      GUILD_BANK_LOG_WITHDRAW_MONEY   = 5,      GUILD_BANK_LOG_REPAIR_MONEY     = 6,      GUILD_BANK_LOG_MOVE_ITEM2       = 7, +    GUILD_BANK_LOG_UNK1             = 8, +    GUILD_BANK_LOG_UNK2             = 9,  };  enum GuildEventLogEntryTypes diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 0c264a76d8b..8b4b124669e 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -206,6 +206,10 @@ bool ItemCanGoIntoBag(ItemPrototype const *pProto, ItemPrototype const *pBagProt                      if(!(pProto->BagFamily & BAG_FAMILY_MASK_LEATHERWORKING_SUPP))                          return false;                      return true; +                case ITEM_SUBCLASS_INSCRIPTION_CONTAINER: +                    if(!(pProto->BagFamily & BAG_FAMILY_MASK_INSCRIPTION_SUPP)) +                        return false; +                    return true;                  default:                      return false;              } @@ -450,7 +454,7 @@ uint32 Item::GetSkill()      const static uint32 item_armor_skills[MAX_ITEM_SUBCLASS_ARMOR] =      { -        0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0 +        0,SKILL_CLOTH,SKILL_LEATHER,SKILL_MAIL,SKILL_PLATE_MAIL,0,SKILL_SHIELD,0,0,0,0      };      ItemPrototype const* proto = GetProto(); @@ -765,9 +769,9 @@ void Item::SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint      if((GetEnchantmentId(slot) == id) && (GetEnchantmentDuration(slot) == duration) && (GetEnchantmentCharges(slot) == charges))          return; -    SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); -    SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); -    SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); +    SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET,id); +    SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); +    SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);      SetState(ITEM_CHANGED);  } @@ -776,7 +780,7 @@ void Item::SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration)      if(GetEnchantmentDuration(slot) == duration)          return; -    SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration); +    SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET,duration);      SetState(ITEM_CHANGED);  } @@ -785,7 +789,7 @@ void Item::SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges)      if(GetEnchantmentCharges(slot) == charges)          return; -    SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges); +    SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET,charges);      SetState(ITEM_CHANGED);  } @@ -795,7 +799,7 @@ void Item::ClearEnchantment(EnchantmentSlot slot)          return;      for(uint8 x = 0; x < 3; ++x) -        SetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + x, 0); +        SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + x, 0);      SetState(ITEM_CHANGED);  } diff --git a/src/game/Item.h b/src/game/Item.h index 72c09b0c1da..4be1d42a32a 100644 --- a/src/game/Item.h +++ b/src/game/Item.h @@ -148,29 +148,30 @@ enum SellFailure  // -1 from client enchantment slot number  enum EnchantmentSlot  { -    PERM_ENCHANTMENT_SLOT       = 0, -    TEMP_ENCHANTMENT_SLOT       = 1, -    SOCK_ENCHANTMENT_SLOT       = 2, -    SOCK_ENCHANTMENT_SLOT_2     = 3, -    SOCK_ENCHANTMENT_SLOT_3     = 4, -    BONUS_ENCHANTMENT_SLOT      = 5, -    MAX_INSPECTED_ENCHANTMENT_SLOT = 6, - -    PROP_ENCHANTMENT_SLOT_0     = 6,                        // used with RandomSuffix -    PROP_ENCHANTMENT_SLOT_1     = 7,                        // used with RandomSuffix -    PROP_ENCHANTMENT_SLOT_2     = 8,                        // used with RandomSuffix and RandomProperty -    PROP_ENCHANTMENT_SLOT_3     = 9,                        // used with RandomProperty -    PROP_ENCHANTMENT_SLOT_4     = 10,                       // used with RandomProperty -    MAX_ENCHANTMENT_SLOT        = 11 +    PERM_ENCHANTMENT_SLOT           = 0, +    TEMP_ENCHANTMENT_SLOT           = 1, +    SOCK_ENCHANTMENT_SLOT           = 2, +    SOCK_ENCHANTMENT_SLOT_2         = 3, +    SOCK_ENCHANTMENT_SLOT_3         = 4, +    BONUS_ENCHANTMENT_SLOT          = 5, +    WOTLK_ENCHANTMENT_SLOT          = 6, +    MAX_INSPECTED_ENCHANTMENT_SLOT  = 7, + +    PROP_ENCHANTMENT_SLOT_0         = 7,                    // used with RandomSuffix +    PROP_ENCHANTMENT_SLOT_1         = 8,                    // used with RandomSuffix +    PROP_ENCHANTMENT_SLOT_2         = 9,                    // used with RandomSuffix and RandomProperty +    PROP_ENCHANTMENT_SLOT_3         = 10,                   // used with RandomProperty +    PROP_ENCHANTMENT_SLOT_4         = 11,                   // used with RandomProperty +    MAX_ENCHANTMENT_SLOT            = 12  }; -#define MAX_VISIBLE_ITEM_OFFSET   16                        // 16 fields per visible item (creator(2) + enchantments(12) + properties(1) + pad(1)) +#define MAX_VISIBLE_ITEM_OFFSET       18                    // 18 fields per visible item (creator(2) + enchantments(13) + properties(1) + seed(1) + pad(1))  enum EnchantmentOffset  {      ENCHANTMENT_ID_OFFSET       = 0,      ENCHANTMENT_DURATION_OFFSET = 1, -    ENCHANTMENT_CHARGES_OFFSET  = 2 +    ENCHANTMENT_CHARGES_OFFSET  = 2                         // now here not only charges, but something new in wotlk  };  #define MAX_ENCHANTMENT_OFFSET    3 @@ -211,6 +212,7 @@ class TRINITY_DLL_SPEC Item : public Object          void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS,ITEM_FLAGS_BINDED,val); }          bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BINDED); } +        bool IsAccountBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_BOA); }          bool IsBindedNotWith(uint64 guid) const { return IsSoulBound() && GetOwnerGUID()!= guid; }          bool IsBoundByEnchant() const;          virtual void SaveToDB(); @@ -256,9 +258,9 @@ class TRINITY_DLL_SPEC Item : public Object          void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration);          void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges);          void ClearEnchantment(EnchantmentSlot slot); -        uint32 GetEnchantmentId(EnchantmentSlot slot)       const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);} -        uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);} -        uint32 GetEnchantmentCharges(EnchantmentSlot slot)  const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);} +        uint32 GetEnchantmentId(EnchantmentSlot slot)       const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_ID_OFFSET);} +        uint32 GetEnchantmentDuration(EnchantmentSlot slot) const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_DURATION_OFFSET);} +        uint32 GetEnchantmentCharges(EnchantmentSlot slot)  const { return GetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1 + slot*MAX_ENCHANTMENT_OFFSET + ENCHANTMENT_CHARGES_OFFSET);}          void SendTimeUpdate(Player* owner);          void UpdateDuration(Player* owner, uint32 diff); diff --git a/src/game/ItemHandler.cpp b/src/game/ItemHandler.cpp index 085c9553a30..3437495bc48 100644 --- a/src/game/ItemHandler.cpp +++ b/src/game/ItemHandler.cpp @@ -324,7 +324,7 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )          data << pProto->ItemId;          data << pProto->Class;          data << pProto->SubClass; -        data << uint32(-1);                                 // new 2.0.3, not exist in wdb cache? +        data << pProto->Unk0;                               // new 2.0.3, not exist in wdb cache?          data << Name;          data << uint8(0x00);                                //pProto->Name2; // blizz not send name there, just uint8(0x00); <-- \0 = empty string = empty name...          data << uint8(0x00);                                //pProto->Name3; // blizz not send name there, just uint8(0x00); @@ -349,11 +349,14 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )          data << pProto->MaxCount;          data << pProto->Stackable;          data << pProto->ContainerSlots; -        for(int i = 0; i < 10; i++) +        data << pProto->StatsCount;                         // item stats count +        for(int i = 0; i < pProto->StatsCount; i++)          {              data << pProto->ItemStat[i].ItemStatType;              data << pProto->ItemStat[i].ItemStatValue;          } +        data << pProto->ScalingStatDistribution;            // scaling stats distribution +        data << pProto->ScalingStatValue;                   // some kind of flags used to determine stat values column          for(int i = 0; i < 5; i++)          {              data << pProto->Damage[i].DamageMin; @@ -437,7 +440,8 @@ void WorldSession::HandleItemQuerySingleOpcode( WorldPacket & recv_data )          data << pProto->GemProperties;          data << pProto->RequiredDisenchantSkill;          data << pProto->ArmorDamageModifier; -        data << uint32(0);                                  // added in 2.4.2.8209, duration (seconds) +        data << pProto->Duration;                           // added in 2.4.2.8209, duration (seconds) +        data << pProto->ItemLimitCategory;                  // WotLK, ItemLimitCategory          SendPacket( &data );      }      else @@ -845,6 +849,7 @@ void WorldSession::HandleBuyBankSlotOpcode(WorldPacket& /*recvPacket*/)      if (_player->GetMoney() < price)          return; +    _player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT, slot);      _player->SetByteValue(PLAYER_BYTES_2, 2, slot);      _player->ModifyMoney(-int32(price));  } diff --git a/src/game/ItemPrototype.h b/src/game/ItemPrototype.h index 1ca412d246a..60c92ad2d70 100644 --- a/src/game/ItemPrototype.h +++ b/src/game/ItemPrototype.h @@ -57,10 +57,18 @@ enum ItemModType      ITEM_MOD_CRIT_TAKEN_RATING        = 34,      ITEM_MOD_RESILIENCE_RATING        = 35,      ITEM_MOD_HASTE_RATING             = 36, -    ITEM_MOD_EXPERTISE_RATING         = 37 +    ITEM_MOD_EXPERTISE_RATING         = 37, +    ITEM_MOD_ATTACK_POWER             = 38, +    ITEM_MOD_RANGED_ATTACK_POWER      = 39, +    ITEM_MOD_FERAL_ATTACK_POWER       = 40, +    ITEM_MOD_SPELL_HEALING_DONE       = 41, +    ITEM_MOD_SPELL_DAMAGE_DONE        = 42, +    ITEM_MOD_MANA_REGENERATION        = 43, +    ITEM_MOD_ARMOR_PENETRATION_RATING = 44, +    ITEM_MOD_SPELL_POWER              = 45  }; -#define MAX_ITEM_MOD                    38 +#define MAX_ITEM_MOD                    46  enum ItemSpelltriggerType  { @@ -185,10 +193,11 @@ enum ItemClass      ITEM_CLASS_QUEST                            = 12,      ITEM_CLASS_KEY                              = 13,      ITEM_CLASS_PERMANENT                        = 14, -    ITEM_CLASS_JUNK                             = 15 +    ITEM_CLASS_MISC                             = 15, +    ITEM_CLASS_GLYPH                            = 16  }; -#define MAX_ITEM_CLASS                            16 +#define MAX_ITEM_CLASS                            17  enum ItemSubclassConsumable  { @@ -214,10 +223,11 @@ enum ItemSubclassContainer      ITEM_SUBCLASS_ENGINEERING_CONTAINER         = 4,      ITEM_SUBCLASS_GEM_CONTAINER                 = 5,      ITEM_SUBCLASS_MINING_CONTAINER              = 6, -    ITEM_SUBCLASS_LEATHERWORKING_CONTAINER      = 7 +    ITEM_SUBCLASS_LEATHERWORKING_CONTAINER      = 7, +    ITEM_SUBCLASS_INSCRIPTION_CONTAINER         = 8  }; -#define MAX_ITEM_SUBCLASS_CONTAINER               8 +#define MAX_ITEM_SUBCLASS_CONTAINER               9  enum ItemSubclassWeapon  { @@ -272,10 +282,11 @@ enum ItemSubclassArmor      ITEM_SUBCLASS_ARMOR_SHIELD                  = 6,      ITEM_SUBCLASS_ARMOR_LIBRAM                  = 7,      ITEM_SUBCLASS_ARMOR_IDOL                    = 8, -    ITEM_SUBCLASS_ARMOR_TOTEM                   = 9 +    ITEM_SUBCLASS_ARMOR_TOTEM                   = 9, +    ITEM_SUBCLASS_ARMOR_SIGIL                   = 10  }; -#define MAX_ITEM_SUBCLASS_ARMOR                   10 +#define MAX_ITEM_SUBCLASS_ARMOR                   11  enum ItemSubclassReagent  { @@ -310,10 +321,12 @@ enum ItemSubclassTradeGoods      ITEM_SUBCLASS_ELEMENTAL                     = 10,      ITEM_SUBCLASS_TRADE_GOODS_OTHER             = 11,      ITEM_SUBCLASS_ENCHANTING                    = 12, -    ITEM_SUBCLASS_MATERIAL                      = 13        // Added in 2.4.2 +    ITEM_SUBCLASS_MATERIAL                      = 13, +    ITEM_SUBCLASS_ARMOR_ENCHANTMENT             = 14, +    ITEM_SUBCLASS_WEAPON_ENCHANTMENT            = 15  }; -#define MAX_ITEM_SUBCLASS_TRADE_GOODS             14 +#define MAX_ITEM_SUBCLASS_TRADE_GOODS             16  enum ItemSubclassGeneric  { @@ -423,7 +436,8 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] =      MAX_ITEM_SUBCLASS_QUEST,      MAX_ITEM_SUBCLASS_KEY,      MAX_ITEM_SUBCLASS_PERMANENT, -    MAX_ITEM_SUBCLASS_JUNK +    MAX_ITEM_SUBCLASS_JUNK, +    MAX_ITEM_SUBCLASS_GLYPH  };  inline uint8 ItemSubClassToDurabilityMultiplierId(uint32 ItemClass, uint32 ItemSubClass) @@ -500,7 +514,10 @@ struct ItemPrototype      uint32 MaxCount;      uint32 Stackable;      uint32 ContainerSlots; +    uint32 StatsCount;      _ItemStat ItemStat[10]; +    uint32 ScalingStatDistribution;                         // id from ScalingStatDistribution.dbc +    uint32 ScalingStatValue;                                // mask for selecting column in ScalingStatValues.dbc      _Damage Damage[5];      uint32 Armor;      uint32 HolyRes; @@ -536,12 +553,13 @@ struct ItemPrototype      uint32 GemProperties;                                   // id from GemProperties.dbc      uint32 RequiredDisenchantSkill;      float  ArmorDamageModifier; +    int32  Duration;                                        // negative = realtime, positive = ingame time +    uint32 ItemLimitCategory;                               // id from ItemLimitCategory.dbc      uint32 ScriptId;      uint32 DisenchantID;      uint32 FoodType;      uint32 MinMoneyLoot;      uint32 MaxMoneyLoot; -    int32 Duration;                                         // negative = realtime, positive = ingame time      // helpers      bool CanChangeEquipStateInCombat() const @@ -563,6 +581,46 @@ struct ItemPrototype          return false;      } + +    uint32 GetScalingStatValuesColumn() const +    { +        if(ScalingStatValue & 0x00000001)                   // stat mod +            return 0; +        if(ScalingStatValue & 0x00000002)                   // stat mod +            return 1; +        if(ScalingStatValue & 0x00000004)                   // stat mod +            return 2; +        if(ScalingStatValue & 0x00000008)                   // stat mod +            return 3; +        if(ScalingStatValue & 0x00000010)                   // stat mod +            return 4; +        if(ScalingStatValue & 0x00000020)                   // armor mod +            return 5; +        if(ScalingStatValue & 0x00000040)                   // armor mod +            return 6; +        if(ScalingStatValue & 0x00000080)                   // armor mod +            return 7; +        if(ScalingStatValue & 0x00000100)                   // armor mod +            return 8; +        if(ScalingStatValue & 0x00000200)                   // damage mod +            return 9; +        if(ScalingStatValue & 0x00000400)                   // damage mod +            return 10; +        if(ScalingStatValue & 0x00000800)                   // damage mod +            return 11; +        if(ScalingStatValue & 0x00001000)                   // damage mod +            return 12; +        if(ScalingStatValue & 0x00002000)                   // damage mod +            return 13; +        if(ScalingStatValue & 0x00004000)                   // damage mod +            return 14; +        if(ScalingStatValue & 0x00008000)                   // spell power +            return 15; +        if(ScalingStatValue & 0x00020000)                   // feral AP +            return 16; + +        return 0; +    }  };  struct ItemLocale diff --git a/src/game/Language.h b/src/game/Language.h index be6401596ea..06f9d0b1ed1 100644 --- a/src/game/Language.h +++ b/src/game/Language.h @@ -170,7 +170,9 @@ enum TrinityStrings      LANG_SOUND_NOT_EXIST                = 170,      LANG_TELEPORTED_TO_BY_CONSOLE       = 171,      LANG_CONSOLE_COMMAND                = 172, -    // Room for more level 1              173-199 not used +    LANG_YOU_CHANGE_RUNIC_POWER         = 173, +    LANG_YOURS_RUNIC_POWER_CHANGED      = 174, +    // Room for more level 1              175-199 not used      // level 2 chat      LANG_NO_SELECTION                   = 200, @@ -328,6 +330,8 @@ enum TrinityStrings      LANG_CREATURE_NOT_FOLLOW_YOU_NOW    = 342,      LANG_CREATURE_NON_TAMEABLE          = 343,      LANG_YOU_ALREADY_HAVE_PET           = 344, +    LANG_CUSTOMIZE_PLAYER               = 345, +    LANG_CUSTOMIZE_PLAYER_GUID          = 346,      // Room for more level 2              345-399 not used      // level 3 chat @@ -642,11 +646,10 @@ enum TrinityStrings      LANG_BG_QUEUE_ANNOUNCE_SELF         = 711,      LANG_BG_QUEUE_ANNOUNCE_WORLD        = 712, - -      LANG_YOUR_ARENA_LEVEL_REQ_ERROR     = 713, -//    LANG_HIS_ARENA_LEVEL_REQ_ERROR      = 714, an opcode exists for this +//                                      = 714, not used      LANG_YOUR_BG_LEVEL_REQ_ERROR        = 715, +  //    LANG_YOUR_ARENA_TEAM_FULL           = 716, an opcode exists for this      LANG_BG_AV_ALLY                     = 717, @@ -712,6 +715,31 @@ enum TrinityStrings      LANG_CANNOT_GO_TO_BG_GM             = 1137, // "You must be in GM mode to teleport to a player in a battleground."      LANG_CANNOT_GO_TO_BG_FROM_BG        = 1138, // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first." +//                                      = 716, not used +    LANG_BG_STARTED_ANNOUNCE_WORLD      = 717, +    LANG_ARENA_QUEUE_ANNOUNCE_WORLD_JOIN= 718, +    LANG_ARENA_QUEUE_ANNOUNCE_WORLD_EXIT= 719, + +    /*LANG_BG_GROUP_TOO_LARGE             = 720,              // "Your group is too large for this battleground. Please regroup to join." +    LANG_ARENA_GROUP_TOO_LARGE          = 721,              // "Your group is too large for this arena. Please regroup to join." +    LANG_ARENA_YOUR_TEAM_ONLY           = 722,              // "Your group has members not in your arena team. Please regroup to join." +    LANG_ARENA_NOT_ENOUGH_PLAYERS       = 723,              // "Your group does not have enough players to join this match." +    LANG_ARENA_GOLD_WINS                = 724,              // "The Gold Team wins!" +    LANG_ARENA_GREEN_WINS               = 725,              // "The Green Team wins!" +    LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING = 726,       // The battleground will end soon, because there aren't enough players. Get more ppl or win already! +    LANG_BG_GROUP_OFFLINE_MEMBER        = 727,              // "Your group has an offline member. Please remove him before joining." +    LANG_BG_GROUP_MIXED_FACTION         = 728,              // "Your group has players from the opposing faction. You can't join the battleground as a group." +    LANG_BG_GROUP_MIXED_LEVELS          = 729,              // "Your group has players from different battleground brakets. You can't join as group." +    LANG_BG_GROUP_MEMBER_ALREADY_IN_QUEUE = 730,            // "Someone in your party is already in this battleground queue. (S)he must leave it before joining as group." +    LANG_BG_GROUP_MEMBER_DESERTER       = 731,              // "Someone in your party is Deserter. You can't join as group." +    LANG_BG_GROUP_MEMBER_NO_FREE_QUEUE_SLOTS = 732,         // "Someone in your party is already in three battleground queues. You cannot join as group." + +    LANG_CANNOT_TELE_TO_BG              = 733,              // "You cannot teleport to a battleground or arena map." +    LANG_CANNOT_SUMMON_TO_BG            = 734,              // "You cannot summon players to a battleground or arena map." +    LANG_CANNOT_GO_TO_BG_GM             = 735,              // "You must be in GM mode to teleport to a player in a battleground." +    LANG_CANNOT_GO_TO_BG_FROM_BG        = 736,              // "You cannot teleport to a battleground from another battleground. Please leave the current battleground first."*/ +    // Room for batleground/arena strings 737-799 not used +      // in game strings      LANG_PET_INVALID_NAME               = 800,      LANG_NOT_ENOUGH_GOLD                = 801, diff --git a/src/game/Level1.cpp b/src/game/Level1.cpp index 000c7bc241e..462d2864621 100644 --- a/src/game/Level1.cpp +++ b/src/game/Level1.cpp @@ -123,8 +123,7 @@ bool ChatHandler::HandleNameAnnounceCommand(const char* args)      WorldPacket data;      if(!*args)          return false; -    //char str[1024]; -    //sprintf(str, GetTrinityString(LANG_ANNOUNCE_COLOR), m_session->GetPlayer()->GetName(), args); +      sWorld.SendWorldText(LANG_ANNOUNCE_COLOR, m_session->GetPlayer()->GetName(), args);      return true;  } @@ -875,6 +874,40 @@ bool ChatHandler::HandleModifyRageCommand(const char* args)      return true;  } +// Edit Player Runic Power +bool ChatHandler::HandleModifyRunicPowerCommand(const char* args) +{ +    if(!*args) +        return false; + +    int32 rune = atoi((char*)args)*10; +    int32 runem = atoi((char*)args)*10; + +    if (rune <= 0 || runem <= 0 || runem < rune) +    { +        SendSysMessage(LANG_BAD_VALUE); +        SetSentErrorMessage(true); +        return false; +    } + +    Player *chr = getSelectedPlayer(); +    if (chr == NULL) +    { +        SendSysMessage(LANG_NO_CHAR_SELECTED); +        SetSentErrorMessage(true); +        return false; +    } + +    PSendSysMessage(LANG_YOU_CHANGE_RUNIC_POWER, chr->GetName(), rune/10, runem/10); +    if (needReportToTarget(chr)) +        ChatHandler(chr).PSendSysMessage(LANG_YOURS_RUNIC_POWER_CHANGED, GetName(), rune/10, runem/10); + +    chr->SetMaxPower(POWER_RUNIC_POWER,runem ); +    chr->SetPower(POWER_RUNIC_POWER, rune ); + +    return true; +} +  //Edit Player Faction  bool ChatHandler::HandleModifyFactionCommand(const char* args)  { @@ -1761,9 +1794,9 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args)                  // send area in "id - [name]" format                  std::ostringstream ss;                  if (m_session) -					ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << " " << localeNames[loc]<< "]|h|r"; -				else -					ss << areaEntry->ID << " - " << name << " " << localeNames[loc]; +                    ss << areaEntry->ID << " - |cffffffff|Harea:" << areaEntry->ID << "|h[" << name << " " << localeNames[loc]<< "]|h|r"; +                else +                    ss << areaEntry->ID << " - " << name << " " << localeNames[loc];                  SendSysMessage (ss.str ().c_str()); @@ -1771,8 +1804,10 @@ bool ChatHandler::HandleLookupAreaCommand(const char* args)              }          }      } +      if (counter == 0)                                      // if counter == 0 then we found nth          SendSysMessage (LANG_COMMAND_NOAREAFOUND); +      return true;  } @@ -1801,7 +1836,7 @@ bool ChatHandler::HandleLookupTeleCommand(const char * args)      std::ostringstream reply; -	GameTeleMap const & teleMap = objmgr.GetGameTeleMap(); +    GameTeleMap const & teleMap = objmgr.GetGameTeleMap();      for(GameTeleMap::const_iterator itr = teleMap.begin(); itr != teleMap.end(); ++itr)      {          GameTele const* tele = &itr->second; @@ -1810,9 +1845,9 @@ bool ChatHandler::HandleLookupTeleCommand(const char * args)              continue;          if (m_session) -			reply << "  |cffffffff|Htele:" << itr->first << "|h[" << tele->name << "]|h|r\n"; -		else -			reply << "  " << itr->first << " " << tele->name << "\n"; +            reply << "  |cffffffff|Htele:" << itr->first << "|h[" << tele->name << "]|h|r\n"; +        else +            reply << "  " << itr->first << " " << tele->name << "\n";      }      if(reply.str().empty()) @@ -1959,7 +1994,6 @@ bool ChatHandler::HandleSendMailCommand(const char* args)          return false;      } -    uint32 mailId = objmgr.GenerateMailID();      // from console show not existed sender      uint32 sender_guidlo = m_session ? m_session->GetPlayer()->GetGUIDLow() : 0; @@ -2157,7 +2191,7 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)          return false;      } -    Map* gmMap = MapManager::Instance().GetMap(m_session->GetPlayer()->GetMapId(),m_session->GetPlayer()); +    Map* gmMap = m_session->GetPlayer()->GetMap();      bool to_instance =  gmMap->Instanceable();      // we are in instance, and can summon only player in our group with us as lead @@ -2187,7 +2221,7 @@ bool ChatHandler::HandleGroupgoCommand(const char* args)          if (to_instance)          { -            Map* plMap = MapManager::Instance().GetMap(pl->GetMapId(),pl); +            Map* plMap = pl->GetMap();              if ( plMap->Instanceable() && plMap->GetInstanceId() != gmMap->GetInstanceId() )              { diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 932ea2352ce..cbbadf5541a 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -950,7 +950,7 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args)      else          unit = getSelectedCreature(); -    if(!unit || unit->isPet() || unit->isTotem()) +    if(!unit || unit->isPet() || unit->isTotem() || unit->isVehicle())      {          SendSysMessage(LANG_SELECT_CREATURE);          SetSentErrorMessage(true); @@ -1063,8 +1063,8 @@ bool ChatHandler::HandleTurnObjectCommand(const char* args)      obj->Relocate(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), o);      obj->SetFloatValue(GAMEOBJECT_FACING, o); -    obj->SetFloatValue(GAMEOBJECT_ROTATION+2, rot2); -    obj->SetFloatValue(GAMEOBJECT_ROTATION+3, rot3); +    obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rot2); +    obj->SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rot3);      map->Add(obj); @@ -3256,6 +3256,59 @@ bool ChatHandler::HandleRenameCommand(const char* args)      return true;  } +// customize characters +bool ChatHandler::HandleCustomizeCommand(const char* args) +{ +    Player* target = NULL; +    uint64 targetGUID = 0; +    std::string oldname; + +    char* px = strtok((char*)args, " "); + +    if(px) +    { +        oldname = px; + +        if(!normalizePlayerName(oldname)) +        { +            SendSysMessage(LANG_PLAYER_NOT_FOUND); +            SetSentErrorMessage(true); +            return false; +        } + +        target = objmgr.GetPlayer(oldname.c_str()); + +        if (!target) +            targetGUID = objmgr.GetPlayerGUIDByName(oldname); +    } + +    if(!target && !targetGUID) +    { +        target = getSelectedPlayer(); +    } + +    if(!target && !targetGUID) +    { +        SendSysMessage(LANG_PLAYER_NOT_FOUND); +        SetSentErrorMessage(true); +        return false; +    } + +    if(target) +    { +        PSendSysMessage(LANG_CUSTOMIZE_PLAYER, target->GetName()); +        target->SetAtLoginFlag(AT_LOGIN_CUSTOMIZE); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", target->GetGUIDLow()); +    } +    else +    { +        PSendSysMessage(LANG_CUSTOMIZE_PLAYER_GUID, oldname.c_str(), GUID_LOPART(targetGUID)); +        CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '8' WHERE guid = '%u'", GUID_LOPART(targetGUID)); +    } + +    return true; +} +  //spawn go  bool ChatHandler::HandleGameObjectCommand(const char* args)  { @@ -3883,6 +3936,36 @@ bool ChatHandler::HandleRepairitemsCommand(const char* /*args*/)      return true;  } +bool ChatHandler::HandleWaterwalkCommand(const char* args) +{ +    if(!*args) +        return false; + +    Player *player = getSelectedPlayer(); + +    if(!player) +    { +        PSendSysMessage(LANG_NO_CHAR_SELECTED); +        SetSentErrorMessage(true); +        return false; +    } + +    if (strncmp(args, "on", 3) == 0) +        player->SetMovement(MOVE_WATER_WALK);               // ON +    else if (strncmp(args, "off", 4) == 0) +        player->SetMovement(MOVE_LAND_WALK);                // OFF +    else +    { +        SendSysMessage(LANG_USE_BOL); +        return false; +    } + +    PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName()); +    if(needReportToTarget(player)) +        ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName()); +    return true; +} +  bool ChatHandler::HandleNpcFollowCommand(const char* /*args*/)  {      Player *player = m_session->GetPlayer(); @@ -3939,6 +4022,72 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/)      return true;  } +bool ChatHandler::HandleNpcTameCommand(const char* /*args*/) +{ +    Creature *creatureTarget = getSelectedCreature (); +    if (!creatureTarget || creatureTarget->isPet ()) +    { +        PSendSysMessage (LANG_SELECT_CREATURE); +        SetSentErrorMessage (true); +        return false; +    } + +    Player *player = m_session->GetPlayer (); + +    if(player->GetPetGUID ()) +    { +        SendSysMessage (LANG_YOU_ALREADY_HAVE_PET); +        SetSentErrorMessage (true); +        return false; +    } + +    CreatureInfo const* cInfo = creatureTarget->GetCreatureInfo(); + +    if (!cInfo->isTameable ()) +    { +        PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); +        SetSentErrorMessage (true); +        return false; +    } + +    // Everything looks OK, create new pet +    Pet* pet = player->CreateTamedPetFrom (creatureTarget); +    if (!pet) +    { +        PSendSysMessage (LANG_CREATURE_NON_TAMEABLE,cInfo->Entry); +        SetSentErrorMessage (true); +        return false; +    } + +    // place pet before player +    float x,y,z; +    player->GetClosePoint (x,y,z,creatureTarget->GetObjectSize (),CONTACT_DISTANCE); +    pet->Relocate (x,y,z,M_PI-player->GetOrientation ()); + +    // set pet to defensive mode by default (some classes can't control controlled pets in fact). +    pet->GetCharmInfo()->SetReactState(REACT_DEFENSIVE); + +    // calculate proper level +    uint32 level = (creatureTarget->getLevel() < (player->getLevel() - 5)) ? (player->getLevel() - 5) : creatureTarget->getLevel(); + +    // prepare visual effect for levelup +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1); + +    // add to world +    pet->GetMap()->Add((Creature*)pet); + +    // visual effect for levelup +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level); + +    // caster have pet now +    player->SetPet(pet); + +    pet->SavePetToDB(PET_SAVE_AS_CURRENT); +    player->PetSpellInitialize(); + +    return true; +} +  bool ChatHandler::HandleCreatePetCommand(const char* args)  {  	Player *player = m_session->GetPlayer(); @@ -4098,7 +4247,7 @@ bool ChatHandler::HandlePetTpCommand(const char *args)  	uint32 tp = atol(args); -	pet->SetTP(tp); +	//pet->SetTP(tp);  	PSendSysMessage("Pet's tp changed to %u", tp);  	return true; @@ -4137,4 +4286,4 @@ bool ChatHandler::HandleActivateObjectCommand(const char *args)  	PSendSysMessage("Object activated!");  	return true; -} +}
\ No newline at end of file diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 123b1dceb09..aef91bf1e9c 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -54,14 +54,6 @@  #include "InstanceData.h"  //reload commands -bool ChatHandler::HandleReloadCommand(const char* arg) -{ -    // this is error catcher for wrong table name in .reload commands -    PSendSysMessage("Db table with name starting from '%s' not found and can't be reloaded.",arg); -    SetSentErrorMessage(true); -    return false; -} -  bool ChatHandler::HandleReloadAllCommand(const char*)  {      HandleReloadAreaTriggerTeleportCommand(""); @@ -299,6 +291,15 @@ bool ChatHandler::HandleReloadLootTemplatesItemCommand(const char*)      return true;  } +bool ChatHandler::HandleReloadLootTemplatesMillingCommand(const char*) +{ +    sLog.outString( "Re-Loading Loot Tables... (`milling_loot_template`)" ); +    LoadLootTemplates_Milling(); +    LootTemplates_Milling.CheckLootRefs(); +    SendGlobalSysMessage("DB table `milling_loot_template` reloaded."); +    return true; +} +  bool ChatHandler::HandleReloadLootTemplatesPickpocketingCommand(const char*)  {      sLog.outString( "Re-Loading Loot Tables... (`pickpocketing_loot_template`)" ); @@ -1748,6 +1749,10 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)          if(!spellInfo)              continue; +        // skip server-side/triggered spells +        if(spellInfo->spellLevel==0) +            continue; +          // skip wrong class/race skills          if(!m_session->GetPlayer()->IsSpellFitByClassAndRace(spellInfo->Id))              continue; @@ -1756,8 +1761,6 @@ bool ChatHandler::HandleLearnAllMySpellsCommand(const char* /*args*/)          if( spellInfo->SpellFamilyName != family)              continue; -        //TODO: skip triggered spells -          // skip spells with first rank learned as talent (and all talents then also)          uint32 first_rank = spellmgr.GetFirstSpellInChain(spellInfo->Id);          if(GetTalentSpellCost(first_rank) > 0 ) @@ -3820,36 +3823,6 @@ bool ChatHandler::HandleHoverCommand(const char* args)      return true;  } -bool ChatHandler::HandleWaterwalkCommand(const char* args) -{ -    if(!args) -        return false; - -    Player *player = getSelectedPlayer(); -    if(!player) -    { -        PSendSysMessage(LANG_NO_CHAR_SELECTED); -        SetSentErrorMessage(true); -        return false; -    } - -    if (strncmp(args, "on", 3) == 0) -        player->SetMovement(MOVE_WATER_WALK);               // ON -    else if (strncmp(args, "off", 4) == 0) -        player->SetMovement(MOVE_LAND_WALK);                // OFF -    else -    { -        SendSysMessage(LANG_USE_BOL); -        return false; -    } - -    PSendSysMessage(LANG_YOU_SET_WATERWALK, args, player->GetName()); -    if(needReportToTarget(player)) -        ChatHandler(player).PSendSysMessage(LANG_YOUR_WATERWALK_SET, args, GetName()); -    return true; - -} -  bool ChatHandler::HandleLevelUpCommand(const char* args)  {      char* px = strtok((char*)args, " "); @@ -4465,7 +4438,7 @@ static bool HandleResetStatsOrLevelHelper(Player* player)      // set UNIT_FIELD_BYTES_1 to init state but preserve m_form value      player->SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); -    player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); +    player->SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP );      player->SetByteValue(UNIT_FIELD_BYTES_2, 3, player->m_form);      player->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); @@ -4510,6 +4483,7 @@ bool ChatHandler::HandleResetLevelCommand(const char * args)      player->SetLevel(1);      player->InitStatsForLevel(true);      player->InitTaxiNodesForLevel(); +    player->InitGlyphsForLevel();      player->InitTalentForLevel();      player->SetUInt32Value(PLAYER_XP,0); @@ -4553,6 +4527,7 @@ bool ChatHandler::HandleResetStatsCommand(const char * args)      player->InitStatsForLevel(true);      player->InitTaxiNodesForLevel(); +    player->InitGlyphsForLevel();      player->InitTalentForLevel();      return true; @@ -6615,30 +6590,27 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)          return false;      } +    PlayerInfo const* info = objmgr.GetPlayerInfo(player->getRace(), player->getClass()); +    if(!info) +        return false; +      char const* gender_str = (char*)args;      int gender_len = strlen(gender_str); -    uint32 displayId = player->GetNativeDisplayId(); -    char const* gender_full = NULL; -    uint32 new_displayId = displayId;      Gender gender; -    if(!strncmp(gender_str,"male",gender_len))              // MALE +    if(!strncmp(gender_str, "male", gender_len))            // MALE      {          if(player->getGender() == GENDER_MALE)              return true; -        gender_full = "male"; -        new_displayId = player->getRace() == RACE_BLOODELF ? displayId+1 : displayId-1;          gender = GENDER_MALE;      } -    else if (!strncmp(gender_str,"female",gender_len))      // FEMALE +    else if (!strncmp(gender_str, "female", gender_len))    // FEMALE      {          if(player->getGender() == GENDER_FEMALE)              return true; -        gender_full = "female"; -        new_displayId = player->getRace() == RACE_BLOODELF ? displayId-1 : displayId+1;          gender = GENDER_FEMALE;      }      else @@ -6650,14 +6622,19 @@ bool ChatHandler::HandleModifyGenderCommand(const char *args)      // Set gender      player->SetByteValue(UNIT_FIELD_BYTES_0, 2, gender); +    player->SetByteValue(PLAYER_BYTES_3, 0, gender);      // Change display ID -    player->SetDisplayId(new_displayId); -    player->SetNativeDisplayId(new_displayId); +    player->SetDisplayId(gender ? info->displayId_f : info->displayId_m); +    player->SetNativeDisplayId(gender ? info->displayId_f : info->displayId_m); + +    char const* gender_full = gender ? "female" : "male"; + +    PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(), gender_full); -    PSendSysMessage(LANG_YOU_CHANGE_GENDER, player->GetName(),gender_full);      if (needReportToTarget(player)) -        ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full,GetName()); +        ChatHandler(player).PSendSysMessage(LANG_YOUR_GENDER_CHANGED, gender_full, GetName()); +      return true;  } diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index a4a8a7a1f01..f1110ca3853 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -154,6 +154,7 @@ void WorldSession::HandleAutostoreLootItemOpcode( WorldPacket & recv_data )          --loot->unlootedCount;          player->SendNewItem(newitem, uint32(item->count), false, false, true); +        player->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item->itemid, item->count);      }      else          player->SendEquipError( msg, NULL, NULL ); @@ -326,7 +327,7 @@ void WorldSession::DoLootRelease( uint64 lguid )                              int32 ReqValue = 175;                              LockEntry const *lockInfo = sLockStore.LookupEntry(go->GetGOInfo()->chest.lockId);                              if(lockInfo) -                                ReqValue = lockInfo->requiredminingskill; +                                ReqValue = lockInfo->Skill[0];                              float skill = float(player->GetSkillValue(SKILL_MINING))/(ReqValue+25);                              double chance = pow(0.8*chance_rate,4*(1/double(max_amount))*double(uses));                              if(roll_chance_f(100*chance+skill)) @@ -495,6 +496,7 @@ void WorldSession::HandleLootMasterGiveOpcode( WorldPacket & recv_data )      // not move item from loot to target inventory      Item * newitem = target->StoreNewItem( dest, item.itemid, true, item.randomPropertyId );      target->SendNewItem(newitem, uint32(item.count), false, false, true ); +    target->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM, item.itemid, item.count);      // mark as looted      item.count=0; diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 4a34f51d672..61c626a544c 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -41,6 +41,7 @@ LootStore LootTemplates_Disenchant(   "disenchant_loot_template",   "item disenc  LootStore LootTemplates_Fishing(      "fishing_loot_template",      "area id");  LootStore LootTemplates_Gameobject(   "gameobject_loot_template",   "gameobject entry");  LootStore LootTemplates_Item(         "item_loot_template",         "item entry"); +LootStore LootTemplates_Milling(      "milling_loot_template",      "item entry");  LootStore LootTemplates_Pickpocketing("pickpocketing_loot_template","creature pickpocket lootid");  LootStore LootTemplates_Prospecting(  "prospecting_loot_template",  "item entry");  LootStore LootTemplates_QuestMail(    "quest_mail_loot_template",   "quest id"); @@ -1138,6 +1139,21 @@ void LoadLootTemplates_Item()      LootTemplates_Item.ReportUnusedIds(ids_set);  } +void LoadLootTemplates_Milling() +{ +    LootIdSet ids_set; +    LootTemplates_Milling.LoadAndCollectLootIds(ids_set); + +    // remove real entries and check existence loot +    for(uint32 i = 1; i < sItemStorage.MaxEntry; ++i ) +        if(ItemPrototype const* proto = sItemStorage.LookupEntry<ItemPrototype>(i)) +            if(ids_set.count(proto->ItemId)) +                ids_set.erase(proto->ItemId); + +    // output error for any still listed (not referenced from appropriate table) ids +    LootTemplates_Milling.ReportUnusedIds(ids_set); +} +  void LoadLootTemplates_Pickpocketing()  {      LootIdSet ids_set, ids_setUsed; @@ -1230,6 +1246,7 @@ void LoadLootTemplates_Reference()      LootTemplates_Fishing.CheckLootRefs(&ids_set);      LootTemplates_Gameobject.CheckLootRefs(&ids_set);      LootTemplates_Item.CheckLootRefs(&ids_set); +    LootTemplates_Milling.CheckLootRefs(&ids_set);      LootTemplates_Pickpocketing.CheckLootRefs(&ids_set);      LootTemplates_Skinning.CheckLootRefs(&ids_set);      LootTemplates_Disenchant.CheckLootRefs(&ids_set); diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index 1cb02c29bfc..f9fed651a1c 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -297,6 +297,7 @@ extern LootStore LootTemplates_Creature;  extern LootStore LootTemplates_Fishing;  extern LootStore LootTemplates_Gameobject;  extern LootStore LootTemplates_Item; +extern LootStore LootTemplates_Milling;  extern LootStore LootTemplates_Pickpocketing;  extern LootStore LootTemplates_Skinning;  extern LootStore LootTemplates_Disenchant; @@ -307,6 +308,7 @@ void LoadLootTemplates_Creature();  void LoadLootTemplates_Fishing();  void LoadLootTemplates_Gameobject();  void LoadLootTemplates_Item(); +void LoadLootTemplates_Milling();  void LoadLootTemplates_Pickpocketing();  void LoadLootTemplates_Skinning();  void LoadLootTemplates_Disenchant(); @@ -320,6 +322,7 @@ inline void LoadLootTables()      LoadLootTemplates_Fishing();      LoadLootTemplates_Gameobject();      LoadLootTemplates_Item(); +    LoadLootTemplates_Milling();      LoadLootTemplates_Pickpocketing();      LoadLootTemplates_Skinning();      LoadLootTemplates_Disenchant(); diff --git a/src/game/Mail.cpp b/src/game/Mail.cpp index 00211094d4e..3d4126bd22a 100644 --- a/src/game/Mail.cpp +++ b/src/game/Mail.cpp @@ -593,7 +593,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )          data << (uint32) (*itr)->mailTemplateId;            // mail template (MailTemplate.dbc)          data << (*itr)->subject;                            // Subject string - once 00, when mail type = 3 -        data << (uint8) item_count; +        data << (uint8) item_count;                         // client limit is 0x10          for(uint8 i = 0; i < item_count; ++i)          { @@ -604,7 +604,7 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )              data << (uint32) (item ? item->GetGUIDLow() : 0);              // entry              data << (uint32) (item ? item->GetEntry() : 0); -            for(uint8 j = 0; j < 6; ++j) +            for(uint8 j = 0; j < 7; ++j)              {                  // unsure                  data << (uint32) (item ? item->GetEnchantmentCharges((EnchantmentSlot)j) : 0); @@ -618,13 +618,15 @@ void WorldSession::HandleGetMail(WorldPacket & recv_data )              // unk              data << (uint32) (item ? item->GetItemSuffixFactor() : 0);              // stack count -            data << (uint8)  (item ? item->GetCount() : 0); +            data << (uint32) (item ? item->GetCount() : 0);              // charges              data << (uint32) (item ? item->GetSpellCharges() : 0);              // durability              data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY) : 0);              // durability              data << (uint32) (item ? item->GetUInt32Value(ITEM_FIELD_DURABILITY) : 0); +            // unknown wotlk +            data << (uint8)  0;          }          mails_count += 1; diff --git a/src/game/Makefile.am b/src/game/Makefile.am index 81259aef1a7..c0eda2ff7ea 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -9,295 +9,276 @@  #  # 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 +# 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 +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  ## Process this file with automake to produce Makefile.in  ## Sub-directories to parse  ## CPP flags for includes, defines, etc. -AM_CPPFLAGS =  +AM_CPPFLAGS = $(TRINI_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../shared/vmap -I$(srcdir)/../realmd -DSYSCONFDIR=\"$(sysconfdir)/\"  ## Build MaNGOS game library as convenience library.  #  All libraries will be convenience libraries. Might be changed to shared  #  later. -noinst_LIBRARIES = libgame.a - -libgame_a_CPPFLAGS = \ -$(MYSQL_INCLUDES) \ -$(POSTGRE_INCLUDES) \ -$(TRINI_INCLUDES) \ --I$(top_srcdir)/dep/include \ --I$(top_srcdir)/src/framework \ --I$(top_srcdir)/src/shared \ --I$(top_srcdir)/src/shared/vmap +noinst_LIBRARIES = libmangosgame.a  #  libmangossgame library will later be reused by ... -libgame_a_SOURCES = \ -$(srcdir)/AccountMgr.cpp \ -$(srcdir)/AccountMgr.h \ -$(srcdir)/AddonHandler.cpp \ -$(srcdir)/AddonHandler.h \ -$(srcdir)/AggressorAI.cpp \ -$(srcdir)/AggressorAI.h \ -$(srcdir)/AnimalRandomMovementGenerator.h \ -$(srcdir)/ArenaTeam.cpp \ -$(srcdir)/ArenaTeam.h \ -$(srcdir)/ArenaTeamHandler.cpp \ -$(srcdir)/AuctionHouse.cpp \ -$(srcdir)/AuctionHouseObject.h \ -$(srcdir)/Bag.cpp \ -$(srcdir)/Bag.h \ -$(srcdir)/BattleGround.cpp \ -$(srcdir)/BattleGroundAA.cpp \ -$(srcdir)/BattleGroundAB.cpp \ -$(srcdir)/BattleGroundAV.cpp \ -$(srcdir)/BattleGroundBE.cpp \ -$(srcdir)/BattleGroundEY.cpp \ -$(srcdir)/BattleGroundNA.cpp \ -$(srcdir)/BattleGroundRL.cpp \ -$(srcdir)/BattleGroundWS.cpp \ -$(srcdir)/BattleGround.h \ -$(srcdir)/BattleGroundAA.h \ -$(srcdir)/BattleGroundAB.h \ -$(srcdir)/BattleGroundAV.h \ -$(srcdir)/BattleGroundBE.h \ -$(srcdir)/BattleGroundEY.h \ -$(srcdir)/BattleGroundNA.h \ -$(srcdir)/BattleGroundRL.h \ -$(srcdir)/BattleGroundWS.h \ -$(srcdir)/BattleGroundHandler.cpp \ -$(srcdir)/BattleGroundMgr.cpp \ -$(srcdir)/BattleGroundMgr.h \ -$(srcdir)/Cell.h \ -$(srcdir)/CellImpl.h \ -$(srcdir)/Channel.cpp \ -$(srcdir)/Channel.h \ -$(srcdir)/ChannelHandler.cpp \ -$(srcdir)/ChannelMgr.h \ -$(srcdir)/CharacterHandler.cpp \ -$(srcdir)/Chat.cpp \ -$(srcdir)/Chat.h \ -$(srcdir)/ChatHandler.cpp \ -$(srcdir)/CombatHandler.cpp \ -$(srcdir)/ConfusedMovementGenerator.cpp \ -$(srcdir)/ConfusedMovementGenerator.h \ -$(srcdir)/Corpse.cpp \ -$(srcdir)/Corpse.h \ -$(srcdir)/CreatureAI.cpp \ -$(srcdir)/CreatureAI.h \ -$(srcdir)/CreatureAIImpl.h \ -$(srcdir)/CreatureAIRegistry.cpp \ -$(srcdir)/CreatureAIRegistry.h \ -$(srcdir)/CreatureAISelector.cpp \ -$(srcdir)/CreatureAISelector.h \ -$(srcdir)/CreatureGroups.cpp \ -$(srcdir)/CreatureGroups.h \ -$(srcdir)/Creature.cpp \ -$(srcdir)/Creature.h \ -$(srcdir)/debugcmds.cpp \ -$(srcdir)/DestinationHolder.cpp \ -$(srcdir)/DestinationHolder.h \ -$(srcdir)/DestinationHolderImp.h \ -$(srcdir)/DuelHandler.cpp \ -$(srcdir)/DynamicObject.cpp \ -$(srcdir)/DynamicObject.h \ -$(srcdir)/FleeingMovementGenerator.cpp \ -$(srcdir)/FleeingMovementGenerator.h \ -$(srcdir)/Formulas.h \ -$(srcdir)/GameEvent.cpp \ -$(srcdir)/GameEvent.h \ -$(srcdir)/GameObject.cpp \ -$(srcdir)/GameObject.h \ -$(srcdir)/GlobalEvents.cpp \ -$(srcdir)/GlobalEvents.h \ -$(srcdir)/GMTicketHandler.cpp \ -$(srcdir)/GMTicketMgr.cpp \ -$(srcdir)/GMTicketMgr.h \ -$(srcdir)/GossipDef.cpp \ -$(srcdir)/GossipDef.h \ -$(srcdir)/GridDefines.h \ -$(srcdir)/GridNotifiers.cpp \ -$(srcdir)/GridNotifiers.h \ -$(srcdir)/GridNotifiersImpl.h \ -$(srcdir)/GridStates.cpp \ -$(srcdir)/GridStates.h \ -$(srcdir)/Group.cpp \ -$(srcdir)/Group.h \ -$(srcdir)/GroupHandler.cpp \ -$(srcdir)/GuardAI.cpp \ -$(srcdir)/GuardAI.h \ -$(srcdir)/Guild.cpp \ -$(srcdir)/Guild.h \ -$(srcdir)/GuildHandler.cpp \ -$(srcdir)/HomeMovementGenerator.cpp \ -$(srcdir)/HomeMovementGenerator.h \ -$(srcdir)/HostilRefManager.cpp \ -$(srcdir)/HostilRefManager.h \ -$(srcdir)/IdleMovementGenerator.cpp \ -$(srcdir)/IdleMovementGenerator.h \ -$(srcdir)/InstanceData.cpp \ -$(srcdir)/InstanceData.h \ -$(srcdir)/InstanceSaveMgr.cpp \ -$(srcdir)/InstanceSaveMgr.h \ -$(srcdir)/Item.cpp \ -$(srcdir)/Item.h \ -$(srcdir)/ItemEnchantmentMgr.cpp \ -$(srcdir)/ItemEnchantmentMgr.h \ -$(srcdir)/ItemHandler.cpp \ -$(srcdir)/ItemPrototype.h \ -$(srcdir)/Language.h \ -$(srcdir)/Level0.cpp \ -$(srcdir)/Level1.cpp \ -$(srcdir)/Level2.cpp \ -$(srcdir)/Level3.cpp \ -$(srcdir)/LFGHandler.cpp \ -$(srcdir)/LootHandler.cpp \ -$(srcdir)/LootMgr.cpp \ -$(srcdir)/LootMgr.h \ -$(srcdir)/Mail.cpp \ -$(srcdir)/Mail.h \ -$(srcdir)/Map.cpp \ -$(srcdir)/Map.h \ -$(srcdir)/MapInstanced.cpp \ -$(srcdir)/MapInstanced.h \ -$(srcdir)/MapManager.cpp \ -$(srcdir)/MapManager.h \ -$(srcdir)/MiscHandler.cpp \ -$(srcdir)/MotionMaster.cpp \ -$(srcdir)/MotionMaster.h \ -$(srcdir)/MovementGenerator.cpp \ -$(srcdir)/MovementGenerator.h \ -$(srcdir)/MovementGeneratorImpl.h \ -$(srcdir)/MovementHandler.cpp \ -$(srcdir)/NPCHandler.cpp \ -$(srcdir)/NPCHandler.h \ -$(srcdir)/NullCreatureAI.cpp \ -$(srcdir)/NullCreatureAI.h \ -$(srcdir)/ObjectAccessor.cpp \ -$(srcdir)/ObjectAccessor.h \ -$(srcdir)/Object.cpp \ -$(srcdir)/ObjectDefines.h \ -$(srcdir)/ObjectGridLoader.cpp \ -$(srcdir)/ObjectGridLoader.h \ -$(srcdir)/Object.h \ -$(srcdir)/ObjectMgr.cpp \ -$(srcdir)/ObjectMgr.h \ -$(srcdir)/Opcodes.cpp \ -$(srcdir)/Opcodes.h \ -$(srcdir)/OutdoorPvP.cpp \ -$(srcdir)/OutdoorPvP.h \ -$(srcdir)/OutdoorPvPEP.cpp \ -$(srcdir)/OutdoorPvPEP.h \ -$(srcdir)/OutdoorPvPHP.cpp \ -$(srcdir)/OutdoorPvPHP.h \ -$(srcdir)/OutdoorPvPMgr.cpp \ -$(srcdir)/OutdoorPvPMgr.h \ -$(srcdir)/OutdoorPvPNA.cpp \ -$(srcdir)/OutdoorPvPNA.h \ -$(srcdir)/OutdoorPvPObjectiveAI.cpp \ -$(srcdir)/OutdoorPvPObjectiveAI.h \ -$(srcdir)/OutdoorPvPSI.cpp \ -$(srcdir)/OutdoorPvPSI.h \ -$(srcdir)/OutdoorPvPTF.cpp \ -$(srcdir)/OutdoorPvPTF.h \ -$(srcdir)/OutdoorPvPZM.cpp \ -$(srcdir)/OutdoorPvPZM.h \ -$(srcdir)/Path.h \ -$(srcdir)/PetAI.cpp \ -$(srcdir)/PetAI.h \ -$(srcdir)/Pet.cpp \ -$(srcdir)/Pet.h \ -$(srcdir)/PetHandler.cpp \ -$(srcdir)/PetitionsHandler.cpp \ -$(srcdir)/Player.cpp \ -$(srcdir)/Player.h \ -$(srcdir)/PlayerDump.cpp \ -$(srcdir)/PlayerDump.h \ -$(srcdir)/PointMovementGenerator.cpp \ -$(srcdir)/PointMovementGenerator.h \ -$(srcdir)/PossessedAI.cpp \ -$(srcdir)/PossessedAI.h \ -$(srcdir)/QueryHandler.cpp \ -$(srcdir)/QuestDef.cpp \ -$(srcdir)/QuestDef.h \ -$(srcdir)/QuestHandler.cpp \ -$(srcdir)/RandomMovementGenerator.cpp \ -$(srcdir)/RandomMovementGenerator.h \ -$(srcdir)/ReactorAI.cpp \ -$(srcdir)/ReactorAI.h \ -$(srcdir)/ScriptCalls.cpp \ -$(srcdir)/ScriptCalls.h \ -$(srcdir)/SharedDefines.h \ -$(srcdir)/SkillHandler.cpp \ -$(srcdir)/SpellAuraDefines.h \ -$(srcdir)/SpellAuras.cpp \ -$(srcdir)/SpellAuras.h \ -$(srcdir)/Spell.cpp \ -$(srcdir)/SpellEffects.cpp \ -$(srcdir)/Spell.h \ -$(srcdir)/SkillDiscovery.cpp \ -$(srcdir)/SkillDiscovery.h \ -$(srcdir)/SkillExtraItems.cpp \ -$(srcdir)/SkillExtraItems.h \ -$(srcdir)/SpellHandler.cpp \ -$(srcdir)/SocialMgr.cpp \ -$(srcdir)/SocialMgr.h \ -$(srcdir)/SpellMgr.cpp \ -$(srcdir)/SpellMgr.h \ -$(srcdir)/StatSystem.cpp \ -$(srcdir)/TargetedMovementGenerator.cpp \ -$(srcdir)/TargetedMovementGenerator.h \ -$(srcdir)/TaxiHandler.cpp \ -$(srcdir)/TemporarySummon.cpp \ -$(srcdir)/TemporarySummon.h \ -$(srcdir)/tools.cpp \ -$(srcdir)/Tools.h \ -$(srcdir)/TotemAI.cpp \ -$(srcdir)/TotemAI.h \ -$(srcdir)/Totem.cpp \ -$(srcdir)/Totem.h \ -$(srcdir)/TradeHandler.cpp \ -$(srcdir)/Transports.cpp \ -$(srcdir)/Transports.h \ -$(srcdir)/ThreatManager.cpp \ -$(srcdir)/ThreatManager.h \ -$(srcdir)/Traveller.h \ -$(srcdir)/Unit.cpp \ -$(srcdir)/Unit.h \ -$(srcdir)/UnitEvents.h \ -$(srcdir)/UpdateData.cpp \ -$(srcdir)/UpdateData.h \ -$(srcdir)/UpdateFields.h \ -$(srcdir)/UpdateMask.h \ -$(srcdir)/VoiceChatHandler.cpp \ -$(srcdir)/WaypointManager.cpp \ -$(srcdir)/WaypointManager.h \ -$(srcdir)/WaypointMovementGenerator.cpp \ -$(srcdir)/WaypointMovementGenerator.h \ -$(srcdir)/Weather.cpp \ -$(srcdir)/Weather.h \ -$(srcdir)/World.cpp \ -$(srcdir)/World.h \ -$(srcdir)/WorldLog.cpp \ -$(srcdir)/WorldLog.h \ -$(srcdir)/WorldSession.cpp \ -$(srcdir)/WorldSession.h \ -$(srcdir)/WorldSocket.cpp \ -$(srcdir)/WorldSocket.h \ -$(srcdir)/WorldSocketMgr.cpp \ -$(srcdir)/WorldSocketMgr.h \ -$(srcdir)/FollowerReference.cpp \ -$(srcdir)/FollowerReference.h \ -$(srcdir)/FollowerRefManager.h \ -$(srcdir)/GroupReference.cpp \ -$(srcdir)/GroupReference.h \ -$(srcdir)/GroupRefManager.h +libmangosgame_a_SOURCES = \ +    AccountMgr.cpp \ +    AccountMgr.h \ +    AchievementMgr.h \ +    AchievementMgr.cpp \ +    AddonHandler.cpp \ +    AddonHandler.h \ +    AggressorAI.cpp \ +    AggressorAI.h \ +    AnimalRandomMovementGenerator.h \ +    ArenaTeam.cpp \ +    ArenaTeam.h \ +    ArenaTeamHandler.cpp \ +    AuctionHouse.cpp \ +    AuctionHouseObject.h \ +    Bag.cpp \ +    Bag.h \ +    BattleGround.cpp \ +    BattleGroundAA.cpp \ +    BattleGroundAB.cpp \ +    BattleGroundAV.cpp \ +    BattleGroundBE.cpp \ +    BattleGroundEY.cpp \ +    BattleGroundNA.cpp \ +    BattleGroundRL.cpp \ +    BattleGroundWS.cpp \ +    BattleGround.h \ +    BattleGroundAA.h \ +    BattleGroundAB.h \ +    BattleGroundAV.h \ +    BattleGroundBE.h \ +    BattleGroundEY.h \ +    BattleGroundNA.h \ +    BattleGroundRL.h \ +    BattleGroundWS.h \ +    BattleGroundHandler.cpp \ +    BattleGroundMgr.cpp \ +    BattleGroundMgr.h \ +    Calendar.cpp \ +    Calendar.h \ +    CalendarHandler.cpp \ +    Cell.h \ +    CellImpl.h \ +    Channel.cpp \ +    Channel.h \ +    ChannelHandler.cpp \ +    ChannelMgr.h \ +    CharacterHandler.cpp \ +    Chat.cpp \ +    Chat.h \ +    ChatHandler.cpp \ +    CombatHandler.cpp \ +    ConfusedMovementGenerator.cpp \ +    ConfusedMovementGenerator.h \ +    Corpse.cpp \ +    Corpse.h \ +    CreatureAI.cpp \ +    CreatureAI.h \ +    CreatureAIImpl.h \ +    CreatureAIRegistry.cpp \ +    CreatureAIRegistry.h \ +    CreatureAISelector.cpp \ +    CreatureAISelector.h \ +    Creature.cpp \ +    Creature.h \ +    debugcmds.cpp \ +    DestinationHolder.cpp \ +    DestinationHolder.h \ +    DestinationHolderImp.h \ +    DuelHandler.cpp \ +    DynamicObject.cpp \ +    DynamicObject.h \ +    FleeingMovementGenerator.cpp \ +    FleeingMovementGenerator.h \ +    Formulas.h \ +    GameEvent.cpp \ +    GameEvent.h \ +    GameObject.cpp \ +    GameObject.h \ +    GlobalEvents.cpp \ +    GlobalEvents.h \ +    GMTicketHandler.cpp \ +    GMTicketMgr.cpp \ +    GMTicketMgr.h \ +    GossipDef.cpp \ +    GossipDef.h \ +    GridDefines.h \ +    GridNotifiers.cpp \ +    GridNotifiers.h \ +    GridNotifiersImpl.h \ +    GridStates.cpp \ +    GridStates.h \ +    Group.cpp \ +    Group.h \ +    GroupHandler.cpp \ +    GuardAI.cpp \ +    GuardAI.h \ +    Guild.cpp \ +    Guild.h \ +    GuildHandler.cpp \ +    HomeMovementGenerator.cpp \ +    HomeMovementGenerator.h \ +    HostilRefManager.cpp \ +    HostilRefManager.h \ +    IdleMovementGenerator.cpp \ +    IdleMovementGenerator.h \ +    InstanceData.cpp \ +    InstanceData.h \ +    InstanceSaveMgr.cpp \ +    InstanceSaveMgr.h \ +    Item.cpp \ +    Item.h \ +    ItemEnchantmentMgr.cpp \ +    ItemEnchantmentMgr.h \ +    ItemHandler.cpp \ +    ItemPrototype.h \ +    Language.h \ +    Level0.cpp \ +    Level1.cpp \ +    Level2.cpp \ +    Level3.cpp \ +    LFGHandler.cpp \ +    LootHandler.cpp \ +    LootMgr.cpp \ +    LootMgr.h \ +    Mail.cpp \ +    Mail.h \ +    Map.cpp \ +    Map.h \ +    MapInstanced.cpp \ +    MapInstanced.h \ +    MapManager.cpp \ +    MapManager.h \ +    MapReference.h \ +    MapRefManager.h \ +    MiscHandler.cpp \ +    MotionMaster.cpp \ +    MotionMaster.h \ +    MovementGenerator.cpp \ +    MovementGenerator.h \ +    MovementGeneratorImpl.h \ +    MovementHandler.cpp \ +    NPCHandler.cpp \ +    NPCHandler.h \ +    NullCreatureAI.cpp \ +    NullCreatureAI.h \ +    ObjectAccessor.cpp \ +    ObjectAccessor.h \ +    Object.cpp \ +    ObjectDefines.h \ +    ObjectGridLoader.cpp \ +    ObjectGridLoader.h \ +    Object.h \ +    ObjectMgr.cpp \ +    ObjectMgr.h \ +    ObjectPosSelector.cpp \ +    ObjectPosSelector.h \ +    Opcodes.cpp \ +    Opcodes.h \ +    Path.h \ +    PetAI.cpp \ +    PetAI.h \ +    Pet.cpp \ +    Pet.h \ +    PetHandler.cpp \ +    PetitionsHandler.cpp \ +    Player.cpp \ +    Player.h \ +    PlayerDump.cpp \ +    PlayerDump.h \ +    PointMovementGenerator.cpp \ +    PointMovementGenerator.h \ +    QueryHandler.cpp \ +    QuestDef.cpp \ +    QuestDef.h \ +    QuestHandler.cpp \ +    RandomMovementGenerator.cpp \ +    RandomMovementGenerator.h \ +    ReactorAI.cpp \ +    ReactorAI.h \ +    ScriptCalls.cpp \ +    ScriptCalls.h \ +    SharedDefines.h \ +    SkillHandler.cpp \ +    SpellAuraDefines.h \ +    SpellAuras.cpp \ +    SpellAuras.h \ +    Spell.cpp \ +    SpellEffects.cpp \ +    Spell.h \ +    SkillDiscovery.cpp \ +    SkillDiscovery.h \ +    SkillExtraItems.cpp \ +    SkillExtraItems.h \ +    SpellHandler.cpp \ +    SocialMgr.cpp \ +    SocialMgr.h \ +    SpellMgr.cpp \ +    SpellMgr.h \ +    StatSystem.cpp \ +    TargetedMovementGenerator.cpp \ +    TargetedMovementGenerator.h \ +    TaxiHandler.cpp \ +    TemporarySummon.cpp \ +    TemporarySummon.h \ +    TotemAI.cpp \ +    TotemAI.h \ +    Totem.cpp \ +    Totem.h \ +    TradeHandler.cpp \ +    Transports.cpp \ +    Transports.h \ +    ThreatManager.cpp \ +    ThreatManager.h \ +    Traveller.h \ +    Unit.cpp \ +    Unit.h \ +    UnitEvents.h \ +    UpdateData.cpp \ +    UpdateData.h \ +    UpdateFields.h \ +    UpdateMask.h \ +    Vehicle.cpp \ +    Vehicle.h \ +    VoiceChatHandler.cpp \ +    WaypointManager.cpp \ +    WaypointManager.h \ +    WaypointMovementGenerator.cpp \ +    WaypointMovementGenerator.h \ +    Weather.cpp \ +    Weather.h \ +    World.cpp \ +    World.h \ +    WorldLog.cpp \ +    WorldLog.h \ +    WorldSession.cpp \ +    WorldSession.h \ +    WorldSocket.cpp \ +    WorldSocket.h \ +    WorldSocketMgr.cpp \ +    WorldSocketMgr.h \ +    FollowerReference.cpp \ +    FollowerReference.h \ +    FollowerRefManager.h \ +    GroupReference.cpp \ +    GroupReference.h \ +    GroupRefManager.h + +## Link against shared library +libmangosgame_a_LIBADD = ../shared/libmangosshared.a ../shared/Auth/libmangosauth.a ../shared/Config/libmangosconfig.a ../shared/Database/libmangosdatabase.a ../shared/vmap/libmangosvmaps.a  ## Additional files to include when running 'make dist'  #  Nothing yet. diff --git a/src/game/Map.cpp b/src/game/Map.cpp index c2fe5bfec74..c1673b1082d 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -45,7 +45,7 @@  #define MAX_GRID_LOAD_TIME      50  // magic *.map header -const char MAP_MAGIC[] = "MAP_2.00"; +const char MAP_MAGIC[] = "MAP_2.01";  GridState* si_GridStates[MAX_GRID_STATE]; @@ -257,7 +257,7 @@ template<>  void Map::AddToGrid(Creature* obj, NGridType *grid, Cell const& cell)  {      // add to world object registry in grid -    if(obj->isPet() || obj->isPossessedByPlayer()) +    if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle())      {          (*grid)(cell.CellX(), cell.CellY()).AddWorldObject<Creature>(obj, obj->GetGUID());          obj->SetCurrentCell(cell); @@ -301,7 +301,7 @@ template<>  void Map::RemoveFromGrid(Creature* obj, NGridType *grid, Cell const& cell)  {      // remove from world object registry in grid -    if(obj->isPet() || obj->isPossessedByPlayer()) +    if(obj->isPet() || obj->isPossessedByPlayer() || obj->isVehicle())      {          (*grid)(cell.CellX(), cell.CellY()).RemoveWorldObject<Creature>(obj, obj->GetGUID());      } diff --git a/src/game/Map.h b/src/game/Map.h index c3ae4830cfb..074c859c408 100644 --- a/src/game/Map.h +++ b/src/game/Map.h @@ -224,6 +224,17 @@ class TRINITY_DLL_SPEC Map : public GridRefManager<NGridType>, public Trinity::O          bool IsBattleGround() const { return i_mapEntry && i_mapEntry->IsBattleGround(); }          bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); }          bool IsBattleGroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattleGroundOrArena(); } +        bool GetEntrancePos(int32 &mapid, float &x, float &y) +        { +            if(!i_mapEntry) +                return false; +            if(i_mapEntry->entrance_map < 0) +                return false; +            mapid = i_mapEntry->entrance_map; +            x = i_mapEntry->entrance_x; +            y = i_mapEntry->entrance_y; +            return true; +        }          void AddObjectToRemoveList(WorldObject *obj);          void DoDelayedMovesAndRemoves(); diff --git a/src/game/MapManager.cpp b/src/game/MapManager.cpp index 26279cb76ec..47be039d415 100644 --- a/src/game/MapManager.cpp +++ b/src/game/MapManager.cpp @@ -175,7 +175,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player)          //The player has a heroic mode and tries to enter into instance which has no a heroic mode          if (!entry->SupportsHeroicMode() && player->GetDifficulty() == DIFFICULTY_HEROIC)          { -            player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY2);      //Send aborted message +            //Send aborted message +            player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);              return false;          } @@ -280,7 +281,8 @@ bool MapManager::ExistMapAndVMap(uint32 mapid, float x,float y)  bool MapManager::IsValidMAP(uint32 mapid)  {      MapEntry const* mEntry = sMapStore.LookupEntry(mapid); -    return mEntry && (!mEntry->Instanceable() || objmgr.GetInstanceTemplate(mapid)); +    return mEntry && (!mEntry->IsDungeon() || objmgr.GetInstanceTemplate(mapid)); +    // TODO: add check for battleground template  }  void MapManager::LoadGrid(int mapid, float x, float y, const WorldObject* obj, bool no_unload) diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index f5ee5dbcf4c..b6b224a2d6a 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -312,7 +312,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ )          data.append(GetPlayer()->GetPackGUID());          data << (uint32)2;          SendPacket( &data ); -        GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +        GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);      }      WorldPacket data( SMSG_LOGOUT_RESPONSE, 5 ); @@ -349,7 +349,7 @@ void WorldSession::HandleLogoutCancelOpcode( WorldPacket & /*recv_data*/ )          GetPlayer()->SetStandState(PLAYER_STATE_NONE);          //! DISABLE_ROTATE -        GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +        GetPlayer()->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);      }      sLog.outDebug( "WORLD: sent SMSG_LOGOUT_CANCEL_ACK Message" ); @@ -363,10 +363,12 @@ void WorldSession::HandleTogglePvP( WorldPacket & recv_data )          bool newPvPStatus;          recv_data >> newPvPStatus;          GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP, newPvPStatus); +        GetPlayer()->ApplyModFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER, !newPvPStatus);      }      else      {          GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP); +        GetPlayer()->ToggleFlag(PLAYER_FLAGS, PLAYER_FLAGS_PVP_TIMER);      }      if(GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP)) @@ -882,7 +884,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)              if(missingItem)                  SendAreaTriggerMessage(GetTrinityString(LANG_LEVEL_MINREQUIRED_AND_ITEM), at->requiredLevel, objmgr.GetItemPrototype(missingItem)->Name1);              else if(missingKey) -                GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY2); +                GetPlayer()->SendTransferAborted(at->target_mapId, TRANSFER_ABORT_DIFFICULTY, DIFFICULTY_HEROIC);              else if(missingQuest)                  SendAreaTriggerMessage(at->requiredFailedText.c_str());              else if(missingLevel) @@ -894,16 +896,96 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)      GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT);  } -void WorldSession::HandleUpdateAccountData(WorldPacket &/*recv_data*/) +void WorldSession::HandleUpdateAccountData(WorldPacket &recv_data)  {      sLog.outDetail("WORLD: Received CMSG_UPDATE_ACCOUNT_DATA"); -    //recv_data.hexlike(); + +    CHECK_PACKET_SIZE(recv_data, 4+4+4); + +    uint32 type, timestamp, decompressedSize; +    recv_data >> type >> timestamp >> decompressedSize; + +    sLog.outDebug("UAD: type %u, time %u, decompressedSize %u", type, timestamp, decompressedSize); + +    if(type > NUM_ACCOUNT_DATA_TYPES) +        return; + +    if(decompressedSize == 0)                               // erase +    { +        SetAccountData(type, timestamp, ""); + +        WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); +        data << uint32(type); +        data << uint32(0); +        SendPacket(&data); + +        return; +    } + +    if(decompressedSize > 0xFFFF) +    { +        sLog.outError("UAD: Account data packet too big, size %u", decompressedSize); +        return; +    } + +    ByteBuffer dest; +    dest.resize(decompressedSize); + +    uLongf realSize = decompressedSize; +    if(uncompress(const_cast<uint8*>(dest.contents()), &realSize, const_cast<uint8*>(recv_data.contents() + recv_data.rpos()), recv_data.size() - recv_data.rpos()) != Z_OK) +    { +        sLog.outError("UAD: Failed to decompress account data"); +        return; +    } + +    std::string adata; +    dest >> adata; + +    SetAccountData(type, timestamp, adata); + +    WorldPacket data(SMSG_UPDATE_ACCOUNT_DATA_COMPLETE, 4+4); +    data << uint32(type); +    data << uint32(0); +    SendPacket(&data);  } -void WorldSession::HandleRequestAccountData(WorldPacket& /*recv_data*/) +void WorldSession::HandleRequestAccountData(WorldPacket& recv_data)  {      sLog.outDetail("WORLD: Received CMSG_REQUEST_ACCOUNT_DATA"); -    //recv_data.hexlike(); + +    CHECK_PACKET_SIZE(recv_data, 4); + +    uint32 type; +    recv_data >> type; + +    sLog.outDebug("RAD: type %u", type); + +    if(type > NUM_ACCOUNT_DATA_TYPES) +        return; + +    AccountData *adata = GetAccountData(type); + +    uint32 size = adata->Data.size(); + +    ByteBuffer dest; +    dest.resize(size); + +    uLongf destSize = size; +    if(compress(const_cast<uint8*>(dest.contents()), &destSize, (uint8*)adata->Data.c_str(), size) != Z_OK) +    { +        sLog.outDebug("RAD: Failed to compress account data"); +        return; +    } + +    dest.resize(destSize); + +    WorldPacket data (SMSG_UPDATE_ACCOUNT_DATA, 8+4+4+4+destSize); +    data << uint64(_player->GetGUID());                     // player guid +    data << uint32(type);                                   // type (0-7) +    data << uint32(adata->Time);                            // unix time +    data << uint32(size);                                   // decompressed length +    data.append(dest);                                      // compressed data +    SendPacket(&data);  }  void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) @@ -1434,11 +1516,11 @@ void WorldSession::HandleChooseTitleOpcode( WorldPacket & recv_data )      GetPlayer()->SetUInt32Value(PLAYER_CHOSEN_TITLE, title);  } -void WorldSession::HandleAllowMoveAckOpcode( WorldPacket & recv_data ) +void WorldSession::HandleTimeSyncResp( WorldPacket & recv_data )  {      CHECK_PACKET_SIZE(recv_data, 4+4); -    sLog.outDebug("CMSG_ALLOW_MOVE_ACK"); +    sLog.outDebug("CMSG_TIME_SYNC_RESP");      uint32 counter, time_;      recv_data >> counter >> time_; @@ -1508,26 +1590,6 @@ void WorldSession::HandleDungeonDifficultyOpcode( WorldPacket & recv_data )      }  } -void WorldSession::HandleNewUnknownOpcode( WorldPacket & recv_data ) -{ -    sLog.outDebug("New Unknown Opcode %u", recv_data.GetOpcode()); -    recv_data.hexlike(); -    /* -    New Unknown Opcode 837 -    STORAGE_SIZE: 60 -    02 00 00 00 00 00 00 00 | 00 00 00 00 01 20 00 00 -    89 EB 33 01 71 5C 24 C4 | 15 03 35 45 74 47 8B 42 -    BA B8 1B 40 00 00 00 00 | 00 00 00 00 77 66 42 BF -    23 91 26 3F 00 00 60 41 | 00 00 00 00 - -    New Unknown Opcode 837 -    STORAGE_SIZE: 44 -    02 00 00 00 00 00 00 00 | 00 00 00 00 00 00 80 00 -    7B 80 34 01 84 EA 2B C4 | 5F A1 36 45 C9 39 1C 42 -    BA B8 1B 40 CE 06 00 00 | 00 00 80 3F -    */ -} -  void WorldSession::HandleDismountOpcode( WorldPacket & /*recv_data*/ )  {      sLog.outDebug("WORLD: CMSG_CANCEL_MOUNT_AURA"); @@ -1594,3 +1656,32 @@ void WorldSession::HandleSetTaxiBenchmarkOpcode( WorldPacket & recv_data )      sLog.outDebug("Client used \"/timetest %d\" command", mode);  } + +void WorldSession::HandleSpellClick( WorldPacket & recv_data ) +{ +    CHECK_PACKET_SIZE(recv_data, 8); + +    uint64 guid; +    recv_data >> guid; + +    Vehicle *vehicle = ObjectAccessor::GetVehicle(guid); + +    if(!vehicle) +        return; + +    _player->EnterVehicle(vehicle); +} + +void WorldSession::HandleInspectAchievements( WorldPacket & recv_data ) +{ +    CHECK_PACKET_SIZE(recv_data, 1); +    uint64 guid; +    if(!recv_data.readPackGUID(guid)) +        return; + +    Player *player = objmgr.GetPlayer(guid); +    if(!player) +        return; + +    player->GetAchievementMgr().SendRespondInspectAchievements(_player); +} diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index 0a310cddd96..29f673061b4 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -178,64 +178,12 @@ void WorldSession::HandleMoveWorldportAckOpcode()  void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )  { -    CHECK_PACKET_SIZE(recv_data, 4+1+4+4+4+4+4); +    uint32 opcode = recv_data.GetOpcode(); +    sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);      /* extract packet */      MovementInfo movementInfo; -    uint32 MovementFlags; - -    recv_data >> MovementFlags; -    recv_data >> movementInfo.unk1; -    recv_data >> movementInfo.time; -    recv_data >> movementInfo.x; -    recv_data >> movementInfo.y; -    recv_data >> movementInfo.z; -    recv_data >> movementInfo.o; - -    if(MovementFlags & MOVEMENTFLAG_ONTRANSPORT) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); - -        recv_data >> movementInfo.t_guid; -        recv_data >> movementInfo.t_x; -        recv_data >> movementInfo.t_y; -        recv_data >> movementInfo.t_z; -        recv_data >> movementInfo.t_o; -        recv_data >> movementInfo.t_time; -    } - -    if(MovementFlags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); - -        recv_data >> movementInfo.s_pitch;                  // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up -    } - -    // recheck -    CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); - -    recv_data >> movementInfo.fallTime;                     // duration of last jump (when in jump duration from jump begin to now) - -    if(MovementFlags & MOVEMENTFLAG_JUMPING) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); - -        recv_data >> movementInfo.j_unk;                    // constant, but different when jumping in water and on land? -        recv_data >> movementInfo.j_sinAngle;               // sin of angle between orientation0 and players orientation -        recv_data >> movementInfo.j_cosAngle;               // cos of angle between orientation0 and players orientation -        recv_data >> movementInfo.j_xyspeed;                // speed of xy movement -    } - -    if(MovementFlags & MOVEMENTFLAG_SPLINE) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); - -        recv_data >> movementInfo.u_unk1;                   // unknown -    } +    ReadMovementInfo(recv_data, &movementInfo);      /*----------------*/      if(recv_data.size() != recv_data.rpos()) @@ -252,7 +200,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )      Unit* pos_unit = GetPlayer()->GetCharm();      if (pos_unit && pos_unit->isPossessed()) // can be charmed but not possessed      { -        HandlePossessedMovement(recv_data, movementInfo, MovementFlags); +        HandlePossessedMovement(recv_data, movementInfo, movementInfo.flags);          return;      } @@ -260,10 +208,10 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )          return;      //Save movement flags -    GetPlayer()->SetUnitMovementFlags(MovementFlags); +    GetPlayer()->SetUnitMovementFlags(movementInfo.flags);      /* handle special cases */ -    if (MovementFlags & MOVEMENTFLAG_ONTRANSPORT) +    if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT)      {          // transports size limited          // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) @@ -282,9 +230,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )              {                  if ((*iter)->GetGUID() == movementInfo.t_guid)                  { -                    // unmount before boarding -                    GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); -                      GetPlayer()->m_transport = (*iter);                      (*iter)->AddPassenger(GetPlayer());                      break; @@ -301,13 +246,14 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )          movementInfo.t_z = 0.0f;          movementInfo.t_o = 0.0f;          movementInfo.t_time = 0; +        movementInfo.t_seat = -1;      }      // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map). -    if (recv_data.GetOpcode() == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight()) +    if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())          GetPlayer()->HandleFallDamage(movementInfo); -    if(((MovementFlags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater()) +    if(((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())      {          // now client not include swimming flag in case jumping under water          GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); @@ -316,14 +262,35 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )      /*----------------------*/      /* process position-change */ -    recv_data.put<uint32>(5, getMSTime());                  // offset flags(4) + unk(1) -    WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size())); -    data.append(GetPlayer()->GetPackGUID()); +    Unit *mover = _player->m_mover; +    recv_data.put<uint32>(6, getMSTime());                  // fix time, offset flags(4) + unk(2) +    WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size())); +    data.append(_player->m_mover->GetPackGUID());           // use mover guid      data.append(recv_data.contents(), recv_data.size());      GetPlayer()->SendMessageToSet(&data, false); -    GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); -    GetPlayer()->m_movementInfo = movementInfo; +    if(!_player->GetCharmGUID())                            // nothing is charmed +    { +        _player->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); +        _player->m_movementInfo = movementInfo; +        _player->SetUnitMovementFlags(movementInfo.flags); +    } +    else +    { +        if(mover->GetTypeId() != TYPEID_PLAYER)             // unit, creature, pet, vehicle... +        { +            if(Map *map = mover->GetMap()) +                map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); +            mover->SetUnitMovementFlags(movementInfo.flags); +        } +        else                                                // player +        { +            ((Player*)mover)->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); +            ((Player*)mover)->m_movementInfo = movementInfo; +            ((Player*)mover)->SetUnitMovementFlags(movementInfo.flags); +        } +    } +      if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)          GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z); @@ -396,20 +363,13 @@ void WorldSession::HandlePossessedMovement(WorldPacket& recv_data, MovementInfo&  void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)  { -    CHECK_PACKET_SIZE(recv_data, 8+4+4+1+4+4+4+4+4); +    sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(recv_data.GetOpcode()), recv_data.GetOpcode(), recv_data.GetOpcode()); + +    CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4);      /* extract packet */      uint64 guid; -    uint8  unkB; -    uint32 unk1, flags, time, fallTime; -    float x, y, z, orientation; - -    uint64 t_GUID; -    float  t_x, t_y, t_z, t_o; -    uint32 t_time; -    float  s_pitch; -    float  j_unk1, j_sinAngle, j_cosAngle, j_xyspeed; -    float  u_unk1; +    uint32 unk1;      float  newspeed;      recv_data >> guid; @@ -420,47 +380,10 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)      // continue parse packet -    recv_data >> unk1; -    recv_data >> flags >> unkB >> time; -    recv_data >> x >> y >> z >> orientation; -    if (flags & MOVEMENTFLAG_ONTRANSPORT) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8+4+4+4+4+4); +    recv_data >> unk1;                                      // counter or moveEvent -        recv_data >> t_GUID; -        recv_data >> t_x >> t_y >> t_z >> t_o >> t_time; -    } -    if (flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); - -        recv_data >> s_pitch;                               // pitch, -1.55=looking down, 0=looking straight forward, +1.55=looking up -    } - -    // recheck -    CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); - -    recv_data >> fallTime;                                  // duration of last jump (when in jump duration from jump begin to now) - -    if ((flags & MOVEMENTFLAG_JUMPING) || (flags & MOVEMENTFLAG_FALLING)) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4+4+4+4); - -        recv_data >> j_unk1;                                // ?constant, but different when jumping in water and on land? -        recv_data >> j_sinAngle >> j_cosAngle;              // sin + cos of angle between orientation0 and players orientation -        recv_data >> j_xyspeed;                             // speed of xy movement -    } - -    if(flags & MOVEMENTFLAG_SPLINE) -    { -        // recheck -        CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); - -        recv_data >> u_unk1;                                // unknown -    } +    MovementInfo movementInfo; +    ReadMovementInfo(recv_data, &movementInfo);      // recheck      CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+4); @@ -473,7 +396,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)      UnitMoveType move_type;      UnitMoveType force_move_type; -    static char const* move_type_name[MAX_MOVE_TYPE] = {  "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack" }; +    static char const* move_type_name[MAX_MOVE_TYPE] = {  "Walk", "Run", "RunBack", "Swim", "SwimBack", "TurnRate", "Flight", "FlightBack", "PitchRate" };      uint16 opcode = recv_data.GetOpcode();      switch(opcode) @@ -486,6 +409,7 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)          case CMSG_FORCE_TURN_RATE_CHANGE_ACK:           move_type = MOVE_TURN_RATE;     force_move_type = MOVE_TURN_RATE;   break;          case CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK:        move_type = MOVE_FLIGHT;        force_move_type = MOVE_FLIGHT;      break;          case CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK:   move_type = MOVE_FLIGHT_BACK;   force_move_type = MOVE_FLIGHT_BACK; break; +        case CMSG_FORCE_PITCH_RATE_CHANGE_ACK:          move_type = MOVE_PITCH_RATE;    force_move_type = MOVE_PITCH_RATE;  break;          default:              sLog.outError("WorldSession::HandleForceSpeedChangeAck: Unknown move type opcode: %u", opcode);              return; @@ -520,20 +444,61 @@ void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)  void WorldSession::HandleSetActiveMoverOpcode(WorldPacket &recv_data)  {      sLog.outDebug("WORLD: Recvd CMSG_SET_ACTIVE_MOVER"); +    recv_data.hexlike(); -    CHECK_PACKET_SIZE(recv_data,8); +    CHECK_PACKET_SIZE(recv_data, 8);      uint64 guid;      recv_data >> guid; -    WorldPacket data(SMSG_TIME_SYNC_REQ, 4);                // new 2.0.x, enable movement -    data << uint32(0x00000000);                             // on blizz it increments periodically -    SendPacket(&data); +    if(_player->m_mover->GetGUID() != guid) +    { +        sLog.outError("HandleSetActiveMoverOpcode: incorrect mover guid: mover is " I64FMT " and should be " I64FMT, _player->m_mover->GetGUID(), guid); +        return; +    }  } -void WorldSession::HandleNotActiveMoverOpcode(WorldPacket& /*recv_data*/) +void WorldSession::HandleMoveNotActiveMover(WorldPacket &recv_data)  {      sLog.outDebug("WORLD: Recvd CMSG_MOVE_NOT_ACTIVE_MOVER"); +    recv_data.hexlike(); + +    CHECK_PACKET_SIZE(recv_data, recv_data.rpos()+8); + +    uint64 old_mover_guid; +    recv_data >> old_mover_guid; + +    if(_player->m_mover->GetGUID() == old_mover_guid) +    { +        sLog.outError("HandleMoveNotActiveMover: incorrect mover guid: mover is " I64FMT " and should be " I64FMT " instead of " I64FMT, _player->m_mover->GetGUID(), _player->GetGUID(), old_mover_guid); +        return; +    } + +    MovementInfo mi; +    ReadMovementInfo(recv_data, &mi); +    _player->m_movementInfo = mi; +} + +void WorldSession::HandleDismissControlledVehicle(WorldPacket &recv_data) +{ +    sLog.outDebug("WORLD: Recvd CMSG_DISMISS_CONTROLLED_VEHICLE"); +    recv_data.hexlike(); + +    uint64 vehicleGUID = _player->GetCharmGUID(); + +    if(!vehicleGUID)                                        // something wrong here... +        return; + +    MovementInfo mi; +    ReadMovementInfo(recv_data, &mi); +    _player->m_movementInfo = mi; + +    // using charm guid, because we don't have vehicle guid... +    if(Vehicle *vehicle = ObjectAccessor::GetVehicle(vehicleGUID)) +    { +        _player->ExitVehicle(vehicle); +        vehicle->Dismiss(); +    }  }  void WorldSession::HandleMountSpecialAnimOpcode(WorldPacket& /*recvdata*/) diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 6bb916d9fe0..c6751512e02 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -524,13 +524,12 @@ void WorldSession::SendStablePet(uint64 guid )          data << uint32(pet->GetEntry());          data << uint32(pet->getLevel());          data << pet->GetName();                             // petname -        data << uint32(pet->GetLoyaltyLevel());             // loyalty -        data << uint8(0x01);                                // client slot 1 == current pet (0) +        data << uint8(0x01);                                // flags?, client slot 1 == current pet (0)          ++num;      } -    //                                                     0      1     2   3      4      5        6 -    QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, loyalty, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow()); +    //                                                     0      1     2   3      4      5 +    QueryResult* result = CharacterDatabase.PQuery("SELECT owner, slot, id, entry, level, name FROM character_pet WHERE owner = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow());      if(result)      { @@ -541,8 +540,7 @@ void WorldSession::SendStablePet(uint64 guid )              data << uint32(fields[2].GetUInt32());          // petnumber              data << uint32(fields[3].GetUInt32());          // creature entry              data << uint32(fields[4].GetUInt32());          // level -            data << fields[6].GetString();                  // name -            data << uint32(fields[5].GetUInt32());          // loyalty +            data << fields[5].GetString();                  // name              data << uint8(fields[1].GetUInt32()+1);         // slot              ++num; @@ -592,7 +590,7 @@ void WorldSession::HandleStablePet( WorldPacket & recv_data )      uint32 free_slot = 1; -    QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u'  AND slot > 0 AND slot < 3 ORDER BY slot ",_player->GetGUIDLow()); +    QueryResult *result = CharacterDatabase.PQuery("SELECT owner,slot,id FROM character_pet WHERE owner = '%u'  AND slot > 0 AND slot < 5 ORDER BY slot ",_player->GetGUIDLow());      if(result)      {          do @@ -656,7 +654,7 @@ void WorldSession::HandleUnstablePet( WorldPacket & recv_data )      Pet *newpet = NULL; -    QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 3",_player->GetGUIDLow(),petnumber); +    QueryResult *result = CharacterDatabase.PQuery("SELECT entry FROM character_pet WHERE owner = '%u' AND id = '%u' AND slot > 0 AND slot < 5",_player->GetGUIDLow(),petnumber);      if(result)      {          Field *fields = result->Fetch(); @@ -700,7 +698,7 @@ void WorldSession::HandleBuyStableSlot( WorldPacket & recv_data )      WorldPacket data(SMSG_STABLE_RESULT, 200); -    if(GetPlayer()->m_stableSlots < 2)                      // max slots amount = 2 +    if(GetPlayer()->m_stableSlots < 4)                      // max slots amount = 4      {          StableSlotPricesEntry const *SlotPrice = sStableSlotPricesStore.LookupEntry(GetPlayer()->m_stableSlots+1);          if(_player->GetMoney() >= SlotPrice->Price) diff --git a/src/game/Object.cpp b/src/game/Object.cpp index efd041f34c2..e4e5230bfb6 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -146,15 +146,9 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c      /** lower flag1 **/      if(target == this)                                      // building packet for oneself -    {          flags |= UPDATEFLAG_SELF; -        /*** temporary reverted - until real source of stack corruption will not found -        updatetype = UPDATETYPE_CREATE_OBJECT2; -        ****/ -    } - -    if(flags & UPDATEFLAG_HASPOSITION) +    if(flags & UPDATEFLAG_HAS_POSITION)      {          // UPDATETYPE_CREATE_OBJECT2 dynamic objects, corpses...          if(isType(TYPEMASK_DYNAMICOBJECT) || isType(TYPEMASK_CORPSE) || isType(TYPEMASK_PLAYER)) @@ -180,6 +174,12 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData *data, Player *target) c                      break;              }          } + +        if(isType(TYPEMASK_UNIT)) +        { +            if(((Unit*)this)->getVictim()) +                flags |= UPDATEFLAG_HAS_TARGET; +        }      }      //sLog.outDebug("BuildCreateUpdate: update-type: %u, object-type: %u got flags: %X, flags2: %X", updatetype, m_objectTypeId, flags, flags2); @@ -251,11 +251,18 @@ void Object::DestroyForPlayer(Player *target) const      WorldPacket data(SMSG_DESTROY_OBJECT, 8);      data << GetGUID(); +    data << uint8(0);                                       // WotLK (bool)      target->GetSession()->SendPacket( &data );  } -void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2 ) const +void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2) const  { +    uint16 unk_flags = ((GetTypeId() == TYPEID_PLAYER) ? ((Player*)this)->m_movementInfo.unk1 : 0); +     +    if(GetTypeId() == TYPEID_UNIT) +        if(((Creature*)this)->isVehicle()) +            unk_flags |= 0x20;                              // always allow pitch +      *data << (uint8)flags;                                  // update flags      // 0x20 @@ -292,12 +299,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2          }          *data << uint32(flags2);                            // movement flags -        *data << uint8(0);                                  // unk 2.3.0 +        *data << uint16(unk_flags);                         // unknown 2.3.0          *data << uint32(getMSTime());                       // time (in milliseconds)      }      // 0x40 -    if (flags & UPDATEFLAG_HASPOSITION) +    if (flags & UPDATEFLAG_HAS_POSITION)      {          // 0x02          if(flags & UPDATEFLAG_TRANSPORT && ((GameObject*)this)->GetGoType() == GAMEOBJECT_TYPE_MO_TRANSPORT) @@ -330,12 +337,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2                  *data << (float)((Player*)this)->GetTransOffsetZ();                  *data << (float)((Player*)this)->GetTransOffsetO();                  *data << (uint32)((Player*)this)->GetTransTime(); +                *data << (int8)((Player*)this)->GetTransSeat();              }              //TrinIty currently not have support for other than player on transport          }          // 0x02200000 -        if(flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) +        if((flags2 & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (unk_flags & 0x20))          {              if(GetTypeId() == TYPEID_PLAYER)                  *data << (float)((Player*)this)->m_movementInfo.s_pitch; @@ -384,6 +392,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2          *data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT );          *data << ((Unit*)this)->GetSpeed( MOVE_FLIGHT_BACK );          *data << ((Unit*)this)->GetSpeed( MOVE_TURN_RATE ); +        *data << ((Unit*)this)->GetSpeed( MOVE_PITCH_RATE );          // 0x08000000          if(flags2 & MOVEMENTFLAG_SPLINE2) @@ -485,7 +494,7 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2                  break;              case TYPEID_PLAYER:                  if(flags & UPDATEFLAG_SELF) -                    *data << uint32(0x00000015);            // unk, can be 0x15 or 0x22 +                    *data << uint32(0x0000002F);            // unk, can be 0x15 or 0x22                  else                      *data << uint32(0x00000008);            // unk, can be 0x7 or 0x8                  break; @@ -508,6 +517,15 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2              case TYPEID_CORPSE:                  *data << uint32(GetGUIDHigh());             // GetGUIDHigh()                  break; +            case TYPEID_UNIT: +                *data << uint32(0x0000000B);                // unk, can be 0xB or 0xC +                break; +            case TYPEID_PLAYER: +                if(flags & UPDATEFLAG_SELF) +                    *data << uint32(0x0000002F);            // unk, can be 0x15 or 0x22 +                else +                    *data << uint32(0x00000008);            // unk, can be 0x7 or 0x8 +                break;              default:                  *data << uint32(0x00000000);                // unk                  break; @@ -515,9 +533,12 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2      }      // 0x4 -    if(flags & UPDATEFLAG_FULLGUID) +    if(flags & UPDATEFLAG_HAS_TARGET)                       // packed guid (current target guid)      { -        *data << uint8(0);                                  // packed guid (probably target guid) +        if(Unit *victim = ((Unit*)this)->getVictim()) +            data->append(victim->GetPackGUID()); +        else +            *data << uint8(0);      }      // 0x2 @@ -525,6 +546,13 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint8 flags, uint32 flags2      {          *data << uint32(getMSTime());                       // ms time      } + +    // 0x80 +    if(flags & UPDATEFLAG_VEHICLE)                          // unused for now +    { +        *data << uint32(((Vehicle*)this)->GetVehicleId());  // vehicle id +        *data << float(0);                                  // facing adjustment +    }  }  void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *updateMask, Player *target) const @@ -540,10 +568,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask              if ( ((GameObject*)this)->ActivateToQuest(target) || target->isGameMaster())              {                  IsActivateToQuest = true; -                updateMask->SetBit(GAMEOBJECT_DYN_FLAGS); +                updateMask->SetBit(GAMEOBJECT_DYNAMIC);              } -            if (GetUInt32Value(GAMEOBJECT_ARTKIT)) -                updateMask->SetBit(GAMEOBJECT_ARTKIT);          }      }      else                                                    //case UPDATETYPE_VALUES @@ -554,8 +580,8 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask              {                  IsActivateToQuest = true;              } -            updateMask->SetBit(GAMEOBJECT_DYN_FLAGS); -            updateMask->SetBit(GAMEOBJECT_ANIMPROGRESS); +            updateMask->SetBit(GAMEOBJECT_DYNAMIC); +            updateMask->SetBit(GAMEOBJECT_BYTES_1);          }      } @@ -572,7 +598,6 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask              if( updateMask->GetBit( index ) )              {                  // remove custom flag before send -                  if( index == UNIT_NPC_FLAGS )                      *data << uint32(m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP));                  // FIXME: Some values at server stored in float format but must be sent to client in uint32 format @@ -641,7 +666,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask              if( updateMask->GetBit( index ) )              {                  // send in current format (float as float, uint32 as uint32) -                if ( index == GAMEOBJECT_DYN_FLAGS ) +                if ( index == GAMEOBJECT_DYNAMIC )                  {                      if(IsActivateToQuest )                      { @@ -1093,7 +1118,7 @@ uint32 WorldObject::GetAreaId() const  InstanceData* WorldObject::GetInstanceData()  { -    Map *map = MapManager::Instance().GetMap(m_mapId, this); +    Map *map = GetMap();      return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceData() : NULL;  } @@ -1303,7 +1328,7 @@ namespace Trinity      {          public:              MessageChatLocaleCacheDo(WorldObject const& obj, ChatMsg msgtype, int32 textId, uint32 language, uint64 targetGUID, float dist) -                : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language),  +                : i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(language),                  i_targetGUID(targetGUID), i_dist(dist)              {              } @@ -1448,7 +1473,7 @@ void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const      data->Initialize(MSG_MOVE_HEARTBEAT, 32);      data->append(GetPackGUID());      *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags -    *data << uint8(0);                                      // 2.3.0 +    *data << uint16(0);                                     // 2.3.0      *data << getMSTime();                                   // time      *data << m_positionX;      *data << m_positionY; @@ -1467,7 +1492,7 @@ void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float      data->append(GetPackGUID());      *data << uint32(0);                                     // this value increments every time      *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags -    *data << uint8(0);                                      // 2.3.0 +    *data << uint16(0);                                     // 2.3.0      *data << getMSTime();                                   // time      *data << x;      *data << y; @@ -1620,4 +1645,4 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,  	z = GetPositionZ();  	UpdateGroundPositionZ(x,y,z); -}
\ No newline at end of file +} diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 7d51c4c0291..4e876d99418 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -134,6 +134,9 @@ ObjectAccessor::GetCreatureOrPet(WorldObject const &u, uint64 guid)      if(Creature *unit = GetPet(guid))          return unit; +    if(Creature *unit = GetVehicle(guid)) +        return unit; +      return GetCreature(u, guid);  } @@ -351,6 +354,12 @@ ObjectAccessor::GetPet(uint64 guid)      return GetObjectInWorld(guid, (Pet*)NULL);  } +Vehicle* +ObjectAccessor::GetVehicle(uint64 guid) +{ +    return GetObjectInWorld(guid, (Vehicle*)NULL); +} +  Corpse*  ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid)  { @@ -602,6 +611,7 @@ template <class T> ZThread::FastMutex HashMapHolder<T>::i_lock;  template class HashMapHolder<Player>;  template class HashMapHolder<Pet>; +template class HashMapHolder<Vehicle>;  template class HashMapHolder<GameObject>;  template class HashMapHolder<DynamicObject>;  template class HashMapHolder<Creature>; @@ -609,6 +619,7 @@ template class HashMapHolder<Corpse>;  template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, uint64 guid, Player* /*fake*/);  template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, uint64 guid, Pet* /*fake*/); +template Vehicle* ObjectAccessor::GetObjectInWorld<Vehicle>(uint32 mapid, float x, float y, uint64 guid, Vehicle* /*fake*/);  template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, uint64 guid, Creature* /*fake*/);  template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, uint64 guid, Corpse* /*fake*/);  template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, uint64 guid, GameObject* /*fake*/); diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index 844a6b49e4d..2202748cd5a 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -33,6 +33,7 @@  #include "GridDefines.h"  #include "Object.h"  #include "Player.h" +#include "Vehicle.h"  #include <set> @@ -150,6 +151,7 @@ class TRINITY_DLL_DECL ObjectAccessor : public Trinity::Singleton<ObjectAccessor          static DynamicObject* GetDynamicObject(Unit const &, uint64);          static Corpse* GetCorpse(WorldObject const &u, uint64 guid);          static Pet* GetPet(uint64 guid); +        static Vehicle* GetVehicle(uint64 guid);          static Player* FindPlayer(uint64);          Player* FindPlayerByName(const char *name) ; diff --git a/src/game/ObjectDefines.h b/src/game/ObjectDefines.h index 88840ebd251..06072cb9917 100644 --- a/src/game/ObjectDefines.h +++ b/src/game/ObjectDefines.h @@ -41,6 +41,7 @@ enum HighGuid      HIGHGUID_TRANSPORT      = 0xF120,                       // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT)      HIGHGUID_UNIT           = 0xF130,                       // blizz F130      HIGHGUID_PET            = 0xF140,                       // blizz F140 +    HIGHGUID_VEHICLE        = 0xF150,                       // blizz F550      HIGHGUID_DYNAMICOBJECT  = 0xF100,                       // blizz F100      HIGHGUID_CORPSE         = 0xF101,                       // blizz F100      HIGHGUID_MO_TRANSPORT   = 0x1FC0,                       // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) @@ -50,6 +51,7 @@ enum HighGuid  #define IS_CREATURE_GUID(Guid)       ( GUID_HIPART(Guid) == HIGHGUID_UNIT )  #define IS_PET_GUID(Guid)            ( GUID_HIPART(Guid) == HIGHGUID_PET ) +#define IS_VEHICLE_GUID(Guid)        ( GUID_HIPART(Guid) == HIGHGUID_VEHICLE )  #define IS_CREATURE_OR_PET_GUID(Guid)( IS_CREATURE_GUID(Guid) || IS_PET_GUID(Guid) )  #define IS_PLAYER_GUID(Guid)         ( GUID_HIPART(Guid) == HIGHGUID_PLAYER && Guid!=0 )  #define IS_UNIT_GUID(Guid)           ( IS_CREATURE_OR_PET_GUID(Guid) || IS_PLAYER_GUID(Guid) ) @@ -87,6 +89,7 @@ inline bool IsGuidHaveEnPart(uint64 const& guid)          case HIGHGUID_TRANSPORT:          case HIGHGUID_UNIT:          case HIGHGUID_PET: +        case HIGHGUID_VEHICLE:          case HIGHGUID_MO_TRANSPORT:          default:              return true; @@ -106,6 +109,7 @@ inline char const* GetLogNameForGuid(uint64 guid)          case HIGHGUID_TRANSPORT:    return "transport";          case HIGHGUID_UNIT:         return "creature";          case HIGHGUID_PET:          return "pet"; +        case HIGHGUID_VEHICLE:      return "vehicle";          case HIGHGUID_DYNAMICOBJECT:return "dynobject";          case HIGHGUID_CORPSE:       return "corpse";          case HIGHGUID_MO_TRANSPORT: return "mo_transport"; diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index 0e2b6ae329d..e58ef1d7de5 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -59,7 +59,7 @@ ObjectGridRespawnMover::Visit(CreatureMapType &m)          Creature * c = iter->getSource(); -        assert(!c->isPet() && "ObjectGridRespawnMover don't must be called for pets"); +        assert((!c->isPet() || !c->isVehicle()) && "ObjectGridRespawnMover don't must be called for pets");          Cell const& cur_cell  = c->GetCurrentCell(); diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 594cfaf0877..5ae6b5b63e0 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -116,6 +116,7 @@ ObjectMgr::ObjectMgr()      m_hiCharGuid        = 1;      m_hiCreatureGuid    = 1;      m_hiPetGuid         = 1; +    m_hiVehicleGuid     = 1;      m_hiItemGuid        = 1;      m_hiGoGuid          = 1;      m_hiDoGuid          = 1; @@ -641,6 +642,22 @@ void ObjectMgr::LoadCreatureLocales()      sLog.outString( ">> Loaded %u creature locale strings", mCreatureLocaleMap.size() );  } +void ObjectMgr::LoadCompletedAchievements() +{ +    QueryResult *result = CharacterDatabase.Query("SELECT achievement FROM character_achievement GROUP BY achievement"); + +    if(!result) +        return; + +    do +    { +        Field *fields = result->Fetch(); +        allCompletedAchievements.insert(fields[0].GetUInt32()); +    } while(result->NextRow()); + +    delete result; +} +  void ObjectMgr::LoadNpcOptionLocales()  {      mNpcOptionLocaleMap.clear();                              // need for reload case @@ -1003,8 +1020,47 @@ void ObjectMgr::LoadEquipmentTemplates()  {      sEquipmentStorage.Load(); +    for(uint32 i=0; i< sEquipmentStorage.MaxEntry; ++i) +    { +        EquipmentInfo const* eqInfo = sEquipmentStorage.LookupEntry<EquipmentInfo>(i); + +        if(!eqInfo) +            continue; + +        for(uint8 j=0; j<3; j++) +        { +            if(!eqInfo->equipentry[j]) +               continue; + +            ItemEntry const *dbcitem = sItemStore.LookupEntry(eqInfo->equipentry[j]); + +            if(!dbcitem) +            { +                sLog.outErrorDb("Unknown item (entry=%u) in creature_equip_template.equipentry%u for entry = %u, forced to 0.", eqInfo->equipentry[j], j+1, i); +                const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0; +                continue; +            } + +            if(dbcitem->InventoryType != INVTYPE_WEAPON && +                    dbcitem->InventoryType != INVTYPE_SHIELD && +                    dbcitem->InventoryType != INVTYPE_RANGED && +                    dbcitem->InventoryType != INVTYPE_2HWEAPON && +                    dbcitem->InventoryType != INVTYPE_WEAPONMAINHAND && +                    dbcitem->InventoryType != INVTYPE_WEAPONOFFHAND && +                    dbcitem->InventoryType != INVTYPE_HOLDABLE && +                    dbcitem->InventoryType != INVTYPE_THROWN && +                    dbcitem->InventoryType != INVTYPE_RANGEDRIGHT) +            { +                sLog.outErrorDb("Item (entry=%u) in creature_equip_template.equipentry%u for entry = %u is not equipable in a hand, forced to 0.", eqInfo->equipentry[j], j+1, i); +                const_cast<EquipmentInfo*>(eqInfo)->equipentry[j] = 0; +            } +        } +    }      sLog.outString( ">> Loaded %u equipment template", sEquipmentStorage.RecordCount );      sLog.outString(); + +    // This DBC is currently only used for item templates and creature equipments checks. +    sItemStore.Clear();  }  CreatureModelInfo const* ObjectMgr::GetCreatureModelInfo(uint32 modelid) @@ -1678,7 +1734,7 @@ void ObjectMgr::LoadItemPrototypes()          if(proto->Class >= MAX_ITEM_CLASS)          {              sLog.outErrorDb("Item (Entry: %u) has wrong Class value (%u)",i,proto->Class); -            const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_JUNK; +            const_cast<ItemPrototype*>(proto)->Class = ITEM_CLASS_MISC;          }          if(proto->SubClass >= MaxItemSubclassValues[proto->Class]) @@ -1775,7 +1831,7 @@ void ObjectMgr::LoadItemPrototypes()          }          // special format -        if(proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) +        if((proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN) || (proto->Spells[0].SpellId == SPELL_ID_GENERIC_LEARN_PET))          {              // spell_1              if(proto->Spells[0].SpellTrigger != ITEM_SPELLTRIGGER_ON_USE) @@ -1812,7 +1868,7 @@ void ObjectMgr::LoadItemPrototypes()                      const_cast<ItemPrototype*>(proto)->Spells[1].SpellTrigger = ITEM_SPELLTRIGGER_ON_USE;                  }                  // allowed only in special format -                else if(proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) +                else if((proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[1].SpellId==SPELL_ID_GENERIC_LEARN_PET))                  {                      sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,1+1,proto->Spells[1].SpellId);                      const_cast<ItemPrototype*>(proto)->Spells[0].SpellId = 0; @@ -1858,7 +1914,7 @@ void ObjectMgr::LoadItemPrototypes()                          const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0;                      }                      // allowed only in special format -                    else if(proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) +                    else if((proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN) || (proto->Spells[j].SpellId==SPELL_ID_GENERIC_LEARN_PET))                      {                          sLog.outErrorDb("Item (Entry: %u) has broken spell in spellid_%d (%u)",i,j+1,proto->Spells[j].SpellId);                          const_cast<ItemPrototype*>(proto)->Spells[j].SpellId = 0; @@ -1927,14 +1983,12 @@ void ObjectMgr::LoadItemPrototypes()              const_cast<ItemPrototype*>(proto)->FoodType = 0;          }      } - -    // this DBC used currently only for check item templates in DB. -    sItemStore.Clear();  }  void ObjectMgr::LoadAuctionItems()  { -    QueryResult *result = CharacterDatabase.Query( "SELECT itemguid,item_template FROM auctionhouse" ); +    // data needs to be at first place for Item::LoadFromDB +    QueryResult *result = CharacterDatabase.Query( "SELECT data,itemguid,item_template FROM auctionhouse JOIN item_instance ON itemguid = guid" );      if( !result )          return; @@ -1949,8 +2003,8 @@ void ObjectMgr::LoadAuctionItems()          bar.step();          fields = result->Fetch(); -        uint32 item_guid        = fields[0].GetUInt32(); -        uint32 item_template    = fields[1].GetUInt32(); +        uint32 item_guid        = fields[1].GetUInt32(); +        uint32 item_template    = fields[2].GetUInt32();          ItemPrototype const *proto = GetItemPrototype(item_template); @@ -1962,7 +2016,7 @@ void ObjectMgr::LoadAuctionItems()          Item *item = NewItemOrBag(proto); -        if(!item->LoadFromDB(item_guid,0)) +        if(!item->LoadFromDB(item_guid,0, result))          {              delete item;              continue; @@ -2919,31 +2973,31 @@ void ObjectMgr::LoadQuests()      QueryResult *result = WorldDatabase.Query("SELECT entry, Method, ZoneOrSort, SkillOrClass, MinLevel, QuestLevel, Type, RequiredRaces, RequiredSkillValue,"      //   9                    10                 11                     12                   13                     14                   15                16          "RepObjectiveFaction, RepObjectiveValue, RequiredMinRepFaction, RequiredMinRepValue, RequiredMaxRepFaction, RequiredMaxRepValue, SuggestedPlayers, LimitTime," -    //   17          18            19           20           21           22              23                24         25            26 -        "QuestFlags, SpecialFlags, CharTitleId, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell," -    //   27     28       29          30               31                32       33              34              35              36 +    //   17          18            19           20            21            22           23           24              25                26         27            28 +        "QuestFlags, SpecialFlags, CharTitleId, PlayersSlain, BonusTalents, PrevQuestId, NextQuestId, ExclusiveGroup, NextQuestInChain, SrcItemId, SrcItemCount, SrcSpell," +    //   29     30       31          32               33                34       35              36              37              38          "Title, Details, Objectives, OfferRewardText, RequestItemsText, EndText, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4," -    //   37          38          39          40          41             42             43             44 +    //   39          40          41          42          43             44             45             46          "ReqItemId1, ReqItemId2, ReqItemId3, ReqItemId4, ReqItemCount1, ReqItemCount2, ReqItemCount3, ReqItemCount4," -    //   45            46            47            48            49               50               51               52               53             54             54             55 +    //   47            48            49            50            51               52               53               54               55             56             57             58          "ReqSourceId1, ReqSourceId2, ReqSourceId3, ReqSourceId4, ReqSourceCount1, ReqSourceCount2, ReqSourceCount3, ReqSourceCount4, ReqSourceRef1, ReqSourceRef2, ReqSourceRef3, ReqSourceRef4," -    //   57                  58                  59                  60                  61                     62                     63                     64 +    //   59                  60                  61                  62                  63                     64                     65                     66          "ReqCreatureOrGOId1, ReqCreatureOrGOId2, ReqCreatureOrGOId3, ReqCreatureOrGOId4, ReqCreatureOrGOCount1, ReqCreatureOrGOCount2, ReqCreatureOrGOCount3, ReqCreatureOrGOCount4," -    //   65             66             67             68 +    //   67             68             69             70          "ReqSpellCast1, ReqSpellCast2, ReqSpellCast3, ReqSpellCast4," -    //   69                70                71                72                73                74 +    //   71                72                73                74                75                76          "RewChoiceItemId1, RewChoiceItemId2, RewChoiceItemId3, RewChoiceItemId4, RewChoiceItemId5, RewChoiceItemId6," -    //   75                   76                   77                   78                   79                   80 +    //   77                   78                   79                   80                   81                   82          "RewChoiceItemCount1, RewChoiceItemCount2, RewChoiceItemCount3, RewChoiceItemCount4, RewChoiceItemCount5, RewChoiceItemCount6," -    //   81          82          83          84          85             86             87             88 +    //   83          84          85          86          87             88             89             90          "RewItemId1, RewItemId2, RewItemId3, RewItemId4, RewItemCount1, RewItemCount2, RewItemCount3, RewItemCount4," -    //   89              90              91              92              93              94            95            96            97            98 +    //   91              92              93              94              95              96            97            98            99            100          "RewRepFaction1, RewRepFaction2, RewRepFaction3, RewRepFaction4, RewRepFaction5, RewRepValue1, RewRepValue2, RewRepValue3, RewRepValue4, RewRepValue5," -    //   99                 100            101               102       103           104                105               106         107     108    109 +    //   101                102            103               104       105           106                107               108         109     110     111          "RewHonorableKills, RewOrReqMoney, RewMoneyMaxLevel, RewSpell, RewSpellCast, RewMailTemplateId, RewMailDelaySecs, PointMapId, PointX, PointY, PointOpt," -    //   110            111            112           113              114            115                116                117                118             119 +    //   112            113            114            115           116              117            118                119                120                121          "DetailsEmote1, DetailsEmote2, DetailsEmote3, DetailsEmote4,IncompleteEmote, CompleteEmote, OfferRewardEmote1, OfferRewardEmote2, OfferRewardEmote3, OfferRewardEmote4," -    //   120            121 +    //   122          123          "StartScript, CompleteScript"          " FROM quest_template");      if(result == NULL) @@ -4776,17 +4830,19 @@ uint16 ObjectMgr::GetTaxiMount( uint32 id, uint32 team )      TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(id);      if(node)      { -        if (team == ALLIANCE) mount_entry = node->alliance_mount_type; -        else mount_entry = node->horde_mount_type; - -        CreatureInfo const *cinfo = GetCreatureTemplate(mount_entry); -        if (cinfo) +        if (team == ALLIANCE)          { -            if(! (mount_id = cinfo->GetRandomValidModelId())) -            { -                sLog.outErrorDb("No displayid found for the taxi mount with the entry %u! Can't load it!", mount_entry); -                return false; -            } +            mount_entry = node->MountCreatureID[1]; +            CreatureInfo const *ci = GetCreatureTemplate(mount_entry); +            if(ci) +                mount_id = ci->Modelid1; +        } +        if (team == HORDE) +        { +            mount_entry = node->MountCreatureID[0]; +            CreatureInfo const *ci = GetCreatureTemplate(mount_entry); +            if(ci) +                mount_id = ci->Modelid3;          }      } @@ -5265,6 +5321,8 @@ void ObjectMgr::SetHighestGuids()      // pet guids are not saved to DB, set to 0 (pet guid != pet id)      m_hiPetGuid = 0; +    // same for vehicles +    m_hiVehicleGuid = 0;      result = CharacterDatabase.Query( "SELECT MAX(guid) FROM item_instance" );      if( result ) @@ -5418,6 +5476,14 @@ uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh)                  World::StopNow(ERROR_EXIT_CODE);              }              return m_hiPetGuid++; +        case HIGHGUID_VEHICLE: +            ++m_hiVehicleGuid; +            if(m_hiVehicleGuid>=0x00FFFFFF) +            { +                sLog.outError("Vehicle guid overflow!! Can't continue, shutting down server. "); +                World::StopNow(ERROR_EXIT_CODE); +            } +            return m_hiVehicleGuid++;          case HIGHGUID_PLAYER:              if(m_hiCharGuid>=0xFFFFFFFE)              { @@ -6380,6 +6446,23 @@ int ObjectMgr::GetOrNewIndexForLocale( LocaleConstant loc )      return m_LocalForIndex.size()-1;  } +AchievementCriteriaEntryList const& ObjectMgr::GetAchievementCriteriaByType(AchievementCriteriaTypes type) +{ +    return m_AchievementCriteriasByType[type]; +} + +void ObjectMgr::LoadAchievementCriteriaList() +{ +    for (uint32 entryId = 0; entryId<sAchievementCriteriaStore.GetNumRows(); entryId++) +    { +        AchievementCriteriaEntry const* criteria = sAchievementCriteriaStore.LookupEntry(entryId); +        if(!criteria) +            continue; + +        m_AchievementCriteriasByType[criteria->requiredType].push_back(criteria); +    } +} +  void ObjectMgr::LoadBattleMastersEntry()  {      mBattleMastersMap.clear();                              // need for reload case @@ -6756,7 +6839,7 @@ bool PlayerCondition::Meets(Player const * player) const          {              Unit::AuraMap const& auras = player->GetAuras();              for(Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) -                if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual==3580) +                if((itr->second->GetSpellProto()->Attributes & 0x1000010) && itr->second->GetSpellProto()->SpellVisual[0]==3580)                      return true;              return false;          } @@ -6933,7 +7016,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)                  return SKILL_RANGE_MONO;          case SKILL_CATEGORY_ARMOR:          case SKILL_CATEGORY_CLASS: -            if(pSkill->id != SKILL_POISONS && pSkill->id != SKILL_LOCKPICKING) +            if(pSkill->id != SKILL_LOCKPICKING)                  return SKILL_RANGE_MONO;              else                  return SKILL_RANGE_LEVEL; @@ -6948,7 +7031,7 @@ SkillRangeType GetSkillRangeType(SkillLineEntry const *pSkill, bool racial)                  return SKILL_RANGE_MONO;          default:          case SKILL_CATEGORY_ATTRIBUTES:                     //not found in dbc -        case SKILL_CATEGORY_NOT_DISPLAYED:                  //only GENEREC(DND) +        case SKILL_CATEGORY_GENERIC:                        //only GENERIC(DND)              return SKILL_RANGE_NONE;      }  } diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 4a35f98b679..ccb3884b163 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -264,6 +264,8 @@ typedef std::list<GossipOption> CacheNpcOptionList;  typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap;  typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap; +typedef std::list<const AchievementCriteriaEntry*> AchievementCriteriaEntryList; +  enum SkillRangeType  {      SKILL_RANGE_LANGUAGE,                                   // 300..300 @@ -588,6 +590,7 @@ class ObjectMgr          void LoadNpcTextId();          void LoadVendors();          void LoadTrainerSpell(); +        void LoadCompletedAchievements();          std::string GeneratePetName(uint32 entry);          uint32 GetBaseXP(uint32 level); @@ -801,6 +804,10 @@ class ObjectMgr          bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event          bool IsVendorItemValid( uint32 vendor_entry, uint32 item, uint32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0 ) const; +        void LoadAchievementCriteriaList(); +        AchievementCriteriaEntryList const& GetAchievementCriteriaByType(AchievementCriteriaTypes type); +        std::set<uint32> allCompletedAchievements; +          void LoadScriptNames();          ScriptNameMap &GetScriptNames() { return m_scriptNames; }          const char * GetScriptName(uint32 id) { return id < m_scriptNames.size() ? m_scriptNames[id].c_str() : ""; } @@ -819,6 +826,7 @@ class ObjectMgr          uint32 m_hiCharGuid;          uint32 m_hiCreatureGuid;          uint32 m_hiPetGuid; +        uint32 m_hiVehicleGuid;          uint32 m_hiItemGuid;          uint32 m_hiGoGuid;          uint32 m_hiDoGuid; @@ -929,6 +937,9 @@ class ObjectMgr          CacheNpcTextIdMap m_mCacheNpcTextIdMap;          CacheVendorItemMap m_mCacheVendorItemMap;          CacheTrainerSpellMap m_mCacheTrainerSpellMap; + +        // store achievement criterias by type to speed up lookup +        AchievementCriteriaEntryList m_AchievementCriteriasByType[ACHIEVEMENT_CRITERIA_TYPE_TOTAL];  };  #define objmgr Trinity::Singleton<ObjectMgr>::Instance() diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index 57c3c0ca879..0fa8e9573d0 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -28,1064 +28,1194 @@  /// Correspondence between opcodes and their names  OpcodeHandler opcodeTable[NUM_MSG_TYPES] =  { -    /*0x000*/ { "MSG_NULL_ACTION",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x001*/ { "CMSG_BOOTME",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x002*/ { "CMSG_DBLOOKUP",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x003*/ { "SMSG_DBLOOKUP",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x008*/ { "CMSG_WORLD_TELEPORT",              STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode       }, -    /*0x009*/ { "CMSG_TELEPORT_TO_UNIT",            STATUS_LOGGEDIN, &WorldSession::Handle_NULL                     }, -    /*0x00A*/ { "CMSG_ZONE_MAP",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x00B*/ { "SMSG_ZONE_MAP",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x00D*/ { "CMSG_EMBLAZON_TABARD_OBSOLETE",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x00E*/ { "CMSG_UNEMBLAZON_TABARD_OBSOLETE",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x00F*/ { "CMSG_RECHARGE",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x010*/ { "CMSG_LEARN_SPELL",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x011*/ { "CMSG_CREATEMONSTER",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x012*/ { "CMSG_DESTROYMONSTER",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x013*/ { "CMSG_CREATEITEM",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x014*/ { "CMSG_CREATEGAMEOBJECT",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x015*/ { "SMSG_CHECK_FOR_BOTS",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x017*/ { "CMSG_BOT_DETECTED2",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x018*/ { "CMSG_FORCEACTION",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x019*/ { "CMSG_FORCEACTIONONOTHER",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x01A*/ { "CMSG_FORCEACTIONSHOW",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x01B*/ { "SMSG_FORCEACTIONSHOW",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x01C*/ { "CMSG_PETGODMODE",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x01D*/ { "SMSG_PETGODMODE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x01E*/ { "SMSG_DEBUGINFOSPELLMISS_OBSOLETE", STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x020*/ { "CMSG_UNDRESSPLAYER",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x021*/ { "CMSG_BEASTMASTER",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x022*/ { "CMSG_GODMODE",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x023*/ { "SMSG_GODMODE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x024*/ { "CMSG_CHEAT_SETMONEY",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x025*/ { "CMSG_LEVEL_CHEAT",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x026*/ { "CMSG_PET_LEVEL_CHEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x027*/ { "CMSG_SET_WORLDSTATE",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x028*/ { "CMSG_COOLDOWN_CHEAT",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x029*/ { "CMSG_USE_SKILL_CHEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x02A*/ { "CMSG_FLAG_QUEST",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x02C*/ { "CMSG_CLEAR_QUEST",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x02D*/ { "CMSG_SEND_EVENT",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x02E*/ { "CMSG_DEBUG_AISTATE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x02F*/ { "SMSG_DEBUG_AISTATE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x032*/ { "CMSG_PVP_PORT_OBSOLETE",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x034*/ { "CMSG_AUTH_SRP6_PROOF",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x035*/ { "CMSG_AUTH_SRP6_RECODE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x036*/ { "CMSG_CHAR_CREATE",                 STATUS_AUTHED,   &WorldSession::HandleCharCreateOpcode          }, -    /*0x037*/ { "CMSG_CHAR_ENUM",                   STATUS_AUTHED,   &WorldSession::HandleCharEnumOpcode            }, -    /*0x038*/ { "CMSG_CHAR_DELETE",                 STATUS_AUTHED,   &WorldSession::HandleCharDeleteOpcode          }, -    /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x03A*/ { "SMSG_CHAR_CREATE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x03B*/ { "SMSG_CHAR_ENUM",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x03C*/ { "SMSG_CHAR_DELETE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x03D*/ { "CMSG_PLAYER_LOGIN",                STATUS_AUTHED,   &WorldSession::HandlePlayerLoginOpcode         }, -    /*0x03E*/ { "SMSG_NEW_WORLD",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x03F*/ { "SMSG_TRANSFER_PENDING",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x040*/ { "SMSG_TRANSFER_ABORTED",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x043*/ { "SMSG_GAMETIME_UPDATE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x044*/ { "CMSG_GAMETIME_SET",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x045*/ { "SMSG_GAMETIME_SET",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x046*/ { "CMSG_GAMESPEED_SET",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x047*/ { "SMSG_GAMESPEED_SET",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x048*/ { "CMSG_SERVERTIME",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x049*/ { "SMSG_SERVERTIME",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x04A*/ { "CMSG_PLAYER_LOGOUT",               STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode        }, -    /*0x04B*/ { "CMSG_LOGOUT_REQUEST",              STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode       }, -    /*0x04C*/ { "SMSG_LOGOUT_RESPONSE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x04D*/ { "SMSG_LOGOUT_COMPLETE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x04E*/ { "CMSG_LOGOUT_CANCEL",               STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode        }, -    /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x050*/ { "CMSG_NAME_QUERY",                  STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode           }, -    /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x052*/ { "CMSG_PET_NAME_QUERY",              STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery              }, -    /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x054*/ { "CMSG_GUILD_QUERY",                 STATUS_AUTHED,   &WorldSession::HandleGuildQueryOpcode          }, -    /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE",           STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode     }, -    /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY",             STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode           }, -    /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x05C*/ { "CMSG_QUEST_QUERY",                 STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode          }, -    /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY",            STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode     }, -    /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x060*/ { "CMSG_CREATURE_QUERY",              STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode       }, -    /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x062*/ { "CMSG_WHO",                         STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode                 }, -    /*0x063*/ { "SMSG_WHO",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x064*/ { "CMSG_WHOIS",                       STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode               }, -    /*0x065*/ { "SMSG_WHOIS",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x066*/ { "CMSG_CONTACT_LIST",                STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode          }, -    /*0x067*/ { "SMSG_CONTACT_LIST",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x068*/ { "SMSG_FRIEND_STATUS",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x069*/ { "CMSG_ADD_FRIEND",                  STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode           }, -    /*0x06A*/ { "CMSG_DEL_FRIEND",                  STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode           }, -    /*0x06B*/ { "CMSG_SET_CONTACT_NOTES",           STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode       }, -    /*0x06C*/ { "CMSG_ADD_IGNORE",                  STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode           }, -    /*0x06D*/ { "CMSG_DEL_IGNORE",                  STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode           }, -    /*0x06E*/ { "CMSG_GROUP_INVITE",                STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode         }, -    /*0x06F*/ { "SMSG_GROUP_INVITE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x070*/ { "CMSG_GROUP_CANCEL",                STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated               }, -    /*0x071*/ { "SMSG_GROUP_CANCEL",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x072*/ { "CMSG_GROUP_ACCEPT",                STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode         }, -    /*0x073*/ { "CMSG_GROUP_DECLINE",               STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode        }, -    /*0x074*/ { "SMSG_GROUP_DECLINE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x075*/ { "CMSG_GROUP_UNINVITE",              STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode   }, -    /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID",         STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode   }, -    /*0x077*/ { "SMSG_GROUP_UNINVITE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x078*/ { "CMSG_GROUP_SET_LEADER",            STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode      }, -    /*0x079*/ { "SMSG_GROUP_SET_LEADER",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x07A*/ { "CMSG_LOOT_METHOD",                 STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode          }, -    /*0x07B*/ { "CMSG_GROUP_DISBAND",               STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode          }, -    /*0x07C*/ { "SMSG_GROUP_DESTROYED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x07D*/ { "SMSG_GROUP_LIST",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x081*/ { "CMSG_GUILD_CREATE",                STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode         }, -    /*0x082*/ { "CMSG_GUILD_INVITE",                STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode         }, -    /*0x083*/ { "SMSG_GUILD_INVITE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x084*/ { "CMSG_GUILD_ACCEPT",                STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode         }, -    /*0x085*/ { "CMSG_GUILD_DECLINE",               STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode        }, -    /*0x086*/ { "SMSG_GUILD_DECLINE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x087*/ { "CMSG_GUILD_INFO",                  STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode           }, -    /*0x088*/ { "SMSG_GUILD_INFO",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x089*/ { "CMSG_GUILD_ROSTER",                STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode         }, -    /*0x08A*/ { "SMSG_GUILD_ROSTER",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x08B*/ { "CMSG_GUILD_PROMOTE",               STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode        }, -    /*0x08C*/ { "CMSG_GUILD_DEMOTE",                STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode         }, -    /*0x08D*/ { "CMSG_GUILD_LEAVE",                 STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode          }, -    /*0x08E*/ { "CMSG_GUILD_REMOVE",                STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode         }, -    /*0x08F*/ { "CMSG_GUILD_DISBAND",               STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode        }, -    /*0x090*/ { "CMSG_GUILD_LEADER",                STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode         }, -    /*0x091*/ { "CMSG_GUILD_MOTD",                  STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode           }, -    /*0x092*/ { "SMSG_GUILD_EVENT",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x094*/ { "UMSG_UPDATE_GUILD",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x095*/ { "CMSG_MESSAGECHAT",                 STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode         }, -    /*0x096*/ { "SMSG_MESSAGECHAT",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x097*/ { "CMSG_JOIN_CHANNEL",                STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin               }, -    /*0x098*/ { "CMSG_LEAVE_CHANNEL",               STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave              }, -    /*0x099*/ { "SMSG_CHANNEL_NOTIFY",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x09A*/ { "CMSG_CHANNEL_LIST",                STATUS_LOGGEDIN, &WorldSession::HandleChannelList               }, -    /*0x09B*/ { "SMSG_CHANNEL_LIST",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x09C*/ { "CMSG_CHANNEL_PASSWORD",            STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword           }, -    /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER",           STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner           }, -    /*0x09E*/ { "CMSG_CHANNEL_OWNER",               STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner              }, -    /*0x09F*/ { "CMSG_CHANNEL_MODERATOR",           STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator          }, -    /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR",         STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator        }, -    /*0x0A1*/ { "CMSG_CHANNEL_MUTE",                STATUS_LOGGEDIN, &WorldSession::HandleChannelMute               }, -    /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE",              STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute             }, -    /*0x0A3*/ { "CMSG_CHANNEL_INVITE",              STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite             }, -    /*0x0A4*/ { "CMSG_CHANNEL_KICK",                STATUS_LOGGEDIN, &WorldSession::HandleChannelKick               }, -    /*0x0A5*/ { "CMSG_CHANNEL_BAN",                 STATUS_LOGGEDIN, &WorldSession::HandleChannelBan                }, -    /*0x0A6*/ { "CMSG_CHANNEL_UNBAN",               STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban              }, -    /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS",       STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce           }, -    /*0x0A8*/ { "CMSG_CHANNEL_MODERATE",            STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate           }, -    /*0x0A9*/ { "SMSG_UPDATE_OBJECT",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0AA*/ { "SMSG_DESTROY_OBJECT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0AB*/ { "CMSG_USE_ITEM",                    STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode             }, -    /*0x0AC*/ { "CMSG_OPEN_ITEM",                   STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode            }, -    /*0x0AD*/ { "CMSG_READ_ITEM",                   STATUS_LOGGEDIN, &WorldSession::HandleReadItem                  }, -    /*0x0AE*/ { "SMSG_READ_ITEM_OK",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0AF*/ { "SMSG_READ_ITEM_FAILED",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0B0*/ { "SMSG_ITEM_COOLDOWN",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0B1*/ { "CMSG_GAMEOBJ_USE",                 STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode       }, -    /*0x0B2*/ { "CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0B4*/ { "CMSG_AREATRIGGER",                 STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode         }, -    /*0x0B5*/ { "MSG_MOVE_START_FORWARD",           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0B6*/ { "MSG_MOVE_START_BACKWARD",          STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0B7*/ { "MSG_MOVE_STOP",                    STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT",       STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT",      STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE",             STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0BB*/ { "MSG_MOVE_JUMP",                    STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT",         STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT",        STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0BE*/ { "MSG_MOVE_STOP_TURN",               STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP",          STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN",        STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0C1*/ { "MSG_MOVE_STOP_PITCH",              STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE",            STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE",           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0C5*/ { "MSG_MOVE_TELEPORT",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK",            STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck           }, -    /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0C9*/ { "MSG_MOVE_FALL_LAND",               STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0CA*/ { "MSG_MOVE_START_SWIM",              STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0CB*/ { "MSG_MOVE_STOP_SWIM",               STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT",STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT",STATUS_NEVER,   &WorldSession::Handle_NULL                     }, -    /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0DA*/ { "MSG_MOVE_SET_FACING",              STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0DB*/ { "MSG_MOVE_SET_PITCH",               STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK",           STATUS_TRANSFER_PENDING, &WorldSession::HandleMoveWorldportAckOpcode}, -    /*0x0DD*/ { "SMSG_MONSTER_MOVE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0DE*/ { "SMSG_MOVE_WATER_WALK",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0DF*/ { "SMSG_MOVE_LAND_WALK",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK",  STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, -    /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE", STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck     }, -    /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, -    /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK",         STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck               }, -    /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK",       STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck             }, -    /*0x0EC*/ { "MSG_MOVE_ROOT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0ED*/ { "MSG_MOVE_UNROOT",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0EE*/ { "MSG_MOVE_HEARTBEAT",               STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK",         STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck          }, -    /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0F4*/ { "SMSG_MOVE_SET_HOVER",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK",              STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck              }, -    /*0x0F7*/ { "MSG_MOVE_HOVER",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0F9*/ { "CMSG_OPENING_CINEMATIC",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA",       STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera       }, -    /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC",          STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema            }, -    /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x0FE*/ { "CMSG_TUTORIAL_FLAG",               STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag              }, -    /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR",              STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear             }, -    /*0x100*/ { "CMSG_TUTORIAL_RESET",              STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset             }, -    /*0x101*/ { "CMSG_STANDSTATECHANGE",            STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode    }, -    /*0x102*/ { "CMSG_EMOTE",                       STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode               }, -    /*0x103*/ { "SMSG_EMOTE",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x104*/ { "CMSG_TEXT_EMOTE",                  STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode           }, -    /*0x105*/ { "SMSG_TEXT_EMOTE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM",         STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode   }, -    /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM",              STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode       }, -    /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM",          STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode    }, -    /*0x10C*/ { "CMSG_SWAP_ITEM",                   STATUS_LOGGEDIN, &WorldSession::HandleSwapItem                  }, -    /*0x10D*/ { "CMSG_SWAP_INV_ITEM",               STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode         }, -    /*0x10E*/ { "CMSG_SPLIT_ITEM",                  STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode           }, -    /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT",         STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode   }, -    /*0x110*/ { "OBSOLETE_DROP_ITEM",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x111*/ { "CMSG_DESTROYITEM",                 STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode         }, -    /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x113*/ { "SMSG_OPEN_CONTAINER",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x114*/ { "CMSG_INSPECT",                     STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode             }, -    /*0x115*/ { "SMSG_INSPECT",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x116*/ { "CMSG_INITIATE_TRADE",              STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode       }, -    /*0x117*/ { "CMSG_BEGIN_TRADE",                 STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode          }, -    /*0x118*/ { "CMSG_BUSY_TRADE",                  STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode           }, -    /*0x119*/ { "CMSG_IGNORE_TRADE",                STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode         }, -    /*0x11A*/ { "CMSG_ACCEPT_TRADE",                STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode         }, -    /*0x11B*/ { "CMSG_UNACCEPT_TRADE",              STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode       }, -    /*0x11C*/ { "CMSG_CANCEL_TRADE",                STATUS_AUTHED,   &WorldSession::HandleCancelTradeOpcode         }, -    /*0x11D*/ { "CMSG_SET_TRADE_ITEM",              STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode        }, -    /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM",            STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode      }, -    /*0x11F*/ { "CMSG_SET_TRADE_GOLD",              STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode        }, -    /*0x120*/ { "SMSG_TRADE_STATUS",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x122*/ { "SMSG_INITIALIZE_FACTIONS",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x123*/ { "SMSG_SET_FACTION_VISIBLE",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x124*/ { "SMSG_SET_FACTION_STANDING",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x125*/ { "CMSG_SET_FACTION_ATWAR",           STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar           }, -    /*0x126*/ { "CMSG_SET_FACTION_CHEAT",           STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat           }, -    /*0x127*/ { "SMSG_SET_PROFICIENCY",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x128*/ { "CMSG_SET_ACTION_BUTTON",           STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode     }, -    /*0x129*/ { "SMSG_ACTION_BUTTONS",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x12A*/ { "SMSG_INITIAL_SPELLS",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x12B*/ { "SMSG_LEARNED_SPELL",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x12C*/ { "SMSG_SUPERCEDED_SPELL",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x12D*/ { "CMSG_NEW_SPELL_SLOT",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x12E*/ { "CMSG_CAST_SPELL",                  STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode           }, -    /*0x12F*/ { "CMSG_CANCEL_CAST",                 STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode          }, -    /*0x130*/ { "SMSG_CAST_FAILED",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x131*/ { "SMSG_SPELL_START",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x132*/ { "SMSG_SPELL_GO",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x133*/ { "SMSG_SPELL_FAILURE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x134*/ { "SMSG_SPELL_COOLDOWN",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x135*/ { "SMSG_COOLDOWN_EVENT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x136*/ { "CMSG_CANCEL_AURA",                 STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode          }, -    /*0x137*/ { "SMSG_UPDATE_AURA_DURATION",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x138*/ { "SMSG_PET_CAST_FAILED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x139*/ { "MSG_CHANNEL_START",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x13A*/ { "MSG_CHANNEL_UPDATE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x13B*/ { "CMSG_CANCEL_CHANNELLING",          STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling          }, -    /*0x13C*/ { "SMSG_AI_REACTION",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x13D*/ { "CMSG_SET_SELECTION",               STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode        }, -    /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE",         STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode           }, -    /*0x13F*/ { "CMSG_UNUSED",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x140*/ { "CMSG_UNUSED2",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x141*/ { "CMSG_ATTACKSWING",                 STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode         }, -    /*0x142*/ { "CMSG_ATTACKSTOP",                  STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode          }, -    /*0x143*/ { "SMSG_ATTACKSTART",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x144*/ { "SMSG_ATTACKSTOP",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x146*/ { "SMSG_ATTACKSWING_BADFACING",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x14E*/ { "SMSG_CANCEL_COMBAT",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x14F*/ { "SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE",STATUS_NEVER,  &WorldSession::Handle_ServerSide               }, -    /*0x150*/ { "SMSG_SPELLHEALLOG",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x151*/ { "SMSG_SPELLENERGIZELOG",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x152*/ { "CMSG_SHEATHE_OBSOLETE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x153*/ { "CMSG_SAVE_PLAYER",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x154*/ { "CMSG_SETDEATHBINDPOINT",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x155*/ { "SMSG_BINDPOINTUPDATE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x156*/ { "CMSG_GETDEATHBINDZONE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x157*/ { "SMSG_BINDZONEREPLY",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x158*/ { "SMSG_PLAYERBOUND",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x15A*/ { "CMSG_REPOP_REQUEST",               STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode        }, -    /*0x15B*/ { "SMSG_RESURRECT_REQUEST",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x15C*/ { "CMSG_RESURRECT_RESPONSE",          STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode   }, -    /*0x15D*/ { "CMSG_LOOT",                        STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode                }, -    /*0x15E*/ { "CMSG_LOOT_MONEY",                  STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode           }, -    /*0x15F*/ { "CMSG_LOOT_RELEASE",                STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode         }, -    /*0x160*/ { "SMSG_LOOT_RESPONSE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x162*/ { "SMSG_LOOT_REMOVED",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x166*/ { "SMSG_ITEM_PUSH_RESULT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x167*/ { "SMSG_DUEL_REQUESTED",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x169*/ { "SMSG_DUEL_INBOUNDS",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x16A*/ { "SMSG_DUEL_COMPLETE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x16B*/ { "SMSG_DUEL_WINNER",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x16C*/ { "CMSG_DUEL_ACCEPTED",               STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode        }, -    /*0x16D*/ { "CMSG_DUEL_CANCELLED",              STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode       }, -    /*0x16E*/ { "SMSG_MOUNTRESULT",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x16F*/ { "SMSG_DISMOUNTRESULT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM",           STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode    }, -    /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x173*/ { "SMSG_PET_TAME_FAILURE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x174*/ { "CMSG_PET_SET_ACTION",              STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction              }, -    /*0x175*/ { "CMSG_PET_ACTION",                  STATUS_LOGGEDIN, &WorldSession::HandlePetAction                 }, -    /*0x176*/ { "CMSG_PET_ABANDON",                 STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon                }, -    /*0x177*/ { "CMSG_PET_RENAME",                  STATUS_LOGGEDIN, &WorldSession::HandlePetRename                 }, -    /*0x178*/ { "SMSG_PET_NAME_INVALID",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x179*/ { "SMSG_PET_SPELLS",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x17A*/ { "SMSG_PET_MODE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x17B*/ { "CMSG_GOSSIP_HELLO",                STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode         }, -    /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION",        STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode  }, -    /*0x17D*/ { "SMSG_GOSSIP_MESSAGE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x17E*/ { "SMSG_GOSSIP_COMPLETE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x17F*/ { "CMSG_NPC_TEXT_QUERY",              STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode        }, -    /*0x180*/ { "SMSG_NPC_TEXT_UPDATE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x181*/ { "SMSG_NPC_WONT_TALK",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY",     STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode}, -    /*0x183*/ { "SMSG_QUESTGIVER_STATUS",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x184*/ { "CMSG_QUESTGIVER_HELLO",            STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode     }, -    /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST",      STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode}, -    /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH", STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch           }, -    /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST",     STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode}, -    /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST",   STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete             }, -    /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD",   STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode}, -    /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD",    STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode}, -    /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x190*/ { "CMSG_QUESTGIVER_CANCEL",           STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel          }, -    /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST",         STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest         }, -    /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST",       STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest       }, -    /*0x195*/ { "SMSG_QUESTLOG_FULL",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x196*/ { "SMSG_QUESTUPDATE_FAILED",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT",        STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept        }, -    /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY",            STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty          }, -    /*0x19E*/ { "CMSG_LIST_INVENTORY",              STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode       }, -    /*0x19F*/ { "SMSG_LIST_INVENTORY",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1A0*/ { "CMSG_SELL_ITEM",                   STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode            }, -    /*0x1A1*/ { "SMSG_SELL_ITEM",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1A2*/ { "CMSG_BUY_ITEM",                    STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode             }, -    /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT",            STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode       }, -    /*0x1A4*/ { "SMSG_BUY_ITEM",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1A5*/ { "SMSG_BUY_FAILED",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1A6*/ { "CMSG_TAXICLEARALLNODES",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1A8*/ { "CMSG_TAXISHOWNODES",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1A9*/ { "SMSG_SHOWTAXINODES",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY",       STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode }, -    /*0x1AB*/ { "SMSG_TAXINODE_STATUS",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES",     STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodesOpcode}, -    /*0x1AD*/ { "CMSG_ACTIVATETAXI",                STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode        }, -    /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1AF*/ { "SMSG_NEW_TAXI_PATH",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1B0*/ { "CMSG_TRAINER_LIST",                STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode         }, -    /*0x1B1*/ { "SMSG_TRAINER_LIST",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL",           STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode     }, -    /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1B5*/ { "CMSG_BINDER_ACTIVATE",             STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode      }, -    /*0x1B6*/ { "SMSG_PLAYERBINDERROR",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1B7*/ { "CMSG_BANKER_ACTIVATE",             STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode      }, -    /*0x1B8*/ { "SMSG_SHOW_BANK",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1B9*/ { "CMSG_BUY_BANK_SLOT",               STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode         }, -    /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1BB*/ { "CMSG_PETITION_SHOWLIST",           STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode    }, -    /*0x1BC*/ { "SMSG_PETITION_SHOWLIST",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1BD*/ { "CMSG_PETITION_BUY",                STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode         }, -    /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES",    STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode    }, -    /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1C0*/ { "CMSG_PETITION_SIGN",               STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode        }, -    /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1C2*/ { "MSG_PETITION_DECLINE",             STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode     }, -    /*0x1C3*/ { "CMSG_OFFER_PETITION",              STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode       }, -    /*0x1C4*/ { "CMSG_TURN_IN_PETITION",            STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode      }, -    /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1C6*/ { "CMSG_PETITION_QUERY",              STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode       }, -    /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1C9*/ { "SMSG_FISH_ESCAPED",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1CA*/ { "CMSG_BUG",                         STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode                 }, -    /*0x1CB*/ { "SMSG_NOTIFICATION",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1CC*/ { "CMSG_PLAYED_TIME",                 STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime                }, -    /*0x1CD*/ { "SMSG_PLAYED_TIME",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1CE*/ { "CMSG_QUERY_TIME",                  STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode           }, -    /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1D0*/ { "SMSG_LOG_XPGAIN",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1D1*/ { "SMSG_AURACASTLOG",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1D2*/ { "CMSG_RECLAIM_CORPSE",              STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode       }, -    /*0x1D3*/ { "CMSG_WRAP_ITEM",                   STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode            }, -    /*0x1D4*/ { "SMSG_LEVELUP_INFO",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1D5*/ { "MSG_MINIMAP_PING",                 STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode         }, -    /*0x1D6*/ { "SMSG_RESISTLOG",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1D7*/ { "SMSG_ENCHANTMENTLOG",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1D9*/ { "SMSG_START_MIRROR_TIMER",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1DC*/ { "CMSG_PING",                        STATUS_NEVER,    &WorldSession::Handle_EarlyProccess            }, -    /*0x1DD*/ { "SMSG_PONG",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1E0*/ { "CMSG_SETSHEATHED",                 STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode         }, -    /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1E2*/ { "SMSG_SPELL_DELAYED",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1E5*/ { "CMSG_GHOST",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1E6*/ { "CMSG_GM_INVIS",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1E8*/ { "MSG_GM_BIND_OTHER",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1E9*/ { "MSG_GM_SUMMON",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1EC*/ { "SMSG_AUTH_CHALLENGE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1ED*/ { "CMSG_AUTH_SESSION",                STATUS_NEVER,    &WorldSession::Handle_EarlyProccess            }, -    /*0x1EE*/ { "SMSG_AUTH_RESPONSE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1EF*/ { "MSG_GM_SHOWLABEL",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1F0*/ { "CMSG_PET_CAST_SPELL",              STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode        }, -    /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM",            STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode     }, -    /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE",        STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode}, -    /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1F4*/ { "CMSG_ZONEUPDATE",                  STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode          }, -    /*0x1F5*/ { "SMSG_PARTYKILLLOG",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1FA*/ { "CMSG_GM_NUKE",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1FB*/ { "MSG_RANDOM_ROLL",                  STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode          }, -    /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x1FE*/ { "SMSG_RWHOIS",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP",            STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup           }, -    /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP",       STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode              }, -    /*0x201*/ { "CMSG_UNLEARN_SPELL",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x202*/ { "CMSG_UNLEARN_SKILL",               STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode        }, -    /*0x203*/ { "SMSG_REMOVED_SPELL",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x204*/ { "CMSG_DECHARGE",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x205*/ { "CMSG_GMTICKET_CREATE",             STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode      }, -    /*0x206*/ { "SMSG_GMTICKET_CREATE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT",         STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode  }, -    /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA",        STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData        }, -    /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA",         STATUS_LOGGEDIN, &WorldSession::HandleUpdateAccountData         }, -    /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x20F*/ { "CMSG_GM_TEACH",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x211*/ { "CMSG_GMTICKET_GETTICKET",          STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode   }, -    /*0x212*/ { "SMSG_GMTICKET_GETTICKET",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x213*/ { "CMSG_UNLEARN_TALENTS",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE",STATUS_NEVER,  &WorldSession::Handle_ServerSide               }, -    /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x216*/ { "MSG_CORPSE_QUERY",                 STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode         }, -    /*0x217*/ { "CMSG_GMTICKET_DELETETICKET",       STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode      }, -    /*0x218*/ { "SMSG_GMTICKET_DELETETICKET",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x219*/ { "SMSG_CHAT_WRONG_FACTION",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS",       STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode}, -    /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE",      STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, -    /*0x21D*/ { "CMSG_SET_STAT_CHEAT",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x21E*/ { "SMSG_SET_REST_START",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x21F*/ { "CMSG_SKILL_BUY_STEP",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x220*/ { "CMSG_SKILL_BUY_RANK",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x221*/ { "CMSG_XP_CHEAT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x224*/ { "SMSG_GOSSIP_POI",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x225*/ { "CMSG_CHAT_IGNORED",                STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode         }, -    /*0x226*/ { "CMSG_GM_VISION",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x227*/ { "CMSG_SERVER_COMMAND",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x228*/ { "CMSG_GM_SILENCE",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x229*/ { "CMSG_GM_REVEALTO",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x22A*/ { "CMSG_GM_RESURRECT",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x22B*/ { "CMSG_GM_SUMMONMOB",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x22C*/ { "CMSG_GM_MOVECORPSE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x22D*/ { "CMSG_GM_FREEZE",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x22E*/ { "CMSG_GM_UBERINVIS",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x230*/ { "SMSG_GM_PLAYER_INFO",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x231*/ { "CMSG_GUILD_RANK",                  STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode           }, -    /*0x232*/ { "CMSG_GUILD_ADD_RANK",              STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode        }, -    /*0x233*/ { "CMSG_GUILD_DEL_RANK",              STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode        }, -    /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE",       STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode  }, -    /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE",      STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode }, -    /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x237*/ { "CMSG_CLEAR_EXPLORATION",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x238*/ { "CMSG_SEND_MAIL",                   STATUS_LOGGEDIN, &WorldSession::HandleSendMail                  }, -    /*0x239*/ { "SMSG_SEND_MAIL_RESULT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x23A*/ { "CMSG_GET_MAIL_LIST",               STATUS_LOGGEDIN, &WorldSession::HandleGetMail                   }, -    /*0x23B*/ { "SMSG_MAIL_LIST_RESULT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x23C*/ { "CMSG_BATTLEFIELD_LIST",            STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode    }, -    /*0x23D*/ { "SMSG_BATTLEFIELD_LIST",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x241*/ { "CMSG_TAXICLEARNODE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x242*/ { "CMSG_TAXIENABLENODE",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x243*/ { "CMSG_ITEM_TEXT_QUERY",             STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery             }, -    /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x245*/ { "CMSG_MAIL_TAKE_MONEY",             STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney                 }, -    /*0x246*/ { "CMSG_MAIL_TAKE_ITEM",              STATUS_LOGGEDIN, &WorldSession::HandleTakeItem                  }, -    /*0x247*/ { "CMSG_MAIL_MARK_AS_READ",           STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead                }, -    /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER",       STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender            }, -    /*0x249*/ { "CMSG_MAIL_DELETE",                 STATUS_LOGGEDIN, &WorldSession::HandleMailDelete                }, -    /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM",       STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem        }, -    /*0x24B*/ { "SMSG_SPELLLOGMISS",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x24C*/ { "SMSG_SPELLLOGEXECUTE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x24D*/ { "SMSG_DEBUGAURAPROC",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x24E*/ { "SMSG_PERIODICAURALOG",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x251*/ { "CMSG_LEARN_TALENT",                STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode         }, -    /*0x252*/ { "SMSG_RESURRECT_FAILED",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x253*/ { "CMSG_TOGGLE_PVP",                  STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP                 }, -    /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x255*/ { "MSG_AUCTION_HELLO",                STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode        }, -    /*0x256*/ { "CMSG_AUCTION_SELL_ITEM",           STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem           }, -    /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM",         STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem         }, -    /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS",          STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems          }, -    /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS",    STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems     }, -    /*0x25A*/ { "CMSG_AUCTION_PLACE_BID",           STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid           }, -    /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION", STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x260*/ { "SMSG_PROCRESIST",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE",STATUS_NEVER,&WorldSession::Handle_ServerSide             }, -    /*0x262*/ { "SMSG_DISPEL_FAILED",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS",   STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems    }, -    /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x268*/ { "CMSG_SET_AMMO",                    STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode             }, -    /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER",            STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode      }, -    /*0x26B*/ { "CMSG_PET_CANCEL_AURA",             STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode       }, -    /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL",    STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode}, -    /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x26F*/ { "MSG_LIST_STABLED_PETS",            STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode     }, -    /*0x270*/ { "CMSG_STABLE_PET",                  STATUS_LOGGEDIN, &WorldSession::HandleStablePet                 }, -    /*0x271*/ { "CMSG_UNSTABLE_PET",                STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet               }, -    /*0x272*/ { "CMSG_BUY_STABLE_SLOT",             STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot             }, -    /*0x273*/ { "SMSG_STABLE_RESULT",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x274*/ { "CMSG_STABLE_REVIVE_PET",           STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet           }, -    /*0x275*/ { "CMSG_STABLE_SWAP_PET",             STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet             }, -    /*0x276*/ { "MSG_QUEST_PUSH_RESULT",            STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult           }, -    /*0x277*/ { "SMSG_PLAY_MUSIC",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x279*/ { "CMSG_REQUEST_PET_INFO",            STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode      }, -    /*0x27A*/ { "CMSG_FAR_SIGHT",                   STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode            }, -    /*0x27B*/ { "SMSG_SPELLDISPELLOG",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP",      STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode }, -    /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS",  STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode}, -    /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x281*/ { "CMSG_RESET_FACTION_CHEAT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM",         STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode   }, -    /*0x283*/ { "CMSG_AUTOBANK_ITEM",               STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode        }, -    /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME",         STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime      }, -    /*0x285*/ { "SMSG_RECEIVED_MAIL",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x286*/ { "SMSG_RAID_GROUP_ONLY",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x28B*/ { "CMSG_SET_PVP_TITLE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x28C*/ { "SMSG_PVP_CREDIT",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT",          STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode         }, -    /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER",      STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode      }, -    /*0x290*/ { "CMSG_BUYBACK_ITEM",                STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem               }, -    /*0x291*/ { "SMSG_SERVER_MESSAGE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x292*/ { "CMSG_MEETINGSTONE_JOIN",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x296*/ { "CMSG_MEETINGSTONE_INFO",           STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo          }, -    /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA",          STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode    }, -    /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x29D*/ { "SMSG_STANDSTATE_UPDATE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x29E*/ { "SMSG_LOOT_ALL_PASSED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x29F*/ { "SMSG_LOOT_ROLL_WON",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A0*/ { "CMSG_LOOT_ROLL",                   STATUS_LOGGEDIN, &WorldSession::HandleLootRoll                  }, -    /*0x2A1*/ { "SMSG_LOOT_START_ROLL",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A2*/ { "SMSG_LOOT_ROLL",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE",            STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode      }, -    /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2A8*/ { "CMSG_REPAIR_ITEM",                 STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode          }, -    /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM",          STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode          }, -    /*0x2AB*/ { "SMSG_SUMMON_REQUEST",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2AC*/ { "CMSG_SUMMON_RESPONSE",             STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode      }, -    /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2AF*/ { "SMSG_PET_BROKEN",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2B1*/ { "MSG_MOVE_WATER_WALK",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2B2*/ { "CMSG_SERVER_BROADCAST",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2B3*/ { "CMSG_SELF_RES",                    STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode             }, -    /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2B5*/ { "CMSG_RUN_SCRIPT",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2B9*/ { "CMSG_TOGGLE_HELM",                 STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode          }, -    /*0x2BA*/ { "CMSG_TOGGLE_CLOAK",                STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode         }, -    /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2BC*/ { "SMSG_PLAYER_SKINNED",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2BE*/ { "CMSG_SET_EXPLORATION",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES",       STATUS_AUTHED,   &WorldSession::HandleSetActionBar              }, -    /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2C1*/ { "MSG_PETITION_RENAME",              STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode      }, -    /*0x2C2*/ { "SMSG_INIT_WORLD_STATES",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY",             STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode       }, -    /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2C7*/ { "CMSG_CHAR_RENAME",                 STATUS_AUTHED,   &WorldSession::HandleChangePlayerNameOpcode    }, -    /*0x2C8*/ { "SMSG_CHAR_RENAME",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE",            STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode }, -    /*0x2CA*/ { "CMSG_MOVE_FALL_RESET",             STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO",           STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode     }, -    /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED",           STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode     }, -    /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK",       STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck            }, -    /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK",         STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck          }, -    /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER",       STATUS_LOGGEDIN, &WorldSession::HandleNotActiveMoverOpcode      }, -    /*0x2D2*/ { "SMSG_PLAY_SOUND",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS",          STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode   }, -    /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT",            STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode}, -    /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS",          STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode   }, -    /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO",          STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode   }, -    /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK", STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, -    /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck    }, -    /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK",  STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, -    /*0x2E0*/ { "MSG_PVP_LOG_DATA",                 STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode}, -    /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD",           STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode   }, -    /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY",    STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, -    /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE",    STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, -    /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2E5*/ { "CMSG_GM_UNTEACH",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2E6*/ { "SMSG_WARDEN_DATA",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2E7*/ { "CMSG_WARDEN_DATA",                 STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode          }, -    /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS",STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode}, -    /*0x2EA*/ { "CMSG_PET_STOP_ATTACK",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2EB*/ { "SMSG_BINDER_CONFIRM",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN",           STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode    }, -    /*0x2EF*/ { "SMSG_ADDON_INFO",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F0*/ { "CMSG_PET_UNLEARN",                 STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode          }, -    /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST",          STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode    }, -    /*0x2F4*/ { "SMSG_WEATHER",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F6*/ { "SMSG_MINIGAME_SETUP",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F7*/ { "SMSG_MINIGAME_STATE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2F8*/ { "CMSG_MINIGAME_MOVE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2FB*/ { "SMSG_COMPRESSED_MOVES",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT",             STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode     }, -    /*0x2FD*/ { "SMSG_CHAT_RESTRICTED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x310*/ { "MSG_GM_DESTROY_CORPSE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS",         STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode     }, -    /*0x313*/ { "SMSG_SET_FACTION_ATWAR",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x314*/ { "SMSG_GAMETIMEBIAS_SET",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x315*/ { "CMSG_DEBUG_ACTIONS_START",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x317*/ { "CMSG_SET_FACTION_INACTIVE",        STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode}, -    /*0x318*/ { "CMSG_SET_WATCHED_FACTION",         STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode}, -    /*0x319*/ { "MSG_MOVE_TIME_SKIPPED",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x31C*/ { "SMSG_INVALIDATE_PLAYER",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x31D*/ { "CMSG_RESET_INSTANCES",             STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode      }, -    /*0x31E*/ { "SMSG_INSTANCE_RESET",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x321*/ { "MSG_RAID_TARGET_UPDATE",           STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode      }, -    /*0x322*/ { "MSG_RAID_READY_CHECK",             STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode      }, -    /*0x323*/ { "CMSG_LUA_USAGE",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x324*/ { "SMSG_PET_ACTION_SOUND",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x325*/ { "SMSG_PET_DISMISS_SOUND",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x326*/ { "SMSG_GHOSTEE_GONE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY",       STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode   }, -    /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT",             STATUS_LOGGEDIN, &WorldSession::HandleGMSurveySubmit            }, -    /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x331*/ { "CMSG_CHAT_FILTERED",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x333*/ { "SMSG_SPELLSTEALLOG",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE",STATUS_NEVER,   &WorldSession::Handle_ServerSide               }, -    /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE", STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x338*/ { "SMSG_CHARACTER_PROFILE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED",STATUS_NEVER,&WorldSession::Handle_ServerSide              }, -    /*0x33A*/ { "SMSG_DEFENSE_MESSAGE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x33D*/ { "SMSG_MOTD",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK",        STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode}, -    /*0x346*/ { "CMSG_MOVE_SET_FLY",                STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x347*/ { "CMSG_SOCKET_GEMS",                 STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode              }, -    /*0x348*/ { "CMSG_ARENA_TEAM_CREATE",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY",            STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode      }, -    /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER",           STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode     }, -    /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE",           STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode  }, -    /*0x350*/ { "SMSG_ARENA_TEAM_INVITE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT",           STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode}, -    /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE",          STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode}, -    /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE",            STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode      }, -    /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE",           STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode}, -    /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND",          STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode    }, -    /*0x356*/ { "CMSG_ARENA_TEAM_LEADER",           STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode}, -    /*0x357*/ { "SMSG_ARENA_TEAM_EVENT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA",     STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin     }, -    /*0x359*/ { "MSG_MOVE_START_ASCEND",            STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x35A*/ { "MSG_MOVE_STOP_ASCEND",             STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x35B*/ { "SMSG_ARENA_TEAM_STATS",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN",            STATUS_AUTHED,   &WorldSession::HandleLfgAutoJoinOpcode         }, -    /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN",          STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode   }, -    /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL",            STATUS_AUTHED,   &WorldSession::HandleLfmAutoAddMembersOpcode   }, -    /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL",          STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode}, -    /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x361*/ { "CMSG_DECLINE_LFG_MATCH",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x362*/ { "CMSG_CANCEL_PENDING_LFG",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP",     STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode            }, -    /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE",      STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode          }, -    /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE",        STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode              }, -    /*0x366*/ { "CMSG_SET_LFG_COMMENT",             STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode       }, -    /*0x367*/ { "SMSG_LFG_TIMEDOUT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER",STATUS_NEVER,   &WorldSession::Handle_ServerSide               }, -    /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x36C*/ { "SMSG_LFG_UPDATE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x36D*/ { "SMSG_LFG_UPDATE_LFM",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x36E*/ { "SMSG_LFG_UPDATE_LFG",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x370*/ { "SMSG_LFG_PENDING_INVITE",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x371*/ { "SMSG_LFG_PENDING_MATCH",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x373*/ { "SMSG_TITLE_EARNED",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x374*/ { "CMSG_SET_TITLE",                   STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode         }, -    /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA",           STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode            }, -    /*0x376*/ { "SMSG_ARENA_ERROR",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS",          STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode   }, -    /*0x378*/ { "SMSG_DEATH_RELEASE_LOC",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT",     STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode}, -    /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT",STATUS_NEVER, &WorldSession::Handle_NULL                     }, -    /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED",   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck       }, -    /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE",STATUS_NEVER,  &WorldSession::Handle_ServerSide               }, -    /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK",STATUS_LOGGEDIN,&WorldSession::HandleForceSpeedChangeAck  }, -    /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE",     STATUS_AUTHED,   &WorldSession::HandleSetTaxiBenchmarkOpcode    }, -    /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x38B*/ { "SMSG_REALM_SPLIT",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x38C*/ { "CMSG_REALM_SPLIT",                 STATUS_AUTHED,   &WorldSession::HandleRealmStateRequestOpcode   }, -    /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT",         STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x38E*/ { "MSG_PARTY_ASSIGNMENT",             STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode        }, -    /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x390*/ { "SMSG_TIME_SYNC_REQ",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x391*/ { "CMSG_TIME_SYNC_RESP",              STATUS_LOGGEDIN, &WorldSession::HandleAllowMoveAckOpcode        }, -    /*0x392*/ { "CMSG_SEND_LOCAL_EVENT",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x397*/ { "SMSG_REAL_GROUP_UPDATE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x398*/ { "SMSG_LFG_DISABLED",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY", STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE",STATUS_NEVER,&WorldSession::Handle_ServerSide           }, -    /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide}, -    /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE", STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY",STATUS_NEVER,   &WorldSession::Handle_ServerSide               }, -    /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST",STATUS_NEVER,  &WorldSession::Handle_NULL                     }, -    /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE",STATUS_NEVER, &WorldSession::Handle_ServerSide               }, -    /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3A7*/ { "MSG_MOVE_START_DESCEND",           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, -    /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT",   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3AC*/ { "SMSG_DISMOUNT",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE",        STATUS_AUTHED,   &WorldSession::HandleVoiceSettingsOpcode       }, -    /*0x3B0*/ { "SMSG_VOICE_PARENTAL_CONTROLS",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3B1*/ { "CMSG_GM_WHISPER",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3B2*/ { "SMSG_GM_MESSAGECHAT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3B3*/ { "MSG_GM_GEARRATING",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3B4*/ { "CMSG_COMMENTATOR_ENABLE",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3B5*/ { "SMSG_COMMENTATOR_STATE_CHANGED",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3B6*/ { "CMSG_COMMENTATOR_GET_MAP_INFO",    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3B7*/ { "SMSG_COMMENTATOR_MAP_INFO",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3B8*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3B9*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO", STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3BA*/ { "SMSG_COMMENTATOR_PLAYER_INFO",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3BB*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE",  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3BC*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE",   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3BD*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND",STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3BE*/ { "SMSG_CLEAR_TARGET",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3BF*/ { "CMSG_BOT_DETECTED",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3C0*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD",STATUS_NEVER,   &WorldSession::Handle_ServerSide               }, -    /*0x3C1*/ { "CMSG_CHEAT_PLAYER_LOGIN",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOOKUP",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3C3*/ { "SMSG_CHEAT_PLAYER_LOOKUP",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3C4*/ { "SMSG_KICK_REASON",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3C5*/ { "MSG_RAID_READY_CHECK_FINISHED",    STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode}, -    /*0x3C6*/ { "CMSG_COMPLAIN",                    STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode          }, -    /*0x3C7*/ { "SMSG_COMPLAIN_RESULT",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3C8*/ { "SMSG_FEATURE_SYSTEM_STATUS",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3C9*/ { "CMSG_GM_SHOW_COMPLAINTS",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3CA*/ { "CMSG_GM_UNSQUELCH",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3CB*/ { "CMSG_CHANNEL_SILENCE_VOICE",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_ALL",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3CD*/ { "CMSG_CHANNEL_UNSILENCE_VOICE",     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_ALL",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3CF*/ { "CMSG_TARGET_CAST",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3D0*/ { "CMSG_TARGET_SCRIPT_CAST",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3D1*/ { "CMSG_CHANNEL_DISPLAY_LIST",        STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery        }, -    /*0x3D2*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL",    STATUS_AUTHED,   &WorldSession::HandleChannelVoiceChatQuery     }, -    /*0x3D3*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT",    STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery          }, -    /*0x3D4*/ { "SMSG_CHANNEL_MEMBER_COUNT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3D5*/ { "CMSG_CHANNEL_VOICE_ON",            STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode  }, -    /*0x3D6*/ { "CMSG_CHANNEL_VOICE_OFF",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3D7*/ { "CMSG_DEBUG_LIST_TARGETS",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3D8*/ { "SMSG_DEBUG_LIST_TARGETS",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3D9*/ { "SMSG_AVAILABLE_VOICE_CHANNEL",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3DA*/ { "CMSG_ADD_VOICE_IGNORE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3DB*/ { "CMSG_DEL_VOICE_IGNORE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3DC*/ { "CMSG_PARTY_SILENCE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3DD*/ { "CMSG_PARTY_UNSILENCE",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3DE*/ { "MSG_NOTIFY_PARTY_SQUELCH",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3DF*/ { "SMSG_COMSAT_RECONNECT_TRY",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3E0*/ { "SMSG_COMSAT_DISCONNECT",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3E1*/ { "SMSG_COMSAT_CONNECT_FAIL",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3E2*/ { "SMSG_VOICE_CHAT_STATUS",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3E3*/ { "CMSG_REPORT_PVP_AFK",              STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK     }, -    /*0x3E4*/ { "CMSG_REPORT_PVP_AFK_RESULT",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3E5*/ { "CMSG_GUILD_BANKER_ACTIVATE",       STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery            }, -    /*0x3E6*/ { "CMSG_GUILD_BANK_QUERY_TAB",        STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon         }, -    /*0x3E7*/ { "SMSG_GUILD_BANK_LIST",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3E8*/ { "CMSG_GUILD_BANK_SWAP_ITEMS",       STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem      }, -    /*0x3E9*/ { "CMSG_GUILD_BANK_BUY_TAB",          STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab           }, -    /*0x3EA*/ { "CMSG_GUILD_BANK_UPDATE_TAB",       STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab        }, -    /*0x3EB*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY",    STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit          }, -    /*0x3EC*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY",   STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw         }, -    /*0x3ED*/ { "MSG_GUILD_BANK_LOG_QUERY",         STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog              }, -    /*0x3EE*/ { "CMSG_SET_CHANNEL_WATCH",           STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify         }, -    /*0x3EF*/ { "SMSG_USERLIST_ADD",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F0*/ { "SMSG_USERLIST_REMOVE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F1*/ { "SMSG_USERLIST_UPDATE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F2*/ { "CMSG_CLEAR_CHANNEL_WATCH",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3F3*/ { "SMSG_INSPECT_TALENT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F4*/ { "SMSG_GOGOGO_OBSOLETE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F5*/ { "SMSG_ECHO_PARTY_SQUELCH",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F6*/ { "CMSG_SET_TITLE_SUFFIX",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3F7*/ { "CMSG_SPELLCLICK",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3F8*/ { "SMSG_LOOT_LIST",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3F9*/ { "CMSG_GM_CHARACTER_RESTORE",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3FA*/ { "CMSG_GM_CHARACTER_SAVE",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x3FB*/ { "SMSG_VOICESESSION_FULL",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x3FC*/ { "MSG_GUILD_PERMISSIONS",            STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights        }, -    /*0x3FD*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN",   STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount   }, -    /*0x3FE*/ { "MSG_GUILD_EVENT_LOG_QUERY",        STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode       }, -    /*0x3FF*/ { "CMSG_MAELSTROM_RENAME_GUILD",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x400*/ { "CMSG_GET_MIRRORIMAGE_DATA",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x401*/ { "SMSG_MIRRORIMAGE_DATA",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x402*/ { "SMSG_FORCE_DISPLAY_UPDATE",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x403*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x404*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_NULL                     }, -    /*0x405*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",STATUS_NEVER,&WorldSession::Handle_ServerSide               }, -    /*0x406*/ { "CMSG_KEEP_ALIVE",                  STATUS_NEVER,    &WorldSession::Handle_EarlyProccess            }, -    /*0x407*/ { "SMSG_RAID_READY_CHECK_ERROR",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x408*/ { "CMSG_OPT_OUT_OF_LOOT",             STATUS_AUTHED,   &WorldSession::HandleGroupPassOnLootOpcode     }, -    /*0x409*/ { "MSG_QUERY_GUILD_BANK_TEXT",        STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText          }, -    /*0x40A*/ { "CMSG_SET_GUILD_BANK_TEXT",         STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText       }, -    /*0x40B*/ { "CMSG_SET_GRANTABLE_LEVELS",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x40C*/ { "CMSG_GRANT_LEVEL",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x40D*/ { "CMSG_REFER_A_FRIEND",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x40E*/ { "MSG_GM_CHANGE_ARENA_RATING",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x40F*/ { "CMSG_DECLINE_CHANNEL_INVITE",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x410*/ { "CMSG_GROUPACTION_THROTTLED",       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x411*/ { "SMSG_OVERRIDE_LIGHT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x412*/ { "SMSG_TOTEM_CREATED",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x413*/ { "CMSG_TOTEM_DESTROYED",             STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy              }, -    /*0x414*/ { "CMSG_EXPIRE_RAID_INSTANCE",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x415*/ { "CMSG_NO_SPELL_VARIANCE",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x416*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY",STATUS_LOGGEDIN,&WorldSession::HandleQuestgiverStatusQueryMultipleOpcode}, -    /*0x417*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE",  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x418*/ { "CMSG_SET_PLAYER_DECLINED_NAMES",   STATUS_AUTHED,   &WorldSession::HandleDeclinedPlayerNameOpcode  }, -    /*0x419*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT",STATUS_NEVER,&WorldSession::Handle_ServerSide               }, -    /*0x41A*/ { "CMSG_QUERY_SERVER_BUCK_DATA",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x41B*/ { "CMSG_CLEAR_SERVER_BUCK_DATA",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x41C*/ { "SMSG_SERVER_BUCK_DATA",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x41D*/ { "SMSG_SEND_UNLEARN_SPELLS",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x41E*/ { "SMSG_PROPOSE_LEVEL_GRANT",         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x41F*/ { "CMSG_ACCEPT_LEVEL_GRANT",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, -    /*0x420*/ { "SMSG_REFER_A_FRIEND_FAILURE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x421*/ { "SMSG_SPLINE_MOVE_SET_FLYING",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x422*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, -    /*0x423*/ { "SMSG_SUMMON_CANCEL",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x000*/ { "MSG_NULL_ACTION",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x001*/ { "CMSG_BOOTME",                                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x002*/ { "CMSG_DBLOOKUP",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x003*/ { "SMSG_DBLOOKUP",                                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x004*/ { "CMSG_QUERY_OBJECT_POSITION",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x005*/ { "SMSG_QUERY_OBJECT_POSITION",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x006*/ { "CMSG_QUERY_OBJECT_ROTATION",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x007*/ { "SMSG_QUERY_OBJECT_ROTATION",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x008*/ { "CMSG_WORLD_TELEPORT",                          STATUS_LOGGEDIN, &WorldSession::HandleWorldTeleportOpcode       }, +    /*0x009*/ { "CMSG_TELEPORT_TO_UNIT",                        STATUS_LOGGEDIN, &WorldSession::Handle_NULL                     }, +    /*0x00A*/ { "CMSG_ZONE_MAP",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x00B*/ { "SMSG_ZONE_MAP",                                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x00C*/ { "CMSG_DEBUG_CHANGECELLZONE",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x00D*/ { "CMSG_MOVE_CHARACTER_CHEAT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x00E*/ { "SMSG_MOVE_CHARACTER_CHEAT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x00F*/ { "CMSG_RECHARGE",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x010*/ { "CMSG_LEARN_SPELL",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x011*/ { "CMSG_CREATEMONSTER",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x012*/ { "CMSG_DESTROYMONSTER",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x013*/ { "CMSG_CREATEITEM",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x014*/ { "CMSG_CREATEGAMEOBJECT",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x015*/ { "SMSG_CHECK_FOR_BOTS",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x016*/ { "CMSG_MAKEMONSTERATTACKGUID",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x017*/ { "CMSG_BOT_DETECTED2",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x018*/ { "CMSG_FORCEACTION",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x019*/ { "CMSG_FORCEACTIONONOTHER",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x01A*/ { "CMSG_FORCEACTIONSHOW",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x01B*/ { "SMSG_FORCEACTIONSHOW",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x01C*/ { "CMSG_PETGODMODE",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x01D*/ { "SMSG_PETGODMODE",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x01E*/ { "SMSG_REFER_A_FRIEND_EXPIRED",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x01F*/ { "CMSG_WEATHER_SPEED_CHEAT",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x020*/ { "CMSG_UNDRESSPLAYER",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x021*/ { "CMSG_BEASTMASTER",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x022*/ { "CMSG_GODMODE",                                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x023*/ { "SMSG_GODMODE",                                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x024*/ { "CMSG_CHEAT_SETMONEY",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x025*/ { "CMSG_LEVEL_CHEAT",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x026*/ { "CMSG_PET_LEVEL_CHEAT",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x027*/ { "CMSG_SET_WORLDSTATE",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x028*/ { "CMSG_COOLDOWN_CHEAT",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x029*/ { "CMSG_USE_SKILL_CHEAT",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x02A*/ { "CMSG_FLAG_QUEST",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x02B*/ { "CMSG_FLAG_QUEST_FINISH",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x02C*/ { "CMSG_CLEAR_QUEST",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x02D*/ { "CMSG_SEND_EVENT",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x02E*/ { "CMSG_DEBUG_AISTATE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x02F*/ { "SMSG_DEBUG_AISTATE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x030*/ { "CMSG_DISABLE_PVP_CHEAT",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x031*/ { "CMSG_ADVANCE_SPAWN_TIME",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x032*/ { "SMSG_DESTRUCTIBLE_BUILDING_DAMAGE",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x033*/ { "CMSG_AUTH_SRP6_BEGIN",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x034*/ { "CMSG_AUTH_SRP6_PROOF",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x035*/ { "CMSG_AUTH_SRP6_RECODE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x036*/ { "CMSG_CHAR_CREATE",                             STATUS_AUTHED,   &WorldSession::HandleCharCreateOpcode          }, +    /*0x037*/ { "CMSG_CHAR_ENUM",                               STATUS_AUTHED,   &WorldSession::HandleCharEnumOpcode            }, +    /*0x038*/ { "CMSG_CHAR_DELETE",                             STATUS_AUTHED,   &WorldSession::HandleCharDeleteOpcode          }, +    /*0x039*/ { "SMSG_AUTH_SRP6_RESPONSE",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x03A*/ { "SMSG_CHAR_CREATE",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x03B*/ { "SMSG_CHAR_ENUM",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x03C*/ { "SMSG_CHAR_DELETE",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x03D*/ { "CMSG_PLAYER_LOGIN",                            STATUS_AUTHED,   &WorldSession::HandlePlayerLoginOpcode         }, +    /*0x03E*/ { "SMSG_NEW_WORLD",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x03F*/ { "SMSG_TRANSFER_PENDING",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x040*/ { "SMSG_TRANSFER_ABORTED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x041*/ { "SMSG_CHARACTER_LOGIN_FAILED",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x042*/ { "SMSG_LOGIN_SETTIMESPEED",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x043*/ { "SMSG_GAMETIME_UPDATE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x044*/ { "CMSG_GAMETIME_SET",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x045*/ { "SMSG_GAMETIME_SET",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x046*/ { "CMSG_GAMESPEED_SET",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x047*/ { "SMSG_GAMESPEED_SET",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x048*/ { "CMSG_SERVERTIME",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x049*/ { "SMSG_SERVERTIME",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x04A*/ { "CMSG_PLAYER_LOGOUT",                           STATUS_LOGGEDIN, &WorldSession::HandlePlayerLogoutOpcode        }, +    /*0x04B*/ { "CMSG_LOGOUT_REQUEST",                          STATUS_LOGGEDIN, &WorldSession::HandleLogoutRequestOpcode       }, +    /*0x04C*/ { "SMSG_LOGOUT_RESPONSE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x04D*/ { "SMSG_LOGOUT_COMPLETE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x04E*/ { "CMSG_LOGOUT_CANCEL",                           STATUS_LOGGEDIN, &WorldSession::HandleLogoutCancelOpcode        }, +    /*0x04F*/ { "SMSG_LOGOUT_CANCEL_ACK",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x050*/ { "CMSG_NAME_QUERY",                              STATUS_LOGGEDIN, &WorldSession::HandleNameQueryOpcode           }, +    /*0x051*/ { "SMSG_NAME_QUERY_RESPONSE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x052*/ { "CMSG_PET_NAME_QUERY",                          STATUS_LOGGEDIN, &WorldSession::HandlePetNameQuery              }, +    /*0x053*/ { "SMSG_PET_NAME_QUERY_RESPONSE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x054*/ { "CMSG_GUILD_QUERY",                             STATUS_AUTHED,   &WorldSession::HandleGuildQueryOpcode          }, +    /*0x055*/ { "SMSG_GUILD_QUERY_RESPONSE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x056*/ { "CMSG_ITEM_QUERY_SINGLE",                       STATUS_LOGGEDIN, &WorldSession::HandleItemQuerySingleOpcode     }, +    /*0x057*/ { "CMSG_ITEM_QUERY_MULTIPLE",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x058*/ { "SMSG_ITEM_QUERY_SINGLE_RESPONSE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x059*/ { "SMSG_ITEM_QUERY_MULTIPLE_RESPONSE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x05A*/ { "CMSG_PAGE_TEXT_QUERY",                         STATUS_LOGGEDIN, &WorldSession::HandlePageQueryOpcode           }, +    /*0x05B*/ { "SMSG_PAGE_TEXT_QUERY_RESPONSE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x05C*/ { "CMSG_QUEST_QUERY",                             STATUS_LOGGEDIN, &WorldSession::HandleQuestQueryOpcode          }, +    /*0x05D*/ { "SMSG_QUEST_QUERY_RESPONSE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x05E*/ { "CMSG_GAMEOBJECT_QUERY",                        STATUS_LOGGEDIN, &WorldSession::HandleGameObjectQueryOpcode     }, +    /*0x05F*/ { "SMSG_GAMEOBJECT_QUERY_RESPONSE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x060*/ { "CMSG_CREATURE_QUERY",                          STATUS_LOGGEDIN, &WorldSession::HandleCreatureQueryOpcode       }, +    /*0x061*/ { "SMSG_CREATURE_QUERY_RESPONSE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x062*/ { "CMSG_WHO",                                     STATUS_LOGGEDIN, &WorldSession::HandleWhoOpcode                 }, +    /*0x063*/ { "SMSG_WHO",                                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x064*/ { "CMSG_WHOIS",                                   STATUS_LOGGEDIN, &WorldSession::HandleWhoisOpcode               }, +    /*0x065*/ { "SMSG_WHOIS",                                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x066*/ { "CMSG_CONTACT_LIST",                            STATUS_LOGGEDIN, &WorldSession::HandleFriendListOpcode          }, +    /*0x067*/ { "SMSG_CONTACT_LIST",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x068*/ { "SMSG_FRIEND_STATUS",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x069*/ { "CMSG_ADD_FRIEND",                              STATUS_LOGGEDIN, &WorldSession::HandleAddFriendOpcode           }, +    /*0x06A*/ { "CMSG_DEL_FRIEND",                              STATUS_LOGGEDIN, &WorldSession::HandleDelFriendOpcode           }, +    /*0x06B*/ { "CMSG_SET_CONTACT_NOTES",                       STATUS_LOGGEDIN, &WorldSession::HandleSetFriendNoteOpcode       }, +    /*0x06C*/ { "CMSG_ADD_IGNORE",                              STATUS_LOGGEDIN, &WorldSession::HandleAddIgnoreOpcode           }, +    /*0x06D*/ { "CMSG_DEL_IGNORE",                              STATUS_LOGGEDIN, &WorldSession::HandleDelIgnoreOpcode           }, +    /*0x06E*/ { "CMSG_GROUP_INVITE",                            STATUS_LOGGEDIN, &WorldSession::HandleGroupInviteOpcode         }, +    /*0x06F*/ { "SMSG_GROUP_INVITE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x070*/ { "CMSG_GROUP_CANCEL",                            STATUS_LOGGEDIN, &WorldSession::Handle_Deprecated               }, +    /*0x071*/ { "SMSG_GROUP_CANCEL",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x072*/ { "CMSG_GROUP_ACCEPT",                            STATUS_LOGGEDIN, &WorldSession::HandleGroupAcceptOpcode         }, +    /*0x073*/ { "CMSG_GROUP_DECLINE",                           STATUS_LOGGEDIN, &WorldSession::HandleGroupDeclineOpcode        }, +    /*0x074*/ { "SMSG_GROUP_DECLINE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x075*/ { "CMSG_GROUP_UNINVITE",                          STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteNameOpcode   }, +    /*0x076*/ { "CMSG_GROUP_UNINVITE_GUID",                     STATUS_LOGGEDIN, &WorldSession::HandleGroupUninviteGuidOpcode   }, +    /*0x077*/ { "SMSG_GROUP_UNINVITE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x078*/ { "CMSG_GROUP_SET_LEADER",                        STATUS_LOGGEDIN, &WorldSession::HandleGroupSetLeaderOpcode      }, +    /*0x079*/ { "SMSG_GROUP_SET_LEADER",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x07A*/ { "CMSG_LOOT_METHOD",                             STATUS_LOGGEDIN, &WorldSession::HandleLootMethodOpcode          }, +    /*0x07B*/ { "CMSG_GROUP_DISBAND",                           STATUS_LOGGEDIN, &WorldSession::HandleGroupLeaveOpcode          }, +    /*0x07C*/ { "SMSG_GROUP_DESTROYED",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x07D*/ { "SMSG_GROUP_LIST",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x07E*/ { "SMSG_PARTY_MEMBER_STATS",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x07F*/ { "SMSG_PARTY_COMMAND_RESULT",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x080*/ { "UMSG_UPDATE_GROUP_MEMBERS",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x081*/ { "CMSG_GUILD_CREATE",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildCreateOpcode         }, +    /*0x082*/ { "CMSG_GUILD_INVITE",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildInviteOpcode         }, +    /*0x083*/ { "SMSG_GUILD_INVITE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x084*/ { "CMSG_GUILD_ACCEPT",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildAcceptOpcode         }, +    /*0x085*/ { "CMSG_GUILD_DECLINE",                           STATUS_LOGGEDIN, &WorldSession::HandleGuildDeclineOpcode        }, +    /*0x086*/ { "SMSG_GUILD_DECLINE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x087*/ { "CMSG_GUILD_INFO",                              STATUS_LOGGEDIN, &WorldSession::HandleGuildInfoOpcode           }, +    /*0x088*/ { "SMSG_GUILD_INFO",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x089*/ { "CMSG_GUILD_ROSTER",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildRosterOpcode         }, +    /*0x08A*/ { "SMSG_GUILD_ROSTER",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x08B*/ { "CMSG_GUILD_PROMOTE",                           STATUS_LOGGEDIN, &WorldSession::HandleGuildPromoteOpcode        }, +    /*0x08C*/ { "CMSG_GUILD_DEMOTE",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildDemoteOpcode         }, +    /*0x08D*/ { "CMSG_GUILD_LEAVE",                             STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaveOpcode          }, +    /*0x08E*/ { "CMSG_GUILD_REMOVE",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildRemoveOpcode         }, +    /*0x08F*/ { "CMSG_GUILD_DISBAND",                           STATUS_LOGGEDIN, &WorldSession::HandleGuildDisbandOpcode        }, +    /*0x090*/ { "CMSG_GUILD_LEADER",                            STATUS_LOGGEDIN, &WorldSession::HandleGuildLeaderOpcode         }, +    /*0x091*/ { "CMSG_GUILD_MOTD",                              STATUS_LOGGEDIN, &WorldSession::HandleGuildMOTDOpcode           }, +    /*0x092*/ { "SMSG_GUILD_EVENT",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x093*/ { "SMSG_GUILD_COMMAND_RESULT",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x094*/ { "UMSG_UPDATE_GUILD",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x095*/ { "CMSG_MESSAGECHAT",                             STATUS_LOGGEDIN, &WorldSession::HandleMessagechatOpcode         }, +    /*0x096*/ { "SMSG_MESSAGECHAT",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x097*/ { "CMSG_JOIN_CHANNEL",                            STATUS_LOGGEDIN, &WorldSession::HandleChannelJoin               }, +    /*0x098*/ { "CMSG_LEAVE_CHANNEL",                           STATUS_LOGGEDIN, &WorldSession::HandleChannelLeave              }, +    /*0x099*/ { "SMSG_CHANNEL_NOTIFY",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x09A*/ { "CMSG_CHANNEL_LIST",                            STATUS_LOGGEDIN, &WorldSession::HandleChannelList               }, +    /*0x09B*/ { "SMSG_CHANNEL_LIST",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x09C*/ { "CMSG_CHANNEL_PASSWORD",                        STATUS_LOGGEDIN, &WorldSession::HandleChannelPassword           }, +    /*0x09D*/ { "CMSG_CHANNEL_SET_OWNER",                       STATUS_LOGGEDIN, &WorldSession::HandleChannelSetOwner           }, +    /*0x09E*/ { "CMSG_CHANNEL_OWNER",                           STATUS_LOGGEDIN, &WorldSession::HandleChannelOwner              }, +    /*0x09F*/ { "CMSG_CHANNEL_MODERATOR",                       STATUS_LOGGEDIN, &WorldSession::HandleChannelModerator          }, +    /*0x0A0*/ { "CMSG_CHANNEL_UNMODERATOR",                     STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmoderator        }, +    /*0x0A1*/ { "CMSG_CHANNEL_MUTE",                            STATUS_LOGGEDIN, &WorldSession::HandleChannelMute               }, +    /*0x0A2*/ { "CMSG_CHANNEL_UNMUTE",                          STATUS_LOGGEDIN, &WorldSession::HandleChannelUnmute             }, +    /*0x0A3*/ { "CMSG_CHANNEL_INVITE",                          STATUS_LOGGEDIN, &WorldSession::HandleChannelInvite             }, +    /*0x0A4*/ { "CMSG_CHANNEL_KICK",                            STATUS_LOGGEDIN, &WorldSession::HandleChannelKick               }, +    /*0x0A5*/ { "CMSG_CHANNEL_BAN",                             STATUS_LOGGEDIN, &WorldSession::HandleChannelBan                }, +    /*0x0A6*/ { "CMSG_CHANNEL_UNBAN",                           STATUS_LOGGEDIN, &WorldSession::HandleChannelUnban              }, +    /*0x0A7*/ { "CMSG_CHANNEL_ANNOUNCEMENTS",                   STATUS_LOGGEDIN, &WorldSession::HandleChannelAnnounce           }, +    /*0x0A8*/ { "CMSG_CHANNEL_MODERATE",                        STATUS_LOGGEDIN, &WorldSession::HandleChannelModerate           }, +    /*0x0A9*/ { "SMSG_UPDATE_OBJECT",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0AA*/ { "SMSG_DESTROY_OBJECT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0AB*/ { "CMSG_USE_ITEM",                                STATUS_LOGGEDIN, &WorldSession::HandleUseItemOpcode             }, +    /*0x0AC*/ { "CMSG_OPEN_ITEM",                               STATUS_LOGGEDIN, &WorldSession::HandleOpenItemOpcode            }, +    /*0x0AD*/ { "CMSG_READ_ITEM",                               STATUS_LOGGEDIN, &WorldSession::HandleReadItem                  }, +    /*0x0AE*/ { "SMSG_READ_ITEM_OK",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0AF*/ { "SMSG_READ_ITEM_FAILED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0B0*/ { "SMSG_ITEM_COOLDOWN",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0B1*/ { "CMSG_GAMEOBJ_USE",                             STATUS_LOGGEDIN, &WorldSession::HandleGameObjectUseOpcode       }, +    /*0x0B2*/ { "CMSG_DESTROY_ITEMS",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0B3*/ { "SMSG_GAMEOBJECT_CUSTOM_ANIM",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0B4*/ { "CMSG_AREATRIGGER",                             STATUS_LOGGEDIN, &WorldSession::HandleAreaTriggerOpcode         }, +    /*0x0B5*/ { "MSG_MOVE_START_FORWARD",                       STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0B6*/ { "MSG_MOVE_START_BACKWARD",                      STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0B7*/ { "MSG_MOVE_STOP",                                STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0B8*/ { "MSG_MOVE_START_STRAFE_LEFT",                   STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0B9*/ { "MSG_MOVE_START_STRAFE_RIGHT",                  STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0BA*/ { "MSG_MOVE_STOP_STRAFE",                         STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0BB*/ { "MSG_MOVE_JUMP",                                STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0BC*/ { "MSG_MOVE_START_TURN_LEFT",                     STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0BD*/ { "MSG_MOVE_START_TURN_RIGHT",                    STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0BE*/ { "MSG_MOVE_STOP_TURN",                           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0BF*/ { "MSG_MOVE_START_PITCH_UP",                      STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0C0*/ { "MSG_MOVE_START_PITCH_DOWN",                    STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0C1*/ { "MSG_MOVE_STOP_PITCH",                          STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0C2*/ { "MSG_MOVE_SET_RUN_MODE",                        STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0C3*/ { "MSG_MOVE_SET_WALK_MODE",                       STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0C4*/ { "MSG_MOVE_TOGGLE_LOGGING",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0C5*/ { "MSG_MOVE_TELEPORT",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0C6*/ { "MSG_MOVE_TELEPORT_CHEAT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0C7*/ { "MSG_MOVE_TELEPORT_ACK",                        STATUS_LOGGEDIN, &WorldSession::HandleMoveTeleportAck           }, +    /*0x0C8*/ { "MSG_MOVE_TOGGLE_FALL_LOGGING",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0C9*/ { "MSG_MOVE_FALL_LAND",                           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0CA*/ { "MSG_MOVE_START_SWIM",                          STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0CB*/ { "MSG_MOVE_STOP_SWIM",                           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0CC*/ { "MSG_MOVE_SET_RUN_SPEED_CHEAT",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0CD*/ { "MSG_MOVE_SET_RUN_SPEED",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0CE*/ { "MSG_MOVE_SET_RUN_BACK_SPEED_CHEAT",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0CF*/ { "MSG_MOVE_SET_RUN_BACK_SPEED",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D0*/ { "MSG_MOVE_SET_WALK_SPEED_CHEAT",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D1*/ { "MSG_MOVE_SET_WALK_SPEED",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D2*/ { "MSG_MOVE_SET_SWIM_SPEED_CHEAT",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D3*/ { "MSG_MOVE_SET_SWIM_SPEED",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D4*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED_CHEAT",           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D5*/ { "MSG_MOVE_SET_SWIM_BACK_SPEED",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D6*/ { "MSG_MOVE_SET_ALL_SPEED_CHEAT",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D7*/ { "MSG_MOVE_SET_TURN_RATE_CHEAT",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D8*/ { "MSG_MOVE_SET_TURN_RATE",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0D9*/ { "MSG_MOVE_TOGGLE_COLLISION_CHEAT",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0DA*/ { "MSG_MOVE_SET_FACING",                          STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0DB*/ { "MSG_MOVE_SET_PITCH",                           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0DC*/ { "MSG_MOVE_WORLDPORT_ACK",                       STATUS_TRANSFER_PENDING,&WorldSession::HandleMoveWorldportAckOpcode}, +    /*0x0DD*/ { "SMSG_MONSTER_MOVE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0DE*/ { "SMSG_MOVE_WATER_WALK",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0DF*/ { "SMSG_MOVE_LAND_WALK",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0E0*/ { "MSG_MOVE_SET_RAW_POSITION_ACK",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0E1*/ { "CMSG_MOVE_SET_RAW_POSITION",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0E2*/ { "SMSG_FORCE_RUN_SPEED_CHANGE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0E3*/ { "CMSG_FORCE_RUN_SPEED_CHANGE_ACK",              STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x0E4*/ { "SMSG_FORCE_RUN_BACK_SPEED_CHANGE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0E5*/ { "CMSG_FORCE_RUN_BACK_SPEED_CHANGE_ACK",         STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x0E6*/ { "SMSG_FORCE_SWIM_SPEED_CHANGE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0E7*/ { "CMSG_FORCE_SWIM_SPEED_CHANGE_ACK",             STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x0E8*/ { "SMSG_FORCE_MOVE_ROOT",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0E9*/ { "CMSG_FORCE_MOVE_ROOT_ACK",                     STATUS_LOGGEDIN, &WorldSession::HandleMoveRootAck               }, +    /*0x0EA*/ { "SMSG_FORCE_MOVE_UNROOT",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0EB*/ { "CMSG_FORCE_MOVE_UNROOT_ACK",                   STATUS_LOGGEDIN, &WorldSession::HandleMoveUnRootAck             }, +    /*0x0EC*/ { "MSG_MOVE_ROOT",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0ED*/ { "MSG_MOVE_UNROOT",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0EE*/ { "MSG_MOVE_HEARTBEAT",                           STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x0EF*/ { "SMSG_MOVE_KNOCK_BACK",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0F0*/ { "CMSG_MOVE_KNOCK_BACK_ACK",                     STATUS_LOGGEDIN, &WorldSession::HandleMoveKnockBackAck          }, +    /*0x0F1*/ { "MSG_MOVE_KNOCK_BACK",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0F2*/ { "SMSG_MOVE_FEATHER_FALL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0F3*/ { "SMSG_MOVE_NORMAL_FALL",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0F4*/ { "SMSG_MOVE_SET_HOVER",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0F5*/ { "SMSG_MOVE_UNSET_HOVER",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0F6*/ { "CMSG_MOVE_HOVER_ACK",                          STATUS_LOGGEDIN, &WorldSession::HandleMoveHoverAck              }, +    /*0x0F7*/ { "MSG_MOVE_HOVER",                               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0F8*/ { "CMSG_TRIGGER_CINEMATIC_CHEAT",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0F9*/ { "CMSG_OPENING_CINEMATIC",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x0FA*/ { "SMSG_TRIGGER_CINEMATIC",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0FB*/ { "CMSG_NEXT_CINEMATIC_CAMERA",                   STATUS_LOGGEDIN, &WorldSession::HandleNextCinematicCamera       }, +    /*0x0FC*/ { "CMSG_COMPLETE_CINEMATIC",                      STATUS_LOGGEDIN, &WorldSession::HandleCompleteCinema            }, +    /*0x0FD*/ { "SMSG_TUTORIAL_FLAGS",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x0FE*/ { "CMSG_TUTORIAL_FLAG",                           STATUS_LOGGEDIN, &WorldSession::HandleTutorialFlag              }, +    /*0x0FF*/ { "CMSG_TUTORIAL_CLEAR",                          STATUS_LOGGEDIN, &WorldSession::HandleTutorialClear             }, +    /*0x100*/ { "CMSG_TUTORIAL_RESET",                          STATUS_LOGGEDIN, &WorldSession::HandleTutorialReset             }, +    /*0x101*/ { "CMSG_STANDSTATECHANGE",                        STATUS_LOGGEDIN, &WorldSession::HandleStandStateChangeOpcode    }, +    /*0x102*/ { "CMSG_EMOTE",                                   STATUS_LOGGEDIN, &WorldSession::HandleEmoteOpcode               }, +    /*0x103*/ { "SMSG_EMOTE",                                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x104*/ { "CMSG_TEXT_EMOTE",                              STATUS_LOGGEDIN, &WorldSession::HandleTextEmoteOpcode           }, +    /*0x105*/ { "SMSG_TEXT_EMOTE",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x106*/ { "CMSG_AUTOEQUIP_GROUND_ITEM",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x107*/ { "CMSG_AUTOSTORE_GROUND_ITEM",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x108*/ { "CMSG_AUTOSTORE_LOOT_ITEM",                     STATUS_LOGGEDIN, &WorldSession::HandleAutostoreLootItemOpcode   }, +    /*0x109*/ { "CMSG_STORE_LOOT_IN_SLOT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x10A*/ { "CMSG_AUTOEQUIP_ITEM",                          STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemOpcode       }, +    /*0x10B*/ { "CMSG_AUTOSTORE_BAG_ITEM",                      STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBagItemOpcode    }, +    /*0x10C*/ { "CMSG_SWAP_ITEM",                               STATUS_LOGGEDIN, &WorldSession::HandleSwapItem                  }, +    /*0x10D*/ { "CMSG_SWAP_INV_ITEM",                           STATUS_LOGGEDIN, &WorldSession::HandleSwapInvItemOpcode         }, +    /*0x10E*/ { "CMSG_SPLIT_ITEM",                              STATUS_LOGGEDIN, &WorldSession::HandleSplitItemOpcode           }, +    /*0x10F*/ { "CMSG_AUTOEQUIP_ITEM_SLOT",                     STATUS_LOGGEDIN, &WorldSession::HandleAutoEquipItemSlotOpcode   }, +    /*0x110*/ { "OBSOLETE_DROP_ITEM",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x111*/ { "CMSG_DESTROYITEM",                             STATUS_LOGGEDIN, &WorldSession::HandleDestroyItemOpcode         }, +    /*0x112*/ { "SMSG_INVENTORY_CHANGE_FAILURE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x113*/ { "SMSG_OPEN_CONTAINER",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x114*/ { "CMSG_INSPECT",                                 STATUS_LOGGEDIN, &WorldSession::HandleInspectOpcode             }, +    /*0x115*/ { "SMSG_INSPECT",                                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x116*/ { "CMSG_INITIATE_TRADE",                          STATUS_LOGGEDIN, &WorldSession::HandleInitiateTradeOpcode       }, +    /*0x117*/ { "CMSG_BEGIN_TRADE",                             STATUS_LOGGEDIN, &WorldSession::HandleBeginTradeOpcode          }, +    /*0x118*/ { "CMSG_BUSY_TRADE",                              STATUS_LOGGEDIN, &WorldSession::HandleBusyTradeOpcode           }, +    /*0x119*/ { "CMSG_IGNORE_TRADE",                            STATUS_LOGGEDIN, &WorldSession::HandleIgnoreTradeOpcode         }, +    /*0x11A*/ { "CMSG_ACCEPT_TRADE",                            STATUS_LOGGEDIN, &WorldSession::HandleAcceptTradeOpcode         }, +    /*0x11B*/ { "CMSG_UNACCEPT_TRADE",                          STATUS_LOGGEDIN, &WorldSession::HandleUnacceptTradeOpcode       }, +    /*0x11C*/ { "CMSG_CANCEL_TRADE",                            STATUS_AUTHED,   &WorldSession::HandleCancelTradeOpcode         }, +    /*0x11D*/ { "CMSG_SET_TRADE_ITEM",                          STATUS_LOGGEDIN, &WorldSession::HandleSetTradeItemOpcode        }, +    /*0x11E*/ { "CMSG_CLEAR_TRADE_ITEM",                        STATUS_LOGGEDIN, &WorldSession::HandleClearTradeItemOpcode      }, +    /*0x11F*/ { "CMSG_SET_TRADE_GOLD",                          STATUS_LOGGEDIN, &WorldSession::HandleSetTradeGoldOpcode        }, +    /*0x120*/ { "SMSG_TRADE_STATUS",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x121*/ { "SMSG_TRADE_STATUS_EXTENDED",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x122*/ { "SMSG_INITIALIZE_FACTIONS",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x123*/ { "SMSG_SET_FACTION_VISIBLE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x124*/ { "SMSG_SET_FACTION_STANDING",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x125*/ { "CMSG_SET_FACTION_ATWAR",                       STATUS_LOGGEDIN, &WorldSession::HandleSetFactionAtWar           }, +    /*0x126*/ { "CMSG_SET_FACTION_CHEAT",                       STATUS_LOGGEDIN, &WorldSession::HandleSetFactionCheat           }, +    /*0x127*/ { "SMSG_SET_PROFICIENCY",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x128*/ { "CMSG_SET_ACTION_BUTTON",                       STATUS_LOGGEDIN, &WorldSession::HandleSetActionButtonOpcode     }, +    /*0x129*/ { "SMSG_ACTION_BUTTONS",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x12A*/ { "SMSG_INITIAL_SPELLS",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x12B*/ { "SMSG_LEARNED_SPELL",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x12C*/ { "SMSG_SUPERCEDED_SPELL",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x12D*/ { "CMSG_NEW_SPELL_SLOT",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x12E*/ { "CMSG_CAST_SPELL",                              STATUS_LOGGEDIN, &WorldSession::HandleCastSpellOpcode           }, +    /*0x12F*/ { "CMSG_CANCEL_CAST",                             STATUS_LOGGEDIN, &WorldSession::HandleCancelCastOpcode          }, +    /*0x130*/ { "SMSG_CAST_FAILED",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x131*/ { "SMSG_SPELL_START",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x132*/ { "SMSG_SPELL_GO",                                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x133*/ { "SMSG_SPELL_FAILURE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x134*/ { "SMSG_SPELL_COOLDOWN",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x135*/ { "SMSG_COOLDOWN_EVENT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x136*/ { "CMSG_CANCEL_AURA",                             STATUS_LOGGEDIN, &WorldSession::HandleCancelAuraOpcode          }, +    /*0x137*/ { "SMSG_UPDATE_AURA_DURATION_OBSOLETE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x138*/ { "SMSG_PET_CAST_FAILED",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x139*/ { "MSG_CHANNEL_START",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x13A*/ { "MSG_CHANNEL_UPDATE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x13B*/ { "CMSG_CANCEL_CHANNELLING",                      STATUS_LOGGEDIN, &WorldSession::HandleCancelChanneling          }, +    /*0x13C*/ { "SMSG_AI_REACTION",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x13D*/ { "CMSG_SET_SELECTION",                           STATUS_LOGGEDIN, &WorldSession::HandleSetSelectionOpcode        }, +    /*0x13E*/ { "CMSG_SET_TARGET_OBSOLETE",                     STATUS_LOGGEDIN, &WorldSession::HandleSetTargetOpcode           }, +    /*0x13F*/ { "CMSG_UNUSED",                                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x140*/ { "CMSG_UNUSED2",                                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x141*/ { "CMSG_ATTACKSWING",                             STATUS_LOGGEDIN, &WorldSession::HandleAttackSwingOpcode         }, +    /*0x142*/ { "CMSG_ATTACKSTOP",                              STATUS_LOGGEDIN, &WorldSession::HandleAttackStopOpcode          }, +    /*0x143*/ { "SMSG_ATTACKSTART",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x144*/ { "SMSG_ATTACKSTOP",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x145*/ { "SMSG_ATTACKSWING_NOTINRANGE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x146*/ { "SMSG_ATTACKSWING_BADFACING",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x147*/ { "SMSG_ATTACKSWING_NOTSTANDING",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x148*/ { "SMSG_ATTACKSWING_DEADTARGET",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x149*/ { "SMSG_ATTACKSWING_CANT_ATTACK",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x14B*/ { "SMSG_VICTIMSTATEUPDATE_OBSOLETE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x14E*/ { "SMSG_CANCEL_COMBAT",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x14F*/ { "SMSG_SPELLBREAKLOG",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x150*/ { "SMSG_SPELLHEALLOG",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x151*/ { "SMSG_SPELLENERGIZELOG",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x152*/ { "SMSG_BREAK_TARGET",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x153*/ { "CMSG_SAVE_PLAYER",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x154*/ { "CMSG_SETDEATHBINDPOINT",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x155*/ { "SMSG_BINDPOINTUPDATE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x156*/ { "CMSG_GETDEATHBINDZONE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x157*/ { "SMSG_BINDZONEREPLY",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x158*/ { "SMSG_PLAYERBOUND",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x159*/ { "SMSG_CLIENT_CONTROL_UPDATE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x15A*/ { "CMSG_REPOP_REQUEST",                           STATUS_LOGGEDIN, &WorldSession::HandleRepopRequestOpcode        }, +    /*0x15B*/ { "SMSG_RESURRECT_REQUEST",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x15C*/ { "CMSG_RESURRECT_RESPONSE",                      STATUS_LOGGEDIN, &WorldSession::HandleResurrectResponseOpcode   }, +    /*0x15D*/ { "CMSG_LOOT",                                    STATUS_LOGGEDIN, &WorldSession::HandleLootOpcode                }, +    /*0x15E*/ { "CMSG_LOOT_MONEY",                              STATUS_LOGGEDIN, &WorldSession::HandleLootMoneyOpcode           }, +    /*0x15F*/ { "CMSG_LOOT_RELEASE",                            STATUS_LOGGEDIN, &WorldSession::HandleLootReleaseOpcode         }, +    /*0x160*/ { "SMSG_LOOT_RESPONSE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x161*/ { "SMSG_LOOT_RELEASE_RESPONSE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x162*/ { "SMSG_LOOT_REMOVED",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x163*/ { "SMSG_LOOT_MONEY_NOTIFY",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x164*/ { "SMSG_LOOT_ITEM_NOTIFY",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x165*/ { "SMSG_LOOT_CLEAR_MONEY",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x166*/ { "SMSG_ITEM_PUSH_RESULT",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x167*/ { "SMSG_DUEL_REQUESTED",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x168*/ { "SMSG_DUEL_OUTOFBOUNDS",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x169*/ { "SMSG_DUEL_INBOUNDS",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x16A*/ { "SMSG_DUEL_COMPLETE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x16B*/ { "SMSG_DUEL_WINNER",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x16C*/ { "CMSG_DUEL_ACCEPTED",                           STATUS_LOGGEDIN, &WorldSession::HandleDuelAcceptedOpcode        }, +    /*0x16D*/ { "CMSG_DUEL_CANCELLED",                          STATUS_LOGGEDIN, &WorldSession::HandleDuelCancelledOpcode       }, +    /*0x16E*/ { "SMSG_MOUNTRESULT",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x16F*/ { "SMSG_DISMOUNTRESULT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x170*/ { "SMSG_PUREMOUNT_CANCELLED_OBSOLETE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x171*/ { "CMSG_MOUNTSPECIAL_ANIM",                       STATUS_LOGGEDIN, &WorldSession::HandleMountSpecialAnimOpcode    }, +    /*0x172*/ { "SMSG_MOUNTSPECIAL_ANIM",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x173*/ { "SMSG_PET_TAME_FAILURE",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x174*/ { "CMSG_PET_SET_ACTION",                          STATUS_LOGGEDIN, &WorldSession::HandlePetSetAction              }, +    /*0x175*/ { "CMSG_PET_ACTION",                              STATUS_LOGGEDIN, &WorldSession::HandlePetAction                 }, +    /*0x176*/ { "CMSG_PET_ABANDON",                             STATUS_LOGGEDIN, &WorldSession::HandlePetAbandon                }, +    /*0x177*/ { "CMSG_PET_RENAME",                              STATUS_LOGGEDIN, &WorldSession::HandlePetRename                 }, +    /*0x178*/ { "SMSG_PET_NAME_INVALID",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x179*/ { "SMSG_PET_SPELLS",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x17A*/ { "SMSG_PET_MODE",                                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x17B*/ { "CMSG_GOSSIP_HELLO",                            STATUS_LOGGEDIN, &WorldSession::HandleGossipHelloOpcode         }, +    /*0x17C*/ { "CMSG_GOSSIP_SELECT_OPTION",                    STATUS_LOGGEDIN, &WorldSession::HandleGossipSelectOptionOpcode  }, +    /*0x17D*/ { "SMSG_GOSSIP_MESSAGE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x17E*/ { "SMSG_GOSSIP_COMPLETE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x17F*/ { "CMSG_NPC_TEXT_QUERY",                          STATUS_LOGGEDIN, &WorldSession::HandleNpcTextQueryOpcode        }, +    /*0x180*/ { "SMSG_NPC_TEXT_UPDATE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x181*/ { "SMSG_NPC_WONT_TALK",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x182*/ { "CMSG_QUESTGIVER_STATUS_QUERY",                 STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryOpcode}, +    /*0x183*/ { "SMSG_QUESTGIVER_STATUS",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x184*/ { "CMSG_QUESTGIVER_HELLO",                        STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverHelloOpcode     }, +    /*0x185*/ { "SMSG_QUESTGIVER_QUEST_LIST",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x186*/ { "CMSG_QUESTGIVER_QUERY_QUEST",                  STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverQuestQueryOpcode}, +    /*0x187*/ { "CMSG_QUESTGIVER_QUEST_AUTOLAUNCH",             STATUS_LOGGEDIN, &WorldSession::HandleQuestAutoLaunch           }, +    /*0x188*/ { "SMSG_QUESTGIVER_QUEST_DETAILS",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x189*/ { "CMSG_QUESTGIVER_ACCEPT_QUEST",                 STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverAcceptQuestOpcode}, +    /*0x18A*/ { "CMSG_QUESTGIVER_COMPLETE_QUEST",               STATUS_LOGGEDIN, &WorldSession::HandleQuestComplete             }, +    /*0x18B*/ { "SMSG_QUESTGIVER_REQUEST_ITEMS",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x18C*/ { "CMSG_QUESTGIVER_REQUEST_REWARD",               STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverRequestRewardOpcode}, +    /*0x18D*/ { "SMSG_QUESTGIVER_OFFER_REWARD",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x18E*/ { "CMSG_QUESTGIVER_CHOOSE_REWARD",                STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverChooseRewardOpcode}, +    /*0x18F*/ { "SMSG_QUESTGIVER_QUEST_INVALID",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x190*/ { "CMSG_QUESTGIVER_CANCEL",                       STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverCancel          }, +    /*0x191*/ { "SMSG_QUESTGIVER_QUEST_COMPLETE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x192*/ { "SMSG_QUESTGIVER_QUEST_FAILED",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x193*/ { "CMSG_QUESTLOG_SWAP_QUEST",                     STATUS_LOGGEDIN, &WorldSession::HandleQuestLogSwapQuest         }, +    /*0x194*/ { "CMSG_QUESTLOG_REMOVE_QUEST",                   STATUS_LOGGEDIN, &WorldSession::HandleQuestLogRemoveQuest       }, +    /*0x195*/ { "SMSG_QUESTLOG_FULL",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x196*/ { "SMSG_QUESTUPDATE_FAILED",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x197*/ { "SMSG_QUESTUPDATE_FAILEDTIMER",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x198*/ { "SMSG_QUESTUPDATE_COMPLETE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x199*/ { "SMSG_QUESTUPDATE_ADD_KILL",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x19A*/ { "SMSG_QUESTUPDATE_ADD_ITEM",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x19B*/ { "CMSG_QUEST_CONFIRM_ACCEPT",                    STATUS_LOGGEDIN, &WorldSession::HandleQuestConfirmAccept        }, +    /*0x19C*/ { "SMSG_QUEST_CONFIRM_ACCEPT",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x19D*/ { "CMSG_PUSHQUESTTOPARTY",                        STATUS_LOGGEDIN, &WorldSession::HandleQuestPushToParty          }, +    /*0x19E*/ { "CMSG_LIST_INVENTORY",                          STATUS_LOGGEDIN, &WorldSession::HandleListInventoryOpcode       }, +    /*0x19F*/ { "SMSG_LIST_INVENTORY",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1A0*/ { "CMSG_SELL_ITEM",                               STATUS_LOGGEDIN, &WorldSession::HandleSellItemOpcode            }, +    /*0x1A1*/ { "SMSG_SELL_ITEM",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1A2*/ { "CMSG_BUY_ITEM",                                STATUS_LOGGEDIN, &WorldSession::HandleBuyItemOpcode             }, +    /*0x1A3*/ { "CMSG_BUY_ITEM_IN_SLOT",                        STATUS_LOGGEDIN, &WorldSession::HandleBuyItemInSlotOpcode       }, +    /*0x1A4*/ { "SMSG_BUY_ITEM",                                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1A5*/ { "SMSG_BUY_FAILED",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1A6*/ { "CMSG_TAXICLEARALLNODES",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1A7*/ { "CMSG_TAXIENABLEALLNODES",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1A8*/ { "CMSG_TAXISHOWNODES",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1A9*/ { "SMSG_SHOWTAXINODES",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1AA*/ { "CMSG_TAXINODE_STATUS_QUERY",                   STATUS_LOGGEDIN, &WorldSession::HandleTaxiNodeStatusQueryOpcode }, +    /*0x1AB*/ { "SMSG_TAXINODE_STATUS",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1AC*/ { "CMSG_TAXIQUERYAVAILABLENODES",                 STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes   }, +    /*0x1AD*/ { "CMSG_ACTIVATETAXI",                            STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiOpcode        }, +    /*0x1AE*/ { "SMSG_ACTIVATETAXIREPLY",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1AF*/ { "SMSG_NEW_TAXI_PATH",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1B0*/ { "CMSG_TRAINER_LIST",                            STATUS_LOGGEDIN, &WorldSession::HandleTrainerListOpcode         }, +    /*0x1B1*/ { "SMSG_TRAINER_LIST",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1B2*/ { "CMSG_TRAINER_BUY_SPELL",                       STATUS_LOGGEDIN, &WorldSession::HandleTrainerBuySpellOpcode     }, +    /*0x1B3*/ { "SMSG_TRAINER_BUY_SUCCEEDED",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1B4*/ { "SMSG_TRAINER_BUY_FAILED",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1B5*/ { "CMSG_BINDER_ACTIVATE",                         STATUS_LOGGEDIN, &WorldSession::HandleBinderActivateOpcode      }, +    /*0x1B6*/ { "SMSG_PLAYERBINDERROR",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1B7*/ { "CMSG_BANKER_ACTIVATE",                         STATUS_LOGGEDIN, &WorldSession::HandleBankerActivateOpcode      }, +    /*0x1B8*/ { "SMSG_SHOW_BANK",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1B9*/ { "CMSG_BUY_BANK_SLOT",                           STATUS_LOGGEDIN, &WorldSession::HandleBuyBankSlotOpcode         }, +    /*0x1BA*/ { "SMSG_BUY_BANK_SLOT_RESULT",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1BB*/ { "CMSG_PETITION_SHOWLIST",                       STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowListOpcode    }, +    /*0x1BC*/ { "SMSG_PETITION_SHOWLIST",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1BD*/ { "CMSG_PETITION_BUY",                            STATUS_LOGGEDIN, &WorldSession::HandlePetitionBuyOpcode         }, +    /*0x1BE*/ { "CMSG_PETITION_SHOW_SIGNATURES",                STATUS_LOGGEDIN, &WorldSession::HandlePetitionShowSignOpcode    }, +    /*0x1BF*/ { "SMSG_PETITION_SHOW_SIGNATURES",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1C0*/ { "CMSG_PETITION_SIGN",                           STATUS_LOGGEDIN, &WorldSession::HandlePetitionSignOpcode        }, +    /*0x1C1*/ { "SMSG_PETITION_SIGN_RESULTS",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1C2*/ { "MSG_PETITION_DECLINE",                         STATUS_LOGGEDIN, &WorldSession::HandlePetitionDeclineOpcode     }, +    /*0x1C3*/ { "CMSG_OFFER_PETITION",                          STATUS_LOGGEDIN, &WorldSession::HandleOfferPetitionOpcode       }, +    /*0x1C4*/ { "CMSG_TURN_IN_PETITION",                        STATUS_LOGGEDIN, &WorldSession::HandleTurnInPetitionOpcode      }, +    /*0x1C5*/ { "SMSG_TURN_IN_PETITION_RESULTS",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1C6*/ { "CMSG_PETITION_QUERY",                          STATUS_LOGGEDIN, &WorldSession::HandlePetitionQueryOpcode       }, +    /*0x1C7*/ { "SMSG_PETITION_QUERY_RESPONSE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1C8*/ { "SMSG_FISH_NOT_HOOKED",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1C9*/ { "SMSG_FISH_ESCAPED",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1CA*/ { "CMSG_BUG",                                     STATUS_LOGGEDIN, &WorldSession::HandleBugOpcode                 }, +    /*0x1CB*/ { "SMSG_NOTIFICATION",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1CC*/ { "CMSG_PLAYED_TIME",                             STATUS_LOGGEDIN, &WorldSession::HandlePlayedTime                }, +    /*0x1CD*/ { "SMSG_PLAYED_TIME",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1CE*/ { "CMSG_QUERY_TIME",                              STATUS_LOGGEDIN, &WorldSession::HandleQueryTimeOpcode           }, +    /*0x1CF*/ { "SMSG_QUERY_TIME_RESPONSE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1D0*/ { "SMSG_LOG_XPGAIN",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1D1*/ { "SMSG_AURACASTLOG",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1D2*/ { "CMSG_RECLAIM_CORPSE",                          STATUS_LOGGEDIN, &WorldSession::HandleCorpseReclaimOpcode       }, +    /*0x1D3*/ { "CMSG_WRAP_ITEM",                               STATUS_LOGGEDIN, &WorldSession::HandleWrapItemOpcode            }, +    /*0x1D4*/ { "SMSG_LEVELUP_INFO",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1D5*/ { "MSG_MINIMAP_PING",                             STATUS_LOGGEDIN, &WorldSession::HandleMinimapPingOpcode         }, +    /*0x1D6*/ { "SMSG_RESISTLOG",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1D7*/ { "SMSG_ENCHANTMENTLOG",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1D8*/ { "CMSG_SET_SKILL_CHEAT",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1D9*/ { "SMSG_START_MIRROR_TIMER",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1DA*/ { "SMSG_PAUSE_MIRROR_TIMER",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1DB*/ { "SMSG_STOP_MIRROR_TIMER",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1DC*/ { "CMSG_PING",                                    STATUS_NEVER,    &WorldSession::Handle_EarlyProccess            }, +    /*0x1DD*/ { "SMSG_PONG",                                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1DE*/ { "SMSG_CLEAR_COOLDOWN",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1DF*/ { "SMSG_GAMEOBJECT_PAGETEXT",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1E0*/ { "CMSG_SETSHEATHED",                             STATUS_LOGGEDIN, &WorldSession::HandleSetSheathedOpcode         }, +    /*0x1E1*/ { "SMSG_COOLDOWN_CHEAT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1E2*/ { "SMSG_SPELL_DELAYED",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1E3*/ { "CMSG_PLAYER_MACRO_OBSOLETE",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1E4*/ { "SMSG_PLAYER_MACRO_OBSOLETE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1E5*/ { "CMSG_GHOST",                                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1E6*/ { "CMSG_GM_INVIS",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1E7*/ { "SMSG_INVALID_PROMOTION_CODE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1E8*/ { "MSG_GM_BIND_OTHER",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1E9*/ { "MSG_GM_SUMMON",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1EA*/ { "SMSG_ITEM_TIME_UPDATE",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1EB*/ { "SMSG_ITEM_ENCHANT_TIME_UPDATE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1EC*/ { "SMSG_AUTH_CHALLENGE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1ED*/ { "CMSG_AUTH_SESSION",                            STATUS_NEVER,    &WorldSession::Handle_EarlyProccess            }, +    /*0x1EE*/ { "SMSG_AUTH_RESPONSE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1EF*/ { "MSG_GM_SHOWLABEL",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1F0*/ { "CMSG_PET_CAST_SPELL",                          STATUS_LOGGEDIN, &WorldSession::HandlePetCastSpellOpcode        }, +    /*0x1F1*/ { "MSG_SAVE_GUILD_EMBLEM",                        STATUS_LOGGEDIN, &WorldSession::HandleGuildSaveEmblemOpcode     }, +    /*0x1F2*/ { "MSG_TABARDVENDOR_ACTIVATE",                    STATUS_LOGGEDIN, &WorldSession::HandleTabardVendorActivateOpcode}, +    /*0x1F3*/ { "SMSG_PLAY_SPELL_VISUAL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1F4*/ { "CMSG_ZONEUPDATE",                              STATUS_LOGGEDIN, &WorldSession::HandleZoneUpdateOpcode          }, +    /*0x1F5*/ { "SMSG_PARTYKILLLOG",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1F6*/ { "SMSG_COMPRESSED_UPDATE_OBJECT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1F7*/ { "SMSG_PLAY_SPELL_IMPACT",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1F8*/ { "SMSG_EXPLORATION_EXPERIENCE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1F9*/ { "CMSG_GM_SET_SECURITY_GROUP",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1FA*/ { "CMSG_GM_NUKE",                                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1FB*/ { "MSG_RANDOM_ROLL",                              STATUS_LOGGEDIN, &WorldSession::HandleRandomRollOpcode          }, +    /*0x1FC*/ { "SMSG_ENVIRONMENTALDAMAGELOG",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1FD*/ { "CMSG_RWHOIS_OBSOLETE",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x1FE*/ { "SMSG_RWHOIS",                                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x1FF*/ { "MSG_LOOKING_FOR_GROUP",                        STATUS_LOGGEDIN, &WorldSession::HandleLookingForGroup           }, +    /*0x200*/ { "CMSG_SET_LOOKING_FOR_GROUP",                   STATUS_LOGGEDIN, &WorldSession::HandleSetLfgOpcode              }, +    /*0x201*/ { "CMSG_UNLEARN_SPELL",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x202*/ { "CMSG_UNLEARN_SKILL",                           STATUS_LOGGEDIN, &WorldSession::HandleUnlearnSkillOpcode        }, +    /*0x203*/ { "SMSG_REMOVED_SPELL",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x204*/ { "CMSG_DECHARGE",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x205*/ { "CMSG_GMTICKET_CREATE",                         STATUS_LOGGEDIN, &WorldSession::HandleGMTicketCreateOpcode      }, +    /*0x206*/ { "SMSG_GMTICKET_CREATE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x207*/ { "CMSG_GMTICKET_UPDATETEXT",                     STATUS_LOGGEDIN, &WorldSession::HandleGMTicketUpdateTextOpcode  }, +    /*0x208*/ { "SMSG_GMTICKET_UPDATETEXT",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x209*/ { "SMSG_ACCOUNT_DATA_TIMES",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x20A*/ { "CMSG_REQUEST_ACCOUNT_DATA",                    STATUS_LOGGEDIN, &WorldSession::HandleRequestAccountData        }, +    /*0x20B*/ { "CMSG_UPDATE_ACCOUNT_DATA",                     STATUS_AUTHED,   &WorldSession::HandleUpdateAccountData         }, +    /*0x20C*/ { "SMSG_UPDATE_ACCOUNT_DATA",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x20D*/ { "SMSG_CLEAR_FAR_SIGHT_IMMEDIATE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x20E*/ { "SMSG_POWERGAINLOG_OBSOLETE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x20F*/ { "CMSG_GM_TEACH",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x210*/ { "CMSG_GM_CREATE_ITEM_TARGET",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x211*/ { "CMSG_GMTICKET_GETTICKET",                      STATUS_LOGGEDIN, &WorldSession::HandleGMTicketGetTicketOpcode   }, +    /*0x212*/ { "SMSG_GMTICKET_GETTICKET",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x213*/ { "CMSG_UNLEARN_TALENTS",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x214*/ { "SMSG_GAMEOBJECT_SPAWN_ANIM_OBSOLETE",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x215*/ { "SMSG_GAMEOBJECT_DESPAWN_ANIM",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x216*/ { "MSG_CORPSE_QUERY",                             STATUS_LOGGEDIN, &WorldSession::HandleCorpseQueryOpcode         }, +    /*0x217*/ { "CMSG_GMTICKET_DELETETICKET",                   STATUS_LOGGEDIN, &WorldSession::HandleGMTicketDeleteOpcode      }, +    /*0x218*/ { "SMSG_GMTICKET_DELETETICKET",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x219*/ { "SMSG_CHAT_WRONG_FACTION",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x21A*/ { "CMSG_GMTICKET_SYSTEMSTATUS",                   STATUS_LOGGEDIN, &WorldSession::HandleGMTicketSystemStatusOpcode}, +    /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE",                  STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, +    /*0x21D*/ { "CMSG_SET_STAT_CHEAT",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x21F*/ { "CMSG_SKILL_BUY_STEP",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x220*/ { "CMSG_SKILL_BUY_RANK",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x221*/ { "CMSG_XP_CHEAT",                                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x222*/ { "SMSG_SPIRIT_HEALER_CONFIRM",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x223*/ { "CMSG_CHARACTER_POINT_CHEAT",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x224*/ { "SMSG_GOSSIP_POI",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x225*/ { "CMSG_CHAT_IGNORED",                            STATUS_LOGGEDIN, &WorldSession::HandleChatIgnoredOpcode         }, +    /*0x226*/ { "CMSG_GM_VISION",                               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x227*/ { "CMSG_SERVER_COMMAND",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x228*/ { "CMSG_GM_SILENCE",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x229*/ { "CMSG_GM_REVEALTO",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x22A*/ { "CMSG_GM_RESURRECT",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x22B*/ { "CMSG_GM_SUMMONMOB",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x22C*/ { "CMSG_GM_MOVECORPSE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x22D*/ { "CMSG_GM_FREEZE",                               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x22E*/ { "CMSG_GM_UBERINVIS",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x22F*/ { "CMSG_GM_REQUEST_PLAYER_INFO",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x230*/ { "SMSG_GM_PLAYER_INFO",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x231*/ { "CMSG_GUILD_RANK",                              STATUS_LOGGEDIN, &WorldSession::HandleGuildRankOpcode           }, +    /*0x232*/ { "CMSG_GUILD_ADD_RANK",                          STATUS_LOGGEDIN, &WorldSession::HandleGuildAddRankOpcode        }, +    /*0x233*/ { "CMSG_GUILD_DEL_RANK",                          STATUS_LOGGEDIN, &WorldSession::HandleGuildDelRankOpcode        }, +    /*0x234*/ { "CMSG_GUILD_SET_PUBLIC_NOTE",                   STATUS_LOGGEDIN, &WorldSession::HandleGuildSetPublicNoteOpcode  }, +    /*0x235*/ { "CMSG_GUILD_SET_OFFICER_NOTE",                  STATUS_LOGGEDIN, &WorldSession::HandleGuildSetOfficerNoteOpcode }, +    /*0x236*/ { "SMSG_LOGIN_VERIFY_WORLD",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x237*/ { "CMSG_CLEAR_EXPLORATION",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x238*/ { "CMSG_SEND_MAIL",                               STATUS_LOGGEDIN, &WorldSession::HandleSendMail                  }, +    /*0x239*/ { "SMSG_SEND_MAIL_RESULT",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x23A*/ { "CMSG_GET_MAIL_LIST",                           STATUS_LOGGEDIN, &WorldSession::HandleGetMail                   }, +    /*0x23B*/ { "SMSG_MAIL_LIST_RESULT",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x23C*/ { "CMSG_BATTLEFIELD_LIST",                        STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundListOpcode    }, +    /*0x23D*/ { "SMSG_BATTLEFIELD_LIST",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x23E*/ { "CMSG_BATTLEFIELD_JOIN",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x23F*/ { "SMSG_BATTLEFIELD_WIN_OBSOLETE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x240*/ { "SMSG_BATTLEFIELD_LOSE_OBSOLETE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x241*/ { "CMSG_TAXICLEARNODE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x242*/ { "CMSG_TAXIENABLENODE",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x243*/ { "CMSG_ITEM_TEXT_QUERY",                         STATUS_LOGGEDIN, &WorldSession::HandleItemTextQuery             }, +    /*0x244*/ { "SMSG_ITEM_TEXT_QUERY_RESPONSE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x245*/ { "CMSG_MAIL_TAKE_MONEY",                         STATUS_LOGGEDIN, &WorldSession::HandleTakeMoney                 }, +    /*0x246*/ { "CMSG_MAIL_TAKE_ITEM",                          STATUS_LOGGEDIN, &WorldSession::HandleTakeItem                  }, +    /*0x247*/ { "CMSG_MAIL_MARK_AS_READ",                       STATUS_LOGGEDIN, &WorldSession::HandleMarkAsRead                }, +    /*0x248*/ { "CMSG_MAIL_RETURN_TO_SENDER",                   STATUS_LOGGEDIN, &WorldSession::HandleReturnToSender            }, +    /*0x249*/ { "CMSG_MAIL_DELETE",                             STATUS_LOGGEDIN, &WorldSession::HandleMailDelete                }, +    /*0x24A*/ { "CMSG_MAIL_CREATE_TEXT_ITEM",                   STATUS_LOGGEDIN, &WorldSession::HandleMailCreateTextItem        }, +    /*0x24B*/ { "SMSG_SPELLLOGMISS",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x24C*/ { "SMSG_SPELLLOGEXECUTE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x24D*/ { "SMSG_DEBUGAURAPROC",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x24E*/ { "SMSG_PERIODICAURALOG",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x24F*/ { "SMSG_SPELLDAMAGESHIELD",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x250*/ { "SMSG_SPELLNONMELEEDAMAGELOG",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x251*/ { "CMSG_LEARN_TALENT",                            STATUS_LOGGEDIN, &WorldSession::HandleLearnTalentOpcode         }, +    /*0x252*/ { "SMSG_RESURRECT_FAILED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x253*/ { "CMSG_TOGGLE_PVP",                              STATUS_LOGGEDIN, &WorldSession::HandleTogglePvP                 }, +    /*0x254*/ { "SMSG_ZONE_UNDER_ATTACK",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x255*/ { "MSG_AUCTION_HELLO",                            STATUS_LOGGEDIN, &WorldSession::HandleAuctionHelloOpcode        }, +    /*0x256*/ { "CMSG_AUCTION_SELL_ITEM",                       STATUS_LOGGEDIN, &WorldSession::HandleAuctionSellItem           }, +    /*0x257*/ { "CMSG_AUCTION_REMOVE_ITEM",                     STATUS_LOGGEDIN, &WorldSession::HandleAuctionRemoveItem         }, +    /*0x258*/ { "CMSG_AUCTION_LIST_ITEMS",                      STATUS_LOGGEDIN, &WorldSession::HandleAuctionListItems          }, +    /*0x259*/ { "CMSG_AUCTION_LIST_OWNER_ITEMS",                STATUS_LOGGEDIN, &WorldSession::HandleAuctionListOwnerItems     }, +    /*0x25A*/ { "CMSG_AUCTION_PLACE_BID",                       STATUS_LOGGEDIN, &WorldSession::HandleAuctionPlaceBid           }, +    /*0x25B*/ { "SMSG_AUCTION_COMMAND_RESULT",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x25C*/ { "SMSG_AUCTION_LIST_RESULT",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x25D*/ { "SMSG_AUCTION_OWNER_LIST_RESULT",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x25E*/ { "SMSG_AUCTION_BIDDER_NOTIFICATION",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x25F*/ { "SMSG_AUCTION_OWNER_NOTIFICATION",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x260*/ { "SMSG_PROCRESIST",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x261*/ { "SMSG_STANDSTATE_CHANGE_FAILURE_OBSOLETE",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x262*/ { "SMSG_DISPEL_FAILED",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x263*/ { "SMSG_SPELLORDAMAGE_IMMUNE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x264*/ { "CMSG_AUCTION_LIST_BIDDER_ITEMS",               STATUS_LOGGEDIN, &WorldSession::HandleAuctionListBidderItems    }, +    /*0x265*/ { "SMSG_AUCTION_BIDDER_LIST_RESULT",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x266*/ { "SMSG_SET_FLAT_SPELL_MODIFIER",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x267*/ { "SMSG_SET_PCT_SPELL_MODIFIER",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x268*/ { "CMSG_SET_AMMO",                                STATUS_LOGGEDIN, &WorldSession::HandleSetAmmoOpcode             }, +    /*0x269*/ { "SMSG_CORPSE_RECLAIM_DELAY",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x26A*/ { "CMSG_SET_ACTIVE_MOVER",                        STATUS_LOGGEDIN, &WorldSession::HandleSetActiveMoverOpcode      }, +    /*0x26B*/ { "CMSG_PET_CANCEL_AURA",                         STATUS_LOGGEDIN, &WorldSession::HandlePetCancelAuraOpcode       }, +    /*0x26C*/ { "CMSG_PLAYER_AI_CHEAT",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x26D*/ { "CMSG_CANCEL_AUTO_REPEAT_SPELL",                STATUS_LOGGEDIN, &WorldSession::HandleCancelAutoRepeatSpellOpcode}, +    /*0x26E*/ { "MSG_GM_ACCOUNT_ONLINE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x26F*/ { "MSG_LIST_STABLED_PETS",                        STATUS_LOGGEDIN, &WorldSession::HandleListStabledPetsOpcode     }, +    /*0x270*/ { "CMSG_STABLE_PET",                              STATUS_LOGGEDIN, &WorldSession::HandleStablePet                 }, +    /*0x271*/ { "CMSG_UNSTABLE_PET",                            STATUS_LOGGEDIN, &WorldSession::HandleUnstablePet               }, +    /*0x272*/ { "CMSG_BUY_STABLE_SLOT",                         STATUS_LOGGEDIN, &WorldSession::HandleBuyStableSlot             }, +    /*0x273*/ { "SMSG_STABLE_RESULT",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x274*/ { "CMSG_STABLE_REVIVE_PET",                       STATUS_LOGGEDIN, &WorldSession::HandleStableRevivePet           }, +    /*0x275*/ { "CMSG_STABLE_SWAP_PET",                         STATUS_LOGGEDIN, &WorldSession::HandleStableSwapPet             }, +    /*0x276*/ { "MSG_QUEST_PUSH_RESULT",                        STATUS_LOGGEDIN, &WorldSession::HandleQuestPushResult           }, +    /*0x277*/ { "SMSG_PLAY_MUSIC",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x278*/ { "SMSG_PLAY_OBJECT_SOUND",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x279*/ { "CMSG_REQUEST_PET_INFO",                        STATUS_LOGGEDIN, &WorldSession::HandleRequestPetInfoOpcode      }, +    /*0x27A*/ { "CMSG_FAR_SIGHT",                               STATUS_LOGGEDIN, &WorldSession::HandleFarSightOpcode            }, +    /*0x27B*/ { "SMSG_SPELLDISPELLOG",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x27C*/ { "SMSG_DAMAGE_CALC_LOG",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x27D*/ { "CMSG_ENABLE_DAMAGE_LOG",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x27E*/ { "CMSG_GROUP_CHANGE_SUB_GROUP",                  STATUS_LOGGEDIN, &WorldSession::HandleGroupChangeSubGroupOpcode }, +    /*0x27F*/ { "CMSG_REQUEST_PARTY_MEMBER_STATS",              STATUS_LOGGEDIN, &WorldSession::HandleRequestPartyMemberStatsOpcode}, +    /*0x280*/ { "CMSG_GROUP_SWAP_SUB_GROUP",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x281*/ { "CMSG_RESET_FACTION_CHEAT",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x282*/ { "CMSG_AUTOSTORE_BANK_ITEM",                     STATUS_LOGGEDIN, &WorldSession::HandleAutoStoreBankItemOpcode   }, +    /*0x283*/ { "CMSG_AUTOBANK_ITEM",                           STATUS_LOGGEDIN, &WorldSession::HandleAutoBankItemOpcode        }, +    /*0x284*/ { "MSG_QUERY_NEXT_MAIL_TIME",                     STATUS_LOGGEDIN, &WorldSession::HandleMsgQueryNextMailtime      }, +    /*0x285*/ { "SMSG_RECEIVED_MAIL",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x286*/ { "SMSG_RAID_GROUP_ONLY",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x287*/ { "CMSG_SET_DURABILITY_CHEAT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x288*/ { "CMSG_SET_PVP_RANK_CHEAT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x289*/ { "CMSG_ADD_PVP_MEDAL_CHEAT",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x28A*/ { "CMSG_DEL_PVP_MEDAL_CHEAT",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x28B*/ { "CMSG_SET_PVP_TITLE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x28C*/ { "SMSG_PVP_CREDIT",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x28D*/ { "SMSG_AUCTION_REMOVED_NOTIFICATION",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x28E*/ { "CMSG_GROUP_RAID_CONVERT",                      STATUS_LOGGEDIN, &WorldSession::HandleRaidConvertOpcode         }, +    /*0x28F*/ { "CMSG_GROUP_ASSISTANT_LEADER",                  STATUS_LOGGEDIN, &WorldSession::HandleGroupAssistantOpcode      }, +    /*0x290*/ { "CMSG_BUYBACK_ITEM",                            STATUS_LOGGEDIN, &WorldSession::HandleBuybackItem               }, +    /*0x291*/ { "SMSG_SERVER_MESSAGE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x292*/ { "CMSG_MEETINGSTONE_JOIN",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x293*/ { "CMSG_MEETINGSTONE_LEAVE",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x294*/ { "CMSG_MEETINGSTONE_CHEAT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x295*/ { "SMSG_MEETINGSTONE_SETQUEUE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x296*/ { "CMSG_MEETINGSTONE_INFO",                       STATUS_LOGGEDIN, &WorldSession::HandleMeetingStoneInfo          }, +    /*0x297*/ { "SMSG_MEETINGSTONE_COMPLETE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x298*/ { "SMSG_MEETINGSTONE_IN_PROGRESS",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x299*/ { "SMSG_MEETINGSTONE_MEMBER_ADDED",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x29A*/ { "CMSG_GMTICKETSYSTEM_TOGGLE",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x29B*/ { "CMSG_CANCEL_GROWTH_AURA",                      STATUS_LOGGEDIN, &WorldSession::HandleCancelGrowthAuraOpcode    }, +    /*0x29C*/ { "SMSG_CANCEL_AUTO_REPEAT",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x29D*/ { "SMSG_STANDSTATE_UPDATE",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x29E*/ { "SMSG_LOOT_ALL_PASSED",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x29F*/ { "SMSG_LOOT_ROLL_WON",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A0*/ { "CMSG_LOOT_ROLL",                               STATUS_LOGGEDIN, &WorldSession::HandleLootRoll                  }, +    /*0x2A1*/ { "SMSG_LOOT_START_ROLL",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A2*/ { "SMSG_LOOT_ROLL",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A3*/ { "CMSG_LOOT_MASTER_GIVE",                        STATUS_LOGGEDIN, &WorldSession::HandleLootMasterGiveOpcode      }, +    /*0x2A4*/ { "SMSG_LOOT_MASTER_LIST",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A5*/ { "SMSG_SET_FORCED_REACTIONS",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A6*/ { "SMSG_SPELL_FAILED_OTHER",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A7*/ { "SMSG_GAMEOBJECT_RESET_STATE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2A8*/ { "CMSG_REPAIR_ITEM",                             STATUS_LOGGEDIN, &WorldSession::HandleRepairItemOpcode          }, +    /*0x2A9*/ { "SMSG_CHAT_PLAYER_NOT_FOUND",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2AA*/ { "MSG_TALENT_WIPE_CONFIRM",                      STATUS_LOGGEDIN, &WorldSession::HandleTalentWipeOpcode          }, +    /*0x2AB*/ { "SMSG_SUMMON_REQUEST",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2AC*/ { "CMSG_SUMMON_RESPONSE",                         STATUS_LOGGEDIN, &WorldSession::HandleSummonResponseOpcode      }, +    /*0x2AD*/ { "MSG_MOVE_TOGGLE_GRAVITY_CHEAT",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2AE*/ { "SMSG_MONSTER_MOVE_TRANSPORT",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2AF*/ { "SMSG_PET_BROKEN",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2B0*/ { "MSG_MOVE_FEATHER_FALL",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2B1*/ { "MSG_MOVE_WATER_WALK",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2B2*/ { "CMSG_SERVER_BROADCAST",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2B3*/ { "CMSG_SELF_RES",                                STATUS_LOGGEDIN, &WorldSession::HandleSelfResOpcode             }, +    /*0x2B4*/ { "SMSG_FEIGN_DEATH_RESISTED",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2B5*/ { "CMSG_RUN_SCRIPT",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2B6*/ { "SMSG_SCRIPT_MESSAGE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2B7*/ { "SMSG_DUEL_COUNTDOWN",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2B8*/ { "SMSG_AREA_TRIGGER_MESSAGE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2B9*/ { "CMSG_SHOWING_HELM",                            STATUS_LOGGEDIN, &WorldSession::HandleToggleHelmOpcode          }, +    /*0x2BA*/ { "CMSG_SHOWING_CLOAK",                           STATUS_LOGGEDIN, &WorldSession::HandleToggleCloakOpcode         }, +    /*0x2BB*/ { "SMSG_MEETINGSTONE_JOINFAILED",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2BC*/ { "SMSG_PLAYER_SKINNED",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2BD*/ { "SMSG_DURABILITY_DAMAGE_DEATH",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2BE*/ { "CMSG_SET_EXPLORATION",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2BF*/ { "CMSG_SET_ACTIONBAR_TOGGLES",                   STATUS_AUTHED,   &WorldSession::HandleSetActionBar              }, +    /*0x2C0*/ { "UMSG_DELETE_GUILD_CHARTER",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2C1*/ { "MSG_PETITION_RENAME",                          STATUS_LOGGEDIN, &WorldSession::HandlePetitionRenameOpcode      }, +    /*0x2C2*/ { "SMSG_INIT_WORLD_STATES",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2C3*/ { "SMSG_UPDATE_WORLD_STATE",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2C4*/ { "CMSG_ITEM_NAME_QUERY",                         STATUS_LOGGEDIN, &WorldSession::HandleItemNameQueryOpcode       }, +    /*0x2C5*/ { "SMSG_ITEM_NAME_QUERY_RESPONSE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2C6*/ { "SMSG_PET_ACTION_FEEDBACK",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2C7*/ { "CMSG_CHAR_RENAME",                             STATUS_AUTHED,   &WorldSession::HandleChangePlayerNameOpcode    }, +    /*0x2C8*/ { "SMSG_CHAR_RENAME",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2C9*/ { "CMSG_MOVE_SPLINE_DONE",                        STATUS_LOGGEDIN, &WorldSession::HandleTaxiNextDestinationOpcode }, +    /*0x2CA*/ { "CMSG_MOVE_FALL_RESET",                         STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x2CB*/ { "SMSG_INSTANCE_SAVE_CREATED",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2CC*/ { "SMSG_RAID_INSTANCE_INFO",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2CD*/ { "CMSG_REQUEST_RAID_INFO",                       STATUS_LOGGEDIN, &WorldSession::HandleRequestRaidInfoOpcode     }, +    /*0x2CE*/ { "CMSG_MOVE_TIME_SKIPPED",                       STATUS_LOGGEDIN, &WorldSession::HandleMoveTimeSkippedOpcode     }, +    /*0x2CF*/ { "CMSG_MOVE_FEATHER_FALL_ACK",                   STATUS_LOGGEDIN, &WorldSession::HandleFeatherFallAck            }, +    /*0x2D0*/ { "CMSG_MOVE_WATER_WALK_ACK",                     STATUS_LOGGEDIN, &WorldSession::HandleMoveWaterWalkAck          }, +    /*0x2D1*/ { "CMSG_MOVE_NOT_ACTIVE_MOVER",                   STATUS_LOGGEDIN, &WorldSession::HandleMoveNotActiveMover        }, +    /*0x2D2*/ { "SMSG_PLAY_SOUND",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2D3*/ { "CMSG_BATTLEFIELD_STATUS",                      STATUS_LOGGEDIN, &WorldSession::HandleBattlefieldStatusOpcode   }, +    /*0x2D4*/ { "SMSG_BATTLEFIELD_STATUS",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2D5*/ { "CMSG_BATTLEFIELD_PORT",                        STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPortOpcode}, +    /*0x2D6*/ { "MSG_INSPECT_HONOR_STATS",                      STATUS_LOGGEDIN, &WorldSession::HandleInspectHonorStatsOpcode   }, +    /*0x2D7*/ { "CMSG_BATTLEMASTER_HELLO",                      STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundHelloOpcode   }, +    /*0x2D8*/ { "CMSG_MOVE_START_SWIM_CHEAT",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2D9*/ { "CMSG_MOVE_STOP_SWIM_CHEAT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2DA*/ { "SMSG_FORCE_WALK_SPEED_CHANGE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2DB*/ { "CMSG_FORCE_WALK_SPEED_CHANGE_ACK",             STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x2DC*/ { "SMSG_FORCE_SWIM_BACK_SPEED_CHANGE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2DD*/ { "CMSG_FORCE_SWIM_BACK_SPEED_CHANGE_ACK",        STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x2DE*/ { "SMSG_FORCE_TURN_RATE_CHANGE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2DF*/ { "CMSG_FORCE_TURN_RATE_CHANGE_ACK",              STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x2E0*/ { "MSG_PVP_LOG_DATA",                             STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPVPlogdataOpcode}, +    /*0x2E1*/ { "CMSG_LEAVE_BATTLEFIELD",                       STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundLeaveOpcode   }, +    /*0x2E2*/ { "CMSG_AREA_SPIRIT_HEALER_QUERY",                STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueryOpcode}, +    /*0x2E3*/ { "CMSG_AREA_SPIRIT_HEALER_QUEUE",                STATUS_LOGGEDIN, &WorldSession::HandleAreaSpiritHealerQueueOpcode}, +    /*0x2E4*/ { "SMSG_AREA_SPIRIT_HEALER_TIME",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2E5*/ { "CMSG_GM_UNTEACH",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2E6*/ { "SMSG_WARDEN_DATA",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2E7*/ { "CMSG_WARDEN_DATA",                             STATUS_LOGGEDIN, &WorldSession::HandleWardenDataOpcode          }, +    /*0x2E8*/ { "SMSG_GROUP_JOINED_BATTLEGROUND",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2E9*/ { "MSG_BATTLEGROUND_PLAYER_POSITIONS",            STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundPlayerPositionsOpcode}, +    /*0x2EA*/ { "CMSG_PET_STOP_ATTACK",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2EB*/ { "SMSG_BINDER_CONFIRM",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2EC*/ { "SMSG_BATTLEGROUND_PLAYER_JOINED",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2ED*/ { "SMSG_BATTLEGROUND_PLAYER_LEFT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2EE*/ { "CMSG_BATTLEMASTER_JOIN",                       STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundJoinOpcode    }, +    /*0x2EF*/ { "SMSG_ADDON_INFO",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F0*/ { "CMSG_PET_UNLEARN",                             STATUS_LOGGEDIN, &WorldSession::HandlePetUnlearnOpcode          }, +    /*0x2F1*/ { "SMSG_PET_UNLEARN_CONFIRM",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F2*/ { "SMSG_PARTY_MEMBER_STATS_FULL",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F3*/ { "CMSG_PET_SPELL_AUTOCAST",                      STATUS_LOGGEDIN, &WorldSession::HandlePetSpellAutocastOpcode    }, +    /*0x2F4*/ { "SMSG_WEATHER",                                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F5*/ { "SMSG_PLAY_TIME_WARNING",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F6*/ { "SMSG_MINIGAME_SETUP",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F7*/ { "SMSG_MINIGAME_STATE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2F8*/ { "CMSG_MINIGAME_MOVE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x2F9*/ { "SMSG_MINIGAME_MOVE_FAILED",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2FA*/ { "SMSG_RAID_INSTANCE_MESSAGE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2FB*/ { "SMSG_COMPRESSED_MOVES",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2FC*/ { "CMSG_GUILD_INFO_TEXT",                         STATUS_LOGGEDIN, &WorldSession::HandleGuildChangeInfoOpcode     }, +    /*0x2FD*/ { "SMSG_CHAT_RESTRICTED",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2FE*/ { "SMSG_SPLINE_SET_RUN_SPEED",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x2FF*/ { "SMSG_SPLINE_SET_RUN_BACK_SPEED",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x300*/ { "SMSG_SPLINE_SET_SWIM_SPEED",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x301*/ { "SMSG_SPLINE_SET_WALK_SPEED",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x302*/ { "SMSG_SPLINE_SET_SWIM_BACK_SPEED",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x303*/ { "SMSG_SPLINE_SET_TURN_RATE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x304*/ { "SMSG_SPLINE_MOVE_UNROOT",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x305*/ { "SMSG_SPLINE_MOVE_FEATHER_FALL",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x306*/ { "SMSG_SPLINE_MOVE_NORMAL_FALL",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x307*/ { "SMSG_SPLINE_MOVE_SET_HOVER",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x308*/ { "SMSG_SPLINE_MOVE_UNSET_HOVER",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x309*/ { "SMSG_SPLINE_MOVE_WATER_WALK",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x30A*/ { "SMSG_SPLINE_MOVE_LAND_WALK",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x30B*/ { "SMSG_SPLINE_MOVE_START_SWIM",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x30C*/ { "SMSG_SPLINE_MOVE_STOP_SWIM",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x30D*/ { "SMSG_SPLINE_MOVE_SET_RUN_MODE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x30E*/ { "SMSG_SPLINE_MOVE_SET_WALK_MODE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x30F*/ { "CMSG_GM_NUKE_ACCOUNT",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x310*/ { "MSG_GM_DESTROY_CORPSE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x311*/ { "CMSG_GM_DESTROY_ONLINE_CORPSE",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x312*/ { "CMSG_ACTIVATETAXIEXPRESS",                     STATUS_LOGGEDIN, &WorldSession::HandleActivateTaxiFarOpcode     }, +    /*0x313*/ { "SMSG_SET_FACTION_ATWAR",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x314*/ { "SMSG_GAMETIMEBIAS_SET",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x315*/ { "CMSG_DEBUG_ACTIONS_START",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x316*/ { "CMSG_DEBUG_ACTIONS_STOP",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x317*/ { "CMSG_SET_FACTION_INACTIVE",                    STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionInactiveOpcode}, +    /*0x318*/ { "CMSG_SET_WATCHED_FACTION",                     STATUS_LOGGEDIN, &WorldSession::HandleSetWatchedFactionIndexOpcode}, +    /*0x319*/ { "MSG_MOVE_TIME_SKIPPED",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x31A*/ { "SMSG_SPLINE_MOVE_ROOT",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x31B*/ { "CMSG_SET_EXPLORATION_ALL",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x31C*/ { "SMSG_INVALIDATE_PLAYER",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x31D*/ { "CMSG_RESET_INSTANCES",                         STATUS_LOGGEDIN, &WorldSession::HandleResetInstancesOpcode      }, +    /*0x31E*/ { "SMSG_INSTANCE_RESET",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x31F*/ { "SMSG_INSTANCE_RESET_FAILED",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x320*/ { "SMSG_UPDATE_LAST_INSTANCE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x321*/ { "MSG_RAID_TARGET_UPDATE",                       STATUS_LOGGEDIN, &WorldSession::HandleRaidIconTargetOpcode      }, +    /*0x322*/ { "MSG_RAID_READY_CHECK",                         STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckOpcode      }, +    /*0x323*/ { "CMSG_LUA_USAGE",                               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x324*/ { "SMSG_PET_ACTION_SOUND",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x325*/ { "SMSG_PET_DISMISS_SOUND",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x326*/ { "SMSG_GHOSTEE_GONE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x327*/ { "CMSG_GM_UPDATE_TICKET_STATUS",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x328*/ { "SMSG_GM_TICKET_STATUS_UPDATE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x329*/ { "MSG_SET_DUNGEON_DIFFICULTY",                   STATUS_LOGGEDIN, &WorldSession::HandleDungeonDifficultyOpcode   }, +    /*0x32A*/ { "CMSG_GMSURVEY_SUBMIT",                         STATUS_LOGGEDIN, &WorldSession::HandleGMSurveySubmit            }, +    /*0x32B*/ { "SMSG_UPDATE_INSTANCE_OWNERSHIP",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x32C*/ { "CMSG_IGNORE_KNOCKBACK_CHEAT",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x32D*/ { "SMSG_CHAT_PLAYER_AMBIGUOUS",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x32E*/ { "MSG_DELAY_GHOST_TELEPORT",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x32F*/ { "SMSG_SPELLINSTAKILLLOG",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x330*/ { "SMSG_SPELL_UPDATE_CHAIN_TARGETS",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x331*/ { "CMSG_CHAT_FILTERED",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x332*/ { "SMSG_EXPECTED_SPAM_RECORDS",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x333*/ { "SMSG_SPELLSTEALLOG",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x334*/ { "CMSG_LOTTERY_QUERY_OBSOLETE",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x335*/ { "SMSG_LOTTERY_QUERY_RESULT_OBSOLETE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x336*/ { "CMSG_BUY_LOTTERY_TICKET_OBSOLETE",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x337*/ { "SMSG_LOTTERY_RESULT_OBSOLETE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x338*/ { "SMSG_CHARACTER_PROFILE",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x339*/ { "SMSG_CHARACTER_PROFILE_REALM_CONNECTED",       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x33A*/ { "SMSG_DEFENSE_MESSAGE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x33B*/ { "SMSG_INSTANCE_DIFFICULTY",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x33C*/ { "MSG_GM_RESETINSTANCELIMIT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x33D*/ { "SMSG_MOTD",                                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x33E*/ { "SMSG_MOVE_SET_FLIGHT_OBSOLETE",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x33F*/ { "SMSG_MOVE_UNSET_FLIGHT_OBSOLETE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x340*/ { "CMSG_MOVE_FLIGHT_ACK_OBSOLETE",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x341*/ { "MSG_MOVE_START_SWIM_CHEAT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x342*/ { "MSG_MOVE_STOP_SWIM_CHEAT",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x343*/ { "SMSG_MOVE_SET_CAN_FLY",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x344*/ { "SMSG_MOVE_UNSET_CAN_FLY",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x345*/ { "CMSG_MOVE_SET_CAN_FLY_ACK",                    STATUS_LOGGEDIN, &WorldSession::HandleMoveFlyModeChangeAckOpcode}, +    /*0x346*/ { "CMSG_MOVE_SET_FLY",                            STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x347*/ { "CMSG_SOCKET_GEMS",                             STATUS_LOGGEDIN, &WorldSession::HandleSocketOpcode              }, +    /*0x348*/ { "CMSG_ARENA_TEAM_CREATE",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x349*/ { "SMSG_ARENA_TEAM_COMMAND_RESULT",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x34A*/ { "UMSG_UPDATE_ARENA_TEAM_OBSOLETE",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x34B*/ { "CMSG_ARENA_TEAM_QUERY",                        STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamQueryOpcode      }, +    /*0x34C*/ { "SMSG_ARENA_TEAM_QUERY_RESPONSE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x34D*/ { "CMSG_ARENA_TEAM_ROSTER",                       STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRosterOpcode     }, +    /*0x34E*/ { "SMSG_ARENA_TEAM_ROSTER",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x34F*/ { "CMSG_ARENA_TEAM_INVITE",                       STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamAddMemberOpcode  }, +    /*0x350*/ { "SMSG_ARENA_TEAM_INVITE",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x351*/ { "CMSG_ARENA_TEAM_ACCEPT",                       STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteAcceptOpcode}, +    /*0x352*/ { "CMSG_ARENA_TEAM_DECLINE",                      STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamInviteDeclineOpcode}, +    /*0x353*/ { "CMSG_ARENA_TEAM_LEAVE",                        STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamLeaveOpcode      }, +    /*0x354*/ { "CMSG_ARENA_TEAM_REMOVE",                       STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamRemoveFromTeamOpcode}, +    /*0x355*/ { "CMSG_ARENA_TEAM_DISBAND",                      STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamDisbandOpcode    }, +    /*0x356*/ { "CMSG_ARENA_TEAM_LEADER",                       STATUS_LOGGEDIN, &WorldSession::HandleArenaTeamPromoteToCaptainOpcode}, +    /*0x357*/ { "SMSG_ARENA_TEAM_EVENT",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x358*/ { "CMSG_BATTLEMASTER_JOIN_ARENA",                 STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundArenaJoin     }, +    /*0x359*/ { "MSG_MOVE_START_ASCEND",                        STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x35A*/ { "MSG_MOVE_STOP_ASCEND",                         STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x35B*/ { "SMSG_ARENA_TEAM_STATS",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x35C*/ { "CMSG_LFG_SET_AUTOJOIN",                        STATUS_AUTHED,   &WorldSession::HandleLfgAutoJoinOpcode         }, +    /*0x35D*/ { "CMSG_LFG_CLEAR_AUTOJOIN",                      STATUS_LOGGEDIN, &WorldSession::HandleLfgCancelAutoJoinOpcode   }, +    /*0x35E*/ { "CMSG_LFM_SET_AUTOFILL",                        STATUS_AUTHED,   &WorldSession::HandleLfmAutoAddMembersOpcode   }, +    /*0x35F*/ { "CMSG_LFM_CLEAR_AUTOFILL",                      STATUS_LOGGEDIN, &WorldSession::HandleLfmCancelAutoAddmembersOpcode}, +    /*0x360*/ { "CMSG_ACCEPT_LFG_MATCH",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x361*/ { "CMSG_DECLINE_LFG_MATCH",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x362*/ { "CMSG_CANCEL_PENDING_LFG",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x363*/ { "CMSG_CLEAR_LOOKING_FOR_GROUP",                 STATUS_LOGGEDIN, &WorldSession::HandleLfgClearOpcode            }, +    /*0x364*/ { "CMSG_CLEAR_LOOKING_FOR_MORE",                  STATUS_LOGGEDIN, &WorldSession::HandleLfmSetNoneOpcode          }, +    /*0x365*/ { "CMSG_SET_LOOKING_FOR_MORE",                    STATUS_LOGGEDIN, &WorldSession::HandleLfmSetOpcode              }, +    /*0x366*/ { "CMSG_SET_LFG_COMMENT",                         STATUS_LOGGEDIN, &WorldSession::HandleLfgSetCommentOpcode       }, +    /*0x367*/ { "SMSG_LFG_TIMEDOUT",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x368*/ { "SMSG_LFG_OTHER_TIMEDOUT",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x369*/ { "SMSG_LFG_AUTOJOIN_FAILED",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x36A*/ { "SMSG_LFG_AUTOJOIN_FAILED_NO_PLAYER",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x36B*/ { "SMSG_LFG_LEADER_IS_LFM",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x36C*/ { "SMSG_LFG_UPDATE",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x36D*/ { "SMSG_LFG_UPDATE_LFM",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x36E*/ { "SMSG_LFG_UPDATE_LFG",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x36F*/ { "SMSG_LFG_UPDATE_QUEUED",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x370*/ { "SMSG_LFG_PENDING_INVITE",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x371*/ { "SMSG_LFG_PENDING_MATCH",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x372*/ { "SMSG_LFG_PENDING_MATCH_DONE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x373*/ { "SMSG_TITLE_EARNED",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x374*/ { "CMSG_SET_TITLE",                               STATUS_LOGGEDIN, &WorldSession::HandleChooseTitleOpcode         }, +    /*0x375*/ { "CMSG_CANCEL_MOUNT_AURA",                       STATUS_LOGGEDIN, &WorldSession::HandleDismountOpcode            }, +    /*0x376*/ { "SMSG_ARENA_ERROR",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x377*/ { "MSG_INSPECT_ARENA_TEAMS",                      STATUS_LOGGEDIN, &WorldSession::HandleInspectArenaStatsOpcode   }, +    /*0x378*/ { "SMSG_DEATH_RELEASE_LOC",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x379*/ { "CMSG_CANCEL_TEMP_ENCHANTMENT",                 STATUS_LOGGEDIN, &WorldSession::HandleCancelTempItemEnchantmentOpcode}, +    /*0x37A*/ { "SMSG_FORCED_DEATH_UPDATE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x37B*/ { "CMSG_CHEAT_SET_HONOR_CURRENCY",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x37C*/ { "CMSG_CHEAT_SET_ARENA_CURRENCY",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x37D*/ { "MSG_MOVE_SET_FLIGHT_SPEED_CHEAT",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x37E*/ { "MSG_MOVE_SET_FLIGHT_SPEED",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x37F*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED_CHEAT",         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x380*/ { "MSG_MOVE_SET_FLIGHT_BACK_SPEED",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x381*/ { "SMSG_FORCE_FLIGHT_SPEED_CHANGE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x382*/ { "CMSG_FORCE_FLIGHT_SPEED_CHANGE_ACK",           STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x383*/ { "SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x384*/ { "CMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE_ACK",      STATUS_LOGGEDIN, &WorldSession::HandleForceSpeedChangeAck       }, +    /*0x385*/ { "SMSG_SPLINE_SET_FLIGHT_SPEED",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x386*/ { "SMSG_SPLINE_SET_FLIGHT_BACK_SPEED",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x387*/ { "CMSG_MAELSTROM_INVALIDATE_CACHE",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x388*/ { "SMSG_FLIGHT_SPLINE_SYNC",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x389*/ { "CMSG_SET_TAXI_BENCHMARK_MODE",                 STATUS_AUTHED,   &WorldSession::HandleSetTaxiBenchmarkOpcode    }, +    /*0x38A*/ { "SMSG_JOINED_BATTLEGROUND_QUEUE",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x38B*/ { "SMSG_REALM_SPLIT",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x38C*/ { "CMSG_REALM_SPLIT",                             STATUS_AUTHED,   &WorldSession::HandleRealmStateRequestOpcode   }, +    /*0x38D*/ { "CMSG_MOVE_CHNG_TRANSPORT",                     STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x38E*/ { "MSG_PARTY_ASSIGNMENT",                         STATUS_LOGGEDIN, &WorldSession::HandleGroupPromoteOpcode        }, +    /*0x38F*/ { "SMSG_OFFER_PETITION_ERROR",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x390*/ { "SMSG_TIME_SYNC_REQ",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x391*/ { "CMSG_TIME_SYNC_RESP",                          STATUS_LOGGEDIN, &WorldSession::HandleTimeSyncResp              }, +    /*0x392*/ { "CMSG_SEND_LOCAL_EVENT",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x393*/ { "CMSG_SEND_GENERAL_TRIGGER",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x394*/ { "CMSG_SEND_COMBAT_TRIGGER",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x395*/ { "CMSG_MAELSTROM_GM_SENT_MAIL",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x396*/ { "SMSG_RESET_FAILED_NOTIFY",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x397*/ { "SMSG_REAL_GROUP_UPDATE",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x398*/ { "SMSG_LFG_DISABLED",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x399*/ { "CMSG_ACTIVE_PVP_CHEAT",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x39A*/ { "CMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x39B*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x39C*/ { "SMSG_CHEAT_DUMP_ITEMS_DEBUG_ONLY_RESPONSE_WRITE_FILE",STATUS_NEVER,&WorldSession::Handle_ServerSide            }, +    /*0x39D*/ { "SMSG_UPDATE_COMBO_POINTS",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x39E*/ { "SMSG_VOICE_SESSION_ROSTER_UPDATE",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x39F*/ { "SMSG_VOICE_SESSION_LEAVE",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A0*/ { "SMSG_VOICE_SESSION_ADJUST_PRIORITY",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A1*/ { "CMSG_VOICE_SET_TALKER_MUTED_REQUEST",          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3A2*/ { "SMSG_VOICE_SET_TALKER_MUTED",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A3*/ { "SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A4*/ { "SMSG_SET_EXTRA_AURA_INFO_OBSOLETE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A5*/ { "SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE",STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A6*/ { "SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE",          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3A7*/ { "MSG_MOVE_START_DESCEND",                       STATUS_LOGGEDIN, &WorldSession::HandleMovementOpcodes           }, +    /*0x3A8*/ { "CMSG_IGNORE_REQUIREMENTS_CHEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3A9*/ { "SMSG_IGNORE_REQUIREMENTS_CHEAT",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3AA*/ { "SMSG_SPELL_CHANCE_PROC_LOG",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3AB*/ { "CMSG_MOVE_SET_RUN_SPEED",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3AC*/ { "SMSG_DISMOUNT",                                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3AD*/ { "MSG_MOVE_UPDATE_CAN_FLY",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3AE*/ { "MSG_RAID_READY_CHECK_CONFIRM",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3AF*/ { "CMSG_VOICE_SESSION_ENABLE",                    STATUS_AUTHED,   &WorldSession::HandleVoiceSettingsOpcode       }, +    /*0x3B0*/ { "SMSG_VOICE_SESSION_ENABLE",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3B1*/ { "SMSG_VOICE_PARENTAL_CONTROLS",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3B2*/ { "CMSG_GM_WHISPER",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3B3*/ { "SMSG_GM_MESSAGECHAT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3B4*/ { "MSG_GM_GEARRATING",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3B5*/ { "CMSG_COMMENTATOR_ENABLE",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3B6*/ { "SMSG_COMMENTATOR_STATE_CHANGED",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3B7*/ { "CMSG_COMMENTATOR_GET_MAP_INFO",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3B8*/ { "SMSG_COMMENTATOR_MAP_INFO",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3B9*/ { "CMSG_COMMENTATOR_GET_PLAYER_INFO",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3BA*/ { "SMSG_COMMENTATOR_GET_PLAYER_INFO",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3BB*/ { "SMSG_COMMENTATOR_PLAYER_INFO",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3BC*/ { "CMSG_COMMENTATOR_ENTER_INSTANCE",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3BD*/ { "CMSG_COMMENTATOR_EXIT_INSTANCE",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3BE*/ { "CMSG_COMMENTATOR_INSTANCE_COMMAND",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3BF*/ { "SMSG_CLEAR_TARGET",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3C0*/ { "CMSG_BOT_DETECTED",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3C1*/ { "SMSG_CROSSED_INEBRIATION_THRESHOLD",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3C2*/ { "CMSG_CHEAT_PLAYER_LOGIN",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3C3*/ { "CMSG_CHEAT_PLAYER_LOOKUP",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3C4*/ { "SMSG_CHEAT_PLAYER_LOOKUP",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3C5*/ { "SMSG_KICK_REASON",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3C6*/ { "MSG_RAID_READY_CHECK_FINISHED",                STATUS_LOGGEDIN, &WorldSession::HandleRaidReadyCheckFinishOpcode}, +    /*0x3C7*/ { "CMSG_COMPLAIN",                                STATUS_LOGGEDIN, &WorldSession::HandleReportSpamOpcode          }, +    /*0x3C8*/ { "SMSG_COMPLAIN_RESULT",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3C9*/ { "SMSG_FEATURE_SYSTEM_STATUS",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3CA*/ { "CMSG_GM_SHOW_COMPLAINTS",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3CB*/ { "CMSG_GM_UNSQUELCH",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3CC*/ { "CMSG_CHANNEL_SILENCE_VOICE",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3CD*/ { "CMSG_CHANNEL_SILENCE_ALL",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3CE*/ { "CMSG_CHANNEL_UNSILENCE_VOICE",                 STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3CF*/ { "CMSG_CHANNEL_UNSILENCE_ALL",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3D0*/ { "CMSG_TARGET_CAST",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3D1*/ { "CMSG_TARGET_SCRIPT_CAST",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3D2*/ { "CMSG_CHANNEL_DISPLAY_LIST",                    STATUS_LOGGEDIN, &WorldSession::HandleChannelRosterQuery        }, +    /*0x3D3*/ { "CMSG_SET_ACTIVE_VOICE_CHANNEL",                STATUS_AUTHED,   &WorldSession::HandleChannelVoiceChatQuery     }, +    /*0x3D4*/ { "CMSG_GET_CHANNEL_MEMBER_COUNT",                STATUS_LOGGEDIN, &WorldSession::HandleChannelInfoQuery          }, +    /*0x3D5*/ { "SMSG_CHANNEL_MEMBER_COUNT",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3D6*/ { "CMSG_CHANNEL_VOICE_ON",                        STATUS_LOGGEDIN, &WorldSession::HandleChannelEnableVoiceOpcode  }, +    /*0x3D7*/ { "CMSG_CHANNEL_VOICE_OFF",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3D8*/ { "CMSG_DEBUG_LIST_TARGETS",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3D9*/ { "SMSG_DEBUG_LIST_TARGETS",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3DA*/ { "SMSG_AVAILABLE_VOICE_CHANNEL",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3DB*/ { "CMSG_ADD_VOICE_IGNORE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3DC*/ { "CMSG_DEL_VOICE_IGNORE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3DD*/ { "CMSG_PARTY_SILENCE",                           STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3DE*/ { "CMSG_PARTY_UNSILENCE",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3DF*/ { "MSG_NOTIFY_PARTY_SQUELCH",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3E0*/ { "SMSG_COMSAT_RECONNECT_TRY",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3E1*/ { "SMSG_COMSAT_DISCONNECT",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3E2*/ { "SMSG_COMSAT_CONNECT_FAIL",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3E3*/ { "SMSG_VOICE_CHAT_STATUS",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3E4*/ { "CMSG_REPORT_PVP_AFK",                          STATUS_LOGGEDIN, &WorldSession::HandleBattleGroundReportAFK     }, +    /*0x3E5*/ { "CMSG_REPORT_PVP_AFK_RESULT",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3E6*/ { "CMSG_GUILD_BANKER_ACTIVATE",                   STATUS_LOGGEDIN, &WorldSession::HandleGuildBankQuery            }, +    /*0x3E7*/ { "CMSG_GUILD_BANK_QUERY_TAB",                    STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabColon         }, +    /*0x3E8*/ { "SMSG_GUILD_BANK_LIST",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3E9*/ { "CMSG_GUILD_BANK_SWAP_ITEMS",                   STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDepositItem      }, +    /*0x3EA*/ { "CMSG_GUILD_BANK_BUY_TAB",                      STATUS_LOGGEDIN, &WorldSession::HandleGuildBankBuyTab           }, +    /*0x3EB*/ { "CMSG_GUILD_BANK_UPDATE_TAB",                   STATUS_LOGGEDIN, &WorldSession::HandleGuildBankModifyTab        }, +    /*0x3EC*/ { "CMSG_GUILD_BANK_DEPOSIT_MONEY",                STATUS_LOGGEDIN, &WorldSession::HandleGuildBankDeposit          }, +    /*0x3ED*/ { "CMSG_GUILD_BANK_WITHDRAW_MONEY",               STATUS_LOGGEDIN, &WorldSession::HandleGuildBankWithdraw         }, +    /*0x3EE*/ { "MSG_GUILD_BANK_LOG_QUERY",                     STATUS_LOGGEDIN, &WorldSession::HandleGuildBankLog              }, +    /*0x3EF*/ { "CMSG_SET_CHANNEL_WATCH",                       STATUS_LOGGEDIN, &WorldSession::HandleChannelJoinNotify         }, +    /*0x3F0*/ { "SMSG_USERLIST_ADD",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3F1*/ { "SMSG_USERLIST_REMOVE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3F2*/ { "SMSG_USERLIST_UPDATE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3F3*/ { "CMSG_CLEAR_CHANNEL_WATCH",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3F4*/ { "SMSG_INSPECT_TALENT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3F5*/ { "SMSG_GOGOGO_OBSOLETE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3F6*/ { "SMSG_ECHO_PARTY_SQUELCH",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3F7*/ { "CMSG_SET_TITLE_SUFFIX",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3F8*/ { "CMSG_SPELLCLICK",                              STATUS_LOGGEDIN, &WorldSession::HandleSpellClick                }, +    /*0x3F9*/ { "SMSG_LOOT_LIST",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3FA*/ { "CMSG_GM_CHARACTER_RESTORE",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3FB*/ { "CMSG_GM_CHARACTER_SAVE",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x3FC*/ { "SMSG_VOICESESSION_FULL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x3FD*/ { "MSG_GUILD_PERMISSIONS",                        STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetRights        }, +    /*0x3FE*/ { "MSG_GUILD_BANK_MONEY_WITHDRAWN",               STATUS_LOGGEDIN, &WorldSession::HandleGuildBankGetMoneyAmount   }, +    /*0x3FF*/ { "MSG_GUILD_EVENT_LOG_QUERY",                    STATUS_LOGGEDIN, &WorldSession::HandleGuildEventLogOpcode       }, +    /*0x400*/ { "CMSG_MAELSTROM_RENAME_GUILD",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x401*/ { "CMSG_GET_MIRRORIMAGE_DATA",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x402*/ { "SMSG_MIRRORIMAGE_DATA",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x403*/ { "SMSG_FORCE_DISPLAY_UPDATE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x404*/ { "SMSG_SPELL_CHANCE_RESIST_PUSHBACK",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x405*/ { "CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x406*/ { "SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x407*/ { "CMSG_KEEP_ALIVE",                              STATUS_NEVER,    &WorldSession::Handle_EarlyProccess            }, +    /*0x408*/ { "SMSG_RAID_READY_CHECK_ERROR",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x409*/ { "CMSG_OPT_OUT_OF_LOOT",                         STATUS_AUTHED,   &WorldSession::HandleGroupPassOnLootOpcode     }, +    /*0x40A*/ { "MSG_QUERY_GUILD_BANK_TEXT",                    STATUS_LOGGEDIN, &WorldSession::HandleGuildBankTabText          }, +    /*0x40B*/ { "CMSG_SET_GUILD_BANK_TEXT",                     STATUS_LOGGEDIN, &WorldSession::HandleGuildBankSetTabText       }, +    /*0x40C*/ { "CMSG_SET_GRANTABLE_LEVELS",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x40D*/ { "CMSG_GRANT_LEVEL",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x40E*/ { "CMSG_REFER_A_FRIEND",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x40F*/ { "MSG_GM_CHANGE_ARENA_RATING",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x410*/ { "CMSG_DECLINE_CHANNEL_INVITE",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x411*/ { "CMSG_GROUPACTION_THROTTLED",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x412*/ { "SMSG_OVERRIDE_LIGHT",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x413*/ { "SMSG_TOTEM_CREATED",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x414*/ { "CMSG_TOTEM_DESTROYED",                         STATUS_LOGGEDIN, &WorldSession::HandleTotemDestroy              }, +    /*0x415*/ { "CMSG_EXPIRE_RAID_INSTANCE",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x416*/ { "CMSG_NO_SPELL_VARIANCE",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x417*/ { "CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY",        STATUS_LOGGEDIN, &WorldSession::HandleQuestgiverStatusQueryMultipleOpcode}, +    /*0x418*/ { "SMSG_QUESTGIVER_STATUS_MULTIPLE",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x419*/ { "CMSG_SET_PLAYER_DECLINED_NAMES",               STATUS_AUTHED,   &WorldSession::HandleDeclinedPlayerNameOpcode  }, +    /*0x41A*/ { "SMSG_SET_PLAYER_DECLINED_NAMES_RESULT",        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x41B*/ { "CMSG_QUERY_SERVER_BUCK_DATA",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x41C*/ { "CMSG_CLEAR_SERVER_BUCK_DATA",                  STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x41D*/ { "SMSG_SERVER_BUCK_DATA",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x41E*/ { "SMSG_SEND_UNLEARN_SPELLS",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x41F*/ { "SMSG_PROPOSE_LEVEL_GRANT",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x420*/ { "CMSG_ACCEPT_LEVEL_GRANT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x421*/ { "SMSG_REFER_A_FRIEND_FAILURE",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x422*/ { "SMSG_SPLINE_MOVE_SET_FLYING",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x423*/ { "SMSG_SPLINE_MOVE_UNSET_FLYING",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x424*/ { "SMSG_SUMMON_CANCEL",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x425*/ { "CMSG_CHANGE_PERSONAL_ARENA_RATING",            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x426*/ { "CMSG_ALTER_APPEARANCE",                        STATUS_LOGGEDIN, &WorldSession::HandleAlterAppearance           }, +    /*0x427*/ { "SMSG_ENABLE_BARBER_SHOP",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x428*/ { "SMSG_BARBER_SHOP_RESULT",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x429*/ { "CMSG_CALENDAR_GET_CALENDAR",                   STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetCalendar       }, +    /*0x42A*/ { "CMSG_CALENDAR_GET_EVENT",                      STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetEvent          }, +    /*0x42B*/ { "CMSG_CALENDAR_GUILD_FILTER",                   STATUS_LOGGEDIN, &WorldSession::HandleCalendarGuildFilter       }, +    /*0x42C*/ { "CMSG_CALENDAR_ARENA_TEAM",                     STATUS_LOGGEDIN, &WorldSession::HandleCalendarArenaTeam         }, +    /*0x42D*/ { "CMSG_CALENDAR_ADD_EVENT",                      STATUS_LOGGEDIN, &WorldSession::HandleCalendarAddEvent          }, +    /*0x42E*/ { "CMSG_CALENDAR_UPDATE_EVENT",                   STATUS_LOGGEDIN, &WorldSession::HandleCalendarUpdateEvent       }, +    /*0x42F*/ { "CMSG_CALENDAR_REMOVE_EVENT",                   STATUS_LOGGEDIN, &WorldSession::HandleCalendarRemoveEvent       }, +    /*0x430*/ { "CMSG_CALENDAR_COPY_EVENT",                     STATUS_LOGGEDIN, &WorldSession::HandleCalendarCopyEvent         }, +    /*0x431*/ { "CMSG_CALENDAR_EVENT_INVITE",                   STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventInvite       }, +    /*0x432*/ { "CMSG_CALENDAR_EVENT_RSVP",                     STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRsvp         }, +    /*0x433*/ { "CMSG_CALENDAR_EVENT_REMOVE_INVITE",            STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventRemoveInvite }, +    /*0x434*/ { "CMSG_CALENDAR_EVENT_STATUS",                   STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventStatus       }, +    /*0x435*/ { "CMSG_CALENDAR_EVENT_MODERATOR_STATUS",         STATUS_LOGGEDIN, &WorldSession::HandleCalendarEventModeratorStatus}, +    /*0x436*/ { "SMSG_CALENDAR_SEND_CALENDAR",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x437*/ { "SMSG_CALENDAR_SEND_EVENT",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x438*/ { "SMSG_CALENDAR_FILTER_GUILD",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x439*/ { "SMSG_CALENDAR_ARENA_TEAM",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x43A*/ { "SMSG_CALENDAR_EVENT_INVITE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x43B*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x43C*/ { "SMSG_CALENDAR_EVENT_STATUS",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x43D*/ { "SMSG_CALENDAR_COMMAND_RESULT",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x43E*/ { "SMSG_CALENDAR_RAID_LOCKOUT_ADDED",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x43F*/ { "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED",           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x440*/ { "SMSG_CALENDAR_EVENT_INVITE_ALERT",             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x441*/ { "SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT",     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x442*/ { "SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT",      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x443*/ { "SMSG_CALENDAR_EVENT_REMOVED_ALERT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x444*/ { "SMSG_CALENDAR_EVENT_UPDATED_ALERT",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x445*/ { "SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT",   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x446*/ { "CMSG_CALENDAR_COMPLAIN",                       STATUS_LOGGEDIN, &WorldSession::HandleCalendarComplain          }, +    /*0x447*/ { "CMSG_CALENDAR_GET_NUM_PENDING",                STATUS_LOGGEDIN, &WorldSession::HandleCalendarGetNumPending     }, +    /*0x448*/ { "SMSG_CALENDAR_SEND_NUM_PENDING",               STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x449*/ { "CMSG_SAVE_DANCE",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x44A*/ { "SMSG_NOTIFY_DANCE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x44B*/ { "CMSG_PLAY_DANCE",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x44C*/ { "SMSG_PLAY_DANCE",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x44D*/ { "CMSG_LOAD_DANCES",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x44E*/ { "CMSG_STOP_DANCE",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x44F*/ { "SMSG_STOP_DANCE",                              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x450*/ { "CMSG_SYNC_DANCE",                              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x451*/ { "CMSG_DANCE_QUERY",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x452*/ { "SMSG_DANCE_QUERY_RESPONSE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x453*/ { "SMSG_INVALIDATE_DANCE",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x454*/ { "CMSG_DELETE_DANCE",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x455*/ { "SMSG_LEARNED_DANCE_MOVES",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x456*/ { "CMSG_LEARN_DANCE_MOVE",                        STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x457*/ { "CMSG_UNLEARN_DANCE_MOVE",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x458*/ { "CMSG_SET_RUNE_COUNT",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x459*/ { "CMSG_SET_RUNE_COOLDOWN",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x45A*/ { "MSG_MOVE_SET_PITCH_RATE_CHEAT",                STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x45B*/ { "MSG_MOVE_SET_PITCH_RATE",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x45C*/ { "SMSG_FORCE_PITCH_RATE_CHANGE",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT",                   STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x464*/ { "SMSG_TRIGGER_MOVIE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x465*/ { "CMSG_COMPLETE_MOVIE",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x466*/ { "CMSG_SET_GLYPH_SLOT",                          STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x467*/ { "CMSG_SET_GLYPH",                               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x468*/ { "SMSG_ACHIEVEMENT_EARNED",                      STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x469*/ { "SMSG_DYNAMIC_DROP_ROLL_RESULT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x46A*/ { "SMSG_CRITERIA_UPDATE",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x46B*/ { "CMSG_QUERY_INSPECT_ACHIEVEMENTS",              STATUS_LOGGEDIN, &WorldSession::HandleInspectAchievements       }, +    /*0x46C*/ { "SMSG_RESPOND_INSPECT_ACHIEVEMENTS",            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x46D*/ { "CMSG_DISMISS_CONTROLLED_VEHICLE",              STATUS_LOGGEDIN, &WorldSession::HandleDismissControlledVehicle  }, +    /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT",              STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x471*/ { "SMSG_GROUP_SWAP_FAILED",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT",                      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x473*/ { "CMSG_CHAR_CUSTOMIZE",                          STATUS_AUTHED,   &WorldSession::HandleCharCustomize             }, +    /*0x474*/ { "SMSG_CHAR_CUSTOMIZE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x475*/ { "SMSG_PET_RENAMEABLE",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x476*/ { "CMSG_REQUEST_VEHICLE_EXIT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x477*/ { "CMSG_REQUEST_VEHICLE_PREV_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x478*/ { "CMSG_REQUEST_VEHICLE_NEXT_SEAT",               STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x479*/ { "CMSG_REQUEST_VEHICLE_SWITCH_SEAT",             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x47A*/ { "CMSG_PET_LEARN_TALENT",                        STATUS_LOGGEDIN, &WorldSession::HandlePetLearnTalent            }, +    /*0x47B*/ { "CMSG_PET_UNLEARN_TALENTS",                     STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x47C*/ { "SMSG_SET_PHASE_SHIFT",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x47D*/ { "SMSG_ALL_ACHIEVEMENT_DATA",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x47E*/ { "CMSG_FORCE_SAY_CHEAT",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x47F*/ { "SMSG_HEALTH_UPDATE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x480*/ { "SMSG_POWER_UPDATE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x481*/ { "CMSG_GAMEOBJ_REPORT_USE",                      STATUS_LOGGEDIN, &WorldSession::HandleGameobjectReportUse       }, +    /*0x482*/ { "SMSG_HIGHEST_THREAT_UPDATE",                   STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x483*/ { "SMSG_THREAT_UPDATE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x484*/ { "SMSG_THREAT_REMOVE",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x485*/ { "SMSG_THREAT_CLEAR",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x486*/ { "SMSG_CONVERT_RUNE",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x487*/ { "SMSG_RESYNC_RUNES",                            STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x488*/ { "SMSG_ADD_RUNE_POWER",                          STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x489*/ { "CMSG_START_QUEST",                             STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x48A*/ { "CMSG_REMOVE_GLYPH",                            STATUS_LOGGEDIN, &WorldSession::HandleRemoveGlyph               }, +    /*0x48B*/ { "CMSG_DUMP_OBJECTS",                            STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x48C*/ { "SMSG_DUMP_OBJECTS_DATA",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x48D*/ { "CMSG_DISMISS_CRITTER",                         STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x48E*/ { "SMSG_NOTIFY_DEST_LOC_SPELL_CAST",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x48F*/ { "CMSG_AUCTION_LIST_PENDING_SALES",              STATUS_LOGGEDIN, &WorldSession::HandleAuctionListPendingSales   }, +    /*0x490*/ { "SMSG_AUCTION_LIST_PENDING_SALES",              STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x491*/ { "SMSG_MODIFY_COOLDOWN",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x492*/ { "SMSG_PET_UPDATE_COMBO_POINTS",                 STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x493*/ { "CMSG_ENABLETAXI",                              STATUS_LOGGEDIN, &WorldSession::HandleTaxiQueryAvailableNodes   }, +    /*0x494*/ { "SMSG_PRE_RESURRECT",                           STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x495*/ { "SMSG_AURA_UPDATE_ALL",                         STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x496*/ { "SMSG_AURA_UPDATE",                             STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x497*/ { "CMSG_FLOOD_GRACE_CHEAT",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x498*/ { "SMSG_SERVER_FIRST_ACHIEVEMENT",                STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x499*/ { "SMSG_PET_LEARNED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x49A*/ { "SMSG_PET_REMOVED_SPELL",                       STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x49B*/ { "CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE",      STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x49C*/ { "CMSG_HEARTH_AND_RESURRECT",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x49D*/ { "SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA",    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x49E*/ { "SMSG_CRITERIA_DELETED",                        STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x49F*/ { "SMSG_ACHIEVEMENT_DELETED",                     STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x4A0*/ { "CMSG_SERVER_INFO_QUERY",                       STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x4A1*/ { "SMSG_SERVER_INFO_RESPONSE",                    STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x4A2*/ { "CMSG_CHECK_LOGIN_CRITERIA",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x4A3*/ { "SMSG_SERVER_BUCK_DATA_START",                  STATUS_NEVER,    &WorldSession::Handle_ServerSide               }, +    /*0x4A4*/ { "CMSG_QUERY_VEHICLE_STATUS",                    STATUS_NEVER,    &WorldSession::Handle_NULL                     }, +    /*0x4A5*/ { "SMSG_PET_GUIDS",                               STATUS_NEVER,    &WorldSession::Handle_ServerSide               },  }; diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index 202166a57a0..7bc3a7c0640 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -49,8 +49,8 @@ enum Opcodes      CMSG_ZONE_MAP                                   = 0x00A,      SMSG_ZONE_MAP                                   = 0x00B,      CMSG_DEBUG_CHANGECELLZONE                       = 0x00C, -    CMSG_EMBLAZON_TABARD_OBSOLETE                   = 0x00D, -    CMSG_UNEMBLAZON_TABARD_OBSOLETE                 = 0x00E, +    CMSG_MOVE_CHARACTER_CHEAT                       = 0x00D, +    SMSG_MOVE_CHARACTER_CHEAT                       = 0x00E,      CMSG_RECHARGE                                   = 0x00F,      CMSG_LEARN_SPELL                                = 0x010,      CMSG_CREATEMONSTER                              = 0x011, @@ -66,7 +66,7 @@ enum Opcodes      SMSG_FORCEACTIONSHOW                            = 0x01B,      CMSG_PETGODMODE                                 = 0x01C,      SMSG_PETGODMODE                                 = 0x01D, -    SMSG_DEBUGINFOSPELLMISS_OBSOLETE                = 0x01E, +    SMSG_REFER_A_FRIEND_EXPIRED                     = 0x01E,      CMSG_WEATHER_SPEED_CHEAT                        = 0x01F,      CMSG_UNDRESSPLAYER                              = 0x020,      CMSG_BEASTMASTER                                = 0x021, @@ -86,7 +86,7 @@ enum Opcodes      SMSG_DEBUG_AISTATE                              = 0x02F,      CMSG_DISABLE_PVP_CHEAT                          = 0x030,      CMSG_ADVANCE_SPAWN_TIME                         = 0x031, -    CMSG_PVP_PORT_OBSOLETE                          = 0x032, +    SMSG_DESTRUCTIBLE_BUILDING_DAMAGE               = 0x032,      CMSG_AUTH_SRP6_BEGIN                            = 0x033,      CMSG_AUTH_SRP6_PROOF                            = 0x034,      CMSG_AUTH_SRP6_RECODE                           = 0x035, @@ -214,7 +214,7 @@ enum Opcodes      SMSG_READ_ITEM_FAILED                           = 0x0AF,      SMSG_ITEM_COOLDOWN                              = 0x0B0,      CMSG_GAMEOBJ_USE                                = 0x0B1, -    CMSG_GAMEOBJ_CHAIR_USE_OBSOLETE                 = 0x0B2, +    CMSG_DESTROY_ITEMS                              = 0x0B2,      SMSG_GAMEOBJECT_CUSTOM_ANIM                     = 0x0B3,      CMSG_AREATRIGGER                                = 0x0B4,      MSG_MOVE_START_FORWARD                          = 0x0B5, @@ -347,7 +347,7 @@ enum Opcodes      SMSG_SPELL_COOLDOWN                             = 0x134,      SMSG_COOLDOWN_EVENT                             = 0x135,      CMSG_CANCEL_AURA                                = 0x136, -    SMSG_UPDATE_AURA_DURATION                       = 0x137, +    SMSG_UPDATE_AURA_DURATION_OBSOLETE              = 0x137,      SMSG_PET_CAST_FAILED                            = 0x138,      MSG_CHANNEL_START                               = 0x139,      MSG_CHANNEL_UPDATE                              = 0x13A, @@ -371,10 +371,10 @@ enum Opcodes      SMSG_DAMAGE_DONE_OBSOLETE                       = 0x14C,      SMSG_DAMAGE_TAKEN_OBSOLETE                      = 0x14D,      SMSG_CANCEL_COMBAT                              = 0x14E, -    SMSG_PLAYER_COMBAT_XP_GAIN_OBSOLETE             = 0x14F, +    SMSG_SPELLBREAKLOG                              = 0x14F,      SMSG_SPELLHEALLOG                               = 0x150,      SMSG_SPELLENERGIZELOG                           = 0x151, -    CMSG_SHEATHE_OBSOLETE                           = 0x152, +    SMSG_BREAK_TARGET                               = 0x152,      CMSG_SAVE_PLAYER                                = 0x153,      CMSG_SETDEATHBINDPOINT                          = 0x154,      SMSG_BINDPOINTUPDATE                            = 0x155, @@ -578,7 +578,7 @@ enum Opcodes      SMSG_GMTICKET_SYSTEMSTATUS                      = 0x21B,      CMSG_SPIRIT_HEALER_ACTIVATE                     = 0x21C,      CMSG_SET_STAT_CHEAT                             = 0x21D, -    SMSG_SET_REST_START                             = 0x21E, +    SMSG_SET_REST_START_OBSOLETE                    = 0x21E,      CMSG_SKILL_BUY_STEP                             = 0x21F,      CMSG_SKILL_BUY_RANK                             = 0x220,      CMSG_XP_CHEAT                                   = 0x221, @@ -733,8 +733,8 @@ enum Opcodes      SMSG_SCRIPT_MESSAGE                             = 0x2B6,      SMSG_DUEL_COUNTDOWN                             = 0x2B7,      SMSG_AREA_TRIGGER_MESSAGE                       = 0x2B8, -    CMSG_TOGGLE_HELM                                = 0x2B9, -    CMSG_TOGGLE_CLOAK                               = 0x2BA, +    CMSG_SHOWING_HELM                               = 0x2B9, +    CMSG_SHOWING_CLOAK                              = 0x2BA,      SMSG_MEETINGSTONE_JOINFAILED                    = 0x2BB,      SMSG_PLAYER_SKINNED                             = 0x2BC,      SMSG_DURABILITY_DAMAGE_DEATH                    = 0x2BD, @@ -967,10 +967,10 @@ enum Opcodes      SMSG_VOICE_SESSION_ADJUST_PRIORITY              = 0x3A0,      CMSG_VOICE_SET_TALKER_MUTED_REQUEST             = 0x3A1,      SMSG_VOICE_SET_TALKER_MUTED                     = 0x3A2, -    SMSG_INIT_EXTRA_AURA_INFO                       = 0x3A3, -    SMSG_SET_EXTRA_AURA_INFO                        = 0x3A4, -    SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE            = 0x3A5, -    SMSG_CLEAR_EXTRA_AURA_INFO                      = 0x3A6, +    SMSG_INIT_EXTRA_AURA_INFO_OBSOLETE              = 0x3A3, +    SMSG_SET_EXTRA_AURA_INFO_OBSOLETE               = 0x3A4, +    SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE_OBSOLETE   = 0x3A5, +    SMSG_CLEAR_EXTRA_AURA_INFO_OBSOLETE             = 0x3A6,      MSG_MOVE_START_DESCEND                          = 0x3A7,      CMSG_IGNORE_REQUIREMENTS_CHEAT                  = 0x3A8,      SMSG_IGNORE_REQUIREMENTS_CHEAT                  = 0x3A9, @@ -980,127 +980,255 @@ enum Opcodes      MSG_MOVE_UPDATE_CAN_FLY                         = 0x3AD,      MSG_RAID_READY_CHECK_CONFIRM                    = 0x3AE,      CMSG_VOICE_SESSION_ENABLE                       = 0x3AF, -    SMSG_VOICE_PARENTAL_CONTROLS                    = 0x3B0, -    CMSG_GM_WHISPER                                 = 0x3B1, -    SMSG_GM_MESSAGECHAT                             = 0x3B2, -    MSG_GM_GEARRATING                               = 0x3B3, -    CMSG_COMMENTATOR_ENABLE                         = 0x3B4, -    SMSG_COMMENTATOR_STATE_CHANGED                  = 0x3B5, -    CMSG_COMMENTATOR_GET_MAP_INFO                   = 0x3B6, -    SMSG_COMMENTATOR_MAP_INFO                       = 0x3B7, -    CMSG_COMMENTATOR_GET_PLAYER_INFO                = 0x3B8, -    SMSG_COMMENTATOR_GET_PLAYER_INFO                = 0x3B9, -    SMSG_COMMENTATOR_PLAYER_INFO                    = 0x3BA, -    CMSG_COMMENTATOR_ENTER_INSTANCE                 = 0x3BB, -    CMSG_COMMENTATOR_EXIT_INSTANCE                  = 0x3BC, -    CMSG_COMMENTATOR_INSTANCE_COMMAND               = 0x3BD, -    SMSG_CLEAR_TARGET                               = 0x3BE, -    CMSG_BOT_DETECTED                               = 0x3BF, -    SMSG_CROSSED_INEBRIATION_THRESHOLD              = 0x3C0, -    CMSG_CHEAT_PLAYER_LOGIN                         = 0x3C1, -    CMSG_CHEAT_PLAYER_LOOKUP                        = 0x3C2, -    SMSG_CHEAT_PLAYER_LOOKUP                        = 0x3C3, -    SMSG_KICK_REASON                                = 0x3C4, -    MSG_RAID_READY_CHECK_FINISHED                   = 0x3C5, -    CMSG_COMPLAIN                                   = 0x3C6, -    SMSG_COMPLAIN_RESULT                            = 0x3C7, -    SMSG_FEATURE_SYSTEM_STATUS                      = 0x3C8, -    CMSG_GM_SHOW_COMPLAINTS                         = 0x3C9, -    CMSG_GM_UNSQUELCH                               = 0x3CA, -    CMSG_CHANNEL_SILENCE_VOICE                      = 0x3CB, -    CMSG_CHANNEL_SILENCE_ALL                        = 0x3CC, -    CMSG_CHANNEL_UNSILENCE_VOICE                    = 0x3CD, -    CMSG_CHANNEL_UNSILENCE_ALL                      = 0x3CE, -    CMSG_TARGET_CAST                                = 0x3CF, -    CMSG_TARGET_SCRIPT_CAST                         = 0x3D0, -    CMSG_CHANNEL_DISPLAY_LIST                       = 0x3D1, -    CMSG_SET_ACTIVE_VOICE_CHANNEL                   = 0x3D2, -    CMSG_GET_CHANNEL_MEMBER_COUNT                   = 0x3D3, -    SMSG_CHANNEL_MEMBER_COUNT                       = 0x3D4, -    CMSG_CHANNEL_VOICE_ON                           = 0x3D5, -    CMSG_CHANNEL_VOICE_OFF                          = 0x3D6, -    CMSG_DEBUG_LIST_TARGETS                         = 0x3D7, -    SMSG_DEBUG_LIST_TARGETS                         = 0x3D8, -    SMSG_AVAILABLE_VOICE_CHANNEL                    = 0x3D9, -    CMSG_ADD_VOICE_IGNORE                           = 0x3DA, -    CMSG_DEL_VOICE_IGNORE                           = 0x3DB, -    CMSG_PARTY_SILENCE                              = 0x3DC, -    CMSG_PARTY_UNSILENCE                            = 0x3DD, -    MSG_NOTIFY_PARTY_SQUELCH                        = 0x3DE, -    SMSG_COMSAT_RECONNECT_TRY                       = 0x3DF, -    SMSG_COMSAT_DISCONNECT                          = 0x3E0, -    SMSG_COMSAT_CONNECT_FAIL                        = 0x3E1, -    SMSG_VOICE_CHAT_STATUS                          = 0x3E2, -    CMSG_REPORT_PVP_AFK                             = 0x3E3, -    CMSG_REPORT_PVP_AFK_RESULT                      = 0x3E4, -    CMSG_GUILD_BANKER_ACTIVATE                      = 0x3E5, -    CMSG_GUILD_BANK_QUERY_TAB                       = 0x3E6, -    SMSG_GUILD_BANK_LIST                            = 0x3E7, -    CMSG_GUILD_BANK_SWAP_ITEMS                      = 0x3E8, -    CMSG_GUILD_BANK_BUY_TAB                         = 0x3E9, -    CMSG_GUILD_BANK_UPDATE_TAB                      = 0x3EA, -    CMSG_GUILD_BANK_DEPOSIT_MONEY                   = 0x3EB, -    CMSG_GUILD_BANK_WITHDRAW_MONEY                  = 0x3EC, -    MSG_GUILD_BANK_LOG_QUERY                        = 0x3ED, -    CMSG_SET_CHANNEL_WATCH                          = 0x3EE, -    SMSG_USERLIST_ADD                               = 0x3EF, -    SMSG_USERLIST_REMOVE                            = 0x3F0, -    SMSG_USERLIST_UPDATE                            = 0x3F1, -    CMSG_CLEAR_CHANNEL_WATCH                        = 0x3F2, -    SMSG_INSPECT_TALENT                             = 0x3F3, -    SMSG_GOGOGO_OBSOLETE                            = 0x3F4, -    SMSG_ECHO_PARTY_SQUELCH                         = 0x3F5, -    CMSG_SET_TITLE_SUFFIX                           = 0x3F6, -    CMSG_SPELLCLICK                                 = 0x3F7, -    SMSG_LOOT_LIST                                  = 0x3F8, -    CMSG_GM_CHARACTER_RESTORE                       = 0x3F9, -    CMSG_GM_CHARACTER_SAVE                          = 0x3FA, -    SMSG_VOICESESSION_FULL                          = 0x3FB, -    MSG_GUILD_PERMISSIONS                           = 0x3FC, -    MSG_GUILD_BANK_MONEY_WITHDRAWN                  = 0x3FD, -    MSG_GUILD_EVENT_LOG_QUERY                       = 0x3FE, -    CMSG_MAELSTROM_RENAME_GUILD                     = 0x3FF, -    CMSG_GET_MIRRORIMAGE_DATA                       = 0x400, -    SMSG_MIRRORIMAGE_DATA                           = 0x401, -    SMSG_FORCE_DISPLAY_UPDATE                       = 0x402, -    SMSG_SPELL_CHANCE_RESIST_PUSHBACK               = 0x403, -    CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT           = 0x404, -    SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT           = 0x405, -    CMSG_KEEP_ALIVE                                 = 0x406, -    SMSG_RAID_READY_CHECK_ERROR                     = 0x407, -    CMSG_OPT_OUT_OF_LOOT                            = 0x408, -    MSG_QUERY_GUILD_BANK_TEXT                       = 0x409, -    CMSG_SET_GUILD_BANK_TEXT                        = 0x40A, -    CMSG_SET_GRANTABLE_LEVELS                       = 0x40B, -    CMSG_GRANT_LEVEL                                = 0x40C, -    CMSG_REFER_A_FRIEND                             = 0x40D, -    MSG_GM_CHANGE_ARENA_RATING                      = 0x40E, -    CMSG_DECLINE_CHANNEL_INVITE                     = 0x40F, -    CMSG_GROUPACTION_THROTTLED                      = 0x410, -    SMSG_OVERRIDE_LIGHT                             = 0x411, -    SMSG_TOTEM_CREATED                              = 0x412, -    CMSG_TOTEM_DESTROYED                            = 0x413, -    CMSG_EXPIRE_RAID_INSTANCE                       = 0x414, -    CMSG_NO_SPELL_VARIANCE                          = 0x415, -    CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY           = 0x416, -    SMSG_QUESTGIVER_STATUS_MULTIPLE                 = 0x417, -    CMSG_SET_PLAYER_DECLINED_NAMES                  = 0x418, -    SMSG_SET_PLAYER_DECLINED_NAMES_RESULT           = 0x419, -    CMSG_QUERY_SERVER_BUCK_DATA                     = 0x41A, -    CMSG_CLEAR_SERVER_BUCK_DATA                     = 0x41B, -    SMSG_SERVER_BUCK_DATA                           = 0x41C, -    SMSG_SEND_UNLEARN_SPELLS                        = 0x41D, -    SMSG_PROPOSE_LEVEL_GRANT                        = 0x41E, -    CMSG_ACCEPT_LEVEL_GRANT                         = 0x41F, -    SMSG_REFER_A_FRIEND_FAILURE                     = 0x420, -    SMSG_SPLINE_MOVE_SET_FLYING                     = 0x421, -    SMSG_SPLINE_MOVE_UNSET_FLYING                   = 0x422, -    SMSG_SUMMON_CANCEL                              = 0x423 +    SMSG_VOICE_SESSION_ENABLE                       = 0x3B0, +    SMSG_VOICE_PARENTAL_CONTROLS                    = 0x3B1, +    CMSG_GM_WHISPER                                 = 0x3B2, +    SMSG_GM_MESSAGECHAT                             = 0x3B3, +    MSG_GM_GEARRATING                               = 0x3B4, +    CMSG_COMMENTATOR_ENABLE                         = 0x3B5, +    SMSG_COMMENTATOR_STATE_CHANGED                  = 0x3B6, +    CMSG_COMMENTATOR_GET_MAP_INFO                   = 0x3B7, +    SMSG_COMMENTATOR_MAP_INFO                       = 0x3B8, +    CMSG_COMMENTATOR_GET_PLAYER_INFO                = 0x3B9, +    SMSG_COMMENTATOR_GET_PLAYER_INFO                = 0x3BA, +    SMSG_COMMENTATOR_PLAYER_INFO                    = 0x3BB, +    CMSG_COMMENTATOR_ENTER_INSTANCE                 = 0x3BC, +    CMSG_COMMENTATOR_EXIT_INSTANCE                  = 0x3BD, +    CMSG_COMMENTATOR_INSTANCE_COMMAND               = 0x3BE, +    SMSG_CLEAR_TARGET                               = 0x3BF, +    CMSG_BOT_DETECTED                               = 0x3C0, +    SMSG_CROSSED_INEBRIATION_THRESHOLD              = 0x3C1, +    CMSG_CHEAT_PLAYER_LOGIN                         = 0x3C2, +    CMSG_CHEAT_PLAYER_LOOKUP                        = 0x3C3, +    SMSG_CHEAT_PLAYER_LOOKUP                        = 0x3C4, +    SMSG_KICK_REASON                                = 0x3C5, +    MSG_RAID_READY_CHECK_FINISHED                   = 0x3C6, +    CMSG_COMPLAIN                                   = 0x3C7, +    SMSG_COMPLAIN_RESULT                            = 0x3C8, +    SMSG_FEATURE_SYSTEM_STATUS                      = 0x3C9, +    CMSG_GM_SHOW_COMPLAINTS                         = 0x3CA, +    CMSG_GM_UNSQUELCH                               = 0x3CB, +    CMSG_CHANNEL_SILENCE_VOICE                      = 0x3CC, +    CMSG_CHANNEL_SILENCE_ALL                        = 0x3CD, +    CMSG_CHANNEL_UNSILENCE_VOICE                    = 0x3CE, +    CMSG_CHANNEL_UNSILENCE_ALL                      = 0x3CF, +    CMSG_TARGET_CAST                                = 0x3D0, +    CMSG_TARGET_SCRIPT_CAST                         = 0x3D1, +    CMSG_CHANNEL_DISPLAY_LIST                       = 0x3D2, +    CMSG_SET_ACTIVE_VOICE_CHANNEL                   = 0x3D3, +    CMSG_GET_CHANNEL_MEMBER_COUNT                   = 0x3D4, +    SMSG_CHANNEL_MEMBER_COUNT                       = 0x3D5, +    CMSG_CHANNEL_VOICE_ON                           = 0x3D6, +    CMSG_CHANNEL_VOICE_OFF                          = 0x3D7, +    CMSG_DEBUG_LIST_TARGETS                         = 0x3D8, +    SMSG_DEBUG_LIST_TARGETS                         = 0x3D9, +    SMSG_AVAILABLE_VOICE_CHANNEL                    = 0x3DA, +    CMSG_ADD_VOICE_IGNORE                           = 0x3DB, +    CMSG_DEL_VOICE_IGNORE                           = 0x3DC, +    CMSG_PARTY_SILENCE                              = 0x3DD, +    CMSG_PARTY_UNSILENCE                            = 0x3DE, +    MSG_NOTIFY_PARTY_SQUELCH                        = 0x3DF, +    SMSG_COMSAT_RECONNECT_TRY                       = 0x3E0, +    SMSG_COMSAT_DISCONNECT                          = 0x3E1, +    SMSG_COMSAT_CONNECT_FAIL                        = 0x3E2, +    SMSG_VOICE_CHAT_STATUS                          = 0x3E3, +    CMSG_REPORT_PVP_AFK                             = 0x3E4, +    CMSG_REPORT_PVP_AFK_RESULT                      = 0x3E5, +    CMSG_GUILD_BANKER_ACTIVATE                      = 0x3E6, +    CMSG_GUILD_BANK_QUERY_TAB                       = 0x3E7, +    SMSG_GUILD_BANK_LIST                            = 0x3E8, +    CMSG_GUILD_BANK_SWAP_ITEMS                      = 0x3E9, +    CMSG_GUILD_BANK_BUY_TAB                         = 0x3EA, +    CMSG_GUILD_BANK_UPDATE_TAB                      = 0x3EB, +    CMSG_GUILD_BANK_DEPOSIT_MONEY                   = 0x3EC, +    CMSG_GUILD_BANK_WITHDRAW_MONEY                  = 0x3ED, +    MSG_GUILD_BANK_LOG_QUERY                        = 0x3EE, +    CMSG_SET_CHANNEL_WATCH                          = 0x3EF, +    SMSG_USERLIST_ADD                               = 0x3F0, +    SMSG_USERLIST_REMOVE                            = 0x3F1, +    SMSG_USERLIST_UPDATE                            = 0x3F2, +    CMSG_CLEAR_CHANNEL_WATCH                        = 0x3F3, +    SMSG_INSPECT_TALENT                             = 0x3F4, +    SMSG_GOGOGO_OBSOLETE                            = 0x3F5, +    SMSG_ECHO_PARTY_SQUELCH                         = 0x3F6, +    CMSG_SET_TITLE_SUFFIX                           = 0x3F7, +    CMSG_SPELLCLICK                                 = 0x3F8, +    SMSG_LOOT_LIST                                  = 0x3F9, +    CMSG_GM_CHARACTER_RESTORE                       = 0x3FA, +    CMSG_GM_CHARACTER_SAVE                          = 0x3FB, +    SMSG_VOICESESSION_FULL                          = 0x3FC, +    MSG_GUILD_PERMISSIONS                           = 0x3FD, +    MSG_GUILD_BANK_MONEY_WITHDRAWN                  = 0x3FE, +    MSG_GUILD_EVENT_LOG_QUERY                       = 0x3FF, +    CMSG_MAELSTROM_RENAME_GUILD                     = 0x400, +    CMSG_GET_MIRRORIMAGE_DATA                       = 0x401, +    SMSG_MIRRORIMAGE_DATA                           = 0x402, +    SMSG_FORCE_DISPLAY_UPDATE                       = 0x403, +    SMSG_SPELL_CHANCE_RESIST_PUSHBACK               = 0x404, +    CMSG_IGNORE_DIMINISHING_RETURNS_CHEAT           = 0x405, +    SMSG_IGNORE_DIMINISHING_RETURNS_CHEAT           = 0x406, +    CMSG_KEEP_ALIVE                                 = 0x407, +    SMSG_RAID_READY_CHECK_ERROR                     = 0x408, +    CMSG_OPT_OUT_OF_LOOT                            = 0x409, +    MSG_QUERY_GUILD_BANK_TEXT                       = 0x40A, +    CMSG_SET_GUILD_BANK_TEXT                        = 0x40B, +    CMSG_SET_GRANTABLE_LEVELS                       = 0x40C, +    CMSG_GRANT_LEVEL                                = 0x40D, +    CMSG_REFER_A_FRIEND                             = 0x40E, +    MSG_GM_CHANGE_ARENA_RATING                      = 0x40F, +    CMSG_DECLINE_CHANNEL_INVITE                     = 0x410, +    CMSG_GROUPACTION_THROTTLED                      = 0x411, +    SMSG_OVERRIDE_LIGHT                             = 0x412, +    SMSG_TOTEM_CREATED                              = 0x413, +    CMSG_TOTEM_DESTROYED                            = 0x414, +    CMSG_EXPIRE_RAID_INSTANCE                       = 0x415, +    CMSG_NO_SPELL_VARIANCE                          = 0x416, +    CMSG_QUESTGIVER_STATUS_MULTIPLE_QUERY           = 0x417, +    SMSG_QUESTGIVER_STATUS_MULTIPLE                 = 0x418, +    CMSG_SET_PLAYER_DECLINED_NAMES                  = 0x419, +    SMSG_SET_PLAYER_DECLINED_NAMES_RESULT           = 0x41A, +    CMSG_QUERY_SERVER_BUCK_DATA                     = 0x41B, +    CMSG_CLEAR_SERVER_BUCK_DATA                     = 0x41C, +    SMSG_SERVER_BUCK_DATA                           = 0x41D, +    SMSG_SEND_UNLEARN_SPELLS                        = 0x41E, +    SMSG_PROPOSE_LEVEL_GRANT                        = 0x41F, +    CMSG_ACCEPT_LEVEL_GRANT                         = 0x420, +    SMSG_REFER_A_FRIEND_FAILURE                     = 0x421, +    SMSG_SPLINE_MOVE_SET_FLYING                     = 0x422, +    SMSG_SPLINE_MOVE_UNSET_FLYING                   = 0x423, +    SMSG_SUMMON_CANCEL                              = 0x424, +    CMSG_CHANGE_PERSONAL_ARENA_RATING               = 0x425, +    CMSG_ALTER_APPEARANCE                           = 0x426, +    SMSG_ENABLE_BARBER_SHOP                         = 0x427, +    SMSG_BARBER_SHOP_RESULT                         = 0x428, +    CMSG_CALENDAR_GET_CALENDAR                      = 0x429, +    CMSG_CALENDAR_GET_EVENT                         = 0x42A, +    CMSG_CALENDAR_GUILD_FILTER                      = 0x42B, +    CMSG_CALENDAR_ARENA_TEAM                        = 0x42C, +    CMSG_CALENDAR_ADD_EVENT                         = 0x42D, +    CMSG_CALENDAR_UPDATE_EVENT                      = 0x42E, +    CMSG_CALENDAR_REMOVE_EVENT                      = 0x42F, +    CMSG_CALENDAR_COPY_EVENT                        = 0x430, +    CMSG_CALENDAR_EVENT_INVITE                      = 0x431, +    CMSG_CALENDAR_EVENT_RSVP                        = 0x432, +    CMSG_CALENDAR_EVENT_REMOVE_INVITE               = 0x433, +    CMSG_CALENDAR_EVENT_STATUS                      = 0x434, +    CMSG_CALENDAR_EVENT_MODERATOR_STATUS            = 0x435, +    SMSG_CALENDAR_SEND_CALENDAR                     = 0x436, +    SMSG_CALENDAR_SEND_EVENT                        = 0x437, +    SMSG_CALENDAR_FILTER_GUILD                      = 0x438, +    SMSG_CALENDAR_ARENA_TEAM                        = 0x439, +    SMSG_CALENDAR_EVENT_INVITE                      = 0x43A, +    SMSG_CALENDAR_EVENT_INVITE_REMOVED              = 0x43B, +    SMSG_CALENDAR_EVENT_STATUS                      = 0x43C, +    SMSG_CALENDAR_COMMAND_RESULT                    = 0x43D, +    SMSG_CALENDAR_RAID_LOCKOUT_ADDED                = 0x43E, +    SMSG_CALENDAR_RAID_LOCKOUT_REMOVED              = 0x43F, +    SMSG_CALENDAR_EVENT_INVITE_ALERT                = 0x440, +    SMSG_CALENDAR_EVENT_INVITE_REMOVED_ALERT        = 0x441, +    SMSG_CALENDAR_EVENT_INVITE_STATUS_ALERT         = 0x442, +    SMSG_CALENDAR_EVENT_REMOVED_ALERT               = 0x443, +    SMSG_CALENDAR_EVENT_UPDATED_ALERT               = 0x444, +    SMSG_CALENDAR_EVENT_MODERATOR_STATUS_ALERT      = 0x445, +    CMSG_CALENDAR_COMPLAIN                          = 0x446, +    CMSG_CALENDAR_GET_NUM_PENDING                   = 0x447, +    SMSG_CALENDAR_SEND_NUM_PENDING                  = 0x448, +    CMSG_SAVE_DANCE                                 = 0x449, +    SMSG_NOTIFY_DANCE                               = 0x44A, +    CMSG_PLAY_DANCE                                 = 0x44B, +    SMSG_PLAY_DANCE                                 = 0x44C, +    CMSG_LOAD_DANCES                                = 0x44D, +    CMSG_STOP_DANCE                                 = 0x44E, +    SMSG_STOP_DANCE                                 = 0x44F, +    CMSG_SYNC_DANCE                                 = 0x450, +    CMSG_DANCE_QUERY                                = 0x451, +    SMSG_DANCE_QUERY_RESPONSE                       = 0x452, +    SMSG_INVALIDATE_DANCE                           = 0x453, +    CMSG_DELETE_DANCE                               = 0x454, +    SMSG_LEARNED_DANCE_MOVES                        = 0x455, +    CMSG_LEARN_DANCE_MOVE                           = 0x456, +    CMSG_UNLEARN_DANCE_MOVE                         = 0x457, +    CMSG_SET_RUNE_COUNT                             = 0x458, +    CMSG_SET_RUNE_COOLDOWN                          = 0x459, +    MSG_MOVE_SET_PITCH_RATE_CHEAT                   = 0x45A, +    MSG_MOVE_SET_PITCH_RATE                         = 0x45B, +    SMSG_FORCE_PITCH_RATE_CHANGE                    = 0x45C, +    CMSG_FORCE_PITCH_RATE_CHANGE_ACK                = 0x45D, +    SMSG_SPLINE_SET_PITCH_RATE                      = 0x45E, +    SMSG_MOVE_ABANDON_TRANSPORT                     = 0x45F, +    MSG_MOVE_ABANDON_TRANSPORT                      = 0x460, +    CMSG_MOVE_ABANDON_TRANSPORT_ACK                 = 0x461, +    CMSG_UPDATE_MISSILE_TRAJECTORY                  = 0x462, +    SMSG_UPDATE_ACCOUNT_DATA_COMPLETE               = 0x463, +    SMSG_TRIGGER_MOVIE                              = 0x464, +    CMSG_COMPLETE_MOVIE                             = 0x465, +    CMSG_SET_GLYPH_SLOT                             = 0x466, +    CMSG_SET_GLYPH                                  = 0x467, +    SMSG_ACHIEVEMENT_EARNED                         = 0x468, +    SMSG_DYNAMIC_DROP_ROLL_RESULT                   = 0x469, +    SMSG_CRITERIA_UPDATE                            = 0x46A, +    CMSG_QUERY_INSPECT_ACHIEVEMENTS                 = 0x46B, +    SMSG_RESPOND_INSPECT_ACHIEVEMENTS               = 0x46C, +    CMSG_DISMISS_CONTROLLED_VEHICLE                 = 0x46D, +    CMSG_COMPLETE_ACHIEVEMENT_CHEAT                 = 0x46E, +    SMSG_QUESTUPDATE_ADD_PVP_KILL                   = 0x46F, +    CMSG_SET_CRITERIA_CHEAT                         = 0x470, +    SMSG_GROUP_SWAP_FAILED                          = 0x471, +    CMSG_UNITANIMTIER_CHEAT                         = 0x472, +    CMSG_CHAR_CUSTOMIZE                             = 0x473, +    SMSG_CHAR_CUSTOMIZE                             = 0x474, +    SMSG_PET_RENAMEABLE                             = 0x475, +    CMSG_REQUEST_VEHICLE_EXIT                       = 0x476, +    CMSG_REQUEST_VEHICLE_PREV_SEAT                  = 0x477, +    CMSG_REQUEST_VEHICLE_NEXT_SEAT                  = 0x478, +    CMSG_REQUEST_VEHICLE_SWITCH_SEAT                = 0x479, +    CMSG_PET_LEARN_TALENT                           = 0x47A, +    CMSG_PET_UNLEARN_TALENTS                        = 0x47B, +    SMSG_SET_PHASE_SHIFT                            = 0x47C, +    SMSG_ALL_ACHIEVEMENT_DATA                       = 0x47D, +    CMSG_FORCE_SAY_CHEAT                            = 0x47E, +    SMSG_HEALTH_UPDATE                              = 0x47F, +    SMSG_POWER_UPDATE                               = 0x480, +    CMSG_GAMEOBJ_REPORT_USE                         = 0x481, +    SMSG_HIGHEST_THREAT_UPDATE                      = 0x482, +    SMSG_THREAT_UPDATE                              = 0x483, +    SMSG_THREAT_REMOVE                              = 0x484, +    SMSG_THREAT_CLEAR                               = 0x485, +    SMSG_CONVERT_RUNE                               = 0x486, +    SMSG_RESYNC_RUNES                               = 0x487, +    SMSG_ADD_RUNE_POWER                             = 0x488, +    CMSG_START_QUEST                                = 0x489, +    CMSG_REMOVE_GLYPH                               = 0x48A, +    CMSG_DUMP_OBJECTS                               = 0x48B, +    SMSG_DUMP_OBJECTS_DATA                          = 0x48C, +    CMSG_DISMISS_CRITTER                            = 0x48D, +    SMSG_NOTIFY_DEST_LOC_SPELL_CAST                 = 0x48E, +    CMSG_AUCTION_LIST_PENDING_SALES                 = 0x48F, +    SMSG_AUCTION_LIST_PENDING_SALES                 = 0x490, +    SMSG_MODIFY_COOLDOWN                            = 0x491, +    SMSG_PET_UPDATE_COMBO_POINTS                    = 0x492, +    CMSG_ENABLETAXI                                 = 0x493, +    SMSG_PRE_RESURRECT                              = 0x494, +    SMSG_AURA_UPDATE_ALL                            = 0x495, +    SMSG_AURA_UPDATE                                = 0x496, +    CMSG_FLOOD_GRACE_CHEAT                          = 0x497, +    SMSG_SERVER_FIRST_ACHIEVEMENT                   = 0x498, +    SMSG_PET_LEARNED_SPELL                          = 0x499, +    SMSG_PET_REMOVED_SPELL                          = 0x49A, +    CMSG_CHANGE_SEATS_ON_CONTROLLED_VEHICLE         = 0x49B, +    CMSG_HEARTH_AND_RESURRECT                       = 0x49C, +    SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA       = 0x49D, +    SMSG_CRITERIA_DELETED                           = 0x49E, +    SMSG_ACHIEVEMENT_DELETED                        = 0x49F, +    CMSG_SERVER_INFO_QUERY                          = 0x4A0, +    SMSG_SERVER_INFO_RESPONSE                       = 0x4A1, +    CMSG_CHECK_LOGIN_CRITERIA                       = 0x4A2, +    SMSG_SERVER_BUCK_DATA_START                     = 0x4A3, +    CMSG_QUERY_VEHICLE_STATUS                       = 0x4A4, +    SMSG_PET_GUIDS                                  = 0x4A5, +    NUM_MSG_TYPES                                   = 0x4A6  }; -// Don't forget to change this value and add opcode name to Opcodes.cpp when you add new opcode! -#define NUM_MSG_TYPES 0x424 -  /// Player state  enum SessionStatus  { diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index d42ab2af746..dc2ea0820b1 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -41,27 +41,6 @@ char const* petTypeSuffix[MAX_PET_TYPE] =      "'s Companion"                                          // MINI_PET  }; -//numbers represent minutes * 100 while happy (you get 100 loyalty points per min while happy) -uint32 const LevelUpLoyalty[6] = -{ -    5500, -    11500, -    17000, -    23500, -    31000, -    39500, -}; - -uint32 const LevelStartLoyalty[6] = -{ -    2000, -    4500, -    7000, -    10000, -    13500, -    17500, -}; -  Pet::Pet(PetType type) : Creature()  {      m_isPet = true; @@ -71,17 +50,16 @@ Pet::Pet(PetType type) : Creature()      m_removed = false;      m_regenTimer = 4000;      m_happinessTimer = 7500; -    m_loyaltyTimer = 12000;      m_duration = 0;      m_bonusdamage = 0; -    m_loyaltyPoints = 0; -    m_TrainingPoints = 0;      m_resetTalentsCost = 0;      m_resetTalentsTime = 0;      m_auraUpdateMask = 0; +    m_loading = false; +      // pets always have a charminfo, even if they are not actually charmed      CharmInfo* charmInfo = InitCharmInfo(this); @@ -126,26 +104,28 @@ void Pet::RemoveFromWorld()      Unit::RemoveFromWorld();  } -bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool current ) +bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool current )  { +    m_loading = true; +      uint32 ownerid = owner->GetGUIDLow();      QueryResult *result;      if(petnumber) -        // known petnumber entry                  0   1      2      3        4      5    6           7              8        9           10    11    12       13         14       15            16      17              18        19                 20                 21              22 -        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber); +        // known petnumber entry                  0   1      2(?)   3        4      5    6           7             8(?)  9     10       11         12       13            14      15              16        17                 18                 19              20 +        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND id = '%u'",ownerid, petnumber);      else if(current) -        // current pet (slot 0)                   0   1      2      3        4      5    6           7              8        9           10    11    12       13         14       15            16      17              18        19                 20                 21              22 -        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid ); +        // current pet (slot 0)                   0   1      2(?)   3        4      5    6           7             8(?)  9     10       11         12       13            14      15              16        17                 18                 19              20 +        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND slot = '0'",ownerid );      else if(petentry)          // known petentry entry (unique for summoned pet, but non unique for hunter pet (only from current or not stabled pets) -        //                                        0   1      2      3        4      5    6           7              8        9           10    11    12       13         14       15            16      17              18        19                 20                 21              22 -        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry ); +        //                                        0   1      2(?)   3        4      5    6           7             8(?)  9     10       11         12       13            14      15              16        17                 18                 19              20 +        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND entry = '%u' AND (slot = '0' OR slot = '3') ",ownerid, petentry );      else          // any current or other non-stabled pet (for hunter "call pet") -        //                                        0   1      2      3        4      5    6           7              8        9           10    11    12       13         14       15            16      17              18        19                 20                 21              22 -        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid); +        //                                        0   1      2(?)   3        4      5    6           7             8(?)  9     10       11         12       13            14      15              16        17                 18                 19              20 +        result = CharacterDatabase.PQuery("SELECT id, entry, owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3') ",ownerid);      if(!result)          return false; @@ -160,7 +140,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu          return false;      } -    uint32 summon_spell_id = fields[21].GetUInt32(); +    uint32 summon_spell_id = fields[19].GetUInt32();      SpellEntry const* spellInfo = sSpellStore.LookupEntry(summon_spell_id);      bool is_temporary_summoned = spellInfo && GetSpellDuration(spellInfo) > 0; @@ -194,8 +174,8 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu          return false;      } -    setPetType(PetType(fields[22].GetUInt8())); -    SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,owner->getFaction()); +    setPetType(PetType(fields[20].GetUInt8())); +    SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, owner->getFaction());      SetUInt32Value(UNIT_CREATED_BY_SPELL, summon_spell_id);      CreatureInfo const *cinfo = GetCreatureInfo(); @@ -206,72 +186,67 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu          delete result;          return true;      } -    if(getPetType()==HUNTER_PET || (getPetType()==SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK)) + +    if(getPetType() == HUNTER_PET || (getPetType() == SUMMON_PET && cinfo->type == CREATURE_TYPE_DEMON && owner->getClass() == CLASS_WARLOCK))          m_charmInfo->SetPetNumber(pet_number, true);      else          m_charmInfo->SetPetNumber(pet_number, false); -    SetUInt64Value(UNIT_FIELD_SUMMONEDBY, owner->GetGUID()); + +    SetOwnerGUID(owner->GetGUID());      SetDisplayId(fields[3].GetUInt32());      SetNativeDisplayId(fields[3].GetUInt32()); -    uint32 petlevel=fields[4].GetUInt32(); -    SetUInt32Value(UNIT_NPC_FLAGS , 0); -    SetName(fields[11].GetString()); +    uint32 petlevel = fields[4].GetUInt32(); +    SetUInt32Value(UNIT_NPC_FLAGS, 0); +    SetName(fields[9].GetString());      switch(getPetType())      { -          case SUMMON_PET:              petlevel=owner->getLevel(); -            SetUInt32Value(UNIT_FIELD_BYTES_0,2048); +            SetUInt32Value(UNIT_FIELD_BYTES_0, 2048);              SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);                                                              // this enables popup window (pet dismiss, cancel)              break;          case HUNTER_PET:              SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100); -            SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[8].GetUInt32()); -            SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); -            SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); - -            if(fields[12].GetBool()) -                SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_NOT_ALLOWED); -            else -                SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); +            SetByteValue(UNIT_FIELD_BYTES_1, 1, fields[7].GetUInt32()); +            SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); +            SetByteValue(UNIT_FIELD_BYTES_2, 2, fields[10].GetBool() ? UNIT_RENAME_NOT_ALLOWED : UNIT_RENAME_ALLOWED);              SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);                                                              // this enables popup window (pet abandon, cancel) -            SetTP(fields[9].GetInt32()); -            SetMaxPower(POWER_HAPPINESS,GetCreatePowers(POWER_HAPPINESS)); -            SetPower(   POWER_HAPPINESS,fields[15].GetUInt32()); +            SetMaxPower(POWER_HAPPINESS, GetCreatePowers(POWER_HAPPINESS)); +            SetPower(POWER_HAPPINESS, fields[13].GetUInt32());              setPowerType(POWER_FOCUS);              break;          default: -            sLog.outError("Pet have incorrect type (%u) for pet loading.",getPetType()); +            sLog.outError("Pet have incorrect type (%u) for pet loading.", getPetType());      } -    InitStatsForLevel( petlevel); + +    InitStatsForLevel(petlevel);      SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));      SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, fields[5].GetUInt32()); -    SetUInt64Value(UNIT_FIELD_CREATEDBY, owner->GetGUID()); +    SetCreatorGUID(owner->GetGUID()); -    m_charmInfo->SetReactState( ReactStates( fields[6].GetUInt8() )); -    m_loyaltyPoints = fields[7].GetInt32(); +    m_charmInfo->SetReactState(ReactStates(fields[6].GetUInt8())); -    uint32 savedhealth = fields[13].GetUInt32(); -    uint32 savedmana = fields[14].GetUInt32(); +    uint32 savedhealth = fields[11].GetUInt32(); +    uint32 savedmana = fields[12].GetUInt32();      // set current pet as current -    if(fields[10].GetUInt32() != 0) +    if(fields[8].GetUInt32() != 0)      {          CharacterDatabase.BeginTransaction(); -        CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'",ownerid, m_charmInfo->GetPetNumber()); -        CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'",ownerid, m_charmInfo->GetPetNumber()); +        CharacterDatabase.PExecute("UPDATE character_pet SET slot = '3' WHERE owner = '%u' AND slot = '0' AND id <> '%u'", ownerid, m_charmInfo->GetPetNumber()); +        CharacterDatabase.PExecute("UPDATE character_pet SET slot = '0' WHERE owner = '%u' AND id = '%u'", ownerid, m_charmInfo->GetPetNumber());          CharacterDatabase.CommitTransaction();      }      if(!is_temporary_summoned)      {          // permanent controlled pets store state in DB -        Tokens tokens = StrSplit(fields[16].GetString(), " "); +        Tokens tokens = StrSplit(fields[14].GetString(), " ");          if(tokens.size() != 20)          { @@ -290,11 +265,11 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu              // patch for old data where some spells have ACT_DECIDE but should have ACT_CAST              // so overwrite old state               SpellEntry const *spellInfo = sSpellStore.LookupEntry(m_charmInfo->GetActionBarEntry(index)->SpellOrAction); -            if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_CAST; +            if (spellInfo && spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) m_charmInfo->GetActionBarEntry(index)->Type = ACT_ENABLED;          }          //init teach spells -        tokens = StrSplit(fields[17].GetString(), " "); +        tokens = StrSplit(fields[15].GetString(), " ");          for (iter = tokens.begin(), index = 0; index < 4; ++iter, ++index)          {              uint32 tmp = atol((*iter).c_str()); @@ -309,7 +284,10 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu      }      // since last save (in seconds) -    uint32 timediff = (time(NULL) - fields[18].GetUInt32()); +    uint32 timediff = (time(NULL) - fields[16].GetUInt32()); + +    m_resetTalentsCost = fields[17].GetUInt32(); +    m_resetTalentsTime = fields[18].GetUInt64();      delete result; @@ -375,6 +353,7 @@ bool Pet::LoadPetFromDB( Unit* owner, uint32 petentry, uint32 petnumber, bool cu          }      } +    m_loading = false;      return true;  } @@ -417,10 +396,6 @@ void Pet::SavePetToDB(PetSaveMode mode)          case PET_SAVE_IN_STABLE_SLOT_2:          case PET_SAVE_NOT_IN_SLOT:          { -            uint32 loyalty =1; -            if(getPetType()!=HUNTER_PET) -                loyalty = GetLoyaltyLevel(); -              uint32 owner = GUID_LOPART(GetOwnerGUID());              std::string name = m_name;              CharacterDatabase.escape_string(name); @@ -437,7 +412,7 @@ void Pet::SavePetToDB(PetSaveMode mode)                  CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u' AND (slot = '0' OR slot = '3')", owner );              // save pet              std::ostringstream ss; -            ss  << "INSERT INTO character_pet ( id, entry,  owner, modelid, level, exp, Reactstate, loyaltypoints, loyalty, trainpoint, slot, name, renamed, curhealth, curmana, curhappiness, abdata,TeachSpelldata,savetime,resettalents_cost,resettalents_time,CreatedBySpell,PetType) " +            ss  << "INSERT INTO character_pet ( id, entry,  owner, modelid, level, exp, Reactstate, talentpoints, slot, name, renamed, curhealth, curmana, curhappiness, abdata, TeachSpelldata, savetime, resettalents_cost, resettalents_time, CreatedBySpell, PetType) "                  << "VALUES ("                  << m_charmInfo->GetPetNumber() << ", "                  << GetEntry() << ", " @@ -446,9 +421,7 @@ void Pet::SavePetToDB(PetSaveMode mode)                  << getLevel() << ", "                  << GetUInt32Value(UNIT_FIELD_PETEXPERIENCE) << ", "                  << uint32(m_charmInfo->GetReactState()) << ", " -                << m_loyaltyPoints << ", " -                << GetLoyaltyLevel() << ", " -                << m_TrainingPoints << ", " +                << uint32(GetFreeTalentPoints()) << ", "                  << uint32(mode) << ", '"                  << name.c_str() << "', "                  << uint32((GetByteValue(UNIT_FIELD_BYTES_2, 2) == UNIT_RENAME_ALLOWED)?0:1) << ", " @@ -521,12 +494,12 @@ void Pet::setDeathState(DeathState s)                       // overwrite virtual              if(!mapEntry || (mapEntry->map_type != MAP_ARENA && mapEntry->map_type != MAP_BATTLEGROUND))                  ModifyPower(POWER_HAPPINESS, -HAPPINESS_LEVEL_SIZE); -            SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +            SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);          }      }      else if(getDeathState()==ALIVE)      { -        RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +        RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);          CastPetAuras(true);      }  } @@ -553,6 +526,7 @@ void Pet::Update(uint32 diff)              // unsummon pet that lost owner              Unit* owner = GetOwner();              if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && !isPossessed()) || isControlled() && !owner->GetPetGUID()) +            //if(!owner || (!IsWithinDistInMap(owner, OWNER_MAX_DISTANCE) && (owner->GetCharmGUID() && (owner->GetCharmGUID() != GetGUID()))) || (isControlled() && !owner->GetPetGUID()))              {                  Remove(PET_SAVE_NOT_IN_SLOT, true);                  return; @@ -598,14 +572,6 @@ void Pet::Update(uint32 diff)              else                  m_happinessTimer -= diff; -            if(m_loyaltyTimer <= diff) -            { -                TickLoyaltyChange(); -                m_loyaltyTimer = 12000; -            } -            else -                m_loyaltyTimer -= diff; -              break;          }          default: @@ -637,83 +603,12 @@ void Pet::LooseHappiness()      uint32 curValue = GetPower(POWER_HAPPINESS);      if (curValue <= 0)          return; -    int32 addvalue = (140 >> GetLoyaltyLevel()) * 125;      //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs) +    int32 addvalue = 670;                                   //value is 70/35/17/8/4 (per min) * 1000 / 8 (timer 7.5 secs)      if(isInCombat())                                        //we know in combat happiness fades faster, multiplier guess          addvalue = int32(addvalue * 1.5);      ModifyPower(POWER_HAPPINESS, -addvalue);  } -void Pet::ModifyLoyalty(int32 addvalue) -{ -    uint32 loyaltylevel = GetLoyaltyLevel(); - -    if(addvalue > 0)                                        //only gain influenced, not loss -        addvalue = int32((float)addvalue * sWorld.getRate(RATE_LOYALTY)); - -    if(loyaltylevel >= BEST_FRIEND && (addvalue + m_loyaltyPoints) > int32(GetMaxLoyaltyPoints(loyaltylevel))) -        return; - -    m_loyaltyPoints += addvalue; - -    if(m_loyaltyPoints < 0) -    { -        if(loyaltylevel > REBELLIOUS) -        { -            //level down -            --loyaltylevel; -            SetLoyaltyLevel(LoyaltyLevel(loyaltylevel)); -            m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel); -            SetTP(m_TrainingPoints - int32(getLevel())); -        } -        else -        { -            m_loyaltyPoints = 0; -            Unit* owner = GetOwner(); -            if(owner && owner->GetTypeId() == TYPEID_PLAYER) -            { -                WorldPacket data(SMSG_PET_BROKEN, 0); -                ((Player*)owner)->GetSession()->SendPacket(&data); - -                //run away -                ((Player*)owner)->RemovePet(this,PET_SAVE_AS_DELETED); -            } -        } -    } -    //level up -    else if(m_loyaltyPoints > int32(GetMaxLoyaltyPoints(loyaltylevel))) -    { -        ++loyaltylevel; -        SetLoyaltyLevel(LoyaltyLevel(loyaltylevel)); -        m_loyaltyPoints = GetStartLoyaltyPoints(loyaltylevel); -        SetTP(m_TrainingPoints + getLevel()); -    } -} - -void Pet::TickLoyaltyChange() -{ -    int32 addvalue; - -    switch(GetHappinessState()) -    { -        case HAPPY:   addvalue =  20; break; -        case CONTENT: addvalue =  10; break; -        case UNHAPPY: addvalue = -20; break; -        default: -            return; -    } -    ModifyLoyalty(addvalue); -} - -void Pet::KillLoyaltyBonus(uint32 level) -{ -    if(level > 100) -        return; - -                                                            //at lower levels gain is faster | the lower loyalty the more loyalty is gained -    uint32 bonus = uint32(((100 - level) / 10) + (6 - GetLoyaltyLevel())); -    ModifyLoyalty(bonus); -} -  HappinessState Pet::GetHappinessState()  {      if(GetPower(POWER_HAPPINESS) < HAPPINESS_LEVEL_SIZE) @@ -724,11 +619,6 @@ HappinessState Pet::GetHappinessState()          return CONTENT;  } -void Pet::SetLoyaltyLevel(LoyaltyLevel level) -{ -    SetByteValue(UNIT_FIELD_BYTES_1, 1, level); -} -  bool Pet::CanTakeMoreActiveSpells(uint32 spellid)  {      uint8  activecount = 1; @@ -765,82 +655,6 @@ bool Pet::CanTakeMoreActiveSpells(uint32 spellid)      return true;  } -bool Pet::HasTPForSpell(uint32 spellid) -{ -    int32 neededtrainp = GetTPForSpell(spellid); -    if((m_TrainingPoints - neededtrainp < 0 || neededtrainp < 0) && neededtrainp != 0) -        return false; -    return true; -} - -int32 Pet::GetTPForSpell(uint32 spellid) -{ -    uint32 basetrainp = 0; - -    SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spellid); -    SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spellid); -    for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) -    { -        if(!_spell_idx->second->reqtrainpoints) -            return 0; - -        basetrainp = _spell_idx->second->reqtrainpoints; -        break; -    } - -    uint32 spenttrainp = 0; -    uint32 chainstart = spellmgr.GetFirstSpellInChain(spellid); - -    for (PetSpellMap::iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) -    { -        if(itr->second->state == PETSPELL_REMOVED) -            continue; - -        if(spellmgr.GetFirstSpellInChain(itr->first) == chainstart) -        { -            SkillLineAbilityMap::const_iterator _lower = spellmgr.GetBeginSkillLineAbilityMap(itr->first); -            SkillLineAbilityMap::const_iterator _upper = spellmgr.GetEndSkillLineAbilityMap(itr->first); - -            for(SkillLineAbilityMap::const_iterator _spell_idx2 = _lower; _spell_idx2 != _upper; ++_spell_idx2) -            { -                if(_spell_idx2->second->reqtrainpoints > spenttrainp) -                { -                    spenttrainp = _spell_idx2->second->reqtrainpoints; -                    break; -                } -            } -        } -    } - -    return int32(basetrainp) - int32(spenttrainp); -} - -uint32 Pet::GetMaxLoyaltyPoints(uint32 level) -{ -    return LevelUpLoyalty[level - 1]; -} - -uint32 Pet::GetStartLoyaltyPoints(uint32 level) -{ -    return LevelStartLoyalty[level - 1]; -} - -void Pet::SetTP(int32 TP) -{ -    m_TrainingPoints = TP; -    SetUInt32Value(UNIT_TRAINING_POINTS, (uint32)GetDispTP()); -} - -int32 Pet::GetDispTP() -{ -    if(getPetType()!= HUNTER_PET) -        return(0); -    if(m_TrainingPoints < 0) -        return -m_TrainingPoints; -    else -        return -(m_TrainingPoints + 1); -} -  void Pet::Remove(PetSaveMode mode, bool returnreagent)  {      Unit* owner = GetOwner(); @@ -903,9 +717,6 @@ void Pet::GivePetXP(uint32 xp)      }      SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, newXP); - -    if(getPetType() == HUNTER_PET) -        KillLoyaltyBonus(level);  }  void Pet::GivePetLevel(uint32 level) @@ -913,9 +724,7 @@ void Pet::GivePetLevel(uint32 level)      if(!level)          return; -    InitStatsForLevel( level); - -    SetTP(m_TrainingPoints + (GetLoyaltyLevel() - 1)); +    InitStatsForLevel(level);  }  bool Pet::CreateBaseAtCreature(Creature* creature) @@ -964,7 +773,6 @@ bool Pet::CreateBaseAtCreature(Creature* creature)      SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, 0);      SetUInt32Value(UNIT_FIELD_PETEXPERIENCE, 0);      SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(creature->getLevel()))/4)); -    SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);      SetUInt32Value(UNIT_NPC_FLAGS, 0);      CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(creature->GetCreatureInfo()->family); @@ -973,16 +781,12 @@ bool Pet::CreateBaseAtCreature(Creature* creature)      else          SetName(creature->GetName()); -    m_loyaltyPoints = 1000;      if(cinfo->type == CREATURE_TYPE_BEAST)      {          SetUInt32Value(UNIT_FIELD_BYTES_0, 0x02020100);          SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); -        SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 );          SetByteValue(UNIT_FIELD_BYTES_2, 2, UNIT_RENAME_ALLOWED); - -        SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED) ); -        SetLoyaltyLevel(REBELLIOUS); +        SetUInt32Value(UNIT_MOD_CAST_SPEED, creature->GetUInt32Value(UNIT_MOD_CAST_SPEED));      }      return true;  } @@ -1112,7 +916,7 @@ bool Pet::InitStatsForLevel(uint32 petlevel)          case HUNTER_PET:          {              SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP, uint32((Trinity::XP::xp_to_level(petlevel))/4)); - +            learnLevelupSpells();              //these formula may not be correct; however, it is designed to be close to what it should be              //this makes dps 0.5 of pets level              SetBaseWeaponDamage(BASE_ATTACK, MINDAMAGE, float(petlevel - (petlevel / 4)) ); @@ -1344,10 +1148,6 @@ void Pet::_LoadAuras(uint32 timediff)      for (int i = 0; i < TOTAL_AURAS; i++)          m_modAuras[i].clear(); -    // all aura related fields -    for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) -        SetUInt32Value(i, 0); -      QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM pet_aura WHERE guid = '%u'",m_charmInfo->GetPetNumber());      if(result) @@ -1488,7 +1288,7 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s      // same spells don't have autocast option      if (spellInfo->AttributesEx & SPELL_ATTR_EX_UNAUTOCASTABLE_BY_PET) -        active = ACT_CAST; +        active = ACT_ENABLED;      PetSpellMap::iterator itr = m_spells.find(spell_id);      if (itr != m_spells.end()) @@ -1540,11 +1340,12 @@ bool Pet::addSpell(uint16 spell_id, uint16 active, PetSpellState state, uint16 s                  ToggleAutocast(itr->first, false);              oldspell_id = itr->first; -            removeSpell(itr->first); +            unlearnSpell(itr->first); +            break;          }      } -    uint16 tmpslot=slot_id; +    uint16 tmpslot = slot_id;      if (tmpslot == 0xffff)      { @@ -1578,20 +1379,65 @@ bool Pet::learnSpell(uint16 spell_id)      if (!addSpell(spell_id))          return false; +    if(GetOwner()->GetTypeId() == TYPEID_PLAYER) +    { +        if(!m_loading) +        { +            WorldPacket data(SMSG_PET_LEARNED_SPELL, 2); +            data << uint16(spell_id); +            ((Player*)GetOwner())->GetSession()->SendPacket(&data); +        } +    } +      Unit* owner = GetOwner(); -    if(owner->GetTypeId()==TYPEID_PLAYER) +    if(owner->GetTypeId() == TYPEID_PLAYER)          ((Player*)owner)->PetSpellInitialize();      return true;  } -void Pet::removeSpell(uint16 spell_id) +void Pet::learnLevelupSpells() +{ +    PetLevelupSpellSet const *levelupSpells = spellmgr.GetPetLevelupSpellList(GetCreatureInfo()->family); +    if(!levelupSpells) +        return; + +    uint32 level = getLevel(); + +    for(PetLevelupSpellSet::const_iterator itr = levelupSpells->begin(); itr != levelupSpells->end(); ++itr) +    { +        if(itr->first <= level) +            learnSpell(itr->second); +        else +            unlearnSpell(itr->second); +    } +} + +bool Pet::unlearnSpell(uint16 spell_id) +{ +    if(removeSpell(spell_id)) +    { +        if(GetOwner()->GetTypeId() == TYPEID_PLAYER) +        { +            if(!m_loading) +            { +                WorldPacket data(SMSG_PET_REMOVED_SPELL, 2); +                data << uint16(spell_id); +                ((Player*)GetOwner())->GetSession()->SendPacket(&data); +            } +        } +        return true; +    } +    return false; +} + +bool Pet::removeSpell(uint16 spell_id)  {      PetSpellMap::iterator itr = m_spells.find(spell_id);      if (itr == m_spells.end()) -        return; +        return false;      if(itr->second->state == PETSPELL_REMOVED) -        return; +        return false;      if(itr->second->state == PETSPELL_NEW)      { @@ -1602,6 +1448,8 @@ void Pet::removeSpell(uint16 spell_id)          itr->second->state = PETSPELL_REMOVED;      RemoveAurasDueToSpell(spell_id); + +    return true;  }  bool Pet::_removeSpell(uint16 spell_id) @@ -1621,7 +1469,7 @@ void Pet::InitPetCreateSpells()      m_charmInfo->InitPetActionBar();      m_spells.clear(); -    int32 usedtrainpoints = 0, petspellid; +    int32 petspellid;      PetCreateSpellEntry const* CreateSpells = objmgr.GetPetCreateSpellEntry(GetEntry());      if(CreateSpells)      { @@ -1650,23 +1498,12 @@ void Pet::InitPetCreateSpells()                  petspellid = learn_spellproto->Id;              addSpell(petspellid); - -            SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]); -            SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(learn_spellproto->EffectTriggerSpell[0]); - -            for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) -            { -                usedtrainpoints += _spell_idx->second->reqtrainpoints; -                break; -            }          }      }      LearnPetPassives();      CastPetAuras(false); - -    SetTP(-usedtrainpoints);  }  void Pet::CheckLearning(uint32 spellid) @@ -1725,7 +1562,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)      if(apply)      { -        for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++); +        for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++) +            ;                                               // just search +          if (i == m_autospells.size())          {              m_autospells.push_back(spellid); @@ -1736,7 +1575,9 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)      else      {          AutoSpellList::iterator itr2 = m_autospells.begin(); -        for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++); +        for (i = 0; i < m_autospells.size() && m_autospells[i] != spellid; i++, itr2++) +            ;                                               // just search +          if (i < m_autospells.size())          {              m_autospells.erase(itr2); @@ -1759,8 +1600,7 @@ bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number)      if(!InitEntry(Entry))          return false; -    SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE ); -    SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_AURAS | UNIT_BYTE2_FLAG_UNK5 ); +    SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE);      if(getPetType() == MINI_PET)                            // always non-attackable          SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); diff --git a/src/game/Pet.h b/src/game/Pet.h index 9d187b24b45..178ebfb131e 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -52,16 +52,6 @@ enum HappinessState      HAPPY   = 3  }; -enum LoyaltyLevel -{ -    REBELLIOUS  = 1, -    UNRULY      = 2, -    SUBMISSIVE  = 3, -    DEPENDABLE  = 4, -    FAITHFUL    = 5, -    BEST_FRIEND = 6 -}; -  enum PetSpellState  {      PETSPELL_UNCHANGED = 0, @@ -122,9 +112,6 @@ typedef std::vector<uint32> AutoSpellList;  #define HAPPINESS_LEVEL_SIZE        333000 -extern const uint32 LevelUpLoyalty[6]; -extern const uint32 LevelStartLoyalty[6]; -  #define ACTIVE_SPELLS_MAX           4  #define OWNER_MAX_DISTANCE 100 @@ -148,7 +135,7 @@ class Pet : public Creature          bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number);          bool CreateBaseAtCreature(Creature* creature); -        bool LoadPetFromDB( Unit* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false ); +        bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );          void SavePetToDB(PetSaveMode mode);          void Remove(PetSaveMode mode, bool returnreagent = false);          static void DeleteFromDB(uint32 guidlow); @@ -167,14 +154,7 @@ class Pet : public Creature          void RegenerateFocus();          void LooseHappiness(); -        void TickLoyaltyChange(); -        void ModifyLoyalty(int32 addvalue);          HappinessState GetHappinessState(); -        uint32 GetMaxLoyaltyPoints(uint32 level); -        uint32 GetStartLoyaltyPoints(uint32 level); -        void KillLoyaltyBonus(uint32 level); -        uint32 GetLoyaltyLevel() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } -        void SetLoyaltyLevel(LoyaltyLevel level);          void GivePetXP(uint32 xp);          void GivePetLevel(uint32 level);          bool InitStatsForLevel(uint32 level); @@ -194,10 +174,8 @@ class Pet : public Creature          void UpdateAttackPowerAndDamage(bool ranged = false);          void UpdateDamagePhysical(WeaponAttackType attType); -        bool   CanTakeMoreActiveSpells(uint32 SpellIconID); -        void   ToggleAutocast(uint32 spellid, bool apply); -        bool   HasTPForSpell(uint32 spellid); -        int32  GetTPForSpell(uint32 spellid); +        bool CanTakeMoreActiveSpells(uint32 SpellIconID); +        void ToggleAutocast(uint32 spellid, bool apply);          bool HasSpell(uint32 spell) const;          void AddTeachSpell(uint32 learned_id, uint32 source_id) { m_teachspells[learned_id] = source_id; } @@ -215,7 +193,9 @@ class Pet : public Creature          bool addSpell(uint16 spell_id,uint16 active = ACT_DECIDE, PetSpellState state = PETSPELL_NEW, uint16 slot_id=0xffff, PetSpellType type = PETSPELL_NORMAL);          bool learnSpell(uint16 spell_id); -        void removeSpell(uint16 spell_id); +        void learnLevelupSpells(); +        bool unlearnSpell(uint16 spell_id); +        bool removeSpell(uint16 spell_id);          bool _removeSpell(uint16 spell_id);          PetSpellMap     m_spells; @@ -225,11 +205,10 @@ class Pet : public Creature          void InitPetCreateSpells();          void CheckLearning(uint32 spellid);          uint32 resetTalentsCost() const; +        uint8 GetMaxTalentPointsForLevel(uint32 level) { return (level >= 20) ? ((level - 16) / 4) : 0; } +        uint8 GetFreeTalentPoints() { return GetByteValue(UNIT_FIELD_BYTES_1, 1); } +        void SetFreeTalentPoints(uint8 points) { SetByteValue(UNIT_FIELD_BYTES_1, 1, points); } -        void  SetTP(int32 TP); -        int32 GetDispTP(); - -        int32   m_TrainingPoints;          uint32  m_resetTalentsCost;          time_t  m_resetTalentsTime; @@ -242,14 +221,12 @@ class Pet : public Creature          bool    m_removed;                                  // prevent overwrite pet state in DB at next Pet::Update if pet already removed(saved)      protected: -        uint32  m_regenTimer;          uint32  m_happinessTimer; -        uint32  m_loyaltyTimer;          PetType m_petType;          int32   m_duration;                                 // time until unsummon (used mostly for summoned guardians and not used for controlled pets) -        int32   m_loyaltyPoints;          int32   m_bonusdamage;          uint64  m_auraUpdateMask; +        bool    m_loading;          DeclinedName *m_declinedname; diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index e4269ddafd6..f059662987c 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -174,9 +174,9 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )                      break;              }              break; -        case ACT_DISABLED:                                  //0x8100    spell (disabled), ignore -        case ACT_CAST:                                      //0x0100 -        case ACT_ENABLED:                                   //0xc100    spell +        case ACT_DISABLED:                                  // 0x8100    spell (disabled), ignore +        case ACT_PASSIVE:                                   // 0x0100 +        case ACT_ENABLED:                                   // 0xC100    spell          {              Unit* unit_target;              if(guid2) @@ -257,7 +257,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data )                  if(pet->isPossessed())                  {                      WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); -                    data << uint32(spellid) << uint8(2) << uint8(result); +                    data << uint8(0) << uint32(spellid) << uint8(result);                      switch (result)                      {                          case SPELL_FAILED_REQUIRES_SPELL_FOCUS: @@ -369,7 +369,7 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data )          sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X\n", _player->GetName(), position, spell_id, act_state);                                                              //if it's act for spell (en/disable/cast) and there is a spell given (0 = remove spell) which pet doesn't know, don't add -        if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_CAST) && spell_id && !pet->HasSpell(spell_id))) +        if(!((act_state == ACT_ENABLED || act_state == ACT_DISABLED || act_state == ACT_PASSIVE) && spell_id && !pet->HasSpell(spell_id)))          {              //sign for autocast              if(act_state == ACT_ENABLED && spell_id) @@ -542,11 +542,10 @@ void WorldSession::HandlePetUnlearnOpcode(WorldPacket& recvPacket)      {          uint32 spell_id = itr->first;                       // Pet::removeSpell can invalidate iterator at erase NEW spell          ++itr; -        pet->removeSpell(spell_id); +        //pet->removeSpell(spell_id); +        pet->unlearnSpell(spell_id);      } -    pet->SetTP(pet->getLevel() * (pet->GetLoyaltyLevel() - 1)); -      for(uint8 i = 0; i < 10; i++)      {          if(charmInfo->GetActionBarEntry(i)->SpellOrAction && charmInfo->GetActionBarEntry(i)->Type == ACT_ENABLED || charmInfo->GetActionBarEntry(i)->Type == ACT_DISABLED) @@ -616,11 +615,15 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )  {      sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL"); -    CHECK_PACKET_SIZE(recvPacket,8+4); +    CHECK_PACKET_SIZE(recvPacket,8+1+4+1);      uint64 guid;      uint32 spellid; +    uint8  cast_count; +    uint8  unk_flags;                                       // flags (if 0x02 - some additional data are received) + +    recvPacket >> guid >> cast_count >> spellid >> unk_flags; -    recvPacket >> guid >> spellid; +    sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);      // This opcode is also sent from charmed and possessed units (players and creatures)      if(!_player->GetPet() && !_player->GetCharm()) @@ -655,6 +658,7 @@ void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )      caster->clearUnitState(UNIT_STAT_FOLLOW);      Spell *spell = new Spell(caster, spellInfo, false); +    spell->m_cast_count = cast_count;                       // probably pending spell cast      spell->m_targets = targets;      int16 result = spell->PetCanCast(NULL); @@ -713,3 +717,132 @@ void WorldSession::SendPetNameInvalid(uint32 error, const std::string& name, Dec          data << uint8(0);      SendPacket(&data);  } + +void WorldSession::HandlePetLearnTalent( WorldPacket & recv_data ) +{ +    sLog.outDebug("WORLD: CMSG_PET_LEARN_TALENT"); +    recv_data.hexlike(); + +    CHECK_PACKET_SIZE(recv_data, 8+4+4); + +    uint64 guid; +    uint32 talent_id, requested_rank; +    recv_data >> guid >> talent_id >> requested_rank; + +    Pet *pet = _player->GetPet(); + +    if(!pet) +        return; + +    if(guid != pet->GetGUID()) +        return; + +    uint32 CurTalentPoints =  pet->GetFreeTalentPoints(); + +    if(CurTalentPoints == 0) +        return; + +    if (requested_rank > 4) +        return; + +    TalentEntry const *talentInfo = sTalentStore.LookupEntry(talent_id); + +    if(!talentInfo) +        return; + +    TalentTabEntry const *talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab); + +    if(!talentTabInfo) +        return; + +    CreatureInfo const *ci = pet->GetCreatureInfo(); + +    if(!ci) +        return; + +    CreatureFamilyEntry const *pet_family = sCreatureFamilyStore.LookupEntry(ci->family); + +    if(!pet_family) +        return; + +    if(pet_family->petTalentType < 0)                       // not hunter pet +        return; + +    // prevent learn talent for different family (cheating) +    if(!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask)) +        return; + +    // prevent skip talent ranks (cheating) +    if(requested_rank > 0 && !pet->HasSpell(talentInfo->RankID[requested_rank-1])) +        return; + +    // Check if it requires another talent +    if (talentInfo->DependsOn > 0) +    { +        if(TalentEntry const *depTalentInfo = sTalentStore.LookupEntry(talentInfo->DependsOn)) +        { +            bool hasEnoughRank = false; +            for (int i = talentInfo->DependsOnRank; i <= 4; i++) +            { +                if (depTalentInfo->RankID[i] != 0) +                    if (pet->HasSpell(depTalentInfo->RankID[i])) +                        hasEnoughRank = true; +            } +            if (!hasEnoughRank) +                return; +        } +    } + +    // Find out how many points we have in this field +    uint32 spentPoints = 0; + +    uint32 tTab = talentInfo->TalentTab; +    if (talentInfo->Row > 0) +    { +        unsigned int numRows = sTalentStore.GetNumRows(); +        for (unsigned int i = 0; i < numRows; i++)          // Loop through all talents. +        { +            // Someday, someone needs to revamp +            const TalentEntry *tmpTalent = sTalentStore.LookupEntry(i); +            if (tmpTalent)                                  // the way talents are tracked +            { +                if (tmpTalent->TalentTab == tTab) +                { +                    for (int j = 0; j <= 4; j++) +                    { +                        if (tmpTalent->RankID[j] != 0) +                        { +                            if (pet->HasSpell(tmpTalent->RankID[j])) +                            { +                                spentPoints += j + 1; +                            } +                        } +                    } +                } +            } +        } +    } + +    // not have required min points spent in talent tree +    if(spentPoints < (talentInfo->Row * 3)) +        return; + +    // spell not set in talent.dbc +    uint32 spellid = talentInfo->RankID[requested_rank]; +    if( spellid == 0 ) +    { +        sLog.outError("Talent.dbc have for talent: %u Rank: %u spell id = 0", talent_id, requested_rank); +        return; +    } + +    // already known +    if(pet->HasSpell(spellid)) +        return; + +    // learn! (other talent ranks will unlearned at learning) +    pet->learnSpell(spellid); +    sLog.outDetail("TalentID: %u Rank: %u Spell: %u\n", talent_id, requested_rank, spellid); + +    // update free talent points +    pet->SetFreeTalentPoints(CurTalentPoints - 1); +} diff --git a/src/game/PetitionsHandler.cpp b/src/game/PetitionsHandler.cpp index 8fc18b1c259..ad3893ce110 100644 --- a/src/game/PetitionsHandler.cpp +++ b/src/game/PetitionsHandler.cpp @@ -199,9 +199,9 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket & recv_data)      if(!charter)          return; -    charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT, charter->GetGUIDLow()); -    // ITEM_FIELD_ENCHANTMENT is guild/arenateam id -    // ITEM_FIELD_ENCHANTMENT+1 is current signatures count (showed on item) +    charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow()); +    // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id +    // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item)      charter->SetState(ITEM_CHANGED, _player);      _player->SendNewItem(charter, 1, true, false); @@ -565,7 +565,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket & recv_data)      // update signs count on charter, required testing...      //Item *item = _player->GetItemByGuid(petitionguid));      //if(item) -    //    item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT+1, signs); +    //    item->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1+1, signs);      // update for owner if online      if(Player *owner = objmgr.GetPlayer(ownerguid)) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 4b187023be4..adf5a5ab167 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -64,6 +64,7 @@  #include "Spell.h"  #include "SocialMgr.h"  #include "GameEvent.h" +#include "AchievementMgr.h"  #include <cmath> @@ -132,7 +133,7 @@ PlayerTaxi::PlayerTaxi()      memset(m_taximask, 0, sizeof(m_taximask));  } -void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level) +void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level)  {      // capital and taxi hub masks      switch(race) @@ -149,6 +150,13 @@ void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 level)          case RACE_BLOODELF: SetTaximaskNode(82); break;     // Blood Elf          case RACE_DRAENEI:  SetTaximaskNode(94); break;     // Draenei      } + +    switch(chrClass) +    { +        case CLASS_DEATH_KNIGHT:                            // TODO: figure out initial known nodes +            break; +    } +      // new continent starting masks (It will be accessible only at new map)      switch(Player::TeamForRace(race))      { @@ -251,7 +259,7 @@ const int32 Player::ReputationRank_Length[MAX_REPUTATION_RANK] = {36000, 3000, 3  UpdateMask Player::updateVisualBits; -Player::Player (WorldSession *session): Unit() +Player::Player (WorldSession *session): Unit(), m_achievementMgr(this)  {      m_transport = 0; @@ -364,6 +372,7 @@ Player::Player (WorldSession *session): Unit()      m_canParry = false;      m_canBlock = false;      m_canDualWield = false; +    m_canTitanGrip = false;      m_ammoDPS = 0.0f;      m_temporaryUnsummonedPetNumber = 0; @@ -408,6 +417,9 @@ Player::Player (WorldSession *session): Unit()          m_auraBaseMod[i][PCT_MOD] = 1.0f;      } +    for (int i = 0; i < MAX_COMBAT_RATING; i++) +        m_baseRatingValue[i] = 0; +      // Honor System      m_lastHonorUpdateTime = time(NULL); @@ -421,6 +433,8 @@ Player::Player (WorldSession *session): Unit()      //Default movement to run mode      m_unit_movement_flags = 0; +    m_mover = NULL; +      m_miniPet = 0;      m_bgAfkReportedTimer = 0;      m_contestedPvPTimer = 0; @@ -430,6 +444,8 @@ Player::Player (WorldSession *session): Unit()      m_isActive = true;      m_farsightVision = false; + +    m_runes = NULL;  }  Player::~Player () @@ -477,6 +493,7 @@ Player::~Player ()          RemovePossess(false);      delete m_declinedname; +    delete m_runes;  }  void Player::CleanupsBeforeDelete() @@ -522,9 +539,9 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8      uint8 powertype = cEntry->powerType; -    uint32 unitfield; +    //uint32 unitfield; -    switch(powertype) +    /*switch(powertype)      {          case POWER_ENERGY:          case POWER_MANA: @@ -533,13 +550,16 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8          case POWER_RAGE:              unitfield = 0x00110000;              break; +        case POWER_RUNIC_POWER: +            unitfield = 0x0000EE00;                         //TODO: find correct unitfield here +            break;          default:              sLog.outError("Invalid default powertype %u for player (class %u)",powertype,class_);              return false; -    } +    }*/ -    SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE ); -    SetFloatValue(UNIT_FIELD_COMBATREACH, DEFAULT_COMBAT_REACH ); +    SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, DEFAULT_WORLD_OBJECT_SIZE); +    SetFloatValue(UNIT_FIELD_COMBATREACH, 1.5f);      switch(gender)      { @@ -562,12 +582,14 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8      uint32 RaceClassGender = ( race ) | ( class_ << 8 ) | ( gender << 16 );      SetUInt32Value(UNIT_FIELD_BYTES_0, ( RaceClassGender | ( powertype << 24 ) ) ); -    SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); -    SetByteValue(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_UNK3 | UNIT_BYTE2_FLAG_UNK5 ); -    SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); +    //SetUInt32Value(UNIT_FIELD_BYTES_1, unitfield); +    SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP ); +    SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE ); +    SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_REGENERATE_POWER);      SetFloatValue(UNIT_MOD_CAST_SPEED, 1.0f);               // fix cast time showed in spell tooltip on client +    SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f);            // default for players in 3.0.3 -                                                            //-1 is default value +                                                            // -1 is default value      SetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, uint32(-1));      SetUInt32Value(PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); @@ -579,17 +601,35 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8      SetUInt32Value( PLAYER_GUILD_TIMESTAMP, 0 );      SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES, 0 );        // 0=disabled +    SetUInt64Value( PLAYER__FIELD_KNOWN_TITLES1, 0 );       // 0=disabled      SetUInt32Value( PLAYER_CHOSEN_TITLE, 0 );      SetUInt32Value( PLAYER_FIELD_KILLS, 0 );      SetUInt32Value( PLAYER_FIELD_LIFETIME_HONORBALE_KILLS, 0 );      SetUInt32Value( PLAYER_FIELD_TODAY_CONTRIBUTION, 0 );      SetUInt32Value( PLAYER_FIELD_YESTERDAY_CONTRIBUTION, 0 ); +    for(uint32 i = 0; i < sGlyphSlotStore.GetNumRows(); ++i) +    { +        GlyphSlotEntry const * gs = sGlyphSlotStore.LookupEntry(i); +        if(gs && gs->Order) +            SetGlyphSlot(gs->Order - 1, gs->Id); +    } +      // set starting level +    uint32 start_level = getClass() != CLASS_DEATH_KNIGHT +        ? sWorld.getConfig(CONFIG_START_PLAYER_LEVEL) +        : sWorld.getConfig(CONFIG_START_HEROIC_PLAYER_LEVEL); +      if (GetSession()->GetSecurity() >= SEC_MODERATOR) -        SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_GM_LEVEL)); -    else -        SetUInt32Value (UNIT_FIELD_LEVEL, sWorld.getConfig(CONFIG_START_PLAYER_LEVEL)); +    { +        uint32 gm_level = sWorld.getConfig(CONFIG_START_GM_LEVEL); +        if(gm_level > start_level) +            start_level = gm_level; +    } + +    SetUInt32Value(UNIT_FIELD_LEVEL, start_level); + +    InitRunes();      SetUInt32Value (PLAYER_FIELD_COINAGE, sWorld.getConfig(CONFIG_START_PLAYER_MONEY));      SetUInt32Value (PLAYER_FIELD_HONOR_CURRENCY, sWorld.getConfig(CONFIG_START_HONOR_POINTS)); @@ -653,6 +693,7 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8      // base stats and related field values      InitStatsForLevel();      InitTaxiNodesForLevel(); +    InitGlyphsForLevel();      InitTalentForLevel();      InitPrimaryProffesions();                               // to max set before any spell added @@ -665,6 +706,14 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8          SetPower(POWER_MANA,GetMaxPower(POWER_MANA));      } +    if(getPowerType() == POWER_RUNIC_POWER) +    { +        SetPower(POWER_RUNE, 8); +        SetMaxPower(POWER_RUNE, 8); +        SetPower(POWER_RUNIC_POWER, 0); +        SetMaxPower(POWER_RUNIC_POWER, 1000); +    } +      // original spells      learnDefaultSpells(true); @@ -708,6 +757,11 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8              uint32 item_id = oEntry->ItemId[j]; + +            // Hack for not existed item id in dbc 3.0.3 +            if(item_id==40582) +                continue; +              ItemPrototype const* iProto = objmgr.GetItemPrototype(item_id);              if(!iProto)              { @@ -935,53 +989,29 @@ void Player::HandleDrowning()  void Player::HandleLava()  { -    bool ValidArea = false; -      if ((m_isunderwater & 0x80) && isAlive())      { -        //Single trigger Set BreathTimer +        // Single trigger Set BreathTimer          if (!(m_isunderwater & 0x80))          {              m_isunderwater|= 0x04;              m_breathTimer = 1000;          } -        //Reset BreathTimer and still in the lava + +        // Reset BreathTimer and still in the lava          if (!m_breathTimer)          {              uint64 guid = GetGUID();              uint32 damage = urand(600, 700);                // TODO: Get more detailed information about lava damage -            uint32 dmgZone = GetZoneId();                   // TODO: Find correct "lava dealing zone" flag in Area Table -            // Deal lava damage only in lava zones. -            switch(dmgZone) -            { -                case 0x8D: -                    ValidArea = false; -                    break; -                case 0x94: -                    ValidArea = false; -                    break; -                case 0x2CE: -                    ValidArea = false; -                    break; -                case 0x2CF: -                    ValidArea = false; -                    break; -                default: -                    if (dmgZone / 5 & 0x408) -                        ValidArea = true; -            } - -            // if is valid area and is not gamemaster then deal damage -            if ( ValidArea && !isGameMaster() ) +            // if not gamemaster then deal damage +            if ( !isGameMaster() )                  EnvironmentalDamage(guid, DAMAGE_LAVA, damage);              m_breathTimer = 1000;          } -      } -    //Death timer disabled and WaterFlags reset -    else if (m_deathState == DEAD) +    else if (m_deathState == DEAD)                          // Disable breath timer and reset underwater flags      {          m_breathTimer = 0;          m_isunderwater = 0; @@ -1316,6 +1346,7 @@ void Player::Update( uint32 p_time )      Pet* pet = GetPet();      if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && !pet->isPossessed()) +    //if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID())))      {          RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true);          return; @@ -1365,6 +1396,7 @@ void Player::setDeathState(DeathState s)          // passive spell          if(!ressSpellId)              ressSpellId = GetResurrectionSpellId(); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP, 1);      }      Unit::setDeathState(s); @@ -1385,13 +1417,15 @@ void Player::setDeathState(DeathState s)  void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )  { -    *p_data << GetGUID(); +    Field *fields = result->Fetch(); + +    *p_data << uint64(GetGUID());      *p_data << m_name; -    *p_data << getRace(); +    *p_data << uint8(getRace());      uint8 pClass = getClass(); -    *p_data << pClass; -    *p_data << getGender(); +    *p_data << uint8(pClass); +    *p_data << uint8(getGender());      uint32 bytes = GetUInt32Value(PLAYER_BYTES);      *p_data << uint8(bytes); @@ -1406,14 +1440,15 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )      // do not use GetMap! it will spawn a new instance since the bound instances are not loaded      uint32 zoneId = MapManager::Instance().GetZoneId(GetMapId(), GetPositionX(),GetPositionY());      sLog.outDebug("Player::BuildEnumData: m:%u, x:%f, y:%f, z:%f zone:%u", GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), zoneId); -    *p_data << zoneId; -    *p_data << GetMapId(); +    *p_data << uint32(zoneId); +    *p_data << uint32(GetMapId());      *p_data << GetPositionX();      *p_data << GetPositionY();      *p_data << GetPositionZ(); -    *p_data << (result ? result->Fetch()[13].GetUInt32() : 0); +    // guild id +    *p_data << (result ? fields[13].GetUInt32() : 0);      uint32 char_flags = 0;      if(HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_HIDE_HELM)) @@ -1424,14 +1459,13 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )          char_flags |= CHARACTER_FLAG_GHOST;      if(HasAtLoginFlag(AT_LOGIN_RENAME))          char_flags |= CHARACTER_FLAG_RENAME; -    // always send the flag if declined names aren't used -    // to let the client select a default method of declining the name -    if(!sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) || (result && result->Fetch()[14].GetCppString() != "")) +    if(sWorld.getConfig(CONFIG_DECLINED_NAMES_USED) && (fields[14].GetCppString() != ""))          char_flags |= CHARACTER_FLAG_DECLINED; -    *p_data << (uint32)char_flags;                          // character flags - -    *p_data << (uint8)1;                                    // unknown +    *p_data << uint32(char_flags);                          // character flags +    // character customize (flags?) +    *p_data << uint32(HasAtLoginFlag(AT_LOGIN_CUSTOMIZE) ? 1 : 0); +    *p_data << uint8(1);                                    // unknown      // Pets info      { @@ -1442,8 +1476,6 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )          // show pet at selection character in character list  only for non-ghost character          if(result && isAlive() && (pClass == CLASS_WARLOCK || pClass == CLASS_HUNTER))          { -            Field* fields = result->Fetch(); -              uint32 entry = fields[10].GetUInt32();              CreatureInfo const* cInfo = sCreatureStorage.LookupEntry<CreatureInfo>(entry);              if(cInfo) @@ -1454,36 +1486,11 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )              }          } -        *p_data << (uint32)petDisplayId; -        *p_data << (uint32)petLevel; -        *p_data << (uint32)petFamily; +        *p_data << uint32(petDisplayId); +        *p_data << uint32(petLevel); +        *p_data << uint32(petFamily);      } -    /*ItemPrototype const *items[EQUIPMENT_SLOT_END]; -    for (int i = 0; i < EQUIPMENT_SLOT_END; i++) -        items[i] = NULL; - -    QueryResult *result = CharacterDatabase.PQuery("SELECT slot,item_template FROM character_inventory WHERE guid = '%u' AND bag = 0",GetGUIDLow()); -    if (result) -    { -        do -        { -            Field *fields  = result->Fetch(); -            uint8  slot    = fields[0].GetUInt8() & 255; -            uint32 item_id = fields[1].GetUInt32(); -            if( slot >= EQUIPMENT_SLOT_END ) -                continue; - -            items[slot] = objmgr.GetItemPrototype(item_id); -            if(!items[slot]) -            { -                sLog.outError( "Player::BuildEnumData: Player %s have unknown item (id: #%u) in inventory, skipped.", GetName(),item_id ); -                continue; -            } -        } while (result->NextRow()); -        delete result; -    }*/ -      for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; slot++)      {          uint32 visualbase = PLAYER_VISIBLE_ITEM_1_0 + (slot * MAX_VISIBLE_ITEM_OFFSET); @@ -1500,20 +1507,20 @@ void Player::BuildEnumData( QueryResult * result, WorldPacket * p_data )          if (proto != NULL)          { -            *p_data << (uint32)proto->DisplayInfoID; -            *p_data << (uint8)proto->InventoryType; -            *p_data << (uint32)(enchant?enchant->aura_id:0); +            *p_data << uint32(proto->DisplayInfoID); +            *p_data << uint8(proto->InventoryType); +            *p_data << uint32(enchant ? enchant->aura_id : 0);          }          else          { -            *p_data << (uint32)0; -            *p_data << (uint8)0; -            *p_data << (uint32)0;                           // enchant? +            *p_data << uint32(0); +            *p_data << uint8(0); +            *p_data << uint32(0);                           // enchant?          }      } -    *p_data << (uint32)0;                                   // first bag display id -    *p_data << (uint8)0;                                    // first bag inventory type -    *p_data << (uint32)0;                                   // enchant? +    *p_data << uint32(0);                                   // first bag display id +    *p_data << uint8(0);                                    // first bag inventory type +    *p_data << uint32(0);                                   // enchant?  }  bool Player::ToggleAFK() @@ -1585,7 +1592,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati          if(GetTransport())              RepopAtGraveyard();                             // teleport to near graveyard if on transport, looks blizz like :) -        SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL1); +        SendTransferAborted(mapid, TRANSFER_ABORT_INSUF_EXPAN_LVL, mEntry->Expansion());          return false;                                       // normal client can't teleport to this map...      } @@ -1894,13 +1901,20 @@ void Player::RegenerateAll()      {          RegenerateHealth();          if (!isInCombat() && !HasAuraType(SPELL_AURA_INTERRUPT_REGEN)) +        {              Regenerate(POWER_RAGE); +            if(getClass() == CLASS_DEATH_KNIGHT) +                Regenerate(POWER_RUNIC_POWER); +        }      }      Regenerate( POWER_ENERGY );      Regenerate( POWER_MANA ); +    if(getClass() == CLASS_DEATH_KNIGHT) +        Regenerate( POWER_RUNE ); +      m_regenTimer = regenDelay;  } @@ -1920,11 +1934,11 @@ void Player::Regenerate(Powers power)              if (recentCast)              {                  // Trinity Updates Mana in intervals of 2s, which is correct -                addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT) *  ManaIncreaseRate * 2.00f; +                addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER) *  ManaIncreaseRate * 2.00f;              }              else              { -                addvalue = GetFloatValue(PLAYER_FIELD_MOD_MANA_REGEN) * ManaIncreaseRate * 2.00f; +                addvalue = GetFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER) * ManaIncreaseRate * 2.00f;              }          }   break;          case POWER_RAGE:                                    // Regenerate rage @@ -1935,6 +1949,17 @@ void Player::Regenerate(Powers power)          case POWER_ENERGY:                                  // Regenerate energy (rogue)              addvalue = 20;              break; +        case POWER_RUNIC_POWER: +        { +            float RunicPowerDecreaseRate = sWorld.getRate(RATE_POWER_RUNICPOWER_LOSS); +            addvalue = 30 * RunicPowerDecreaseRate;         // 3 RunicPower by tick +        }   break; +        case POWER_RUNE: +        { +            for(uint32 i = 0; i < MAX_RUNES; ++i) +                if(uint8 cd = GetRuneCooldown(i))           // if we have cooldown, reduce it... +                    SetRuneCooldown(i, cd - 1);             // ... by 2 sec (because update is every 2 sec) +        }   break;          case POWER_FOCUS:          case POWER_HAPPINESS:              break; @@ -1950,7 +1975,7 @@ void Player::Regenerate(Powers power)                  addvalue *= ((*i)->GetModifierValue() + 100) / 100.0f;      } -    if (power != POWER_RAGE) +    if (power != POWER_RAGE && power != POWER_RUNIC_POWER)      {          curValue += uint32(addvalue);          if (curValue > maxValue) @@ -2234,6 +2259,8 @@ void Player::GiveLevel(uint32 level)      data << uint32(0);      data << uint32(0);      data << uint32(0); +    data << uint32(0); +    data << uint32(0);      // end for      for(int i = STAT_STRENGTH; i < MAX_STATS; ++i)          // Stats loop (0-4)          data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i))); @@ -2257,6 +2284,7 @@ void Player::GiveLevel(uint32 level)      InitTalentForLevel();      InitTaxiNodesForLevel(); +    InitGlyphsForLevel();      UpdateAllStats(); @@ -2276,6 +2304,7 @@ void Player::GiveLevel(uint32 level)      Pet* pet = GetPet();      if(pet && pet->getPetType()==SUMMON_PET)          pet->GivePetLevel(level); +    GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);  }  void Player::InitTalentForLevel() @@ -2412,6 +2441,9 @@ void Player::InitStatsForLevel(bool reapplyMods)          SetFloatValue(UNIT_FIELD_POWER_COST_MODIFIER+i,0.0f);          SetFloatValue(UNIT_FIELD_POWER_COST_MULTIPLIER+i,0.0f);      } +    // Reset no reagent cost field +    for(int i = 0; i < 3; i++) +        SetUInt32Value(PLAYER_NO_REAGENT_COST_1 + i, 0);      // Init data for form but skip reapply item mods for form      InitDataForForm(reapplyMods); @@ -2428,7 +2460,7 @@ void Player::InitStatsForLevel(bool reapplyMods)      RemoveFlag( UNIT_FIELD_FLAGS,          UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_NOT_ATTACKABLE_1 |          UNIT_FLAG_PET_IN_COMBAT  | UNIT_FLAG_SILENCED     | UNIT_FLAG_PACIFIED         | -        UNIT_FLAG_DISABLE_ROTATE | UNIT_FLAG_IN_COMBAT    | UNIT_FLAG_DISARMED         | +        UNIT_FLAG_STUNNED        | UNIT_FLAG_IN_COMBAT    | UNIT_FLAG_DISARMED         |          UNIT_FLAG_CONFUSED       | UNIT_FLAG_FLEEING      | UNIT_FLAG_NOT_SELECTABLE   |          UNIT_FLAG_SKINNABLE      | UNIT_FLAG_MOUNT        | UNIT_FLAG_TAXI_FLIGHT      );      SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE );   // must be set @@ -2452,6 +2484,7 @@ void Player::InitStatsForLevel(bool reapplyMods)          SetPower(POWER_RAGE, GetMaxPower(POWER_RAGE));      SetPower(POWER_FOCUS, 0);      SetPower(POWER_HAPPINESS, 0); +    SetPower(POWER_RUNIC_POWER, 0);  }  void Player::SendInitialSpells() @@ -2866,8 +2899,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,                  continue;              if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || -                // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL -                pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 ||                  // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL                  pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 )              { @@ -2904,6 +2935,12 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool loading,          }      } +    if(!loading) +    { +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS); +    } +      // return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell      return active && !disabled && !superceded_old;  } @@ -3053,8 +3090,6 @@ void Player::removeSpell(uint32 spell_id, bool disabled)                  continue;              if(_spell_idx->second->learnOnGetSkill == ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL || -                // poison special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL -                pSkill->id==SKILL_POISONS && _spell_idx->second->max_value==0 ||                  // lockpicking special case, not have ABILITY_LEARNED_ON_GET_RACE_OR_CLASS_SKILL                  pSkill->id==SKILL_LOCKPICKING && _spell_idx->second->max_value==0 )              { @@ -3354,50 +3389,46 @@ void Player::InitVisibleBits()  {      updateVisualBits.SetCount(PLAYER_END); -    // TODO: really implement OWNER_ONLY and GROUP_ONLY. Flags can be found in UpdateFields.h -      updateVisualBits.SetBit(OBJECT_FIELD_GUID);      updateVisualBits.SetBit(OBJECT_FIELD_TYPE); +    updateVisualBits.SetBit(OBJECT_FIELD_ENTRY);      updateVisualBits.SetBit(OBJECT_FIELD_SCALE_X); - -    updateVisualBits.SetBit(UNIT_FIELD_CHARM); -    updateVisualBits.SetBit(UNIT_FIELD_CHARM+1); - -    updateVisualBits.SetBit(UNIT_FIELD_SUMMON); -    updateVisualBits.SetBit(UNIT_FIELD_SUMMON+1); - -    updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY); -    updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY+1); - -    updateVisualBits.SetBit(UNIT_FIELD_TARGET); -    updateVisualBits.SetBit(UNIT_FIELD_TARGET+1); - -    updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT); -    updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT+1); - +    updateVisualBits.SetBit(UNIT_FIELD_CHARM + 0); +    updateVisualBits.SetBit(UNIT_FIELD_CHARM + 1); +    updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 0); +    updateVisualBits.SetBit(UNIT_FIELD_SUMMON + 1); +    updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 0); +    updateVisualBits.SetBit(UNIT_FIELD_CHARMEDBY + 1); +    updateVisualBits.SetBit(UNIT_FIELD_TARGET + 0); +    updateVisualBits.SetBit(UNIT_FIELD_TARGET + 1); +    updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 0); +    updateVisualBits.SetBit(UNIT_FIELD_CHANNEL_OBJECT + 1); +    updateVisualBits.SetBit(UNIT_FIELD_BYTES_0);      updateVisualBits.SetBit(UNIT_FIELD_HEALTH);      updateVisualBits.SetBit(UNIT_FIELD_POWER1);      updateVisualBits.SetBit(UNIT_FIELD_POWER2);      updateVisualBits.SetBit(UNIT_FIELD_POWER3);      updateVisualBits.SetBit(UNIT_FIELD_POWER4);      updateVisualBits.SetBit(UNIT_FIELD_POWER5); - +    updateVisualBits.SetBit(UNIT_FIELD_POWER6); +    updateVisualBits.SetBit(UNIT_FIELD_POWER7);      updateVisualBits.SetBit(UNIT_FIELD_MAXHEALTH);      updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER1);      updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER2);      updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER3);      updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER4);      updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER5); - +    updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER6); +    updateVisualBits.SetBit(UNIT_FIELD_MAXPOWER7);      updateVisualBits.SetBit(UNIT_FIELD_LEVEL);      updateVisualBits.SetBit(UNIT_FIELD_FACTIONTEMPLATE); -    updateVisualBits.SetBit(UNIT_FIELD_BYTES_0); +    updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 0); +    updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 1); +    updateVisualBits.SetBit(UNIT_VIRTUAL_ITEM_SLOT_ID + 2);      updateVisualBits.SetBit(UNIT_FIELD_FLAGS);      updateVisualBits.SetBit(UNIT_FIELD_FLAGS_2); -    for(uint16 i = UNIT_FIELD_AURA; i < UNIT_FIELD_AURASTATE; ++i) -        updateVisualBits.SetBit(i);      updateVisualBits.SetBit(UNIT_FIELD_AURASTATE); -    updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME); +    updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 0);      updateVisualBits.SetBit(UNIT_FIELD_BASEATTACKTIME + 1);      updateVisualBits.SetBit(UNIT_FIELD_BOUNDINGRADIUS);      updateVisualBits.SetBit(UNIT_FIELD_COMBATREACH); @@ -3410,10 +3441,12 @@ void Player::InitVisibleBits()      updateVisualBits.SetBit(UNIT_DYNAMIC_FLAGS);      updateVisualBits.SetBit(UNIT_CHANNEL_SPELL);      updateVisualBits.SetBit(UNIT_MOD_CAST_SPEED); +    updateVisualBits.SetBit(UNIT_FIELD_BASE_MANA);      updateVisualBits.SetBit(UNIT_FIELD_BYTES_2); +    updateVisualBits.SetBit(UNIT_FIELD_HOVERHEIGHT); -    updateVisualBits.SetBit(PLAYER_DUEL_ARBITER); -    updateVisualBits.SetBit(PLAYER_DUEL_ARBITER+1); +    updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 0); +    updateVisualBits.SetBit(PLAYER_DUEL_ARBITER + 1);      updateVisualBits.SetBit(PLAYER_FLAGS);      updateVisualBits.SetBit(PLAYER_GUILDID);      updateVisualBits.SetBit(PLAYER_GUILDRANK); @@ -3424,29 +3457,29 @@ void Player::InitVisibleBits()      updateVisualBits.SetBit(PLAYER_GUILD_TIMESTAMP);      // PLAYER_QUEST_LOG_x also visible bit on official (but only on party/raid)... -    for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i+=4) +    for(uint16 i = PLAYER_QUEST_LOG_1_1; i < PLAYER_QUEST_LOG_25_2; i += 4)          updateVisualBits.SetBit(i); -    //Players visible items are not inventory stuff -    //431) = 884 (0x374) = main weapon -    for(uint16 i = 0; i < EQUIPMENT_SLOT_END; i++) +    // Players visible items are not inventory stuff +    for(uint16 i = 0; i < EQUIPMENT_SLOT_END; ++i)      { -        // item creator -        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 0); -        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + (i*MAX_VISIBLE_ITEM_OFFSET) + 1); +        uint32 offset = i * MAX_VISIBLE_ITEM_OFFSET; -        uint16 visual_base = PLAYER_VISIBLE_ITEM_1_0 + (i*MAX_VISIBLE_ITEM_OFFSET); +        // item creator +        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 0 + offset); +        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_CREATOR + 1 + offset);          // item entry -        updateVisualBits.SetBit(visual_base + 0); +        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 0 + offset); -        // item enchantment IDs -        for(uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) -            updateVisualBits.SetBit(visual_base + 1 + j); +        // item enchantments +        for(uint8 j = 0; j < MAX_ENCHANTMENT_SLOT; ++j) +            updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_0 + 1 + j + offset);          // random properties -        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 0 + (i*MAX_VISIBLE_ITEM_OFFSET)); -        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + 1 + (i*MAX_VISIBLE_ITEM_OFFSET)); +        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PROPERTIES + offset); +        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_SEED + offset); +        updateVisualBits.SetBit(PLAYER_VISIBLE_ITEM_1_PAD + offset);      }      updateVisualBits.SetBit(PLAYER_CHOSEN_TITLE); @@ -3464,7 +3497,6 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )      if(target == this)      { -          for(int i = INVENTORY_SLOT_BAG_START; i < BANK_SLOT_BAG_END; i++)          {              if(m_items[i] == NULL) @@ -3472,7 +3504,7 @@ void Player::BuildCreateUpdateBlockForPlayer( UpdateData *data, Player *target )              m_items[i]->BuildCreateUpdateBlockForPlayer( data, target );          } -        for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +        for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)          {              if(m_items[i] == NULL)                  continue; @@ -3505,7 +3537,7 @@ void Player::DestroyForPlayer( Player *target ) const              m_items[i]->DestroyForPlayer( target );          } -        for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +        for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)          {              if(m_items[i] == NULL)                  continue; @@ -3593,27 +3625,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC      }      // remove from arena teams -    uint32 at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_2v2); -    if(at_id != 0) -    { -        ArenaTeam * at = objmgr.GetArenaTeamById(at_id); -        if(at) -            at->DelMember(playerguid); -    } -    at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_3v3); -    if(at_id != 0) -    { -        ArenaTeam * at = objmgr.GetArenaTeamById(at_id); -        if(at) -            at->DelMember(playerguid); -    } -    at_id = GetArenaTeamIdFromDB(playerguid,ARENA_TEAM_5v5); -    if(at_id != 0) -    { -        ArenaTeam * at = objmgr.GetArenaTeamById(at_id); -        if(at) -            at->DelMember(playerguid); -    } +    LeaveAllArenaTeams(playerguid);      // the player was uninvited already on logout so just remove from group      QueryResult *resultGroup = CharacterDatabase.PQuery("SELECT leaderGuid FROM group_member WHERE memberGuid='%u'", guid); @@ -3654,15 +3666,16 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC              MailItemsInfo mi;              if(has_items)              { -                QueryResult *resultItems = CharacterDatabase.PQuery("SELECT item_guid,item_template FROM mail_items WHERE mail_id='%u'", mail_id); +                // data needs to be at first place for Item::LoadFromDB +                QueryResult *resultItems = CharacterDatabase.PQuery("SELECT data,item_guid,item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id='%u'", mail_id);                  if(resultItems)                  {                      do                      {                          Field *fields2 = resultItems->Fetch(); -                        uint32 item_guidlow = fields2[0].GetUInt32(); -                        uint32 item_template = fields2[1].GetUInt32(); +                        uint32 item_guidlow = fields2[1].GetUInt32(); +                        uint32 item_template = fields2[2].GetUInt32();                          ItemPrototype const* itemProto = objmgr.GetItemPrototype(item_template);                          if(!itemProto) @@ -3672,7 +3685,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC                          }                          Item *pItem = NewItemOrBag(itemProto); -                        if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER))) +                        if(!pItem->LoadFromDB(item_guidlow, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER),resultItems))                          {                              pItem->FSetState(ITEM_REMOVED);                              pItem->SaveToDB();              // it also deletes item object ! @@ -3735,6 +3748,8 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC      CharacterDatabase.PExecute("DELETE FROM mail_items WHERE receiver = '%u'",guid);      CharacterDatabase.PExecute("DELETE FROM character_pet WHERE owner = '%u'",guid);      CharacterDatabase.PExecute("DELETE FROM character_pet_declinedname WHERE owner = '%u'",guid); +    CharacterDatabase.PExecute("DELETE FROM character_achievement WHERE guid = '%u'",guid); +    CharacterDatabase.PExecute("DELETE FROM character_achievement_progress WHERE guid = '%u'",guid);      CharacterDatabase.CommitTransaction();      //loginDatabase.PExecute("UPDATE realmcharacters SET numchars = numchars - 1 WHERE acctid = %d AND realmid = %d", accountId, realmID); @@ -3765,6 +3780,10 @@ void Player::SetMovement(PlayerMovementType pType)  */  void Player::BuildPlayerRepop()  { +    WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size()); +    data.append(GetPackGUID()); +    GetSession()->SendPacket(&data); +      if(getRace() == RACE_NIGHTELF)          CastSpell(this, 20584, true);                       // auras SPELL_AURA_INCREASE_SPEED(+speed in wisp form), SPELL_AURA_INCREASE_SWIM_SPEED(+swim speed in wisp form), SPELL_AURA_TRANSFORM (to wisp form)      CastSpell(this, 8326, true);                            // auras SPELL_AURA_GHOST, SPELL_AURA_INCREASE_SPEED(why?), SPELL_AURA_INCREASE_SWIM_SPEED(why?) @@ -3885,7 +3904,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness)                  if(Aura* Aur = GetAura(SPELL_ID_PASSIVE_RESURRECTION_SICKNESS,i))                  {                      Aur->SetAuraDuration(delta*1000); -                    Aur->UpdateAuraDuration(); +                    Aur->SendAuraUpdate(false);                  }              }          } @@ -4422,7 +4441,7 @@ uint32 Player::GetShieldBlockValue() const  {      BaseModGroup modGroup = SHIELD_BLOCK_VALUE; -    float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH)/20 - 1; +    float value = GetTotalBaseModValue(modGroup) + GetStat(STAT_STRENGTH) * 0.5f - 10;      value = (value < 0) ? 0 : value; @@ -4611,7 +4630,18 @@ float Player::OCTRegenMPPerSpirit()  void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)  { -    ApplyModUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, value, apply); +    m_baseRatingValue[cr]+=(apply ? value : -value); +     +    int32 amount = uint32(m_baseRatingValue[cr]); +    // Apply bonus from SPELL_AURA_MOD_RATING_FROM_STAT +    // stat used stored in miscValueB for this aura +    AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT); +    for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i) +        if ((*i)->GetMiscValue() & (1<<cr)) +            amount += GetStat(Stats((*i)->GetMiscBValue())) * (*i)->GetModifier()->m_amount / 100.0f; +    if (amount < 0) +        amount = 0; +    SetUInt32Value(PLAYER_FIELD_COMBAT_RATING_1 + cr, uint32(amount));      float RatingCoeffecient = GetRatingCoefficient(cr);      float RatingChange = 0.0f; @@ -4634,16 +4664,13 @@ void Player::ApplyRatingMod(CombatRating cr, int32 value, bool apply)              UpdateBlockPercentage();              break;          case CR_HIT_MELEE: -            RatingChange = value / RatingCoeffecient; -            m_modMeleeHitChance += apply ? RatingChange : -RatingChange; +            UpdateMeleeHitChances();              break;          case CR_HIT_RANGED: -            RatingChange = value / RatingCoeffecient; -            m_modRangedHitChance += apply ? RatingChange : -RatingChange; +            UpdateRangedHitChances();              break;          case CR_HIT_SPELL: -            RatingChange = value / RatingCoeffecient; -            m_modSpellHitChance += apply ? RatingChange : -RatingChange; +            UpdateSpellHitChances();              break;          case CR_CRIT_MELEE:              if(affectStats) @@ -4741,6 +4768,7 @@ bool Player::UpdateSkill(uint32 skill_id, uint32 step)              new_value = max;          SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,max)); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);          return true;      } @@ -4803,6 +4831,7 @@ bool Player::UpdateGatherSkill(uint32 SkillId, uint32 SkillValue, uint32 RedLeve          case SKILL_HERBALISM:          case SKILL_LOCKPICKING:          case SKILL_JEWELCRAFTING: +        case SKILL_INSCRIPTION:              return UpdateSkillPro(SkillId, SkillGainChance(SkillValue, RedLevel+100, RedLevel+50, RedLevel+25)*Multiplicator,gathering_skill_gain);          case SKILL_SKINNING:              if( sWorld.getConfig(CONFIG_SKILL_CHANCE_SKINNING_STEPS)==0) @@ -4865,6 +4894,7 @@ bool Player::UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step)              new_value = MaxValue;          SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(new_value,MaxValue)); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);          sLog.outDebug("Player::UpdateSkillPro Chance=%3.1f%% taken", Chance/10.0);          return true;      } @@ -5052,7 +5082,10 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)      if(i<PLAYER_MAX_SKILLS)                                 //has skill      {          if(currVal) +        {              SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal)); +            GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL); +        }          else                                                //remove          {              // clear skill fields @@ -5100,6 +5133,7 @@ void Player::SetSkill(uint32 id, uint16 currVal, uint16 maxVal)              else                  SetUInt32Value(PLAYER_SKILL_INDEX(i), MAKE_PAIR32(id,0));              SetUInt32Value(PLAYER_SKILL_VALUE_INDEX(i),MAKE_SKILL_VALUE(currVal,maxVal)); +            GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL);              // apply skill bonuses              SetUInt32Value(PLAYER_SKILL_BONUS_INDEX(i),0); @@ -5414,6 +5448,8 @@ void Player::CheckExploreSystem()      {          SetUInt32Value(PLAYER_EXPLORED_ZONES_1 + offset, (uint32)(currFields | val)); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA); +          AreaTableEntry const *p = GetAreaEntryByAreaFlagAndMap(areaFlag,GetMapId());          if(!p)          { @@ -5510,6 +5546,7 @@ void Player::SendFactionState(FactionState const* faction) const      {          WorldPacket data(SMSG_SET_FACTION_STANDING, (16));  // last check 2.4.0          data << (float) 0;                                  // unk 2.4.0 +        data << (uint8) 0;                                  // wotlk 8634          data << (uint32) 1;                                 // count          // for          data << (uint32) faction->ReputationListID; @@ -5841,7 +5878,8 @@ bool Player::ModifyOneFactionReputation(FactionEntry const* factionEntry, int32                  }              }          } - +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION);          SendFactionState(&(itr->second));          return true; @@ -5907,6 +5945,8 @@ bool Player::SetOneFactionReputation(FactionEntry const* factionEntry, int32 sta              SetFactionAtWar(&itr->second,true);          SendFactionState(&(itr->second)); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION);          return true;      }      return false; @@ -6234,24 +6274,18 @@ void Player::ModifyArenaPoints( int32 value )  uint32 Player::GetGuildIdFromDB(uint64 guid)  { -    std::ostringstream ss; -    ss<<"SELECT guildid FROM guild_member WHERE guid='"<<guid<<"'"; -    QueryResult *result = CharacterDatabase.Query( ss.str().c_str() ); -    if( result ) -    { -        uint32 v = result->Fetch()[0].GetUInt32(); -        delete result; -        return v; -    } -    else +    QueryResult* result = CharacterDatabase.PQuery("SELECT guildid FROM guild_member WHERE guid='%u'", GUID_LOPART(guid)); +    if(!result)          return 0; + +    uint32 id = result->Fetch()[0].GetUInt32(); +    delete result; +    return id;  }  uint32 Player::GetRankFromDB(uint64 guid)  { -    std::ostringstream ss; -    ss<<"SELECT rank FROM guild_member WHERE guid='"<<guid<<"'"; -    QueryResult *result = CharacterDatabase.Query( ss.str().c_str() ); +    QueryResult *result = CharacterDatabase.PQuery( "SELECT rank FROM guild_member WHERE guid='%u'", GUID_LOPART(guid) );      if( result )      {          uint32 v = result->Fetch()[0].GetUInt32(); @@ -6275,10 +6309,8 @@ uint32 Player::GetArenaTeamIdFromDB(uint64 guid, uint8 type)  uint32 Player::GetZoneIdFromDB(uint64 guid)  { -    std::ostringstream ss; - -    ss<<"SELECT zone FROM characters WHERE guid='"<<GUID_LOPART(guid)<<"'"; -    QueryResult *result = CharacterDatabase.Query( ss.str().c_str() ); +    uint32 guidLow = GUID_LOPART(guid); +    QueryResult *result = CharacterDatabase.PQuery( "SELECT zone FROM characters WHERE guid='%u'", guidLow );      if (!result)          return 0;      Field* fields = result->Fetch(); @@ -6288,22 +6320,18 @@ uint32 Player::GetZoneIdFromDB(uint64 guid)      if (!zone)      {          // stored zone is zero, use generic and slow zone detection -        ss.str(""); -        ss<<"SELECT map,position_x,position_y FROM characters WHERE guid='"<<GUID_LOPART(guid)<<"'"; -        result = CharacterDatabase.Query(ss.str().c_str()); +        result = CharacterDatabase.PQuery("SELECT map,position_x,position_y FROM characters WHERE guid='%u'", guidLow);          if( !result )              return 0;          fields = result->Fetch(); -        uint32 map  = fields[0].GetUInt32(); +        uint32 map = fields[0].GetUInt32();          float posx = fields[1].GetFloat();          float posy = fields[2].GetFloat();          delete result;          zone = MapManager::Instance().GetZoneId(map,posx,posy); -        ss.str(""); -        ss << "UPDATE characters SET zone='"<<zone<<"' WHERE guid='"<<GUID_LOPART(guid)<<"'"; -        CharacterDatabase.Execute(ss.str().c_str()); +        CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow);      }      return zone; @@ -6389,13 +6417,13 @@ void Player::UpdateZone(uint32 newZone)      if(zone->flags & AREA_FLAG_SANCTUARY)                   // in sanctuary      { -        SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY); +        SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);          if(sWorld.IsFFAPvPRealm())              RemoveFlag(PLAYER_FLAGS,PLAYER_FLAGS_FFA_PVP);      }      else      { -        RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY); +        RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);      }      if(zone->flags & AREA_FLAG_CAPITAL)                     // in capital city @@ -6617,19 +6645,43 @@ void Player::_ApplyItemMods(Item *item, uint8 slot,bool apply)      sLog.outDebug("_ApplyItemMods complete.");  } -void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply) +void Player::_ApplyItemBonuses(ItemPrototype const *proto, uint8 slot, bool apply)  {      if(slot >= INVENTORY_SLOT_BAG_END || !proto)          return;      for (int i = 0; i < 10; i++)      { -        float val = float (proto->ItemStat[i].ItemStatValue); +        uint32 statType = 0; +        int32 val = 0; + +        if(proto->ScalingStatDistribution) +        { +            if(ScalingStatDistributionEntry const *ssd = sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution)) +            { +                statType = ssd->StatMod[i]; + +                if(uint32 modifier = ssd->Modifier[i]) +                { +                    uint32 level = ((getLevel() > ssd->MaxLevel) ? ssd->MaxLevel : getLevel()); +                    if(ScalingStatValuesEntry const *ssv = sScalingStatValuesStore.LookupEntry(level)) +                    { +                        int multiplier = ssv->Multiplier[proto->GetScalingStatValuesColumn()]; +                        val = (multiplier * modifier) / 10000; +                    } +                } +            } +        } +        else +        { +            statType = proto->ItemStat[i].ItemStatType; +            val = float(proto->ItemStat[i].ItemStatValue); +        } -        if(val==0) +        if(val == 0)              continue; -        switch (proto->ItemStat[i].ItemStatType) +        switch (statType)          {              case ITEM_MOD_MANA:                  HandleStatModifier(UNIT_MOD_MANA, BASE_VALUE, float(val), apply); @@ -6747,6 +6799,9 @@ void Player::_ApplyItemBonuses(ItemPrototype const *proto,uint8 slot,bool apply)              case ITEM_MOD_EXPERTISE_RATING:                  ApplyRatingMod(CR_EXPERTISE, int32(val), apply);                  break; +            case ITEM_MOD_ARMOR_PENETRATION_RATING: +                ApplyRatingMod(CR_ARMOR_PENETRATION, int32(val), apply); +                break;          }      } @@ -7362,6 +7417,17 @@ void Player::SendLoot(uint64 guid, LootType loot_type)                  loot->FillLoot(item->GetEntry(), LootTemplates_Prospecting, this);              }          } +        else if(loot_type == LOOT_MILLING) +        { +            loot = &item->loot; + +            if(!item->m_lootGenerated) +            { +                item->m_lootGenerated = true; +                loot->clear(); +                loot->FillLoot(item->GetEntry(), LootTemplates_Milling, this); +            } +        }          else          {              loot = &item->loot; @@ -7557,8 +7623,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type)              conditional_list = itr->second;      } -    // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING and LOOT_INSIGNIA unsupported by client, sending LOOT_SKINNING instead -    if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA) +    // LOOT_PICKPOCKETING, LOOT_PROSPECTING, LOOT_DISENCHANTING, LOOT_INSIGNIA and LOOT_MILLING unsupported by client, sending LOOT_SKINNING instead +    if(loot_type == LOOT_PICKPOCKETING || loot_type == LOOT_DISENCHANTING || loot_type == LOOT_PROSPECTING || loot_type == LOOT_INSIGNIA || loot_type == LOOT_MILLING)          loot_type = LOOT_SKINNING;      if(loot_type == LOOT_FISHINGHOLE) @@ -8282,7 +8348,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap              // (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ...              if(CanDualWield())                  slots[1] = EQUIPMENT_SLOT_OFFHAND; -        };break; +            break; +        };          case INVTYPE_SHIELD:              slots[0] = EQUIPMENT_SLOT_OFFHAND;              break; @@ -8291,6 +8358,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap              break;          case INVTYPE_2HWEAPON:              slots[0] = EQUIPMENT_SLOT_MAINHAND; +            if (CanDualWield() && CanTitanGrip()) +                slots[1] = EQUIPMENT_SLOT_OFFHAND;              break;          case INVTYPE_TABARD:              slots[0] = EQUIPMENT_SLOT_TABARD; @@ -8336,6 +8405,10 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap                      if (pClass == CLASS_WARLOCK)                          slots[0] = EQUIPMENT_SLOT_RANGED;                      break; +                case ITEM_SUBCLASS_ARMOR_SIGIL: +                    if (pClass == CLASS_DEATH_KNIGHT) +                        slots[0] = EQUIPMENT_SLOT_RANGED; +                    break;              }              break;          } @@ -8361,14 +8434,8 @@ uint8 Player::FindEquipSlot( ItemPrototype const* proto, uint32 slot, bool swap          {              if ( slots[i] != NULL_SLOT && !GetItemByPos( INVENTORY_SLOT_BAG_0, slots[i] ) )              { -                // in case 2hand equipped weapon offhand slot empty but not free -                if(slots[i]==EQUIPMENT_SLOT_OFFHAND) -                { -                    Item* mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); -                    if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) -                        return slots[i]; -                } -                else +                // in case 2hand equipped weapon (without titan grip) offhand slot empty but not free +                if(slots[i]!=EQUIPMENT_SLOT_OFFHAND || !IsTwoHandUsed())                      return slots[i];              }          } @@ -8418,7 +8485,7 @@ uint8 Player::CanUnequipItems( uint32 item, uint32 count ) const                  return EQUIP_ERR_OK;          }      } -    for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +    for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)      {          pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && pItem->GetEntry() == item ) @@ -8460,7 +8527,7 @@ uint32 Player::GetItemCount( uint32 item, bool inBankAlso, Item* skipItem ) cons          if( pItem && pItem != skipItem &&  pItem->GetEntry() == item )              count += pItem->GetCount();      } -    for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +    for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)      {          Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && pItem != skipItem && pItem->GetEntry() == item ) @@ -8520,7 +8587,7 @@ Item* Player::GetItemByGuid( uint64 guid ) const          if( pItem && pItem->GetGUID() == guid )              return pItem;      } -    for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +    for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)      {          Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && pItem->GetGUID() == guid ) @@ -8566,7 +8633,7 @@ Item* Player::GetItemByPos( uint16 pos ) const  Item* Player::GetItemByPos( uint8 bag, uint8 slot ) const  { -    if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) +    if( bag == INVENTORY_SLOT_BAG_0 && ( slot < BANK_SLOT_BAG_END || slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) )          return m_items[slot];      else if(bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END          || bag >= BANK_SLOT_BAG_START && bag < BANK_SLOT_BAG_END ) @@ -8644,7 +8711,7 @@ bool Player::IsInventoryPos( uint8 bag, uint8 slot )          return true;      if( bag >= INVENTORY_SLOT_BAG_START && bag < INVENTORY_SLOT_BAG_END )          return true; -    if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_END ) ) +    if( bag == INVENTORY_SLOT_BAG_0 && ( slot >= KEYRING_SLOT_START && slot < QUESTBAG_SLOT_END ) )          return true;      return false;  } @@ -8765,7 +8832,7 @@ bool Player::HasItemCount( uint32 item, uint32 count, bool inBankAlso ) const                  return true;          }      } -    for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +    for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)      {          Item *pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && pItem->GetEntry() == item ) @@ -8887,7 +8954,7 @@ bool Player::HasItemTotemCategory( uint32 TotemCategory ) const          if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory ))              return true;      } -    for(uint8 i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; ++i) +    for(uint8 i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; ++i)      {          pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && IsTotemCategoryCompatiableWith(pItem->GetProto()->TotemCategory,TotemCategory )) @@ -8927,6 +8994,18 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV              if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS))                  return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; +            // vanitypet case +            if(slot >= VANITYPET_SLOT_START && slot < VANITYPET_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS)) +                return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + +            // currencytoken case +            if(slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)) +                return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + +            // guestbag case +            if(slot >= QUESTBAG_SLOT_START && slot < QUESTBAG_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS)) +                return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; +              // prevent cheating              if(slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END)                  return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; @@ -9171,7 +9250,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3          {              if( bag == INVENTORY_SLOT_BAG_0 )               // inventory              { -                res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); +                res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot);                  if(res!=EQUIP_ERR_OK)                  {                      if(no_space_count) @@ -9258,6 +9337,66 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3                      return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;                  }              } +            else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) +            { +                res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot); +                if(res!=EQUIP_ERR_OK) +                { +                    if(no_space_count) +                        *no_space_count = count + no_similar_count; +                    return res; +                } + +                if(count==0) +                { +                    if(no_similar_count==0) +                        return EQUIP_ERR_OK; + +                    if(no_space_count) +                        *no_space_count = count + no_similar_count; +                    return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; +                } +            } +            else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +            { +                res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); +                if(res!=EQUIP_ERR_OK) +                { +                    if(no_space_count) +                        *no_space_count = count + no_similar_count; +                    return res; +                } + +                if(count==0) +                { +                    if(no_similar_count==0) +                        return EQUIP_ERR_OK; + +                    if(no_space_count) +                        *no_space_count = count + no_similar_count; +                    return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; +                } +            } +            else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) +            { +                res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot); +                if(res!=EQUIP_ERR_OK) +                { +                    if(no_space_count) +                        *no_space_count = count + no_similar_count; +                    return res; +                } + +                if(count==0) +                { +                    if(no_similar_count==0) +                        return EQUIP_ERR_OK; + +                    if(no_space_count) +                        *no_space_count = count + no_similar_count; +                    return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; +                } +            }              res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot);              if(res!=EQUIP_ERR_OK) @@ -9307,7 +9446,7 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3      // search stack for merge to      if( pProto->Stackable > 1 )      { -        res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_END,dest,pProto,count,true,pItem,bag,slot); +        res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,true,pItem,bag,slot);          if(res!=EQUIP_ERR_OK)          {              if(no_space_count) @@ -9405,6 +9544,66 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3                  return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS;              }          } +        else if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) +        { +            res = _CanStoreItem_InInventorySlots(VANITYPET_SLOT_START,VANITYPET_SLOT_END,dest,pProto,count,false,pItem,bag,slot); +            if(res!=EQUIP_ERR_OK) +            { +                if(no_space_count) +                    *no_space_count = count + no_similar_count; +                return res; +            } + +            if(count==0) +            { +                if(no_similar_count==0) +                    return EQUIP_ERR_OK; + +                if(no_space_count) +                    *no_space_count = count + no_similar_count; +                return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; +            } +        } +        else if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +        { +            res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); +            if(res!=EQUIP_ERR_OK) +            { +                if(no_space_count) +                    *no_space_count = count + no_similar_count; +                return res; +            } + +            if(count==0) +            { +                if(no_similar_count==0) +                    return EQUIP_ERR_OK; + +                if(no_space_count) +                    *no_space_count = count + no_similar_count; +                return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; +            } +        } +        else if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) +        { +            res = _CanStoreItem_InInventorySlots(QUESTBAG_SLOT_START,QUESTBAG_SLOT_END,dest,pProto,count,false,pItem,bag,slot); +            if(res!=EQUIP_ERR_OK) +            { +                if(no_space_count) +                    *no_space_count = count + no_similar_count; +                return res; +            } + +            if(count==0) +            { +                if(no_similar_count==0) +                    return EQUIP_ERR_OK; + +                if(no_space_count) +                    *no_space_count = count + no_similar_count; +                return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; +            } +        }          for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)          { @@ -9475,10 +9674,16 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const      int inv_slot_items[INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START];      int inv_bags[INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START][MAX_BAG_SIZE];      int inv_keys[KEYRING_SLOT_END-KEYRING_SLOT_START]; +    int inv_pets[VANITYPET_SLOT_END-VANITYPET_SLOT_START]; +    int inv_tokens[CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START]; +    int inv_quests[QUESTBAG_SLOT_END-QUESTBAG_SLOT_START];      memset(inv_slot_items,0,sizeof(int)*(INVENTORY_SLOT_ITEM_END-INVENTORY_SLOT_ITEM_START));      memset(inv_bags,0,sizeof(int)*(INVENTORY_SLOT_BAG_END-INVENTORY_SLOT_BAG_START)*MAX_BAG_SIZE);      memset(inv_keys,0,sizeof(int)*(KEYRING_SLOT_END-KEYRING_SLOT_START)); +    memset(inv_pets,0,sizeof(int)*(VANITYPET_SLOT_END-VANITYPET_SLOT_START)); +    memset(inv_tokens,0,sizeof(int)*(CURRENCYTOKEN_SLOT_END-CURRENCYTOKEN_SLOT_START)); +    memset(inv_quests,0,sizeof(int)*(QUESTBAG_SLOT_END-QUESTBAG_SLOT_START));      for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++)      { @@ -9500,6 +9705,36 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const          }      } +    for(int i = VANITYPET_SLOT_START; i < VANITYPET_SLOT_END; i++) +    { +        pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + +        if (pItem2 && !pItem2->IsInTrade()) +        { +            inv_pets[i-VANITYPET_SLOT_START] = pItem2->GetCount(); +        } +    } + +    for(int i = CURRENCYTOKEN_SLOT_START; i < CURRENCYTOKEN_SLOT_END; i++) +    { +        pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + +        if (pItem2 && !pItem2->IsInTrade()) +        { +            inv_tokens[i-CURRENCYTOKEN_SLOT_START] = pItem2->GetCount(); +        } +    } + +    for(int i = QUESTBAG_SLOT_START; i < QUESTBAG_SLOT_END; i++) +    { +        pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, i ); + +        if (pItem2 && !pItem2->IsInTrade()) +        { +            inv_quests[i-QUESTBAG_SLOT_START] = pItem2->GetCount(); +        } +    } +      for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++)      {          if(Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, i )) @@ -9559,6 +9794,42 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const              }              if (b_found) continue; +            for(int t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; t++) +            { +                pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); +                if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_pets[t-VANITYPET_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) +                { +                    inv_pets[t-VANITYPET_SLOT_START] += pItem->GetCount(); +                    b_found = true; +                    break; +                } +            } +            if (b_found) continue; + +            for(int t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; t++) +            { +                pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); +                if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_tokens[t-CURRENCYTOKEN_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) +                { +                    inv_tokens[t-CURRENCYTOKEN_SLOT_START] += pItem->GetCount(); +                    b_found = true; +                    break; +                } +            } +            if (b_found) continue; + +            for(int t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; t++) +            { +                pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); +                if( pItem2 && pItem2->GetEntry() == pItem->GetEntry() && inv_quests[t-QUESTBAG_SLOT_START] + pItem->GetCount() <= pProto->Stackable ) +                { +                    inv_quests[t-QUESTBAG_SLOT_START] += pItem->GetCount(); +                    b_found = true; +                    break; +                } +            } +            if (b_found) continue; +              for(int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; t++)              {                  pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, t ); @@ -9611,6 +9882,51 @@ uint8 Player::CanStoreItems( Item **pItems,int count) const              if (b_found) continue; +            if(pProto->BagFamily & BAG_FAMILY_MASK_VANITY_PETS) +            { +                for(uint32 t = VANITYPET_SLOT_START; t < VANITYPET_SLOT_END; ++t) +                { +                    if( inv_pets[t-VANITYPET_SLOT_START] == 0 ) +                    { +                        inv_pets[t-VANITYPET_SLOT_START] = 1; +                        b_found = true; +                        break; +                    } +                } +            } + +            if (b_found) continue; + +            if(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS) +            { +                for(uint32 t = CURRENCYTOKEN_SLOT_START; t < CURRENCYTOKEN_SLOT_END; ++t) +                { +                    if( inv_tokens[t-CURRENCYTOKEN_SLOT_START] == 0 ) +                    { +                        inv_tokens[t-CURRENCYTOKEN_SLOT_START] = 1; +                        b_found = true; +                        break; +                    } +                } +            } + +            if (b_found) continue; + +            if(pProto->BagFamily & BAG_FAMILY_MASK_QUEST_ITEMS) +            { +                for(uint32 t = QUESTBAG_SLOT_START; t < QUESTBAG_SLOT_END; ++t) +                { +                    if( inv_quests[t-QUESTBAG_SLOT_START] == 0 ) +                    { +                        inv_quests[t-QUESTBAG_SLOT_START] = 1; +                        b_found = true; +                        break; +                    } +                } +            } + +            if (b_found) continue; +              for(int t = INVENTORY_SLOT_BAG_START; !b_found && t < INVENTORY_SLOT_BAG_END; t++)              {                  pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, t ); @@ -9796,33 +10112,42 @@ uint8 Player::CanEquipItem( uint8 slot, uint16 &dest, Item *pItem, bool swap, bo              if(eslot == EQUIPMENT_SLOT_OFFHAND)              { -                if( type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND ) +                if (type == INVTYPE_WEAPON || type == INVTYPE_WEAPONOFFHAND)                  {                      if(!CanDualWield())                          return EQUIP_ERR_CANT_DUAL_WIELD;                  } - -                Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); -                if(mainItem) +                else if (type == INVTYPE_2HWEAPON)                   { -                    if(mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON) -                        return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED; +                    if(!CanDualWield() || !CanTitanGrip()) +                        return EQUIP_ERR_CANT_DUAL_WIELD;                  } + +                if(IsTwoHandUsed()) +                    return EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED;              }              // equip two-hand weapon case (with possible unequip 2 items)              if( type == INVTYPE_2HWEAPON )              { -                if(eslot != EQUIPMENT_SLOT_MAINHAND) +                if (eslot == EQUIPMENT_SLOT_OFFHAND) +                { +                    if (!CanTitanGrip()) +                        return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; +                } +                else if (eslot != EQUIPMENT_SLOT_MAINHAND)                      return EQUIP_ERR_ITEM_CANT_BE_EQUIPPED; -                // offhand item must can be stored in inventory for offhand item and it also must be unequipped -                Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); -                ItemPosCountVec off_dest; -                if( offItem && (!not_loading || -                    CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) !=  EQUIP_ERR_OK || -                    CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) !=  EQUIP_ERR_OK ) ) -                    return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; +                if (!CanTitanGrip()) +                { +                    // offhand item must can be stored in inventory for offhand item and it also must be unequipped +                    Item *offItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND ); +                    ItemPosCountVec off_dest; +                    if( offItem && (!not_loading || +                        CanUnequipItem(uint16(INVENTORY_SLOT_BAG_0) << 8 | EQUIPMENT_SLOT_OFFHAND,false) !=  EQUIP_ERR_OK || +                        CanStoreItem( NULL_BAG, NULL_SLOT, off_dest, offItem, false ) !=  EQUIP_ERR_OK ) ) +                        return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED : EQUIP_ERR_INVENTORY_FULL; +                }              }              dest = ((INVENTORY_SLOT_BAG_0 << 8) | eslot);              return EQUIP_ERR_OK; @@ -10742,7 +11067,7 @@ void Player::DestroyItemCount( uint32 item, uint32 count, bool update, bool uneq              }          }      } -    for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +    for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)      {          pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && pItem->GetEntry() == item ) @@ -10845,7 +11170,7 @@ void Player::DestroyZoneLimitedItem( bool update, uint32 new_zone )          if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) )              DestroyItem( INVENTORY_SLOT_BAG_0, i, update);      } -    for(int i = KEYRING_SLOT_START; i < KEYRING_SLOT_END; i++) +    for(int i = KEYRING_SLOT_START; i < QUESTBAG_SLOT_END; i++)      {          Item* pItem = GetItemByPos( INVENTORY_SLOT_BAG_0, i );          if( pItem && pItem->IsLimitedToAnotherMapOrZone(GetMapId(),new_zone) ) @@ -11842,6 +12167,10 @@ void Player::ApplyEnchantment(Item *item,EnchantmentSlot slot,bool apply, bool a                          ((Player*)this)->ApplyRatingMod(CR_EXPERTISE, enchant_amount, apply);                          sLog.outDebug("+ %u EXPERTISE", enchant_amount);                          break; +                    case ITEM_MOD_ARMOR_PENETRATION_RATING: +                        ((Player*)this)->ApplyRatingMod(CR_ARMOR_PENETRATION, enchant_amount, apply); +                        sLog.outDebug("+ %u ARMOR PENETRATION", enchant_amount); +                        break;                      default:                          break;                  } @@ -12564,7 +12893,10 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver      }      if(pQuest->IsDaily()) +    {          SetDailyQuestStatus(quest_id); +        GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1); +    }      if ( !pQuest->IsRepeatable() )          SetQuestStatus(quest_id, QUEST_STATUS_COMPLETE); @@ -12577,6 +12909,8 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver          SendQuestReward( pQuest, XP, questGiver );      if (q_status.uState != QUEST_NEW) q_status.uState = QUEST_CHANGED; +    GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT); +    GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST);  }  void Player::FailQuest( uint32 quest_id ) @@ -13202,6 +13536,7 @@ void Player::ItemAddedQuestCheck( uint32 entry, uint32 count )          }      }      UpdateForQuestsGO(); +    GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM, entry);  }  void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count ) @@ -13248,6 +13583,7 @@ void Player::ItemRemovedQuestCheck( uint32 entry, uint32 count )  void Player::KilledMonster( uint32 entry, uint64 guid )  {      uint32 addkillcount = 1; +    GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE, entry, addkillcount);      for( int i = 0; i < MAX_QUEST_LOG_SIZE; i++ )      {          uint32 questid = GetQuestSlotQuestId(i); @@ -13526,13 +13862,12 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive      uint32 questid = pQuest->GetQuestId();      sLog.outDebug( "WORLD: Sent SMSG_QUESTGIVER_QUEST_COMPLETE quest = %u", questid );      gameeventmgr.HandleQuestComplete(questid); -    WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4+4+pQuest->GetRewItemsCount()*8) ); -    data << questid; -    data << uint32(0x03); +    WorldPacket data( SMSG_QUESTGIVER_QUEST_COMPLETE, (4+4+4+4+4) ); +    data << uint32(questid);      if ( getLevel() < sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL) )      { -        data << XP; +        data << uint32(XP);          data << uint32(pQuest->GetRewOrReqMoney());      }      else @@ -13540,16 +13875,9 @@ void Player::SendQuestReward( Quest const *pQuest, uint32 XP, Object * questGive          data << uint32(0);          data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY)));      } -    data << uint32(0);                                      // new 2.3.0, HonorPoints? -    data << uint32( pQuest->GetRewItemsCount() );           // max is 5 -    for (uint32 i = 0; i < pQuest->GetRewItemsCount(); ++i) -    { -        if ( pQuest->RewItemId[i] > 0 ) -            data << pQuest->RewItemId[i] << pQuest->RewItemCount[i]; -        else -            data << uint32(0) << uint32(0); -    } +    data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills())); +    data << uint32(pQuest->GetBonusTalents());              // bonus talents      GetSession()->SendPacket( &data );      if (pQuest->GetQuestCompleteScript() != 0) @@ -13560,8 +13888,9 @@ void Player::SendQuestFailed( uint32 quest_id )  {      if( quest_id )      { -        WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4 ); +        WorldPacket data( SMSG_QUESTGIVER_QUEST_FAILED, 4+4 );          data << quest_id; +        data << uint32(0);                                  // failed reason (4 for inventory is full)          GetSession()->SendPacket( &data );          sLog.outDebug("WORLD: Sent SMSG_QUESTGIVER_QUEST_FAILED");      } @@ -13600,10 +13929,10 @@ void Player::SendPushToPartyResponse( Player *pPlayer, uint32 msg )  void Player::SendQuestUpdateAddItem( Quest const* pQuest, uint32 item_idx, uint32 count )  { -    WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, (4+4) ); +    WorldPacket data( SMSG_QUESTUPDATE_ADD_ITEM, 0 );      sLog.outDebug( "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM" ); -    data << pQuest->ReqItemId[item_idx]; -    data << count; +    //data << pQuest->ReqItemId[item_idx]; +    //data << count;      GetSession()->SendPacket( &data );  } @@ -13649,7 +13978,7 @@ bool Player::MinimalLoadFromDB( QueryResult *result, uint32 guid )      if(!LoadValues( fields[1].GetString()))      { -        sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded.",GUID_LOPART(guid)); +        sLog.outError("ERROR: Player #%d have broken data in `data` field. Can't be loaded for character list.",GUID_LOPART(guid));          if(delete_result) delete result;          return false;      } @@ -13719,7 +14048,7 @@ void Player::_LoadArenaTeamInfo(QueryResult *result)          ArenaTeam* aTeam = objmgr.GetArenaTeamById(arenateamid);          if(!aTeam)          { -            sLog.outError("FATAL: couldn't load arenateam %u", arenateamid); +            sLog.outError("Player::_LoadArenaTeamInfo: couldn't load arenateam %u, week %u, season %u, rating %u", arenateamid, played_week, played_season, personal_rating);              continue;          }          uint8  arenaSlot = aTeam->GetSlot(); @@ -14121,10 +14450,10 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )      uint32 extraflags = fields[25].GetUInt32();      m_stableSlots = fields[26].GetUInt32(); -    if(m_stableSlots > 2) +    if(m_stableSlots > 4)      { -        sLog.outError("Player can have not more 2 stable slots, but have in DB %u",uint32(m_stableSlots)); -        m_stableSlots = 2; +        sLog.outError("Player can have not more 4 stable slots, but have in DB %u",uint32(m_stableSlots)); +        m_stableSlots = 4;      }      m_atLoginFlags = fields[27].GetUInt32(); @@ -14193,6 +14522,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )      // reset stats before loading any modifiers      InitStatsForLevel();      InitTaxiNodesForLevel(); +    InitGlyphsForLevel(); +    InitRunes();      // apply original stats mods before spell loading or item equipment that call before equip _RemoveStatsMods() @@ -14349,6 +14680,8 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )      _LoadDeclinedNames(holder->GetResult(PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES)); +    m_achievementMgr.LoadFromDB(holder->GetResult(PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS), holder->GetResult(PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS)); +    m_achievementMgr.CheckAllAchievementCriteria();      return true;  } @@ -14402,10 +14735,6 @@ void Player::_LoadAuras(QueryResult *result, uint32 timediff)      for (int i = 0; i < TOTAL_AURAS; i++)          m_modAuras[i].clear(); -    // all aura related fields -    for(int i = UNIT_FIELD_AURA; i <= UNIT_FIELD_AURASTATE; ++i) -        SetUInt32Value(i, 0); -      //QueryResult *result = CharacterDatabase.PQuery("SELECT caster_guid,spell,effect_index,stackcount,amount,maxduration,remaintime,remaincharges FROM character_aura WHERE guid = '%u'",GetGUIDLow());      if(result) @@ -14651,15 +14980,16 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff)  // load mailed item which should receive current player  void Player::_LoadMailedItems(Mail *mail)  { -    QueryResult* result = CharacterDatabase.PQuery("SELECT item_guid, item_template FROM mail_items WHERE mail_id='%u'", mail->messageID); +    // data needs to be at first place for Item::LoadFromDB +    QueryResult* result = CharacterDatabase.PQuery("SELECT data, item_guid, item_template FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id='%u'", mail->messageID);      if(!result)          return;      do      {          Field *fields = result->Fetch(); -        uint32 item_guid_low = fields[0].GetUInt32(); -        uint32 item_template = fields[1].GetUInt32(); +        uint32 item_guid_low = fields[1].GetUInt32(); +        uint32 item_template = fields[2].GetUInt32();          mail->AddItem(item_guid_low, item_template); @@ -14675,7 +15005,7 @@ void Player::_LoadMailedItems(Mail *mail)          Item *item = NewItemOrBag(proto); -        if(!item->LoadFromDB(item_guid_low, 0)) +        if(!item->LoadFromDB(item_guid_low, 0, result))          {              sLog.outError( "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, item_guid_low);              CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid = '%u'", item_guid_low); @@ -15317,7 +15647,7 @@ void Player::SaveToDB()      SetByteValue(UNIT_FIELD_BYTES_1, 0, 0);                 // stand state      SetByteValue(UNIT_FIELD_BYTES_2, 3, 0);                 // shapeshift      SetByteValue(UNIT_FIELD_BYTES_1, 3, 0);                 // stand flags? -    RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +    RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);      SetDisplayId(GetNativeDisplayId());      bool inworld = IsInWorld(); @@ -15468,7 +15798,7 @@ void Player::SaveToDB()          pet->SavePetToDB(PET_SAVE_AS_CURRENT);      //to prevent access to DB we should cache some data, which is used very often -    CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow()); +    /*CachePlayerInfoMap::iterator _iter = objmgr.m_mPlayerInfoMap.find(GetGUIDLow());      if(_iter != objmgr.m_mPlayerInfoMap.end())//skip new players      {          _iter->second->unLevel = getLevel(); @@ -15482,7 +15812,8 @@ void Player::SaveToDB()          _iter->second->unArenaInfoId0 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (0 * 6));          _iter->second->unArenaInfoId1 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (1 * 6));          _iter->second->unArenaInfoId2 = GetUInt32Value(PLAYER_FIELD_ARENA_TEAM_INFO_1_1 + (2 * 6)); -    } +    }*/ +    m_achievementMgr.SaveToDB();  }  // fast save function for item/money cheating preventing - save only inventory and money state @@ -15944,6 +16275,42 @@ void Player::SetFloatValueInDB(uint16 index, float value, uint64 guid)      Player::SetUInt32ValueInDB(index, temp, guid);  } +void Player::Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair) +{ +    Tokens tokens; +    if(!LoadValuesArrayFromDB(tokens, guid)) +        return; + +    uint32 unit_bytes0 = GetUInt32ValueFromArray(tokens, UNIT_FIELD_BYTES_0); +    uint8 race = unit_bytes0 & 0xFF; +    uint8 class_ = (unit_bytes0 >> 8) & 0xFF; + +    PlayerInfo const* info = objmgr.GetPlayerInfo(race, class_); +    if(!info) +        return; + +    unit_bytes0 &= ~(0xFF << 16); +    unit_bytes0 |= (gender << 16); +    SetUInt32ValueInArray(tokens, UNIT_FIELD_BYTES_0, unit_bytes0); + +    SetUInt32ValueInArray(tokens, UNIT_FIELD_DISPLAYID, gender ? info->displayId_f : info->displayId_m); +    SetUInt32ValueInArray(tokens, UNIT_FIELD_NATIVEDISPLAYID, gender ? info->displayId_f : info->displayId_m); + +    SetUInt32ValueInArray(tokens, PLAYER_BYTES, (skin | (face << 8) | (hairStyle << 16) | (hairColor << 24))); + +    uint32 player_bytes2 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_2); +    player_bytes2 &= ~0xFF; +    player_bytes2 |= facialHair; +    SetUInt32ValueInArray(tokens, PLAYER_BYTES_2, player_bytes2); + +    uint32 player_bytes3 = GetUInt32ValueFromArray(tokens, PLAYER_BYTES_3); +    player_bytes3 &= ~0xFF; +    player_bytes3 |= gender; +    SetUInt32ValueInArray(tokens, PLAYER_BYTES_3, player_bytes3); + +    SaveValuesArrayInDB(tokens, guid); +} +  void Player::SendAttackSwingNotStanding()  {      WorldPacket data(SMSG_ATTACKSWING_NOTSTANDING, 0); @@ -15976,7 +16343,8 @@ void Player::SendAttackSwingBadFacingAttack()  void Player::SendAutoRepeatCancel()  { -    WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, 0); +    WorldPacket data(SMSG_CANCEL_AUTO_REPEAT, GetPackGUID().size()); +    data.append(GetPackGUID());                             // may be it's target guid      GetSession()->SendPacket( &data );  } @@ -16205,6 +16573,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)      {          WorldPacket data(SMSG_PET_SPELLS, 8);          data << uint64(0); +        data << uint32(0);          GetSession()->SendPacket(&data);          if(GetGroup()) @@ -16336,65 +16705,79 @@ void Player::PetSpellInitialize()  {      Pet* pet = GetPet(); -    if(pet) -    { -        uint8 addlist = 0; +    if(!pet) +        return; -        sLog.outDebug("Pet Spells Groups"); +    sLog.outDebug("Pet Spells Groups"); -        CreatureInfo const *cinfo = pet->GetCreatureInfo(); +    CharmInfo *charmInfo = pet->GetCharmInfo(); -        if(pet->isControlled() && (pet->getPetType() == HUNTER_PET || cinfo && cinfo->type == CREATURE_TYPE_DEMON && getClass() == CLASS_WARLOCK)) -        { -            for(PetSpellMap::iterator itr = pet->m_spells.begin();itr != pet->m_spells.end();++itr) -            { -                if(itr->second->state == PETSPELL_REMOVED) -                    continue; -                ++addlist; -            } -        } +    WorldPacket data(SMSG_PET_SPELLS, 8+4+4+4+10*4); +    data << uint64(pet->GetGUID()); +    data << uint32(pet->GetCreatureInfo()->family);         // creature family (required for pet talents) +    data << uint32(0); +    data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); -        // first line + actionbar + spellcount + spells + last adds -        WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25); +    // action bar loop +    for(uint32 i = 0; i < 10; i++) +    { +        data << uint32(charmInfo->GetActionBarEntry(i)->Raw); +    } -        CharmInfo *charmInfo = pet->GetCharmInfo(); +    size_t spellsCountPos = data.wpos(); -                                                            //16 -        data << (uint64)pet->GetGUID() << uint32(0x00000000) << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState()) << uint16(0); +    // spells count +    uint8 addlist = 0; +    data << uint8(addlist);                                 // placeholder -        for(uint32 i = 0; i < 10; i++)                      //40 +    if(pet->isControlled() && ((pet->getPetType() == HUNTER_PET) || ((pet->GetCreatureInfo()->type == CREATURE_TYPE_DEMON) && (getClass() == CLASS_WARLOCK)))) +    { +        // spells loop +        for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr)          { -            data << uint16(charmInfo->GetActionBarEntry(i)->SpellOrAction) << uint16(charmInfo->GetActionBarEntry(i)->Type); +            if(itr->second->state == PETSPELL_REMOVED) +                continue; + +            data << uint16(itr->first); +            data << uint16(itr->second->active);            // pet spell active state isn't boolean +            ++addlist;          } +    } -        data << uint8(addlist);                             //1 +    data.put<uint8>(spellsCountPos, addlist); -        if(addlist && pet->isControlled()) -        { -            for (PetSpellMap::iterator itr = pet->m_spells.begin(); itr != pet->m_spells.end(); ++itr) -            { -                if(itr->second->state == PETSPELL_REMOVED) -                    continue; +    uint8 cooldownsCount = pet->m_CreatureSpellCooldowns.size() + pet->m_CreatureCategoryCooldowns.size(); +    data << uint8(cooldownsCount); -                data << uint16(itr->first); -                data << uint16(itr->second->active);        // pet spell active state isn't boolean -            } -        } +    time_t curTime = time(NULL); -        //data << uint8(0x01) << uint32(0x6010) << uint32(0x01) << uint32(0x05) << uint16(0x00);    //15 -        uint8 count = 3;                                    //1+8+8+8=25 +    for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr) +    { +        time_t cooldown = 0; -        // if count = 0, then end of packet... -        data << count; -        // uint32 value is spell id... -        // uint64 value is constant 0, unknown... -        data << uint32(0x6010) << uint64(0);                // if count = 1, 2 or 3 -        //data << uint32(0x5fd1) << uint64(0);  // if count = 2 -        data << uint32(0x8e8c) << uint64(0);                // if count = 3 -        data << uint32(0x8e8b) << uint64(0);                // if count = 3 +        if(itr->second > curTime) +            cooldown = (itr->second - curTime) * 1000; -        GetSession()->SendPacket(&data); +        data << uint16(itr->first);                         // spellid +        data << uint16(0);                                  // spell category? +        data << uint32(itr->second);                        // cooldown +        data << uint32(0);                                  // category cooldown +    } + +    for(CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr) +    { +        time_t cooldown = 0; + +        if(itr->second > curTime) +            cooldown = (itr->second - curTime) * 1000; + +        data << uint16(itr->first);                         // spellid +        data << uint16(0);                                  // spell category? +        data << uint32(0);                                  // cooldown +        data << uint32(itr->second);                        // category cooldown      } + +    GetSession()->SendPacket(&data);  }  void Player::PossessSpellInitialize() @@ -16416,7 +16799,10 @@ void Player::PossessSpellInitialize()      WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds                                                              //16 -    data << (uint64)charm->GetGUID() << uint32(0x00000000) << uint8(0) << uint8(0) << uint16(0); +    data << uint64(charm->GetGUID()); +    data << uint32(0x00000000); +    data << uint32(0); +    data << uint8(0) << uint8(0) << uint16(0);      for(uint32 i = 0; i < 10; i++)                          //40      { @@ -16425,11 +16811,8 @@ void Player::PossessSpellInitialize()      data << uint8(addlist);                                 //1 -    uint8 count = 3; -    data << count; -    data << uint32(0x6010) << uint64(0);                    // if count = 1, 2 or 3 -    data << uint32(0x8e8c) << uint64(0);                    // if count = 3 -    data << uint32(0x8e8b) << uint64(0);                    // if count = 3 +    uint8 count = 0; +    data << uint8(count);                                   // cooldowns count      GetSession()->SendPacket(&data);  } @@ -16466,13 +16849,13 @@ void Player::CharmSpellInitialize()      WorldPacket data(SMSG_PET_SPELLS, 16+40+1+4*addlist+25);// first line + actionbar + spellcount + spells + last adds -    data << (uint64)charm->GetGUID() << uint32(0x00000000); - +    data << uint64(charm->GetGUID()); +    data << uint32(0x00000000); +    data << uint32(0);      if(charm->GetTypeId() != TYPEID_PLAYER)          data << uint8(charmInfo->GetReactState()) << uint8(charmInfo->GetCommandState());      else          data << uint8(0) << uint8(0); -      data << uint16(0);      for(uint32 i = 0; i < 10; i++)                          //40 @@ -16495,51 +16878,12 @@ void Player::CharmSpellInitialize()          }      } -    uint8 count = 3; -    data << count; -    data << uint32(0x6010) << uint64(0);                    // if count = 1, 2 or 3 -    data << uint32(0x8e8c) << uint64(0);                    // if count = 3 -    data << uint32(0x8e8b) << uint64(0);                    // if count = 3 +    uint8 count = 0; +    data << uint8(count);                                   // cooldowns count      GetSession()->SendPacket(&data);  } -int32 Player::GetTotalFlatMods(uint32 spellId, SpellModOp op) -{ -    SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); -    if (!spellInfo) return 0; -    int32 total = 0; -    for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) -    { -        SpellModifier *mod = *itr; - -        if(!IsAffectedBySpellmod(spellInfo,mod)) -            continue; - -        if (mod->type == SPELLMOD_FLAT) -            total += mod->value; -    } -    return total; -} - -int32 Player::GetTotalPctMods(uint32 spellId, SpellModOp op) -{ -    SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); -    if (!spellInfo) return 0; -    int32 total = 0; -    for (SpellModList::iterator itr = m_spellMods[op].begin(); itr != m_spellMods[op].end(); ++itr) -    { -        SpellModifier *mod = *itr; - -        if(!IsAffectedBySpellmod(spellInfo,mod)) -            continue; - -        if (mod->type == SPELLMOD_PCT) -            total += mod->value; -    } -    return total; -} -  bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell)  {      if (!mod || !spellInfo) @@ -16557,22 +16901,25 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo              return false;      } -    return spellmgr.IsAffectedBySpell(spellInfo,mod->spellId,mod->effectId,mod->mask); +    return spellmgr.IsAffectedByMod(spellInfo, mod);  }  void Player::AddSpellMod(SpellModifier* mod, bool apply)  {      uint16 Opcode= (mod->type == SPELLMOD_FLAT) ? SMSG_SET_FLAT_SPELL_MODIFIER : SMSG_SET_PCT_SPELL_MODIFIER; -    for(int eff=0;eff<64;++eff) +    for(int eff=0;eff<96;++eff)      { -        uint64 _mask = uint64(1) << eff; -        if ( mod->mask & _mask) +        uint64 _mask = 0; +        uint64 _mask2= 0; +        if (eff<64) _mask = uint64(1) << (eff- 0); +        else        _mask2= uint64(1) << (eff-64); +        if ( mod->mask & _mask || mod->mask2 & _mask2)          {              int32 val = 0;              for (SpellModList::iterator itr = m_spellMods[mod->op].begin(); itr != m_spellMods[mod->op].end(); ++itr)              { -                if ((*itr)->type == mod->type && (*itr)->mask & _mask) +                if ((*itr)->type == mod->type && ((*itr)->mask & _mask || (*itr)->mask2 & _mask2))                      val += (*itr)->value;              }              val += apply ? mod->value : -(mod->value); @@ -16671,6 +17018,27 @@ void Player::RemovePetitionsAndSigns(uint64 guid, uint32 type)      CharacterDatabase.CommitTransaction();  } +void Player::LeaveAllArenaTeams(uint64 guid) +{ +    QueryResult *result = CharacterDatabase.PQuery("SELECT arena_team_member.arenateamid FROM arena_team_member JOIN arena_team ON arena_team_member.arenateamid = arena_team.arenateamid WHERE guid='%u'", GUID_LOPART(guid)); +    if(!result) +        return; + +    do +    { +        Field *fields = result->Fetch(); +        uint32 at_id = fields[0].GetUInt32(); +        if(at_id != 0) +        { +            ArenaTeam * at = objmgr.GetArenaTeamById(at_id); +            if(at) +                at->DelMember(guid); +        } +    } while (result->NextRow()); + +    delete result; +} +  void Player::SetRestBonus (float rest_bonus_new)  {      // Prevent resting on max level @@ -16720,7 +17088,7 @@ void Player::HandleStealthedUnitsDetection()              // send data at target visibility change (adding to client)              if((*i)!=this && (*i)->isType(TYPEMASK_UNIT))              { -                SendAuraDurationsForTarget(*i); +                SendAurasForTarget(*i);                  //if(((Unit*)(*i))->isAlive()) //should be always alive                  {                      if((*i)->GetTypeId()==TYPEID_UNIT) @@ -17714,7 +18082,7 @@ void Player::UpdateVisibilityOf(WorldObject* target)              // send data at target visibility change (adding to client)              if(target!=this && target->isType(TYPEMASK_UNIT))              { -                SendAuraDurationsForTarget((Unit*)target); +                SendAurasForTarget((Unit*)target);                  if(((Unit*)target)->isAlive())                  {                      if(target->GetTypeId()==TYPEID_UNIT) @@ -17893,7 +18261,7 @@ void Player::SetGroup(Group *group, int8 subgroup)  void Player::SendInitialPacketsBeforeAddToMap()  { -    WorldPacket data(SMSG_SET_REST_START, 4); +    WorldPacket data(SMSG_SET_REST_START_OBSOLETE, 4);      data << uint32(0);                                      // unknown, may be rest state time or experience      GetSession()->SendPacket(&data); @@ -17921,6 +18289,7 @@ void Player::SendInitialPacketsBeforeAddToMap()      SendInitialActionButtons();      SendInitialReputations(); +    m_achievementMgr.SendAllAchievementData();      UpdateZone(GetZoneId());      SendInitWorldStates(); @@ -17931,13 +18300,23 @@ void Player::SendInitialPacketsBeforeAddToMap()      data << (float)0.01666667f;                             // game speed      GetSession()->SendPacket( &data ); +    data.Initialize(SMSG_TIME_SYNC_REQ, 4);                 // new 2.0.x, enable movement +    data << uint32(0x00000000);                             // on blizz it increments periodically +    GetSession()->SendPacket(&data); +      // set fly flag if in fly form or taxi flight to prevent visually drop at ground in showup moment      if(HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED) || isInFlight())          AddUnitMovementFlag(MOVEMENTFLAG_FLYING2); + +    m_mover = this;  }  void Player::SendInitialPacketsAfterAddToMap()  { +    WorldPacket data(SMSG_TIME_SYNC_REQ, 4);                // new 2.0.x, enable movement +    data << uint32(0x00000000);                             // on blizz it increments periodically +    GetSession()->SendPacket(&data); +      CastSpell(this, 836, true);                             // LOGINEFFECT      // set some aura effects that send packet to player client after add player to map @@ -17968,6 +18347,7 @@ void Player::SendInitialPacketsAfterAddToMap()          SendMessageToSet(&data,true);      } +    SendAurasForTarget(this);      SendEnchantmentDurations();                             // must be after add to map      SendItemDurations();                                    // must be after add to map  } @@ -17985,11 +18365,19 @@ void Player::SendUpdateToOutOfRangeGroupMembers()          pet->ResetAuraUpdateMask();  } -void Player::SendTransferAborted(uint32 mapid, uint16 reason) +void Player::SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg)  {      WorldPacket data(SMSG_TRANSFER_ABORTED, 4+2);      data << uint32(mapid); -    data << uint16(reason);                                 // transfer abort reason +    data << uint8(reason);                                 // transfer abort reason +    switch(reason) +    { +        case TRANSFER_ABORT_INSUF_EXPAN_LVL: +        case TRANSFER_ABORT_DIFFICULTY: +        case TRANSFER_ABORT_UNIQUE_MESSAGE: +            data << uint8(arg); +            break; +    }      GetSession()->SendPacket(&data);  } @@ -18199,16 +18587,51 @@ void Player::learnSkillRewardedSpells()      }  } -void Player::SendAuraDurationsForTarget(Unit* target) +void Player::SendAurasForTarget(Unit *target)  { -    for(Unit::AuraMap::const_iterator itr = target->GetAuras().begin(); itr != target->GetAuras().end(); ++itr) +    if(target->GetVisibleAuras()->empty())                  // speedup things +        return; + +    WorldPacket data(SMSG_AURA_UPDATE_ALL); +    data.append(target->GetPackGUID()); + +    Unit::VisibleAuraMap const *visibleAuras = target->GetVisibleAuras(); +    for(Unit::VisibleAuraMap::const_iterator itr = visibleAuras->begin(); itr != visibleAuras->end(); ++itr)      { -        Aura* aura = itr->second; -        if(aura->GetAuraSlot() >= MAX_AURAS || aura->IsPassive() || aura->GetCasterGUID()!=GetGUID()) -            continue; +        for(uint32 j = 0; j < 3; ++j) +        { +            if(Aura *aura = target->GetAura(itr->second, j)) +            { +                data << uint8(aura->GetAuraSlot()); +                data << uint32(aura->GetId()); + +                if(aura->GetId()) +                { +                    uint8 auraFlags = aura->GetAuraFlags(); +                    // flags +                    data << uint8(auraFlags); +                    // level +                    data << uint8(aura->GetAuraLevel()); +                    // charges +                    data << uint8(aura->m_procCharges >= 0 ? aura->m_procCharges : 0 ); + +                    if(!(auraFlags & AFLAG_NOT_CASTER)) +                    { +                        data << uint8(0);                   // packed GUID of someone (caster?) +                    } -        aura->SendAuraDurationForCaster(this); +                    if(auraFlags & AFLAG_DURATION)          // include aura duration +                    { +                        data << uint32(aura->GetAuraMaxDuration()); +                        data << uint32(aura->GetAuraDuration()); +                    } +                } +                break; +            } +        }      } + +    GetSession()->SendPacket(&data);  }  void Player::SetDailyQuestStatus( uint32 quest_id ) @@ -18270,15 +18693,15 @@ uint32 Player::GetMinLevelForBattleGroundQueueId(uint32 queue_id)      if(queue_id < 1)          return 0; -    if(queue_id >=6) -        queue_id = 6; +    if(queue_id >=7) +        queue_id = 7;      return 10*(queue_id+1);  }  uint32 Player::GetMaxLevelForBattleGroundQueueId(uint32 queue_id)  { -    if(queue_id >=6) +    if(queue_id >=7)          return 255;                                         // hardcoded max level      return 10*(queue_id+2)-1; @@ -18290,8 +18713,8 @@ uint32 Player::GetBattleGroundQueueIdFromLevel() const      uint32 level = getLevel();      if(level <= 19)          return 0; -    else if (level > 69) -        return 6; +    else if (level > 79) +        return 7;      else          return level/10 - 1;                                // 20..29 -> 1, 30-39 -> 2, ...      /* @@ -18437,9 +18860,8 @@ void Player::AutoUnequipOffhandIfNeed()      if(!offItem)          return; -    Item *mainItem = GetItemByPos( INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND ); - -    if(!mainItem || mainItem->GetProto()->InventoryType != INVTYPE_2HWEAPON) +    // need unequip for 2h-weapon without TitanGrip +    if (!IsTwoHandUsed())          return;      ItemPosCountVec off_dest; @@ -18505,6 +18927,23 @@ bool Player::HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item cons      return false;  } +bool Player::CanNoReagentCast(SpellEntry const* spellInfo) const +{ +    // don't take reagents for spells with SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP +    if (spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && +        HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) +        return true; + +    // Check no reagent use mask +    uint64 noReagentMask_0_1 = GetUInt64Value(PLAYER_NO_REAGENT_COST_1); +    uint32 noReagentMask_2   = GetUInt64Value(PLAYER_NO_REAGENT_COST_1+2); +    if (spellInfo->SpellFamilyFlags  & noReagentMask_0_1 || +        spellInfo->SpellFamilyFlags2 & noReagentMask_2) +        return true; + +    return false; +} +  void Player::RemoveItemDependentAurasAndCasts( Item * pItem )  {      AuraMap& auras = GetAuras(); @@ -18550,7 +18989,7 @@ uint32 Player::GetResurrectionSpellId()      for(AuraList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr)      {          // Soulstone Resurrection                           // prio: 3 (max, non death persistent) -        if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 ) +        if( prio < 2 && (*itr)->GetSpellProto()->SpellVisual[0] == 99 && (*itr)->GetSpellProto()->SpellIconID == 92 )          {              switch((*itr)->GetId())              { @@ -18709,6 +19148,9 @@ uint32 Player::GetBaseWeaponSkillValue (WeaponAttackType attType) const  void Player::ResurectUsingRequestData()  { +    /// Teleport before resurrecting, otherwise the player might get attacked from creatures near his corpse +    TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); +      ResurrectPlayer(0.0f,false);      if(GetMaxHealth() > m_resurrectHealth) @@ -18726,8 +19168,6 @@ void Player::ResurectUsingRequestData()      SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) );      SpawnCorpseBones(); - -    TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation());  }  void Player::SetClientControl(Unit* target, uint8 allowMove) @@ -18741,8 +19181,8 @@ void Player::SetClientControl(Unit* target, uint8 allowMove)  void Player::UpdateZoneDependentAuras( uint32 newZone )  {      // remove new continent flight forms -    if( !isGameMaster() && -        GetVirtualMapForMapAndZone(GetMapId(),newZone) != 530) +    uint32 v_map = GetVirtualMapForMapAndZone(GetMapId(), newZone); +    if( !isGameMaster() && v_map != 530 && v_map != 571)      {          RemoveSpellsCausingAura(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED);          RemoveSpellsCausingAura(SPELL_AURA_FLY); @@ -18962,8 +19402,8 @@ bool ItemPosCount::isContainedIn(ItemPosCountVec const& vec) const  void Player::HandleFallDamage(MovementInfo& movementInfo)  { -    if(movementInfo.fallTime < 1500) -        return; +    //if(movementInfo.fallTime < 1500) +    //    return;      // calculate total z distance of the fall      float z_diff = m_lastFallZ - movementInfo.z; @@ -19269,6 +19709,152 @@ bool Player::isAllowUseBattleGroundObject()             );  } +uint32 Player::GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair) +{ +    uint32 level = getLevel(); + +    if(level > GT_MAX_LEVEL) +        level = GT_MAX_LEVEL;                               // max level in this dbc + +    uint8 hairstyle = GetByteValue(PLAYER_BYTES, 2); +    uint8 haircolor = GetByteValue(PLAYER_BYTES, 3); +    uint8 facialhair = GetByteValue(PLAYER_BYTES_2, 0); + +    if((hairstyle == newhairstyle) && (haircolor == newhaircolor) && (facialhair == newfacialhair)) +        return 0; + +    GtBarberShopCostBaseEntry const *bsc = sGtBarberShopCostBaseStore.LookupEntry(level - 1); + +    if(!bsc)                                                // shouldn't happen +        return 0xFFFFFFFF; + +    float cost = 0; + +    if(hairstyle != newhairstyle) +        cost += bsc->cost;                                  // full price + +    if((haircolor != newhaircolor) && (hairstyle == newhairstyle)) +        cost += bsc->cost * 0.5f;                           // +1/2 of price + +    if(facialhair != newfacialhair) +        cost += bsc->cost * 0.75f;                          // +3/4 of price + +    return uint32(cost); +} + +void Player::InitGlyphsForLevel() +{ +    uint32 level = getLevel(); +    uint32 value = 0; + +    // 0x3F = 0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 for 80 level +    if(level >= 15) +        value |= (0x01 | 0x02); +    if(level >= 30) +        value |= 0x04; +    if(level >= 50) +        value |= 0x08; +    if(level >= 70) +        value |= 0x10; +    if(level >= 80) +        value |= 0x20; + +    SetUInt32Value(PLAYER_GLYPHS_ENABLED, value); +} + +void Player::EnterVehicle(Vehicle *vehicle) +{ +    VehicleEntry const *ve = sVehicleStore.LookupEntry(vehicle->GetVehicleId()); +    if(!ve) +        return; + +    VehicleSeatEntry const *veSeat = sVehicleSeatStore.LookupEntry(ve->m_seatID[0]); +    if(!veSeat) +        return; + +    vehicle->SetCharmerGUID(GetGUID()); +    vehicle->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); +    vehicle->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); +    vehicle->setFaction(getFaction()); + +    SetCharm(vehicle);                                      // charm +    SetFarSight(vehicle->GetGUID());                        // set view + +    SetClientControl(vehicle, 1);                           // redirect controls to vehicle + +    WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); +    GetSession()->SendPacket(&data); + +    data.Initialize(MSG_MOVE_TELEPORT_ACK, 30); +    data.append(GetPackGUID()); +    data << uint32(0);                                      // counter? +    data << uint32(MOVEMENTFLAG_ONTRANSPORT);               // transport +    data << uint16(0);                                      // special flags +    data << uint32(getMSTime());                            // time +    data << vehicle->GetPositionX();                        // x +    data << vehicle->GetPositionY();                        // y +    data << vehicle->GetPositionZ();                        // z +    data << vehicle->GetOrientation();                      // o +    // transport part, TODO: load/calculate seat offsets +    data << uint64(vehicle->GetGUID());                     // transport guid +    data << float(veSeat->m_attachmentOffsetX);             // transport offsetX +    data << float(veSeat->m_attachmentOffsetY);             // transport offsetY +    data << float(veSeat->m_attachmentOffsetZ);             // transport offsetZ +    data << float(0);                                       // transport orientation +    data << uint32(getMSTime());                            // transport time +    data << uint8(0);                                       // seat +    // end of transport part +    data << uint32(0);                                      // fall time +    GetSession()->SendPacket(&data); + +    data.Initialize(SMSG_PET_SPELLS, 8+4+4+4+4*10+1+1); +    data << uint64(vehicle->GetGUID()); +    data << uint32(0x00000000); +    data << uint32(0x00000000); +    data << uint32(0x00000101); + +    for(uint32 i = 0; i < 10; ++i) +        data << uint16(0) << uint8(0) << uint8(i+8); + +    data << uint8(0); +    data << uint8(0); +    GetSession()->SendPacket(&data); +} + +void Player::ExitVehicle(Vehicle *vehicle) +{ +    vehicle->SetCharmerGUID(0); +    vehicle->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); +    vehicle->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); +    vehicle->setFaction((GetTeam() == ALLIANCE) ? vehicle->GetCreatureInfo()->faction_A : vehicle->GetCreatureInfo()->faction_H); + +    SetCharm(NULL); +    SetFarSight(NULL); + +    SetClientControl(vehicle, 0); + +    WorldPacket data(MSG_MOVE_TELEPORT_ACK, 30); +    data.append(GetPackGUID()); +    data << uint32(0);                                      // counter? +    data << uint32(MOVEMENTFLAG_FLY_UNK1);                  // fly unk +    data << uint16(0x40);                                   // special flags +    data << uint32(getMSTime());                            // time +    data << vehicle->GetPositionX();                        // x +    data << vehicle->GetPositionY();                        // y +    data << vehicle->GetPositionZ();                        // z +    data << vehicle->GetOrientation();                      // o +    data << uint32(0);                                      // fall time +    GetSession()->SendPacket(&data); + +    data.Initialize(SMSG_PET_SPELLS, 8+4); +    data << uint64(0); +    data << uint32(0); +    GetSession()->SendPacket(&data); + +    // only for flyable vehicles? +    CastSpell(this, 45472, true);                           // Parachute +} +  bool Player::HasTitle(uint32 bitIndex)  {      if (bitIndex > 128) @@ -19286,7 +19872,6 @@ void Player::SetTitle(CharTitlesEntry const* title)      SetFlag(PLAYER__FIELD_KNOWN_TITLES+fieldIndexOffset, flag);  } -  /*-----------------------TRINITY--------------------------*/  bool Player::isTotalImmunity()  { @@ -19343,3 +19928,52 @@ void Player::UpdateCharmedAI()          Attack(target, true);      }  } + +void Player::ConvertRune(uint8 index, uint8 newType) +{ +    SetCurrentRune(index, newType); +     +    WorldPacket data(SMSG_CONVERT_RUNE, 2); +    data << uint8(index); +    data << uint8(newType); +    GetSession()->SendPacket(&data); +} + +void Player::ResyncRunes(uint8 count) +{ +    WorldPacket data(SMSG_RESYNC_RUNES, count * 2); +    for(uint32 i = 0; i < count; ++i) +    { +        data << uint8(GetCurrentRune(i));                   // rune type +        data << uint8(255 - (GetRuneCooldown(i) * 51));     // passed cooldown time (0-255) +    } +    GetSession()->SendPacket(&data); +} + +void Player::AddRunePower(uint8 index) +{ +    WorldPacket data(SMSG_ADD_RUNE_POWER, 4); +    data << uint32(1 << index);                             // mask (0x00-0x3F probably) +    GetSession()->SendPacket(&data); +} + +void Player::InitRunes() +{ +    if(getClass() != CLASS_DEATH_KNIGHT) +        return; + +    m_runes = new Runes; + +    m_runes->runeState = 0; + +    for(uint32 i = 0; i < MAX_RUNES; ++i) +    { +        SetBaseRune(i, i / 2);                              // init base types +        SetCurrentRune(i, i / 2);                           // init current types +        SetRuneCooldown(i, 0);                              // reset cooldowns +        m_runes->SetRuneState(i); +    } + +    for(uint32 i = 0; i < NUM_RUNE_TYPES; ++i) +        SetFloatValue(PLAYER_RUNE_REGEN_1 + i, 0.1f); +} diff --git a/src/game/Player.h b/src/game/Player.h index c97f771190e..e40e3859bdc 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -35,6 +35,7 @@  #include "Pet.h"  #include "MapReference.h"  #include "Util.h"                                           // for Tokens typedef +#include "AchievementMgr.h"  #include<string>  #include<vector> @@ -49,6 +50,8 @@ class Transport;  class UpdateMask;  class PlayerSocial;  class OutdoorPvP; +class AchievementMgr; +class Vehicle;  typedef std::deque<Mail*> PlayerMails; @@ -80,15 +83,17 @@ struct PlayerSpell  #define SPELL_WITHOUT_SLOT_ID uint16(-1) +// Spell modifier (used for modify other spells)  struct SpellModifier  { +    SpellModifier() : charges(0), lastAffected(NULL) {}      SpellModOp   op   : 8;      SpellModType type : 8;      int16 charges     : 16;      int32 value;      uint64 mask; +    uint64 mask2;      uint32 spellId; -    uint32 effectId;      Spell const* lastAffected;  }; @@ -224,6 +229,39 @@ struct Areas      float y2;  }; +#define MAX_RUNES       6 +#define RUNE_COOLDOWN   5                                   // 5*2=10 sec + +enum RuneType +{ +    RUNE_BLOOD      = 0, +    RUNE_UNHOLY     = 1, +    RUNE_FROST      = 2, +    RUNE_DEATH      = 3, +    NUM_RUNE_TYPES  = 4 +}; + +struct RuneInfo +{ +    uint8 BaseRune; +    uint8 CurrentRune; +    uint8 Cooldown; +}; + +struct Runes +{ +    RuneInfo runes[MAX_RUNES]; +    uint8 runeState;                                        // mask of available runes + +    void SetRuneState(uint8 index, bool set = true) +    { +        if(set) +            runeState |= (1 << index);                      // usable +        else +            runeState &= ~(1 << index);                     // on cooldown +    } +}; +  enum FactionFlags  {      FACTION_FLAG_VISIBLE            = 0x01,                 // makes visible in client (set or can be set at interaction with target of this faction) @@ -390,9 +428,9 @@ enum PlayerFlags      PLAYER_FLAGS_UNK1           = 0x00001000,               // played long time      PLAYER_FLAGS_UNK2           = 0x00002000,               // played too long time      PLAYER_FLAGS_UNK3           = 0x00008000,               // strange visual effect (2.0.1), looks like PLAYER_FLAGS_GHOST flag -    PLAYER_FLAGS_SANCTUARY      = 0x00010000,               // player entered sanctuary -    PLAYER_FLAGS_UNK4           = 0x00020000,               // taxi benchmark mode (on/off) (2.0.1) -    PLAYER_UNK                  = 0x00040000,               // 2.0.8... +    PLAYER_FLAGS_UNK4           = 0x00010000,               // pre-3.0.3 PLAYER_FLAGS_SANCTUARY flag for player entered sanctuary +    PLAYER_FLAGS_UNK5           = 0x00020000,               // taxi benchmark mode (on/off) (2.0.1) +    PLAYER_FLAGS_PVP_TIMER      = 0x00040000,               // 3.0.2, pvp timer active (after you disable pvp manually)  };  // used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1) @@ -481,7 +519,8 @@ enum LootType      LOOT_DISENCHANTING          = 5,                        // unsupported by client, sending LOOT_SKINNING instead      LOOT_PROSPECTING            = 6,                        // unsupported by client, sending LOOT_SKINNING instead      LOOT_INSIGNIA               = 7,                        // unsupported by client, sending LOOT_SKINNING instead -    LOOT_FISHINGHOLE            = 8                         // unsupported by client, sending LOOT_FISHING instead +    LOOT_FISHINGHOLE            = 8,                        // unsupported by client, sending LOOT_FISHING instead +    LOOT_MILLING                = 9                         // unsupported by client, sending LOOT_SKINNING instead  };  enum MirrorTimerType @@ -512,7 +551,8 @@ enum AtLoginFlags      AT_LOGIN_NONE          = 0,      AT_LOGIN_RENAME        = 1,      AT_LOGIN_RESET_SPELLS  = 2, -    AT_LOGIN_RESET_TALENTS = 4 +    AT_LOGIN_RESET_TALENTS = 4, +    AT_LOGIN_CUSTOMIZE     = 8  };  typedef std::map<uint32, QuestStatusData> QuestStatusMap; @@ -544,7 +584,7 @@ enum PlayerSlots      // first slot for item stored (in any way in player m_items data)      PLAYER_SLOT_START           = 0,      // last+1 slot for item stored (in any way in player m_items data) -    PLAYER_SLOT_END             = 118, +    PLAYER_SLOT_END             = 200,      PLAYER_SLOTS_COUNT          = (PLAYER_SLOT_END - PLAYER_SLOT_START)  }; @@ -672,6 +712,24 @@ enum KeyRingSlots      KEYRING_SLOT_END            = 118  }; +enum VanityPetSlots +{ +    VANITYPET_SLOT_START        = 118, +    VANITYPET_SLOT_END          = 136 +}; + +enum CurrencyTokenSlots +{ +    CURRENCYTOKEN_SLOT_START    = 136, +    CURRENCYTOKEN_SLOT_END      = 168 +}; + +enum QuestBagSlots +{ +    QUESTBAG_SLOT_START         = 168, +    QUESTBAG_SLOT_END           = 200 +}; +  struct ItemPosCount  {      ItemPosCount(uint16 _pos, uint8 _count) : pos(_pos), count(_count) {} @@ -690,14 +748,15 @@ enum TradeSlots  enum TransferAbortReason  { -    TRANSFER_ABORT_MAX_PLAYERS          = 0x0001,           // Transfer Aborted: instance is full -    TRANSFER_ABORT_NOT_FOUND            = 0x0002,           // Transfer Aborted: instance not found -    TRANSFER_ABORT_TOO_MANY_INSTANCES   = 0x0003,           // You have entered too many instances recently. -    TRANSFER_ABORT_ZONE_IN_COMBAT       = 0x0005,           // Unable to zone in while an encounter is in progress. -    TRANSFER_ABORT_INSUF_EXPAN_LVL1     = 0x0106,           // You must have TBC expansion installed to access this area. -    TRANSFER_ABORT_DIFFICULTY1          = 0x0007,           // Normal difficulty mode is not available for %s. -    TRANSFER_ABORT_DIFFICULTY2          = 0x0107,           // Heroic difficulty mode is not available for %s. -    TRANSFER_ABORT_DIFFICULTY3          = 0x0207            // Epic difficulty mode is not available for %s. +    TRANSFER_ABORT_ERROR                    = 0x00, +    TRANSFER_ABORT_MAX_PLAYERS              = 0x01,         // Transfer Aborted: instance is full +    TRANSFER_ABORT_NOT_FOUND                = 0x02,         // Transfer Aborted: instance not found +    TRANSFER_ABORT_TOO_MANY_INSTANCES       = 0x03,         // You have entered too many instances recently. +    TRANSFER_ABORT_ZONE_IN_COMBAT           = 0x05,         // Unable to zone in while an encounter is in progress. +    TRANSFER_ABORT_INSUF_EXPAN_LVL          = 0x06,         // You must have <TBC,WotLK> expansion installed to access this area. +    TRANSFER_ABORT_DIFFICULTY               = 0x07,         // <Normal,Heroic,Epic> difficulty mode is not available for %s. +    TRANSFER_ABORT_UNIQUE_MESSAGE           = 0x08,         // Until you've escaped TLK's grasp, you cannot leave this place! +    TRANSFER_ABORT_TOO_MANY_REALM_INSTANCES = 0x09          // Additional instances cannot be launched, please try again later.  };  enum InstanceResetWarningType @@ -711,15 +770,16 @@ enum InstanceResetWarningType  struct MovementInfo  {      // common -    //uint32  flags; -    uint8   unk1; +    uint32  flags; +    uint16  unk1;      uint32  time;      float   x, y, z, o;      // transport      uint64  t_guid;      float   t_x, t_y, t_z, t_o;      uint32  t_time; -    // swimming and unk +    int8    t_seat; +    // swimming and unknown      float   s_pitch;      // last fall time      uint32  fallTime; @@ -730,17 +790,17 @@ struct MovementInfo      MovementInfo()      { -        //flags = +        flags = 0;          time = t_time = fallTime = 0;          unk1 = 0;          x = y = z = o = t_x = t_y = t_z = t_o = s_pitch = j_unk = j_sinAngle = j_cosAngle = j_xyspeed = u_unk1 = 0.0f;          t_guid = 0;      } -    /*void SetMovementFlags(uint32 _flags) +    void SetMovementFlags(uint32 _flags)      {          flags = _flags; -    }*/ +    }  };  // flags that use in movement check for example at spell casting @@ -813,10 +873,12 @@ enum PlayerLoginQueryIndex      PLAYER_LOGIN_QUERY_LOADDECLINEDNAMES        = 16,      PLAYER_LOGIN_QUERY_LOADGUILD                = 17,      PLAYER_LOGIN_QUERY_LOADARENAINFO            = 18, - -    MAX_PLAYER_LOGIN_QUERY +    PLAYER_LOGIN_QUERY_LOADACHIEVEMENTS         = 19, +    PLAYER_LOGIN_QUERY_LOADCRITERIAPROGRESS     = 20, +    MAX_PLAYER_LOGIN_QUERY                      = 21  }; +  // Player summoning auto-decline time (in secs)  #define MAX_PLAYER_SUMMON_DELAY                   (2*MINUTE)  #define MAX_MONEY_AMOUNT                       (0x7FFFFFFF-1) @@ -837,7 +899,7 @@ class TRINITY_DLL_SPEC PlayerTaxi          PlayerTaxi();          ~PlayerTaxi() {}          // Nodes -        void InitTaxiNodesForLevel(uint32 race, uint32 level); +        void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint32 level);          void LoadTaxiMask(const char* data);          void SaveTaxiMask(const char* data); @@ -940,7 +1002,7 @@ class TRINITY_DLL_SPEC Player : public Unit          void SendInitialPacketsBeforeAddToMap();          void SendInitialPacketsAfterAddToMap(); -        void SendTransferAborted(uint32 mapid, uint16 reason); +        void SendTransferAborted(uint32 mapid, uint8 reason, uint8 arg = 0);          void SendInstanceResetWarning(uint32 mapid, uint32 time);          bool CanInteractWithNPCs(bool alive = true) const; @@ -953,10 +1015,12 @@ class TRINITY_DLL_SPEC Player : public Unit          std::string afkMsg;          std::string dndMsg; +        uint32 GetBarberShopCost(uint8 newhairstyle, uint8 newhaircolor, uint8 newfacialhair); +          PlayerSocial *GetSocial() { return m_social; }          PlayerTaxi m_taxi; -        void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(),getLevel()); } +        void InitTaxiNodesForLevel() { m_taxi.InitTaxiNodesForLevel(getRace(), getClass(), getLevel()); }          bool ActivateTaxiPathTo(std::vector<uint32> const& nodes, uint32 mount_id = 0 , Creature* npc = NULL);                                                              // mount_id can be used in scripting calls          bool isAcceptTickets() const { return GetSession()->GetSecurity() >= SEC_GAMEMASTER && (m_ExtraFlags & PLAYER_EXTRA_GM_ACCEPT_TICKETS); } @@ -1052,6 +1116,7 @@ class TRINITY_DLL_SPEC Player : public Unit          bool HasBankBagSlot( uint8 slot ) const;          bool HasItemCount( uint32 item, uint32 count, bool inBankAlso = false ) const;          bool HasItemFitToSpellReqirements(SpellEntry const* spellInfo, Item const* ignoreItem = NULL); +        bool CanNoReagentCast(SpellEntry const* spellInfo) const;          Item* GetItemOrItemWithGemEquipped( uint32 item ) const;          uint8 CanTakeMoreSimilarItems(Item* pItem) const { return _CanTakeMoreSimilarItems(pItem->GetEntry(),pItem->GetCount(),pItem); }          uint8 CanTakeMoreSimilarItems(uint32 entry, uint32 count) const { return _CanTakeMoreSimilarItems(entry,count,NULL); } @@ -1130,6 +1195,11 @@ class TRINITY_DLL_SPEC Player : public Unit              // disarm applied only to mainhand weapon              return !IsInFeralForm() && (!mainhand || !HasFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_DISARMED) );          } +        bool IsTwoHandUsed() const +        { +            Item* mainItem = GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND); +            return mainItem && mainItem->GetProto()->InventoryType == INVTYPE_2HWEAPON && !CanTitanGrip(); +        }          void SendNewItem( Item *item, uint32 count, bool received, bool created, bool broadcast = false );          bool BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint64 bagguid, uint8 slot); @@ -1285,6 +1355,7 @@ class TRINITY_DLL_SPEC Player : public Unit          static void SetFloatValueInArray(Tokens& data,uint16 index, float value);          static void SetUInt32ValueInDB(uint16 index, uint32 value, uint64 guid);          static void SetFloatValueInDB(uint16 index, float value, uint64 guid); +        static void Customize(uint64 guid, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair);          static void SavePositionInDB(uint32 mapid, float x,float y,float z,float o,uint32 zone,uint64 guid);          bool m_mailsLoaded; @@ -1423,6 +1494,12 @@ class TRINITY_DLL_SPEC Player : public Unit          uint32 resetTalentsCost() const;          void InitTalentForLevel(); +        void InitGlyphsForLevel(); +        void SetGlyphSlot(uint8 slot, uint32 slottype) { SetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot, slottype); } +        uint32 GetGlyphSlot(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPH_SLOTS_1 + slot); } +        void SetGlyph(uint8 slot, uint32 glyph) { SetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot, glyph); } +        uint32 GetGlyph(uint8 slot) { return GetUInt32Value(PLAYER_FIELD_GLYPHS_1 + slot); } +          uint32 GetFreePrimaryProffesionPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS2); }          void SetFreePrimaryProffesions(uint16 profs) { SetUInt32Value(PLAYER_CHARACTER_POINTS2,profs); }          void InitPrimaryProffesions(); @@ -1431,8 +1508,6 @@ class TRINITY_DLL_SPEC Player : public Unit          PlayerSpellMap      & GetSpellMap()       { return m_spells; }          void AddSpellMod(SpellModifier* mod, bool apply); -        int32 GetTotalFlatMods(uint32 spellId, SpellModOp op); -        int32 GetTotalPctMods(uint32 spellId, SpellModOp op);          bool IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mod, Spell const* spell = NULL);          template <class T> T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL);          void RemoveSpellMods(Spell const* spell); @@ -1537,6 +1612,7 @@ class TRINITY_DLL_SPEC Player : public Unit          static uint32 GetArenaTeamIdFromDB(uint64 guid, uint8 slot);          void SetArenaTeamIdInvited(uint32 ArenaTeamId) { m_ArenaTeamIdInvited = ArenaTeamId; }          uint32 GetArenaTeamIdInvited() { return m_ArenaTeamIdInvited; } +        static void LeaveAllArenaTeams(uint64 guid);          void SetDifficulty(uint32 dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; }          uint8 GetDifficulty() { return m_dungeonDifficulty; } @@ -1589,6 +1665,10 @@ class TRINITY_DLL_SPEC Player : public Unit          void UpdateAllCritPercentages();          void UpdateParryPercentage();          void UpdateDodgePercentage(); +        void UpdateMeleeHitChances(); +        void UpdateRangedHitChances(); +        void UpdateSpellHitChances(); +          void UpdateAllSpellCritChances();          void UpdateSpellCritChance(uint32 school);          void UpdateExpertise(WeaponAttackType attType); @@ -1759,6 +1839,8 @@ class TRINITY_DLL_SPEC Player : public Unit          void SetCanParry(bool value);          bool CanBlock() const { return m_canBlock; }          void SetCanBlock(bool value); +        bool CanTitanGrip() const { return m_canTitanGrip ; } +        void SetCanTitanGrip(bool value) { m_canTitanGrip = value; }          void SetRegularAttackTime();          void SetBaseModValue(BaseModGroup modGroup, BaseModType modType, float value) { m_auraBaseMod[modGroup][modType] = value; } @@ -1792,7 +1874,7 @@ class TRINITY_DLL_SPEC Player : public Unit          void SendUpdateWorldState(uint32 Field, uint32 Value);          void SendDirectMessage(WorldPacket *data); -        void SendAuraDurationsForTarget(Unit* target); +        void SendAurasForTarget(Unit *target);          PlayerMenu* PlayerTalkClass;          std::vector<ItemSetEffect *> ItemSetEff; @@ -1953,6 +2035,7 @@ class TRINITY_DLL_SPEC Player : public Unit          MovementInfo m_movementInfo;          uint32 m_lastFallTime;          float  m_lastFallZ; +        Unit *m_mover;          void SetFallInformation(uint32 time, float z)          {              m_lastFallTime = time; @@ -1970,6 +2053,9 @@ class TRINITY_DLL_SPEC Player : public Unit          void SetClientControl(Unit* target, uint8 allowMove); +        void EnterVehicle(Vehicle *vehicle); +        void ExitVehicle(Vehicle *vehicle); +          uint64 GetFarSight() const { return GetUInt64Value(PLAYER_FARSIGHT); }          void SetFarSight(uint64 guid) { SetUInt64Value(PLAYER_FARSIGHT, guid); } @@ -1982,6 +2068,7 @@ class TRINITY_DLL_SPEC Player : public Unit          float GetTransOffsetZ() const { return m_movementInfo.t_z; }          float GetTransOffsetO() const { return m_movementInfo.t_o; }          uint32 GetTransTime() const { return m_movementInfo.t_time; } +        int8 GetTransSeat() const { return m_movementInfo.t_seat; }          uint32 GetSaveTimer() const { return m_nextSave; }          void   SetSaveTimer(uint32 timer) { m_nextSave = timer; } @@ -2081,6 +2168,18 @@ class TRINITY_DLL_SPEC Player : public Unit          WorldLocation& GetTeleportDest() { return m_teleport_dest; }          DeclinedName const* GetDeclinedNames() const { return m_declinedname; } +        uint8 GetRunesState() const { return m_runes->runeState; } +        uint8 GetBaseRune(uint8 index) const { return m_runes->runes[index].BaseRune; } +        uint8 GetCurrentRune(uint8 index) const { return m_runes->runes[index].CurrentRune; } +        uint8 GetRuneCooldown(uint8 index) const { return m_runes->runes[index].Cooldown; } +        void SetBaseRune(uint8 index, uint8 baseRune) { m_runes->runes[index].BaseRune = baseRune; } +        void SetCurrentRune(uint8 index, uint8 currentRune) { m_runes->runes[index].CurrentRune = currentRune; } +        void SetRuneCooldown(uint8 index, uint8 cooldown) { m_runes->runes[index].Cooldown = cooldown; m_runes->SetRuneState(index, (cooldown == 0) ? true : false); } +        void ConvertRune(uint8 index, uint8 newType); +        void ResyncRunes(uint8 count); +        void AddRunePower(uint8 index); +        void InitRunes(); +        AchievementMgr& GetAchievementMgr() { return m_achievementMgr; }          bool HasTitle(uint32 bitIndex);          bool HasTitle(CharTitlesEntry const* title) { return HasTitle(title->bit_index); }          void SetTitle(CharTitlesEntry const* title); @@ -2217,6 +2316,7 @@ class TRINITY_DLL_SPEC Player : public Unit          ActionButtonList m_actionButtons;          float m_auraBaseMod[BASEMOD_END][MOD_END]; +        int16 m_baseRatingValue[MAX_COMBAT_RATING];          SpellModList m_spellMods[MAX_SPELLMOD];          int32 m_SpellModRemoveCount; @@ -2250,7 +2350,6 @@ class TRINITY_DLL_SPEC Player : public Unit          bool   m_DailyQuestChanged;          time_t m_lastDailyQuestTime; -        uint32 m_regenTimer;          uint32 m_breathTimer;          uint32 m_drunkTimer;          uint16 m_drunk; @@ -2269,8 +2368,10 @@ class TRINITY_DLL_SPEC Player : public Unit          uint32 m_ArmorProficiency;          bool m_canParry;          bool m_canBlock; +        bool m_canTitanGrip;          uint8 m_swingErrorMsg;          float m_ammoDPS; +          ////////////////////Rest System/////////////////////          int time_inn_enter;          uint32 inn_pos_mapid; @@ -2317,6 +2418,8 @@ class TRINITY_DLL_SPEC Player : public Unit          bool m_farsightVision;          DeclinedName *m_declinedname; +        Runes *m_runes; +        AchievementMgr m_achievementMgr;      private:          // internal common parts for CanStore/StoreItem functions          uint8 _CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool swap, Item *pSrcItem ) const; diff --git a/src/game/QueryHandler.cpp b/src/game/QueryHandler.cpp index 9f9eecc2234..5b5679a81d7 100644 --- a/src/game/QueryHandler.cpp +++ b/src/game/QueryHandler.cpp @@ -33,6 +33,7 @@  #include "NPCHandler.h"  #include "ObjectAccessor.h"  #include "Pet.h" +#include "MapManager.h"  void WorldSession::SendNameQueryOpcode(Player *p)  { @@ -185,7 +186,6 @@ void WorldSession::HandleCreatureQueryOpcode( WorldPacket & recv_data )          data << (uint32)ci->type;          data << (uint32)ci->family;                         // family         wdbFeild9          data << (uint32)ci->rank;                           // rank           wdbFeild10 -        data << (uint32)0;                                  // unknown        wdbFeild11          data << (uint32)ci->PetSpellDataId;                 // Id from CreatureSpellData.dbc    wdbField12          data << (uint32)ci->Modelid1;                       // Modelid1          data << (uint32)ci->Modelid2;                       // Modelid2 @@ -276,20 +276,43 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/)      Corpse *corpse = GetPlayer()->GetCorpse(); -    uint8 found = 1;      if(!corpse) -        found = 0; +    { +        WorldPacket data(MSG_CORPSE_QUERY, 1); +        data << uint8(0);                                   // corpse not found +        SendPacket(&data); +        return; +    } -    WorldPacket data(MSG_CORPSE_QUERY, (1+found*(5*4))); -    data << uint8(found); -    if(found) +    int32 mapid = corpse->GetMapId(); +    float x = corpse->GetPositionX(); +    float y = corpse->GetPositionY(); +    float z = corpse->GetPositionZ(); +    int32 corpsemapid = _player->GetMapId(); + +    if(Map *map = corpse->GetMap())      { -        data << corpse->GetMapId(); -        data << corpse->GetPositionX(); -        data << corpse->GetPositionY(); -        data << corpse->GetPositionZ(); -        data << _player->GetMapId(); +        if(map->IsDungeon()) +        { +            if(!map->GetEntrancePos(mapid, x, y)) +                return; + +            Map *entrance_map = MapManager::Instance().GetMap(mapid, _player); +            if(!entrance_map) +                return; + +            z = entrance_map->GetHeight(x, y, MAX_HEIGHT); +            corpsemapid = corpse->GetMapId(); +        }      } + +    WorldPacket data(MSG_CORPSE_QUERY, 1+(5*4)); +    data << uint8(1);                                       // corpse found +    data << int32(mapid); +    data << float(x); +    data << float(y); +    data << float(z); +    data << int32(corpsemapid);      SendPacket(&data);  } diff --git a/src/game/QuestDef.cpp b/src/game/QuestDef.cpp index 4dd202bc344..e56a3a4c982 100644 --- a/src/game/QuestDef.cpp +++ b/src/game/QuestDef.cpp @@ -44,88 +44,90 @@ Quest::Quest(Field * questRecord)      QuestFlags = questRecord[17].GetUInt16();      uint32 SpecialFlags = questRecord[18].GetUInt16();      CharTitleId = questRecord[19].GetUInt32(); -    PrevQuestId = questRecord[20].GetInt32(); -    NextQuestId = questRecord[21].GetInt32(); -    ExclusiveGroup = questRecord[22].GetInt32(); -    NextQuestInChain = questRecord[23].GetUInt32(); -    SrcItemId = questRecord[24].GetUInt32(); -    SrcItemCount = questRecord[25].GetUInt32(); -    SrcSpell = questRecord[26].GetUInt32(); -    Title = questRecord[27].GetCppString(); -    Details = questRecord[28].GetCppString(); -    Objectives = questRecord[29].GetCppString(); -    OfferRewardText = questRecord[30].GetCppString(); -    RequestItemsText = questRecord[31].GetCppString(); -    EndText = questRecord[32].GetCppString(); +    PlayersSlain = questRecord[20].GetUInt32(); +    BonusTalents = questRecord[21].GetUInt32(); +    PrevQuestId = questRecord[22].GetInt32(); +    NextQuestId = questRecord[23].GetInt32(); +    ExclusiveGroup = questRecord[24].GetInt32(); +    NextQuestInChain = questRecord[25].GetUInt32(); +    SrcItemId = questRecord[26].GetUInt32(); +    SrcItemCount = questRecord[27].GetUInt32(); +    SrcSpell = questRecord[28].GetUInt32(); +    Title = questRecord[29].GetCppString(); +    Details = questRecord[30].GetCppString(); +    Objectives = questRecord[31].GetCppString(); +    OfferRewardText = questRecord[32].GetCppString(); +    RequestItemsText = questRecord[33].GetCppString(); +    EndText = questRecord[34].GetCppString();      for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) -        ObjectiveText[i] = questRecord[33+i].GetCppString(); +        ObjectiveText[i] = questRecord[35+i].GetCppString();      for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) -        ReqItemId[i] = questRecord[37+i].GetUInt32(); +        ReqItemId[i] = questRecord[39+i].GetUInt32();      for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) -        ReqItemCount[i] = questRecord[41+i].GetUInt32(); +        ReqItemCount[i] = questRecord[43+i].GetUInt32();      for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) -        ReqSourceId[i] = questRecord[45+i].GetUInt32(); +        ReqSourceId[i] = questRecord[47+i].GetUInt32();      for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) -        ReqSourceCount[i] = questRecord[49+i].GetUInt32(); +        ReqSourceCount[i] = questRecord[51+i].GetUInt32();      for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) -        ReqSourceRef[i] = questRecord[53+i].GetUInt32(); +        ReqSourceRef[i] = questRecord[55+i].GetUInt32();      for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) -        ReqCreatureOrGOId[i] = questRecord[57+i].GetInt32(); +        ReqCreatureOrGOId[i] = questRecord[59+i].GetInt32();      for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) -        ReqCreatureOrGOCount[i] = questRecord[61+i].GetUInt32(); +        ReqCreatureOrGOCount[i] = questRecord[63+i].GetUInt32();      for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) -        ReqSpell[i] = questRecord[65+i].GetUInt32(); +        ReqSpell[i] = questRecord[67+i].GetUInt32();      for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) -        RewChoiceItemId[i] = questRecord[69+i].GetUInt32(); +        RewChoiceItemId[i] = questRecord[71+i].GetUInt32();      for (int i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i) -        RewChoiceItemCount[i] = questRecord[75+i].GetUInt32(); +        RewChoiceItemCount[i] = questRecord[77+i].GetUInt32();      for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) -        RewItemId[i] = questRecord[81+i].GetUInt32(); +        RewItemId[i] = questRecord[83+i].GetUInt32();      for (int i = 0; i < QUEST_REWARDS_COUNT; ++i) -        RewItemCount[i] = questRecord[85+i].GetUInt32(); +        RewItemCount[i] = questRecord[87+i].GetUInt32();      for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) -        RewRepFaction[i] = questRecord[89+i].GetUInt32(); +        RewRepFaction[i] = questRecord[91+i].GetUInt32();      for (int i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) -        RewRepValue[i] = questRecord[94+i].GetInt32(); - -    RewHonorableKills = questRecord[99].GetUInt32(); -    RewOrReqMoney = questRecord[100].GetInt32(); -    RewMoneyMaxLevel = questRecord[101].GetUInt32(); -    RewSpell = questRecord[102].GetUInt32(); -    RewSpellCast = questRecord[103].GetUInt32(); -    RewMailTemplateId = questRecord[104].GetUInt32(); -    RewMailDelaySecs = questRecord[105].GetUInt32(); -    PointMapId = questRecord[106].GetUInt32(); -    PointX = questRecord[107].GetFloat(); -    PointY = questRecord[108].GetFloat(); -    PointOpt = questRecord[109].GetUInt32(); +        RewRepValue[i] = questRecord[96+i].GetInt32(); + +    RewHonorableKills = questRecord[101].GetUInt32(); +    RewOrReqMoney = questRecord[102].GetInt32(); +    RewMoneyMaxLevel = questRecord[103].GetUInt32(); +    RewSpell = questRecord[104].GetUInt32(); +    RewSpellCast = questRecord[105].GetUInt32(); +    RewMailTemplateId = questRecord[106].GetUInt32(); +    RewMailDelaySecs = questRecord[107].GetUInt32(); +    PointMapId = questRecord[108].GetUInt32(); +    PointX = questRecord[109].GetFloat(); +    PointY = questRecord[110].GetFloat(); +    PointOpt = questRecord[111].GetUInt32();      for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) -        DetailsEmote[i] = questRecord[110+i].GetUInt32(); +        DetailsEmote[i] = questRecord[112+i].GetUInt32(); -    IncompleteEmote = questRecord[114].GetUInt32(); -    CompleteEmote = questRecord[115].GetUInt32(); +    IncompleteEmote = questRecord[116].GetUInt32(); +    CompleteEmote = questRecord[117].GetUInt32();      for (int i = 0; i < QUEST_EMOTE_COUNT; ++i) -        OfferRewardEmote[i] = questRecord[116+i].GetInt32(); +        OfferRewardEmote[i] = questRecord[118+i].GetInt32(); -    QuestStartScript = questRecord[120].GetUInt32(); -    QuestCompleteScript = questRecord[121].GetUInt32(); +    QuestStartScript = questRecord[122].GetUInt32(); +    QuestCompleteScript = questRecord[123].GetUInt32();      QuestFlags |= SpecialFlags << 16; diff --git a/src/game/QuestDef.h b/src/game/QuestDef.h index 52f58c2c87e..1904cbe08a8 100644 --- a/src/game/QuestDef.h +++ b/src/game/QuestDef.h @@ -44,30 +44,33 @@ class ObjectMgr;  enum QuestFailedReasons  {      INVALIDREASON_DONT_HAVE_REQ                 = 0, -    INVALIDREASON_QUEST_FAILED_LOW_LEVEL        = 1,        //You are not high enough level for that quest. -    INVALIDREASON_QUEST_FAILED_WRONG_RACE       = 6,        //That quest is not available to your race. -    INVALIDREASON_QUEST_ALREADY_DONE            = 7,        //You have completed that quest. -    INVALIDREASON_QUEST_ONLY_ONE_TIMED          = 12,       //You can only be on one timed quest at a time. -    INVALIDREASON_QUEST_ALREADY_ON              = 13,       //You are already on that quest -    INVALIDREASON_QUEST_FAILED_EXPANSION        = 16,       //This quest requires an expansion enabled account. -    INVALIDREASON_QUEST_ALREADY_ON2             = 18,       //You are already on that quest -    INVALIDREASON_QUEST_FAILED_MISSING_ITEMS    = 21,       //You don't have the required items with you. Check storage. -    INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23,       //You don't have enough money for that quest. -    INVALIDREASON_DAILY_QUESTS_REMAINING        = 26,       //You have already completed 10 daily quests today -    INVALIDREASON_QUEST_FAILED_CAIS             = 27,       //You cannot complete quests once you have reached tired time +    INVALIDREASON_QUEST_FAILED_LOW_LEVEL        = 1,        // You are not high enough level for that quest. +    INVALIDREASON_QUEST_FAILED_WRONG_RACE       = 6,        // That quest is not available to your race. +    INVALIDREASON_QUEST_ALREADY_DONE            = 7,        // You have completed that quest. +    INVALIDREASON_QUEST_ONLY_ONE_TIMED          = 12,       // You can only be on one timed quest at a time. +    INVALIDREASON_QUEST_ALREADY_ON              = 13,       // You are already on that quest. +    INVALIDREASON_QUEST_FAILED_EXPANSION        = 16,       // This quest requires an expansion enabled account. +    INVALIDREASON_QUEST_ALREADY_ON2             = 18,       // You are already on that quest. +    INVALIDREASON_QUEST_FAILED_MISSING_ITEMS    = 21,       // You don't have the required items with you. Check storage. +    INVALIDREASON_QUEST_FAILED_NOT_ENOUGH_MONEY = 23,       // You don't have enough money for that quest. +    INVALIDREASON_DAILY_QUESTS_REMAINING        = 26,       // You have already completed 25 daily quests today. +    INVALIDREASON_QUEST_FAILED_CAIS             = 27,       // You cannot complete quests once you have reached tired time. +    INVALIDREASON_DAILY_QUEST_COMPLETED_TODAY   = 29        // You have completed that daily quest today.  };  enum QuestShareMessages  { -    QUEST_PARTY_MSG_SHARING_QUEST   = 0, -    QUEST_PARTY_MSG_CANT_TAKE_QUEST = 1, -    QUEST_PARTY_MSG_ACCEPT_QUEST    = 2, -    QUEST_PARTY_MSG_REFUSE_QUEST    = 3, -    QUEST_PARTY_MSG_TOO_FAR         = 4, -    QUEST_PARTY_MSG_BUSY            = 5, -    QUEST_PARTY_MSG_LOG_FULL        = 6, -    QUEST_PARTY_MSG_HAVE_QUEST      = 7, -    QUEST_PARTY_MSG_FINISH_QUEST    = 8, +    QUEST_PARTY_MSG_SHARING_QUEST           = 0, +    QUEST_PARTY_MSG_CANT_TAKE_QUEST         = 1, +    QUEST_PARTY_MSG_ACCEPT_QUEST            = 2, +    QUEST_PARTY_MSG_DECLINE_QUEST           = 3, +    QUEST_PARTY_MSG_BUSY                    = 4, +    QUEST_PARTY_MSG_LOG_FULL                = 5, +    QUEST_PARTY_MSG_HAVE_QUEST              = 6, +    QUEST_PARTY_MSG_FINISH_QUEST            = 7, +    QUEST_PARTY_MSG_CANT_BE_SHARED_TODAY    = 8, +    QUEST_PARTY_MSG_SHARING_TIMER_EXPIRED   = 9, +    QUEST_PARTY_MSG_NOT_IN_PARTY            = 10  };  enum __QuestTradeSkill @@ -190,6 +193,8 @@ class Quest          int32  GetExclusiveGroup() const { return ExclusiveGroup; }          uint32 GetNextQuestInChain() const { return NextQuestInChain; }          uint32 GetCharTitleId() const { return CharTitleId; } +        uint32 GetPlayersSlain() const { return PlayersSlain; } +        uint32 GetBonusTalents() const { return BonusTalents; }          uint32 GetSrcItemId() const { return SrcItemId; }          uint32 GetSrcItemCount() const { return SrcItemCount; }          uint32 GetSrcSpell() const { return SrcSpell; } @@ -277,6 +282,8 @@ class Quest          uint32 LimitTime;          uint32 QuestFlags;          uint32 CharTitleId; +        uint32 PlayersSlain; +        uint32 BonusTalents;          int32  PrevQuestId;          int32  NextQuestId;          int32  ExclusiveGroup; diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index abb285e6dbb..784a2affbc0 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -451,12 +451,6 @@ void WorldSession::HandleQuestPushToParty(WorldPacket& recvPacket)                      _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); -                    if( _player->GetDistance( pPlayer ) > 10 ) -                    { -                        _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_TOO_FAR ); -                        continue; -                    } -                      if( !pPlayer->SatisfyQuestStatus( pQuest, false ) )                      {                          _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST ); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 07840998cf2..b8a0f135ab7 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -88,7 +88,8 @@ enum Classes  #define CLASSMASK_ALL_PLAYABLE \      ((1<<(CLASS_WARRIOR-1))|(1<<(CLASS_PALADIN-1))|(1<<(CLASS_HUNTER-1))| \      (1<<(CLASS_ROGUE-1))  |(1<<(CLASS_PRIEST-1)) |(1<<(CLASS_SHAMAN-1))| \ -    (1<<(CLASS_MAGE-1))   |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1))   ) +    (1<<(CLASS_MAGE-1))   |(1<<(CLASS_WARLOCK-1))|(1<<(CLASS_DRUID-1)) | \ +    (1<<(CLASS_DEATH_KNIGHT-1)) )  #define CLASSMASK_WAND_USERS ((1<<(CLASS_PRIEST-1))|(1<<(CLASS_MAGE-1))|(1<<(CLASS_WARLOCK-1))) @@ -134,11 +135,12 @@ enum Powers      POWER_FOCUS                         = 2,      POWER_ENERGY                        = 3,      POWER_HAPPINESS                     = 4, -    POWER_RUNES                         = 5, +    POWER_RUNE                          = 5, +    POWER_RUNIC_POWER                   = 6,      POWER_HEALTH                        = 0xFFFFFFFE    // (-2 as signed value)  }; -#define MAX_POWERS                        5                 // not count POWER_RUNES for now +#define MAX_POWERS                        7  enum SpellSchools  { @@ -199,10 +201,11 @@ enum ItemQualities      ITEM_QUALITY_RARE                  = 3,                 //BLUE      ITEM_QUALITY_EPIC                  = 4,                 //PURPLE      ITEM_QUALITY_LEGENDARY             = 5,                 //ORANGE -    ITEM_QUALITY_ARTIFACT              = 6                  //LIGHT YELLOW +    ITEM_QUALITY_ARTIFACT              = 6,                 //LIGHT YELLOW +    ITEM_QUALITY_HEIRLOOM              = 7  }; -#define MAX_ITEM_QUALITY                 7 +#define MAX_ITEM_QUALITY                 8  enum SpellCategory  { @@ -217,7 +220,7 @@ enum SpellCategory  #define SPELL_ATTR_UNK0                           0x00000001            // 0  #define SPELL_ATTR_RANGED                         0x00000002            // 1 All ranged abilities have this flag  #define SPELL_ATTR_ON_NEXT_SWING_1                0x00000004            // 2 on next swing -#define SPELL_ATTR_UNK3                           0x00000008            // 3 not set in 2.4.2 +#define SPELL_ATTR_UNK3                           0x00000008            // 3 not set in 3.0.3  #define SPELL_ATTR_UNK4                           0x00000010            // 4  #define SPELL_ATTR_UNK5                           0x00000020            // 5 trade spells?  #define SPELL_ATTR_PASSIVE                        0x00000040            // 6 Passive spell @@ -272,7 +275,7 @@ enum SpellCategory  #define SPELL_ATTR_EX_REQ_COMBO_POINTS2           0x00400000            // 22 Req combo points on target  #define SPELL_ATTR_EX_UNK23                       0x00800000            // 23  #define SPELL_ATTR_EX_UNK24                       0x01000000            // 24 Req fishing pole?? -#define SPELL_ATTR_EX_UNK25                       0x02000000            // 25 not set in 2.4.2 +#define SPELL_ATTR_EX_UNK25                       0x02000000            // 25  #define SPELL_ATTR_EX_UNK26                       0x04000000            // 26  #define SPELL_ATTR_EX_UNK27                       0x08000000            // 27  #define SPELL_ATTR_EX_UNK28                       0x10000000            // 28 @@ -288,14 +291,14 @@ enum SpellCategory  #define SPELL_ATTR_EX2_UNK5                       0x00000020            // 5  #define SPELL_ATTR_EX2_UNK6                       0x00000040            // 6  #define SPELL_ATTR_EX2_UNK7                       0x00000080            // 7 -#define SPELL_ATTR_EX2_UNK8                       0x00000100            // 8 not set in 2.4.2 +#define SPELL_ATTR_EX2_UNK8                       0x00000100            // 8 not set in 3.0.3  #define SPELL_ATTR_EX2_UNK9                       0x00000200            // 9  #define SPELL_ATTR_EX2_UNK10                      0x00000400            // 10  #define SPELL_ATTR_EX2_HEALTH_FUNNEL              0x00000800            // 11  #define SPELL_ATTR_EX2_UNK12                      0x00001000            // 12  #define SPELL_ATTR_EX2_UNK13                      0x00002000            // 13  #define SPELL_ATTR_EX2_UNK14                      0x00004000            // 14 -#define SPELL_ATTR_EX2_UNK15                      0x00008000            // 15 not set in 2.4.2 +#define SPELL_ATTR_EX2_UNK15                      0x00008000            // 15 not set in 3.0.3  #define SPELL_ATTR_EX2_TAME_BEAST                 0x00010000            // 16  #define SPELL_ATTR_EX2_NOT_RESET_AUTOSHOT         0x00020000            // 17 Hunters Shot and Stings only have this flag  #define SPELL_ATTR_EX2_UNK18                      0x00040000            // 18 Only Revive pet - possible req dead pet @@ -413,37 +416,37 @@ enum SpellCategory  #define SPELL_ATTR_EX5_UNK31                      0x80000000            // 31 Forces all nearby enemies to focus attacks caster  #define SPELL_ATTR_EX6_UNK0                       0x00000001            // 0 Only Move spell have this flag -#define SPELL_ATTR_EX6_UNK1                       0x00000002            // 1 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK1                       0x00000002            // 1 not set in 3.0.3  #define SPELL_ATTR_EX6_UNK2                       0x00000004            // 2  #define SPELL_ATTR_EX6_UNK3                       0x00000008            // 3 -#define SPELL_ATTR_EX6_UNK4                       0x00000010            // 4 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK4                       0x00000010            // 4  #define SPELL_ATTR_EX6_UNK5                       0x00000020            // 5  #define SPELL_ATTR_EX6_UNK6                       0x00000040            // 6  #define SPELL_ATTR_EX6_UNK7                       0x00000080            // 7  #define SPELL_ATTR_EX6_UNK8                       0x00000100            // 8 -#define SPELL_ATTR_EX6_UNK9                       0x00000200            // 9 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK9                       0x00000200            // 9  #define SPELL_ATTR_EX6_UNK10                      0x00000400            // 10  #define SPELL_ATTR_EX6_UNK11                      0x00000800            // 11 -#define SPELL_ATTR_EX6_UNK12                      0x00001000            // 12 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK13                      0x00002000            // 13 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK14                      0x00004000            // 14 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK15                      0x00008000            // 15 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK16                      0x00010000            // 16 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK17                      0x00020000            // 17 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK18                      0x00040000            // 18 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK19                      0x00080000            // 19 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK20                      0x00100000            // 20 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK21                      0x00200000            // 21 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK22                      0x00400000            // 22 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK23                      0x00800000            // 23 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK24                      0x01000000            // 24 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK25                      0x02000000            // 25 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK26                      0x04000000            // 26 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK27                      0x08000000            // 27 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK28                      0x10000000            // 28 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK29                      0x20000000            // 29 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK30                      0x40000000            // 30 not set in 2.4.2 -#define SPELL_ATTR_EX6_UNK31                      0x80000000            // 31 not set in 2.4.2 +#define SPELL_ATTR_EX6_UNK12                      0x00001000            // 12 +#define SPELL_ATTR_EX6_UNK13                      0x00002000            // 13 +#define SPELL_ATTR_EX6_UNK14                      0x00004000            // 14 +#define SPELL_ATTR_EX6_UNK15                      0x00008000            // 15 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK16                      0x00010000            // 16 +#define SPELL_ATTR_EX6_UNK17                      0x00020000            // 17 +#define SPELL_ATTR_EX6_UNK18                      0x00040000            // 18 +#define SPELL_ATTR_EX6_UNK19                      0x00080000            // 19 +#define SPELL_ATTR_EX6_UNK20                      0x00100000            // 20 +#define SPELL_ATTR_EX6_UNK21                      0x00200000            // 21 +#define SPELL_ATTR_EX6_UNK22                      0x00400000            // 22 +#define SPELL_ATTR_EX6_UNK23                      0x00800000            // 23 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK24                      0x01000000            // 24 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK25                      0x02000000            // 25 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK26                      0x04000000            // 26 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK27                      0x08000000            // 27 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK28                      0x10000000            // 28 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK29                      0x20000000            // 29 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK30                      0x40000000            // 30 not set in 3.0.3 +#define SPELL_ATTR_EX6_UNK31                      0x80000000            // 31 not set in 3.0.3  enum SheathTypes  { @@ -566,7 +569,7 @@ enum SpellEffects      SPELL_EFFECT_SUMMON_GUARDIAN           = 42,      SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43,      SPELL_EFFECT_SKILL_STEP                = 44, -    SPELL_EFFECT_UNDEFINED_45              = 45, +    SPELL_EFFECT_ADD_HONOR                 = 45,      SPELL_EFFECT_SPAWN                     = 46,      SPELL_EFFECT_TRADE_SKILL               = 47,      SPELL_EFFECT_STEALTH                   = 48, @@ -586,16 +589,16 @@ enum SpellEffects      SPELL_EFFECT_POWER_BURN                = 62,      SPELL_EFFECT_THREAT                    = 63,      SPELL_EFFECT_TRIGGER_SPELL             = 64, -    SPELL_EFFECT_HEALTH_FUNNEL             = 65, -    SPELL_EFFECT_POWER_FUNNEL              = 66, +    SPELL_EFFECT_APPLY_AREA_AURA_RAID      = 65, +    SPELL_EFFECT_CREATE_MANA_GEM           = 66,      SPELL_EFFECT_HEAL_MAX_HEALTH           = 67,      SPELL_EFFECT_INTERRUPT_CAST            = 68,      SPELL_EFFECT_DISTRACT                  = 69,      SPELL_EFFECT_PULL                      = 70,      SPELL_EFFECT_PICKPOCKET                = 71,      SPELL_EFFECT_ADD_FARSIGHT              = 72, -    SPELL_EFFECT_SUMMON_POSSESSED          = 73, -    SPELL_EFFECT_SUMMON_TOTEM              = 74, +    SPELL_EFFECT_UNTRAIN_TALENTS           = 73, +    SPELL_EFFECT_APPLY_GLYPH               = 74,      SPELL_EFFECT_HEAL_MECHANICAL           = 75,      SPELL_EFFECT_SUMMON_OBJECT_WILD        = 76,      SPELL_EFFECT_SCRIPT_EFFECT             = 77, @@ -608,10 +611,10 @@ enum SpellEffects      SPELL_EFFECT_STUCK                     = 84,      SPELL_EFFECT_SUMMON_PLAYER             = 85,      SPELL_EFFECT_ACTIVATE_OBJECT           = 86, -    SPELL_EFFECT_SUMMON_TOTEM_SLOT1        = 87, -    SPELL_EFFECT_SUMMON_TOTEM_SLOT2        = 88, -    SPELL_EFFECT_SUMMON_TOTEM_SLOT3        = 89, -    SPELL_EFFECT_SUMMON_TOTEM_SLOT4        = 90, +    SPELL_EFFECT_WMO_DAMAGE                = 87, +    SPELL_EFFECT_WMO_REPAIR                = 88, +    SPELL_EFFECT_WMO_CHANGE                = 89, +    SPELL_EFFECT_KILL_CREDIT               = 90,      SPELL_EFFECT_THREAT_ALL                = 91,      SPELL_EFFECT_ENCHANT_HELD_ITEM         = 92,      SPELL_EFFECT_SUMMON_PHANTASM           = 93, //unused @@ -655,19 +658,19 @@ enum SpellEffects      SPELL_EFFECT_131                       = 131,      SPELL_EFFECT_132                       = 132,      SPELL_EFFECT_UNLEARN_SPECIALIZATION    = 133, -    SPELL_EFFECT_KILL_CREDIT               = 134, +    SPELL_EFFECT_KILL_CREDIT2              = 134,      SPELL_EFFECT_135                       = 135,      SPELL_EFFECT_HEAL_PCT                  = 136,      SPELL_EFFECT_ENERGIZE_PCT              = 137,      SPELL_EFFECT_138                       = 138, -    SPELL_EFFECT_139                       = 139, +    SPELL_EFFECT_CLEAR_QUEST               = 139,      SPELL_EFFECT_FORCE_CAST                = 140,      SPELL_EFFECT_141                       = 141,      SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE  = 142,      SPELL_EFFECT_APPLY_AREA_AURA_OWNER     = 143,      SPELL_EFFECT_144                       = 144,      SPELL_EFFECT_145                       = 145, -    SPELL_EFFECT_146                       = 146, +    SPELL_EFFECT_ACTIVATE_RUNE             = 146,      SPELL_EFFECT_QUEST_FAIL                = 147,      SPELL_EFFECT_148                       = 148,      SPELL_EFFECT_149                       = 149, @@ -675,7 +678,13 @@ enum SpellEffects      SPELL_EFFECT_TRIGGER_SPELL_2           = 151,      SPELL_EFFECT_152                       = 152,      SPELL_EFFECT_153                       = 153, -    TOTAL_SPELL_EFFECTS                    = 154 +    SPELL_EFFECT_154                       = 154, +    SPELL_EFFECT_TITAN_GRIP                = 155, +    SPELL_EFFECT_ADD_SOCKET                = 156, +    SPELL_EFFECT_157                       = 157, +    SPELL_EFFECT_MILLING                   = 158, +    SPELL_EFFECT_ALLOW_RENAME_PET          = 159, +    TOTAL_SPELL_EFFECTS                    = 160  };  // Spell aura states @@ -703,7 +712,8 @@ enum AuraState      AURA_STATE_DEADLY_POISON                = 16,           //   T |      AURA_STATE_FORBEARANCE                  = 17,           //  c t|      AURA_STATE_WEAKENED_SOUL                = 18,           //    t| -    AURA_STATE_HYPOTHERMIA                  = 19            //  c  | +    AURA_STATE_HYPOTHERMIA                  = 19,           //  c  | +    AURA_STATE_HEALTH_ABOVE_75_PERCENT      = 23,           // C   | not implemented yet  };  // Spell mechanics @@ -711,11 +721,11 @@ enum Mechanics  {      MECHANIC_NONE             = 0,      MECHANIC_CHARM            = 1, -    MECHANIC_CONFUSED         = 2, +    MECHANIC_DISORIENTED      = 2,      MECHANIC_DISARM           = 3,      MECHANIC_DISTRACT         = 4,      MECHANIC_FEAR             = 5, -    MECHANIC_FUMBLE           = 6, +    MECHANIC_GRIP             = 6,      MECHANIC_ROOT             = 7,      MECHANIC_PACIFY           = 8,                          //0 spells use this mechanic      MECHANIC_SILENCE          = 9, @@ -731,7 +741,7 @@ enum Mechanics      MECHANIC_SHIELD           = 19,      MECHANIC_SHACKLE          = 20,      MECHANIC_MOUNT            = 21, -    MECHANIC_PERSUADE         = 22,                         //0 spells use this mechanic +    MECHANIC_INFECTED         = 22,      MECHANIC_TURN             = 23,      MECHANIC_HORROR           = 24,      MECHANIC_INVULNERABILITY  = 25, @@ -739,12 +749,13 @@ enum Mechanics      MECHANIC_DAZE             = 27,      MECHANIC_DISCOVERY        = 28,      MECHANIC_IMMUNE_SHIELD    = 29,                         // Divine (Blessing) Shield/Protection and Ice Block -    MECHANIC_SAPPED           = 30 +    MECHANIC_SAPPED           = 30, +    MECHANIC_ENRAGED          = 31  };  // Used for spell 42292 Immune Movement Impairment and Loss of Control (0x49967da6)  #define IMMUNE_TO_MOVEMENT_IMPAIRMENT_AND_LOSS_CONTROL_MASK ( \ -    (1<<MECHANIC_CHARM   )|(1<<MECHANIC_CONFUSED )|(1<<MECHANIC_FEAR  )| \ +    (1<<MECHANIC_CHARM   )|(1<<MECHANIC_DISORIENTED )|(1<<MECHANIC_FEAR  )| \      (1<<MECHANIC_ROOT    )|(1<<MECHANIC_PACIFY   )|(1<<MECHANIC_SLEEP )| \      (1<<MECHANIC_SNARE   )|(1<<MECHANIC_STUN     )|(1<<MECHANIC_FREEZE)| \      (1<<MECHANIC_KNOCKOUT)|(1<<MECHANIC_POLYMORPH)|(1<<MECHANIC_BANISH)| \ @@ -764,7 +775,8 @@ enum DispelType      DISPEL_ALL          = 7,      DISPEL_SPE_NPC_ONLY = 8,      DISPEL_ENRAGE       = 9, -    DISPEL_ZG_TICKET    = 10 +    DISPEL_ZG_TICKET    = 10, +    DESPEL_OLD_UNUSED   = 11  };  #define DISPEL_ALL_MASK ( (1<<DISPEL_MAGIC) | (1<<DISPEL_CURSE) | (1<<DISPEL_DISEASE) | (1<<DISPEL_POISON) ) @@ -977,9 +989,10 @@ enum GameobjectTypes      GAMEOBJECT_TYPE_BARBER_CHAIR           = 32,      GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING  = 33,      GAMEOBJECT_TYPE_GUILD_BANK             = 34, +    GAMEOBJECT_TYPE_TRAPDOOR               = 35  }; -#define MAX_GAMEOBJECT_TYPE                  35             // sending to client this or greater value can crash client. +#define MAX_GAMEOBJECT_TYPE                  36             // sending to client this or greater value can crash client.  #define GAMEOBJECT_FISHINGNODE_ENTRY        35591           // Better to define it somewhere instead of hardcoding everywhere @@ -1546,7 +1559,9 @@ enum LockType      LOCKTYPE_BLASTING              = 16,      LOCKTYPE_SLOW_OPEN             = 17,      LOCKTYPE_SLOW_CLOSE            = 18, -    LOCKTYPE_FISHING               = 19 +    LOCKTYPE_FISHING               = 19, +    LOCKTYPE_INSCRIPTION           = 20, +    LOCKTYPE_OPEN_FROM_VEHICLE     = 21  };  enum TrainerType                                            // this is important type for npcs! @@ -1600,7 +1615,7 @@ enum CreatureFamily      CREATURE_FAMILY_IMP            = 23,      CREATURE_FAMILY_BAT            = 24,      CREATURE_FAMILY_HYENA          = 25, -    CREATURE_FAMILY_OWL            = 26, +    CREATURE_FAMILY_BIRD_OF_PREY   = 26,      CREATURE_FAMILY_WIND_SERPENT   = 27,      CREATURE_FAMILY_REMOTE_CONTROL = 28,      CREATURE_FAMILY_FELGUARD       = 29, @@ -1610,7 +1625,16 @@ enum CreatureFamily      CREATURE_FAMILY_SPOREBAT       = 33,      CREATURE_FAMILY_NETHER_RAY     = 34,      CREATURE_FAMILY_SERPENT        = 35, -    CREATURE_FAMILY_SEA_LION       = 36 +    CREATURE_FAMILY_MOTH           = 37, +    CREATURE_FAMILY_CHIMAERA       = 38, +    CREATURE_FAMILY_DEVILSAUR      = 39, +    CREATURE_FAMILY_GHOUL          = 40, +    CREATURE_FAMILY_SILITHID       = 41, +    CREATURE_FAMILY_WORM           = 42, +    CREATURE_FAMILY_RHINO          = 43, +    CREATURE_FAMILY_WASP           = 44, +    CREATURE_FAMILY_CORE_HOUND     = 45, +    CREATURE_FAMILY_SPIRIT_BEAST   = 46  };  enum CreatureTypeFlags @@ -1642,6 +1666,8 @@ enum QuestTypes      QUEST_TYPE_LEGENDARY           = 83,      QUEST_TYPE_ESCORT              = 84,      QUEST_TYPE_HEROIC              = 85, +    QUEST_TYPE_RAID_10             = 88, +    QUEST_TYPE_RAID_25             = 89  };  // values based at QuestSort.dbc @@ -1652,7 +1678,7 @@ enum QuestSort      QUEST_SORT_SEASONAL            = 22,      QUEST_SORT_UNDERCITY_OLD       = 23,      QUEST_SORT_HERBALISM           = 24, -    QUEST_SORT_SCARLET_MONASTERY_OLD= 25, +    QUEST_SORT_BATTLEGROUNDS       = 25,      QUEST_SORT_ULDAMN_OLD          = 41,      QUEST_SORT_WARLOCK             = 61,      QUEST_SORT_WARRIOR             = 81, @@ -1681,22 +1707,26 @@ enum QuestSort      QUEST_SORT_REPUTATION          = 367,      QUEST_SORT_INVASION            = 368,      QUEST_SORT_MIDSUMMER           = 369, -    QUEST_SORT_BREWFEST            = 370 +    QUEST_SORT_BREWFEST            = 370, +    QUEST_SORT_INSCRIPTION         = 371, +    QUEST_SORT_DEATH_KNIGHT        = 372, +    QUEST_SORT_JEWELCRAFTING       = 373  };  inline uint8 ClassByQuestSort(int32 QuestSort)  {      switch(QuestSort)      { -        case QUEST_SORT_WARLOCK: return CLASS_WARLOCK; -        case QUEST_SORT_WARRIOR: return CLASS_WARRIOR; -        case QUEST_SORT_SHAMAN:  return CLASS_SHAMAN; -        case QUEST_SORT_PALADIN: return CLASS_PALADIN; -        case QUEST_SORT_MAGE:    return CLASS_MAGE; -        case QUEST_SORT_ROGUE:   return CLASS_ROGUE; -        case QUEST_SORT_HUNTER:  return CLASS_HUNTER; -        case QUEST_SORT_PRIEST:  return CLASS_PRIEST; -        case QUEST_SORT_DRUID:   return CLASS_DRUID; +        case QUEST_SORT_WARLOCK:        return CLASS_WARLOCK; +        case QUEST_SORT_WARRIOR:        return CLASS_WARRIOR; +        case QUEST_SORT_SHAMAN:         return CLASS_SHAMAN; +        case QUEST_SORT_PALADIN:        return CLASS_PALADIN; +        case QUEST_SORT_MAGE:           return CLASS_MAGE; +        case QUEST_SORT_ROGUE:          return CLASS_ROGUE; +        case QUEST_SORT_HUNTER:         return CLASS_HUNTER; +        case QUEST_SORT_PRIEST:         return CLASS_PRIEST; +        case QUEST_SORT_DRUID:          return CLASS_DRUID; +        case QUEST_SORT_DEATH_KNIGHT:   return CLASS_DEATH_KNIGHT;      }      return 0;  } @@ -1708,7 +1738,6 @@ enum SkillType      SKILL_ARMS                     = 26,      SKILL_COMBAT                   = 38,      SKILL_SUBTLETY                 = 39, -    SKILL_POISONS                  = 40,      SKILL_SWORDS                   = 43,      SKILL_AXES                     = 44,      SKILL_BOWS                     = 45, @@ -1716,8 +1745,8 @@ enum SkillType      SKILL_BEAST_MASTERY            = 50,      SKILL_SURVIVAL                 = 51,      SKILL_MACES                    = 54, -    SKILL_HOLY                     = 56,      SKILL_2H_SWORDS                = 55, +    SKILL_HOLY                     = 56,      SKILL_SHADOW                   = 78,      SKILL_DEFENSE                  = 95,      SKILL_LANG_COMMON              = 98, @@ -1773,24 +1802,20 @@ enum SkillType      SKILL_PET_BOAR                 = 211,      SKILL_PET_CROCILISK            = 212,      SKILL_PET_CARRION_BIRD         = 213, -    SKILL_PET_GORILLA              = 215,      SKILL_PET_CRAB                 = 214, +    SKILL_PET_GORILLA              = 215,      SKILL_PET_RAPTOR               = 217,      SKILL_PET_TALLSTRIDER          = 218,      SKILL_RACIAL_UNDED             = 220, -    SKILL_WEAPON_TALENTS           = 222,      SKILL_CROSSBOWS                = 226, -    SKILL_SPEARS                   = 227,      SKILL_WANDS                    = 228,      SKILL_POLEARMS                 = 229,      SKILL_PET_SCORPID              = 236,      SKILL_ARCANE                   = 237, -    SKILL_OPEN_LOCK                = 242,      SKILL_PET_TURTLE               = 251,      SKILL_ASSASSINATION            = 253,      SKILL_FURY                     = 256,      SKILL_PROTECTION               = 257, -    SKILL_BEAST_TRAINING           = 261,      SKILL_PROTECTION2              = 267,      SKILL_PET_TALENTS              = 270,      SKILL_PLATE_MAIL               = 293, @@ -1820,7 +1845,7 @@ enum SkillType      SKILL_LOCKPICKING              = 633,      SKILL_PET_BAT                  = 653,      SKILL_PET_HYENA                = 654, -    SKILL_PET_OWL                  = 655, +    SKILL_PET_BIRD_OF_PREY         = 655,      SKILL_PET_WIND_SERPENT         = 656,      SKILL_LANG_GUTTERSPEAK         = 673,      SKILL_RIDING_KODO              = 713, @@ -1840,10 +1865,27 @@ enum SkillType      SKILL_PET_WARP_STALKER         = 766,      SKILL_PET_RAVAGER              = 767,      SKILL_PET_SERPENT              = 768, -    SKILL_INTERNAL                 = 769 +    SKILL_INTERNAL                 = 769, +    SKILL_DK_BLOOD                 = 770, +    SKILL_DK_FROST                 = 771, +    SKILL_DK_UNHOLY                = 772, +    SKILL_INSCRIPTION              = 773, +    SKILL_PET_MOTH                 = 775, +    SKILL_RUNEFORGING              = 776, +    SKILL_MOUNTS                   = 777, +    SKILL_COMPANIONS               = 778, +    SKILL_PET_EXOTIC_CHIMAERA      = 780, +    SKILL_PET_EXOTIC_DEVILSAUR     = 781, +    SKILL_PET_GHOUL                = 782, +    SKILL_PET_EXOTIC_SILITHID      = 783, +    SKILL_PET_EXOTIC_WORM          = 784, +    SKILL_PET_WASP                 = 785, +    SKILL_PET_EXOTIC_RHINO         = 786, +    SKILL_PET_EXOTIC_CORE_HOUND    = 787, +    SKILL_PET_EXOTIC_SPIRIT_BEAST  = 788  }; -#define MAX_SKILL_TYPE               770 +#define MAX_SKILL_TYPE               789  inline uint32 SkillByQuestSort(int32 QuestSort)  { @@ -1858,25 +1900,27 @@ inline uint32 SkillByQuestSort(int32 QuestSort)          case QUEST_SORT_TAILORING:      return SKILL_TAILORING;          case QUEST_SORT_COOKING:        return SKILL_COOKING;          case QUEST_SORT_FIRST_AID:      return SKILL_FIRST_AID; +        case QUEST_SORT_JEWELCRAFTING:  return SKILL_JEWELCRAFTING; +        case QUEST_SORT_INSCRIPTION:    return SKILL_INSCRIPTION;      }      return 0;  }  enum SkillCategory  { -    SKILL_CATEGORY_ATTRIBUTES    =  5, -    SKILL_CATEGORY_WEAPON        =  6, -    SKILL_CATEGORY_CLASS         =  7, -    SKILL_CATEGORY_ARMOR         =  8, -    SKILL_CATEGORY_SECONDARY     =  9,                      // secondary professions +    SKILL_CATEGORY_ATTRIBUTES    = 5, +    SKILL_CATEGORY_WEAPON        = 6, +    SKILL_CATEGORY_CLASS         = 7, +    SKILL_CATEGORY_ARMOR         = 8, +    SKILL_CATEGORY_SECONDARY     = 9,                       // secondary professions      SKILL_CATEGORY_LANGUAGES     = 10,      SKILL_CATEGORY_PROFESSION    = 11,                      // primary professions -    SKILL_CATEGORY_NOT_DISPLAYED = 12 +    SKILL_CATEGORY_GENERIC       = 12  };  enum TotemCategory  { -    TC_SKINNING_SKIFE              = 1, +    TC_SKINNING_SKIFE_OLD          = 1,      TC_EARTH_TOTEM                 = 2,      TC_AIR_TOTEM                   = 3,      TC_FIRE_TOTEM                  = 4, @@ -1886,15 +1930,28 @@ enum TotemCategory      TC_GOLDEN_ROD                  = 8,      TC_TRUESILVER_ROD              = 9,      TC_ARCANITE_ROD                = 10, -    TC_MINING_PICK                 = 11, +    TC_MINING_PICK_OLD             = 11,      TC_PHILOSOPHERS_STONE          = 12, -    TC_BLACKSMITH_HAMMER           = 13, +    TC_BLACKSMITH_HAMMER_OLD       = 13,      TC_ARCLIGHT_SPANNER            = 14,      TC_GYROMATIC_MA                = 15,      TC_MASTER_TOTEM                = 21,      TC_FEL_IRON_ROD                = 41,      TC_ADAMANTITE_ROD              = 62, -    TC_ETERNIUM_ROD                = 63 +    TC_ETERNIUM_ROD                = 63, +    TC_HOLLOW_QUILL                = 81, +    TC_RUNED_AZURITE_ROD           = 101, +    TC_VIRTUOSO_INKING_SET         = 121, +    TC_DRUMS                       = 141, +    TC_GNOMISH_ARMY_KNIFE          = 161, +    TC_BLACKSMITH_HAMMER           = 162, +    TC_MINING_PICK                 = 165, +    TC_SKINNING_KNIFE              = 166, +    TC_HAMMER_PICK                 = 167, +    TC_BLADED_PICKAXE              = 168, +    TC_FLINT_AND_TINDER            = 169, +    TC_RUNED_COBALT_ROD            = 189, +    TC_RUNED_TITANIUM_ROD          = 190  };  enum UnitDynFlags @@ -1904,7 +1961,8 @@ enum UnitDynFlags      UNIT_DYNFLAG_OTHER_TAGGER      = 0x0004,      UNIT_DYNFLAG_ROOTED            = 0x0008,      UNIT_DYNFLAG_SPECIALINFO       = 0x0010, -    UNIT_DYNFLAG_DEAD              = 0x0020 +    UNIT_DYNFLAG_DEAD              = 0x0020, +    UNIT_DYNFLAG_REFER_A_FRIEND    = 0x0040  };  enum CorpseDynFlags @@ -1914,6 +1972,7 @@ enum CorpseDynFlags  // Passive Spell codes explicit used in code  #define SPELL_ID_GENERIC_LEARN                   483 +#define SPELL_ID_GENERIC_LEARN_PET               55884      // used for learning mounts and companions  #define SPELL_ID_PASSIVE_BATTLE_STANCE           2457  #define SPELL_ID_PASSIVE_RESURRECTION_SICKNESS   15007  #define SPELL_ID_WEAPON_SWITCH_COOLDOWN_1_5s     6119 @@ -1981,9 +2040,12 @@ enum ChatMsg      CHAT_MSG_BATTLEGROUND           = 0x2C,      CHAT_MSG_BATTLEGROUND_LEADER    = 0x2D,      CHAT_MSG_RESTRICTED             = 0x2E, +    CHAT_MSG_BN                     = 0x2F, +    CHAT_MSG_ACHIEVEMENT            = 0x30, +    CHAT_MSG_GUILD_ACHIEVEMENT      = 0x31  }; -#define MAX_CHAT_MSG_TYPE 0x2F +#define MAX_CHAT_MSG_TYPE 0x32  // Values from ItemPetFood (power of (value-1) used for compare with CreatureFamilyEntry.petDietMask  enum PetDiet @@ -2152,42 +2214,45 @@ enum ResponseCodes      CHAR_CREATE_SERVER_QUEUE                               = 0x37,      CHAR_CREATE_ONLY_EXISTING                              = 0x38,      CHAR_CREATE_EXPANSION                                  = 0x39, - -    CHAR_DELETE_IN_PROGRESS                                = 0x3A, -    CHAR_DELETE_SUCCESS                                    = 0x3B, -    CHAR_DELETE_FAILED                                     = 0x3C, -    CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER                 = 0x3D, -    CHAR_DELETE_FAILED_GUILD_LEADER                        = 0x3E, -    CHAR_DELETE_FAILED_ARENA_CAPTAIN                       = 0x3F, - -    CHAR_LOGIN_IN_PROGRESS                                 = 0x40, -    CHAR_LOGIN_SUCCESS                                     = 0x41, -    CHAR_LOGIN_NO_WORLD                                    = 0x42, -    CHAR_LOGIN_DUPLICATE_CHARACTER                         = 0x43, -    CHAR_LOGIN_NO_INSTANCES                                = 0x44, -    CHAR_LOGIN_FAILED                                      = 0x45, -    CHAR_LOGIN_DISABLED                                    = 0x46, -    CHAR_LOGIN_NO_CHARACTER                                = 0x47, -    CHAR_LOGIN_LOCKED_FOR_TRANSFER                         = 0x48, -    CHAR_LOGIN_LOCKED_BY_BILLING                           = 0x49, - -    CHAR_NAME_SUCCESS                                      = 0x4A, -    CHAR_NAME_FAILURE                                      = 0x4B, -    CHAR_NAME_NO_NAME                                      = 0x4C, -    CHAR_NAME_TOO_SHORT                                    = 0x4D, -    CHAR_NAME_TOO_LONG                                     = 0x4E, -    CHAR_NAME_INVALID_CHARACTER                            = 0x4F, -    CHAR_NAME_MIXED_LANGUAGES                              = 0x50, -    CHAR_NAME_PROFANE                                      = 0x51, -    CHAR_NAME_RESERVED                                     = 0x52, -    CHAR_NAME_INVALID_APOSTROPHE                           = 0x53, -    CHAR_NAME_MULTIPLE_APOSTROPHES                         = 0x54, -    CHAR_NAME_THREE_CONSECUTIVE                            = 0x55, -    CHAR_NAME_INVALID_SPACE                                = 0x56, -    CHAR_NAME_CONSECUTIVE_SPACES                           = 0x57, -    CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS        = 0x58, -    CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x59, -    CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME            = 0x5A, +    CHAR_CREATE_EXPANSION_CLASS                            = 0x3A, +    CHAR_CREATE_LEVEL_REQUIREMENT                          = 0x3B, +    CHAR_CREATE_UNIQUE_CLASS_LIMIT                         = 0x3C, + +    CHAR_DELETE_IN_PROGRESS                                = 0x3D, +    CHAR_DELETE_SUCCESS                                    = 0x3E, +    CHAR_DELETE_FAILED                                     = 0x3F, +    CHAR_DELETE_FAILED_LOCKED_FOR_TRANSFER                 = 0x40, +    CHAR_DELETE_FAILED_GUILD_LEADER                        = 0x41, +    CHAR_DELETE_FAILED_ARENA_CAPTAIN                       = 0x42, + +    CHAR_LOGIN_IN_PROGRESS                                 = 0x43, +    CHAR_LOGIN_SUCCESS                                     = 0x44, +    CHAR_LOGIN_NO_WORLD                                    = 0x45, +    CHAR_LOGIN_DUPLICATE_CHARACTER                         = 0x46, +    CHAR_LOGIN_NO_INSTANCES                                = 0x47, +    CHAR_LOGIN_FAILED                                      = 0x48, +    CHAR_LOGIN_DISABLED                                    = 0x49, +    CHAR_LOGIN_NO_CHARACTER                                = 0x4A, +    CHAR_LOGIN_LOCKED_FOR_TRANSFER                         = 0x4B, +    CHAR_LOGIN_LOCKED_BY_BILLING                           = 0x4C, + +    CHAR_NAME_SUCCESS                                      = 0x4D, +    CHAR_NAME_FAILURE                                      = 0x4E, +    CHAR_NAME_NO_NAME                                      = 0x4F, +    CHAR_NAME_TOO_SHORT                                    = 0x50, +    CHAR_NAME_TOO_LONG                                     = 0x51, +    CHAR_NAME_INVALID_CHARACTER                            = 0x52, +    CHAR_NAME_MIXED_LANGUAGES                              = 0x53, +    CHAR_NAME_PROFANE                                      = 0x54, +    CHAR_NAME_RESERVED                                     = 0x55, +    CHAR_NAME_INVALID_APOSTROPHE                           = 0x56, +    CHAR_NAME_MULTIPLE_APOSTROPHES                         = 0x57, +    CHAR_NAME_THREE_CONSECUTIVE                            = 0x58, +    CHAR_NAME_INVALID_SPACE                                = 0x59, +    CHAR_NAME_CONSECUTIVE_SPACES                           = 0x5A, +    CHAR_NAME_RUSSIAN_CONSECUTIVE_SILENT_CHARACTERS        = 0x5B, +    CHAR_NAME_RUSSIAN_SILENT_CHARACTER_AT_BEGINNING_OR_END = 0x5C, +    CHAR_NAME_DECLENSION_DOESNT_MATCH_BASE_NAME            = 0x5D  };  /// Ban function modes diff --git a/src/game/SkillHandler.cpp b/src/game/SkillHandler.cpp index 56e48bf75c4..9f3915c30cb 100644 --- a/src/game/SkillHandler.cpp +++ b/src/game/SkillHandler.cpp @@ -82,10 +82,6 @@ void WorldSession::HandleLearnTalentOpcode( WorldPacket & recv_data )          }      } -    // Check if it requires spell -    if( talentInfo->DependsOnSpell && !player->HasSpell(talentInfo->DependsOnSpell) ) -        return; -      // Find out how many points we have in this field      uint32 spentPoints = 0; diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index c17e5632cb9..d78db70b653 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -43,7 +43,6 @@  #include "CellImpl.h"  #include "Policies/SingletonImp.h"  #include "SharedDefines.h" -#include "Tools.h"  #include "LootMgr.h"  #include "VMapFactory.h"  #include "BattleGround.h" @@ -177,16 +176,16 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )          return true;      // TARGET_FLAG_UNK2 is used for non-combat pets, maybe other? -    if( m_targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2) ) -        if(!readGUID(*data, m_unitTargetGUID)) +    if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_UNK2 )) +        if(!data->readPackGUID(m_unitTargetGUID))              return false;      if( m_targetMask & ( TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK )) -        if(!readGUID(*data, m_GOTargetGUID)) +        if(!data->readPackGUID(m_GOTargetGUID))              return false;      if(( m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM )) && caster->GetTypeId() == TYPEID_PLAYER) -        if(!readGUID(*data, m_itemTargetGUID)) +        if(!data->readPackGUID(m_itemTargetGUID))              return false;      /*if( m_targetMask & TARGET_FLAG_SOURCE_LOCATION ) @@ -219,7 +218,7 @@ bool SpellCastTargets::read ( WorldPacket * data, Unit *caster )      }      if( m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE ) ) -        if(!readGUID(*data, m_CorpseTargetGUID)) +        if(!data->readPackGUID(m_CorpseTargetGUID))              return false;      // find real units/GOs @@ -231,7 +230,7 @@ void SpellCastTargets::write ( WorldPacket * data )  {      *data << uint32(m_targetMask); -    if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) ) +    if( m_targetMask & ( TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK2 ) )      {          if(m_targetMask & TARGET_FLAG_UNIT)          { @@ -351,6 +350,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi      gameObjTarget = NULL;      focusObject = NULL;      m_cast_count = 0; +    m_glyphIndex = 0;      m_triggeredByAuraSpell  = NULL;      //Auto Shot & Shoot @@ -359,6 +359,7 @@ Spell::Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 origi      else          m_autoRepeat = false; +    m_runesState = 0;      m_powerCost = 0;                                        // setup to correct value in Spell::prepare, don't must be used before.      m_casttime = 0;                                         // setup to correct value in Spell::prepare, don't must be used before.      m_timer = 0;                                            // will set to castime in prepare @@ -507,6 +508,8 @@ void Spell::FillTargetMap()                  case SPELL_EFFECT_CREATE_ITEM:                  case SPELL_EFFECT_TRIGGER_SPELL:                  case SPELL_EFFECT_SKILL_STEP: +                case SPELL_EFFECT_PROFICIENCY: +                case SPELL_EFFECT_SUMMON_OBJECT_WILD:                  case SPELL_EFFECT_SELF_RESURRECT:                  case SPELL_EFFECT_REPUTATION:                  case SPELL_EFFECT_LEARN_SPELL: @@ -539,6 +542,7 @@ void Spell::FillTargetMap()                      break;                  case SPELL_EFFECT_SUMMON_CHANGE_ITEM:                  case SPELL_EFFECT_ADD_FARSIGHT: +                case SPELL_EFFECT_APPLY_GLYPH:                  case SPELL_EFFECT_STUCK:                  case SPELL_EFFECT_DESTROY_ALL_TOTEMS:                      tmpUnitMap.push_back(m_caster); @@ -552,6 +556,7 @@ void Spell::FillTargetMap()                  case SPELL_EFFECT_DISENCHANT:                  case SPELL_EFFECT_FEED_PET:                  case SPELL_EFFECT_PROSPECTING: +                case SPELL_EFFECT_MILLING:                      if(m_targets.getItemTarget())                          AddItemTarget(m_targets.getItemTarget(), i);                      break;*/ @@ -845,83 +850,6 @@ void Spell::AddItemTarget(Item* pitem, uint32 effIndex)      target.effectMask = 1<<effIndex;      m_UniqueItemInfo.push_back(target);  } -/* -void Spell::doTriggers(SpellMissInfo missInfo, uint32 damage, SpellSchoolMask damageSchoolMask, uint32 block, uint32 absorb, bool crit) -{ -    // Do triggers depends from hit result (triggers on hit do in effects) -    // Set aura states depends from hit result -    if (missInfo!=SPELL_MISS_NONE) -    { -        // Miss/dodge/parry/block only for melee based spells -        // Resist only for magic based spells -        switch (missInfo) -        { -            case SPELL_MISS_MISS: -                if(m_caster->GetTypeId()== TYPEID_PLAYER) -                    ((Player*)m_caster)->UpdateWeaponSkill(BASE_ATTACK); - -                m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_MISS, m_spellInfo, m_IsTriggeredSpell); -                break; -            case SPELL_MISS_RESIST: -                m_caster->ProcDamageAndSpell(unitTarget, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, damageSchoolMask, m_spellInfo, m_IsTriggeredSpell); -                break; -            case SPELL_MISS_DODGE: -                if(unitTarget->GetTypeId() == TYPEID_PLAYER) -                    ((Player*)unitTarget)->UpdateDefense(); - -                // Overpower -                if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_WARRIOR) -                { -                    ((Player*) m_caster)->AddComboPoints(unitTarget, 1); -                    m_caster->StartReactiveTimer( REACTIVE_OVERPOWER ); -                } - -                // Riposte -                if (unitTarget->getClass() != CLASS_ROGUE) -                { -                    unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true); -                    unitTarget->StartReactiveTimer( REACTIVE_DEFENSE ); -                } - -                m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_DODGE, m_spellInfo, m_IsTriggeredSpell); -                break; -            case SPELL_MISS_PARRY: -                // Update victim defense ? -                if(unitTarget->GetTypeId() == TYPEID_PLAYER) -                    ((Player*)unitTarget)->UpdateDefense(); -                // Mongoose bite - set only Counterattack here -                if (unitTarget->getClass() == CLASS_HUNTER) -                { -                    unitTarget->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true); -                    unitTarget->StartReactiveTimer( REACTIVE_HUNTER_PARRY ); -                } -                else -                { -                    unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true); -                    unitTarget->StartReactiveTimer( REACTIVE_DEFENSE ); -                } -                m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_PARRY, m_spellInfo, m_IsTriggeredSpell); -                break; -            case SPELL_MISS_BLOCK: -                unitTarget->ModifyAuraState(AURA_STATE_DEFENSE, true); -                unitTarget->StartReactiveTimer( REACTIVE_DEFENSE ); - -                m_caster->CastMeleeProcDamageAndSpell(unitTarget, 0, damageSchoolMask, m_attackType, MELEE_HIT_BLOCK, m_spellInfo, m_IsTriggeredSpell); -                break; -                // Trigger from this events not supported -            case SPELL_MISS_EVADE: -            case SPELL_MISS_IMMUNE: -            case SPELL_MISS_IMMUNE2: -            case SPELL_MISS_DEFLECT: -            case SPELL_MISS_ABSORB: -                // Trigger from reflects need do after get reflect result -            case SPELL_MISS_REFLECT: -                break; -            default: -                break; -        } -    } -}*/  void Spell::DoAllEffectOnTarget(TargetInfo *target)  { @@ -1109,6 +1037,17 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)          return;      } +    if (unit->GetTypeId() == TYPEID_PLAYER) +    { +        ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id); +        ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2, m_spellInfo->Id); +    } + +    if(m_caster->GetTypeId() == TYPEID_PLAYER) +    { +        ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2, m_spellInfo->Id, 0, unit); +    } +      if( m_caster != unit )      {          if (unit->GetCharmerOrOwnerGUID() != m_caster->GetGUID()) @@ -1328,6 +1267,16 @@ void Spell::SearchChainTarget(std::list<Unit*> &TagUnitMap, Unit* pUnitTarget, f      if(!pUnitTarget)          return; +    // Get spell max affected targets +    /*uint32 unMaxTargets = m_spellInfo->MaxAffectedTargets; +    Unit::AuraList const& mod = m_caster->GetAurasByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS); +    for(Unit::AuraList::const_iterator m = mod.begin(); m != mod.end(); ++m) +    { +        if (!(*m)->isAffectedOnSpell(m_spellInfo)) +            continue; +        unMaxTargets+=(*m)->GetModifier()->m_amount; +    }*/ +      //FIXME: This very like horrible hack and wrong for most spells      if(m_spellInfo->DmgClass != SPELL_DAMAGE_CLASS_MELEE)          max_range += unMaxTargets * CHAIN_SPELL_JUMP_RADIUS; @@ -2223,6 +2172,14 @@ void Spell::cast(bool skipCheck)      // set to real guid to be sent later to the client      m_targets.updateTradeSlotItem(); +    if (m_caster->GetTypeId() == TYPEID_PLAYER) +    { +        if (m_CastItem) +            ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM, m_CastItem->GetEntry()); + +        ((Player*)m_caster)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL, m_spellInfo->Id); +    } +      // CAST SPELL      SendSpellCooldown(); @@ -2652,7 +2609,7 @@ void Spell::finish(bool ok)      {          SpellEntry const *auraSpellInfo = (*i)->GetSpellProto();          uint32 auraSpellIdx = (*i)->GetEffIndex(); -        if (IsAffectedBy(auraSpellInfo, auraSpellIdx)) +        if (IsAffectedByAura((*i)))          {              for(std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin();ihit != m_UniqueTargetInfo.end();++ihit)                  if( ihit->effectMask & (1<<auraSpellIdx) ) @@ -2708,9 +2665,9 @@ void Spell::SendCastResult(uint8 result)      if(result != 0)      {          WorldPacket data(SMSG_CAST_FAILED, (4+1+1)); +        data << uint8(m_cast_count);                        // single cast or multi 2.3 (0/1)          data << uint32(m_spellInfo->Id);          data << uint8(result);                              // problem -        data << uint8(m_cast_count);                        // single cast or multi 2.3 (0/1)          switch (result)          {              case SPELL_FAILED_REQUIRES_SPELL_FOCUS: @@ -2751,18 +2708,11 @@ void Spell::SendCastResult(uint8 result)              case SPELL_FAILED_EQUIPPED_ITEM_CLASS:                  data << uint32(m_spellInfo->EquippedItemClass);                  data << uint32(m_spellInfo->EquippedItemSubClassMask); -                data << uint32(m_spellInfo->EquippedItemInventoryTypeMask); +                //data << uint32(m_spellInfo->EquippedItemInventoryTypeMask);                  break;          }          ((Player*)m_caster)->GetSession()->SendPacket(&data);      } -    else -    { -        WorldPacket data(SMSG_CLEAR_EXTRA_AURA_INFO, (8+4)); -        data.append(m_caster->GetPackGUID()); -        data << uint32(m_spellInfo->Id); -        ((Player*)m_caster)->GetSession()->SendPacket(&data); -    }  }  void Spell::SendSpellStart() @@ -2776,6 +2726,9 @@ void Spell::SendSpellStart()      if(IsRangedSpell())          castFlags |= CAST_FLAG_AMMO; +    if(m_spellInfo->runeCostID) +        castFlags |= CAST_FLAG_UNKNOWN10; +      Unit *target = m_targets.getUnitTarget() ? m_targets.getUnitTarget() : m_caster;      WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2)); @@ -2785,14 +2738,32 @@ void Spell::SendSpellStart()          data.append(m_caster->GetPackGUID());      data.append(m_caster->GetPackGUID()); -    data << uint32(m_spellInfo->Id); -    data << uint8(m_cast_count);                            // single cast or multi 2.3 (0/1) -    data << uint16(castFlags); -    data << uint32(m_timer); +    data << uint8(m_cast_count);                            // pending spell cast? +    data << uint32(m_spellInfo->Id);                        // spellId +    data << uint32(castFlags);                              // cast flags +    data << uint32(m_timer);                                // delay?      m_targets.write(&data); -    if( castFlags & CAST_FLAG_AMMO ) +    if ( castFlags & CAST_FLAG_UNKNOWN6 )                   // predicted power? +        data << uint32(0); + +    if ( castFlags & CAST_FLAG_UNKNOWN7 )                   // rune cooldowns list +    { +        uint8 v1 = 0;//m_runesState; +        uint8 v2 = 0;//((Player*)m_caster)->GetRunesState(); +        data << uint8(v1);                                  // runes state before +        data << uint8(v2);                                  // runes state after +        for(uint8 i = 0; i < MAX_RUNES; ++i) +        { +            uint8 m = (1 << i); +            if(m & v1)                                      // usable before... +                if(!(m & v2))                               // ...but on cooldown now... +                    data << uint8(0);                       // some unknown byte (time?) +        } +    } + +    if ( castFlags & CAST_FLAG_AMMO )          WriteAmmoToPacket(&data);      m_caster->SendMessageToSet(&data, true); @@ -2812,6 +2783,13 @@ void Spell::SendSpellGo()      if(IsRangedSpell())          castFlags |= CAST_FLAG_AMMO;                        // arrows/bullets visual +    if((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID) +    { +        castFlags |= CAST_FLAG_UNKNOWN10;                   // same as in SMSG_SPELL_START +        castFlags |= CAST_FLAG_UNKNOWN6;                    // makes cooldowns visible +        castFlags |= CAST_FLAG_UNKNOWN7;                    // rune cooldowns list +    } +      WorldPacket data(SMSG_SPELL_GO, 50);                    // guess size      if(m_CastItem)          data.append(m_CastItem->GetPackGUID()); @@ -2819,17 +2797,53 @@ void Spell::SendSpellGo()          data.append(m_caster->GetPackGUID());      data.append(m_caster->GetPackGUID()); -    data << uint32(m_spellInfo->Id); -    data << uint16(castFlags); +    data << uint8(m_cast_count);                            // pending spell cast? +    data << uint32(m_spellInfo->Id);                        // spellId +    data << uint32(castFlags);                              // cast flags      data << uint32(getMSTime());                            // timestamp      WriteSpellGoTargets(&data);      m_targets.write(&data); -    if( castFlags & CAST_FLAG_AMMO ) +    if ( castFlags & CAST_FLAG_UNKNOWN6 )                   // unknown wotlk, predicted power? +        data << uint32(0); + +    if ( castFlags & CAST_FLAG_UNKNOWN7 )                   // rune cooldowns list +    { +        uint8 v1 = m_runesState; +        uint8 v2 = ((Player*)m_caster)->GetRunesState(); +        data << uint8(v1);                                  // runes state before +        data << uint8(v2);                                  // runes state after +        for(uint8 i = 0; i < MAX_RUNES; ++i) +        { +            uint8 m = (1 << i); +            if(m & v1)                                      // usable before... +                if(!(m & v2))                               // ...but on cooldown now... +                    data << uint8(0);                       // some unknown byte (time?) +        } +    } + +    if ( castFlags & CAST_FLAG_UNKNOWN4 )                   // unknown wotlk +    { +        data << float(0); +        data << uint32(0); +    } + +    if ( castFlags & CAST_FLAG_AMMO )          WriteAmmoToPacket(&data); +    if ( castFlags & CAST_FLAG_UNKNOWN5 )                   // unknown wotlk +    { +        data << uint32(0); +        data << uint32(0); +    } + +    if ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION ) +    { +        data << uint8(0); +    } +      m_caster->SendMessageToSet(&data, true);  } @@ -2957,30 +2971,19 @@ void Spell::SendLogExecute()                          data << uint8(0);                      break;                  case SPELL_EFFECT_CREATE_ITEM: +                case SPELL_EFFECT_157:                      data << uint32(m_spellInfo->EffectItemType[0]);                      break;                  case SPELL_EFFECT_SUMMON: -                case SPELL_EFFECT_SUMMON_WILD: -                case SPELL_EFFECT_SUMMON_GUARDIAN:                  case SPELL_EFFECT_TRANS_DOOR:                  case SPELL_EFFECT_SUMMON_PET: -                case SPELL_EFFECT_SUMMON_POSSESSED: -                case SPELL_EFFECT_SUMMON_TOTEM:                  case SPELL_EFFECT_SUMMON_OBJECT_WILD:                  case SPELL_EFFECT_CREATE_HOUSE:                  case SPELL_EFFECT_DUEL: -                case SPELL_EFFECT_SUMMON_TOTEM_SLOT1: -                case SPELL_EFFECT_SUMMON_TOTEM_SLOT2: -                case SPELL_EFFECT_SUMMON_TOTEM_SLOT3: -                case SPELL_EFFECT_SUMMON_TOTEM_SLOT4: -                case SPELL_EFFECT_SUMMON_PHANTASM: -                case SPELL_EFFECT_SUMMON_CRITTER:                  case SPELL_EFFECT_SUMMON_OBJECT_SLOT1:                  case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:                  case SPELL_EFFECT_SUMMON_OBJECT_SLOT3:                  case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: -                case SPELL_EFFECT_SUMMON_DEMON: -                case SPELL_EFFECT_150:                      if(Unit *unit = m_targets.getUnitTarget())                          data.append(unit->GetPackGUID());                      else if(m_targets.getItemTargetGUID()) @@ -2999,6 +3002,13 @@ void Spell::SendLogExecute()                      else                          data << uint8(0);                      break; +                case SPELL_EFFECT_RESURRECT: +                case SPELL_EFFECT_RESURRECT_NEW: +                    if(Unit *unit = m_targets.getUnitTarget()) +                        data.append(unit->GetPackGUID()); +                    else +                        data << uint8(0); +                    break;                  default:                      return;              } @@ -3012,13 +3022,16 @@ void Spell::SendInterrupted(uint8 result)  {      WorldPacket data(SMSG_SPELL_FAILURE, (8+4+1));      data.append(m_caster->GetPackGUID()); -    data << m_spellInfo->Id; -    data << result; +    data << uint8(m_cast_count); +    data << uint32(m_spellInfo->Id); +    data << uint8(result);      m_caster->SendMessageToSet(&data, true);      data.Initialize(SMSG_SPELL_FAILED_OTHER, (8+4));      data.append(m_caster->GetPackGUID()); -    data << m_spellInfo->Id; +    data << uint8(m_cast_count); +    data << uint32(m_spellInfo->Id); +    data << uint8(result);      m_caster->SendMessageToSet(&data, true);  } @@ -3086,10 +3099,19 @@ void Spell::SendChannelStart(uint32 duration)  void Spell::SendResurrectRequest(Player* target)  { -    WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+2+4)); -    data << m_caster->GetGUID(); -    data << uint32(1) << uint16(0) << uint32(1); +    // Both players and NPCs can resurrect using spells - have a look at creature 28487 for example +    // However, the packet structure differs slightly +    const char* sentName = m_caster->GetTypeId()==TYPEID_PLAYER ?"":m_caster->GetNameForLocaleIdx(target->GetSession()->GetSessionDbLocaleIndex()); + +    WorldPacket data(SMSG_RESURRECT_REQUEST, (8+4+strlen(sentName)+1+1+1)); +    data << uint64(m_caster->GetGUID()); +    data << uint32(strlen(sentName)+1); + +    data << sentName; +    data << uint8(0); + +    data << uint8(m_caster->GetTypeId()==TYPEID_PLAYER ?0:1);      target->GetSession()->SendPacket(&data);  } @@ -3186,6 +3208,12 @@ void Spell::TakePower()      Powers powerType = Powers(m_spellInfo->powerType); +    if(powerType == POWER_RUNE) +    { +        TakeRunePower(); +        return; +    } +      m_caster->ModifyPower(powerType, -(int32)m_powerCost);      // Set the five second timer @@ -3193,6 +3221,116 @@ void Spell::TakePower()          m_caster->SetLastManaUse(getMSTime());  } +uint8 Spell::CheckRuneCost(uint32 runeCostID) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return 0; + +    Player *plr = (Player*)m_caster; + +    if(plr->getClass() != CLASS_DEATH_KNIGHT) +        return 0; + +    SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(runeCostID); + +    if(!src) +        return 0; + +    if(src->NoRuneCost()) +        return 0; + +    int32 runeCost[NUM_RUNE_TYPES];                         // blood, frost, unholy, death + +    for(uint32 i = 0; i < RUNE_DEATH; ++i) +    { +        runeCost[i] = src->RuneCost[i]; +    } + +    runeCost[RUNE_DEATH] = 0;                               // calculated later + +    for(uint32 i = 0; i < MAX_RUNES; ++i) +    { +        uint8 rune = plr->GetCurrentRune(i); +        if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) +        { +            runeCost[rune]--; +        } +    } + +    for(uint32 i = 0; i < RUNE_DEATH; ++i) +    { +        if(runeCost[i] > 0) +        { +            runeCost[RUNE_DEATH] += runeCost[i]; +        } +    } + +    if(runeCost[RUNE_DEATH] > 0) +        return SPELL_FAILED_NO_POWER;                       // not sure if result code is correct + +    return 0; +} + +void Spell::TakeRunePower() +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player *plr = (Player*)m_caster; + +    if(plr->getClass() != CLASS_DEATH_KNIGHT) +        return; + +    SpellRuneCostEntry const *src = sSpellRuneCostStore.LookupEntry(m_spellInfo->runeCostID); + +    if(!src || (src->NoRuneCost() && src->NoRunicPowerGain())) +        return; + +    m_runesState = plr->GetRunesState();                    // store previous state + +    int32 runeCost[NUM_RUNE_TYPES];                         // blood, frost, unholy, death + +    for(uint32 i = 0; i < RUNE_DEATH; ++i) +    { +        runeCost[i] = src->RuneCost[i]; +    } + +    runeCost[RUNE_DEATH] = 0;                               // calculated later + +    for(uint32 i = 0; i < MAX_RUNES; ++i) +    { +        uint8 rune = plr->GetCurrentRune(i); +        if((plr->GetRuneCooldown(i) == 0) && (runeCost[rune] > 0)) +        { +            plr->SetRuneCooldown(i, RUNE_COOLDOWN);         // 5*2=10 sec +            runeCost[rune]--; +        } +    } + +    runeCost[RUNE_DEATH] = runeCost[RUNE_BLOOD] + runeCost[RUNE_UNHOLY] + runeCost[RUNE_FROST]; + +    if(runeCost[RUNE_DEATH] > 0) +    { +        for(uint32 i = 0; i < MAX_RUNES; ++i) +        { +            uint8 rune = plr->GetCurrentRune(i); +            if((plr->GetRuneCooldown(i) == 0) && (rune == RUNE_DEATH)) +            { +                plr->SetRuneCooldown(i, RUNE_COOLDOWN);     // 5*2=10 sec +                runeCost[rune]--; +                plr->ConvertRune(i, plr->GetBaseRune(i)); +                if(runeCost[RUNE_DEATH] == 0) +                    break; +            } +        } +    } + +    // you can gain some runic power when use runes +    float rp = src->runePowerGain;; +    rp *= sWorld.getRate(RATE_POWER_RUNICPOWER_INCOME); +    plr->ModifyPower(POWER_RUNIC_POWER, (int32)rp); +} +  void Spell::TakeReagents()  {      if(m_IsTriggeredSpell)                                  // reagents used in triggered spell removed by original spell or don't must be removed. @@ -3201,11 +3339,9 @@ void Spell::TakeReagents()      if (m_caster->GetTypeId() != TYPEID_PLAYER)          return; -    if (m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && -        m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION)) -        return; -      Player* p_caster = (Player*)m_caster; +    if (p_caster->CanNoReagentCast(m_spellInfo)) +        return;      for(uint32 x=0;x<8;x++)      { @@ -3329,12 +3465,25 @@ uint8 Spell::CanCast(bool strict)      // for now, ignore triggered spells      if( strict && !m_IsTriggeredSpell)      { -        // Cannot be used in this stance/form -        if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form)) -            return shapeError; +        bool checkForm = true; +        // Ignore form req aura +        Unit::AuraList const& ignore = m_caster->GetAurasByType(SPELL_AURA_MOD_IGNORE_SHAPESHIFT); +        for(Unit::AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) +        { +            if (!(*i)->isAffectedOnSpell(m_spellInfo)) +                continue; +            checkForm = false; +            break; +        } +        if (checkForm) +        { +            // Cannot be used in this stance/form +            if(uint8 shapeError = GetErrorAtShapeshiftedCast(m_spellInfo, m_caster->m_form)) +                return shapeError; -        if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) -            return SPELL_FAILED_ONLY_STEALTHED; +            if ((m_spellInfo->Attributes & SPELL_ATTR_ONLY_STEALTHED) && !(m_caster->HasStealthAura())) +                return SPELL_FAILED_ONLY_STEALTHED; +        }      }      // caster state requirements @@ -3444,8 +3593,12 @@ uint8 Spell::CanCast(bool strict)          if( m_spellInfo->AttributesEx2 == 0x100000 && (m_spellInfo->AttributesEx & 0x200) == 0x200 && target->HasInArc(M_PI, m_caster)               && (m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL))          { -            SendInterrupted(2); -            return SPELL_FAILED_NOT_BEHIND; +            //Exclusion for Pounce: Facing Limitation was removed in 2.0.1, but it still uses the same, old Ex-Flags +            if( m_spellInfo->SpellFamilyName != SPELLFAMILY_DRUID || m_spellInfo->SpellFamilyFlags != 0x0000000000020000LL ) +            { +                SendInterrupted(2); +                return SPELL_FAILED_NOT_BEHIND; +            }          }          //Target must be facing you. @@ -3671,7 +3824,7 @@ uint8 Spell::CanCast(bool strict)              case SPELL_EFFECT_SCHOOL_DAMAGE:              {                  // Hammer of Wrath -                if(m_spellInfo->SpellVisual == 7250) +                if(m_spellInfo->SpellVisual[0] == 7250)                  {                      if (!m_targets.getUnitTarget())                          return SPELL_FAILED_BAD_IMPLICIT_TARGETS; @@ -3696,15 +3849,9 @@ uint8 Spell::CanCast(bool strict)                  if(!learn_spellproto)                      return SPELL_FAILED_NOT_KNOWN; -                if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id)) -                    return SPELL_FAILED_TOO_MANY_SKILLS; -                  if(m_spellInfo->spellLevel > pet->getLevel())                      return SPELL_FAILED_LOWLEVEL; -                if(!pet->HasTPForSpell(learn_spellproto->Id)) -                    return SPELL_FAILED_TRAINING_POINTS; -                  break;              }              case SPELL_EFFECT_LEARN_PET_SPELL: @@ -3719,15 +3866,9 @@ uint8 Spell::CanCast(bool strict)                  if(!learn_spellproto)                      return SPELL_FAILED_NOT_KNOWN; -                if(!pet->CanTakeMoreActiveSpells(learn_spellproto->Id)) -                    return SPELL_FAILED_TOO_MANY_SKILLS; -                  if(m_spellInfo->spellLevel > pet->getLevel())                      return SPELL_FAILED_LOWLEVEL; -                if(!pet->HasTPForSpell(learn_spellproto->Id)) -                    return SPELL_FAILED_TRAINING_POINTS; -                  break;              }              case SPELL_EFFECT_FEED_PET: @@ -3830,27 +3971,27 @@ uint8 Spell::CanCast(bool strict)                  {                      // check for lock - key pair (checked by client also, just prevent cheating                      bool ok_key = false; -                    for(int it = 0; it < 5; ++it) +                    for(int it = 0; it < 8; ++it)                      { -                        switch(lockInfo->keytype[it]) +                        switch(lockInfo->Type[it])                          {                              case LOCK_KEY_NONE:                                  break;                              case LOCK_KEY_ITEM:                              { -                                if(lockInfo->key[it]) +                                if(lockInfo->Index[it])                                  { -                                    if(m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it]) +                                    if(m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])                                          ok_key =true;                                      break;                                  }                              }                              case LOCK_KEY_SKILL:                              { -                                if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->key[it]) +                                if(uint32(m_spellInfo->EffectMiscValue[i])!=lockInfo->Index[it])                                      break; -                                switch(lockInfo->key[it]) +                                switch(lockInfo->Index[it])                                  {                                      case LOCKTYPE_HERBALISM:                                          if(((Player*)m_caster)->HasSkill(SKILL_HERBALISM)) @@ -3908,9 +4049,9 @@ uint8 Spell::CanCast(bool strict)                  {                      // check for lock - key pair                      bool ok = false; -                    for(int it = 0; it < 5; ++it) +                    for(int it = 0; it < 8; ++it)                      { -                        if(lockInfo->keytype[it]==LOCK_KEY_ITEM && lockInfo->key[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[it]) +                        if(lockInfo->Type[it]==LOCK_KEY_ITEM && lockInfo->Index[it] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[it])                          {                              // if so, we're good to go                              ok = true; @@ -3921,9 +4062,9 @@ uint8 Spell::CanCast(bool strict)                          break;                      if (m_spellInfo->EffectMiscValue[i] == LOCKTYPE_PICKLOCK) -                        ReqValue = lockInfo->requiredlockskill; +                        ReqValue = lockInfo->Skill[1];                      else -                        ReqValue = lockInfo->requiredminingskill; +                        ReqValue = lockInfo->Skill[0];                  }                  // skill doesn't meet the required value @@ -3972,7 +4113,6 @@ uint8 Spell::CanCast(bool strict)              }              // Don't make this check for SPELL_EFFECT_SUMMON_CRITTER, SPELL_EFFECT_SUMMON_WILD or SPELL_EFFECT_SUMMON_GUARDIAN.              // These won't show up in m_caster->GetPetGUID() -            case SPELL_EFFECT_SUMMON_POSSESSED:              case SPELL_EFFECT_SUMMON_PHANTASM:              case SPELL_EFFECT_SUMMON_DEMON:              { @@ -4129,7 +4269,7 @@ uint8 Spell::CanCast(bool strict)                  if( form == FORM_CAT          || form == FORM_TREE      || form == FORM_TRAVEL   ||                      form == FORM_AQUA         || form == FORM_BEAR      || form == FORM_DIREBEAR ||                      form == FORM_CREATUREBEAR || form == FORM_GHOSTWOLF || form == FORM_FLIGHT   || -                    form == FORM_FLIGHT_EPIC  || form == FORM_MOONKIN ) +                    form == FORM_FLIGHT_EPIC  || form == FORM_MOONKIN   || form == FORM_METAMORPHOSIS )                      return SPELL_FAILED_NOT_SHAPESHIFT;                  break; @@ -4151,8 +4291,8 @@ uint8 Spell::CanCast(bool strict)                  // not allow cast fly spells at old maps by players (all spells is self target)                  if(m_caster->GetTypeId()==TYPEID_PLAYER)                  { -                    if( !((Player*)m_caster)->isGameMaster() && -                        GetVirtualMapForMapAndZone(m_caster->GetMapId(),m_caster->GetZoneId()) != 530) +                    uint32 v_map = GetVirtualMapForMapAndZone(m_caster->GetMapId(), m_caster->GetZoneId()); +                    if( !((Player*)m_caster)->isGameMaster() && v_map != 530 && !(v_map == 571 && ((Player*)m_caster)->HasSpell(54197)))                          return SPELL_FAILED_NOT_HERE;                  } @@ -4467,9 +4607,12 @@ int32 Spell::CalculatePowerCost()              case POWER_FOCUS:              case POWER_ENERGY:              case POWER_HAPPINESS: -                //            case POWER_RUNES:                  powerCost += m_spellInfo->ManaCostPercentage * m_caster->GetMaxPower(Powers(m_spellInfo->powerType)) / 100;                  break; +            case POWER_RUNE: +            case POWER_RUNIC_POWER: +                sLog.outDebug("Spell::CalculateManaCost: Not implemented yet!"); +                break;              default:                  sLog.outError("Spell::CalculateManaCost: Unknown power type '%d' in spell %d", m_spellInfo->powerType, m_spellInfo->Id);                  return 0; @@ -4514,6 +4657,11 @@ uint8 Spell::CheckPower()          sLog.outError("Spell::CheckMana: Unknown power type '%d'", m_spellInfo->powerType);          return SPELL_FAILED_UNKNOWN;      } + +    uint8 failReason = CheckRuneCost(m_spellInfo->runeCostID); +    if(failReason) +        return failReason; +      // Check power amount      Powers powerType = Powers(m_spellInfo->powerType);      if(m_caster->GetPower(powerType) < m_powerCost) @@ -4641,8 +4789,7 @@ uint8 Spell::CheckItems()          focusObject = ok;                                   // game object found in range      } -    if (!(m_spellInfo->AttributesEx5 & SPELL_ATTR_EX5_NO_REAGENT_WHILE_PREP && -        m_caster->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION))) +    if (!p_caster->CanNoReagentCast(m_spellInfo))      {          for(uint32 i=0;i<8;i++)          { @@ -4810,13 +4957,36 @@ uint8 Spell::CheckItems()                      return SPELL_FAILED_LOW_CASTLEVEL;                  //make sure the player has the required ores in inventory                  if(m_targets.getItemTarget()->GetCount() < 5) -                    return SPELL_FAILED_PROSPECT_NEED_MORE; +                    return SPELL_FAILED_NEED_MORE_ITEMS;                  if(!LootTemplates_Prospecting.HaveLootFor(m_targets.getItemTargetEntry()))                      return SPELL_FAILED_CANT_BE_PROSPECTED;                  break;              } +            case SPELL_EFFECT_MILLING: +            { +                if(!m_targets.getItemTarget()) +                    return SPELL_FAILED_CANT_BE_MILLED; +                //ensure item is a millable herb +                if(!(m_targets.getItemTarget()->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS) || m_targets.getItemTarget()->GetProto()->Class != ITEM_CLASS_TRADE_GOODS) +                    return SPELL_FAILED_CANT_BE_MILLED; +                //prevent milling in trade slot +                if( m_targets.getItemTarget()->GetOwnerGUID() != m_caster->GetGUID() ) +                    return SPELL_FAILED_CANT_BE_MILLED; +                //Check for enough skill in inscription +                uint32 item_millingskilllevel = m_targets.getItemTarget()->GetProto()->RequiredSkillRank; +                if(item_millingskilllevel >p_caster->GetSkillValue(SKILL_INSCRIPTION)) +                    return SPELL_FAILED_LOW_CASTLEVEL; +                //make sure the player has the required herbs in inventory +                if(m_targets.getItemTarget()->GetCount() < 5) +                    return SPELL_FAILED_NEED_MORE_ITEMS; + +                if(!LootTemplates_Milling.HaveLootFor(m_targets.getItemTargetEntry())) +                    return SPELL_FAILED_CANT_BE_MILLED; + +                break; +            }              case SPELL_EFFECT_WEAPON_DAMAGE:              case SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL:              { @@ -4989,9 +5159,9 @@ void Spell::UpdatePointers()      m_targets.Update(m_caster);  } -bool Spell::IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId) +bool Spell::IsAffectedByAura(Aura *aura)  { -    return spellmgr.IsAffectedBySpell(m_spellInfo,spellInfo->Id,effectId,spellInfo->EffectItemType[effectId]); +    return spellmgr.IsAffectedByMod(m_spellInfo, aura->getAuraSpellMod());  }  bool Spell::CheckTargetCreatureType(Unit* target) const diff --git a/src/game/Spell.h b/src/game/Spell.h index 17a103ad0c5..588d5cf01a8 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -47,26 +47,51 @@ enum SpellCastTargetFlags      TARGET_FLAG_RESURRECTABLE    = 0x8000*/      TARGET_FLAG_SELF            = 0x00000000, +    TARGET_FLAG_UNUSED1         = 0x00000001,               // not used in any spells as of 3.0.3 (can be set dynamically)      TARGET_FLAG_UNIT            = 0x00000002,               // pguid +    TARGET_FLAG_UNUSED2         = 0x00000004,               // not used in any spells as of 3.0.3 (can be set dynamically) +    TARGET_FLAG_UNUSED3         = 0x00000008,               // not used in any spells as of 3.0.3 (can be set dynamically)      TARGET_FLAG_ITEM            = 0x00000010,               // pguid      TARGET_FLAG_SOURCE_LOCATION = 0x00000020,               // 3 float      TARGET_FLAG_DEST_LOCATION   = 0x00000040,               // 3 float -    TARGET_FLAG_OBJECT_UNK      = 0x00000080,               // ? +    TARGET_FLAG_OBJECT_UNK      = 0x00000080,               // used in 7 spells only +    TARGET_FLAG_UNIT_UNK        = 0x00000100,               // looks like self target (480 spells)      TARGET_FLAG_PVP_CORPSE      = 0x00000200,               // pguid -    TARGET_FLAG_OBJECT          = 0x00000800,               // pguid -    TARGET_FLAG_TRADE_ITEM      = 0x00001000,               // pguid -    TARGET_FLAG_STRING          = 0x00002000,               // string -    TARGET_FLAG_UNK1            = 0x00004000,               // ? -    TARGET_FLAG_CORPSE          = 0x00008000,               // pguid -    TARGET_FLAG_UNK2            = 0x00010000                // pguid +    TARGET_FLAG_UNIT_CORPSE     = 0x00000400,               // 10 spells (gathering professions) +    TARGET_FLAG_OBJECT          = 0x00000800,               // pguid, 2 spells +    TARGET_FLAG_TRADE_ITEM      = 0x00001000,               // pguid, 0 spells +    TARGET_FLAG_STRING          = 0x00002000,               // string, 0 spells +    TARGET_FLAG_UNK1            = 0x00004000,               // 199 spells, opening object/lock +    TARGET_FLAG_CORPSE          = 0x00008000,               // pguid, resurrection spells +    TARGET_FLAG_UNK2            = 0x00010000,               // pguid, not used in any spells as of 3.0.3 (can be set dynamically) +    TARGET_FLAG_GLYPH           = 0x00020000                // used in glyph spells  };  enum SpellCastFlags  { +    CAST_FLAG_NONE               = 0x00000000, +    CAST_FLAG_UNKNOWN0           = 0x00000001,              // may be pending spell cast      CAST_FLAG_UNKNOWN1           = 0x00000002, +    CAST_FLAG_UNKNOWN11          = 0x00000004, +    CAST_FLAG_UNKNOWN12          = 0x00000008,      CAST_FLAG_UNKNOWN2           = 0x00000010, -    CAST_FLAG_AMMO               = 0x00000020, -    CAST_FLAG_UNKNOWN3           = 0x00000100 +    CAST_FLAG_AMMO               = 0x00000020,              // Projectiles visual +    CAST_FLAG_UNKNOWN8           = 0x00000040, +    CAST_FLAG_UNKNOWN9           = 0x00000080, +    CAST_FLAG_UNKNOWN3           = 0x00000100, +    CAST_FLAG_UNKNOWN13          = 0x00000200, +    CAST_FLAG_UNKNOWN14          = 0x00000400, +    CAST_FLAG_UNKNOWN6           = 0x00000800,              // wotlk, trigger rune cooldown +    CAST_FLAG_UNKNOWN15          = 0x00001000, +    CAST_FLAG_UNKNOWN16          = 0x00002000, +    CAST_FLAG_UNKNOWN17          = 0x00004000, +    CAST_FLAG_UNKNOWN18          = 0x00008000, +    CAST_FLAG_UNKNOWN19          = 0x00010000, +    CAST_FLAG_UNKNOWN4           = 0x00020000,              // wotlk +    CAST_FLAG_UNKNOWN10          = 0x00040000, +    CAST_FLAG_UNKNOWN5           = 0x00080000,              // wotlk +    CAST_FLAG_UNKNOWN20          = 0x00100000, +    CAST_FLAG_UNKNOWN7           = 0x00200000               // wotlk, rune cooldown list  };  enum SpellRangeFlag @@ -275,6 +300,7 @@ class Spell          void EffectStuck(uint32 i);          void EffectSummonPlayer(uint32 i);          void EffectActivateObject(uint32 i); +        void EffectApplyGlyph(uint32 i);          void EffectSummonTotem(uint32 i);          void EffectEnchantHeldItem(uint32 i);          void EffectSummonObject(uint32 i); @@ -292,6 +318,7 @@ class Spell          void EffectSkinning(uint32 i);          void EffectCharge(uint32 i);          void EffectProspecting(uint32 i); +        void EffectMilling(uint32 i);          void EffectSendTaxi(uint32 i);          void EffectSummonCritter(uint32 i);          void EffectKnockBack(uint32 i); @@ -318,6 +345,8 @@ class Spell          void EffectKillCredit(uint32 i);          void EffectQuestFail(uint32 i);          void EffectRedirectThreat(uint32 i); +        void EffectActivateRune(uint32 i); +        void EffectTitanGrip(uint32 i);          Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL );          ~Spell(); @@ -328,6 +357,8 @@ class Spell          void cast(bool skipCheck = false);          void finish(bool ok = true);          void TakePower(); +        uint8 CheckRuneCost(uint32 runeCostID); +        void TakeRunePower();          void TakeReagents();          void TakeCastItem();          void TriggerSpell(); @@ -386,6 +417,7 @@ class Spell          int32 m_currentBasePoints[3];                       // cache SpellEntry::EffectBasePoints and use for set custom base points          Item* m_CastItem;          uint8 m_cast_count; +        uint32 m_glyphIndex;          SpellCastTargets m_targets;          int32 GetCastTime() const { return m_casttime; } @@ -422,7 +454,7 @@ class Spell          void UpdatePointers();                              // must be used at call Spell code after time delay (non triggered spell cast/update spell call/etc) -        bool IsAffectedBy(SpellEntry const *spellInfo, uint32 effectId); +        bool IsAffectedByAura(Aura *aura);          bool CheckTargetCreatureType(Unit* target) const; @@ -449,6 +481,7 @@ class Spell          int32 m_casttime;                                   // Calculated spell cast time initialized only in Spell::prepare          bool m_canReflect;                                  // can reflect this spell?          bool m_autoRepeat; +        uint8 m_runesState;          uint8 m_delayAtDamageCount;          int32 GetNextDelayAtDamageMsTime() { return m_delayAtDamageCount < 5 ? 1000 - (m_delayAtDamageCount++)* 200 : 200; } diff --git a/src/game/SpellAuraDefines.h b/src/game/SpellAuraDefines.h index cf628515925..59bb8128e11 100644 --- a/src/game/SpellAuraDefines.h +++ b/src/game/SpellAuraDefines.h @@ -20,14 +20,19 @@  #ifndef TRINITY_SPELLAURADEFINES_H  #define TRINITY_SPELLAURADEFINES_H -#define MAX_AURAS 56 -#define MAX_POSITIVE_AURAS 40 +#define MAX_AURAS 64                                        // client support up to 255, but it will cause problems with group auras updating  enum AURA_FLAGS  { -    AFLAG_NEGATIVE          = 0x09, -    AFLAG_POSITIVE          = 0x1F, -    AFLAG_MASK              = 0xFF +    AFLAG_NONE              = 0x00, +    AFLAG_EFF_INDEX_0       = 0x01, +    AFLAG_EFF_INDEX_1       = 0x02, +    AFLAG_EFF_INDEX_2       = 0x04, +    AFLAG_NOT_CASTER        = 0x08, +    AFLAG_POSITIVE          = 0x10, +    AFLAG_DURATION          = 0x20, +    AFLAG_UNK2              = 0x40, +    AFLAG_NEGATIVE          = 0x80  };  //m_schoolAbsorb @@ -233,7 +238,7 @@ enum AuraType      SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED = 191,      SPELL_AURA_HASTE_MELEE = 192,      SPELL_AURA_MELEE_SLOW = 193, -    SPELL_AURA_MOD_DEPRICATED_1  = 194,                     // not used now, old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT +    SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL  = 194,      SPELL_AURA_MOD_DEPRICATED_2  = 195,                     // not used now, old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT      SPELL_AURA_MOD_COOLDOWN = 196,                          // only 24818 Noxious Breath      SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE = 197, @@ -275,7 +280,7 @@ enum AuraType      SPELL_AURA_233 = 233,      SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK = 234,      SPELL_AURA_MOD_DISPEL_RESIST = 235, -    SPELL_AURA_236 = 236, +    SPELL_AURA_CONTROL_VEHICLE = 236,      SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER = 237,      SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER = 238,      SPELL_AURA_MOD_SCALE_2 = 239, @@ -285,28 +290,51 @@ enum AuraType      SPELL_AURA_243 = 243,      SPELL_AURA_COMPREHEND_LANGUAGE = 244,      SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS = 245, -    SPELL_AURA_246 = 246, +    SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL = 246,      SPELL_AURA_247 = 247,      SPELL_AURA_MOD_COMBAT_RESULT_CHANCE = 248, -    SPELL_AURA_249 = 249, +    SPELL_AURA_CONVERT_RUNE = 249,      SPELL_AURA_MOD_INCREASE_HEALTH_2 = 250,      SPELL_AURA_MOD_ENEMY_DODGE = 251,      SPELL_AURA_252 = 252, -    SPELL_AURA_253 = 253, -    SPELL_AURA_254 = 254, -    SPELL_AURA_255 = 255, -    SPELL_AURA_256 = 256, -    SPELL_AURA_257 = 257, +    SPELL_AURA_MOD_BLOCK_CRIT_CHANCE = 253, +    SPELL_AURA_MOD_DISARM_SHIELD = 254, +    SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT = 255, +    SPELL_AURA_NO_REAGENT_USE = 256, +    SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS = 257,      SPELL_AURA_258 = 258,      SPELL_AURA_259 = 259,      SPELL_AURA_260 = 260,      SPELL_AURA_261 = 261, -    TOTAL_AURAS=262 +    SPELL_AURA_262 = 262, +    SPELL_AURA_ALLOW_ONLY_ABILITY = 263, +    SPELL_AURA_264 = 264, +    SPELL_AURA_265 = 265, +    SPELL_AURA_266 = 266, +    SPELL_AURA_267 = 267, +    SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT = 268, +    SPELL_AURA_269 = 269, +    SPELL_AURA_270 = 270, +    SPELL_AURA_271 = 271, +    SPELL_AURA_272 = 272, +    SPELL_AURA_273 = 273, +    SPELL_AURA_274 = 274, +    SPELL_AURA_MOD_IGNORE_SHAPESHIFT = 275, +    SPELL_AURA_276 = 276,                    // Only "Test Mod Damage % Mechanic" spell, possible mod damage done +    SPELL_AURA_MOD_MAX_AFFECTED_TARGETS = 277, +    SPELL_AURA_MOD_DISARM_RANGED = 278, +    SPELL_AURA_279 = 279, +    SPELL_AURA_MOD_TARGET_ARMOR_PCT = 280, +    SPELL_AURA_MOD_HONOR_GAIN = 281, +    SPELL_AURA_MOD_BASE_HEALTH_PCT = 282, +    SPELL_AURA_MOD_HEALING_RECEIVED = 283,   // Possibly only for some spell family class spells +    TOTAL_AURAS = 284  };  enum AreaAuraType  {      AREA_AURA_PARTY, +    AREA_AURA_RAID,      AREA_AURA_FRIEND,      AREA_AURA_ENEMY,      AREA_AURA_PET, diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index d22266f2e15..38ca4e91d4c 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -163,7 +163,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleAuraHover,                                 //106 SPELL_AURA_HOVER      &Aura::HandleAddModifier,                               //107 SPELL_AURA_ADD_FLAT_MODIFIER      &Aura::HandleAddModifier,                               //108 SPELL_AURA_ADD_PCT_MODIFIER -    &Aura::HandleNoImmediateEffect,                         //109 SPELL_AURA_ADD_TARGET_TRIGGER +    &Aura::HandleAddTargetTrigger,                          //109 SPELL_AURA_ADD_TARGET_TRIGGER      &Aura::HandleModPowerRegenPCT,                          //110 SPELL_AURA_MOD_POWER_REGEN_PERCENT      &Aura::HandleNULL,                                      //111 SPELL_AURA_ADD_CASTER_HIT_TRIGGER      &Aura::HandleNoImmediateEffect,                         //112 SPELL_AURA_OVERRIDE_CLASS_SCRIPTS @@ -228,7 +228,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleAuraModIncreaseSpeed,                      //171 SPELL_AURA_MOD_SPEED_NOT_STACK      &Aura::HandleAuraModIncreaseMountedSpeed,               //172 SPELL_AURA_MOD_MOUNTED_SPEED_NOT_STACK      &Aura::HandleUnused,                                    //173 SPELL_AURA_ALLOW_CHAMPION_SPELLS  only for Proclaim Champion spell -    &Aura::HandleModSpellDamagePercentFromStat,             //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT  implemented in Unit::SpellBaseDamageBonus (by default intellect, dependent from SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT) +    &Aura::HandleModSpellDamagePercentFromStat,             //174 SPELL_AURA_MOD_SPELL_DAMAGE_OF_STAT_PERCENT  implemented in Unit::SpellBaseDamageBonus      &Aura::HandleModSpellHealingPercentFromStat,            //175 SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT implemented in Unit::SpellBaseHealingBonus      &Aura::HandleSpiritOfRedemption,                        //176 SPELL_AURA_SPIRIT_OF_REDEMPTION   only for Spirit of Redemption spell, die at aura end      &Aura::HandleNULL,                                      //177 SPELL_AURA_AOE_CHARM @@ -248,7 +248,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleAuraModUseNormalSpeed,                     //191 SPELL_AURA_USE_NORMAL_MOVEMENT_SPEED      &Aura::HandleModMeleeRangedSpeedPct,                    //192 SPELL_AURA_HASTE_MELEE      &Aura::HandleModCombatSpeedPct,                         //193 SPELL_AURA_MELEE_SLOW (in fact combat (any type attack) speed pct) -    &Aura::HandleUnused,                                    //194 SPELL_AURA_MOD_DEPRICATED_1 not used now (old SPELL_AURA_MOD_SPELL_DAMAGE_OF_INTELLECT) +    &Aura::HandleUnused,                                    //194 SPELL_AURA_MOD_IGNORE_ABSORB_SCHOOL      &Aura::HandleUnused,                                    //195 SPELL_AURA_MOD_DEPRICATED_2 not used now (old SPELL_AURA_MOD_SPELL_HEALING_OF_INTELLECT)      &Aura::HandleNULL,                                      //196 SPELL_AURA_MOD_COOLDOWN      &Aura::HandleNoImmediateEffect,                         //197 SPELL_AURA_MOD_ATTACKER_SPELL_AND_WEAPON_CRIT_CHANCE implemented in Unit::SpellCriticalBonus Unit::GetUnitCriticalChance @@ -274,7 +274,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleUnused,                                    //217                                   unused      &Aura::HandleAuraModRangedHaste,                        //218 SPELL_AURA_HASTE_RANGED      &Aura::HandleModManaRegen,                              //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT -    &Aura::HandleNULL,                                      //220 SPELL_AURA_MOD_RATING_FROM_STAT +    &Aura::HandleModRatingFromStat,                         //220 SPELL_AURA_MOD_RATING_FROM_STAT      &Aura::HandleNULL,                                      //221 ignored      &Aura::HandleUnused,                                    //222 unused      &Aura::HandleNULL,                                      //223 Cold Stare @@ -290,7 +290,7 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleNULL,                                      //233 set model id to the one of the creature with id m_modifier.m_miscvalue      &Aura::HandleNoImmediateEffect,                         //234 SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK implement in Unit::CalculateSpellDuration      &Aura::HandleAuraModDispelResist,                       //235 SPELL_AURA_MOD_DISPEL_RESIST               implement in Unit::MagicSpellHitResult -    &Aura::HandleUnused,                                    //236 unused +    &Aura::HandleAuraControlVehicle,                        //236 SPELL_AURA_CONTROL_VEHICLE      &Aura::HandleModSpellDamagePercentFromAttackPower,      //237 SPELL_AURA_MOD_SPELL_DAMAGE_OF_ATTACK_POWER  implemented in Unit::SpellBaseDamageBonus      &Aura::HandleModSpellHealingPercentFromAttackPower,     //238 SPELL_AURA_MOD_SPELL_HEALING_OF_ATTACK_POWER implemented in Unit::SpellBaseHealingBonus      &Aura::HandleAuraModScale,                              //239 SPELL_AURA_MOD_SCALE_2 only in Noggenfogger Elixir (16595) before 2.3.0 aura 61 @@ -300,22 +300,44 @@ pAuraHandler AuraHandler[TOTAL_AURAS]=      &Aura::HandleUnused,                                    //243 used by two test spells      &Aura::HandleComprehendLanguage,                        //244 Comprehend language      &Aura::HandleUnused,                                    //245 SPELL_AURA_MOD_DURATION_OF_MAGIC_EFFECTS -    &Aura::HandleUnused,                                    //246 unused +    &Aura::HandleNoImmediateEffect,                         //246 SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL      &Aura::HandleUnused,                                    //247 unused      &Aura::HandleNoImmediateEffect,                         //248 SPELL_AURA_MOD_COMBAT_RESULT_CHANCE         implemented in Unit::RollMeleeOutcomeAgainst -    &Aura::HandleNULL,                                      //249 +    &Aura::HandleAuraConvertRune,                           //249 SPELL_AURA_CONVERT_RUNE      &Aura::HandleAuraModIncreaseHealth,                     //250 SPELL_AURA_MOD_INCREASE_HEALTH_2      &Aura::HandleNULL,                                      //251 SPELL_AURA_MOD_ENEMY_DODGE -    &Aura::HandleUnused,                                    //252 unused -    &Aura::HandleUnused,                                    //253 unused -    &Aura::HandleUnused,                                    //254 unused -    &Aura::HandleUnused,                                    //255 unused -    &Aura::HandleUnused,                                    //256 unused -    &Aura::HandleUnused,                                    //257 unused -    &Aura::HandleUnused,                                    //258 unused -    &Aura::HandleUnused,                                    //259 unused -    &Aura::HandleUnused,                                    //260 unused -    &Aura::HandleNULL                                       //261 SPELL_AURA_261 some phased state (44856 spell) +    &Aura::HandleNULL,                                      //252 haste all? +    &Aura::HandleNULL,                                      //253 SPELL_AURA_MOD_BLOCK_CRIT_CHANCE +    &Aura::HandleNULL,                                      //254 SPELL_AURA_MOD_DISARM_SHIELD disarm Shield +    &Aura::HandleNULL,                                      //255 SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT +    &Aura::HandleNoReagentUseAura,                          //256 SPELL_AURA_NO_REAGENT_USE Use SpellClassMask for spell select +    &Aura::HandleNULL,                                      //257 SPELL_AURA_MOD_TARGET_RESIST_BY_SPELL_CLASS Use SpellClassMask for spell select +    &Aura::HandleNULL,                                      //258 SPELL_AURA_MOD_SPELL_VISUAL +    &Aura::HandleNULL,                                      //259 corrupt healing over time spell +    &Aura::HandleNULL,                                      //260 +    &Aura::HandleNULL,                                      //261 out of phase? +    &Aura::HandleNULL,                                      //262 +    &Aura::HandleNULL,                                      //263 SPELL_AURA_ALLOW_ONLY_ABILITY player can use only abilites set in SpellClassMask +    &Aura::HandleNULL,                                      //264 unused +    &Aura::HandleNULL,                                      //265 unused +    &Aura::HandleNULL,                                      //266 unused +    &Aura::HandleNULL,                                      //267 some immunity? +    &Aura::HandleAuraModAttackPowerOfStatPercent,           //268 SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT +    &Aura::HandleNULL,                                      //269 ignore DR effects? +    &Aura::HandleNULL,                                      //270 +    &Aura::HandleNULL,                                      //271 increase damage done? +    &Aura::HandleNULL,                                      //272 reduce spell cast time? +    &Aura::HandleNULL,                                      //273 +    &Aura::HandleNULL,                                      //274 proc free shot? +    &Aura::HandleNoImmediateEffect,                         //275 SPELL_AURA_MOD_IGNORE_SHAPESHIFT Use SpellClassMask for spell select +    &Aura::HandleNULL,                                      //276 mod damage % mechanic? +    &Aura::HandleNoImmediateEffect,                         //277 SPELL_AURA_MOD_MAX_AFFECTED_TARGETS Use SpellClassMask for spell select +    &Aura::HandleNULL,                                      //278 SPELL_AURA_MOD_DISARM_RANGED disarm ranged weapon +    &Aura::HandleNULL,                                      //279 +    &Aura::HandleNULL,                                      //280 SPELL_AURA_MOD_TARGET_ARMOR_PCT +    &Aura::HandleNULL,                                      //281 SPELL_AURA_MOD_HONOR_GAIN +    &Aura::HandleAuraIncreaseBaseHealthPercent,             //282 SPELL_AURA_INCREASE_BASE_HEALTH_PERCENT +    &Aura::HandleNULL                                       //283 SPD/heal from AP?  };  Aura::Aura(SpellEntry const* spellproto, uint32 eff, int32 *currentBasePoints, Unit *target, Unit *caster, Item* castItem) : @@ -446,6 +468,11 @@ Unit *caster, Item* castItem) : Aura(spellproto, eff, currentBasePoints, target,              if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem())                  m_modifier.m_auraname = SPELL_AURA_NONE;              break; +        case SPELL_EFFECT_APPLY_AREA_AURA_RAID: +            m_areaAuraType = AREA_AURA_RAID; +            if(target->GetTypeId() == TYPEID_UNIT && ((Creature*)target)->isTotem()) +                m_modifier.m_auraname = SPELL_AURA_NONE; +            break;          case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:              m_areaAuraType = AREA_AURA_FRIEND;              break; @@ -612,8 +639,8 @@ void AreaAura::Update(uint32 diff)              switch(m_areaAuraType)              { -                case AREA_AURA_PARTY: -                    caster->GetPartyMember(targets, m_radius);  +                case AREA_AURA_RAID: +                    caster->GetRaidMember(targets, m_radius);                       break;                  case AREA_AURA_FRIEND:                  { @@ -696,6 +723,24 @@ void AreaAura::Update(uint32 diff)                      tmp_target->RemoveAura(tmp_spellId, tmp_effIndex);              }          } +        else if( m_areaAuraType == AREA_AURA_RAID)          // TODO: fix me! +        { +            // not check group if target == owner or target == pet +            if (caster->GetCharmerOrOwnerGUID() != tmp_target->GetGUID() && caster->GetGUID() != tmp_target->GetCharmerOrOwnerGUID()) +            { +                Player* check = caster->GetCharmerOrOwnerPlayerOrPlayerItself(); + +                Group *pGroup = check ? check->GetGroup() : NULL; +                if( pGroup ) +                { +                    Player* checkTarget = tmp_target->GetCharmerOrOwnerPlayerOrPlayerItself(); +                    if(!checkTarget) +                        tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); +                } +                else +                    tmp_target->RemoveAura(tmp_spellId, tmp_effIndex); +            } +        }          else if( m_areaAuraType == AREA_AURA_PET || m_areaAuraType == AREA_AURA_OWNER )          {              if( tmp_target->GetGUID() != caster->GetCharmerOrOwnerGUID() ) @@ -746,47 +791,6 @@ void Aura::ApplyModifier(bool apply, bool Real)      m_in_use = false;  } -void Aura::UpdateAuraDuration() -{ -    if(m_auraSlot >= MAX_AURAS || m_isPassive) -        return; - -    if( m_target->GetTypeId() == TYPEID_PLAYER) -    { -        WorldPacket data(SMSG_UPDATE_AURA_DURATION, 5); -        data << (uint8)m_auraSlot << (uint32)m_duration; -        ((Player*)m_target)->SendDirectMessage(&data); - -        data.Initialize(SMSG_SET_EXTRA_AURA_INFO, (8+1+4+4+4)); -        data.append(m_target->GetPackGUID()); -        data << uint8(m_auraSlot); -        data << uint32(GetId()); -        data << uint32(GetAuraMaxDuration()); -        data << uint32(GetAuraDuration()); -        ((Player*)m_target)->SendDirectMessage(&data); -    } - -    // not send in case player loading (will not work anyway until player not added to map), sent in visibility change code -    if(m_target->GetTypeId() == TYPEID_PLAYER && ((Player*)m_target)->GetSession()->PlayerLoading()) -        return; - -    Unit* caster = GetCaster(); - -    if(caster && caster->GetTypeId() == TYPEID_PLAYER && caster != m_target) -        SendAuraDurationForCaster((Player*)caster); -} - -void Aura::SendAuraDurationForCaster(Player* caster) -{ -    WorldPacket data(SMSG_SET_EXTRA_AURA_INFO_NEED_UPDATE, (8+1+4+4+4)); -    data.append(m_target->GetPackGUID()); -    data << uint8(m_auraSlot); -    data << uint32(GetId()); -    data << uint32(GetAuraMaxDuration());                   // full -    data << uint32(GetAuraDuration());                      // remain -    caster->GetSession()->SendPacket(&data); -} -  void Aura::_AddAura()  {      if (!GetId()) @@ -852,22 +856,13 @@ void Aura::_AddAura()      {          if(!secondaura)                                     // new slot need          { -            if (IsPositive())                               // empty positive slot +            if(m_target->GetVisibleAurasCount() < MAX_AURAS)              { -                for (uint8 i = 0; i < MAX_POSITIVE_AURAS; i++) +                Unit::VisibleAuraMap const *visibleAuras = m_target->GetVisibleAuras(); +                for(uint8 i = 0; i < MAX_AURAS; ++i)                  { -                    if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0) -                    { -                        slot = i; -                        break; -                    } -                } -            } -            else                                            // empty negative slot -            { -                for (uint8 i = MAX_POSITIVE_AURAS; i < MAX_AURAS; i++) -                { -                    if (m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + i)) == 0) +                    Unit::VisibleAuraMap::const_iterator itr = visibleAuras->find(i); +                    if(itr == visibleAuras->end())                      {                          slot = i;                          break; @@ -880,11 +875,12 @@ void Aura::_AddAura()              // Not update fields for not first spell's aura, all data already in fields              if(slot < MAX_AURAS)                        // slot found              { -                SetAura(slot, false); -                SetAuraFlag(slot, true); -                SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); +                SetAura(false); +                SetAuraFlags((1 << GetEffIndex()) | AFLAG_NOT_CASTER | ((GetAuraMaxDuration() > 0) ? AFLAG_DURATION : AFLAG_NONE) | (IsPositive() ? AFLAG_POSITIVE : AFLAG_NEGATIVE)); +                SetAuraLevel(caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL));                  UpdateAuraCharges(); -                 +                SendAuraUpdate(false); +                  // update for out of range group members                  m_target->UpdateAuraForGroup(slot, true);              } @@ -942,7 +938,7 @@ void Aura::_RemoveAura()      if(slot >= MAX_AURAS)                                   // slot not set          return; -    if(m_target->GetUInt32Value((uint16)(UNIT_FIELD_AURA + slot)) == 0) +    if(m_target->GetVisibleAura(slot) == 0)          return;      bool samespell = false; @@ -967,11 +963,12 @@ void Aura::_RemoveAura()      // only remove icon when the last aura of the spell is removed (current aura already removed from list)      if (!samespell)      { -        SetAura(slot, true); -        SetAuraFlag(slot, false); -        SetAuraLevel(slot,caster ? caster->getLevel() : sWorld.getConfig(CONFIG_MAX_PLAYER_LEVEL)); +        SetAura(true); +        SetAuraFlags(AFLAG_NONE); +        SetAuraLevel(0); +        SetAuraCharges(0); +        SendAuraUpdate(true); -        SetAuraApplication(slot, 0);          // update for out of range group members          m_target->UpdateAuraForGroup(slot, false); @@ -1010,40 +1007,36 @@ void Aura::_RemoveAura()      }  } -void Aura::SetAuraFlag(uint32 slot, bool add) +void Aura::SendAuraUpdate(bool remove)  { -    uint32 index    = slot / 4; -    uint32 byte     = (slot % 4) * 8; -    uint32 val      = m_target->GetUInt32Value(UNIT_FIELD_AURAFLAGS + index); -    val &= ~((uint32)AFLAG_MASK << byte); -    if(add) +    WorldPacket data(SMSG_AURA_UPDATE); +    data.append(m_target->GetPackGUID()); +    data << uint8(GetAuraSlot()); +    data << uint32(remove ? 0 : GetId()); + +    if(remove)      { -        if (IsPositive()) -            val |= ((uint32)AFLAG_POSITIVE << byte); -        else -            val |= ((uint32)AFLAG_NEGATIVE << byte); +        m_target->SendMessageToSet(&data, true); +        return;      } -    m_target->SetUInt32Value(UNIT_FIELD_AURAFLAGS + index, val); -} -void Aura::SetAuraLevel(uint32 slot,uint32 level) -{ -    uint32 index    = slot / 4; -    uint32 byte     = (slot % 4) * 8; -    uint32 val      = m_target->GetUInt32Value(UNIT_FIELD_AURALEVELS + index); -    val &= ~(0xFF << byte); -    val |= (level << byte); -    m_target->SetUInt32Value(UNIT_FIELD_AURALEVELS + index, val); -} +    uint8 auraFlags = GetAuraFlags(); +    data << uint8(auraFlags); +    data << uint8(GetAuraLevel()); +    data << uint8(m_procCharges >= 0 ? m_procCharges : 0); -void Aura::SetAuraApplication(uint32 slot, int8 count) -{ -    uint32 index    = slot / 4; -    uint32 byte     = (slot % 4) * 8; -    uint32 val      = m_target->GetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index); -    val &= ~(0xFF << byte); -    val |= ((uint8(count)) << byte); -    m_target->SetUInt32Value(UNIT_FIELD_AURAAPPLICATIONS + index, val); +    if(!(auraFlags & AFLAG_NOT_CASTER)) +    { +        data << uint8(0);                                   // pguid +    } + +    if(auraFlags & AFLAG_DURATION) +    { +        data << uint32(GetAuraMaxDuration()); +        data << uint32(GetAuraDuration()); +    } + +    m_target->SendMessageToSet(&data, true);  }  void Aura::UpdateSlotCounterAndDuration() @@ -1056,10 +1049,26 @@ void Aura::UpdateSlotCounterAndDuration()      // Charge = 0; Stack >= 0      // Charge = 1; Stack >= 0      // Charge > 1; Stack = 0 +    //SetAuraDuration(GetAuraDuration());      if(m_procCharges < 2) -        SetAuraApplication(slot, m_stackAmount-1); +    { +        SetAuraCharges(m_stackAmount-1); +        SendAuraUpdate(false); +    } +} -    UpdateAuraDuration(); +bool Aura::isAffectedOnSpell(SpellEntry const *spell) const +{ +    // Check family name +    if (spell->SpellFamilyName != m_spellProto->SpellFamilyName) +        return false; +    // Check EffectClassMask +    uint32 const *ptr = getAuraSpellClassMask(); +    if (((uint64*)ptr)[0] & spell->SpellFamilyFlags) +        return true; +    if (ptr[2] & spell->SpellFamilyFlags2) +        return true; +    return false;  }  /*********************************************************/ @@ -1070,10 +1079,6 @@ void Aura::HandleAddModifier(bool apply, bool Real)      if(m_target->GetTypeId() != TYPEID_PLAYER || !Real)          return; -    SpellEntry const *spellInfo = GetSpellProto(); -    if(!spellInfo) -        return; -      if(m_modifier.m_miscvalue >= MAX_SPELLMOD)          return; @@ -1084,7 +1089,10 @@ void Aura::HandleAddModifier(bool apply, bool Real)          {              case 17941:    // Shadow Trance              case 22008:    // Netherwind Focus +            case 31834:    // Light's Grace +            case 34754:    // Clearcasting              case 34936:    // Backlash +            case 48108:    // Hot Streak                  m_procCharges = 1;                  break;          } @@ -1094,15 +1102,25 @@ void Aura::HandleAddModifier(bool apply, bool Real)          mod->value = GetModifierValue();          mod->type = SpellModType(m_modifier.m_auraname);    // SpellModType value == spell aura types          mod->spellId = GetId(); -        mod->effectId = m_effIndex; -        mod->lastAffected = NULL; -        uint64 spellAffectMask = spellmgr.GetSpellAffectMask(GetId(), m_effIndex); - -        if (spellAffectMask) -            mod->mask = spellAffectMask; +        uint32 const *ptr; +        SpellAffectEntry const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex); +        if (spellAffect) +            ptr = &spellAffect->SpellClassMask[0];          else -            mod->mask = spellInfo->EffectItemType[m_effIndex]; +        { +            switch (m_effIndex) +            { +                case 0: ptr = &m_spellProto->EffectSpellClassMaskA[0]; break; +                case 1: ptr = &m_spellProto->EffectSpellClassMaskB[0]; break; +                case 2: ptr = &m_spellProto->EffectSpellClassMaskC[0]; break; +                default: +                    return; +            } +        } + +        mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32; +        mod->mask2= (uint64)ptr[2];          if (m_procCharges > 0)              mod->charges = m_procCharges; @@ -1117,7 +1135,7 @@ void Aura::HandleAddModifier(bool apply, bool Real)      ((Player*)m_target)->AddSpellMod(m_spellmod, apply);      // reapply some passive spells after add/remove related spellmods -    if(spellInfo->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL)) +    if(m_spellProto->SpellFamilyName==SPELLFAMILY_WARRIOR && (spellFamilyMask & 0x0000100000000000LL))      {          m_target->RemoveAurasDueToSpell(45471); @@ -1125,7 +1143,42 @@ void Aura::HandleAddModifier(bool apply, bool Real)              m_target->CastSpell(m_target,45471,true);      }  } +void Aura::HandleAddTargetTrigger(bool apply, bool Real) +{ +    // Use SpellModifier structure for check +    // used only fields: +    //  spellId, mask, mask2 +    if (apply) +    { +        SpellModifier *mod = new SpellModifier; +        mod->spellId = GetId(); + +        uint32 const *ptr; +        SpellAffectEntry const *spellAffect = spellmgr.GetSpellAffect(GetId(), m_effIndex); +        if (spellAffect) +            ptr = &spellAffect->SpellClassMask[0]; +        else +        { +            switch (m_effIndex) +            { +                case 0: ptr = &m_spellProto->EffectSpellClassMaskA[0]; break; +                case 1: ptr = &m_spellProto->EffectSpellClassMaskB[0]; break; +                case 2: ptr = &m_spellProto->EffectSpellClassMaskC[0]; break; +                default: +                    return; +            } +        } +        mod->mask = (uint64)ptr[0] | (uint64)ptr[1]<<32; +        mod->mask2= (uint64)ptr[2]; +        m_spellmod = mod; +    } +    else +    { +        delete m_spellmod; +        m_spellmod = NULL; +    } +}  void Aura::TriggerSpell()  {      Unit* caster = GetCaster(); @@ -2103,10 +2156,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real)                      mod->value = m_modifier.m_amount/7;                      mod->type = SPELLMOD_FLAT;                      mod->spellId = GetId(); -                    mod->effectId = m_effIndex; -                    mod->lastAffected = NULL;                      mod->mask = 0x001000000000LL; -                    mod->charges = 0; +                    mod->mask2= 0LL;                      m_spellmod = mod;                  } @@ -2129,10 +2180,8 @@ void Aura::HandleAuraDummy(bool apply, bool Real)                      mod->value = m_modifier.m_amount;                      mod->type = SPELLMOD_FLAT;                      mod->spellId = GetId(); -                    mod->effectId = m_effIndex; -                    mod->lastAffected = NULL;                      mod->mask = 0x4000000000000LL; -                    mod->charges = 0; +                    mod->mask2= 0LL;                      m_spellmod = mod;                  } @@ -2154,18 +2203,17 @@ void Aura::HandleAuraDummy(bool apply, bool Real)                      mod->value = m_modifier.m_amount;                      mod->type = SPELLMOD_PCT;                      mod->spellId = GetId(); -                    mod->effectId = m_effIndex; -                    mod->lastAffected = NULL;                      switch (m_effIndex)                      {                          case 0:                              mod->mask = 0x00200000000LL;    // Windfury Totem +                            mod->mask2= 0LL;                              break;                          case 1:                              mod->mask = 0x00400000000LL;    // Flametongue Totem +                            mod->mask2= 0LL;                              break;                      } -                    mod->charges = 0;                      m_spellmod = mod;                  } @@ -2212,6 +2260,8 @@ void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)      if(!Real)          return; +    Unit* caster = GetCaster(); +      SpellEntry const*spell = GetSpellProto();      switch( spell->SpellFamilyName)      { @@ -2235,6 +2285,16 @@ void Aura::HandleAuraPeriodicDummy(bool apply, bool Real)                      ((Player*)m_target)->UpdateManaRegen();                  break;              } +            // Explosive Shot +            if (spell->SpellFamilyFlags & 0x8000000000000000LL) +            { +                if (apply && caster) +                { +                    int32 damage = m_modifier.m_amount + caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; +                    caster->CastCustomSpell(m_target, 53352, &damage, 0, 0, true, 0, this); +                } +                break; +            }              break;          }      } @@ -2407,6 +2467,9 @@ void Aura::HandleAuraModShapeshift(bool apply, bool Real)              else                  modelid = 21244;              break; +        case FORM_METAMORPHOSIS: +            modelid = 25277; +            break;          case FORM_AMBIENT:          case FORM_SHADOW:          case FORM_STEALTH: @@ -2877,6 +2940,36 @@ void Aura::HandleModPossess(bool apply, bool Real)      }      else          m_target->UnpossessSelf(true); +    /*{ +        m_target->SetCharmerGUID(0); + +        if(m_target->GetTypeId() == TYPEID_PLAYER) +            ((Player*)m_target)->setFactionForRace(m_target->getRace()); +        else if(m_target->GetTypeId() == TYPEID_UNIT) +        { +            CreatureInfo const *cinfo = ((Creature*)m_target)->GetCreatureInfo(); +            m_target->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE,cinfo->faction_A); +        } + +        caster->SetCharm(0); + +        if(caster->GetTypeId() == TYPEID_PLAYER) +        { +            WorldPacket data(SMSG_PET_SPELLS, 8); +            data << uint64(0); +            data << uint32(0); +            ((Player*)caster)->GetSession()->SendPacket(&data); +        } +        if(m_target->GetTypeId() == TYPEID_UNIT) +        { +            ((Creature*)m_target)->AIM_Initialize(); + +            if (((Creature*)m_target)->AI()) +                ((Creature*)m_target)->AI()->AttackStart(caster); +        } +    } +    if(caster->GetTypeId() == TYPEID_PLAYER) +        ((Player*)caster)->SetFarSight(apply ? m_target->GetGUID() : NULL);*/  }  void Aura::HandleModPossessPet(bool apply, bool Real) @@ -2887,16 +2980,33 @@ void Aura::HandleModPossessPet(bool apply, bool Real)      Unit* caster = GetCaster();      if(!caster || caster->GetTypeId() != TYPEID_PLAYER)          return; -    if(caster->GetPet() != m_target) + +    Pet *pet = caster->GetPet(); +    if(!pet || pet != m_target)          return;      if(apply) +        pet->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); +    else +        pet->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNKNOWN5); + +    ((Player*)caster)->SetFarSight(apply ? pet->GetGUID() : NULL); +    ((Player*)caster)->SetCharm(apply ? pet : NULL); +    ((Player*)caster)->SetClientControl(pet, apply ? 1 : 0); + +    if(apply)      {          ((Player*)caster)->Possess(m_target);      }      else      {          ((Player*)caster)->RemovePossess(false); +        /*pet->StopMoving(); +        pet->GetMotionMaster()->Clear(); +        pet->GetMotionMaster()->MoveIdle();*/ +        pet->AttackStop(); +        pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); +        pet->SetUnitMovementFlags(MOVEMENTFLAG_NONE);      }  } @@ -3003,6 +3113,7 @@ void Aura::HandleModCharm(bool apply, bool Real)              {                  WorldPacket data(SMSG_PET_SPELLS, 8);                  data << uint64(0); +                data << uint32(0);                  ((Player*)caster)->GetSession()->SendPacket(&data);              }          } @@ -3951,7 +4062,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)          case SPELLFAMILY_ROGUE:          {              // Deadly poison aura state -            if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual==5100) +            if((m_spellProto->SpellFamilyFlags & 0x10000) && m_spellProto->SpellVisual[0]==5100)              {                  if(apply)                      m_target->ModifyAuraState(AURA_STATE_DEADLY_POISON,true); @@ -3963,7 +4074,7 @@ void Aura::HandlePeriodicDamage(bool apply, bool Real)                      for(Unit::AuraList::const_iterator itr = auras.begin(); itr != auras.end(); ++itr)                      {                          SpellEntry const* itr_spell = (*itr)->GetSpellProto(); -                        if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual==5100) +                        if(itr_spell && itr_spell->SpellFamilyName==SPELLFAMILY_ROGUE && (itr_spell->SpellFamilyFlags & 0x10000) && itr_spell->SpellVisual[0]==5100)                          {                              found = true;                              break; @@ -4536,6 +4647,11 @@ void Aura::HandleAuraModIncreaseHealthPercent(bool apply, bool /*Real*/)      m_target->HandleStatModifier(UNIT_MOD_HEALTH, TOTAL_PCT, float(GetModifierValue()), apply);  } +void Aura::HandleAuraIncreaseBaseHealthPercent(bool apply, bool /*Real*/) +{ +    m_target->HandleStatModifier(UNIT_MOD_HEALTH, BASE_PCT, float(m_modifier.m_amount), apply); +} +  /********************************/  /***          FIGHT           ***/  /********************************/ @@ -4609,13 +4725,28 @@ void Aura::HandleAuraModCritPercent(bool apply, bool Real)  void Aura::HandleModHitChance(bool apply, bool Real)  { -    m_target->m_modMeleeHitChance += apply ? GetModifierValue() : -GetModifierValue(); -    m_target->m_modRangedHitChance += apply ? GetModifierValue() : -GetModifierValue(); +    if(m_target->GetTypeId() == TYPEID_PLAYER) +    { +        ((Player*)m_target)->UpdateMeleeHitChances(); +        ((Player*)m_target)->UpdateRangedHitChances(); +    } +    else +    { +        m_target->m_modMeleeHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount); +        m_target->m_modRangedHitChance += apply ? m_modifier.m_amount : (-m_modifier.m_amount); +    }  }  void Aura::HandleModSpellHitChance(bool apply, bool Real)  { -    m_target->m_modSpellHitChance += apply ? GetModifierValue(): -GetModifierValue(); +    if(m_target->GetTypeId() == TYPEID_PLAYER) +    { +        ((Player*)m_target)->UpdateSpellHitChances(); +    } +    else +    { +        m_target->m_modSpellHitChance += apply ? m_modifier.m_amount: (-m_modifier.m_amount); +    }  }  void Aura::HandleModSpellCritChance(bool apply, bool Real) @@ -4740,15 +4871,21 @@ void Aura::HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real)      if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)          return; -    if(m_modifier.m_miscvalue != STAT_INTELLECT) -    { -        // support required adding UpdateAttackPowerAndDamage calls at stat update -        sLog.outError("Aura SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT (212) need support non-intellect stats!"); +    // Recalculate bonus +    ((Player*)m_target)->UpdateAttackPowerAndDamage(true); +} + +void Aura::HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real) +{ +    // spells required only Real aura add/remove +    if(!Real) +        return; + +    if(m_target->GetTypeId() == TYPEID_PLAYER && (m_target->getClassMask() & CLASSMASK_WAND_USERS)!=0)          return; -    }      // Recalculate bonus -    ((Player*)m_target)->UpdateAttackPowerAndDamage(true); +    ((Player*)m_target)->UpdateAttackPowerAndDamage(false);  }  /********************************/ @@ -4932,6 +5069,28 @@ void Aura::HandleModPowerCost(bool apply, bool Real)              m_target->ApplyModInt32Value(UNIT_FIELD_POWER_COST_MODIFIER+i,GetModifierValue(),apply);  } +void Aura::HandleNoReagentUseAura(bool Apply, bool Real) +{ +    // spells required only Real aura add/remove +    if(!Real) +        return; +    if(m_target->GetTypeId() != TYPEID_PLAYER) +        return; +    uint32 mask[3] = {0, 0, 0}; +    Unit::AuraList const& noReagent = m_target->GetAurasByType(SPELL_AURA_NO_REAGENT_USE); +        for(Unit::AuraList::const_iterator i = noReagent.begin(); i !=  noReagent.end(); ++i) +        { +            uint32 const *ptr = (*i)->getAuraSpellClassMask(); +            mask[0]|=ptr[0]; +            mask[1]|=ptr[1]; +            mask[2]|=ptr[2]; +        } + +    m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1  , mask[0]); +    m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+1, mask[1]); +    m_target->SetUInt32Value(PLAYER_NO_REAGENT_COST_1+2, mask[2]); +} +  /*********************************************************/  /***                    OTHERS                         ***/  /*********************************************************/ @@ -4988,6 +5147,10 @@ void Aura::HandleShapeshiftBoosts(bool apply)              spellId  = 40122;              spellId2 = 40121;              break; +        case FORM_METAMORPHOSIS: +            spellId  = 54817; +            spellId2 = 54879; +            break;          case FORM_SPIRITOFREDEMPTION:              spellId  = 27792;              spellId2 = 27795;                               // must be second, this important at aura remove to prevent to early iterator invalidation. @@ -5153,6 +5316,20 @@ void Aura::HandleModRating(bool apply, bool Real)              ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), GetModifierValue(), apply);  } +void Aura::HandleModRatingFromStat(bool apply, bool Real) +{ +    // spells required only Real aura add/remove +    if(!Real) +        return; + +    if(m_target->GetTypeId() != TYPEID_PLAYER) +        return; +    // Just recalculate ratings +    for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) +        if (m_modifier.m_miscvalue & (1 << rating)) +            ((Player*)m_target)->ApplyRatingMod(CombatRating(rating), 0, apply); +} +  void Aura::HandleForceMoveForward(bool apply, bool Real)  {      if(!Real || m_target->GetTypeId() != TYPEID_PLAYER) @@ -5462,6 +5639,7 @@ void Aura::PeriodicTick()              data << (uint32)GetSpellSchoolMask(GetSpellProto()); // will be mask in 2.4.x              data << (uint32)absorb;              data << (uint32)resist; +            data << uint32(0);                              // wotlk              m_target->SendMessageToSet(&data,true);              Unit* target = m_target;                        // aura can be deleted in DealDamage @@ -5625,7 +5803,7 @@ void Aura::PeriodicTick()                  return;              // heal for caster damage (must be alive) -            if(m_target != pCaster && GetSpellProto()->SpellVisual==163 && !pCaster->isAlive()) +            if(m_target != pCaster && GetSpellProto()->SpellVisual[0]==163 && !pCaster->isAlive())                  return;              // ignore non positive values (can be result apply spellmods to aura damage @@ -5652,6 +5830,7 @@ void Aura::PeriodicTick()              data << uint32(1);              data << uint32(m_modifier.m_auraname);              data << (uint32)pdamage; +            data << uint32(0);                              // wotlk              m_target->SendMessageToSet(&data,true);              int32 gain = m_target->ModifyHealth(pdamage); @@ -5671,7 +5850,7 @@ void Aura::PeriodicTick()              bool haveCastItem = GetCastItemGUID()!=0;              // heal for caster damage -            if(m_target!=pCaster && spellProto->SpellVisual==163) +            if(m_target!=pCaster && spellProto->SpellVisual[0]==163)              {                  uint32 dmg = spellProto->manaPerSecond;                  if(pCaster->GetHealth() <= dmg && pCaster->GetTypeId()==TYPEID_PLAYER) @@ -5892,114 +6071,136 @@ void Aura::PeriodicTick()  void Aura::PeriodicDummyTick()  { +    Unit *caster = GetCaster();      SpellEntry const* spell = GetSpellProto(); -    switch (spell->Id) -    { -        // Drink -        case 430: -        case 431: -        case 432: -        case 1133: -        case 1135: -        case 1137: -        case 10250: -        case 22734: -        case 27089: -        case 34291: -        case 43706: -        case 46755: -        { -            if (m_target->GetTypeId() != TYPEID_PLAYER) -                return; -            // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus -            Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN); -            for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i) +    switch (spell->SpellFamilyName) +    { +        case SPELLFAMILY_GENERIC: +        switch (spell->Id) +        { +            // Drink +            case 430: +            case 431: +            case 432: +            case 1133: +            case 1135: +            case 1137: +            case 10250: +            case 22734: +            case 27089: +            case 34291: +            case 43706: +            case 46755: +            case 49472: // Drink Coffee +            case 61830:              { -                if ((*i)->GetId() == GetId()) -                { -                    // Get tick number -                    int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime; -                    // Default case (not on arenas) -                    if (tick == 0) -                    { -                        (*i)->GetModifier()->m_amount = m_modifier.m_amount; -                        ((Player*)m_target)->UpdateManaRegen(); -                        // Disable continue -                        m_isPeriodic = false; -                    } +                if (m_target->GetTypeId() != TYPEID_PLAYER)                      return; -                    //********************************************** -                    // Code commended since arena patch not added -                    // This feature uses only in arenas -                    //********************************************** -                    // Here need increase mana regen per tick (6 second rule) -                    // on 0 tick -   0  (handled in 2 second) -                    // on 1 tick - 166% (handled in 4 second) -                    // on 2 tick - 133% (handled in 6 second) -                    // Not need update after 3 tick -                    /* -                    if (tick > 3) -                        return; -                    // Apply bonus for 0 - 3 tick -                    switch (tick) +                // Search SPELL_AURA_MOD_POWER_REGEN aura for this spell and add bonus +                Unit::AuraList const& aura = m_target->GetAurasByType(SPELL_AURA_MOD_POWER_REGEN); +                for(Unit::AuraList::const_iterator i = aura.begin(); i != aura.end(); ++i) +                { +                    if ((*i)->GetId() == GetId())                      { -                        case 0:   // 0% -                            (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0; -                            break; -                        case 1:   // 166% -                            (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3; -                            break; -                        case 2:   // 133% -                            (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3; -                            break; -                        default:  // 100% - normal regen +                        // Get tick number +                        int32 tick = (m_maxduration - m_duration) / m_modifier.periodictime; +                        // Default case (not on arenas) +                        if (tick == 0) +                        {                              (*i)->GetModifier()->m_amount = m_modifier.m_amount; -                            break; +                            ((Player*)m_target)->UpdateManaRegen(); +                            // Disable continue +                            m_isPeriodic = false; +                        } +                        return; +                        //********************************************** +                        // Code commended since arena patch not added +                        // This feature uses only in arenas +                        //********************************************** +                        // Here need increase mana regen per tick (6 second rule) +                        // on 0 tick -   0  (handled in 2 second) +                        // on 1 tick - 166% (handled in 4 second) +                        // on 2 tick - 133% (handled in 6 second) +                        // Not need update after 3 tick +                        /* +                        if (tick > 3) +                            return; +                        // Apply bonus for 0 - 3 tick +                        switch (tick) +                        { +                            case 0:   // 0% +                                (*i)->GetModifier()->m_amount = m_modifier.m_amount = 0; +                                break; +                            case 1:   // 166% +                                (*i)->GetModifier()->m_amount = m_modifier.m_amount * 5 / 3; +                                break; +                            case 2:   // 133% +                                (*i)->GetModifier()->m_amount = m_modifier.m_amount * 4 / 3; +                                break; +                            default:  // 100% - normal regen +                                (*i)->GetModifier()->m_amount = m_modifier.m_amount; +                                break; +                        } +                        ((Player*)m_target)->UpdateManaRegen(); +                        return;*/                      } -                    ((Player*)m_target)->UpdateManaRegen(); -                    return;*/                  } +                return; +            } +            // Forsaken Skills +            case 7054: +            { +                // Possibly need cast one of them (but +                // 7038 Forsaken Skill: Swords +                // 7039 Forsaken Skill: Axes +                // 7040 Forsaken Skill: Daggers +                // 7041 Forsaken Skill: Maces +                // 7042 Forsaken Skill: Staves +                // 7043 Forsaken Skill: Bows +                // 7044 Forsaken Skill: Guns +                // 7045 Forsaken Skill: 2H Axes +                // 7046 Forsaken Skill: 2H Maces +                // 7047 Forsaken Skill: 2H Swords +                // 7048 Forsaken Skill: Defense +                // 7049 Forsaken Skill: Fire +                // 7050 Forsaken Skill: Frost +                // 7051 Forsaken Skill: Holy +                // 7053 Forsaken Skill: Shadow +                return;              } -            return; -        }  //        // Panda  //        case 19230: break; -//        // Master of Subtlety -//        case 31666: break;  //        // Gossip NPC Periodic - Talk  //        case 33208: break;  //        // Gossip NPC Periodic - Despawn  //        case 33209: break; -//        // Force of Nature -//        case 33831: break; -        // Aspect of the Viper -        case 34074: -        { -            if (m_target->GetTypeId() != TYPEID_PLAYER) -                return; -            // Should be manauser -            if (m_target->getPowerType()!=POWER_MANA) -                return; -            Unit *caster = GetCaster(); -            if (!caster) +  +            // TODO: now its not periodic dummy - need move out from here +            // Aspect of the Viper +            case 34074: +            { +                if (m_target->GetTypeId() != TYPEID_PLAYER) +                    return; +                // Should be manauser +                if (m_target->getPowerType()!=POWER_MANA) +                    return; +                if (!caster) +                    return; +                // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell) +                int mana = m_target->GetPower(POWER_MANA); +                int max_mana = m_target->GetMaxPower(POWER_MANA); +                int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target); +                float regen_pct = 1.20f - 1.1f * mana / max_mana; +                if      (regen_pct > 1.0f) regen_pct = 1.0f; +                else if (regen_pct < 0.2f) regen_pct = 0.2f; +                m_modifier.m_amount = int32 (base_regen * regen_pct); +                ((Player*)m_target)->UpdateManaRegen();                  return; -            // Regen amount is max (100% from spell) on 21% or less mana and min on 92.5% or greater mana (20% from spell) -            int mana = m_target->GetPower(POWER_MANA); -            int max_mana = m_target->GetMaxPower(POWER_MANA); -            int32 base_regen = caster->CalculateSpellDamage(m_spellProto, m_effIndex, m_currentBasePoints, m_target); -            float regen_pct = 1.20f - 1.1f * mana / max_mana; -            if      (regen_pct > 1.0f) regen_pct = 1.0f; -            else if (regen_pct < 0.2f) regen_pct = 0.2f; -            m_modifier.m_amount = int32 (base_regen * regen_pct); -            ((Player*)m_target)->UpdateManaRegen(); -            return; -        } +            }  //        // Steal Weapon  //        case 36207: break;  //        // Simon Game START timer, (DND)  //        case 39993: break; -//        // Harpooner's Mark -//        case 40084: break;  //        // Knockdown Fel Cannon: break; The Aggro Burst  //        case 40119: break;  //        // Old Mount Spell @@ -6012,6 +6213,8 @@ void Aura::PeriodicDummyTick()  //        case 40846: break;  //        // Copy Weapon  //        case 41054: break; +//        // Dementia +//        case 41404: break;  //        // Ethereal Ring Visual, Lightning Aura  //        case 41477: break;  //        // Ethereal Ring Visual, Lightning Aura (Fork) @@ -6060,6 +6263,8 @@ void Aura::PeriodicDummyTick()  //        case 43310: break;  //        // Headless Horseman - Maniacal Laugh, Maniacal, Delayed 17  //        case 43884: break; +//        // Wretched! +//        case 43963: break;  //        // Headless Horseman - Maniacal Laugh, Maniacal, other, Delayed 17  //        case 44000: break;  //        // Energy Feedback @@ -6126,14 +6331,179 @@ void Aura::PeriodicDummyTick()  //        case 47407: break;  //        // Mole Machine Port Schedule  //        case 47489: break; +//        case 47941: break; // Crystal Spike +//        case 48200: break; // Healer Aura +//        case 48630: break; // Summon Gauntlet Mobs Periodic +//        case 49313: break; // Proximity Mine Area Aura  //        // Mole Machine Portal Schedule  //        case 49466: break; -//        // Drink Coffee -//        case 49472: break; +//        case 49555: break; // Corpse Explode +//        case 49592: break; // Temporal Rift +//        case 49957: break; // Cutting Laser +//        case 50085: break; // Slow Fall  //        // Listening to Music  //        case 50493: break;  //        // Love Rocket Barrage  //        case 50530: break; +// Exist more after, need add later +            default: +                break; +        } +        break; +        case SPELLFAMILY_MAGE: +        { +            // Mirror Image +//            if (spell->Id == 55342) +//                return; +            break; +        } +        case SPELLFAMILY_WARRIOR: +        { +            // Armored to the Teeth +            if (spell->SpellIconID == 3516) +            { +                // Increases your attack power by $s1 for every $s2 armor value you have. +                // Calculate AP bonus (from 1 efect of this spell) +                int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target); +                m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this); +                return; +            } +            break; +        } +        case SPELLFAMILY_DRUID: +        { +            switch (spell->Id) +            { +                // Frenzied Regeneration +                case 22842: +                { +                    // Converts up to 10 rage per second into health for $d.  Each point of rage is converted into ${$m2/10}.1% of max health. +                    // Should be manauser +                    if (m_target->getPowerType()!=POWER_RAGE) +                        return; +                    uint32 rage = m_target->GetPower(POWER_RAGE); +                    // Nothing todo +                    if (rage == 0) +                        return; +                    int32 mod = (rage < 100) ? rage : 100; +                    int32 points = m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target); +                    int32 regen = m_target->GetMaxHealth() * (mod * points / 10) / 1000; +                    m_target->CastCustomSpell(m_target, 22845, ®en, 0, 0, true, 0, this); +                    m_target->SetPower(POWER_RAGE, rage-mod); +                    return; +                } +                // Force of Nature +                case 33831: +                    return; +                default: +                    break; +            } +            break; +        } +        case SPELLFAMILY_ROGUE: +        { +//            switch (spell->Id) +//            { +                // Master of Subtlety +//                case 31666: break; +                // Killing Spree +//                case 51690: break; +                // Overkill +//                case 58428: break; +//                default: +//                    break; +//            } +            break; +        } +        case SPELLFAMILY_HUNTER: +        { +            // Explosive Shot +            if (spell->SpellFamilyFlags & 0x8000000000000000LL) +            { +                if (!caster) +                    return; +                // Skip 0 tick +                if (m_duration < m_modifier.periodictime) +                    return; +                int32 damage = caster->CalculateSpellDamage(spell, GetEffIndex(), GetBasePoints(), m_target); +                damage+=caster->GetTotalAttackPowerValue(RANGED_ATTACK) * 8 / 100; +                damage/=4; +                caster->CastCustomSpell(m_target, 56298, &damage, 0, 0, true, 0, this); +                return; +            } +            switch (spell->Id) +            { +                // Harpooner's Mark +                // case 40084: +                //    return; +                // Feeding Frenzy Rank 1 +                case 53511: +                    if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 ) +                        m_target->CastSpell(m_target, 60096, true, 0, this); +                    return; +                // Feeding Frenzy Rank 2 +                case 53512: +                    if ( m_target->GetHealth() * 100 < m_target->GetMaxHealth() * 35 ) +                        m_target->CastSpell(m_target, 60097, true, 0, this); +                    return; +                default: +                    break; +            } +            break; +        } +        case SPELLFAMILY_SHAMAN: +        { +            // Astral Shift +//            if (spell->Id == 52179) +//                return; +            break; +        } +        case SPELLFAMILY_DEATHKNIGHT: +        { +            // Death and Decay +//            if (spell->SpellFamilyFlags & 0x0000000000000020LL) +//                return; +            // Raise Dead +//            if (spell->SpellFamilyFlags & 0x0000000000001000LL) +//                return; +            // Chains of Ice +            if (spell->SpellFamilyFlags & 0x0000400000000000LL) +            { +                // Get 0 effect aura +                Aura *slow = m_target->GetAura(GetId(), 0); +                if (slow) +                { +                    slow->ApplyModifier(false, true); +                    Modifier *mod = slow->GetModifier(); +                    mod->m_amount+= m_modifier.m_amount; +                    if (mod->m_amount > 0) mod->m_amount = 0; +                    slow->ApplyModifier(true, true); +                } +                return; +            } +            // Summon Gargoyle +//            if (spell->SpellFamilyFlags & 0x0000008000000000LL) +//                return; +            // Death Rune Mastery +//            if (spell->SpellFamilyFlags & 0x0000000000004000LL) +//                return; +            // Bladed Armor +            if (spell->SpellIconID == 2653) +            { +                // Increases your attack power by $s1 for every $s2 armor value you have. +                // Calculate AP bonus (from 1 efect of this spell) +                int32 apBonus = m_modifier.m_amount * m_target->GetArmor() / m_target->CalculateSpellDamage(spell, 1, spell->EffectBasePoints[1], m_target); +                m_target->CastCustomSpell(m_target, 61217, &apBonus, &apBonus, 0, true, 0, this); +                return; +            } +            // Reaping +//            if (spell->SpellIconID == 22) +//                return; +            // Blood of the North +//            if (spell->SpellIconID == 30412) +//                return; +            break; +        }          default:              break;      } @@ -6199,14 +6569,61 @@ void Aura::HandleArenaPreparation(bool apply, bool Real)          m_target->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PREPARATION);  } -void Aura::HandleModAttackerSpellHitChance(bool apply, bool Real) +void Aura::HandleAuraControlVehicle(bool apply, bool Real)  {      if(!Real)          return; +    if(m_target->GetTypeId() != TYPEID_PLAYER) +        return; + +    if(Pet *pet = m_target->GetPet()) +        pet->Remove(PET_SAVE_AS_CURRENT); + +    WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); +    ((Player*)m_target)->GetSession()->SendPacket(&data); +} + +void Aura::HandleAuraConvertRune(bool apply, bool Real) +{ +    if(!Real) +        return; + +    if(m_target->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player *plr = (Player*)m_target; + +    if(plr->getClass() != CLASS_DEATH_KNIGHT) +        return; + +    // how to determine what rune need to be converted? +    for(uint32 i = 0; i < MAX_RUNES; ++i) +    { +        if(apply) +        { +            if(!plr->GetRuneCooldown(i)) +            { +                plr->ConvertRune(i, GetSpellProto()->EffectMiscValueB[m_effIndex]); +                break; +            } +        } +        else +        { +            if(plr->GetCurrentRune(i) == GetSpellProto()->EffectMiscValueB[m_effIndex]) +            { +                plr->ConvertRune(i, plr->GetBaseRune(i)); +                break; +            } +        } +    } +} + +void Aura::HandleModAttackerSpellHitChance(bool apply, bool Real) +{      if(GetId() != 31224)          return;      //cloak of shadows : flare      m_target->ApplySpellImmune(31224, IMMUNITY_ID, 1543, apply); -}
\ No newline at end of file +} diff --git a/src/game/SpellAuras.h b/src/game/SpellAuras.h index 1e9a8bd8c63..99c170d1139 100644 --- a/src/game/SpellAuras.h +++ b/src/game/SpellAuras.h @@ -100,6 +100,7 @@ class TRINITY_DLL_SPEC Aura          void HandleAuraFeatherFall(bool Apply, bool Real);          void HandleAuraHover(bool Apply, bool Real);          void HandleAddModifier(bool Apply, bool Real); +        void HandleAddTargetTrigger(bool Apply, bool Real);          void HandleAuraModStun(bool Apply, bool Real);          void HandleModDamageDone(bool Apply, bool Real);          void HandleAuraUntrackable(bool Apply, bool Real); @@ -184,10 +185,12 @@ class TRINITY_DLL_SPEC Aura          void HandleAuraGhost(bool Apply, bool Real);          void HandleAuraAllowFlight(bool Apply, bool Real);          void HandleModRating(bool apply, bool Real); +        void HandleModRatingFromStat(bool apply, bool Real);          void HandleModTargetResistance(bool apply, bool Real);          void HandleAuraModAttackPowerPercent(bool apply, bool Real);          void HandleAuraModRangedAttackPowerPercent(bool apply, bool Real);          void HandleAuraModRangedAttackPowerOfStatPercent(bool apply, bool Real); +        void HandleAuraModAttackPowerOfStatPercent(bool apply, bool Real);          void HandleSpiritOfRedemption(bool apply, bool Real);          void HandleModManaRegen(bool apply, bool Real);          void HandleComprehendLanguage(bool apply, bool Real); @@ -197,6 +200,7 @@ class TRINITY_DLL_SPEC Aura          void HandleModSpellDamagePercentFromStat(bool apply, bool Real);          void HandleModSpellHealingPercentFromStat(bool apply, bool Real);          void HandleAuraModDispelResist(bool apply, bool Real); +        void HandleAuraControlVehicle(bool apply, bool Real);          void HandleModSpellDamagePercentFromAttackPower(bool apply, bool Real);          void HandleModSpellHealingPercentFromAttackPower(bool apply, bool Real);          void HandleAuraModPacifyAndSilence(bool Apply, bool Real); @@ -209,6 +213,9 @@ class TRINITY_DLL_SPEC Aura          void HandlePreventFleeing(bool apply, bool Real);          void HandleManaShield(bool apply, bool Real);          void HandleArenaPreparation(bool apply, bool Real); +        void HandleAuraConvertRune(bool apply, bool Real); +        void HandleAuraIncreaseBaseHealthPercent(bool Apply, bool Real); +        void HandleNoReagentUseAura(bool Apply, bool Real);          void HandleModAttackerSpellHitChance(bool apply, bool Real);          virtual ~Aura(); @@ -231,6 +238,8 @@ class TRINITY_DLL_SPEC Aura          int32 GetAuraDuration() const { return m_duration; }          void SetAuraDuration(int32 duration) { m_duration = duration; }          time_t GetAuraApplyTime() { return m_applyTime; } +        SpellModifier *getAuraSpellMod() {return m_spellmod; } +          void UpdateAuraDuration();          void SendAuraDurationForCaster(Player* caster);          void UpdateSlotCounterAndDuration(); @@ -250,13 +259,19 @@ class TRINITY_DLL_SPEC Aura          uint8 GetAuraSlot() const { return m_auraSlot; }          void SetAuraSlot(uint8 slot) { m_auraSlot = slot; } +        uint8 GetAuraFlags() const { return m_auraFlags; } +        void SetAuraFlags(uint8 flags) { m_auraFlags = flags; } +        uint8 GetAuraLevel() const { return m_auraLevel; } +        void SetAuraLevel(uint8 level) { m_auraLevel = level; } +        uint8 GetAuraCharges() const { return m_procCharges; } +        void SetAuraCharges(uint8 charges) { m_procCharges = charges; } +        void SetAura(bool remove) { m_target->SetVisibleAura(m_auraSlot, remove ? 0 : GetId()); } +        void SendAuraUpdate(bool remove);          void UpdateAuraCharges()          { -            uint8 slot = GetAuraSlot(); -              // only aura in slot with charges and without stack limitation -            if (slot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0) -                SetAuraApplication(slot, m_procCharges - 1); +            if (m_auraSlot < MAX_AURAS && m_procCharges >= 1 && GetSpellProto()->StackAmount==0) +                SendAuraUpdate(false);          }          bool IsPositive() { return m_positive; } @@ -300,6 +315,9 @@ class TRINITY_DLL_SPEC Aura          void PeriodicTick();          void PeriodicDummyTick(); +        uint32 const *getAuraSpellClassMask() const { return  m_spellProto->EffectSpellClassMaskA + m_effIndex * 3; } +        bool isAffectedOnSpell(SpellEntry const *spell) const; +          int32 GetStackAmount() {return m_stackAmount;}          void SetStackAmount(int32 amount) {m_stackAmount=amount;}      protected: @@ -321,6 +339,8 @@ class TRINITY_DLL_SPEC Aura          AuraRemoveMode m_removeMode;          uint8 m_auraSlot; +        uint8 m_auraFlags; +        uint8 m_auraLevel;          bool m_positive:1;          bool m_permanent:1; @@ -341,10 +361,6 @@ class TRINITY_DLL_SPEC Aura          int32 m_stackAmount;      private:          void CleanupTriggeredSpells(); -        void SetAura(uint32 slot, bool remove) { m_target->SetUInt32Value(UNIT_FIELD_AURA + slot, remove ? 0 : GetId()); } -        void SetAuraFlag(uint32 slot, bool add); -        void SetAuraLevel(uint32 slot, uint32 level); -        void SetAuraApplication(uint32 slot, int8 count);  };  class TRINITY_DLL_SPEC AreaAura : public Aura diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 85984eeaa3d..20924d1ef56 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -128,16 +128,16 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectPowerBurn,                                // 62 SPELL_EFFECT_POWER_BURN      &Spell::EffectThreat,                                   // 63 SPELL_EFFECT_THREAT      &Spell::EffectTriggerSpell,                             // 64 SPELL_EFFECT_TRIGGER_SPELL -    &Spell::EffectUnused,                                   // 65 SPELL_EFFECT_HEALTH_FUNNEL            unused -    &Spell::EffectUnused,                                   // 66 SPELL_EFFECT_POWER_FUNNEL             unused +    &Spell::EffectApplyAreaAura,                            // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID +    &Spell::EffectUnused,                                   // 66 SPELL_EFFECT_CREATE_MANA_GEM          (possibly recharge it, misc - is item ID)      &Spell::EffectHealMaxHealth,                            // 67 SPELL_EFFECT_HEAL_MAX_HEALTH      &Spell::EffectInterruptCast,                            // 68 SPELL_EFFECT_INTERRUPT_CAST      &Spell::EffectDistract,                                 // 69 SPELL_EFFECT_DISTRACT      &Spell::EffectPull,                                     // 70 SPELL_EFFECT_PULL                     one spell: Distract Move      &Spell::EffectPickPocket,                               // 71 SPELL_EFFECT_PICKPOCKET      &Spell::EffectAddFarsight,                              // 72 SPELL_EFFECT_ADD_FARSIGHT -    &Spell::EffectSummonPossessed,                          // 73 SPELL_EFFECT_SUMMON_POSSESSED -    &Spell::EffectSummonTotem,                              // 74 SPELL_EFFECT_SUMMON_TOTEM +    &Spell::EffectUnused,                                   // 73 SPELL_EFFECT_UNTRAIN_TALENTS +    &Spell::EffectApplyGlyph,                               // 74 SPELL_EFFECT_APPLY_GLYPH      &Spell::EffectHealMechanical,                           // 75 SPELL_EFFECT_HEAL_MECHANICAL          one spell: Mechanical Patch Kit      &Spell::EffectSummonObjectWild,                         // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD      &Spell::EffectScriptEffect,                             // 77 SPELL_EFFECT_SCRIPT_EFFECT @@ -150,10 +150,10 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectStuck,                                    // 84 SPELL_EFFECT_STUCK      &Spell::EffectSummonPlayer,                             // 85 SPELL_EFFECT_SUMMON_PLAYER      &Spell::EffectActivateObject,                           // 86 SPELL_EFFECT_ACTIVATE_OBJECT -    &Spell::EffectSummonTotem,                              // 87 SPELL_EFFECT_SUMMON_TOTEM_SLOT1 -    &Spell::EffectSummonTotem,                              // 88 SPELL_EFFECT_SUMMON_TOTEM_SLOT2 -    &Spell::EffectSummonTotem,                              // 89 SPELL_EFFECT_SUMMON_TOTEM_SLOT3 -    &Spell::EffectSummonTotem,                              // 90 SPELL_EFFECT_SUMMON_TOTEM_SLOT4 +    &Spell::EffectUnused,                                   // 87 SPELL_EFFECT_WMO_DAMAGE +    &Spell::EffectUnused,                                   // 88 SPELL_EFFECT_WMO_REPAIR  +    &Spell::EffectUnused,                                   // 89 SPELL_EFFECT_WMO_CHANGE +    &Spell::EffectUnused,                                   // 90 SPELL_EFFECT_KILL_CREDIT      &Spell::EffectUnused,                                   // 91 SPELL_EFFECT_THREAT_ALL               one spell: zzOLDBrainwash      &Spell::EffectEnchantHeldItem,                          // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM      &Spell::EffectUnused,                                   // 93 SPELL_EFFECT_SUMMON_PHANTASM @@ -195,21 +195,21 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectApplyAreaAura,                            //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY      &Spell::EffectRedirectThreat,                           //130 SPELL_EFFECT_REDIRECT_THREAT      &Spell::EffectUnused,                                   //131 SPELL_EFFECT_131                      used in some test spells -    &Spell::EffectNULL,                                     //132 SPELL_EFFECT_PLAY_MUSIC               sound id in misc value +    &Spell::EffectNULL,                                     //132 SPELL_EFFECT_PLAY_MUSIC               sound id in misc value (SoundEntries.dbc)      &Spell::EffectUnlearnSpecialization,                    //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION   unlearn profession specialization      &Spell::EffectKillCredit,                               //134 SPELL_EFFECT_KILL_CREDIT              misc value is creature entry      &Spell::EffectNULL,                                     //135 SPELL_EFFECT_CALL_PET      &Spell::EffectHealPct,                                  //136 SPELL_EFFECT_HEAL_PCT      &Spell::EffectEnergisePct,                              //137 SPELL_EFFECT_ENERGIZE_PCT      &Spell::EffectNULL,                                     //138 SPELL_EFFECT_138                      Leap -    &Spell::EffectUnused,                                   //139 SPELL_EFFECT_139                      unused +    &Spell::EffectUnused,                                   //139 SPELL_EFFECT_CLEAR_QUEST              (misc - is quest ID)      &Spell::EffectForceCast,                                //140 SPELL_EFFECT_FORCE_CAST      &Spell::EffectNULL,                                     //141 SPELL_EFFECT_141                      damage and reduce speed?      &Spell::EffectTriggerSpellWithValue,                    //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE      &Spell::EffectApplyAreaAura,                            //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER      &Spell::EffectNULL,                                     //144 SPELL_EFFECT_144                      Spectral Blast      &Spell::EffectNULL,                                     //145 SPELL_EFFECT_145                      Black Hole Effect -    &Spell::EffectUnused,                                   //146 SPELL_EFFECT_146                      unused +    &Spell::EffectActivateRune,                             //146 SPELL_EFFECT_ACTIVATE_RUNE      &Spell::EffectQuestFail,                                //147 SPELL_EFFECT_QUEST_FAIL               quest fail      &Spell::EffectUnused,                                   //148 SPELL_EFFECT_148                      unused      &Spell::EffectNULL,                                     //149 SPELL_EFFECT_149                      swoop @@ -217,6 +217,12 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=      &Spell::EffectTriggerRitualOfSummoning,                 //151 SPELL_EFFECT_TRIGGER_SPELL_2      &Spell::EffectNULL,                                     //152 SPELL_EFFECT_152                      summon Refer-a-Friend      &Spell::EffectNULL,                                     //153 SPELL_EFFECT_CREATE_PET               misc value is creature entry +    &Spell::EffectNULL,                                     //154 unused +    &Spell::EffectTitanGrip,                                //155 SPELL_EFFECT_TITAN_GRIP Allows you to equip two-handed axes, maces and swords in one hand, but you attack $49152s1% slower than normal. +    &Spell::EffectNULL,                                     //156 Add Socket +    &Spell::EffectNULL,                                     //157 create/learn random item/spell for profession +    &Spell::EffectMilling,                                  //158 milling +    &Spell::EffectNULL                                      //159 allow rename pet once again  };  void Spell::EffectNULL(uint32 /*i*/) @@ -339,6 +345,13 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                              damage = 200;                          break;                      } +                    // Intercept (warrior spell trigger) +                    case 20253: +                    case 61491: +                    { +                        damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.12f); +                        break; +                    }                      // arcane charge. must only affect demons (also undead?)                      case 45072:                      { @@ -388,6 +401,12 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                      damage = uint32(damage * m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 100);                      m_caster->ModifyAuraState(AURA_STATE_WARRIOR_VICTORY_RUSH, false);                  } +                // Revenge ${$m1+$AP*0.207} to ${$M1+$AP*0.207} +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000400LL) +                    damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.207f); +                // Heroic Throw ${$m1+$AP*.50} +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000100000000LL) +                    damage+= uint32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * 0.5f);                  break;              }              case SPELLFAMILY_WARLOCK: @@ -397,7 +416,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                  {                      // Incinerate does more dmg (dmg*0.25) if the target is Immolated.                      if(unitTarget->HasAuraState(AURA_STATE_IMMOLATE)) -                        damage += int32(damage*0.25); +                        damage += int32(damage*0.25f);                  }                  // Conflagrate - consumes immolate @@ -420,11 +439,13 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)              case SPELLFAMILY_DRUID:              {                  // Ferocious Bite -                if((m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual==6587) +                if(m_caster->GetTypeId()==TYPEID_PLAYER && (m_spellInfo->SpellFamilyFlags & 0x000800000) && m_spellInfo->SpellVisual[0]==6587)                  { -                    // converts each extra point of energy into ($f1+$AP/630) additional damage -                    float multiple = m_caster->GetTotalAttackPowerValue(BASE_ATTACK) / 630 + m_spellInfo->DmgMultiplier[effect_idx]; +                    // converts each extra point of energy into ($f1+$AP/410) additional damage +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    float multiple = ap / 410 + m_spellInfo->DmgMultiplier[effect_idx];                      damage += int32(m_caster->GetPower(POWER_ENERGY) * multiple); +                    damage += int32(((Player*)m_caster)->GetComboPoints() * ap * 7 / 100);                      m_caster->SetPower(POWER_ENERGY,0);                  }                  // Rake @@ -500,7 +521,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                          {                              // Deadly poison (only attacker applied)                              if( (*itr)->GetSpellProto()->SpellFamilyName==SPELLFAMILY_ROGUE && ((*itr)->GetSpellProto()->SpellFamilyFlags & 0x10000) && -                                (*itr)->GetSpellProto()->SpellVisual==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() ) +                                (*itr)->GetSpellProto()->SpellVisual[0]==5100 && (*itr)->GetCasterGUID()==m_caster->GetGUID() )                              {                                  --combo;                                  ++doses; @@ -526,26 +547,47 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                  {                      if(uint32 combo = ((Player*)m_caster)->GetComboPoints())                      { -                        damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK) * combo * 0.03f); +                        float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                        damage += irand(int32(ap * combo * 0.03f), int32(ap * combo * 0.07f));                          // Eviscerate and Envenom Bonus Damage (item set effect)                          if(m_caster->GetDummyAura(37169))                              damage += combo*40;                      }                  } +                // Gouge +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000000000008LL) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.02f); +                } +                // Instant Poison +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000000002000LL) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.10f); +                } +                // Wound Poison +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000010000000LL) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.04f); +                }                  break;              }              case SPELLFAMILY_HUNTER:              {                  // Mongoose Bite -                if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual==342) +                if((m_spellInfo->SpellFamilyFlags & 0x000000002) && m_spellInfo->SpellVisual[0]==342) +                { +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f); +                } +                // Counterattack +                else if(m_spellInfo->SpellFamilyFlags & 0x0008000000000000LL)                  { -                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2); +                    damage += int32(m_caster->GetTotalAttackPowerValue(BASE_ATTACK)*0.2f);                  }                  // Arcane Shot                  else if((m_spellInfo->SpellFamilyFlags & 0x00000800) && m_spellInfo->maxLevel > 0)                  { -                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15); +                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.15f);                  }                  // Steady Shot                  else if(m_spellInfo->SpellFamilyFlags & 0x100000000LL) @@ -570,16 +612,16 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                      if(found)                          damage += m_spellInfo->EffectBasePoints[1];                  } -                //Explosive Trap Effect +                // Explosive Trap Effect                  else if(m_spellInfo->SpellFamilyFlags & 0x00000004)                  { -                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1); +                    damage += int32(m_caster->GetTotalAttackPowerValue(RANGED_ATTACK)*0.1f);                  }                  break;              }              case SPELLFAMILY_PALADIN:              { -                //Judgement of Vengeance +                // Judgement of Vengeance                  if((m_spellInfo->SpellFamilyFlags & 0x800000000LL) && m_spellInfo->SpellIconID==2292)                  {                      uint32 stacks = 0; @@ -593,6 +635,38 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx)                      else                          damage *= stacks;                  } +                // Avenger's Shield ($m1+0.07*$SPH+0.07*$AP) +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000000004000LL) +                { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + +                                 m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); +                    damage += int32(ap * 0.07f) + int32(holy * 7 / 100); +                } +                // Exorcism ($m1+0.15*$SPH+0.15*$AP) +                else if(m_spellInfo->SpellFamilyFlags & 0x0000000200000000LL) +                { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + +                                 m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); +                    damage += int32(ap * 0.15f) + int32(holy * 15 / 100); +                } +                // Hammer of Wrath ($m1+0.15*$SPH+0.15*$AP) +                else if(m_spellInfo->SpellFamilyFlags & 0x0000008000000000LL) +                { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + +                                 m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); +                    damage += int32(ap * 0.15f) + int32(holy * 15 / 100); +                } +                // Holy Wrath ($m1+0.07*$SPH+0.07*$AP) +                else if(m_spellInfo->SpellFamilyFlags & 0x0020000000000000LL) +                { +                    float ap = m_caster->GetTotalAttackPowerValue(BASE_ATTACK); +                    int32 holy = m_caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellInfo)) + +                                 m_caster->SpellBaseDamageBonusForVictim(GetSpellSchoolMask(m_spellInfo), unitTarget); +                    damage += int32(ap * 0.15f) + int32(holy * 15 / 100); +                }                  break;              }          } @@ -1192,6 +1266,12 @@ void Spell::EffectDummy(uint32 i)                      m_caster->CastSpell(m_caster, 30452, true, NULL);                      return;                  } +                case 53341: +                case 53343: +                { +                    m_caster->CastSpell(m_caster,54586,true); +                    return; +                 }              }              //All IconID Check in there @@ -1265,7 +1345,7 @@ void Spell::EffectDummy(uint32 i)              break;          case SPELLFAMILY_WARRIOR:              // Charge -            if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual == 867) +            if(m_spellInfo->SpellFamilyFlags & 0x1 && m_spellInfo->SpellVisual[0] == 867)              {                  int32 chargeBasePoints0 = damage;                  m_caster->CastCustomSpell(m_caster,34846,&chargeBasePoints0,NULL,NULL,true); @@ -1529,10 +1609,8 @@ void Spell::EffectDummy(uint32 i)                          mod->value = -50;                          mod->type = SPELLMOD_PCT;                          mod->spellId = m_spellInfo->Id; -                        mod->effectId = i; -                        mod->lastAffected = NULL;                          mod->mask = 0x0000020000000000LL; -                        mod->charges = 0; +                        mod->mask2= 0LL;                          ((Player*)m_caster)->AddSpellMod(mod, true);                          m_caster->CastSpell(unitTarget,spell_proto,true,NULL); @@ -2897,10 +2975,10 @@ void Spell::EffectOpenLock(uint32 /*i*/)      }      // check key -    for(int i = 0; i < 5; ++i) +    for(int i = 0; i < 8; ++i)      { -        // type==1 This means lockInfo->key[i] is an item -        if(lockInfo->keytype[i]==LOCK_KEY_ITEM && lockInfo->key[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->key[i]) +        // Type==1 This means lockInfo->Index[i] is an item +        if(lockInfo->Type[i]==LOCK_KEY_ITEM && lockInfo->Index[i] && m_CastItem && m_CastItem->GetEntry()==lockInfo->Index[i])          {              SendLoot(guid, loottype);              return; @@ -2918,9 +2996,9 @@ void Spell::EffectOpenLock(uint32 /*i*/)      // skill bonus provided by casting spell (mostly item spells)      uint32 spellSkillBonus = uint32(damage/*m_currentBasePoints[0]+1*/); -    uint32 reqSkillValue = lockInfo->requiredminingskill; +    uint32 reqSkillValue = lockInfo->Skill[0]; -    if(lockInfo->requiredlockskill)                         // required pick lock skill applying +    if(lockInfo->Skill[1])                                  // required pick lock skill applying      {          if(SkillId != SKILL_LOCKPICKING)                    // wrong skill (cheating?)          { @@ -2928,7 +3006,7 @@ void Spell::EffectOpenLock(uint32 /*i*/)              return;          } -        reqSkillValue = lockInfo->requiredlockskill; +        reqSkillValue = lockInfo->Skill[1];      }      else if(SkillId == SKILL_LOCKPICKING)                   // apply picklock skill to wrong target      { @@ -3158,7 +3236,7 @@ void Spell::EffectSummon(uint32 i)      Pet* spawnCreature = new Pet(SUMMON_PET);      spawnCreature->setActive(m_caster->isActive()); -    if(spawnCreature->LoadPetFromDB(m_caster,pet_entry)) +    if(m_caster->GetTypeId()==TYPEID_PLAYER && spawnCreature->LoadPetFromDB((Player*)m_caster,pet_entry))      {          // set timer for unsummon          int32 duration = GetSpellDuration(m_spellInfo); @@ -3255,7 +3333,7 @@ void Spell::EffectLearnSpell(uint32 i)      Player *player = (Player*)unitTarget; -    uint32 spellToLearn = (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) ? damage : m_spellInfo->EffectTriggerSpell[i]; +    uint32 spellToLearn = ((m_spellInfo->Id==SPELL_ID_GENERIC_LEARN) || (m_spellInfo->Id==SPELL_ID_GENERIC_LEARN_PET)) ? damage : m_spellInfo->EffectTriggerSpell[i];      player->learnSpell(spellToLearn);      sLog.outDebug( "Spell: Player %u have learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow() ); @@ -3897,13 +3975,13 @@ void Spell::EffectEnchantItemTmp(uint32 i)      else if(m_spellInfo->SpellFamilyName==SPELLFAMILY_SHAMAN)          duration = 1800;                                    // 30 mins      // other cases with this SpellVisual already selected -    else if(m_spellInfo->SpellVisual==215) +    else if(m_spellInfo->SpellVisual[0]==215)          duration = 1800;                                    // 30 mins      // some fishing pole bonuses -    else if(m_spellInfo->SpellVisual==563) +    else if(m_spellInfo->SpellVisual[0]==563)          duration = 600;                                     // 10 mins      // shaman rockbiter enchantments -    else if(m_spellInfo->SpellVisual==0) +    else if(m_spellInfo->SpellVisual[0]==0)          duration = 1800;                                    // 30 mins      else if(m_spellInfo->Id==29702)          duration = 300;                                     // 5 mins @@ -3966,14 +4044,16 @@ void Spell::EffectTameCreature(uint32 /*i*/)      creatureTarget->RemoveCorpse();      creatureTarget->SetHealth(0);                       // just for nice GM-mode view +    uint32 level = (creatureTarget->getLevel() < (m_caster->getLevel() - 5)) ? (m_caster->getLevel() - 5) : creatureTarget->getLevel(); +      // prepare visual effect for levelup -    pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()-1); +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level - 1);      // add to world      pet->GetMap()->Add((Creature*)pet);      // visual effect for levelup -    pet->SetUInt32Value(UNIT_FIELD_LEVEL,creatureTarget->getLevel()); +    pet->SetUInt32Value(UNIT_FIELD_LEVEL, level);      // caster have pet now      m_caster->SetPet(pet); @@ -4026,7 +4106,7 @@ void Spell::EffectSummonPet(uint32 i)      NewSummon->setActive(m_caster->isActive());      // petentry==0 for hunter "call pet" (current pet summoned if any) -    if(NewSummon->LoadPetFromDB(m_caster,petentry)) +    if(m_caster->GetTypeId() == TYPEID_PLAYER && NewSummon->LoadPetFromDB((Player*)m_caster,petentry))      {          if(NewSummon->getPetType()==SUMMON_PET)          { @@ -4111,7 +4191,8 @@ void Spell::EffectSummonPet(uint32 i)      // this enables pet details window (Shift+P)      // this enables popup window (pet dismiss, cancel), hunter pet additional flags set later -    NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); +    if(m_caster->GetTypeId() == TYPEID_PLAYER) +        NewSummon->SetUInt32Value(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);      NewSummon->InitStatsForLevel(petlevel);      NewSummon->InitPetCreateSpells(); @@ -4172,7 +4253,6 @@ void Spell::EffectLearnPetSpell(uint32 i)      if(!learn_spellproto)          return; -    pet->SetTP(pet->m_TrainingPoints - pet->GetTPForSpell(learn_spellproto->Id));      pet->learnSpell(learn_spellproto->Id);      pet->SavePetToDB(PET_SAVE_AS_CURRENT); @@ -4236,7 +4316,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)          case SPELLFAMILY_WARRIOR:          {              // Devastate bonus and sunder armor refresh -            if(m_spellInfo->SpellVisual == 671 && m_spellInfo->SpellIconID == 1508) +            if(m_spellInfo->SpellVisual[0] == 671 && m_spellInfo->SpellIconID == 1508)              {                  uint32 stack = 0; @@ -4249,7 +4329,7 @@ void Spell::SpellDamageWeaponDmg(uint32 i)                      {                          int32 duration = GetSpellDuration(proto);                          (*itr)->SetAuraDuration(duration); -                        (*itr)->UpdateAuraDuration(); +                        (*itr)->SendAuraUpdate(false);                          stack = (*itr)->GetStackAmount();                          break;                      } @@ -4961,9 +5041,69 @@ void Spell::EffectScriptEffect(uint32 effIndex)                  ((Player*)unitTarget)->ModifyMoney(50000000);              break;          } +        case 51770: +        { +            if(!unitTarget) +                return; + +            unitTarget->CastSpell(unitTarget,51771,false); +            break; +        }      } +    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_HUNTER ) +    { +        switch(m_spellInfo->Id) +        { +            // Chimera Shot +            case 53209: +            { +                uint32 spellId = 0; +                int32 basePoint = 0; +                Unit::AuraMap& Auras = unitTarget->GetAuras(); +                for(Unit::AuraMap::iterator i = Auras.begin(); i != Auras.end(); ++i) +                { +                    Aura *aura = (*i).second; +                    if (aura->GetCasterGUID() != m_caster->GetGUID()) +                        continue; +                    // Search only Serpent Sting, Viper Sting, Scorpid Sting auras +                    uint64 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; +                    if (!(familyFlag & 0x000000800000C000LL)) +                        continue; +                    // Refresh aura duration +                    aura->SetAuraDuration(aura->GetAuraMaxDuration()); +                    aura->SendAuraUpdate(false); -    if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN ) +                    // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. +                    if (familyFlag & 0x0000000000004000LL && aura->GetEffIndex() == 0) +                    { +                        spellId = 53353; // 53353 Chimera Shot - Serpent +                        basePoint = aura->GetModifier()->m_amount * 5 * 40 / 100; +                    } +                    // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. +                    if (familyFlag & 0x0000008000000000LL && aura->GetEffIndex() == 0) +                    { +                        spellId = 53358; // 53358 Chimera Shot - Viper +                        basePoint = aura->GetModifier()->m_amount * 4 * 60 / 100; +                    } +                    // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. +                    if (familyFlag & 0x0000000000008000LL) +                        spellId = 53359; // 53359 Chimera Shot - Scorpid +                    // ?? nothing say in spell desc (possibly need addition check) +                    //if (familyFlag & 0x0000010000000000LL || // dot +                    //    familyFlag & 0x0000100000000000LL)   // stun +                    //{ +                    //    spellId = 53366; // 53366 Chimera Shot - Wyvern +                    //} +                } +                if (spellId) +                    m_caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); +                return; +            } +            default: +                break; +        } +    } +    else if( m_spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN )      {          switch(m_spellInfo->SpellFamilyFlags)          { @@ -5086,6 +5226,7 @@ void Spell::EffectDuel(uint32 i)      // Players can only fight a duel with each other outside (=not inside dungeons and not in capital cities)      // Don't have to check the target's map since you cannot challenge someone across maps      if(caster->GetMap()->Instanceable()) +    //if( mapid != 0 && mapid != 1 && mapid != 530 && mapid != 571 && mapid != 609)      {          SendCastResult(SPELL_FAILED_NO_DUELING);            // Dueling isn't allowed here          return; @@ -5224,6 +5365,43 @@ void Spell::EffectActivateObject(uint32 effect_idx)      sWorld.ScriptCommandStart(activateCommand, delay_secs, m_caster, gameObjTarget);  } +void Spell::EffectApplyGlyph(uint32 i) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player *player = (Player*)m_caster; + +    // remove old glyph +    if(uint32 oldglyph = player->GetGlyph(m_glyphIndex)) +    { +        if(GlyphPropertiesEntry const *old_gp = sGlyphPropertiesStore.LookupEntry(oldglyph)) +        { +            player->RemoveAurasDueToSpell(old_gp->SpellId); +            player->SetGlyph(m_glyphIndex, 0); +        } +    } + +    // apply new one +    if(uint32 glyph = m_spellInfo->EffectMiscValue[i]) +    { +        if(GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(glyph)) +        { +            if(GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(player->GetGlyphSlot(m_glyphIndex))) +            { +                if(gp->TypeFlags != gs->TypeFlags) +                { +                    SendCastResult(SPELL_FAILED_INVALID_GLYPH); +                    return;                                 // glyph slot missmatch +                } +            } + +            player->CastSpell(m_caster, gp->SpellId, true); +            player->SetGlyph(m_glyphIndex, glyph); +        } +    } +} +  void Spell::EffectSummonTotem(uint32 i)  {      uint8 slot = 0; @@ -5292,7 +5470,9 @@ void Spell::EffectSummonTotem(uint32 i)      }      pTotem->SetUInt32Value(UNIT_CREATED_BY_SPELL,m_spellInfo->Id); -    pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE); + +    if(m_caster->GetTypeId() == TYPEID_PLAYER) +        pTotem->SetFlag(UNIT_FIELD_FLAGS,UNIT_FLAG_PVP_ATTACKABLE);      pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_MOD_FEAR,true);      pTotem->ApplySpellImmune(m_spellInfo->Id,IMMUNITY_STATE,SPELL_AURA_TRANSFORM,true); @@ -5547,18 +5727,14 @@ void Spell::EffectAddExtraAttacks(uint32 /*i*/)  void Spell::EffectParry(uint32 /*i*/)  { -    if (unitTarget->GetTypeId() == TYPEID_PLAYER) -    { +    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER)          ((Player*)unitTarget)->SetCanParry(true); -    }  }  void Spell::EffectBlock(uint32 /*i*/)  { -    if (unitTarget->GetTypeId() != TYPEID_PLAYER) -        return; - -    ((Player*)unitTarget)->SetCanBlock(true); +    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) +        ((Player*)unitTarget)->SetCanBlock(true);  }  void Spell::EffectMomentMove(uint32 i) @@ -5866,17 +6042,20 @@ void Spell::EffectSendTaxi(uint32 i)      uint32 mountid = 0;      switch(m_spellInfo->Id)      { -        case 31606:       //Stormcrow Amulet +        case 31606:                                         //Stormcrow Amulet              mountid = 17447;              break; -        case 45071:      //Quest - Sunwell Daily - Dead Scar Bombing Run -        case 45113:      //Quest - Sunwell Daily - Ship Bombing Run -        case 45353:      //Quest - Sunwell Daily - Ship Bombing Run Return +        case 45071:                                         //Quest - Sunwell Daily - Dead Scar Bombing Run +        case 45113:                                         //Quest - Sunwell Daily - Ship Bombing Run +        case 45353:                                         //Quest - Sunwell Daily - Ship Bombing Run Return              mountid = 22840;              break; -        case 34905:      //Stealth Flight +        case 34905:                                         //Stealth Flight              mountid = 6851;              break; +        case 53335:                                         //Stormwind Harbor Flight - Peaceful +            mountid = 6852; +            break;      }      ((Player*)unitTarget)->ActivateTaxiPathTo(nodes,mountid); @@ -6108,9 +6287,9 @@ void Spell::EffectTransmitted(uint32 effIndex)          {              m_caster->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT,pGameObj->GetGUID());                                                              // Orientation3 -            pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 2, 0.88431775569915771 ); +            pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 2, 0.88431775569915771 );                                                              // Orientation4 -            pGameObj->SetFloatValue(GAMEOBJECT_ROTATION + 3, -0.4668855369091033 ); +            pGameObj->SetFloatValue(GAMEOBJECT_PARENTROTATION + 3, -0.4668855369091033 );              m_caster->AddGameObject(pGameObj);              // will removed at spell cancel              // end time of range when possible catch fish (FISHING_BOBBER_READY_TIME..GetDuration(m_spellInfo)) @@ -6205,6 +6384,28 @@ void Spell::EffectProspecting(uint32 /*i*/)      ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_PROSPECTING);  } +void Spell::EffectMilling(uint32 /*i*/) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player* p_caster = (Player*)m_caster; +    if(!itemTarget || !(itemTarget->GetProto()->BagFamily & BAG_FAMILY_MASK_HERBS)) +        return; + +    if(itemTarget->GetCount() < 5) +        return; + +    if( sWorld.getConfig(CONFIG_SKILL_MILLING)) +    { +        uint32 SkillValue = p_caster->GetPureSkillValue(SKILL_INSCRIPTION); +        uint32 reqSkillValue = itemTarget->GetProto()->RequiredSkillRank; +        p_caster->UpdateGatherSkill(SKILL_INSCRIPTION, SkillValue, reqSkillValue); +    } + +    ((Player*)m_caster)->SendLoot(itemTarget->GetGUID(), LOOT_MILLING); +} +  void Spell::EffectSkill(uint32 /*i*/)  {      sLog.outDebug("WORLD: SkillEFFECT"); @@ -6352,6 +6553,31 @@ void Spell::EffectQuestFail(uint32 i)      ((Player*)unitTarget)->FailQuest(m_spellInfo->EffectMiscValue[i]);  } +void Spell::EffectActivateRune(uint32 i) +{ +    if(m_caster->GetTypeId() != TYPEID_PLAYER) +        return; + +    Player *plr = (Player*)m_caster; + +    if(plr->getClass() != CLASS_DEATH_KNIGHT) +        return; + +    for(uint32 j = 0; j < MAX_RUNES; ++j) +    { +        if(plr->GetRuneCooldown(j) && plr->GetCurrentRune(j) == m_spellInfo->EffectMiscValue[i]) +        { +            plr->SetRuneCooldown(j, 0); +        } +    } +} + +void Spell::EffectTitanGrip(uint32 i) +{ +    if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) +        ((Player*)unitTarget)->SetCanTitanGrip(true); +} +  void Spell::EffectRedirectThreat(uint32 /*i*/)  {      if(unitTarget) diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 9b77e19b30b..8648e7a76c6 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -38,15 +38,17 @@  void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)  {      // TODO: add targets.read() check -    CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8); +    CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1);      Player* pUser = _player;      uint8 bagIndex, slot; -    uint8 spell_count;                                      // number of spells at item, not used +    uint8 unk_flags;                                        // flags (if 0x02 - some additional data are received)      uint8 cast_count;                                       // next cast if exists (single or not)      uint64 item_guid; +    uint32 glyphIndex;                                      // something to do with glyphs? +    uint32 spellid;                                         // casted spell id -    recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid; +    recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;      Item *pItem = pUser->GetItemByPos(bagIndex, slot);      if(!pItem) @@ -61,7 +63,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)          return;      } -    sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), recvPacket.size()); +    sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, recvPacket.size());      ItemPrototype const *proto = pItem->GetProto();      if(!proto) @@ -128,14 +130,15 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)          // no script or script not process request by self          // special learning case -        if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) +        if((pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN) || (pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN_PET))          { +            uint32 learn_spell_id = pItem->GetProto()->Spells[0].SpellId;              uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId; -            SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN); +            SpellEntry const *spellInfo = sSpellStore.LookupEntry(learn_spell_id);              if(!spellInfo)              { -                sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, SPELL_ID_GENERIC_LEARN); +                sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, learn_spell_id);                  pUser->SendEquipError(EQUIP_ERR_NONE,pItem,NULL);                  return;              } @@ -172,7 +175,8 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)              Spell *spell = new Spell(pUser, spellInfo, (count > 0));              spell->m_CastItem = pItem; -            spell->m_cast_count = cast_count;               //set count of casts +            spell->m_cast_count = cast_count;               // set count of casts +            spell->m_glyphIndex = glyphIndex;               // glyph index              spell->prepare(&targets);              ++count; @@ -227,7 +231,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket)          }          // required picklocking -        if(lockInfo->requiredlockskill || lockInfo->requiredminingskill) +        if(lockInfo->Skill[1] || lockInfo->Skill[0])          {              pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, pItem, NULL );              return; @@ -281,17 +285,28 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )      obj->Use(_player);  } +void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) +{ +    CHECK_PACKET_SIZE(recvPacket,8); + +    uint64 guid; +    recvPacket >> guid; + +    sLog.outDebug( "WORLD: Recvd CMSG_GAMEOBJ_REPORT_USE Message [in game guid: %u]", GUID_LOPART(guid)); +} +  void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)  { -    CHECK_PACKET_SIZE(recvPacket,4+1+2); +    CHECK_PACKET_SIZE(recvPacket,1+4+1);      uint32 spellId; -    uint8  cast_count; -    recvPacket >> spellId; +    uint8  cast_count, unk_flags;      recvPacket >> cast_count; +    recvPacket >> spellId; +    recvPacket >> unk_flags;                                // flags (if 0x02 - some additional data are received) -    sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i", -        spellId, cast_count, recvPacket.size()); +    sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i", +        spellId, cast_count, unk_flags, recvPacket.size());      SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); @@ -334,9 +349,12 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)  void WorldSession::HandleCancelCastOpcode(WorldPacket& recvPacket)  { -    CHECK_PACKET_SIZE(recvPacket,4); +    CHECK_PACKET_SIZE(recvPacket,5); +    // increments with every CANCEL packet, don't use for now +    uint8 counter;      uint32 spellId; +    recvPacket >> counter;      recvPacket >> spellId;      //FIXME: hack, ignore unexpected client cancel Deadly Throw cast diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index e67030b77f2..2e0d25d4c6a 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -41,13 +41,13 @@ SpellMgr::SpellMgr()              case SPELL_EFFECT_TRANS_DOOR:           //50 summon object              case SPELL_EFFECT_SUMMON_PET:           //56              case SPELL_EFFECT_ADD_FARSIGHT:         //72 -            case SPELL_EFFECT_SUMMON_POSSESSED:     //73 -            case SPELL_EFFECT_SUMMON_TOTEM:         //74 +            //case SPELL_EFFECT_SUMMON_POSSESSED:     //73 +            //case SPELL_EFFECT_SUMMON_TOTEM:         //74              case SPELL_EFFECT_SUMMON_OBJECT_WILD:   //76 -            case SPELL_EFFECT_SUMMON_TOTEM_SLOT1:   //87 -            case SPELL_EFFECT_SUMMON_TOTEM_SLOT2:   //88 -            case SPELL_EFFECT_SUMMON_TOTEM_SLOT3:   //89 -            case SPELL_EFFECT_SUMMON_TOTEM_SLOT4:   //90 +            //case SPELL_EFFECT_SUMMON_TOTEM_SLOT1:   //87 +            //case SPELL_EFFECT_SUMMON_TOTEM_SLOT2:   //88 +            //case SPELL_EFFECT_SUMMON_TOTEM_SLOT3:   //89 +            //case SPELL_EFFECT_SUMMON_TOTEM_SLOT4:   //90              case SPELL_EFFECT_SUMMON_CRITTER:       //97              case SPELL_EFFECT_SUMMON_OBJECT_SLOT1:  //104              case SPELL_EFFECT_SUMMON_OBJECT_SLOT2:  //105 @@ -364,10 +364,10 @@ SpellSpecific GetSpellSpecific(uint32 spellId)              if ((spellInfo->SpellFamilyFlags & 0x00000820180400LL) && (spellInfo->AttributesEx3 & 0x200))                  return SPELL_JUDGEMENT; -            for (int i = 0; i < 3; i++) +            for (int i = 0; i < 3; i++)                     // TODO: fix it for WotLK!!!              {                  // only paladin auras have this -                if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY) +                if (spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID)                      return SPELL_AURA;              }              break; @@ -385,7 +385,7 @@ SpellSpecific GetSpellSpecific(uint32 spellId)      }      // only warlock armor/skin have this (in additional to family cases) -    if( spellInfo->SpellVisual == 130 && spellInfo->SpellIconID == 89) +    if( spellInfo->SpellVisual[0] == 130 && spellInfo->SpellIconID == 89)      {          return SPELL_WARLOCK_ARMOR;      } @@ -874,8 +874,8 @@ void SpellMgr::LoadSpellAffects()      uint32 count = 0; -    //                                                0      1         2 -    QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellFamilyMask FROM spell_affect"); +    //                                                0      1         2                3                4 +    QueryResult *result = WorldDatabase.Query("SELECT entry, effectId, SpellClassMask0, SpellClassMask1, SpellClassMask2 FROM spell_affect");      if( !result )      { @@ -922,26 +922,29 @@ void SpellMgr::LoadSpellAffects()              continue;          } -        uint64 spellAffectMask = fields[2].GetUInt64(); +        SpellAffectEntry affect; +        affect.SpellClassMask[0] = fields[2].GetUInt32(); +        affect.SpellClassMask[1] = fields[3].GetUInt32(); +        affect.SpellClassMask[2] = fields[4].GetUInt32(); -        // Spell.dbc have own data for low part of SpellFamilyMask -        if( spellInfo->EffectItemType[effectId]) +        // Spell.dbc have own data +        uint32 const *ptr = 0; +        switch (effectId)          { -            if(spellInfo->EffectItemType[effectId] == spellAffectMask) -            { -                sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectItemType%d) data for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId); -                continue; -            } - -            // 24429 have wrong data in EffectItemType and overwrites by DB, possible bug in client -            if(spellInfo->Id!=24429 && spellInfo->EffectItemType[effectId] != spellAffectMask) -            { -                sLog.outErrorDb("Spell %u listed in `spell_affect` have different low part from EffectItemType%d for effect index (%u) and not needed, skipped.", entry,effectId+1,effectId); +            case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break; +            case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break; +            case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break; +            default:                   continue; -            } +        } +        if(ptr[0] == affect.SpellClassMask[0] || ptr[1] == affect.SpellClassMask[1] || ptr[2] == affect.SpellClassMask[2]) +        { +            char text[]="ABC"; +            sLog.outErrorDb("Spell %u listed in `spell_affect` have redundant (same with EffectSpellClassMask%c) data for effect index (%u) and not needed, skipped.", entry, text[effectId], effectId); +            continue;          } -        mSpellAffectMap.insert(SpellAffectMap::value_type((entry<<8) + effectId,spellAffectMask)); +        mSpellAffectMap[(entry<<8) + effectId] = affect;          ++count;      } while( result->NextRow() ); @@ -949,7 +952,7 @@ void SpellMgr::LoadSpellAffects()      delete result;      sLog.outString(); -    sLog.outString( ">> Loaded %u spell affect definitions", count ); +    sLog.outString( ">> Loaded %u custom spell affect definitions", count );      for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id)      { @@ -965,7 +968,16 @@ void SpellMgr::LoadSpellAffects()                  spellInfo->EffectApplyAuraName[effectId] != SPELL_AURA_ADD_TARGET_TRIGGER) )                  continue; -            if(spellInfo->EffectItemType[effectId] != 0) +            uint32 const *ptr = 0; +            switch (effectId) +            { +                case 0: ptr = &spellInfo->EffectSpellClassMaskA[0]; break; +                case 1: ptr = &spellInfo->EffectSpellClassMaskB[0]; break; +                case 2: ptr = &spellInfo->EffectSpellClassMaskC[0]; break; +                default:  +                    continue; +            } +            if(ptr[0] || ptr[1] || ptr[2])                  continue;              if(mSpellAffectMap.find((id<<8) + effectId) !=  mSpellAffectMap.end()) @@ -976,33 +988,20 @@ void SpellMgr::LoadSpellAffects()      }  } -bool SpellMgr::IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const +bool SpellMgr::IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const  {      // false for spellInfo == NULL -    if (!spellInfo) +    if (!spellInfo || !mod)          return false; -    SpellEntry const *affect_spell = sSpellStore.LookupEntry(spellId); -    // false for affect_spell == NULL -    if (!affect_spell) +    SpellEntry const *affect_spell = sSpellStore.LookupEntry(mod->spellId); +    // False if affect_spell == NULL or spellFamily not equal +    if (!affect_spell || affect_spell->SpellFamilyName != spellInfo->SpellFamilyName)          return false; -    // False if spellFamily not equal -    if (affect_spell->SpellFamilyName != spellInfo->SpellFamilyName) -        return false; - -    // If familyFlags == 0 -    if (!familyFlags) -    { -        // Get it from spellAffect table -        familyFlags = GetSpellAffectMask(spellId,effectId); -        // false if familyFlags == 0 -        if (!familyFlags) -            return false; -    } -      // true -    if (familyFlags & spellInfo->SpellFamilyFlags) +    if (mod->mask  & spellInfo->SpellFamilyFlags || +        mod->mask2 & spellInfo->SpellFamilyFlags2)          return true;      return false; @@ -1074,80 +1073,10 @@ void SpellMgr::LoadSpellProcEvents()      sLog.outString();      if (customProc) -        sLog.outString( ">> Loaded %u custom spell proc event conditions +%u custom",  count, customProc ); +        sLog.outString( ">> Loaded %u extra spell proc event conditions +%u custom",  count, customProc );      else -        sLog.outString( ">> Loaded %u spell proc event conditions", count ); - -    /* -    // Commented for now, as it still produces many errors (still quite many spells miss spell_proc_event) -    for (uint32 id = 0; id < sSpellStore.GetNumRows(); ++id) -    { -        SpellEntry const* spellInfo = sSpellStore.LookupEntry(id); -        if (!spellInfo) -            continue; - -        bool found = false; -        for (int effectId = 0; effectId < 3; ++effectId) -        { -            // at this moment check only SPELL_AURA_PROC_TRIGGER_SPELL -            if( spellInfo->EffectApplyAuraName[effectId] == SPELL_AURA_PROC_TRIGGER_SPELL ) -            { -                found = true; -                break; -            } -        } - -        if(!found) -            continue; - -        if(GetSpellProcEvent(id)) -            continue; - -        sLog.outErrorDb("Spell %u (%s) misses spell_proc_event",id,spellInfo->SpellName[sWorld.GetDBClang()]); -    } -    */ -} - -/* -bool SpellMgr::IsSpellProcEventCanTriggeredBy( SpellProcEventEntry const * spellProcEvent, SpellEntry const * procSpell, uint32 procFlags ) -{ -    if((procFlags & spellProcEvent->procFlags) == 0) -        return false; - -    // Additional checks in case spell cast/hit/crit is the event -    // Check (if set) school, category, skill line, spell talent mask -    if(spellProcEvent->schoolMask && (!procSpell || (GetSpellSchoolMask(procSpell) & spellProcEvent->schoolMask) == 0)) -        return false; -    if(spellProcEvent->category && (!procSpell || procSpell->Category != spellProcEvent->category)) -        return false; -    if(spellProcEvent->skillId) -    { -        if (!procSpell) -            return false; - -        SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(procSpell->Id); -        SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(procSpell->Id); - -        bool found = false; -        for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx) -        { -            if(_spell_idx->second->skillId == spellProcEvent->skillId) -            { -                found = true; -                break; -            } -        } -        if (!found) -            return false; -    } -    if(spellProcEvent->spellFamilyName && (!procSpell || spellProcEvent->spellFamilyName != procSpell->SpellFamilyName)) -        return false; -    if(spellProcEvent->spellFamilyMask && (!procSpell || (spellProcEvent->spellFamilyMask & procSpell->SpellFamilyFlags) == 0)) -        return false; - -    return true; +        sLog.outString( ">> Loaded %u extra spell proc event conditions", count );  } -*/  bool SpellMgr::IsSpellProcEventCanTriggeredBy(SpellProcEventEntry const * spellProcEvent, uint32 EventProcFlag, SpellEntry const * procSpell, uint32 procFlags, uint32 procExtra, bool active)  { @@ -1296,7 +1225,7 @@ bool SpellMgr::canStackSpellRanks(SpellEntry const *spellInfo)      {          // Paladin aura Spell          if(spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN -            && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_PARTY) +            && spellInfo->Effect[i]==SPELL_EFFECT_APPLY_AREA_AURA_RAID)              return false;          // Druid form Spell          if(spellInfo->SpellFamilyName == SPELLFAMILY_DRUID @@ -1433,7 +1362,8 @@ SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spell      {          if( IsPositiveEffect(spellInfo->Id, i) && (              spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA || -            spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY +            spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_PARTY || +            spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA_RAID              ) )          {              needRankSelection = true; @@ -1565,7 +1495,7 @@ void SpellMgr::LoadSpellChains()          entry.ProcFlags=SpellInfo->procFlags;          entry.SpellFamilyFlags=SpellInfo->SpellFamilyFlags;          entry.TargetAuraState=SpellInfo->TargetAuraState; -        entry.SpellVisual=SpellInfo->SpellVisual; +        entry.SpellVisual=SpellInfo->SpellVisual[0];          entry.ManaCost=SpellInfo->manaCost;          value.Id=spell_id; @@ -1789,7 +1719,15 @@ void SpellMgr::LoadSpellLearnSpells()              {                  SpellLearnSpellNode dbc_node;                  dbc_node.spell       = entry->EffectTriggerSpell[i]; -                dbc_node.autoLearned = true; + +                // ignore learning not existed spells (broken/outdated/or generic learnig spell 483 +                if(!sSpellStore.LookupEntry(dbc_node.spell)) +                    continue; + +                // talent or passive spells or skill-step spells auto-casted and not need dependent learning, +                // pet teaching spells don't must be dependent learning (casted) +                // other required explicit dependent learning +                dbc_node.autoLearned = entry->EffectImplicitTargetA[i]==TARGET_PET || GetTalentSpellCost(spell) > 0 || IsPassiveSpell(spell) || IsSpellHaveEffect(entry,SPELL_EFFECT_SKILL_STEP);                  SpellLearnSpellMap::const_iterator db_node_begin = GetBeginSpellLearnSpell(spell);                  SpellLearnSpellMap::const_iterator db_node_end   = GetEndSpellLearnSpell(spell); @@ -2088,7 +2026,7 @@ void SpellMgr::LoadSpellCustomAttr()              }          } -        if(spellInfo->SpellVisual == 3879) +        if(spellInfo->SpellVisual[0] == 3879)              mSpellCustomAttr[i] |= SPELL_ATTR_CU_CONE_BACK;          switch(i) @@ -2192,6 +2130,187 @@ void SpellMgr::LoadSpellLinked()  }  /// Some checks for spells, to prevent adding depricated/broken spells for trainers, spell book, etc +void SpellMgr::LoadPetLevelupSpellMap() +{ +    CreatureFamilyEntry const *creatureFamily; +    SpellEntry const *spell; +    uint32 count = 0; + +    for (uint32 i = 0; i < sCreatureFamilyStore.GetNumRows(); ++i) +    { +        creatureFamily = sCreatureFamilyStore.LookupEntry(i); + +        if(!creatureFamily)                                 // not exist +            continue; + +        if(creatureFamily->petTalentType < 0)               // not hunter pet family +            continue; + +        for(uint32 j = 0; j < sSpellStore.GetNumRows(); ++j) +        { +            spell = sSpellStore.LookupEntry(j); + +            // not exist +            if(!spell) +                continue; + +            // not hunter spell +            if(spell->SpellFamilyName != SPELLFAMILY_HUNTER) +                continue; + +            // not pet spell +            if(!(spell->SpellFamilyFlags & 0x1000000000000000LL)) +                continue; + +            // not Growl or Cower (generics) +            if(spell->SpellIconID != 201 && spell->SpellIconID != 958) +            { +                switch(creatureFamily->ID) +                { +                    case CREATURE_FAMILY_BAT:               // Bite and Sonic Blast +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1577) +                            continue; +                        break; +                    case CREATURE_FAMILY_BEAR:              // Claw and Swipe +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 1562) +                            continue; +                        break; +                    case CREATURE_FAMILY_BIRD_OF_PREY:      // Claw and Snatch +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 168) +                            continue; +                        break; +                    case CREATURE_FAMILY_BOAR:              // Bite and Gore +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1578) +                            continue; +                        break; +                    case CREATURE_FAMILY_CARRION_BIRD:      // Bite and Demoralizing Screech +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1579) +                            continue; +                        break; +                    case CREATURE_FAMILY_CAT:               // Claw and Prowl and Rake +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 494) +                            continue; +                        break; +                    case CREATURE_FAMILY_CHIMAERA:          // Bite and Froststorm Breath +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) +                            continue; +                        break; +                    case CREATURE_FAMILY_CORE_HOUND:        // Bite and Lava Breath +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1197) +                            continue; +                        break; +                    case CREATURE_FAMILY_CRAB:              // Claw and Pin +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 2679) +                            continue; +                        break; +                    case CREATURE_FAMILY_CROCOLISK:         // Bite and Bad Attitude +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1581) +                            continue; +                        break; +                    case CREATURE_FAMILY_DEVILSAUR:         // Bite and Monstrous Bite +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 599) +                            continue; +                        break; +                    case CREATURE_FAMILY_DRAGONHAWK:        // Bite and Fire Breath +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 2128) +                            continue; +                        break; +                    case CREATURE_FAMILY_GORILLA:           // Smack and Thunderstomp +                        if(spell->SpellIconID != 473 && spell->SpellIconID != 148) +                            continue; +                        break; +                    case CREATURE_FAMILY_HYENA:             // Bite and Tendon Rip +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 138) +                            continue; +                        break; +                    case CREATURE_FAMILY_MOTH:              // Serenity Dust and Smack +                        if(spell->SpellIconID != 1714 && spell->SpellIconID != 473) +                            continue; +                        break; +                    case CREATURE_FAMILY_NETHER_RAY:        // Bite and Nether Shock +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 2027) +                            continue; +                        break; +                    case CREATURE_FAMILY_RAPTOR:            // Claw and Savage Rend +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 245) +                            continue; +                        break; +                    case CREATURE_FAMILY_RAVAGER:           // Bite and Ravage +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 2253) +                            continue; +                        break; +                    case CREATURE_FAMILY_RHINO:             // Smack and Stampede +                        if(spell->SpellIconID != 473 && spell->SpellIconID != 3066) +                            continue; +                        break; +                    case CREATURE_FAMILY_SCORPID:           // Claw and Scorpid Poison +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 163) +                            continue; +                        break; +                    case CREATURE_FAMILY_SERPENT:           // Bite and Poison Spit +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 68) +                            continue; +                        break; +                    case CREATURE_FAMILY_SILITHID:          // Claw and Venom Web Spray +                        if(spell->SpellIconID != 262 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 12013)) +                            continue; +                        break; +                    case CREATURE_FAMILY_SPIDER:            // Bite and Web +                        if(spell->SpellIconID != 1680 && (spell->SpellIconID != 272 && spell->SpellVisual[0] != 684)) +                            continue; +                        break; +                    case CREATURE_FAMILY_SPIRIT_BEAST:      // Claw and Prowl and Spirit Strike +                        if(spell->SpellIconID != 262 && spell->SpellIconID != 495 && spell->SpellIconID != 255) +                            continue; +                        break; +                    case CREATURE_FAMILY_SPOREBAT:          // Smack and Spore Cloud +                        if(spell->SpellIconID != 473 && spell->SpellIconID != 2681) +                            continue; +                        break; +                    case CREATURE_FAMILY_TALLSTRIDER:       // Claw and Dust Cloud +                        if(spell->SpellIconID != 262 && (spell->SpellIconID != 157 && !(spell->Attributes & 0x4000000))) +                            continue; +                        break; +                    case CREATURE_FAMILY_TURTLE:            // Bite and Shell Shield +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1588) +                            continue; +                        break; +                    case CREATURE_FAMILY_WARP_STALKER:      // Bite and Warp +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1952) +                            continue; +                         break; +                    case CREATURE_FAMILY_WASP:              // Smack and Sting +                        if(spell->SpellIconID != 473 && spell->SpellIconID != 110) +                            continue; +                        break; +                    case CREATURE_FAMILY_WIND_SERPENT:      // Bite and Lightning Breath +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 62) +                            continue; +                        break; +                    case CREATURE_FAMILY_WOLF:              // Bite and Furious Howl +                        if(spell->SpellIconID != 1680 && spell->SpellIconID != 1573) +                            continue; +                        break; +                    case CREATURE_FAMILY_WORM:              // Acid Spit and Bite +                        if(spell->SpellIconID != 636 && spell->SpellIconID != 1680) +                            continue; +                        break; +                    default: +                        sLog.outError("LoadPetLevelupSpellMap: Unhandled creature family %u", creatureFamily->ID); +                        continue; +                    } +            } + +            mPetLevelupSpellMap[creatureFamily->ID][spell->spellLevel] = spell->Id; +            count++; +        } +    } + +    sLog.outString(); +    sLog.outString( ">> Loaded %u pet levelup spells", count ); +} + +/// Some checks for spells, to prevent adding deprecated/broken spells for trainers, spell book, etc  bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)  {      // not exist @@ -2269,7 +2388,7 @@ bool SpellMgr::IsSpellValid(SpellEntry const* spellInfo, Player* pl, bool msg)  bool IsSpellAllowedInLocation(SpellEntry const *spellInfo,uint32 map_id,uint32 zone_id,uint32 area_id)  {      // normal case -    if( spellInfo->AreaId && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id ) +    if( spellInfo->AreaId > 0 && spellInfo->AreaId != zone_id && spellInfo->AreaId != area_id )          return false;      // elixirs (all area dependent elixirs have family SPELLFAMILY_POTION, use this for speedup) diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index ef5e8379341..a37d219743f 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -29,6 +29,9 @@  #include "Database/SQLStorage.h"  #include "Utilities/UnorderedMap.h" + +#include "Player.h" +  #include <map>  class Player; @@ -38,175 +41,188 @@ extern SQLStorage sSpellThreatStore;  enum SpellFailedReason  { -    SPELL_FAILED_AFFECTING_COMBAT               = 0x00, -    SPELL_FAILED_ALREADY_AT_FULL_HEALTH         = 0x01, -    SPELL_FAILED_ALREADY_AT_FULL_MANA           = 0x02, -    SPELL_FAILED_ALREADY_AT_FULL_POWER          = 0x03, -    SPELL_FAILED_ALREADY_BEING_TAMED            = 0x04, -    SPELL_FAILED_ALREADY_HAVE_CHARM             = 0x05, -    SPELL_FAILED_ALREADY_HAVE_SUMMON            = 0x06, -    SPELL_FAILED_ALREADY_OPEN                   = 0x07, -    SPELL_FAILED_AURA_BOUNCED                   = 0x08, -    SPELL_FAILED_AUTOTRACK_INTERRUPTED          = 0x09, -    SPELL_FAILED_BAD_IMPLICIT_TARGETS           = 0x0A, -    SPELL_FAILED_BAD_TARGETS                    = 0x0B, -    SPELL_FAILED_CANT_BE_CHARMED                = 0x0C, -    SPELL_FAILED_CANT_BE_DISENCHANTED           = 0x0D, -    SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL     = 0x0E, -    SPELL_FAILED_CANT_BE_PROSPECTED             = 0x0F, -    SPELL_FAILED_CANT_CAST_ON_TAPPED            = 0x10, -    SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE      = 0x11, -    SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED      = 0x12, -    SPELL_FAILED_CANT_STEALTH                   = 0x13, -    SPELL_FAILED_CASTER_AURASTATE               = 0x14, -    SPELL_FAILED_CASTER_DEAD                    = 0x15, -    SPELL_FAILED_CHARMED                        = 0x16, -    SPELL_FAILED_CHEST_IN_USE                   = 0x17, -    SPELL_FAILED_CONFUSED                       = 0x18, -    SPELL_FAILED_DONT_REPORT                    = 0x19, -    SPELL_FAILED_EQUIPPED_ITEM                  = 0x1A, -    SPELL_FAILED_EQUIPPED_ITEM_CLASS            = 0x1B, -    SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND   = 0x1C, -    SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND    = 0x1D, -    SPELL_FAILED_ERROR                          = 0x1E, -    SPELL_FAILED_FIZZLE                         = 0x1F, -    SPELL_FAILED_FLEEING                        = 0x20, -    SPELL_FAILED_FOOD_LOWLEVEL                  = 0x21, -    SPELL_FAILED_HIGHLEVEL                      = 0x22, -    SPELL_FAILED_HUNGER_SATIATED                = 0x23, -    SPELL_FAILED_IMMUNE                         = 0x24, -    SPELL_FAILED_INTERRUPTED                    = 0x25, -    SPELL_FAILED_INTERRUPTED_COMBAT             = 0x26, -    SPELL_FAILED_ITEM_ALREADY_ENCHANTED         = 0x27, -    SPELL_FAILED_ITEM_GONE                      = 0x28, -    SPELL_FAILED_ITEM_NOT_FOUND                 = 0x29, -    SPELL_FAILED_ITEM_NOT_READY                 = 0x2A, -    SPELL_FAILED_LEVEL_REQUIREMENT              = 0x2B, -    SPELL_FAILED_LINE_OF_SIGHT                  = 0x2C, -    SPELL_FAILED_LOWLEVEL                       = 0x2D, -    SPELL_FAILED_LOW_CASTLEVEL                  = 0x2E, -    SPELL_FAILED_MAINHAND_EMPTY                 = 0x2F, -    SPELL_FAILED_MOVING                         = 0x30, -    SPELL_FAILED_NEED_AMMO                      = 0x31, -    SPELL_FAILED_NEED_AMMO_POUCH                = 0x32, -    SPELL_FAILED_NEED_EXOTIC_AMMO               = 0x33, -    SPELL_FAILED_NOPATH                         = 0x34, -    SPELL_FAILED_NOT_BEHIND                     = 0x35, -    SPELL_FAILED_NOT_FISHABLE                   = 0x36, -    SPELL_FAILED_NOT_FLYING                     = 0x37, -    SPELL_FAILED_NOT_HERE                       = 0x38, -    SPELL_FAILED_NOT_INFRONT                    = 0x39, -    SPELL_FAILED_NOT_IN_CONTROL                 = 0x3A, -    SPELL_FAILED_NOT_KNOWN                      = 0x3B, -    SPELL_FAILED_NOT_MOUNTED                    = 0x3C, -    SPELL_FAILED_NOT_ON_TAXI                    = 0x3D, -    SPELL_FAILED_NOT_ON_TRANSPORT               = 0x3E, -    SPELL_FAILED_NOT_READY                      = 0x3F, -    SPELL_FAILED_NOT_SHAPESHIFT                 = 0x40, -    SPELL_FAILED_NOT_STANDING                   = 0x41, -    SPELL_FAILED_NOT_TRADEABLE                  = 0x42, -    SPELL_FAILED_NOT_TRADING                    = 0x43, -    SPELL_FAILED_NOT_UNSHEATHED                 = 0x44, -    SPELL_FAILED_NOT_WHILE_GHOST                = 0x45, -    SPELL_FAILED_NO_AMMO                        = 0x46, -    SPELL_FAILED_NO_CHARGES_REMAIN              = 0x47, -    SPELL_FAILED_NO_CHAMPION                    = 0x48, -    SPELL_FAILED_NO_COMBO_POINTS                = 0x49, -    SPELL_FAILED_NO_DUELING                     = 0x4A, -    SPELL_FAILED_NO_ENDURANCE                   = 0x4B, -    SPELL_FAILED_NO_FISH                        = 0x4C, -    SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED    = 0x4D, -    SPELL_FAILED_NO_MOUNTS_ALLOWED              = 0x4E, -    SPELL_FAILED_NO_PET                         = 0x4F, -    SPELL_FAILED_NO_POWER                       = 0x50, -    SPELL_FAILED_NOTHING_TO_DISPEL              = 0x51, -    SPELL_FAILED_NOTHING_TO_STEAL               = 0x52, -    SPELL_FAILED_ONLY_ABOVEWATER                = 0x53, -    SPELL_FAILED_ONLY_DAYTIME                   = 0x54, -    SPELL_FAILED_ONLY_INDOORS                   = 0x55, -    SPELL_FAILED_ONLY_MOUNTED                   = 0x56, -    SPELL_FAILED_ONLY_NIGHTTIME                 = 0x57, -    SPELL_FAILED_ONLY_OUTDOORS                  = 0x58, -    SPELL_FAILED_ONLY_SHAPESHIFT                = 0x59, -    SPELL_FAILED_ONLY_STEALTHED                 = 0x5A, -    SPELL_FAILED_ONLY_UNDERWATER                = 0x5B, -    SPELL_FAILED_OUT_OF_RANGE                   = 0x5C, -    SPELL_FAILED_PACIFIED                       = 0x5D, -    SPELL_FAILED_POSSESSED                      = 0x5E, -    SPELL_FAILED_REAGENTS                       = 0x5F, -    SPELL_FAILED_REQUIRES_AREA                  = 0x60, -    SPELL_FAILED_REQUIRES_SPELL_FOCUS           = 0x61, -    SPELL_FAILED_ROOTED                         = 0x62, -    SPELL_FAILED_SILENCED                       = 0x63, -    SPELL_FAILED_SPELL_IN_PROGRESS              = 0x64, -    SPELL_FAILED_SPELL_LEARNED                  = 0x65, -    SPELL_FAILED_SPELL_UNAVAILABLE              = 0x66, -    SPELL_FAILED_STUNNED                        = 0x67, -    SPELL_FAILED_TARGETS_DEAD                   = 0x68, -    SPELL_FAILED_TARGET_AFFECTING_COMBAT        = 0x69, -    SPELL_FAILED_TARGET_AURASTATE               = 0x6A, -    SPELL_FAILED_TARGET_DUELING                 = 0x6B, -    SPELL_FAILED_TARGET_ENEMY                   = 0x6C, -    SPELL_FAILED_TARGET_ENRAGED                 = 0x6D, -    SPELL_FAILED_TARGET_FRIENDLY                = 0x6E, -    SPELL_FAILED_TARGET_IN_COMBAT               = 0x6F, -    SPELL_FAILED_TARGET_IS_PLAYER               = 0x70, -    SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED    = 0x71, -    SPELL_FAILED_TARGET_NOT_DEAD                = 0x72, -    SPELL_FAILED_TARGET_NOT_IN_PARTY            = 0x73, -    SPELL_FAILED_TARGET_NOT_LOOTED              = 0x74, -    SPELL_FAILED_TARGET_NOT_PLAYER              = 0x75, -    SPELL_FAILED_TARGET_NO_POCKETS              = 0x76, -    SPELL_FAILED_TARGET_NO_WEAPONS              = 0x77, -    SPELL_FAILED_TARGET_UNSKINNABLE             = 0x78, -    SPELL_FAILED_THIRST_SATIATED                = 0x79, -    SPELL_FAILED_TOO_CLOSE                      = 0x7A, -    SPELL_FAILED_TOO_MANY_OF_ITEM               = 0x7B, -    SPELL_FAILED_TOTEM_CATEGORY                 = 0x7C, -    SPELL_FAILED_TOTEMS                         = 0x7D, -    SPELL_FAILED_TRAINING_POINTS                = 0x7E, -    SPELL_FAILED_TRY_AGAIN                      = 0x7F, -    SPELL_FAILED_UNIT_NOT_BEHIND                = 0x80, -    SPELL_FAILED_UNIT_NOT_INFRONT               = 0x81, -    SPELL_FAILED_WRONG_PET_FOOD                 = 0x82, -    SPELL_FAILED_NOT_WHILE_FATIGUED             = 0x83, -    SPELL_FAILED_TARGET_NOT_IN_INSTANCE         = 0x84, -    SPELL_FAILED_NOT_WHILE_TRADING              = 0x85, -    SPELL_FAILED_TARGET_NOT_IN_RAID             = 0x86, -    SPELL_FAILED_DISENCHANT_WHILE_LOOTING       = 0x87, -    SPELL_FAILED_PROSPECT_WHILE_LOOTING         = 0x88, -    SPELL_FAILED_PROSPECT_NEED_MORE             = 0x89, -    SPELL_FAILED_TARGET_FREEFORALL              = 0x8A, -    SPELL_FAILED_NO_EDIBLE_CORPSES              = 0x8B, -    SPELL_FAILED_ONLY_BATTLEGROUNDS             = 0x8C, -    SPELL_FAILED_TARGET_NOT_GHOST               = 0x8D, -    SPELL_FAILED_TOO_MANY_SKILLS                = 0x8E, -    SPELL_FAILED_TRANSFORM_UNUSABLE             = 0x8F, -    SPELL_FAILED_WRONG_WEATHER                  = 0x90, -    SPELL_FAILED_DAMAGE_IMMUNE                  = 0x91, -    SPELL_FAILED_PREVENTED_BY_MECHANIC          = 0x92, -    SPELL_FAILED_PLAY_TIME                      = 0x93, -    SPELL_FAILED_REPUTATION                     = 0x94, -    SPELL_FAILED_MIN_SKILL                      = 0x95, -    SPELL_FAILED_NOT_IN_ARENA                   = 0x96, -    SPELL_FAILED_NOT_ON_SHAPESHIFT              = 0x97, -    SPELL_FAILED_NOT_ON_STEALTHED               = 0x98, -    SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE           = 0x99, -    SPELL_FAILED_NOT_ON_MOUNTED                 = 0x9A, -    SPELL_FAILED_TOO_SHALLOW                    = 0x9B, -    SPELL_FAILED_TARGET_NOT_IN_SANCTUARY        = 0x9C, -    SPELL_FAILED_TARGET_IS_TRIVIAL              = 0x9D, -    SPELL_FAILED_BM_OR_INVISGOD                 = 0x9E, -    SPELL_FAILED_EXPERT_RIDING_REQUIREMENT      = 0x9F, -    SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT     = 0xA0, -    SPELL_FAILED_NOT_IDLE                       = 0xA1, -    SPELL_FAILED_NOT_INACTIVE                   = 0xA2, -    SPELL_FAILED_PARTIAL_PLAYTIME               = 0xA3, -    SPELL_FAILED_NO_PLAYTIME                    = 0xA4, -    SPELL_FAILED_NOT_IN_BATTLEGROUND            = 0xA5, -    SPELL_FAILED_ONLY_IN_ARENA                  = 0xA6, -    SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 0xA7, -    SPELL_FAILED_UNKNOWN                        = 0xA8, +    SPELL_FAILED_AFFECTING_COMBAT = 0, +    SPELL_FAILED_ALREADY_AT_FULL_HEALTH = 1, +    SPELL_FAILED_ALREADY_AT_FULL_MANA = 2, +    SPELL_FAILED_ALREADY_AT_FULL_POWER = 3, +    SPELL_FAILED_ALREADY_BEING_TAMED = 4, +    SPELL_FAILED_ALREADY_HAVE_CHARM = 5, +    SPELL_FAILED_ALREADY_HAVE_SUMMON = 6, +    SPELL_FAILED_ALREADY_OPEN = 7, +    SPELL_FAILED_AURA_BOUNCED = 8, +    SPELL_FAILED_AUTOTRACK_INTERRUPTED = 9, +    SPELL_FAILED_BAD_IMPLICIT_TARGETS = 10, +    SPELL_FAILED_BAD_TARGETS = 11, +    SPELL_FAILED_CANT_BE_CHARMED = 12, +    SPELL_FAILED_CANT_BE_DISENCHANTED = 13, +    SPELL_FAILED_CANT_BE_DISENCHANTED_SKILL = 14, +    SPELL_FAILED_CANT_BE_MILLED = 15, +    SPELL_FAILED_CANT_BE_PROSPECTED = 16, +    SPELL_FAILED_CANT_CAST_ON_TAPPED = 17, +    SPELL_FAILED_CANT_DUEL_WHILE_INVISIBLE = 18, +    SPELL_FAILED_CANT_DUEL_WHILE_STEALTHED = 19, +    SPELL_FAILED_CANT_STEALTH = 20, +    SPELL_FAILED_CASTER_AURASTATE = 21, +    SPELL_FAILED_CASTER_DEAD = 22, +    SPELL_FAILED_CHARMED = 23, +    SPELL_FAILED_CHEST_IN_USE = 24, +    SPELL_FAILED_CONFUSED = 25, +    SPELL_FAILED_DONT_REPORT = 26, +    SPELL_FAILED_EQUIPPED_ITEM = 27, +    SPELL_FAILED_EQUIPPED_ITEM_CLASS = 28, +    SPELL_FAILED_EQUIPPED_ITEM_CLASS_MAINHAND = 29, +    SPELL_FAILED_EQUIPPED_ITEM_CLASS_OFFHAND = 30, +    SPELL_FAILED_ERROR = 31, +    SPELL_FAILED_FIZZLE = 32, +    SPELL_FAILED_FLEEING = 33, +    SPELL_FAILED_FOOD_LOWLEVEL = 34, +    SPELL_FAILED_HIGHLEVEL = 35, +    SPELL_FAILED_HUNGER_SATIATED = 36, +    SPELL_FAILED_IMMUNE = 37, +    SPELL_FAILED_INCORRECT_AREA = 38, +    SPELL_FAILED_INTERRUPTED = 39, +    SPELL_FAILED_INTERRUPTED_COMBAT = 40, +    SPELL_FAILED_ITEM_ALREADY_ENCHANTED = 41, +    SPELL_FAILED_ITEM_GONE = 42, +    SPELL_FAILED_ITEM_NOT_FOUND = 43, +    SPELL_FAILED_ITEM_NOT_READY = 44, +    SPELL_FAILED_LEVEL_REQUIREMENT = 45, +    SPELL_FAILED_LINE_OF_SIGHT = 46, +    SPELL_FAILED_LOWLEVEL = 47, +    SPELL_FAILED_LOW_CASTLEVEL = 48, +    SPELL_FAILED_MAINHAND_EMPTY = 49, +    SPELL_FAILED_MOVING = 50, +    SPELL_FAILED_NEED_AMMO = 51, +    SPELL_FAILED_NEED_AMMO_POUCH = 52, +    SPELL_FAILED_NEED_EXOTIC_AMMO = 53, +    SPELL_FAILED_NEED_MORE_ITEMS = 54, +    SPELL_FAILED_NOPATH = 55, +    SPELL_FAILED_NOT_BEHIND = 56, +    SPELL_FAILED_NOT_FISHABLE = 57, +    SPELL_FAILED_NOT_FLYING = 58, +    SPELL_FAILED_NOT_HERE = 59, +    SPELL_FAILED_NOT_INFRONT = 60, +    SPELL_FAILED_NOT_IN_CONTROL = 61, +    SPELL_FAILED_NOT_KNOWN = 62, +    SPELL_FAILED_NOT_MOUNTED = 63, +    SPELL_FAILED_NOT_ON_TAXI = 64, +    SPELL_FAILED_NOT_ON_TRANSPORT = 65, +    SPELL_FAILED_NOT_READY = 66, +    SPELL_FAILED_NOT_SHAPESHIFT = 67, +    SPELL_FAILED_NOT_STANDING = 68, +    SPELL_FAILED_NOT_TRADEABLE = 69, +    SPELL_FAILED_NOT_TRADING = 70, +    SPELL_FAILED_NOT_UNSHEATHED = 71, +    SPELL_FAILED_NOT_WHILE_GHOST = 72, +    SPELL_FAILED_NOT_WHILE_LOOTING = 73, +    SPELL_FAILED_NO_AMMO = 74, +    SPELL_FAILED_NO_CHARGES_REMAIN = 75, +    SPELL_FAILED_NO_CHAMPION = 76, +    SPELL_FAILED_NO_COMBO_POINTS = 77, +    SPELL_FAILED_NO_DUELING = 78, +    SPELL_FAILED_NO_ENDURANCE = 79, +    SPELL_FAILED_NO_FISH = 80, +    SPELL_FAILED_NO_ITEMS_WHILE_SHAPESHIFTED = 81, +    SPELL_FAILED_NO_MOUNTS_ALLOWED = 82, +    SPELL_FAILED_NO_PET = 83, +    SPELL_FAILED_NO_POWER = 84, +    SPELL_FAILED_NOTHING_TO_DISPEL = 85, +    SPELL_FAILED_NOTHING_TO_STEAL = 86, +    SPELL_FAILED_ONLY_ABOVEWATER = 87, +    SPELL_FAILED_ONLY_DAYTIME = 88, +    SPELL_FAILED_ONLY_INDOORS = 89, +    SPELL_FAILED_ONLY_MOUNTED = 90, +    SPELL_FAILED_ONLY_NIGHTTIME = 91, +    SPELL_FAILED_ONLY_OUTDOORS = 92, +    SPELL_FAILED_ONLY_SHAPESHIFT = 93, +    SPELL_FAILED_ONLY_STEALTHED = 94, +    SPELL_FAILED_ONLY_UNDERWATER = 95, +    SPELL_FAILED_OUT_OF_RANGE = 96, +    SPELL_FAILED_PACIFIED = 97, +    SPELL_FAILED_POSSESSED = 98, +    SPELL_FAILED_REAGENTS = 99, +    SPELL_FAILED_REQUIRES_AREA = 100, +    SPELL_FAILED_REQUIRES_SPELL_FOCUS = 101, +    SPELL_FAILED_ROOTED = 102, +    SPELL_FAILED_SILENCED = 103, +    SPELL_FAILED_SPELL_IN_PROGRESS = 104, +    SPELL_FAILED_SPELL_LEARNED = 105, +    SPELL_FAILED_SPELL_UNAVAILABLE = 106, +    SPELL_FAILED_STUNNED = 107, +    SPELL_FAILED_TARGETS_DEAD = 108, +    SPELL_FAILED_TARGET_AFFECTING_COMBAT = 109, +    SPELL_FAILED_TARGET_AURASTATE = 110, +    SPELL_FAILED_TARGET_DUELING = 111, +    SPELL_FAILED_TARGET_ENEMY = 112, +    SPELL_FAILED_TARGET_ENRAGED = 113, +    SPELL_FAILED_TARGET_FRIENDLY = 114, +    SPELL_FAILED_TARGET_IN_COMBAT = 115, +    SPELL_FAILED_TARGET_IS_PLAYER = 116, +    SPELL_FAILED_TARGET_IS_PLAYER_CONTROLLED = 117, +    SPELL_FAILED_TARGET_NOT_DEAD = 118, +    SPELL_FAILED_TARGET_NOT_IN_PARTY = 119, +    SPELL_FAILED_TARGET_NOT_LOOTED = 120, +    SPELL_FAILED_TARGET_NOT_PLAYER = 121, +    SPELL_FAILED_TARGET_NO_POCKETS = 122, +    SPELL_FAILED_TARGET_NO_WEAPONS = 123, +    SPELL_FAILED_TARGET_NO_RANGED_WEAPONS = 124, +    SPELL_FAILED_TARGET_UNSKINNABLE = 125, +    SPELL_FAILED_THIRST_SATIATED = 126, +    SPELL_FAILED_TOO_CLOSE = 127, +    SPELL_FAILED_TOO_MANY_OF_ITEM = 128, +    SPELL_FAILED_TOTEM_CATEGORY = 129, +    SPELL_FAILED_TOTEMS = 130, +    SPELL_FAILED_TRY_AGAIN = 131, +    SPELL_FAILED_UNIT_NOT_BEHIND = 132, +    SPELL_FAILED_UNIT_NOT_INFRONT = 133, +    SPELL_FAILED_WRONG_PET_FOOD = 134, +    SPELL_FAILED_NOT_WHILE_FATIGUED = 135, +    SPELL_FAILED_TARGET_NOT_IN_INSTANCE = 136, +    SPELL_FAILED_NOT_WHILE_TRADING = 137, +    SPELL_FAILED_TARGET_NOT_IN_RAID = 138, +    SPELL_FAILED_TARGET_FREEFORALL = 139, +    SPELL_FAILED_NO_EDIBLE_CORPSES = 140, +    SPELL_FAILED_ONLY_BATTLEGROUNDS = 141, +    SPELL_FAILED_TARGET_NOT_GHOST = 142, +    SPELL_FAILED_TRANSFORM_UNUSABLE = 143, +    SPELL_FAILED_WRONG_WEATHER = 144, +    SPELL_FAILED_DAMAGE_IMMUNE = 145, +    SPELL_FAILED_PREVENTED_BY_MECHANIC = 146, +    SPELL_FAILED_PLAY_TIME = 147, +    SPELL_FAILED_REPUTATION = 148, +    SPELL_FAILED_MIN_SKILL = 149, +    SPELL_FAILED_NOT_IN_ARENA = 150, +    SPELL_FAILED_NOT_ON_SHAPESHIFT = 151, +    SPELL_FAILED_NOT_ON_STEALTHED = 152, +    SPELL_FAILED_NOT_ON_DAMAGE_IMMUNE = 153, +    SPELL_FAILED_NOT_ON_MOUNTED = 154, +    SPELL_FAILED_TOO_SHALLOW = 155, +    SPELL_FAILED_TARGET_NOT_IN_SANCTUARY = 156, +    SPELL_FAILED_TARGET_IS_TRIVIAL = 157, +    SPELL_FAILED_BM_OR_INVISGOD = 158, +    SPELL_FAILED_EXPERT_RIDING_REQUIREMENT = 159, +    SPELL_FAILED_ARTISAN_RIDING_REQUIREMENT = 160, +    SPELL_FAILED_NOT_IDLE = 161, +    SPELL_FAILED_NOT_INACTIVE = 162, +    SPELL_FAILED_PARTIAL_PLAYTIME = 163, +    SPELL_FAILED_NO_PLAYTIME = 164, +    SPELL_FAILED_NOT_IN_BATTLEGROUND = 165, +    SPELL_FAILED_NOT_IN_RAID_INSTANCE = 166, +    SPELL_FAILED_ONLY_IN_ARENA = 167, +    SPELL_FAILED_TARGET_LOCKED_TO_RAID_INSTANCE = 168, +    SPELL_FAILED_ON_USE_ENCHANT = 169, +    SPELL_FAILED_NOT_ON_GROUND = 170, +    SPELL_FAILED_CUSTOM_ERROR = 171, +    SPELL_FAILED_CANT_DO_THAT_RIGHT_NOW = 172, +    SPELL_FAILED_TOO_MANY_SOCKETS = 173, +    SPELL_FAILED_INVALID_GLYPH = 174, +    SPELL_FAILED_UNIQUE_GLYPH = 175, +    SPELL_FAILED_GLYPH_SOCKET_LOCKED = 176, +    SPELL_FAILED_NO_VALID_TARGETS = 177, +    SPELL_FAILED_ITEM_AT_MAX_CHARGES = 178, +    SPELL_FAILED_NOT_IN_BARBERSHOP = 179, +    SPELL_FAILED_FISHING_TOO_LOW = 180, +    SPELL_FAILED_UNKNOWN = 181  };  enum SpellFamilyNames @@ -223,8 +239,12 @@ enum SpellFamilyNames      SPELLFAMILY_HUNTER      = 9,      SPELLFAMILY_PALADIN     = 10,      SPELLFAMILY_SHAMAN      = 11, -    SPELLFAMILY_UNK2        = 12, -    SPELLFAMILY_POTION      = 13 +    SPELLFAMILY_UNK2        = 12,                           // 2 spells (silence resistance) +    SPELLFAMILY_POTION      = 13, +    // 14 - unused +    SPELLFAMILY_DEATHKNIGHT = 15, +    // 16 - unused +    SPELLFAMILY_PET         = 17  };  enum SpellDisableTypes @@ -375,6 +395,7 @@ inline bool IsAreaOfEffectSpell(SpellEntry const *spellInfo)  inline bool IsAreaAuraEffect(uint32 effect)  {      if( effect == SPELL_EFFECT_APPLY_AREA_AURA_PARTY    || +        effect == SPELL_EFFECT_APPLY_AREA_AURA_RAID     ||          effect == SPELL_EFFECT_APPLY_AREA_AURA_FRIEND   ||          effect == SPELL_EFFECT_APPLY_AREA_AURA_ENEMY    ||          effect == SPELL_EFFECT_APPLY_AREA_AURA_PET      || @@ -447,7 +468,11 @@ bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group);  DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group);  // Spell affects related declarations (accessed using SpellMgr functions) -typedef std::map<uint32, uint64> SpellAffectMap; +struct SpellAffectEntry +{ +    uint32 SpellClassMask[3]; +}; +typedef UNORDERED_MAP<uint32, SpellAffectEntry> SpellAffectMap;  // Spell proc event related declarations (accessed using SpellMgr functions)  enum ProcFlags @@ -457,14 +482,14 @@ enum ProcFlags     PROC_FLAG_KILLED                        = 0x00000001,    // 00 Killed by agressor     PROC_FLAG_KILL_AND_GET_XP               = 0x00000002,    // 01 Kill that yields experience or honor -   PROC_FLAG_SUCCESSFUL_MILEE_HIT          = 0x00000004,    // 02 Successful melee attack -   PROC_FLAG_TAKEN_MELEE_HIT               = 0x00000008,    // 03 Taken damage from melee strike hit +   PROC_FLAG_SUCCESSFUL_MILEE_HIT          = 0x00000004,    // 02 Successful melee auto attack +   PROC_FLAG_TAKEN_MELEE_HIT               = 0x00000008,    // 03 Taken damage from melee auto attack hit     PROC_FLAG_SUCCESSFUL_MELEE_SPELL_HIT    = 0x00000010,    // 04 Successful attack by Spell that use melee weapon     PROC_FLAG_TAKEN_MELEE_SPELL_HIT         = 0x00000020,    // 05 Taken damage by Spell that use melee weapon -   PROC_FLAG_SUCCESSFUL_RANGED_HIT         = 0x00000040,    // 06 Successful Ranged attack (all ranged attack deal as spell so newer set :( ) -   PROC_FLAG_TAKEN_RANGED_HIT              = 0x00000080,    // 07 Taken damage from ranged attack (all ranged attack deal as spell so newer set :( ) +   PROC_FLAG_SUCCESSFUL_RANGED_HIT         = 0x00000040,    // 06 Successful Ranged auto attack +   PROC_FLAG_TAKEN_RANGED_HIT              = 0x00000080,    // 07 Taken damage from ranged auto attack     PROC_FLAG_SUCCESSFUL_RANGED_SPELL_HIT   = 0x00000100,    // 08 Successful Ranged attack by Spell that use ranged weapon     PROC_FLAG_TAKEN_RANGED_SPELL_HIT        = 0x00000200,    // 09 Taken damage by Spell that use ranged weapon @@ -515,12 +540,12 @@ enum ProcFlagsEx     PROC_EX_DEFLECT             = 0x0000200,     PROC_EX_ABSORB              = 0x0000400,     PROC_EX_REFLECT             = 0x0000800, -   PROC_EX_INTERRUPT           = 0x0001000,                 // Melle hit result can be Interrupt (not used) +   PROC_EX_INTERRUPT           = 0x0001000,                 // Melee hit result can be Interrupt (not used)     PROC_EX_RESERVED1           = 0x0002000,     PROC_EX_RESERVED2           = 0x0004000,     PROC_EX_RESERVED3           = 0x0008000,     PROC_EX_EX_TRIGGER_ALWAYS   = 0x0010000,                 // If set trigger always ( no matter another flags) used for drop charges -   PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000                  // If set trigger always but only one time +   PROC_EX_EX_ONE_TIME_TRIGGER = 0x0020000                  // If set trigger always but only one time (not used)  };  struct SpellProcEventEntry @@ -665,6 +690,9 @@ typedef std::multimap<uint32, SpellLearnSpellNode> SpellLearnSpellMap;  typedef std::multimap<uint32, SkillLineAbilityEntry const*> SkillLineAbilityMap; +typedef std::map<uint32, uint32> PetLevelupSpellSet; +typedef std::map<uint32, PetLevelupSpellSet> PetLevelupSpellMap; +  inline bool IsPrimaryProfessionSkill(uint32 skill)  {      SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(skill); @@ -705,15 +733,15 @@ class SpellMgr          // Accessors (const or static functions)      public:          // Spell affects -        uint64 GetSpellAffectMask(uint16 spellId, uint8 effectId) const +        SpellAffectEntry const*GetSpellAffect(uint16 spellId, uint8 effectId) const          {              SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId);              if( itr != mSpellAffectMap.end( ) ) -                return itr->second; +                return &itr->second;              return 0;          } -        bool IsAffectedBySpell(SpellEntry const *spellInfo, uint32 spellId, uint8 effectId, uint64 familyFlags) const; +        bool IsAffectedByMod(SpellEntry const *spellInfo, SpellModifier *mod) const;          SpellElixirMap const& GetSpellElixirMap() const { return mSpellElixirs; } @@ -916,11 +944,6 @@ class SpellMgr                  return 0;              else                  return mSpellCustomAttr[spell_id]; -            /*SpellCustomAttrMap::const_iterator itr = mSpellCustomAttrMap.find(spell_id); -            if(itr != mSpellCustomAttrMap.end()) -                return itr->second; -            else -                return 0;*/          }          const std::vector<int32> *GetSpellLinked(int32 spell_id) const @@ -932,6 +955,15 @@ class SpellMgr          SpellEffectTargetTypes EffectTargetType[TOTAL_SPELL_EFFECTS];          SpellSelectTargetTypes SpellTargetType[TOTAL_SPELL_TARGETS]; +        PetLevelupSpellSet const* GetPetLevelupSpellList(uint32 petFamily) const +        { +            PetLevelupSpellMap::const_iterator itr = mPetLevelupSpellMap.find(petFamily); +            if(itr != mPetLevelupSpellMap.end()) +                return &itr->second; +            else +                return NULL; +        } +          // Modifiers      public:          static SpellMgr& Instance(); @@ -951,6 +983,7 @@ class SpellMgr          void LoadSpellPetAuras();          void LoadSpellCustomAttr();          void LoadSpellLinked(); +        void LoadPetLevelupSpellMap();      private:          SpellScriptTarget  mSpellScriptTarget; @@ -967,6 +1000,7 @@ class SpellMgr          SpellPetAuraMap     mSpellPetAuraMap;          SpellCustomAttribute  mSpellCustomAttr;          SpellLinkedMap      mSpellLinkedMap; +        PetLevelupSpellMap mPetLevelupSpellMap;  };  #define spellmgr SpellMgr::Instance() diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp index dd324fbc684..43faf9b3654 100644 --- a/src/game/StatSystem.cpp +++ b/src/game/StatSystem.cpp @@ -51,24 +51,17 @@ bool Player::UpdateStats(Stats stat)      switch(stat)      {          case STAT_STRENGTH: -            UpdateAttackPowerAndDamage();              UpdateShieldBlockValue();              break;          case STAT_AGILITY:              UpdateArmor(); -            UpdateAttackPowerAndDamage(true); -            if(getClass() == CLASS_ROGUE || getClass() == CLASS_HUNTER || getClass() == CLASS_DRUID && m_form==FORM_CAT) -                UpdateAttackPowerAndDamage(); -              UpdateAllCritPercentages();              UpdateDodgePercentage();              break; -          case STAT_STAMINA:   UpdateMaxHealth(); break;          case STAT_INTELLECT:              UpdateMaxPower(POWER_MANA);              UpdateAllSpellCritChances(); -            UpdateAttackPowerAndDamage(true);               //SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT, only intellect currently              UpdateArmor();                                  //SPELL_AURA_MOD_RESISTANCE_OF_INTELLECT_PERCENT, only armor currently              break; @@ -78,8 +71,25 @@ bool Player::UpdateStats(Stats stat)          default:              break;      } +    // Need update (exist AP from stat auras) +    UpdateAttackPowerAndDamage(); +    UpdateAttackPowerAndDamage(true); +      UpdateSpellDamageAndHealingBonus();      UpdateManaRegen(); + +    // Update ratings in exist SPELL_AURA_MOD_RATING_FROM_STAT and only depends from stat +    uint32 mask = 0; +    AuraList const& modRatingFromStat = GetAurasByType(SPELL_AURA_MOD_RATING_FROM_STAT); +    for(AuraList::const_iterator i = modRatingFromStat.begin();i != modRatingFromStat.end(); ++i) +        if (Stats((*i)->GetMiscBValue()) == stat) +            mask |= (*i)->GetMiscValue(); +    if (mask) +    { +        for (uint32 rating = 0; rating < MAX_COMBAT_RATING; ++rating) +            if (mask & (1 << rating)) +                ApplyRatingMod(CombatRating(rating), 0, true); +    }      return true;  } @@ -255,6 +265,7 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )          {              case CLASS_WARRIOR: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f                    - 20.0f; break;              case CLASS_PALADIN: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f                    - 20.0f; break; +            case CLASS_DEATH_KNIGHT: val2 = level*3.0f + GetStat(STAT_STRENGTH)*2.0f                    - 20.0f; break;              case CLASS_ROGUE:   val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;              case CLASS_HUNTER:  val2 = level*2.0f + GetStat(STAT_STRENGTH) + GetStat(STAT_AGILITY) - 20.0f; break;              case CLASS_SHAMAN:  val2 = level*2.0f + GetStat(STAT_STRENGTH)*2.0f                    - 20.0f; break; @@ -309,11 +320,20 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )      float attPowerMod = GetModifierValue(unitMod, TOTAL_VALUE);      //add dynamic flat mods -    if( ranged && (getClassMask() & CLASSMASK_WAND_USERS)==0) +    if ((getClassMask() & CLASSMASK_WAND_USERS)==0)      { -        AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); -        for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) -            attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifierValue() / 100.0f); +        if( ranged ) +        { +            AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_OF_STAT_PERCENT); +            for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) +                attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); +        } +        else +        { +            AuraList const& mRAPbyIntellect = GetAurasByType(SPELL_AURA_MOD_ATTACK_POWER_OF_STAT_PERCENT); +            for(AuraList::const_iterator i = mRAPbyIntellect.begin();i != mRAPbyIntellect.end(); ++i) +                attPowerMod += int32(GetStat(Stats((*i)->GetModifier()->m_miscvalue)) * (*i)->GetModifier()->m_amount / 100.0f); +        }      }      float attPowerMultiplier = GetModifierValue(unitMod, TOTAL_PCT) - 1.0f; @@ -554,6 +574,24 @@ void Player::UpdateSpellCritChance(uint32 school)      SetFloatValue(PLAYER_SPELL_CRIT_PERCENTAGE1 + school, crit);  } +void Player::UpdateMeleeHitChances() +{ +    m_modMeleeHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); +    m_modMeleeHitChance+=  GetRatingBonusValue(CR_HIT_MELEE); +} + +void Player::UpdateRangedHitChances() +{ +    m_modRangedHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_HIT_CHANCE); +    m_modRangedHitChance+= GetRatingBonusValue(CR_HIT_RANGED); +} + +void Player::UpdateSpellHitChances() +{ +    m_modSpellHitChance = GetTotalAuraModifier(SPELL_AURA_MOD_SPELL_HIT_CHANCE); +    m_modSpellHitChance+= GetRatingBonusValue(CR_HIT_SPELL); +} +  void Player::UpdateAllSpellCritChances()  {      for (int i = SPELL_SCHOOL_NORMAL; i < MAX_SPELL_SCHOOL; i++) @@ -624,9 +662,9 @@ void Player::UpdateManaRegen()      int32 modManaRegenInterrupt = GetTotalAuraModifier(SPELL_AURA_MOD_MANA_REGEN_INTERRUPT);      if (modManaRegenInterrupt > 100)          modManaRegenInterrupt = 100; -    SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f); +    SetStatFloatValue(UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER, power_regen_mp5 + power_regen * modManaRegenInterrupt / 100.0f); -    SetStatFloatValue(PLAYER_FIELD_MOD_MANA_REGEN, power_regen_mp5 + power_regen); +    SetStatFloatValue(UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER, power_regen_mp5 + power_regen);  }  void Player::_ApplyAllStatBonuses() @@ -923,7 +961,7 @@ void Pet::UpdateAttackPowerAndDamage(bool ranged)          if(getPetType() == HUNTER_PET)                      //hunter pets benefit from owner's attack power          {              bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f; -            SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.125f)); +            SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f));          }          //demons benefit from warlocks shadow or fire damage          else if(getPetType() == SUMMON_PET && owner->getClass() == CLASS_WARLOCK) diff --git a/src/game/TaxiHandler.cpp b/src/game/TaxiHandler.cpp index 640618eaebb..fa649e20f6e 100644 --- a/src/game/TaxiHandler.cpp +++ b/src/game/TaxiHandler.cpp @@ -71,7 +71,7 @@ void WorldSession::SendTaxiStatus( uint64 guid )      sLog.outDebug( "WORLD: Sent SMSG_TAXINODE_STATUS" );  } -void WorldSession::HandleTaxiQueryAvailableNodesOpcode( WorldPacket & recv_data ) +void WorldSession::HandleTaxiQueryAvailableNodes( WorldPacket & recv_data )  {      CHECK_PACKET_SIZE(recv_data,8); diff --git a/src/game/Transports.cpp b/src/game/Transports.cpp index 21d3d3b1f27..be71fcc3f98 100644 --- a/src/game/Transports.cpp +++ b/src/game/Transports.cpp @@ -137,7 +137,7 @@ void MapManager::LoadTransports()  Transport::Transport() : GameObject()  {                                                              // 2.3.2 - 0x5A -    m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION); +    m_updateFlag = (UPDATEFLAG_TRANSPORT | UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION);  }  bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, float ang, uint32 animprogress, uint32 dynflags) @@ -168,9 +168,10 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,      SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size);      SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); -    SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); - -    SetUInt32Value(OBJECT_FIELD_ENTRY, goinfo->id); +    //SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); +    SetUInt32Value(GAMEOBJECT_FLAGS, MAKE_PAIR32(0x28, 0x64)); +    SetUInt32Value(GAMEOBJECT_LEVEL, m_period); +    SetEntry(goinfo->id);      SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); @@ -179,7 +180,7 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,      SetGoAnimProgress(animprogress);      if(dynflags) -        SetUInt32Value(GAMEOBJECT_DYN_FLAGS, dynflags); +        SetUInt32Value(GAMEOBJECT_DYNAMIC, MAKE_PAIR32(0, dynflags));      return true;  } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 1fed4717db6..289bfb963ad 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -60,74 +60,17 @@ float baseMoveSpeed[MAX_MOVE_TYPE] =      3.141594f,                                              // MOVE_TURN_RATE      7.0f,                                                   // MOVE_FLIGHT      4.5f,                                                   // MOVE_FLIGHT_BACK +    3.14f                                                   // MOVE_PITCH_RATE  }; -void InitTriggerAuraData(); - -// auraTypes contains attacker auras capable of proc'ing cast auras -static Unit::AuraTypeSet GenerateAttakerProcCastAuraTypes() -{ -    static Unit::AuraTypeSet auraTypes; -    auraTypes.insert(SPELL_AURA_DUMMY); -    auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL); -    auraTypes.insert(SPELL_AURA_MOD_HASTE); -    auraTypes.insert(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); -    return auraTypes; -} - -// auraTypes contains victim auras capable of proc'ing cast auras -static Unit::AuraTypeSet GenerateVictimProcCastAuraTypes() -{ -    static Unit::AuraTypeSet auraTypes; -    auraTypes.insert(SPELL_AURA_DUMMY); -    auraTypes.insert(SPELL_AURA_PRAYER_OF_MENDING); -    auraTypes.insert(SPELL_AURA_PROC_TRIGGER_SPELL); -    return auraTypes; -} - -// auraTypes contains auras capable of proc effect/damage (but not cast) for attacker -static Unit::AuraTypeSet GenerateAttakerProcEffectAuraTypes() -{ -    static Unit::AuraTypeSet auraTypes; -    auraTypes.insert(SPELL_AURA_MOD_DAMAGE_DONE); -    auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE); -    auraTypes.insert(SPELL_AURA_MOD_CASTING_SPEED); -    auraTypes.insert(SPELL_AURA_MOD_RATING); -    return auraTypes; -} - -// auraTypes contains auras capable of proc effect/damage (but not cast) for victim -static Unit::AuraTypeSet GenerateVictimProcEffectAuraTypes() -{ -    static Unit::AuraTypeSet auraTypes; -    auraTypes.insert(SPELL_AURA_MOD_RESISTANCE); -    auraTypes.insert(SPELL_AURA_PROC_TRIGGER_DAMAGE); -    auraTypes.insert(SPELL_AURA_MOD_PARRY_PERCENT); -    auraTypes.insert(SPELL_AURA_MOD_BLOCK_PERCENT); -    auraTypes.insert(SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN); -    return auraTypes; -} - -static Unit::AuraTypeSet attackerProcCastAuraTypes = GenerateAttakerProcCastAuraTypes(); -static Unit::AuraTypeSet attackerProcEffectAuraTypes = GenerateAttakerProcEffectAuraTypes(); - -static Unit::AuraTypeSet victimProcCastAuraTypes = GenerateVictimProcCastAuraTypes(); -static Unit::AuraTypeSet victimProcEffectAuraTypes   = GenerateVictimProcEffectAuraTypes(); - -// auraTypes contains auras capable of proc'ing for attacker and victim -static Unit::AuraTypeSet GenerateProcAuraTypes() -{ -    InitTriggerAuraData(); - -    Unit::AuraTypeSet auraTypes; -    auraTypes.insert(attackerProcCastAuraTypes.begin(),attackerProcCastAuraTypes.end()); -    auraTypes.insert(attackerProcEffectAuraTypes.begin(),attackerProcEffectAuraTypes.end()); -    auraTypes.insert(victimProcCastAuraTypes.begin(),victimProcCastAuraTypes.end()); -    auraTypes.insert(victimProcEffectAuraTypes.begin(),victimProcEffectAuraTypes.end()); -    return auraTypes; -} - -static Unit::AuraTypeSet procAuraTypes = GenerateProcAuraTypes(); +// Used for prepare can/can`t triggr aura +static bool InitTriggerAuraData(); +// Define can trigger auras +static bool isTriggerAura[TOTAL_AURAS]; +// Define can`t trigger auras (need for disable second trigger) +static bool isNonTriggerAura[TOTAL_AURAS]; +// Prepare lists +static bool procPrepared = InitTriggerAuraData();  bool IsPassiveStackableSpell( uint32 spellId )  { @@ -137,12 +80,8 @@ bool IsPassiveStackableSpell( uint32 spellId )      SpellEntry const* spellProto = sSpellStore.LookupEntry(spellId);      if(!spellProto)          return false; - -    for(int j = 0; j < 3; ++j) -    { -        if(std::find(procAuraTypes.begin(),procAuraTypes.end(),spellProto->EffectApplyAuraName[j])!=procAuraTypes.end()) -            return false; -    } +    if (spellProto->procFlags) +        return false;      return true;  } @@ -154,7 +93,7 @@ Unit::Unit()      m_objectType |= TYPEMASK_UNIT;      m_objectTypeId = TYPEID_UNIT;                                                              // 2.3.2 - 0x70 -    m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HASPOSITION); +    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION);      m_attackTimer[BASE_ATTACK]   = 0;      m_attackTimer[OFF_ATTACK]    = 0; @@ -721,6 +660,169 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa      {          DEBUG_LOG("DealDamage: victim just died");          Kill(pVictim, durabilityLoss); + +        /*// find player: owner of controlled `this` or `this` itself maybe +        Player *player = GetCharmerOrOwnerPlayerOrPlayerItself(); + +        if(pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->GetLootRecipient()) +            player = ((Creature*)pVictim)->GetLootRecipient(); +        // Reward player, his pets, and group/raid members +        // call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop) +        if(player && player!=pVictim) +        { +            if(player->RewardPlayerAndGroupAtKill(pVictim)) +                player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL_AND_GET_XP, PROC_FLAG_KILLED, PROC_EX_NONE, 0); +            else +                player->ProcDamageAndSpell(pVictim, PROC_FLAG_NONE, PROC_FLAG_KILLED,PROC_EX_NONE, 0); +        } + +        DEBUG_LOG("DealDamageAttackStop"); + +        // stop combat +        pVictim->CombatStop(); +        pVictim->getHostilRefManager().deleteReferences(); + +        bool damageFromSpiritOfRedemtionTalent = spellProto && spellProto->Id == 27795; + +        // if talent known but not triggered (check priest class for speedup check) +        Aura* spiritOfRedemtionTalentReady = NULL; +        if( !damageFromSpiritOfRedemtionTalent &&           // not called from SPELL_AURA_SPIRIT_OF_REDEMPTION +            pVictim->GetTypeId()==TYPEID_PLAYER && pVictim->getClass()==CLASS_PRIEST ) +        { +            AuraList const& vDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY); +            for(AuraList::const_iterator itr = vDummyAuras.begin(); itr != vDummyAuras.end(); ++itr) +            { +                if((*itr)->GetSpellProto()->SpellIconID==1654) +                { +                    spiritOfRedemtionTalentReady = *itr; +                    break; +                } +            } +        } + +        DEBUG_LOG("SET JUST_DIED"); +        if(!spiritOfRedemtionTalentReady) +            pVictim->setDeathState(JUST_DIED); + +        DEBUG_LOG("DealDamageHealth1"); + +        if(spiritOfRedemtionTalentReady) +        { +            // save value before aura remove +            uint32 ressSpellId = pVictim->GetUInt32Value(PLAYER_SELF_RES_SPELL); +            if(!ressSpellId) +                ressSpellId = ((Player*)pVictim)->GetResurrectionSpellId(); + +            //Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers) +            pVictim->RemoveAllAurasOnDeath(); + +            // restore for use at real death +            pVictim->SetUInt32Value(PLAYER_SELF_RES_SPELL,ressSpellId); + +            // FORM_SPIRITOFREDEMPTION and related auras +            pVictim->CastSpell(pVictim,27827,true,NULL,spiritOfRedemtionTalentReady); +        } +        else +            pVictim->SetHealth(0); + +        // remember victim PvP death for corpse type and corpse reclaim delay +        // at original death (not at SpiritOfRedemtionTalent timeout) +        if( pVictim->GetTypeId()==TYPEID_PLAYER && !damageFromSpiritOfRedemtionTalent ) +            ((Player*)pVictim)->SetPvPDeath(player!=NULL); + +        // Call KilledUnit for creatures +        if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI()) +            ((Creature*)this)->AI()->KilledUnit(pVictim); + +        // achievement stuff +        if ( pVictim->GetTypeId() == TYPEID_PLAYER) +        { +            if(GetTypeId() == TYPEID_UNIT) +                ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); +            else if(GetTypeId() == TYPEID_PLAYER) +                ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1); +        } + +        // 10% durability loss on death +        // clean InHateListOf +        if (pVictim->GetTypeId() == TYPEID_PLAYER) +        { +            // only if not player and not controlled by player pet. And not at BG +            if (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround()) +            { +                DEBUG_LOG("We are dead, loosing 10 percents durability"); +                ((Player*)pVictim)->DurabilityLossAll(0.10f,false); +                // durability lost message +                WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); +                ((Player*)pVictim)->GetSession()->SendPacket(&data); +            } +        } +        else                                                // creature died +        { +            DEBUG_LOG("DealDamageNotPlayer"); +            Creature *cVictim = (Creature*)pVictim; + +            if(!cVictim->isPet()) +            { +                cVictim->DeleteThreatList(); +                cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); +            } +            // Call creature just died function +            if (cVictim->AI()) +                cVictim->AI()->JustDied(this); + +            // Dungeon specific stuff, only applies to players killing creatures +            if(cVictim->GetInstanceId()) +            { +                Map *m = cVictim->GetMap(); +                Player *creditedPlayer = GetCharmerOrOwnerPlayerOrPlayerItself(); +                // TODO: do instance binding anyway if the charmer/owner is offline + +                if(m->IsDungeon() && creditedPlayer) +                { +                    if(m->IsRaid() || m->IsHeroic()) +                    { +                        if(cVictim->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) +                            ((InstanceMap *)m)->PermBindAllPlayers(creditedPlayer); +                    } +                    else +                    { +                        // the reset time is set but not added to the scheduler +                        // until the players leave the instance +                        time_t resettime = cVictim->GetRespawnTimeEx() + 2 * HOUR; +                        if(InstanceSave *save = sInstanceSaveManager.GetInstanceSave(cVictim->GetInstanceId())) +                            if(save->GetResetTime() < resettime) save->SetResetTime(resettime); +                    } +                } +            } +        } + +        // last damage from non duel opponent or opponent controlled creature +        if(duel_hasEnded) +        { +            assert(pVictim->GetTypeId()==TYPEID_PLAYER); +            Player *he = (Player*)pVictim; + +            assert(he->duel); + +            he->duel->opponent->CombatStopWithPets(true); +            he->CombatStopWithPets(true); + +            he->DuelComplete(DUEL_INTERUPTED); +        } + +        // battleground things (do this at the end, so the death state flag will be properly set to handle in the bg->handlekill) +        if(pVictim->GetTypeId() == TYPEID_PLAYER && ((Player*)pVictim)->InBattleGround()) +        { +            Player *killed = ((Player*)pVictim); +            if(BattleGround *bg = killed->GetBattleGround()) +                if(player) +                    bg->HandleKillPlayer(killed, player); +                //later we can add support for creature->player kills here i'm +                //not sure, but i guess those kills also get counted in av +                //else if(GetTypeId() == TYPEID_UNIT) +                //    bg->HandleKillPlayer(killed,(Creature*)this); +        }*/      }      else                                                    // if (health <= damage)      { @@ -751,7 +853,6 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa              //if (!spellProto || !(spellProto->AuraInterruptFlags&AURA_INTERRUPT_FLAG_DIRECT_DAMAGE))                  pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_DIRECT_DAMAGE, spellProto ? spellProto->Id : 0);          } -          if (pVictim->GetTypeId() != TYPEID_PLAYER)          {              if(spellProto && IsDamageToThreatSpell(spellProto)) @@ -1060,419 +1161,6 @@ void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castI      spell->prepare(&targets, triggeredByAura);  } -/* -void Unit::DealFlatDamage(Unit *pVictim, SpellEntry const *spellInfo, uint32 *damage, CleanDamage *cleanDamage, bool *crit, bool isTriggeredSpell) -{ -    // TODO this in only generic way, check for exceptions -    DEBUG_LOG("DealFlatDamage (BEFORE) >> DMG:%u", *damage); - -    // Per-damage class calculation -    switch (spellInfo->DmgClass) -    { -        // Melee and Ranged Spells -        case SPELL_DAMAGE_CLASS_RANGED: -        case SPELL_DAMAGE_CLASS_MELEE: -        { -            // Calculate physical outcome -            MeleeHitOutcome outcome = RollPhysicalOutcomeAgainst(pVictim, BASE_ATTACK, spellInfo); - -            //Used to store the Hit Outcome -            cleanDamage->hitOutCome = outcome; - -            // Return miss/evade first (sends miss message) -            switch(outcome) -            { -                case MELEE_HIT_EVADE: -                { -                    SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_EVADES,0); -                    *damage = 0; -                    return; -                } -                case MELEE_HIT_MISS: -                { -                    SendAttackStateUpdate(HITINFO_MISS, pVictim, 1, GetSpellSchoolMask(spellInfo), 0, 0,0,VICTIMSTATE_NORMAL,0); -                    *damage = 0; - -                    if(GetTypeId()== TYPEID_PLAYER) -                        ((Player*)this)->UpdateWeaponSkill(BASE_ATTACK); - -                    CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,MELEE_HIT_MISS,spellInfo,isTriggeredSpell); -                    return; -                } -            } - -            //  Hitinfo, Victimstate -            uint32 hitInfo = HITINFO_NORMALSWING; -            VictimState victimState = VICTIMSTATE_NORMAL; - -            // Physical Damage -            if ( GetSpellSchoolMask(spellInfo) & SPELL_SCHOOL_MASK_NORMAL ) -            { -                // apply spellmod to Done damage -                if(Player* modOwner = GetSpellModOwner()) -                    modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_DAMAGE, *damage); - -                //Calculate armor mitigation -                uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage); - -                // random durability for main hand weapon (ABSORB) -                if(damageAfterArmor < *damage) -                    if(pVictim->GetTypeId() == TYPEID_PLAYER) -                        if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB))) -                            ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK))); - -                cleanDamage->damage += *damage - damageAfterArmor; -                *damage = damageAfterArmor; -            } -            // Magical Damage -            else -            { -                // Calculate damage bonus -                *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE); -            } - -            // Classify outcome -            switch (outcome) -            { -                case MELEE_HIT_BLOCK_CRIT: -                case MELEE_HIT_CRIT: -                { -                    uint32 bonusDmg = *damage; - -                    // Apply crit_damage bonus -                    if(Player* modOwner = GetSpellModOwner()) -                        modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, bonusDmg); - -                    uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); -                    AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS); -                    for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) -                        if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) -                            bonusDmg = uint32(bonusDmg * ((*i)->GetModifierValue()+100.0f)/100.0f); - -                    *damage += bonusDmg; - -                    // Resilience - reduce crit damage -                    if (pVictim->GetTypeId()==TYPEID_PLAYER) -                    { -                        uint32 resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage); -                        cleanDamage->damage += resilienceReduction; -                        *damage -=  resilienceReduction; -                    } - -                    *crit = true; -                    hitInfo |= HITINFO_CRITICALHIT; - -                    ModifyAuraState(AURA_STATE_CRIT, true); -                    StartReactiveTimer( REACTIVE_CRIT ); - -                    if(getClass()==CLASS_HUNTER) -                    { -                        ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true); -                        StartReactiveTimer( REACTIVE_HUNTER_CRIT ); -                    } - -                    if ( outcome == MELEE_HIT_BLOCK_CRIT ) -                    { -                        uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue()); -                        if (blocked_amount >= *damage) -                        { -                            hitInfo |= HITINFO_SWINGNOHITSOUND; -                            victimState = VICTIMSTATE_BLOCKS; -                            cleanDamage->damage += *damage; // To Help Calculate Rage -                            *damage = 0; -                        } -                        else -                        { -                            // To Help Calculate Rage -                            cleanDamage->damage += blocked_amount; -                            *damage = *damage - blocked_amount; -                        } - -                        pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); -                        pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); - -                        if(pVictim->GetTypeId() == TYPEID_PLAYER) -                        { -                            // Update defense -                            ((Player*)pVictim)->UpdateDefense(); - -                            // random durability for main hand weapon (BLOCK) -                            if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) -                                ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); -                        } -                    } -                    break; -                } -                case MELEE_HIT_PARRY: -                { -                    cleanDamage->damage += *damage;         // To Help Calculate Rage -                    *damage = 0; -                    victimState = VICTIMSTATE_PARRY; - -                    // Counter-attack ( explained in Unit::DoAttackDamage() ) -                    if(pVictim->GetTypeId()==TYPEID_PLAYER || !(((Creature*)pVictim)->GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN) ) -                    { -                        // Get attack timers -                        float offtime  = float(pVictim->getAttackTimer(OFF_ATTACK)); -                        float basetime = float(pVictim->getAttackTimer(BASE_ATTACK)); - -                        // Reduce attack time -                        if (pVictim->haveOffhandWeapon() && offtime < basetime) -                        { -                            float percent20 = pVictim->GetAttackTime(OFF_ATTACK) * 0.20; -                            float percent60 = 3 * percent20; -                            if(offtime > percent20 && offtime <= percent60) -                            { -                                pVictim->setAttackTimer(OFF_ATTACK, uint32(percent20)); -                            } -                            else if(offtime > percent60) -                            { -                                offtime -= 2 * percent20; -                                pVictim->setAttackTimer(OFF_ATTACK, uint32(offtime)); -                            } -                        } -                        else -                        { -                            float percent20 = pVictim->GetAttackTime(BASE_ATTACK) * 0.20; -                            float percent60 = 3 * percent20; -                            if(basetime > percent20 && basetime <= percent60) -                            { -                                pVictim->setAttackTimer(BASE_ATTACK, uint32(percent20)); -                            } -                            else if(basetime > percent60) -                            { -                                basetime -= 2 * percent20; -                                pVictim->setAttackTimer(BASE_ATTACK, uint32(basetime)); -                            } -                        } -                    } - -                    if(pVictim->GetTypeId() == TYPEID_PLAYER) -                    { -                        // Update victim defense ? -                        ((Player*)pVictim)->UpdateDefense(); - -                        // random durability for main hand weapon (PARRY) -                        if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY))) -                            ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND); -                    } - -                    // Set parry flags -                    pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); - -                    // Mongoose bite - set only Counterattack here -                    if (pVictim->getClass() == CLASS_HUNTER) -                    { -                        pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true); -                        pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY ); -                    } -                    else -                    { -                        pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); -                        pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); -                    } -                    break; -                } -                case MELEE_HIT_DODGE: -                { -                    if(pVictim->GetTypeId() == TYPEID_PLAYER) -                        ((Player*)pVictim)->UpdateDefense(); - -                    cleanDamage->damage += *damage;         // To Help Calculate Rage -                    *damage = 0; -                    hitInfo |= HITINFO_SWINGNOHITSOUND; -                    victimState = VICTIMSTATE_DODGE; - -                    // Set dodge flags -                    pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); - -                    // Overpower -                    if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) -                    { -                        ((Player*)this)->AddComboPoints(pVictim, 1); -                        StartReactiveTimer( REACTIVE_OVERPOWER ); -                    } - -                    // Riposte -                    if (pVictim->getClass() != CLASS_ROGUE) -                    { -                        pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); -                        pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); -                    } -                    break; -                } -                case MELEE_HIT_BLOCK: -                { -                    uint32 blocked_amount = uint32(pVictim->GetShieldBlockValue()); -                    if (blocked_amount >= *damage) -                    { -                        hitInfo |= HITINFO_SWINGNOHITSOUND; -                        victimState = VICTIMSTATE_BLOCKS; -                        cleanDamage->damage += *damage;     // To Help Calculate Rage -                        *damage = 0; -                    } -                    else -                    { -                        // To Help Calculate Rage -                        cleanDamage->damage += blocked_amount; -                        *damage = *damage - blocked_amount; -                    } - -                    pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); -                    pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); - -                    if(pVictim->GetTypeId() == TYPEID_PLAYER) -                    { -                        // Update defense -                        ((Player*)pVictim)->UpdateDefense(); - -                        // random durability for main hand weapon (BLOCK) -                        if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) -                            ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); -                    } -                    break; -                } -                case MELEE_HIT_EVADE:                       // already processed early -                case MELEE_HIT_MISS:                        // already processed early -                case MELEE_HIT_GLANCING: -                case MELEE_HIT_CRUSHING: -                case MELEE_HIT_NORMAL: -                    break; -            } - -            // do all damage=0 cases here -            if(*damage == 0) -                CastMeleeProcDamageAndSpell(pVictim,0,GetSpellSchoolMask(spellInfo),BASE_ATTACK,outcome,spellInfo,isTriggeredSpell); - -            break; -        } -        // Magical Attacks -        case SPELL_DAMAGE_CLASS_NONE: -        case SPELL_DAMAGE_CLASS_MAGIC: -        { -            // Calculate damage bonus -            *damage = SpellDamageBonus(pVictim, spellInfo, *damage, SPELL_DIRECT_DAMAGE); - -            *crit = isSpellCrit(pVictim, spellInfo, GetSpellSchoolMask(spellInfo), BASE_ATTACK); -            if (*crit) -            { -                *damage = SpellCriticalBonus(spellInfo, *damage, pVictim); - -                // Resilience - reduce crit damage -                if (pVictim && pVictim->GetTypeId()==TYPEID_PLAYER) -                { -                    uint32 damage_reduction = ((Player *)pVictim)->GetSpellCritDamageReduction(*damage); -                    if(*damage > damage_reduction) -                        *damage -= damage_reduction; -                    else -                        *damage = 0; -                } - -                cleanDamage->hitOutCome = MELEE_HIT_CRIT; -            } -            // spell proc all magic damage==0 case in this function -            if(*damage == 0) -            { -                // Procflags -                uint32 procAttacker = PROC_FLAG_HIT_SPELL; -                uint32 procVictim   = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE); - -                ProcDamageAndSpell(pVictim, procAttacker, procVictim, 0, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell); -            } - -            break; -        } -    } - -    // TODO this in only generic way, check for exceptions -    DEBUG_LOG("DealFlatDamage (AFTER) >> DMG:%u", *damage); -} - -uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage) -{ -    if(!this || !pVictim) -        return 0; -    if(!isAlive() || !pVictim->isAlive()) -        return 0; - -    SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); -    if(!spellInfo) -        return 0; - -    CleanDamage cleanDamage = CleanDamage(0, BASE_ATTACK, MELEE_HIT_NORMAL); -    bool crit = false; - -    if (useSpellDamage) -        DealFlatDamage(pVictim, spellInfo, &damage, &cleanDamage, &crit, isTriggeredSpell); - -    // If we actually dealt some damage (spell proc's for 0 damage (normal and magic) called in DealFlatDamage) -    if(damage > 0) -    { -        // Calculate absorb & resists -        uint32 absorb = 0; -        uint32 resist = 0; - -        CalcAbsorbResist(pVictim,GetSpellSchoolMask(spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist); - -        //No more damage left, target absorbed and/or resisted all damage -        if (damage > absorb + resist) -            damage -= absorb + resist;      //Remove Absorbed and Resisted from damage actually dealt -        else -        { -            uint32 HitInfo = HITINFO_SWINGNOHITSOUND; - -            if (absorb) -                HitInfo |= HITINFO_ABSORB; -            if (resist) -            { -                HitInfo |= HITINFO_RESIST; -                ProcDamageAndSpell(pVictim, PROC_FLAG_TARGET_RESISTS, PROC_FLAG_RESIST_SPELL, 0, GetSpellSchoolMask(spellInfo), spellInfo,isTriggeredSpell); -            } - -            //Send resist -            SendAttackStateUpdate(HitInfo, pVictim, 1, GetSpellSchoolMask(spellInfo), damage, absorb,resist,VICTIMSTATE_NORMAL,0); -            return 0; -        } - -        // Deal damage done -        damage = DealDamage(pVictim, damage, &cleanDamage, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellInfo), spellInfo, true); - -        // Send damage log -        sLog.outDetail("SpellNonMeleeDamageLog: %u (TypeId: %u) attacked %u (TypeId: %u) for %u dmg inflicted by %u,absorb is %u,resist is %u", -            GetGUIDLow(), GetTypeId(), pVictim->GetGUIDLow(), pVictim->GetTypeId(), damage, spellID, absorb,resist); - -        // Actual log sent to client -        SendSpellNonMeleeDamageLog(pVictim, spellID, damage + resist, GetSpellSchoolMask(spellInfo), absorb, resist, false, 0, crit); - -        // Procflags -        uint32 procAttacker = PROC_FLAG_HIT_SPELL; -        uint32 procVictim   = (PROC_FLAG_STRUCK_SPELL|PROC_FLAG_TAKE_DAMAGE); - -        if (crit) -        { -            procAttacker |= PROC_FLAG_CRIT_SPELL; -            procVictim   |= PROC_FLAG_STRUCK_CRIT_SPELL; -        } - -        ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, GetSpellSchoolMask(spellInfo), spellInfo, isTriggeredSpell); - -        return damage; -    } -    else -    { -        // all spell proc for 0 normal and magic damage called in DealFlatDamage - -        //Check for rage -        if(cleanDamage.damage) -            // Rage from damage received. -            if(pVictim->GetTypeId() == TYPEID_PLAYER && (pVictim->getPowerType() == POWER_RAGE)) -                ((Player*)pVictim)->RewardRage(cleanDamage.damage, 0, false); - -        return 0; -    } -} -*/ -  // Obsolete func need remove, here only for comotability vs another patches  uint32 Unit::SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage, bool isTriggeredSpell, bool useSpellDamage)  { @@ -1631,7 +1319,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage *damageInfo, bool durabilityLoss)              if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))              {                  (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); -                (*itr).second->UpdateAuraDuration(); +                (*itr).second->SendAuraUpdate(false);              }          }      } @@ -1790,6 +1478,7 @@ void Unit::CalculateMeleeDamage(Unit *pVictim, uint32 damage, CalcDamageInfo *da          case MELEE_HIT_BLOCK:          {              damageInfo->TargetState = VICTIMSTATE_NORMAL; +            damageInfo->HitInfo |= HITINFO_BLOCK;              damageInfo->procEx|=PROC_EX_BLOCK;              damageInfo->blocked_amount = damageInfo->target->GetShieldBlockValue();              if (damageInfo->blocked_amount >= damageInfo->damage) @@ -1947,7 +1636,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)              if( spellInfo->AttributesEx3 & 0x40000 && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && ((*itr).second->GetCasterGUID() == GetGUID()))              {                  (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); -                (*itr).second->UpdateAuraDuration(); +                (*itr).second->SendAuraUpdate(false);              }          }      } @@ -1981,11 +1670,13 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)                 //CalcAbsorbResist(pVictim, SpellSchools(spellProto->School), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist);                 //damage-=absorb + resist; -               WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4)); +               WorldPacket data(SMSG_SPELLDAMAGESHIELD,(8+8+4+4+4+4));                 data << uint64(pVictim->GetGUID());                 data << uint64(GetGUID()); +               data << uint32(spellProto->Id); +               data << uint32(damage);                  // Damage +               data << uint32(0);                       // Overkill                 data << uint32(spellProto->SchoolMask); -               data << uint32(damage);                 pVictim->SendMessageToSet(&data, true );                 pVictim->DealDamage(this, damage, 0, SPELL_DIRECT_DAMAGE, GetSpellSchoolMask(spellProto), spellProto, true); @@ -2004,9 +1695,8 @@ void Unit::DealMeleeDamage(CalcDamageInfo *damageInfo, bool durabilityLoss)  void Unit::HandleEmoteCommand(uint32 anim_id)  {      WorldPacket data( SMSG_EMOTE, 12 ); -    data << anim_id << GetGUID(); -    WPAssert(data.size() == 12); - +    data << uint32(anim_id); +    data << uint64(GetGUID());      SendMessageToSet(&data, true);  } @@ -2017,15 +1707,18 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage)      // Ignore enemy armor by SPELL_AURA_MOD_TARGET_RESISTANCE aura      armor += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_TARGET_RESISTANCE, SPELL_SCHOOL_MASK_NORMAL); -    if (armor<0.0f) armor=0.0f; +    // Apply Player CR_ARMOR_PENETRATION rating +    if (GetTypeId()==TYPEID_PLAYER) +        armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f; -    float tmpvalue = 0.0f; -    if(getLevel() <= 59)                                    //Level 1-59 -        tmpvalue = armor / (armor + 400.0f + 85.0f * getLevel()); -    else if(getLevel() < 70)                                //Level 60-69 -        tmpvalue = armor / (armor - 22167.5f + 467.5f * getLevel()); -    else                                                    //Level 70+ -        tmpvalue = armor / (armor + 10557.5f); +    if (armor < 0.0f) armor=0.0f; + +    float levelModifier = getLevel(); +    if ( levelModifier > 59 ) +        levelModifier = levelModifier + (4.5f * (levelModifier-59)); + +    float tmpvalue = 0.1f * armor / (8.5f * levelModifier + 40); +    tmpvalue = tmpvalue/(1.0f + tmpvalue);      if(tmpvalue < 0.0f)          tmpvalue = 0.0f; @@ -2112,7 +1805,7 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe          int32 currentAbsorb; -        //Reflective Shield +        // Reflective Shield          if ((pVictim != this) && (*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && (*i)->GetSpellProto()->SpellFamilyFlags == 0x1)          {              if(Unit* caster = (*i)->GetCaster()) @@ -2258,407 +1951,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe      *absorb = damage - RemainingDamage - *resist;  } -/* -void Unit::DoAttackDamage (Unit *pVictim, uint32 *damage, CleanDamage *cleanDamage, uint32 *blocked_amount, SpellSchoolMask damageSchoolMask, uint32 *hitInfo, VictimState *victimState, uint32 *absorbDamage, uint32 *resistDamage, WeaponAttackType attType, SpellEntry const *spellCasted, bool isTriggeredSpell) -{ -    MeleeHitOutcome outcome; - -    // If is casted Melee spell, calculate like physical -    if(!spellCasted) -        outcome = RollMeleeOutcomeAgainst (pVictim, attType); -    else -        outcome = RollPhysicalOutcomeAgainst (pVictim, attType, spellCasted); - -    if(outcome == MELEE_HIT_MISS ||outcome == MELEE_HIT_DODGE ||outcome == MELEE_HIT_BLOCK ||outcome == MELEE_HIT_PARRY) -        pVictim->AddThreat(this, 0.0f); -    switch(outcome) -    { -        case MELEE_HIT_EVADE: -        { -            *hitInfo |= HITINFO_MISS; -            *damage = 0; -            cleanDamage->damage = 0; -            return; -        } -        case MELEE_HIT_MISS: -        { -            *hitInfo |= HITINFO_MISS; -            *damage = 0; -            cleanDamage->damage = 0; -            if(GetTypeId()== TYPEID_PLAYER) -                ((Player*)this)->UpdateWeaponSkill(attType); -            return; -        } -    } - -    /// If this is a creature and it attacks from behind it has a probability to daze it's victim -    if( (outcome==MELEE_HIT_CRIT || outcome==MELEE_HIT_CRUSHING || outcome==MELEE_HIT_NORMAL || outcome==MELEE_HIT_GLANCING) && -        GetTypeId() != TYPEID_PLAYER && !((Creature*)this)->GetCharmerOrOwnerGUID() && !pVictim->HasInArc(M_PI, this) -        && pVictim->GetTypeId() == TYPEID_PLAYER) -    { -        // -probability is between 0% and 40% -        // 20% base chance -        float Probability = 20; - -        //there is a newbie protection, at level 10 just 7% base chance; assuming linear function -        if( pVictim->getLevel() < 30 ) -            Probability = 0.65f*pVictim->getLevel()+0.5; - -        uint32 VictimDefense=pVictim->GetDefenseSkillValue(this); -        uint32 AttackerMeleeSkill=GetUnitMeleeSkill(pVictim); - -        Probability *= AttackerMeleeSkill/(float)VictimDefense; - -        if(Probability > 40.0f) -            Probability = 40.0f; - -        if(roll_chance_f(Probability)) -            CastSpell(pVictim, 1604, true); -    } - -    //Calculate the damage after armor mitigation if SPELL_SCHOOL_NORMAL -    if (damageSchoolMask & SPELL_SCHOOL_MASK_NORMAL) -    { -        uint32 damageAfterArmor = CalcArmorReducedDamage(pVictim, *damage); - -        // random durability for main hand weapon (ABSORB) -        if(damageAfterArmor < *damage) -            if(pVictim->GetTypeId() == TYPEID_PLAYER) -                if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_ABSORB))) -                    ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EquipmentSlots(urand(EQUIPMENT_SLOT_START,EQUIPMENT_SLOT_BACK))); - -        cleanDamage->damage += *damage - damageAfterArmor; -        *damage = damageAfterArmor; -    } - -    if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER ) -        ((Player*)this)->UpdateCombatSkills(pVictim, attType, outcome, false); - -    if(GetTypeId() != TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) -        ((Player*)pVictim)->UpdateCombatSkills(this, attType, outcome, true); - -    switch (outcome) -    { -        case MELEE_HIT_BLOCK_CRIT: -        case MELEE_HIT_CRIT: -        { -            //*hitInfo = 0xEA; -            // 0xEA -            *hitInfo  = HITINFO_CRITICALHIT | HITINFO_NORMALSWING2 | 0x8; - -            // Crit bonus calc -            uint32 crit_bonus; -            crit_bonus = *damage; - -            // Apply crit_damage bonus for melee spells -            if (spellCasted) -            { -                if(Player* modOwner = GetSpellModOwner()) -                    modOwner->ApplySpellMod(spellCasted->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); - -                uint32 creatureTypeMask = pVictim->GetCreatureTypeMask(); -                AuraList const& mDamageDoneVersus = GetAurasByType(SPELL_AURA_MOD_CRIT_PERCENT_VERSUS); -                for(AuraList::const_iterator i = mDamageDoneVersus.begin();i != mDamageDoneVersus.end(); ++i) -                    if(creatureTypeMask & uint32((*i)->GetModifier()->m_miscvalue)) -                        crit_bonus = uint32(crit_bonus * ((*i)->GetModifierValue()+100.0f)/100.0f); -            } - -            *damage += crit_bonus; - -            uint32 resilienceReduction = 0; - -            if(attType == RANGED_ATTACK) -            { -                int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE); -                *damage = int32((*damage) * float((100.0f + mod)/100.0f)); -                // Resilience - reduce crit damage -                if (pVictim->GetTypeId()==TYPEID_PLAYER) -                    resilienceReduction = ((Player*)pVictim)->GetRangedCritDamageReduction(*damage); -            } -            else -            { -                int32 mod = pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE); -                mod += GetTotalAuraModifier(SPELL_AURA_MOD_CRIT_DAMAGE_BONUS_MELEE); -                *damage = int32((*damage) * float((100.0f + mod)/100.0f)); -                // Resilience - reduce crit damage -                if (pVictim->GetTypeId()==TYPEID_PLAYER) -                    resilienceReduction = ((Player*)pVictim)->GetMeleeCritDamageReduction(*damage); -            } - -            *damage -= resilienceReduction; -            cleanDamage->damage += resilienceReduction; - -            if(GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() != TYPEID_PLAYER && pVictim->GetCreatureType() != CREATURE_TYPE_CRITTER ) -                ((Player*)this)->UpdateWeaponSkill(attType); - -            ModifyAuraState(AURA_STATE_CRIT, true); -            StartReactiveTimer( REACTIVE_CRIT ); - -            if(getClass()==CLASS_HUNTER) -            { -                ModifyAuraState(AURA_STATE_HUNTER_CRIT_STRIKE, true); -                StartReactiveTimer( REACTIVE_HUNTER_CRIT ); -            } - -            if ( outcome == MELEE_HIT_BLOCK_CRIT ) -            { -                *blocked_amount = pVictim->GetShieldBlockValue(); - -                if (pVictim->GetUnitBlockChance()) -                    pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD); -                else -                    pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); - -                //Only set VICTIMSTATE_BLOCK on a full block -                if (*blocked_amount >= uint32(*damage)) -                { -                    *victimState = VICTIMSTATE_BLOCKS; -                    *blocked_amount = uint32(*damage); -                } - -                if(pVictim->GetTypeId() == TYPEID_PLAYER) -                { -                    // Update defense -                    ((Player*)pVictim)->UpdateDefense(); - -                    // random durability for main hand weapon (BLOCK) -                    if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) -                        ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); -                } - -                pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true); -                pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); -                break; -            } - -            pVictim->HandleEmoteCommand(EMOTE_ONESHOT_WOUNDCRITICAL); -            break; -        } -        case MELEE_HIT_PARRY: -        { -            if(attType == RANGED_ATTACK)                    //range attack - no parry -            { -                outcome = MELEE_HIT_NORMAL; -                break; -            } - -            cleanDamage->damage += *damage; -            *damage = 0; -            *victimState = VICTIMSTATE_PARRY; - -            // instant (maybe with small delay) counter attack -            { -                float offtime  = float(pVictim->getAttackTimer(OFF_ATTACK)); -                float basetime = float(pVictim->getAttackTimer(BASE_ATTACK)); - -                // after parry nearest next attack time will reduced at %40 from full attack time. -                // The delay cannot be reduced to less than 20% of your weapon base swing delay. -                if (pVictim->haveOffhandWeapon() && offtime < basetime) -                { -                    float percent20 = pVictim->GetAttackTime(OFF_ATTACK)*0.20; -                    float percent60 = 3*percent20; -                    // set to 20% if in range 20%...20+40% of full time -                    if(offtime > percent20 && offtime <= percent60) -                    { -                        pVictim->setAttackTimer(OFF_ATTACK,uint32(percent20)); -                    } -                    // decrease at %40 from full time -                    else if(offtime > percent60) -                    { -                        offtime -= 2*percent20; -                        pVictim->setAttackTimer(OFF_ATTACK,uint32(offtime)); -                    } -                    // ELSE not changed -                } -                else -                { -                    float percent20 = pVictim->GetAttackTime(BASE_ATTACK)*0.20; -                    float percent60 = 3*percent20; -                    // set to 20% if in range 20%...20+40% of full time -                    if(basetime > percent20 && basetime <= percent60) -                    { -                        pVictim->setAttackTimer(BASE_ATTACK,uint32(percent20)); -                    } -                    // decrease at %40 from full time -                    else if(basetime > percent60) -                    { -                        basetime -= 2*percent20; -                        pVictim->setAttackTimer(BASE_ATTACK,uint32(basetime)); -                    } -                    // ELSE not changed -                } -            } - -            if(pVictim->GetTypeId() == TYPEID_PLAYER) -            { -                // Update victim defense ? -                ((Player*)pVictim)->UpdateDefense(); - -                // random durability for main hand weapon (PARRY) -                if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_PARRY))) -                    ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_MAINHAND); -            } - -            pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); - -            if (pVictim->getClass() == CLASS_HUNTER) -            { -                pVictim->ModifyAuraState(AURA_STATE_HUNTER_PARRY,true); -                pVictim->StartReactiveTimer( REACTIVE_HUNTER_PARRY ); -            } -            else -            { -                pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); -                pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); -            } - -            CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); -            return; -        } -        case MELEE_HIT_DODGE: -        { -            if(attType == RANGED_ATTACK)                    //range attack - no dodge -            { -                outcome = MELEE_HIT_NORMAL; -                break; -            } - -            cleanDamage->damage += *damage; -            *damage = 0; -            *victimState = VICTIMSTATE_DODGE; - -            if(pVictim->GetTypeId() == TYPEID_PLAYER) -                ((Player*)pVictim)->UpdateDefense(); - -            pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); - -            if (pVictim->getClass() != CLASS_ROGUE)         // Riposte -            { -                pVictim->ModifyAuraState(AURA_STATE_DEFENSE, true); -                pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); -            } - -            // Overpower -            if (GetTypeId() == TYPEID_PLAYER && getClass() == CLASS_WARRIOR) -            { -                ((Player*)this)->AddComboPoints(pVictim, 1); -                StartReactiveTimer( REACTIVE_OVERPOWER ); -            } - -            CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); -            return; -        } -        case MELEE_HIT_BLOCK: -        { -            *blocked_amount = pVictim->GetShieldBlockValue(); - -            if (pVictim->GetUnitBlockChance()) -                pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYSHIELD); -            else -                pVictim->HandleEmoteCommand(EMOTE_ONESHOT_PARRYUNARMED); - -            //Only set VICTIMSTATE_BLOCK on a full block -            if (*blocked_amount >= uint32(*damage)) -            { -                *victimState = VICTIMSTATE_BLOCKS; -                *blocked_amount = uint32(*damage); -            } - -            if(pVictim->GetTypeId() == TYPEID_PLAYER) -            { -                // Update defense -                ((Player*)pVictim)->UpdateDefense(); - -                // random durability for main hand weapon (BLOCK) -                if (roll_chance_f(sWorld.getRate(RATE_DURABILITY_LOSS_BLOCK))) -                    ((Player*)pVictim)->DurabilityPointLossForEquipSlot(EQUIPMENT_SLOT_OFFHAND); -            } - -            pVictim->ModifyAuraState(AURA_STATE_DEFENSE,true); -            pVictim->StartReactiveTimer( REACTIVE_DEFENSE ); - -            break; -        } -        case MELEE_HIT_GLANCING: -        { -            int32 leveldif = int32(pVictim->getLevel()) - int32(getLevel()); -            if (leveldif > 3) leveldif = 3; -            *damage *= (1 - leveldif * 0.1f); -            cleanDamage->damage = *damage; -            *hitInfo |= HITINFO_GLANCING; -            break; -        } -        case MELEE_HIT_CRUSHING: -        { -            // 150% normal damage -            *damage += (*damage / 2); -            cleanDamage->damage = *damage; -            *hitInfo |= HITINFO_CRUSHING; -            // TODO: victimState, victim animation? -            break; -        } -        default: -            break; -    } - -    // apply melee damage bonus and absorb only if base damage not fully blocked to prevent negative damage or damage with full block -    if(*victimState != VICTIMSTATE_BLOCKS) -    { -        MeleeDamageBonus(pVictim, damage,attType,spellCasted); -        CalcAbsorbResist(pVictim, damageSchoolMask, DIRECT_DAMAGE, *damage-*blocked_amount, absorbDamage, resistDamage); -    } - -    if (*absorbDamage) *hitInfo |= HITINFO_ABSORB; -    if (*resistDamage) *hitInfo |= HITINFO_RESIST; - -    cleanDamage->damage += *blocked_amount; - -    if (*damage <= *absorbDamage + *resistDamage + *blocked_amount) -    { -        //*hitInfo = 0x00010020; -        //*hitInfo |= HITINFO_SWINGNOHITSOUND; -        //*damageType = 0; -        CastMeleeProcDamageAndSpell(pVictim, 0, damageSchoolMask, attType, outcome, spellCasted, isTriggeredSpell); -        return; -    } - -    // update at damage Judgement aura duration that applied by attacker at victim -    if(*damage) -    { -        AuraMap const& vAuras = pVictim->GetAuras(); -        for(AuraMap::const_iterator itr = vAuras.begin(); itr != vAuras.end(); ++itr) -        { -            SpellEntry const *spellInfo = (*itr).second->GetSpellProto(); -            if( (spellInfo->AttributesEx3 & 0x40000) && spellInfo->SpellFamilyName == SPELLFAMILY_PALADIN && -                ((*itr).second->GetCasterGUID() == GetGUID() && (!spellCasted || spellCasted->Id == 35395)) ) -            { -                (*itr).second->SetAuraDuration((*itr).second->GetAuraMaxDuration()); -                (*itr).second->UpdateAuraDuration(); -            } -        } -    } - -    CastMeleeProcDamageAndSpell(pVictim, (*damage - *absorbDamage pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifier()->m_amount, false, false);eld -    // yet another hack to fix crashes related to the aura getting removed during iteration -    std::set<Aura*> alreadyDone; -    uint32 removedAuras = pVictim->m_removedAuras; -    AuraList const& vDamageShields = pVictim->GetAurasByType(SPELL_AURA_DAMAGE_SHIELD); -    for(AuraList::const_iterator i = vDamageShields.begin(), next = vDamageShields.begin(); i != vDamageShields.end(); i = next) -    { -        ++next; -        if (alreadyDone.find(*i) == alreadyDone.end()) -        { -            alreadyDone.insert(*i); -            pVictim->SpellNonMeleeDamageLog(this, (*i)->GetId(), (*i)->GetModifierValue(), false, false); -            if (pVictim->m_removedAuras > removedAuras) -            { -                removedAuras = pVictim->m_removedAuras; -                next = vDamageShields.begin(); -            } -        } -    } -}*/ -  void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool extra )  {      if(hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED) ) @@ -2725,67 +2017,6 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex      }  } -/* -MeleeHitOutcome Unit::RollPhysicalOutcomeAgainst (Unit const *pVictim, WeaponAttackType attType, SpellEntry const *spellInfo) -{ -    // Miss chance based on melee -    float miss_chance = MeleeMissChanceCalc(pVictim, attType); - -    // Critical hit chance -    float crit_chance = GetUnitCriticalChance(attType, pVictim); -    // this is to avoid compiler issue when declaring variables inside if -    float block_chance, parry_chance, dodge_chance; - -    // cannot be dodged/parried/blocked -    if(spellInfo->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK) -    { -        block_chance = 0.0f; -        parry_chance = 0.0f; -        dodge_chance = 0.0f; -    } -    else -    { -        // parry can be avoided only by some abilities -        parry_chance = pVictim->GetUnitParryChance(); -        // block might be bypassed by it as well -        block_chance = pVictim->GetUnitBlockChance(); -        // stunned target cannot dodge and this is check in GetUnitDodgeChance() -        dodge_chance = pVictim->GetUnitDodgeChance(); -    } - -    // Only players can have Talent&Spell bonuses -    if (GetTypeId() == TYPEID_PLAYER) -    { -        // Increase from SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL aura -        crit_chance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_SPELL_CRIT_CHANCE_SCHOOL, spellInfo->SchoolMask); - -        if( dodge_chance != 0.0f )                          // if dodge chance is already 0, ignore talents for speed -        { -            AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); -            for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i) -            { -                // can't be dodged rogue finishing move -                if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE) -                { -                    if(spellInfo->SpellFamilyName==SPELLFAMILY_ROGUE && (spellInfo->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE)) -                    { -                        dodge_chance = 0.0f; -                        break; -                    } -                } -            } -        } -    } - -    // Spellmods -    if(Player* modOwner = GetSpellModOwner()) -        modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance); - -    DEBUG_LOG("PHYSICAL OUTCOME: miss %f crit %f dodge %f parry %f block %f",miss_chance,crit_chance,dodge_chance,parry_chance, block_chance); - -    return RollMeleeOutcomeAgainst(pVictim, attType, int32(crit_chance*100), int32(miss_chance*100),int32(dodge_chance*100),int32(parry_chance*100),int32(block_chance*100), true); -}*/ -  MeleeHitOutcome Unit::RollMeleeOutcomeAgainst(const Unit *pVictim, WeaponAttackType attType) const  {      // This is only wrapper @@ -3060,6 +2291,15 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAtt  {      if (pVictim->HasInArc(M_PI,this))      { +        // Ignore combat result aura (parry/dodge check on prepare) +        AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); +        for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i) +        { +            if (!(*i)->isAffectedOnSpell(spellProto)) +                continue; +            if ((*i)->GetModifier()->m_miscvalue == MELEE_HIT_BLOCK) +                return false; +        }          float blockChance = GetUnitBlockChance();          blockChance += (GetWeaponSkillValue(attackType) - pVictim->GetMaxSkillValueForLevel() )*0.04;          if (roll_chance_f(blockChance)) @@ -3070,22 +2310,18 @@ bool Unit::isSpellBlocked(Unit *pVictim, SpellEntry const *spellProto, WeaponAtt  // Melee based spells can be miss, parry or dodge on this step  // Crit or block - determined on damage calculation phase! (and can be both in some time) -float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const +/*float Unit::MeleeSpellMissChance(Unit *pVictim, WeaponAttackType attType, int32 skillDiff, SpellEntry const *spell)  {      // Calculate hit chance (more correct for chance mod)      int32 HitChance;      // PvP - PvE melee chances -    /*int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7; +    int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7;      int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim);      if(leveldif < 3)          HitChance = 95 - leveldif;      else -        HitChance = 93 - (leveldif - 2) * lchance;*/ -    if (spellId || attType == RANGED_ATTACK || !haveOffhandWeapon()) -        HitChance = 95.0f; -    else -        HitChance = 76.0f; +        HitChance = 93 - (leveldif - 2) * lchance;      // Hit chance depends from victim auras      if(attType == RANGED_ATTACK) @@ -3094,11 +2330,8 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,          HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE);      // Spellmod from SPELLMOD_RESIST_MISS_CHANCE -    if(spellId) -    { -        if(Player *modOwner = GetSpellModOwner()) -            modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, HitChance); -    } +    if(Player *modOwner = GetSpellModOwner()) +        modOwner->ApplySpellMod(spell->Id, SPELLMOD_RESIST_MISS_CHANCE, HitChance);      // Miss = 100 - hit      float miss_chance= 100.0f - HitChance; @@ -3110,12 +2343,7 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,          miss_chance -= m_modMeleeHitChance;      // bonus from skills is 0.04% -    //miss_chance -= skillDiff * 0.04f; -    int32 diff = -skillDiff; -    if(pVictim->GetTypeId()==TYPEID_PLAYER) -        miss_chance += diff > 0 ? diff * 0.04 : diff * 0.02; -    else -        miss_chance += diff > 10 ? 2 + (diff - 10) * 0.4 : diff * 0.1; +    miss_chance -= skillDiff * 0.04f;      // Limit miss chance from 0 to 60%      if (miss_chance < 0.0f) @@ -3123,7 +2351,7 @@ float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType,      if (miss_chance > 60.0f)          return 60.0f;      return miss_chance; -} +}*/  // Melee based spells hit result calculations  SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell) @@ -3139,68 +2367,82 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell)      int32 fullSkillDiff = attackerWeaponSkill - int32(pVictim->GetDefenseSkillValue(this));      uint32 roll = urand (0, 10000); -    uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell->Id)*100.0f); +    uint32 missChance = uint32(MeleeSpellMissChance(pVictim, attType, fullSkillDiff, spell->Id)*100.0f);      // Roll miss      uint32 tmp = missChance;      if (roll < tmp)          return SPELL_MISS_MISS; +    bool canDodge = true; +    bool canParry = true; +      // Same spells cannot be parry/dodge      if (spell->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK)          return SPELL_MISS_NONE; -    // Ranged attack can`t miss too +    // Ranged attack cannot be parry/dodge      if (attType == RANGED_ATTACK)          return SPELL_MISS_NONE; -    bool attackFromBehind = !pVictim->HasInArc(M_PI,this); - -    // Roll dodge -    int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4; -    // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE -    dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE); - -    // Reduce dodge chance by attacker expertise rating -    if (GetTypeId() == TYPEID_PLAYER) -        dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f); -    if (dodgeChance < 0) -        dodgeChance = 0; - -    // Can`t dodge from behind in PvP (but its possible in PvE) -    if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER && attackFromBehind) -        dodgeChance = 0; +    // Check for attack from behind +    if (!pVictim->HasInArc(M_PI,this)) +    { +        // Can`t dodge from behind in PvP (but its possible in PvE) +        if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER) +            canDodge = false; +        // Can`t parry  +        canParry = false; +    } -    // Rogue talent`s cant be dodged -    AuraList const& mCanNotBeDodge = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); -    for(AuraList::const_iterator i = mCanNotBeDodge.begin(); i != mCanNotBeDodge.end(); ++i) +    // Ignore combat result aura +    AuraList const& ignore = GetAurasByType(SPELL_AURA_IGNORE_COMBAT_RESULT); +    for(AuraList::const_iterator i = ignore.begin(); i != ignore.end(); ++i)      { -        if((*i)->GetModifier()->m_miscvalue == VICTIMSTATE_DODGE)       // can't be dodged rogue finishing move +        if (!(*i)->isAffectedOnSpell(spell)) +            continue; +        switch((*i)->GetModifier()->m_miscvalue)          { -            if(spell->SpellFamilyName==SPELLFAMILY_ROGUE && (spell->SpellFamilyFlags & SPELLFAMILYFLAG_ROGUE__FINISHING_MOVE)) -            { -                dodgeChance = 0; +            case MELEE_HIT_DODGE: canDodge = false; break; +            case MELEE_HIT_BLOCK: break; // Block check in hit step +            case MELEE_HIT_PARRY: canParry = false; break; +            default: +                DEBUG_LOG("Spell %u SPELL_AURA_IGNORE_COMBAT_RESULT have unhandled state %d", (*i)->GetId(), (*i)->GetModifier()->m_miscvalue);                  break; -            }          }      } -    tmp += dodgeChance; -    if (roll < tmp) -        return SPELL_MISS_DODGE; +    if (canDodge) +    { +        // Roll dodge +        int32 dodgeChance = int32(pVictim->GetUnitDodgeChance()*100.0f) - skillDiff * 4; +        // Reduce enemy dodge chance by SPELL_AURA_MOD_COMBAT_RESULT_CHANCE +        dodgeChance+= GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_COMBAT_RESULT_CHANCE, VICTIMSTATE_DODGE); +        // Reduce dodge chance by attacker expertise rating +        if (GetTypeId() == TYPEID_PLAYER) +            dodgeChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f); +        if (dodgeChance < 0) +            dodgeChance = 0; -    // Roll parry -    int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f)  - skillDiff * 4; -    // Reduce parry chance by attacker expertise rating -    if (GetTypeId() == TYPEID_PLAYER) -        parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f); -    // Can`t parry from behind -    if (parryChance < 0 || attackFromBehind) -        parryChance = 0; +        tmp += dodgeChance; +        if (roll < tmp) +            return SPELL_MISS_DODGE; +    } -    tmp += parryChance; -    if (roll < tmp) -        return SPELL_MISS_PARRY; +    if (canParry) +    { +        // Roll parry +        int32 parryChance = int32(pVictim->GetUnitParryChance()*100.0f)  - skillDiff * 4; +        // Reduce parry chance by attacker expertise rating +        if (GetTypeId() == TYPEID_PLAYER) +            parryChance-=int32(((Player*)this)->GetExpertiseDodgeOrParryReduction(attType) * 100.0f); +        if (parryChance < 0) +            parryChance = 0; + +        tmp += parryChance; +        if (roll < tmp) +            return SPELL_MISS_PARRY; +    }      return SPELL_MISS_NONE;  } @@ -4738,7 +3980,7 @@ void Unit::DelayAura(uint32 spellId, uint32 effindex, int32 delaytime)              iter->second->SetAuraDuration(0);          else              iter->second->SetAuraDuration(iter->second->GetAuraDuration() - delaytime); -        iter->second->UpdateAuraDuration(); +        iter->second->SendAuraUpdate(false);          sLog.outDebug("Aura %u partially interrupted on unit %u, new duration: %u ms",iter->second->GetModifier()->m_auraname, GetGUIDLow(), iter->second->GetAuraDuration());      }  } @@ -4911,6 +4153,7 @@ void Unit::SendSpellNonMeleeDamageLog(SpellNonMeleeDamage *log)      data.append(log->attacker->GetPackGUID());      data << uint32(log->SpellID);      data << uint32(log->damage);                             //damage amount +    data << uint32(0);      data << uint8 (log->schoolMask);                         //damage school      data << uint32(log->absorb);                             //AbsorbedDamage      data << uint32(log->resist);                             //resist @@ -4930,6 +4173,7 @@ void Unit::SendSpellNonMeleeDamageLog(Unit *target,uint32 SpellID,uint32 Damage,      data.append(GetPackGUID());      data << uint32(SpellID);      data << uint32(Damage-AbsorbedDamage-Resist-Blocked); +    data << uint32(0);                                      // wotlk      data << uint8(damageSchoolMask);                        // spell school      data << uint32(AbsorbedDamage);                         // AbsorbedDamage      data << uint32(Resist);                                 // resist @@ -4968,25 +4212,65 @@ void Unit::SendSpellMiss(Unit *target, uint32 spellID, SpellMissInfo missInfo)  void Unit::SendAttackStateUpdate(CalcDamageInfo *damageInfo)  { -    WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+84));    // we guess size +    uint32 count = 1; +    WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45));    // we guess size      data << (uint32)damageInfo->HitInfo;      data.append(GetPackGUID());      data.append(damageInfo->target->GetPackGUID());      data << (uint32)(damageInfo->damage);     // Full damage +    data << uint32(0);                        // overkill value + +    data << (uint8)count;                     // Sub damage count + +    for(int i = 0; i < count; ++i) +    { +        data << (uint32)(damageInfo->damageSchoolMask); // School of sub damage +        data << (float)damageInfo->damage;        // sub damage +        data << (uint32)damageInfo->damage;       // Sub Damage +    } + +    if(damageInfo->HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2)) +    { +        for(int i = 0; i < count; ++i) +            data << (uint32)damageInfo->absorb;       // Absorb +    } + +    if(damageInfo->HitInfo & (HITINFO_RESIST | HITINFO_RESIST2)) +    { +        for(int i = 0; i < count; ++i) +            data << (uint32)damageInfo->resist;       // Resist +    } -    data << (uint8)1;                         // Sub damage count -    //===  Sub damage description -    data << (uint32)(damageInfo->damageSchoolMask); // School of sub damage -    data << (float)damageInfo->damage;        // sub damage -    data << (uint32)damageInfo->damage;       // Sub Damage -    data << (uint32)damageInfo->absorb;       // Absorb -    data << (uint32)damageInfo->resist;       // Resist -    //=================================================      data << (uint32)damageInfo->TargetState;      data << (uint32)0;      data << (uint32)0; -    data << (uint32)damageInfo->blocked_amount; -    SendMessageToSet( &data, true );/**/ + +    if(damageInfo->HitInfo & HITINFO_BLOCK) +        data << (uint32)damageInfo->blocked_amount; + +    if(damageInfo->HitInfo & HITINFO_UNK3) +        data << uint32(0); + +    if(damageInfo->HitInfo & HITINFO_UNK1) +    { +        data << uint32(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        for(uint8 i = 0; i < 5; ++i) +        { +            data << float(0); +            data << float(0); +        } +        data << uint32(0); +    } + +    SendMessageToSet( &data, true );  }  void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType, SpellSchoolMask damageSchoolMask, uint32 Damage, uint32 AbsorbDamage, uint32 Resist, VictimState TargetState, uint32 BlockedAmount) @@ -4994,169 +4278,69 @@ void Unit::SendAttackStateUpdate(uint32 HitInfo, Unit *target, uint8 SwingType,      sLog.outDebug("WORLD: Sending SMSG_ATTACKERSTATEUPDATE");      WorldPacket data(SMSG_ATTACKERSTATEUPDATE, (16+45));    // we guess size -    data << (uint32)HitInfo; +    data << uint32(HitInfo);                                // flags      data.append(GetPackGUID());      data.append(target->GetPackGUID()); -    data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); +    data << uint32(Damage-AbsorbDamage-Resist-BlockedAmount);// damage +    data << uint32(0);                                      // overkill value      data << (uint8)SwingType;                               // count?      // for(i = 0; i < SwingType; ++i)      data << (uint32)damageSchoolMask;      data << (float)(Damage-AbsorbDamage-Resist-BlockedAmount); -    // still need to double check damage      data << (uint32)(Damage-AbsorbDamage-Resist-BlockedAmount); -    data << (uint32)AbsorbDamage; -    data << (uint32)Resist;      // end loop -    data << (uint32)TargetState; - -    if( AbsorbDamage == 0 )                                 //also 0x3E8 = 0x3E8, check when that happens -        data << (uint32)0; -    else -        data << (uint32)-1; - -    data << (uint32)0; -    data << (uint32)BlockedAmount; - -    SendMessageToSet( &data, true ); -} -/* -void Unit::ProcDamageAndSpell(Unit *pVictim, uint32 procAttacker, uint32 procVictim, uint32 damage, SpellSchoolMask damageSchoolMask, SpellEntry const *procSpell, bool isTriggeredSpell, WeaponAttackType attType) -{ -    sLog.outDebug("ProcDamageAndSpell: attacker flags are 0x%x, victim flags 0x%x", procAttacker, procVictim); -    if(procSpell) -        sLog.outDebug("ProcDamageAndSpell: invoked due to spell id %u %s", procSpell->Id, (isTriggeredSpell?"(triggered)":"")); - -    // Assign melee/ranged proc flags for magic attacks, that are actually melee/ranged abilities -    // not assign for spell proc triggered spell to prevent infinity (or unexpected 2-3 times) melee damage spell proc call with melee damage effect -    // That is the question though if it's fully correct -    if(procSpell && !isTriggeredSpell) +    if(HitInfo & (HITINFO_ABSORB | HITINFO_ABSORB2))      { -        if(procSpell->DmgClass == SPELL_DAMAGE_CLASS_MELEE) -        { -            if(procAttacker &  PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_MELEE; -            if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_MELEE; -            if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_MELEE; -            if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_MELEE; -            attType = BASE_ATTACK;                          // Melee abilities are assumed to be dealt with mainhand weapon -        } -        else if (procSpell->DmgClass == SPELL_DAMAGE_CLASS_RANGED) -        { -            if(procAttacker &  PROC_FLAG_HIT_SPELL) procAttacker |= PROC_FLAG_HIT_RANGED; -            if(procAttacker & PROC_FLAG_CRIT_SPELL) procAttacker |= PROC_FLAG_CRIT_RANGED; -            if(procVictim & PROC_FLAG_STRUCK_SPELL) procVictim |= PROC_FLAG_STRUCK_RANGED; -            if(procVictim & PROC_FLAG_STRUCK_CRIT_SPELL) procVictim |= PROC_FLAG_STRUCK_CRIT_RANGED; -            attType = RANGED_ATTACK; -        } +        // for(i = 0; i < SwingType; ++i) +        data << uint32(AbsorbDamage); +        // end loop      } -    if(damage && (procVictim & (PROC_FLAG_STRUCK_MELEE|PROC_FLAG_STRUCK_RANGED|PROC_FLAG_STRUCK_SPELL))) -        procVictim |= (PROC_FLAG_TAKE_DAMAGE|PROC_FLAG_TOUCH); -    // Not much to do if no flags are set. -    if (procAttacker) +    if(HitInfo & (HITINFO_RESIST | HITINFO_RESIST2))      { -        // processing auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set -        ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcEffectAuraTypes,attType, procSpell, damage, damageSchoolMask); -        ProcDamageAndSpellFor(false,pVictim,procAttacker,attackerProcCastAuraTypes,attType, procSpell, damage, damageSchoolMask); +        // for(i = 0; i < SwingType; ++i) +        data << uint32(Resist); +        // end loop      } -    // Now go on with a victim's events'n'auras -    // Not much to do if no flags are set or there is no victim -    if(pVictim && pVictim->isAlive() && procVictim) +    data << (uint8)TargetState; +    data << (uint32)0; +    data << (uint32)0; + +    if(HitInfo & HITINFO_BLOCK)      { -        // processing auras that not generate casts at proc event before auras that generate casts to prevent proc aura added at prev. proc aura execute in set -        pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcEffectAuraTypes,attType,procSpell, damage, damageSchoolMask); -        pVictim->ProcDamageAndSpellFor(true,this,procVictim,victimProcCastAuraTypes,attType,procSpell, damage, damageSchoolMask); +        data << uint32(BlockedAmount);      } -} -void Unit::CastMeleeProcDamageAndSpell(Unit* pVictim, uint32 damage, SpellSchoolMask damageSchoolMask, WeaponAttackType attType, MeleeHitOutcome outcome, SpellEntry const *spellCasted, bool isTriggeredSpell) -{ -    if(!pVictim) -        return; - -    uint32 procAttacker = PROC_FLAG_NONE; -    uint32 procVictim   = PROC_FLAG_NONE; - -    switch(outcome) +    if(HitInfo & HITINFO_UNK3)      { -        case MELEE_HIT_EVADE: -            return; -        case MELEE_HIT_MISS: -            if(attType == BASE_ATTACK || attType == OFF_ATTACK) -            { -                procAttacker = PROC_FLAG_MISS; -            } -            break; -        case MELEE_HIT_BLOCK_CRIT: -        case MELEE_HIT_CRIT: -            if(spellCasted && attType == BASE_ATTACK) -            { -                procAttacker |= PROC_FLAG_CRIT_SPELL; -                procVictim   |= PROC_FLAG_STRUCK_CRIT_SPELL; -                if ( outcome == MELEE_HIT_BLOCK_CRIT ) -                { -                    procVictim |= PROC_FLAG_BLOCK; -                    procAttacker |= PROC_FLAG_TARGET_BLOCK; -                } -            } -            else if(attType == BASE_ATTACK || attType == OFF_ATTACK) -            { -                procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE; -                procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE; -            } -            else -            { -                procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED; -                procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED; -            } -            break; -        case MELEE_HIT_PARRY: -            procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY; -            procVictim = PROC_FLAG_PARRY; -            break; -        case MELEE_HIT_BLOCK: -            procAttacker = PROC_FLAG_TARGET_BLOCK; -            procVictim = PROC_FLAG_BLOCK; -            break; -        case MELEE_HIT_DODGE: -            procAttacker = PROC_FLAG_TARGET_DODGE_OR_PARRY; -            procVictim = PROC_FLAG_DODGE; -            break; -        case MELEE_HIT_CRUSHING: -            if(attType == BASE_ATTACK || attType == OFF_ATTACK) -            { -                procAttacker = PROC_FLAG_HIT_MELEE | PROC_FLAG_CRIT_MELEE; -                procVictim = PROC_FLAG_STRUCK_MELEE | PROC_FLAG_STRUCK_CRIT_MELEE; -            } -            else -            { -                procAttacker = PROC_FLAG_HIT_RANGED | PROC_FLAG_CRIT_RANGED; -                procVictim = PROC_FLAG_STRUCK_RANGED | PROC_FLAG_STRUCK_CRIT_RANGED; -            } -            break; -        default: -            if(attType == BASE_ATTACK || attType == OFF_ATTACK) -            { -                procAttacker = PROC_FLAG_HIT_MELEE; -                procVictim = PROC_FLAG_STRUCK_MELEE; -            } -            else -            { -                procAttacker = PROC_FLAG_HIT_RANGED; -                procVictim = PROC_FLAG_STRUCK_RANGED; -            } -            break; +        data << uint32(0);      } -    if(damage > 0) -        procVictim |= PROC_FLAG_TAKE_DAMAGE; +    if(HitInfo & HITINFO_UNK1) +    { +        data << uint32(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        data << float(0); +        for(uint8 i = 0; i < 5; ++i) +        { +            data << float(0); +            data << float(0); +        } +        data << uint32(0); +    } -    if(procAttacker != PROC_FLAG_NONE || procVictim != PROC_FLAG_NONE) -        ProcDamageAndSpell(pVictim, procAttacker, procVictim, damage, damageSchoolMask, spellCasted, isTriggeredSpell, attType); -}*/ +    SendMessageToSet( &data, true ); +}  bool Unit::HandleHasteAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 /*procEx*/, uint32 cooldown)  { @@ -5239,7 +4423,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu          {              switch (dummySpell->Id)              { -                // Eye of Eye +                // Eye for an Eye                  case 9799:                  case 25988:                  { @@ -5856,7 +5040,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu                      triggered_spell_id = 39373;                      break;                  } -                // Vestments of Faith (Priest Tier 3) - 4 pieces bonus +                // Greater Heal (Vestments of Faith (Priest Tier 3) - 4 pieces bonus)                  case 28809:                  {                      triggered_spell_id = 28810; @@ -5993,6 +5177,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu          }          case SPELLFAMILY_PALADIN:          { +            // TODO: spell list, formula change in 3.0.3              // Seal of Righteousness - melee proc dummy              if (dummySpell->SpellFamilyFlags&0x000000008000000LL && triggeredByAura->GetEffIndex()==0)              { @@ -6089,7 +5274,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu                      }                      break;                  } -                //Seal of Vengeance +                // TODO: fix basepoint calculation (changed in 3.0.3) +                // Seal of Vengeance                  case 31801:                  {                      if(effIndex != 0)                       // effect 1,2 used by seal unleashing code @@ -6098,7 +5284,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu                      triggered_spell_id = 31803;                      break;                  } -                // Spiritual Att. +                // Spiritual Attunement                  case 31785:                  case 33776:                  { @@ -6282,7 +5468,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu              }              // Earth Shield -            if(dummySpell->SpellFamilyFlags==0x40000000000LL) +            if(dummySpell->SpellFamilyFlags & 0x0000040000000000LL)              {                  if(GetTypeId() != TYPEID_PLAYER)                      return false; @@ -6320,6 +5506,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu                      case 15208: spellId = 45294; break;     // Rank 10                      case 25448: spellId = 45295; break;     // Rank 11                      case 25449: spellId = 45296; break;     // Rank 12 +                    case 49237: spellId = 49239; break;     // Rank 13 +                    case 49238: spellId = 49240; break;     // Rank 14                      // Chain Lightning                      case   421: spellId = 45297; break;     // Rank  1                      case   930: spellId = 45298; break;     // Rank  2 @@ -6327,6 +5515,8 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu                      case 10605: spellId = 45300; break;     // Rank  4                      case 25439: spellId = 45301; break;     // Rank  5                      case 25442: spellId = 45302; break;     // Rank  6 +                    case 49268: spellId = 49270; break;     // Rank  7 +                    case 49269: spellId = 49271; break;     // Rank  8                      default:                          sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id);                          return false; @@ -6337,21 +5527,14 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu                  mod->value = -100;                  mod->type = SPELLMOD_PCT;                  mod->spellId = dummySpell->Id; -                mod->effectId = 0; -                mod->lastAffected = NULL;                  mod->mask = 0x0000000000000003LL; -                mod->charges = 0; +                mod->mask2= 0LL;                  ((Player*)this)->AddSpellMod(mod, true);                  // Remove cooldown (Chain Lightning - have Category Recovery time)                  if (procSpell->SpellFamilyFlags & 0x0000000000000002LL)                      ((Player*)this)->RemoveSpellCooldown(spellId); -                // Hmmm.. in most case spells already set half basepoints but... -                // Lightning Bolt (2-10 rank) have full basepoint and half bonus from level -                // As on wiki: -                // BUG: Rank 2 to 10 (and maybe 11) of Lightning Bolt will proc another Bolt with FULL damage (not halved). This bug is known and will probably be fixed soon. -                // So - no add changes :)                  CastSpell(pVictim, spellId, true, castItem, triggeredByAura);                  ((Player*)this)->AddSpellMod(mod, false); @@ -6396,668 +5579,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu      return true;  } -/* -bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags,WeaponAttackType attackType, uint32 cooldown) -{ -    SpellEntry const* auraSpellInfo = triggeredByAura->GetSpellProto(); - -    Item* castItem = triggeredByAura->GetCastItemGUID() && GetTypeId()==TYPEID_PLAYER -        ? ((Player*)this)->GetItemByGuid(triggeredByAura->GetCastItemGUID()) : NULL; - -    uint32 triggered_spell_id = auraSpellInfo->EffectTriggerSpell[triggeredByAura->GetEffIndex()]; -    Unit* target = !(procFlags & PROC_FLAG_HEAL) && IsPositiveSpell(triggered_spell_id) ? this : pVictim; -    int32 basepoints0 = 0; - -    switch(auraSpellInfo->SpellFamilyName) -    { -        case SPELLFAMILY_GENERIC: -        { -            switch(auraSpellInfo->Id) -            { -                // Aegis of Preservation -                case 23780: -                    //Aegis Heal (instead non-existed triggered spell) -                    triggered_spell_id = 23781; -                    target = this; -                    break; -                // Elune's Touch (moonkin mana restore) -                case 24905: -                { -                    // Elune's Touch (instead non-existed triggered spell) -                    triggered_spell_id = 33926; -                    basepoints0 = int32(0.3f * GetTotalAttackPowerValue(BASE_ATTACK)); -                    target = this; -                    break; -                } -                // Enlightenment -                case 29601: -                { -                    // only for cast with mana price -                    if(!procSpell || procSpell->powerType!=POWER_MANA || procSpell->manaCost==0 && procSpell->ManaCostPercentage==0 && procSpell->manaCostPerlevel==0) -                        return false; -                    break;                                  // fall through to normal cast -                } -                // Health Restore -                case 33510: -                { -                    // at melee hit call std triggered spell -                    if(procFlags & PROC_FLAG_HIT_MELEE) -                        break;                              // fall through to normal cast - -                    // Mark of Conquest - else (at range hit) called custom case -                    triggered_spell_id = 39557; -                    target = this; -                    break; -                } -                // Shaleskin -                case 36576: -                    return true;                            // nothing to do -                // Forgotten Knowledge (Blade of Wizardry) -                case 38319: -                    // only for harmful enemy targeted spell -                    if(!pVictim || pVictim==this || !procSpell || IsPositiveSpell(procSpell->Id)) -                        return false; -                    break;                              // fall through to normal cast -                // Aura of Wrath (Darkmoon Card: Wrath trinket bonus) -                case 39442: -                { -                    // proc only at non-crit hits -                    if(procFlags & (PROC_FLAG_CRIT_MELEE|PROC_FLAG_CRIT_RANGED|PROC_FLAG_CRIT_SPELL)) -                        return false; -                    break;                                  // fall through to normal cast -                } -                // Augment Pain (Timbal's Focusing Crystal trinket bonus) -                case 45054: -                { -                    if(!procSpell) -                        return false; - -                    //only periodic damage can trigger spell -                    bool found = false; -                    for(int j = 0; j < 3; ++j) -                    { -                        if( procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE         || -                            procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_DAMAGE_PERCENT || -                            procSpell->EffectApplyAuraName[j]==SPELL_AURA_PERIODIC_LEECH          ) -                        { -                            found = true; -                            break; -                        } -                    } -                    if(!found) -                        return false; - -                    break;                                  // fall through to normal cast -                } -                // Evasive Maneuvers (Commendation of Kael'thas) -                case 45057: -                { -                    // damage taken that reduces below 35% health -                    // does NOT mean you must have been >= 35% before -                    if (int32(GetHealth())-int32(damage) >= int32(GetMaxHealth()*0.35f)) -                        return false; -                    break;                                  // fall through to normal cast -                } -            } - -            switch(triggered_spell_id) -            { -                // Setup -                case 15250: -                { -                    // applied only for main target -                    if(!pVictim || pVictim != getVictim()) -                        return false; - -                    // continue normal case -                    break; -                } -                // Shamanistic Rage triggered spell -                case 30824: -                    basepoints0 = int32(GetTotalAttackPowerValue(BASE_ATTACK)*triggeredByAura->GetModifier()->m_amount/100); -                    break; -            } -            break; -        } -        case SPELLFAMILY_MAGE: -        { -            switch(auraSpellInfo->SpellIconID) -            { -                // Blazing Speed -                case 2127: -                    //Blazing Speed (instead non-existed triggered spell) -                    triggered_spell_id = 31643; -                    target = this; -                    break; -            } -            switch(auraSpellInfo->Id) -            { -                // Persistent Shield (Scarab Brooch) -                case 26467: -                    basepoints0 = int32(damage * 0.15f); -                    break; -            } -            break; -        } -        case SPELLFAMILY_WARRIOR: -        { -            //Rampage -            if((auraSpellInfo->SpellFamilyFlags & 0x100000) && auraSpellInfo->SpellIconID==2006) -            { -                //all ranks have effect[0]==AURA (Proc Trigger Spell, non-existed) -                //and effect[1]==TriggerSpell -                if(auraSpellInfo->Effect[1]!=SPELL_EFFECT_TRIGGER_SPELL) -                { -                    sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have wrong effect in RM",triggeredByAura->GetSpellProto()->Id); -                    return false; -                } -                triggered_spell_id = auraSpellInfo->EffectTriggerSpell[1]; -                break;                                      // fall through to normal cast -            } -            break; -        } -        case SPELLFAMILY_WARLOCK: -        { -            // Pyroclasm -            if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000 && auraSpellInfo->SpellIconID==1137) -            { -                // last case for Hellfire that damage caster also but don't must stun caster -                if( pVictim == this ) -                    return false; - -                // custom chance -                float chance = 0; -                switch (triggeredByAura->GetId()) -                { -                    case 18096: chance = 13.0f; break; -                    case 18073: chance = 26.0f; break; -                } -                if (!roll_chance_f(chance)) -                    return false; - -                // Pyroclasm (instead non-existed triggered spell) -                triggered_spell_id = 18093; -                target = pVictim; -                break; -            } -            // Drain Soul -            if(auraSpellInfo->SpellFamilyFlags & 0x0000000000004000) -            { -                bool found = false; -                Unit::AuraList const& mAddFlatModifier = GetAurasByType(SPELL_AURA_ADD_FLAT_MODIFIER); -                for(Unit::AuraList::const_iterator i = mAddFlatModifier.begin(); i != mAddFlatModifier.end(); ++i) -                { -                    //Improved Drain Soul -                    if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113) -                    { -                        int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this); -                        basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100; -                        // Drain Soul -                        CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); -                        break; -                    } -                } -                // Not remove charge (aura removed on death in any cases) -                // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura -                return false; -            } -            break; -        } -        case SPELLFAMILY_PRIEST: -        { -            //Blessed Recovery -            if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL && auraSpellInfo->SpellIconID==1875) -            { -                switch (triggeredByAura->GetSpellProto()->Id) -                { -                    case 27811: triggered_spell_id = 27813; break; -                    case 27815: triggered_spell_id = 27817; break; -                    case 27816: triggered_spell_id = 27818; break; -                    default: -                        sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in BR",triggeredByAura->GetSpellProto()->Id); -                        return false; -                } - -                int32 heal_amount = damage * triggeredByAura->GetModifier()->m_amount / 100; -                basepoints0 = heal_amount/3; -                target = this; -                break; -            } -            // Shadowguard -            if((auraSpellInfo->SpellFamilyFlags & 0x80000000LL) && auraSpellInfo->SpellVisual==7958) -            { -                switch(triggeredByAura->GetSpellProto()->Id) -                { -                    case 18137: -                        triggered_spell_id = 28377; break;  // Rank 1 -                    case 19308: -                        triggered_spell_id = 28378; break;  // Rank 2 -                    case 19309: -                        triggered_spell_id = 28379; break;  // Rank 3 -                    case 19310: -                        triggered_spell_id = 28380; break;  // Rank 4 -                    case 19311: -                        triggered_spell_id = 28381; break;  // Rank 5 -                    case 19312: -                        triggered_spell_id = 28382; break;  // Rank 6 -                    case 25477: -                        triggered_spell_id = 28385; break;  // Rank 7 -                    default: -                        sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG",triggeredByAura->GetSpellProto()->Id); -                        return false; -                } -                target = pVictim; -                break; -            } -            break; -        } -        case SPELLFAMILY_DRUID: -        { -            switch(auraSpellInfo->Id) -            { -                // Leader of the Pack (triggering Improved Leader of the Pack heal) -                case 24932: -                { -                    if (triggeredByAura->GetModifier()->m_amount == 0) -                        return false; -                    basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100; -                    triggered_spell_id = 34299; -                    break; -                }; -                // Druid Forms Trinket (Druid Tier5 Trinket, triggers different spells per Form) -                case 37336: -                { -                    switch(m_form) -                    { -                        case FORM_BEAR: -                        case FORM_DIREBEAR: -                            triggered_spell_id=37340; break;// Ursine Blessing -                        case FORM_CAT: -                            triggered_spell_id=37341; break;// Feline Blessing -                        case FORM_TREE: -                            triggered_spell_id=37342; break;// Slyvan Blessing -                        case FORM_MOONKIN: -                            triggered_spell_id=37343; break;// Lunar Blessing -                        case FORM_NONE: -                            triggered_spell_id=37344; break;// Cenarion Blessing (for caster form, except FORM_MOONKIN) -                        default: -                            return false; -                    } - -                    target = this; -                    break; -                } -            } -            break; -        } -        case SPELLFAMILY_ROGUE: -        { -            if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000LL) -            { -                switch(auraSpellInfo->SpellIconID) -                { -                    // Combat Potency -                    case 2260: -                    { -                        // skip non offhand attacks -                        if(attackType!=OFF_ATTACK) -                            return false; -                        break;                                  // fall through to normal cast -                    } -                } -            } -            break; -        } -        case SPELLFAMILY_PALADIN: -        { -            if(auraSpellInfo->SpellFamilyFlags == 0x00000000LL) -            { -                switch(auraSpellInfo->Id) -                { -                    // Lightning Capacitor -                    case 37657: -                    { -                        // trinket ProcTriggerSpell but for safe checks for player -                        if(!castItem || !pVictim || !pVictim->isAlive() || GetTypeId()!=TYPEID_PLAYER) -                            return false; - -                        if(((Player*)this)->HasSpellCooldown(37657)) -                            return false; - -                        // stacking -                        CastSpell(this, 37658, true, castItem, triggeredByAura); -                        // 2.5s cooldown before it can stack again, current system allow 1 sec step in cooldown -                        ((Player*)this)->AddSpellCooldown(37657,0,time(NULL)+(roll_chance_i(50) ? 2 : 3)); - -                        // counting -                        Aura * dummy = GetDummyAura(37658); -                        if (!dummy) -                            return false; - -                        // release at 3 aura in stack -                        if(dummy->GetStackAmount() <= 2) -                            return true;                    // main triggered spell casted anyway - -                        RemoveAurasDueToSpell(37658); -                        CastSpell(pVictim, 37661, true, castItem, triggeredByAura); -                        return true; -                    } -                    // Healing Discount -                    case 37705: -                        // Healing Trance (instead non-existed triggered spell) -                        triggered_spell_id = 37706; -                        target = this; -                        break; -                    // HoTs on Heals (Fel Reaver's Piston trinket) -                    case 38299: -                    { -                        // at direct heal effect -                        if(!procSpell || !IsSpellHaveEffect(procSpell,SPELL_EFFECT_HEAL)) -                            return false; - -                        // single proc at time -                        AuraList const& scAuras = GetSingleCastAuras(); -                        for(AuraList::const_iterator itr = scAuras.begin(); itr != scAuras.end(); ++itr) -                            if((*itr)->GetId()==triggered_spell_id) -                                return false; - -                        // positive cast at victim instead self -                        target = pVictim; -                        break; -                    } -                } -                switch(auraSpellInfo->SpellIconID) -                { -                    case 241: -                    { -                        switch(auraSpellInfo->EffectTriggerSpell[0]) -                        { -                            //Illumination -                            case 18350: -                            { -                                if(!procSpell) -                                    return false; - -                                // procspell is triggered spell but we need mana cost of original casted spell -                                uint32 originalSpellId = procSpell->Id; - -                                // Holy Shock -                                if(procSpell->SpellFamilyName == SPELLFAMILY_PALADIN) -                                { -                                    if(procSpell->SpellFamilyFlags & 0x0001000000000000LL) -                                    { -                                        switch(procSpell->Id) -                                        { -                                            case 25914: originalSpellId = 20473; break; -                                            case 25913: originalSpellId = 20929; break; -                                            case 25903: originalSpellId = 20930; break; -                                            case 27175: originalSpellId = 27174; break; -                                            case 33074: originalSpellId = 33072; break; -                                            default: -                                                sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in HShock",procSpell->Id); -                                                return false; -                                        } -                                    } -                                } - -                                SpellEntry const *originalSpell = sSpellStore.LookupEntry(originalSpellId); -                                if(!originalSpell) -                                { -                                    sLog.outError("Unit::HandleProcTriggerSpell: Spell %u unknown but selected as original in Illu",originalSpellId); -                                    return false; -                                } - -                                // percent stored in effect 1 (class scripts) base points -                                int32 percent = auraSpellInfo->EffectBasePoints[1]+1; - -                                basepoints0 = originalSpell->manaCost*percent/100; -                                triggered_spell_id = 20272; -                                target = this; -                                break; -                            } -                        } -                        break; -                    } -                } -            } -            if(auraSpellInfo->SpellFamilyFlags & 0x00080000) -            { -                switch(auraSpellInfo->SpellIconID) -                { -                    //Judgement of Wisdom (overwrite non existing triggered spell call in spell.dbc -                    case 206: -                    { -                        if(!pVictim || !pVictim->isAlive()) -                            return false; - -                        switch(triggeredByAura->GetSpellProto()->Id) -                        { -                            case 20186: -                                triggered_spell_id = 20268; // Rank 1 -                                break; -                            case 20354: -                                triggered_spell_id = 20352; // Rank 2 -                                break; -                            case 20355: -                                triggered_spell_id = 20353; // Rank 3 -                                break; -                            case 27164: -                                triggered_spell_id = 27165; // Rank 4 -                                break; -                            default: -                                sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoW",triggeredByAura->GetSpellProto()->Id); -                                return false; -                        } - -                        pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID()); -                        return true;                        // no hidden cooldown -                    } -                    //Judgement of Light -                    case 299: -                    { -                        if(!pVictim || !pVictim->isAlive()) -                            return false; - -                        // overwrite non existing triggered spell call in spell.dbc -                        switch(triggeredByAura->GetSpellProto()->Id) -                        { -                            case 20185: -                                triggered_spell_id = 20267; // Rank 1 -                                break; -                            case 20344: -                                triggered_spell_id = 20341; // Rank 2 -                                break; -                            case 20345: -                                triggered_spell_id = 20342; // Rank 3 -                                break; -                            case 20346: -                                triggered_spell_id = 20343; // Rank 4 -                                break; -                            case 27162: -                                triggered_spell_id = 27163; // Rank 5 -                                break; -                            default: -                                sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in JoL",triggeredByAura->GetSpellProto()->Id); -                                return false; -                        } -                        pVictim->CastSpell(pVictim,triggered_spell_id,true,castItem,triggeredByAura,GetGUID()); -                        return true;                        // no hidden cooldown -                    } -                } -            } -            // custom check for proc spell -            switch(auraSpellInfo->Id) -            { -                // Bonus Healing (item spell) -                case 40971: -                { -                    if(!pVictim || !pVictim->isAlive()) -                        return false; - -                    // bonus if health < 50% -                    if(pVictim->GetHealth() >= pVictim->GetMaxHealth()*triggeredByAura->GetModifier()->m_amount/100) -                        return false; - -                    // cast at target positive spell -                    target = pVictim; -                    break; -                } -            } -            switch(triggered_spell_id) -            { -                // Seal of Command -                case 20424: -                    // prevent chain of triggered spell from same triggered spell -                    if(procSpell && procSpell->Id==20424) -                        return false; -                    break; -            } -            break; -        } -        case SPELLFAMILY_SHAMAN: -        { -            if(auraSpellInfo->SpellFamilyFlags == 0x0000000000000000) -            { -                switch(auraSpellInfo->SpellIconID) -                { -                    case 19: -                    { -                        switch(auraSpellInfo->Id) -                        { -                            case 23551:                     // Lightning Shield - Tier2: 8 pieces proc shield -                            { -                                // Lightning Shield (overwrite non existing triggered spell call in spell.dbc) -                                triggered_spell_id = 23552; -                                target = pVictim; -                                break; -                            } -                            case 23552:                     // Lightning Shield - trigger shield damage -                            { -                                // Lightning Shield (overwrite non existing triggered spell call in spell.dbc) -                                triggered_spell_id = 27635; -                                target = pVictim; -                                break; -                            } -                        } -                        break; -                    } -                    // Mana Surge (Shaman T1 bonus) -                    case 87: -                    { -                        if(!procSpell) -                            return false; - -                        basepoints0 = procSpell->manaCost * 35/100; -                        triggered_spell_id = 23571; -                        target = this; -                        break; -                    } -                    //Nature's Guardian -                    case 2013: -                    { -                        if(GetTypeId()!=TYPEID_PLAYER) -                            return false; - -                        // damage taken that reduces below 30% health -                        // does NOT mean you must have been >= 30% before -                        if (10*(int32(GetHealth())-int32(damage)) >= 3*GetMaxHealth()) -                            return false; - -                        triggered_spell_id = 31616; - -                        // need check cooldown now -                        if( cooldown && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) -                            return false; - -                        basepoints0 = triggeredByAura->GetModifier()->m_amount * GetMaxHealth() / 100; -                        target = this; -                        if(pVictim && pVictim->isAlive()) -                            pVictim->getThreatManager().modifyThreatPercent(this,-10); -                        break; -                    } -                } -            } - -            // Water Shield (we can't set cooldown for main spell - it's player casted spell -            if((auraSpellInfo->SpellFamilyFlags & 0x0000002000000000LL) && auraSpellInfo->SpellVisual==7358) -            { -                target = this; -                break; -            } - -            // Lightning Shield -            if((auraSpellInfo->SpellFamilyFlags & 0x00000400) && auraSpellInfo->SpellVisual==37) -            { -                // overwrite non existing triggered spell call in spell.dbc -                switch(triggeredByAura->GetSpellProto()->Id) -                { -                    case   324: -                        triggered_spell_id = 26364; break;  // Rank 1 -                    case   325: -                        triggered_spell_id = 26365; break;  // Rank 2 -                    case   905: -                        triggered_spell_id = 26366; break;  // Rank 3 -                    case   945: -                        triggered_spell_id = 26367; break;  // Rank 4 -                    case  8134: -                        triggered_spell_id = 26369; break;  // Rank 5 -                    case 10431: -                        triggered_spell_id = 26370; break;  // Rank 6 -                    case 10432: -                        triggered_spell_id = 26363; break;  // Rank 7 -                    case 25469: -                        triggered_spell_id = 26371; break;  // Rank 8 -                    case 25472: -                        triggered_spell_id = 26372; break;  // Rank 9 -                    default: -                        sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield",triggeredByAura->GetSpellProto()->Id); -                        return false; -                } - -                target = pVictim; -                break; -            } -            break; -        } -    } - -    // standard non-dummy case -    if(!triggered_spell_id) -    { -        sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have 0 in EffectTriggered[%d], not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex()); -        return false; -    } - -    SpellEntry const* triggerEntry = sSpellStore.LookupEntry(triggered_spell_id); - -    if(!triggerEntry) -    { -        sLog.outError("Unit::HandleProcTriggerSpell: Spell %u have not existed EffectTriggered[%d]=%u, not handled custom case?",auraSpellInfo->Id,triggeredByAura->GetEffIndex(),triggered_spell_id); -        return false; -    } - -    // not allow proc extra attack spell at extra attack -    if( m_extraAttacks && IsSpellHaveEffect(triggerEntry,SPELL_EFFECT_ADD_EXTRA_ATTACKS) ) -        return false; - -    if( cooldown && GetTypeId()==TYPEID_PLAYER && ((Player*)this)->HasSpellCooldown(triggered_spell_id)) -        return false; - -    // default case -    if(!target || target!=this && !target->isAlive()) -        return false; - -    if(basepoints0) -        CastCustomSpell(target,triggered_spell_id,&basepoints0,NULL,NULL,true,castItem,triggeredByAura); -    else -        CastSpell(target,triggered_spell_id,true,castItem,triggeredByAura); - -    if( cooldown && GetTypeId()==TYPEID_PLAYER ) -        ((Player*)this)->AddSpellCooldown(triggered_spell_id,0,time(NULL) + cooldown); - -    return true; -} -*/  bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredByAura, SpellEntry const *procSpell, uint32 procFlags, uint32 procEx, uint32 cooldown)  { @@ -7085,14 +5606,30 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB       // .....       //=====================================================================       case SPELLFAMILY_GENERIC: +//     if (auraSpellInfo->Id==59532)    // Abandon Passengers on Poly +//     if (auraSpellInfo->Id==54775)    // Abandon Vehicle on Poly  //     if (auraSpellInfo->Id==34082)      // Advantaged State (DND) -//          trigger_spell_id = ???;       if (auraSpellInfo->Id == 23780)      // Aegis of Preservation (Aegis of Preservation trinket) -          trigger_spell_id = 23781; +         trigger_spell_id = 23781;  //     else if (auraSpellInfo->Id==43504) // Alterac Valley OnKill Proc Aura -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id == 48876)      // Beast's Mark +//     { +//         trigger_spell_id = 48877; +//     } +//     else if (auraSpellInfo->Id == 59237)      // Beast's Mark +//     { +//         trigger_spell_id = 59233; +//     } +//     else if (auraSpellInfo->Id==46939)   // Black Bow of the Betrayer +//     { +//         trigger_spell_id = 29471; // gain mana +//         27526; // drain mana if possible +//     } +//     else if (auraSpellInfo->Id==50844) // Blood Mirror +//     else if (auraSpellInfo->Id==54476) // Blood Presence +//     else if (auraSpellInfo->Id==50689) // Blood Presence (Rank 1)  //     else if (auraSpellInfo->Id==37030) // Chaotic Temperament -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id==52856) // Charge       else if (auraSpellInfo->Id==43820)   // Charm of the Witch Doctor (Amani Charm of the Witch Doctor trinket)       {            // Pct value stored in dummy @@ -7102,31 +5639,37 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB       }  //     else if (auraSpellInfo->Id==41248) // Consuming Strikes  //          trigger_spell_id = 41249; +//     else if (auraSpellInfo->Id==45205) // Copy Offhand Weapon +//     else if (auraSpellInfo->Id==57594) // Copy Ranged Weapon  //     else if (auraSpellInfo->Id==41054) // Copy Weapon  //          trigger_spell_id = 41055; +//     else if (auraSpellInfo->Id==45343) // Dark Flame Aura +//     else if (auraSpellInfo->Id==47300) // Dark Flame Aura +     else if (auraSpellInfo->Id==57345) // Darkmoon Card: Greatness +     { +         uint32 stat = 0; +         // strength +         if (GetStat(STAT_STRENGTH) > stat){trigger_spell_id = 60229;stat = GetStat(STAT_STRENGTH);} +         // agility +         if (GetStat(STAT_AGILITY) > stat){trigger_spell_id = 60233;stat = GetStat(STAT_AGILITY);} +         // intellect +         if (GetStat(STAT_INTELLECT) > stat){trigger_spell_id = 60234;stat = GetStat(STAT_INTELLECT);} +         // spirit +         if (GetStat(STAT_SPIRIT) > stat){trigger_spell_id = 60235;stat = GetStat(STAT_SPIRIT);} +     }  //     else if (auraSpellInfo->Id==31255) // Deadly Swiftness (Rank 1) -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==5301)  // Defensive State (DND) -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==13358) // Defensive State (DND) -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==16092) // Defensive State (DND) -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==24949) // Defensive State 2 (DND) -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==40329) // Demo Shout Sensor -//          trigger_spell_id = ;       // Desperate Defense (Stonescythe Whelp, Stonescythe Alpha, Stonescythe Ambusher)       else if (auraSpellInfo->Id == 33896)           trigger_spell_id = 33898;  //     else if (auraSpellInfo->Id==18943) // Double Attack -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==19194) // Double Attack -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==19817) // Double Attack -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==19818) // Double Attack -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==22835) // Drunken Rage  //          trigger_spell_id = 14822;   /* @@ -7158,21 +5701,21 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB               return false;           }       }*/ -//     else if (auraSpellInfo->Id==6542)  // Enraged Defense -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==40364) // Entangling Roots Sensor -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==33207) // Gossip NPC Periodic - Fidget -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id==50051) // Ethereal Pet Aura  //     else if (auraSpellInfo->Id==35321) // Gushing Wound -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==38363) // Gushing Wound -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==39215) // Gushing Wound -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id==44527) // Hate Monster (Spar Buddy) (30 sec) +//     else if (auraSpellInfo->Id==44819) // Hate Monster (Spar Buddy) (>30% Health) +//     else if (auraSpellInfo->Id==44526) // Hate Monster (Spar) (30 sec) +//     else if (auraSpellInfo->Id==44820) // Hate Monster (Spar) (<30%) +//     else if (auraSpellInfo->Id==49059) // Horde, Hate Monster (Spar Buddy) (>30% Health)  //     else if (auraSpellInfo->Id==40250) // Improved Duration -//          trigger_spell_id = ; -     else if (auraSpellInfo->Id==27522)   // Mana Drain Trigger +//     else if (auraSpellInfo->Id==59288) // Infra-Green Shield +//     else if (auraSpellInfo->Id==54072) // Knockback Ball Passive +     else if (auraSpellInfo->Id==27522 || auraSpellInfo->Id==40336)   // Mana Drain Trigger       {           // On successful melee or ranged attack gain $29471s1 mana and if possible drain $27526s1 mana from the target.           if (this && this->isAlive()) @@ -7181,27 +5724,21 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB               CastSpell(pVictim, 27526, true, castItem, triggeredByAura);           return true;       } -     else if (auraSpellInfo->Id==24905)   // Moonkin Form (Passive) -     { -         // Elune's Touch (instead non-existed triggered spell) 30% from AP -         trigger_spell_id = 33926; -         basepoints0 = GetTotalAttackPowerValue(BASE_ATTACK) * 30 / 100; -         target = this; -     } +//     else if (auraSpellInfo->Id==55580) // Mana Link +//     else if (auraSpellInfo->Id==45903) // Offensive State +//     else if (auraSpellInfo->Id==44326) // Pure Energy Passive  //     else if (auraSpellInfo->Id==43453) // Rune Ward -//          trigger_spell_id = ; -//     else if (auraSpellInfo->Id==7137)  // Shadow Charge (Rank 1) -//          trigger_spell_id = ; -       // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger -//     else if (auraSpellInfo->Id==36576) -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id== 7137) // Shadow Charge (Rank 1) +//     else if (auraSpellInfo->Id==36576) // Shaleskin (Shaleskin Flayer, Shaleskin Ripper) 30023 trigger  //     else if (auraSpellInfo->Id==34783) // Spell Reflection -//          trigger_spell_id = ;  //     else if (auraSpellInfo->Id==36096) // Spell Reflection -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id==57587) // Steal Ranged ()  //     else if (auraSpellInfo->Id==36207) // Steal Weapon -//          trigger_spell_id = ; +//     else if (auraSpellInfo->Id== 7377) // Take Immune Periodic Damage <Not Working>  //     else if (auraSpellInfo->Id==35205) // Vanish +//     else if (auraSpellInfo->Id==42730) // Woe Strike +//     else if (auraSpellInfo->Id==59735) // Woe Strike +//     else if (auraSpellInfo->Id==46146) // [PH] Ahune  Spanky Hands       break;       //=====================================================================       // Mage @@ -7227,27 +5764,20 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB       //=====================================================================       // Warrior       //===================================================================== -     // Rampage (Rank 1-3) trigger = 18350 +     // Scent of Blood       //=====================================================================       case SPELLFAMILY_WARRIOR: -     // Rampage -     if (auraSpellInfo->SpellIconID == 2006 && auraSpellInfo->SpellFamilyFlags==0x100000)       { -         switch(auraSpellInfo->Id) -         { -             case 29801: trigger_spell_id = 30029; break;       // Rank 1 -             case 30030: trigger_spell_id = 30031; break;       // Rank 2 -             case 30033: trigger_spell_id = 30032; break;       // Rank 3 -             default: -                 sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in Rampage",auraSpellInfo->Id); -             return false; -         } +         // Scent of Blood +         if (auraSpellInfo->Id == 50421) +             trigger_spell_id = 50422;       }       break;       //=====================================================================       // Warlock       //=====================================================================       // Pyroclasm             trigger = 18350 +     // Nether Protection     trigger = 1206       // Drain Soul (Rank 1-5) trigger = 0       //=====================================================================       case SPELLFAMILY_WARLOCK: @@ -7291,12 +5821,33 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB                   if ((*i)->GetModifier()->m_miscvalue == SPELLMOD_CHANCE_OF_SUCCESS && (*i)->GetSpellProto()->SpellIconID == 113)                   {                       int32 value2 = CalculateSpellDamage((*i)->GetSpellProto(),2,(*i)->GetSpellProto()->EffectBasePoints[2],this); -                     basepoints0 = value2 * GetMaxPower(POWER_MANA) / 100; +                     // Drain Soul +                     CastCustomSpell(this, 18371, &basepoints0, NULL, NULL, true, castItem, triggeredByAura); +                     break;                   }               } -             if ( basepoints0 == 0 ) +             // Not remove charge (aura removed on death in any cases) +             // Need for correct work Drain Soul SPELL_AURA_CHANNEL_DEATH_ITEM aura +             return false; +         } +         // Nether Protection +         else if (auraSpellInfo->SpellIconID == 1985) +         { +             if (!procSpell)                   return false; -             trigger_spell_id = 18371; +             switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) +             { +                 case SPELL_SCHOOL_NORMAL: +                 case SPELL_SCHOOL_HOLY: +                     return false;                   // ignore +                 case SPELL_SCHOOL_FIRE:   trigger_spell_id = 54371; break; +                 case SPELL_SCHOOL_NATURE: trigger_spell_id = 54375; break; +                 case SPELL_SCHOOL_FROST:  trigger_spell_id = 54372; break; +                 case SPELL_SCHOOL_SHADOW: trigger_spell_id = 54374; break; +                 case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break; +                 default: +                     return false; +             }           }           break;       } @@ -7305,30 +5856,12 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB       //=====================================================================       // Greater Heal Refund         trigger = 18350       // Blessed Recovery (Rank 1-3) trigger = 18350 -     // Shadowguard (1-7)           trigger = 28376       //=====================================================================       case SPELLFAMILY_PRIEST:       {           // Greater Heal Refund           if (auraSpellInfo->Id==37594)               trigger_spell_id = 37595; -         // Shadowguard -         else if(auraSpellInfo->SpellFamilyFlags==0x100080000000LL && auraSpellInfo->SpellVisual==7958) -         { -             switch(auraSpellInfo->Id) -             { -                 case 18137: trigger_spell_id = 28377; break;   // Rank 1 -                 case 19308: trigger_spell_id = 28378; break;   // Rank 2 -                 case 19309: trigger_spell_id = 28379; break;   // Rank 3 -                 case 19310: trigger_spell_id = 28380; break;   // Rank 4 -                 case 19311: trigger_spell_id = 28381; break;   // Rank 5 -                 case 19312: trigger_spell_id = 28382; break;   // Rank 6 -                 case 25477: trigger_spell_id = 28385; break;   // Rank 7 -                 default: -                     sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in SG", auraSpellInfo->Id); -                 return false; -             } -         }           // Blessed Recovery           else if (auraSpellInfo->SpellIconID == 1875)           { @@ -7395,9 +5928,9 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB       // Blessed Life                   trigger = 31934       // Healing Discount               trigger = 18350       // Illumination (Rank 1-5)        trigger = 18350 -     // Judgement of Light (Rank 1-5)  trigger = 5373 -     // Judgement of Wisdom (Rank 1-4) trigger = 1826       // Lightning Capacitor            trigger = 18350 +     // Thunder Capacitor              trigger = 18350 +     // Soul Preserver                 trigger = 18350       //=====================================================================       case SPELLFAMILY_PALADIN:       { @@ -7421,28 +5954,11 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB               trigger_spell_id = 37706;               target = this;           } -         // Judgement of Light and Judgement of Wisdom -         else if (auraSpellInfo->SpellFamilyFlags & 0x0000000000080000LL) +         // Soul Preserver +         if (auraSpellInfo->Id==60510)           { -             switch (auraSpellInfo->Id) -             { -                 // Judgement of Light -                 case 20185: trigger_spell_id = 20267;break; // Rank 1 -                 case 20344: trigger_spell_id = 20341;break; // Rank 2 -                 case 20345: trigger_spell_id = 20342;break; // Rank 3 -                 case 20346: trigger_spell_id = 20343;break; // Rank 4 -                 case 27162: trigger_spell_id = 27163;break; // Rank 5 -                 // Judgement of Wisdom -                 case 20186: trigger_spell_id = 20268;break; // Rank 1 -                 case 20354: trigger_spell_id = 20352;break; // Rank 2 -                 case 20355: trigger_spell_id = 20353;break; // Rank 3 -                 case 27164: trigger_spell_id = 27165;break; // Rank 4 -                 default: -                     sLog.outError("Unit::HandleProcTriggerSpell: Spell %u miss posibly Judgement of Light/Wisdom", auraSpellInfo->Id); -                 return false; -             } -             pVictim->CastSpell(pVictim, trigger_spell_id, true, castItem, triggeredByAura); -             return true;                        // no hidden cooldown +             trigger_spell_id = 60515; +             target = this;           }           // Illumination           else if (auraSpellInfo->SpellIconID==241) @@ -7489,13 +6005,34 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB               if (!dummy)                   return false;               // release at 3 aura in stack (cont contain in basepoint of trigger aura) -             if(dummy->GetStackAmount() <= 2) +             if(dummy->GetStackAmount() < triggerAmount)                   return false;               RemoveAurasDueToSpell(37658);               trigger_spell_id = 37661;               target = pVictim;           } +         // Thunder Capacitor +         else if (auraSpellInfo->Id == 54841) +         { +             if(!pVictim || !pVictim->isAlive()) +                 return false; +             // stacking +             CastSpell(this, 54842, true, NULL, triggeredByAura); +             // counting +             uint32 count = 0; +             AuraList const& dummyAura = GetAurasByType(SPELL_AURA_DUMMY); +             for(AuraList::const_iterator itr = dummyAura.begin(); itr != dummyAura.end(); ++itr) +                 if((*itr)->GetId()==54842) +                     ++count; +             // release at 3 aura in stack (cont contain in basepoint of trigger aura) +             if(count < triggerAmount) +                 return false; + +             RemoveAurasDueToSpell(54842); +             trigger_spell_id = 54843; +             target = pVictim; +         }           break;       }       //===================================================================== @@ -7507,8 +6044,8 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB       //=====================================================================       case SPELLFAMILY_SHAMAN:       { -         //Lightning Shield (overwrite non existing triggered spell call in spell.dbc -         if(auraSpellInfo->SpellFamilyFlags==0x00000400 && auraSpellInfo->SpellVisual==37) +         // Lightning Shield (overwrite non existing triggered spell call in spell.dbc +         if(auraSpellInfo->SpellFamilyFlags & 0x0000000000000400)           {               switch(auraSpellInfo->Id)               { @@ -7521,6 +6058,8 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB                   case 10432: trigger_spell_id = 26363; break;  // Rank 7                   case 25469: trigger_spell_id = 26371; break;  // Rank 8                   case 25472: trigger_spell_id = 26372; break;  // Rank 9 +                 case 49280: trigger_spell_id = 49278; break;  // Rank 10 +                 case 49281: trigger_spell_id = 49279; break;  // Rank 11                   default:                       sLog.outError("Unit::HandleProcTriggerSpell: Spell %u not handled in LShield", auraSpellInfo->Id);                   return false; @@ -7544,7 +6083,8 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB               trigger_spell_id = 23571;               target = this;           } -         else if (auraSpellInfo->SpellIconID == 2013) //Nature's Guardian +         // Nature's Guardian +         else if (auraSpellInfo->SpellIconID == 2013)           {               // Check health condition - should drop to less 30% (damage deal after this!)               if (!(10*(int32(GetHealth() - damage)) < 3 * GetMaxHealth())) @@ -7559,6 +6099,45 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, Aura* triggeredB           }           break;       } +     //===================================================================== +     // Death Knight +     //==================================================================== +     // Acclimation       trigger = 1206 +     // Blood Presence    trigger = 1206 +     //===================================================================== +     case SPELLFAMILY_DEATHKNIGHT: +     { +         // Acclimation +         if (auraSpellInfo->SpellIconID == 1930) +         { +             if (!procSpell) +                 return false; +             switch(GetFirstSchoolInMask(GetSpellSchoolMask(procSpell))) +             { +                 case SPELL_SCHOOL_NORMAL: +                     return false;                   // ignore +                 case SPELL_SCHOOL_HOLY:   trigger_spell_id = 50490; break; +                 case SPELL_SCHOOL_FIRE:   trigger_spell_id = 50362; break; +                 case SPELL_SCHOOL_NATURE: trigger_spell_id = 50488; break; +                 case SPELL_SCHOOL_FROST:  trigger_spell_id = 50485; break; +                 case SPELL_SCHOOL_SHADOW: trigger_spell_id = 50489; break; +                 case SPELL_SCHOOL_ARCANE: trigger_spell_id = 54373; break; +                 default: +                     return false; +             } +         } +         // Blood Presence +         else if (auraSpellInfo->Id == 48266) +         { +             if (GetTypeId() != TYPEID_PLAYER) +                 return false; +             if (!((Player*)this)->RewardPlayerAndGroupAtKill(pVictim)) +                 return false; +             trigger_spell_id = 50475; +             basepoints0 = damage * triggerAmount / 100; +         } +         break; +     }       // default       default:           break; @@ -7720,21 +6299,21 @@ bool Unit::HandleOverrideClassScriptAuraProc(Unit *pVictim, Aura *triggeredByAur      {          case 836:                                           // Improved Blizzard (Rank 1)          { -            if (!procSpell || procSpell->SpellVisual!=9487) +            if (!procSpell || procSpell->SpellVisual[0]!=9487)                  return false;              triggered_spell_id = 12484;              break;          }          case 988:                                           // Improved Blizzard (Rank 2)          { -            if (!procSpell || procSpell->SpellVisual!=9487) +            if (!procSpell || procSpell->SpellVisual[0]!=9487)                  return false;              triggered_spell_id = 12485;              break;          }          case 989:                                           // Improved Blizzard (Rank 3)          { -            if (!procSpell || procSpell->SpellVisual!=9487) +            if (!procSpell || procSpell->SpellVisual[0]!=9487)                  return false;              triggered_spell_id = 12486;              break; @@ -7912,7 +6491,7 @@ bool Unit::IsHostileTo(Unit const* unit) const              return false;          // Sanctuary -        if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY)) +        if(pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))              return false;          // PvP FFA state @@ -8021,7 +6600,7 @@ bool Unit::IsFriendlyTo(Unit const* unit) const              return true;          // Sanctuary -        if(pTarget->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY) && pTester->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_SANCTUARY)) +        if(pTarget->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY) && pTester->HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY))              return true;          // PvP FFA state @@ -8390,6 +6969,9 @@ void Unit::SetPet(Pet* pet)  void Unit::SetCharm(Unit* pet)  {      SetUInt64Value(UNIT_FIELD_CHARM, pet ? pet->GetGUID() : 0); + +    if(GetTypeId() == TYPEID_PLAYER) +        ((Player*)this)->m_mover = pet ? pet : this;  }  void Unit::AddPlayerToVision(Player* plr)  @@ -8468,6 +7050,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, bool c      data.append(GetPackGUID());      data << uint32(SpellID);      data << uint32(Damage); +    data << uint32(0);                                      // over healing?      data << uint8(critical ? 1 : 0);      data << uint8(0);                                       // unused in client?      SendMessageToSet(&data, true); @@ -8650,7 +7233,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3  				CastingTime = 0;  			}  			// Darkmoon Card: Vengeance - 0.1% -			else if (spellProto->SpellVisual == 9850 && spellProto->SpellIconID == 2230) +			else if (spellProto->SpellVisual[0] == 9850 && spellProto->SpellIconID == 2230)  			{  				CastingTime = 3.5;  			} @@ -8918,14 +7501,8 @@ int32 Unit::SpellBaseDamageBonus(SpellSchoolMask schoolMask)          {              if((*i)->GetModifier()->m_miscvalue & schoolMask)              { -                SpellEntry const* iSpellProto = (*i)->GetSpellProto(); -                uint8 eff = (*i)->GetEffIndex(); - -                // stat used dependent from next effect aura SPELL_AURA_MOD_SPELL_HEALING presence and misc value (stat index) -                Stats usedStat = STAT_INTELLECT; -                if(eff < 2 && iSpellProto->EffectApplyAuraName[eff+1]==SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT) -                    usedStat = Stats(iSpellProto->EffectMiscValue[eff+1]); - +                // stat used stored in miscValueB for this aura +                Stats usedStat = Stats((*i)->GetMiscBValue());                  DoneAdvertisedBenefit += int32(GetStat(usedStat) * (*i)->GetModifierValue() / 100.0f);              }          } @@ -9096,7 +7673,7 @@ uint32 Unit::SpellHealingBonus(SpellEntry const *spellProto, uint32 healamount,          AuraList const& mDummyAuras = pVictim->GetAurasByType(SPELL_AURA_DUMMY);          for(AuraList::const_iterator i = mDummyAuras.begin();i != mDummyAuras.end(); ++i)          { -            if((*i)->GetSpellProto()->SpellVisual == 9180) +            if((*i)->GetSpellProto()->SpellVisual[0] == 9180)              {                  // Flash of Light                  if ((spellProto->SpellFamilyFlags & 0x0000000040000000LL) && (*i)->GetEffIndex() == 1) @@ -9676,7 +8253,7 @@ void Unit::Unmount()      if(GetTypeId() == TYPEID_PLAYER && IsInWorld() && ((Player*)this)->GetTemporaryUnsummonedPetNumber() && isAlive())      {          Pet* NewPet = new Pet; -        if(!NewPet->LoadPetFromDB(this, 0, ((Player*)this)->GetTemporaryUnsummonedPetNumber(), true)) +        if(!NewPet->LoadPetFromDB((Player*)this, 0, ((Player*)this)->GetTemporaryUnsummonedPetNumber(), true))              delete NewPet;          ((Player*)this)->SetTemporaryUnsummonedPetNumber(0); @@ -10112,38 +8689,37 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)      propagateSpeedChange(); -    // Send speed change packet only for player -    if (GetTypeId()!=TYPEID_PLAYER) -        return; -      WorldPacket data;      if(!forced)      {          switch(mtype)          {              case MOVE_WALK: -                data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_WALK_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_RUN: -                data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_RUN_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_RUN_BACK: -                data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_RUN_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_SWIM: -                data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_SWIM_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_SWIM_BACK: -                data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_SWIM_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_TURN_RATE: -                data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_TURN_RATE, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_FLIGHT: -                data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_FLIGHT_SPEED, 8+4+2+4+4+4+4+4+4+4);                  break;              case MOVE_FLIGHT_BACK: -                data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+1+4+4+4+4+4+4+4); +                data.Initialize(MSG_MOVE_SET_FLIGHT_BACK_SPEED, 8+4+2+4+4+4+4+4+4+4); +                break; +            case MOVE_PITCH_RATE: +                data.Initialize(MSG_MOVE_SET_PITCH_RATE, 8+4+2+4+4+4+4+4+4+4);                  break;              default:                  sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype); @@ -10151,22 +8727,26 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)          }          data.append(GetPackGUID()); -        data << uint32(0);                                  //movement flags -        data << uint8(0);                                   //unk +        data << uint32(0);                                  // movement flags +        data << uint16(0);                                  // unk flags          data << uint32(getMSTime());          data << float(GetPositionX());          data << float(GetPositionY());          data << float(GetPositionZ());          data << float(GetOrientation()); -        data << uint32(0);                                  //flag unk +        data << uint32(0);                                  // fall time          data << float(GetSpeed(mtype));          SendMessageToSet( &data, true );      }      else      { -        // register forced speed changes for WorldSession::HandleForceSpeedChangeAck -        // and do it only for real sent packets and use run for run/mounted as client expected -        ++((Player*)this)->m_forced_speed_changes[mtype]; +        if(GetTypeId() == TYPEID_PLAYER) +        { +            // register forced speed changes for WorldSession::HandleForceSpeedChangeAck +            // and do it only for real sent packets and use run for run/mounted as client expected +            ++((Player*)this)->m_forced_speed_changes[mtype]; +        } +          switch(mtype)          {              case MOVE_WALK: @@ -10193,6 +8773,9 @@ void Unit::SetSpeed(UnitMoveType mtype, float rate, bool forced)              case MOVE_FLIGHT_BACK:                  data.Initialize(SMSG_FORCE_FLIGHT_BACK_SPEED_CHANGE, 16);                  break; +            case MOVE_PITCH_RATE: +                data.Initialize(SMSG_FORCE_PITCH_RATE_CHANGE, 16); +                break;              default:                  sLog.outError("Unit::SetSpeed: Unsupported move type (%d), data not sent to client.",mtype);                  return; @@ -10282,6 +8865,10 @@ bool Unit::CanHaveThreatList() const      if( ((Creature*)this)->isTotem() )          return false; +    // vehicles can not have threat list +    if( ((Creature*)this)->isVehicle() ) +        return false; +      // pets can not have a threat list, unless they are controlled by a creature      if( ((Creature*)this)->isPet() && IS_PLAYER_GUID(((Pet*)this)->GetOwnerGUID()) )          return false; @@ -10530,6 +9117,8 @@ int32 Unit::CalculateSpellDuration(SpellEntry const* spellProto, uint8 effect_in          int32 mechanic = GetEffectMechanic(spellProto, effect_index);          // Find total mod value (negative bonus)          int32 durationMod_always = target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD, mechanic); +        // Modify from SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL aura (stack always ?) +        durationMod_always+=target->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DURATION_OF_EFFECTS_BY_DISPEL, spellProto->Dispel);          // Find max mod (negative bonus)          int32 durationMod_not_stack = target->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MECHANIC_DURATION_MOD_NOT_STACK, mechanic); @@ -10731,7 +9320,9 @@ bool Unit::HandleStatModifier(UnitMods unitMod, UnitModifierType modifierType, f          case UNIT_MOD_RAGE:          case UNIT_MOD_FOCUS:          case UNIT_MOD_ENERGY: -        case UNIT_MOD_HAPPINESS:           UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod));         break; +        case UNIT_MOD_HAPPINESS: +        case UNIT_MOD_RUNE: +        case UNIT_MOD_RUNIC_POWER:          UpdateMaxPower(GetPowerTypeByAuraGroup(unitMod));          break;          case UNIT_MOD_RESISTANCE_HOLY:          case UNIT_MOD_RESISTANCE_FIRE: @@ -10844,21 +9435,18 @@ Stats Unit::GetStatByAuraGroup(UnitMods unitMod) const  Powers Unit::GetPowerTypeByAuraGroup(UnitMods unitMod) const  { -    Powers power = POWER_MANA; -      switch(unitMod)      { -        case UNIT_MOD_MANA:       power = POWER_MANA;       break; -        case UNIT_MOD_RAGE:       power = POWER_RAGE;       break; -        case UNIT_MOD_FOCUS:      power = POWER_FOCUS;      break; -        case UNIT_MOD_ENERGY:     power = POWER_ENERGY;     break; -        case UNIT_MOD_HAPPINESS:  power = POWER_HAPPINESS;  break; - -        default: -            break; +        case UNIT_MOD_MANA:       return POWER_MANA; +        case UNIT_MOD_RAGE:       return POWER_RAGE; +        case UNIT_MOD_FOCUS:      return POWER_FOCUS; +        case UNIT_MOD_ENERGY:     return POWER_ENERGY; +        case UNIT_MOD_HAPPINESS:  return POWER_HAPPINESS; +        case UNIT_MOD_RUNE:       return POWER_RUNE; +        case UNIT_MOD_RUNIC_POWER:return POWER_RUNIC_POWER;      } -    return power; +    return POWER_MANA;  }  float Unit::GetTotalAttackPowerValue(WeaponAttackType attType) const @@ -10957,6 +9545,12 @@ void Unit::SetPower(Powers power, uint32 val)      SetStatInt32Value(UNIT_FIELD_POWER1 + power, val); +    WorldPacket data(SMSG_POWER_UPDATE); +    data.append(GetPackGUID()); +    data << uint8(power); +    data << uint32(val); +    SendMessageToSet(&data, GetTypeId() == TYPEID_PLAYER ? true : false); +      // group update      if(GetTypeId() == TYPEID_PLAYER)      { @@ -11070,6 +9664,7 @@ uint32 Unit::GetCreatePowers( Powers power ) const          case POWER_FOCUS:     return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 100);          case POWER_ENERGY:    return 100;          case POWER_HAPPINESS: return (GetTypeId()==TYPEID_PLAYER || !((Creature const*)this)->isPet() || ((Pet const*)this)->getPetType()!=HUNTER_PET ? 0 : 1050000); +        case POWER_RUNIC_POWER: return 1000;      }      return 0; @@ -11157,7 +9752,7 @@ void CharmInfo::InitEmptyActionBar(bool withAttack)      for(uint32 x = 0; x < 10; ++x)      { -        PetActionBar[x].Type = ACT_CAST; +        PetActionBar[x].Type = ACT_PASSIVE;          PetActionBar[x].SpellOrAction = 0;      }      if (withAttack) @@ -11173,13 +9768,20 @@ void CharmInfo::InitPossessCreateSpells()      InitEmptyActionBar();      if(m_unit->GetTypeId() == TYPEID_UNIT)      { -        for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) +        /*for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i)          {              uint32 spellid = ((Creature*)m_unit)->m_spells[i];              if(IsPassiveSpell(spellid))                  m_unit->CastSpell(m_unit, spellid, true);              else                  AddSpellToAB(0, spellid, ACT_CAST); +        }*/ +        for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) +        { +            if (IsPassiveSpell(((Creature*)m_unit)->m_spells[x])) +                m_unit->CastSpell(m_unit, ((Creature*)m_unit)->m_spells[x], true); +            else +                AddSpellToAB(0, ((Creature*)m_unit)->m_spells[x], ACT_PASSIVE);          }      }  } @@ -11223,7 +9825,7 @@ void CharmInfo::InitCharmCreateSpells()              if(onlyselfcast || !IsPositiveSpell(spellId))   //only self cast and spells versus enemies are autocastable                  newstate = ACT_DISABLED;              else -                newstate = ACT_CAST; +                newstate = ACT_PASSIVE;              AddSpellToAB(0, spellId, newstate);          } @@ -11234,7 +9836,7 @@ bool CharmInfo::AddSpellToAB(uint32 oldid, uint32 newid, ActiveStates newstate)  {      for(uint8 i = 0; i < 10; i++)      { -        if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_CAST) && PetActionBar[i].SpellOrAction == oldid) +        if((PetActionBar[i].Type == ACT_DISABLED || PetActionBar[i].Type == ACT_ENABLED || PetActionBar[i].Type == ACT_PASSIVE) && PetActionBar[i].SpellOrAction == oldid)          {              PetActionBar[i].SpellOrAction = newid;              if(!oldid) @@ -11283,181 +9885,6 @@ bool Unit::isFrozen() const      return false;  } -/* -struct ProcTriggeredData -{ -    ProcTriggeredData(Aura* _triggeredByAura, uint32 _cooldown) -        : triggeredByAura(_triggeredByAura), -        triggeredByAura_SpellPair(Unit::spellEffectPair(triggeredByAura->GetId(),triggeredByAura->GetEffIndex())), -        cooldown(_cooldown) -    {} - -    Aura* triggeredByAura;                                  // triggred aura, can be invalidate at triggered aura proccessing -    Unit::spellEffectPair triggeredByAura_SpellPair;        // spell pair, used for re-find aura (by pointer comparison in range) -    uint32 cooldown;                                        // possible hidden cooldown -}; - -typedef std::list< ProcTriggeredData > ProcTriggeredList; - -void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag, AuraTypeSet const& procAuraTypes, WeaponAttackType attType, SpellEntry const * procSpell, uint32 damage, SpellSchoolMask damageSchoolMask ) -{ -    for(AuraTypeSet::const_iterator aur = procAuraTypes.begin(); aur != procAuraTypes.end(); ++aur) -    { -        // List of spells (effects) that proceed. Spell prototype and aura-specific value (damage for TRIGGER_DAMAGE) -        ProcTriggeredList procTriggered; - -        AuraList const& auras = GetAurasByType(*aur); -        for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) -        { -            next = i; ++next; - -            Aura* i_aura = *i; - -            uint32 cooldown;                                // returned at next line -            if(!IsTriggeredAtSpellProcEvent(i_aura->GetSpellProto(), procSpell, procFlag,attType,isVictim,cooldown)) -                continue; - -            procTriggered.push_back( ProcTriggeredData(i_aura, cooldown) ); -        } - -        // Handle effects proceed this time -        for(ProcTriggeredList::iterator i = procTriggered.begin(); i != procTriggered.end(); ++i) -        { -            // Some auras can be deleted in function called in this loop (except first, ofc) -            // Until storing auras in std::multimap to hard check deleting by another way -            if(i != procTriggered.begin()) -            { -                bool found = false; -                AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); -                AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); -                for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) -                { -                    if(itr->second==i->triggeredByAura) -                    { -                        found = true; -                        break; -                    } -                } - -                if(!found) -                { -                    sLog.outError("Spell aura %u (id:%u effect:%u) has been deleted before call spell proc event handler",*aur,i->triggeredByAura_SpellPair.first,i->triggeredByAura_SpellPair.second); -                    sLog.outError("It can be deleted one from early processed auras:"); -                    for(ProcTriggeredList::iterator i2 = procTriggered.begin(); i != i2; ++i2) -                        sLog.outError("     Spell aura %u (id:%u effect:%u)",*aur,i2->triggeredByAura_SpellPair.first,i2->triggeredByAura_SpellPair.second); -                    sLog.outError("     <end of list>"); -                    continue; -                } -            } - -            /// this is aura triggering code call -            Aura* triggeredByAura = i->triggeredByAura; - -            /// save charges existence before processing to prevent crash at access to deleted triggered aura after -            /// used in speedup code check before check aura existance. -            bool triggeredByAuraWithCharges =  triggeredByAura->m_procCharges > 0; - -            /// success in event proccesing -            /// used in speedup code check before check aura existance. -            bool casted = false; - -            /// process triggered code -            switch(*aur) -            { -                case SPELL_AURA_PROC_TRIGGER_SPELL: -                { -                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s proc aura of spell %u)", -                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); -                    casted = HandleProcTriggerSpell(pTarget, damage, triggeredByAura, procSpell, procFlag, attType, i->cooldown); -                    break; -                } -                case SPELL_AURA_PROC_TRIGGER_DAMAGE: -                { -                    uint32 triggered_damage = triggeredByAura->GetModifier()->m_amount; -                    sLog.outDebug("ProcDamageAndSpell: doing %u damage (triggered by %s aura of spell %u)", -                        triggered_damage, (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); -                    SpellNonMeleeDamageLog(pTarget, triggeredByAura->GetId(), triggered_damage, true, true); -                    casted = true; -                    break; -                } -                case SPELL_AURA_DUMMY: -                { -                    uint32 effect = triggeredByAura->GetEffIndex(); -                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s dummy aura of spell %u)", -                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); -                    casted = HandleDummyAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); -                    break; -                } -                case SPELL_AURA_PRAYER_OF_MENDING: -                { -                    sLog.outDebug("ProcDamageAndSpell: casting mending (triggered by %s dummy aura of spell %u)", -                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); - -                    casted = HandleMeandingAuraProc(triggeredByAura); -                    break; -                } -                case SPELL_AURA_MOD_HASTE: -                { -                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s haste aura of spell %u)", -                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); -                    casted = HandleHasteAuraProc(pTarget, damage, triggeredByAura, procSpell, procFlag,i->cooldown); -                    break; -                } -                case SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN: -                { -                    // nothing do, just charges counter -                    // but count only in case appropriate school damage -                    casted = triggeredByAura->GetModifier()->m_miscvalue & damageSchoolMask; -                    break; -                } -                case SPELL_AURA_OVERRIDE_CLASS_SCRIPTS: -                { -                    sLog.outDebug("ProcDamageAndSpell: casting spell (triggered by %s class script aura of spell %u)", -                        (isVictim?"a victim's":"an attacker's"),triggeredByAura->GetId()); -                    casted = HandleOverrideClassScriptAuraProc(pTarget, triggeredByAura, procSpell,i->cooldown); -                    break; -                } -                default: -                { -                    // nothing do, just charges counter -                    casted = true; -                    break; -                } -            } - -            /// Update charge (aura can be removed by triggers) -            if(casted && triggeredByAuraWithCharges) -            { -                /// need re-found aura (can be dropped by triggers) -                AuraMap::const_iterator lower = GetAuras().lower_bound(i->triggeredByAura_SpellPair); -                AuraMap::const_iterator upper = GetAuras().upper_bound(i->triggeredByAura_SpellPair); -                for(AuraMap::const_iterator itr = lower; itr!= upper; ++itr) -                { -                    if(itr->second == triggeredByAura)      // pointer still valid -                    { -                        if(triggeredByAura->m_procCharges > 0) -                            triggeredByAura->m_procCharges -= 1; - -                        triggeredByAura->UpdateAuraCharges(); -                        break; -                    } -                } -            } -        } - -        /// Safely remove auras with zero charges -        for(AuraList::const_iterator i = auras.begin(), next; i != auras.end(); i = next) -        { -            next = i; ++next; -            if((*i)->m_procCharges == 0) -            { -                RemoveAurasDueToSpell((*i)->GetId()); -                next = auras.begin(); -            } -        } -    } -} -*/  struct ProcTriggeredData  {      ProcTriggeredData(SpellProcEventEntry const * _spellProcEvent, Aura* _triggeredByAura) @@ -11476,9 +9903,7 @@ typedef std::list< uint32> RemoveSpellList;  // in most case need for drop charges  // in some types of aura need do additional check  // for example SPELL_AURA_MECHANIC_IMMUNITY - need check for mechanic -static bool isTriggerAura[TOTAL_AURAS]; -static bool isNonTriggerAura[TOTAL_AURAS]; -void InitTriggerAuraData() +bool InitTriggerAuraData()  {      for (int i=0;i<TOTAL_AURAS;i++)      { @@ -11515,6 +9940,8 @@ void InitTriggerAuraData()      isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true;      isNonTriggerAura[SPELL_AURA_RESIST_PUSHBACK]=true; + +    return true;  }  uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missCondition) @@ -11849,8 +10276,11 @@ void Unit::SendPetCastFail(uint32 spellid, uint8 msg)          return;      WorldPacket data(SMSG_PET_CAST_FAILED, (4+1)); +    data << uint8(0);                                       // cast count?      data << uint32(spellid);      data << uint8(msg); +    // uint32 for some reason +    // uint32 for some reason      ((Player*)owner)->GetSession()->SendPacket(&data);  } @@ -12410,7 +10840,13 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget,uint32 spell_id)      pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction());      pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, spell_id); -    if(!pet->InitStatsForLevel(creatureTarget->getLevel())) +    if(GetTypeId()==TYPEID_PLAYER) +        pet->SetUInt32Value(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE); + +    uint32 level = (creatureTarget->getLevel() < (getLevel() - 5)) ? (getLevel() - 5) : creatureTarget->getLevel(); +    pet->SetFreeTalentPoints(pet->GetMaxTalentPointsForLevel(level)); + +    if(!pet->InitStatsForLevel(level))      {          sLog.outError("ERROR: Pet::InitStatsForLevel() failed for creature (Entry: %u)!",creatureTarget->GetEntry());          delete pet; @@ -12541,10 +10977,8 @@ bool Unit::HandleMeandingAuraProc( Aura* triggeredByAura )                  mod->value = jumps-5;               // negative                  mod->type = SPELLMOD_FLAT;                  mod->spellId = spellProto->Id; -                mod->effectId = effIdx; -                mod->lastAffected = NULL; -                mod->mask = spellProto->SpellFamilyFlags; -                mod->charges = 0; +                mod->mask  = spellProto->SpellFamilyFlags; +                mod->mask2 = spellProto->SpellFamilyFlags2;                  caster->AddSpellMod(mod, true);                  CastCustomSpell(target,spellProto->Id,&heal,NULL,NULL,true,NULL,triggeredByAura,caster->GetGUID()); @@ -12732,6 +11166,15 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)                  bg->HandleKillUnit((Creature*)pVictim, player);          }      } + +        // achievement stuff +        if ( pVictim->GetTypeId() == TYPEID_PLAYER) +        { +            if(GetTypeId() == TYPEID_UNIT) +                ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE, GetEntry()); +            else if(GetTypeId() == TYPEID_PLAYER) +                ((Player*)pVictim)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER, 1); +        }  }  void Unit::SetControlled(bool apply, UnitState state) @@ -12801,7 +11244,7 @@ void Unit::SetStunned(bool apply)      if(apply)      {          SetUInt64Value(UNIT_FIELD_TARGET, 0); -        SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +        SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);          CastStop();          // Creature specific @@ -12819,7 +11262,7 @@ void Unit::SetStunned(bool apply)      {          if(isAlive() && getVictim())              SetUInt64Value(UNIT_FIELD_TARGET, getVictim()->GetGUID()); -        RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_ROTATE); +        RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);          if(!hasUnitState(UNIT_STAT_ROOT))         // prevent allow move if have also root effect          { @@ -13040,4 +11483,61 @@ void Unit::AddAura(uint32 spellId, Unit* target)              }          }      } -}
\ No newline at end of file +} + +// Melee based spells can be miss, parry or dodge on this step +// Crit or block - determined on damage calculation phase! (and can be both in some time) +float Unit::MeleeSpellMissChance(const Unit *pVictim, WeaponAttackType attType, int32 skillDiff, uint32 spellId) const +{ +    // Calculate hit chance (more correct for chance mod) +    int32 HitChance; + +    // PvP - PvE melee chances +    /*int32 lchance = pVictim->GetTypeId() == TYPEID_PLAYER ? 5 : 7; +    int32 leveldif = pVictim->getLevelForTarget(this) - getLevelForTarget(pVictim); +    if(leveldif < 3) +        HitChance = 95 - leveldif; +    else +        HitChance = 93 - (leveldif - 2) * lchance;*/ +    if (spellId || attType == RANGED_ATTACK || !haveOffhandWeapon()) +        HitChance = 95.0f; +    else +        HitChance = 76.0f; + +    // Hit chance depends from victim auras +    if(attType == RANGED_ATTACK) +        HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE); +    else +        HitChance += pVictim->GetTotalAuraModifier(SPELL_AURA_MOD_ATTACKER_MELEE_HIT_CHANCE); + +    // Spellmod from SPELLMOD_RESIST_MISS_CHANCE +    if(spellId) +    { +        if(Player *modOwner = GetSpellModOwner()) +            modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, HitChance); +    } + +    // Miss = 100 - hit +    float miss_chance= 100.0f - HitChance; + +    // Bonuses from attacker aura and ratings +    if (attType == RANGED_ATTACK) +        miss_chance -= m_modRangedHitChance; +    else +        miss_chance -= m_modMeleeHitChance; + +    // bonus from skills is 0.04% +    //miss_chance -= skillDiff * 0.04f; +    int32 diff = -skillDiff; +    if(pVictim->GetTypeId()==TYPEID_PLAYER) +        miss_chance += diff > 0 ? diff * 0.04 : diff * 0.02; +    else +        miss_chance += diff > 10 ? 2 + (diff - 10) * 0.4 : diff * 0.1; + +    // Limit miss chance from 0 to 60% +    if (miss_chance < 0.0f) +        return 0.0f; +    if (miss_chance > 60.0f) +        return 60.0f; +    return miss_chance; +} diff --git a/src/game/Unit.h b/src/game/Unit.h index 2f1af0c32d8..01eba9d0184 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -149,6 +149,7 @@ enum ShapeshiftForm      FORM_BERSERKERSTANCE    = 0x13,      FORM_TEST               = 0x14,      FORM_ZOMBIE             = 0x15, +    FORM_METAMORPHOSIS      = 0x16,      FORM_FLIGHT_EPIC        = 0x1B,      FORM_SHADOW             = 0x1C,      FORM_FLIGHT             = 0x1D, @@ -168,14 +169,14 @@ enum SheathState  // byte (1 from 0..3) of UNIT_FIELD_BYTES_2  enum UnitBytes2_Flags  { -    UNIT_BYTE2_FLAG_UNK0  = 0x01, -    UNIT_BYTE2_FLAG_UNK1  = 0x02, -    UNIT_BYTE2_FLAG_UNK2  = 0x04, -    UNIT_BYTE2_FLAG_UNK3  = 0x08, -    UNIT_BYTE2_FLAG_AURAS = 0x10,                           // show possitive auras as positive, and allow its dispel -    UNIT_BYTE2_FLAG_UNK5  = 0x20, -    UNIT_BYTE2_FLAG_UNK6  = 0x40, -    UNIT_BYTE2_FLAG_UNK7  = 0x80 +    UNIT_BYTE2_FLAG_PVP         = 0x01, +    UNIT_BYTE2_FLAG_UNK1        = 0x02, +    UNIT_BYTE2_FLAG_FFA_PVP     = 0x04, +    UNIT_BYTE2_FLAG_SANCTUARY   = 0x08, +    UNIT_BYTE2_FLAG_UNK4        = 0x10, +    UNIT_BYTE2_FLAG_UNK5        = 0x20, +    UNIT_BYTE2_FLAG_UNK6        = 0x40, +    UNIT_BYTE2_FLAG_UNK7        = 0x80  };  // byte (2 from 0..3) of UNIT_FIELD_BYTES_2 @@ -213,16 +214,27 @@ enum HitInfo      HITINFO_UNK1                = 0x00000001,               // req correct packet structure      HITINFO_NORMALSWING2        = 0x00000002,      HITINFO_LEFTSWING           = 0x00000004, +    HITINFO_UNK2                = 0x00000008,      HITINFO_MISS                = 0x00000010, -    HITINFO_ABSORB              = 0x00000020,               // plays absorb sound -    HITINFO_RESIST              = 0x00000040,               // resisted at least some damage -    HITINFO_CRITICALHIT         = 0x00000080, -    HITINFO_UNK2                = 0x00000100,               // wotlk? -    HITINFO_UNK3                = 0x00002000,               // wotlk? -    HITINFO_GLANCING            = 0x00004000, -    HITINFO_CRUSHING            = 0x00008000, -    HITINFO_NOACTION            = 0x00010000, -    HITINFO_SWINGNOHITSOUND     = 0x00080000 +    HITINFO_ABSORB              = 0x00000020,               // absorbed damage +    HITINFO_ABSORB2             = 0x00000040,               // absorbed damage +    HITINFO_RESIST              = 0x00000080,               // resisted atleast some damage +    HITINFO_RESIST2             = 0x00000100,               // resisted atleast some damage +    HITINFO_CRITICALHIT         = 0x00000200,               // critical hit +    // 0x00000400 +    // 0x00000800 +    // 0x00001000 +    HITINFO_BLOCK               = 0x00002000,               // blocked damage +    // 0x00004000 +    // 0x00008000 +    HITINFO_GLANCING            = 0x00010000, +    HITINFO_CRUSHING            = 0x00020000, +    HITINFO_NOACTION            = 0x00040000,               // guessed +    // 0x00080000 +    // 0x00100000 +    HITINFO_SWINGNOHITSOUND     = 0x00200000,               // guessed +    // 0x00400000 +    HITINFO_UNK3                = 0x00800000  };  //i would like to remove this: (it is defined in item.h @@ -294,11 +306,13 @@ enum UnitMods      UNIT_MOD_STAT_INTELLECT,      UNIT_MOD_STAT_SPIRIT,      UNIT_MOD_HEALTH, -    UNIT_MOD_MANA,                                          // UNIT_MOD_MANA..UNIT_MOD_HAPPINESS must be in existed order, it's accessed by index values of Powers enum. +    UNIT_MOD_MANA,                                          // UNIT_MOD_MANA..UNIT_MOD_RUNIC_POWER must be in existed order, it's accessed by index values of Powers enum.      UNIT_MOD_RAGE,      UNIT_MOD_FOCUS,      UNIT_MOD_ENERGY,      UNIT_MOD_HAPPINESS, +    UNIT_MOD_RUNE, +    UNIT_MOD_RUNIC_POWER,      UNIT_MOD_ARMOR,                                         // UNIT_MOD_ARMOR..UNIT_MOD_RESISTANCE_ARCANE must be in existed order, it's accessed by index values of SpellSchools enum.      UNIT_MOD_RESISTANCE_HOLY,      UNIT_MOD_RESISTANCE_FIRE, @@ -318,7 +332,7 @@ enum UnitMods      UNIT_MOD_RESISTANCE_START = UNIT_MOD_ARMOR,      UNIT_MOD_RESISTANCE_END = UNIT_MOD_RESISTANCE_ARCANE + 1,      UNIT_MOD_POWER_START = UNIT_MOD_MANA, -    UNIT_MOD_POWER_END = UNIT_MOD_HAPPINESS + 1 +    UNIT_MOD_POWER_END = UNIT_MOD_RUNIC_POWER + 1  };  enum BaseModGroup @@ -383,9 +397,10 @@ enum UnitMoveType      MOVE_TURN_RATE      = 5,      MOVE_FLIGHT         = 6,      MOVE_FLIGHT_BACK    = 7, +    MOVE_PITCH_RATE     = 8  }; -#define MAX_MOVE_TYPE 8 +#define MAX_MOVE_TYPE     9  extern float baseMoveSpeed[MAX_MOVE_TYPE]; @@ -423,10 +438,11 @@ enum CombatRating      CR_WEAPON_SKILL_MAINHAND    = 20,      CR_WEAPON_SKILL_OFFHAND     = 21,      CR_WEAPON_SKILL_RANGED      = 22, -    CR_EXPERTISE                = 23 +    CR_EXPERTISE                = 23, +    CR_ARMOR_PENETRATION        = 24  }; -#define MAX_COMBAT_RATING         24 +#define MAX_COMBAT_RATING         25  enum DamageEffectType  { @@ -460,19 +476,19 @@ enum UnitFlags      UNIT_FLAG_UNKNOWN9         = 0x00000040,      UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080,                // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE      UNIT_FLAG_NOT_ATTACKABLE_2 = 0x00000100,                // 2.0.8 -    UNIT_FLAG_UNKNOWN11        = 0x00000200, +    UNIT_FLAG_UNKNOWN11        = 0x00000200,                // 3.0.3 - makes you unable to attack everything      UNIT_FLAG_LOOTING          = 0x00000400,                // loot animation      UNIT_FLAG_PET_IN_COMBAT    = 0x00000800,                // in combat?, 2.0.8 -    UNIT_FLAG_PVP              = 0x00001000, +    UNIT_FLAG_PVP              = 0x00001000,                // changed in 3.0.3      UNIT_FLAG_SILENCED         = 0x00002000,                // silenced, 2.1.1      UNIT_FLAG_UNKNOWN4         = 0x00004000,                // 2.0.8      UNIT_FLAG_UNKNOWN13        = 0x00008000,      UNIT_FLAG_UNKNOWN14        = 0x00010000, -    UNIT_FLAG_PACIFIED         = 0x00020000, -    UNIT_FLAG_DISABLE_ROTATE   = 0x00040000,                // stunned, 2.1.1 +    UNIT_FLAG_PACIFIED         = 0x00020000,                // 3.0.3 ok +    UNIT_FLAG_STUNNED          = 0x00040000,                // 3.0.3 ok      UNIT_FLAG_IN_COMBAT        = 0x00080000,      UNIT_FLAG_TAXI_FLIGHT      = 0x00100000,                // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag -    UNIT_FLAG_DISARMED         = 0x00200000,                // disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. +    UNIT_FLAG_DISARMED         = 0x00200000,                // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip.      UNIT_FLAG_CONFUSED         = 0x00400000,      UNIT_FLAG_FLEEING          = 0x00800000,      UNIT_FLAG_UNKNOWN5         = 0x01000000,                // used in spell Eyes of the Beast for pet... @@ -487,9 +503,10 @@ enum UnitFlags  // Value masks for UNIT_FIELD_FLAGS_2  enum UnitFlags2  { -    UNIT_FLAG2_FEIGN_DEATH    = 0x00000001, -    UNIT_FLAG2_COMPREHEND_LANG= 0x00000008, -    UNIT_FLAG2_FORCE_MOVE     = 0x00000040 +    UNIT_FLAG2_FEIGN_DEATH      = 0x00000001, +    UNIT_FLAG2_COMPREHEND_LANG  = 0x00000008, +    UNIT_FLAG2_FORCE_MOVE       = 0x00000040, +    UNIT_FLAG2_REGENERATE_POWER = 0x00000800  };  /// Non Player Character flags @@ -635,8 +652,18 @@ uint32 createProcExtendMask(SpellNonMeleeDamage *damageInfo, SpellMissInfo missC  struct UnitActionBarEntry  { -    uint32 Type; -    uint32 SpellOrAction; +    union +    { +        struct  +        { +            uint16 SpellOrAction; +            uint16 Type; +        }; +        struct +        { +            uint32 Raw; +        }; +    };  };  #define MAX_DECLINED_NAME_CASES 5 @@ -658,13 +685,12 @@ enum CurrentSpellTypes  enum ActiveStates  { -    ACT_ENABLED  = 0xC100, -    ACT_DISABLED = 0x8100, -    ACT_COMMAND  = 0x0700, -    ACT_REACTION = 0x0600, -    ACT_CAST     = 0x0100, -    ACT_PASSIVE  = 0x0000, -    ACT_DECIDE   = 0x0001 +    ACT_PASSIVE  = 0x0100,                                  // 0x0100 - passive +    ACT_DISABLED = 0x8100,                                  // 0x8000 - castable +    ACT_ENABLED  = 0xC100,                                  // 0x4000 | 0x8000 - auto cast + castable +    ACT_COMMAND  = 0x0700,                                  // 0x0100 | 0x0200 | 0x0400 +    ACT_REACTION = 0x0600,                                  // 0x0200 | 0x0400 +    ACT_DECIDE   = 0x0001                                   // what is it?  };  enum ReactStates @@ -752,8 +778,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject          typedef std::multimap< spellEffectPair, Aura*> AuraMap;          typedef std::list<Aura *> AuraList;          typedef std::list<DiminishingReturn> Diminishing; -        typedef std::set<AuraType> AuraTypeSet;          typedef std::set<uint32> ComboPointHolderSet; +        typedef std::map<uint8, uint32> VisibleAuraMap;          virtual ~Unit ( ); @@ -884,8 +910,14 @@ class TRINITY_DLL_SPEC Unit : public WorldObject              return false;          } -        bool IsPvP() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); } -        void SetPvP(bool state) { if(state) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); else RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP); } +        bool IsPvP() const { return HasByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); } +        void SetPvP(bool state) +        { +            if(state) +                SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); +            else +                RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_PVP); +        }          uint32 GetCreatureType() const;          uint32 GetCreatureTypeMask() const          { @@ -1255,6 +1287,30 @@ class TRINITY_DLL_SPEC Unit : public WorldObject          void removeHatedBy(HostilReference* /*pHostilReference*/ ) { /* nothing to do yet */ }          HostilRefManager& getHostilRefManager() { return m_HostilRefManager; } +        uint32 GetVisibleAura(uint8 slot) +        { +            VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); +            if(itr != m_visibleAuras.end()) +                return itr->second; +            return 0; +        } +        void SetVisibleAura(uint8 slot, uint32 spellid) +        { +            if(spellid == 0) +            { +                VisibleAuraMap::iterator itr = m_visibleAuras.find(slot); +                if(itr != m_visibleAuras.end()) +                { +                    m_visibleAuras.erase(itr); +                    return; +                } +            } +            else +                m_visibleAuras[slot] = spellid; +        } +        VisibleAuraMap const *GetVisibleAuras() { return &m_visibleAuras; } +        uint8 GetVisibleAurasCount() { return m_visibleAuras.size(); } +          Aura* GetAura(uint32 spellId, uint32 effindex);          AuraMap      & GetAuras()       { return m_Auras; }          AuraMap const& GetAuras() const { return m_Auras; } @@ -1446,6 +1502,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject          float m_weaponDamage[MAX_ATTACK][2];          bool m_canModifyStats;          //std::list< spellEffectPair > AuraSpells[TOTAL_AURAS];  // TODO: use this if ok for mem +        VisibleAuraMap m_visibleAuras;          float m_speed_rate[MAX_MOVE_TYPE]; @@ -1459,6 +1516,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject          uint32 m_unit_movement_flags;          uint32 m_reactiveTimer[MAX_REACTIVE]; +        uint32 m_regenTimer;      private:          void SendAttackStop(Unit* victim);                  // only from AttackStop(Unit*) diff --git a/src/game/UpdateData.cpp b/src/game/UpdateData.cpp index 2b6282997e8..ce50a326917 100644 --- a/src/game/UpdateData.cpp +++ b/src/game/UpdateData.cpp @@ -108,7 +108,7 @@ bool UpdateData::BuildPacket(WorldPacket *packet, bool hasTransport)      ByteBuffer buf(m_data.size() + 10 + m_outOfRangeGUIDs.size()*8);      buf << (uint32) (!m_outOfRangeGUIDs.empty() ? m_blockCount + 1 : m_blockCount); -    buf << (uint8) (hasTransport ? 1 : 0); +    //buf << (uint8) (hasTransport ? 1 : 0);      if(!m_outOfRangeGUIDs.empty())      { diff --git a/src/game/UpdateData.h b/src/game/UpdateData.h index 8fdcac4b400..48c7fc35efc 100644 --- a/src/game/UpdateData.h +++ b/src/game/UpdateData.h @@ -38,11 +38,12 @@ enum OBJECT_UPDATE_FLAGS      UPDATEFLAG_NONE         = 0x00,      UPDATEFLAG_SELF         = 0x01,      UPDATEFLAG_TRANSPORT    = 0x02, -    UPDATEFLAG_FULLGUID     = 0x04, +    UPDATEFLAG_HAS_TARGET   = 0x04,      UPDATEFLAG_LOWGUID      = 0x08,      UPDATEFLAG_HIGHGUID     = 0x10,      UPDATEFLAG_LIVING       = 0x20, -    UPDATEFLAG_HASPOSITION  = 0x40 +    UPDATEFLAG_HAS_POSITION = 0x40, +    UPDATEFLAG_VEHICLE      = 0x80  };  class UpdateData diff --git a/src/game/UpdateFields.h b/src/game/UpdateFields.h index db64e0bc1dd..3810cb83429 100644 --- a/src/game/UpdateFields.h +++ b/src/game/UpdateFields.h @@ -21,7 +21,7 @@  #ifndef _UPDATEFIELDS_AUTO_H  #define _UPDATEFIELDS_AUTO_H -// Auto generated for version 2, 4, 3, 8606 +// Auto generated for version 3, 0, 3, 9183  enum EObjectFields  { @@ -43,13 +43,37 @@ enum EItemFields      ITEM_FIELD_DURATION                       = OBJECT_END + 0x0009, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2      ITEM_FIELD_SPELL_CHARGES                  = OBJECT_END + 0x000A, // Size: 5, Type: INT, Flags: OWNER_ONLY, UNK2      ITEM_FIELD_FLAGS                          = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC -    ITEM_FIELD_ENCHANTMENT                    = OBJECT_END + 0x0010, // Size: 33, Type: INT, Flags: PUBLIC -    ITEM_FIELD_PROPERTY_SEED                  = OBJECT_END + 0x0031, // Size: 1, Type: INT, Flags: PUBLIC -    ITEM_FIELD_RANDOM_PROPERTIES_ID           = OBJECT_END + 0x0032, // Size: 1, Type: INT, Flags: PUBLIC -    ITEM_FIELD_ITEM_TEXT_ID                   = OBJECT_END + 0x0033, // Size: 1, Type: INT, Flags: OWNER_ONLY -    ITEM_FIELD_DURABILITY                     = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 -    ITEM_FIELD_MAXDURABILITY                  = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 -    ITEM_END                                  = OBJECT_END + 0x0036, +    ITEM_FIELD_ENCHANTMENT_1_1                = OBJECT_END + 0x0010, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_1_3                = OBJECT_END + 0x0012, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_2_1                = OBJECT_END + 0x0013, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_2_3                = OBJECT_END + 0x0015, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_3_1                = OBJECT_END + 0x0016, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_3_3                = OBJECT_END + 0x0018, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_4_1                = OBJECT_END + 0x0019, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_4_3                = OBJECT_END + 0x001B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_5_1                = OBJECT_END + 0x001C, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_5_3                = OBJECT_END + 0x001E, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_6_1                = OBJECT_END + 0x001F, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_6_3                = OBJECT_END + 0x0021, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_7_1                = OBJECT_END + 0x0022, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_7_3                = OBJECT_END + 0x0024, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_8_1                = OBJECT_END + 0x0025, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_8_3                = OBJECT_END + 0x0027, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_9_1                = OBJECT_END + 0x0028, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_9_3                = OBJECT_END + 0x002A, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_10_1               = OBJECT_END + 0x002B, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_10_3               = OBJECT_END + 0x002D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_11_1               = OBJECT_END + 0x002E, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_11_3               = OBJECT_END + 0x0030, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_12_1               = OBJECT_END + 0x0031, // Size: 2, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ENCHANTMENT_12_3               = OBJECT_END + 0x0033, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    ITEM_FIELD_PROPERTY_SEED                  = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC +    ITEM_FIELD_RANDOM_PROPERTIES_ID           = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC +    ITEM_FIELD_ITEM_TEXT_ID                   = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: OWNER_ONLY +    ITEM_FIELD_DURABILITY                     = OBJECT_END + 0x0037, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 +    ITEM_FIELD_MAXDURABILITY                  = OBJECT_END + 0x0038, // Size: 1, Type: INT, Flags: OWNER_ONLY, UNK2 +    ITEM_FIELD_PAD                            = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: NONE +    ITEM_END                                  = OBJECT_END + 0x003A,  };  enum EContainerFields @@ -64,93 +88,94 @@ enum EUnitFields  {      UNIT_FIELD_CHARM                          = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC      UNIT_FIELD_SUMMON                         = OBJECT_END + 0x0002, // Size: 2, Type: LONG, Flags: PUBLIC -    UNIT_FIELD_CHARMEDBY                      = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC -    UNIT_FIELD_SUMMONEDBY                     = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC -    UNIT_FIELD_CREATEDBY                      = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC -    UNIT_FIELD_TARGET                         = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC -    UNIT_FIELD_PERSUADED                      = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC +    UNIT_FIELD_CRITTER                        = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PRIVATE +    UNIT_FIELD_CHARMEDBY                      = OBJECT_END + 0x0006, // Size: 2, Type: LONG, Flags: PUBLIC +    UNIT_FIELD_SUMMONEDBY                     = OBJECT_END + 0x0008, // Size: 2, Type: LONG, Flags: PUBLIC +    UNIT_FIELD_CREATEDBY                      = OBJECT_END + 0x000A, // Size: 2, Type: LONG, Flags: PUBLIC +    UNIT_FIELD_TARGET                         = OBJECT_END + 0x000C, // Size: 2, Type: LONG, Flags: PUBLIC      UNIT_FIELD_CHANNEL_OBJECT                 = OBJECT_END + 0x000E, // Size: 2, Type: LONG, Flags: PUBLIC -    UNIT_FIELD_HEALTH                         = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: DYNAMIC -    UNIT_FIELD_POWER1                         = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_POWER2                         = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_POWER3                         = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_POWER4                         = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_POWER5                         = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MAXHEALTH                      = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: DYNAMIC -    UNIT_FIELD_MAXPOWER1                      = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MAXPOWER2                      = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MAXPOWER3                      = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MAXPOWER4                      = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MAXPOWER5                      = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_LEVEL                          = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_FACTIONTEMPLATE                = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_BYTES_0                        = OBJECT_END + 0x001E, // Size: 1, Type: BYTES, Flags: PUBLIC -    UNIT_VIRTUAL_ITEM_SLOT_DISPLAY            = OBJECT_END + 0x001F, // Size: 3, Type: INT, Flags: PUBLIC -    UNIT_VIRTUAL_ITEM_INFO                    = OBJECT_END + 0x0022, // Size: 6, Type: BYTES, Flags: PUBLIC -    UNIT_FIELD_FLAGS                          = OBJECT_END + 0x0028, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_FLAGS_2                        = OBJECT_END + 0x0029, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_AURA                           = OBJECT_END + 0x002A, // Size: 56, Type: INT, Flags: PUBLIC -    UNIT_FIELD_AURAFLAGS                      = OBJECT_END + 0x0062, // Size: 14, Type: BYTES, Flags: PUBLIC -    UNIT_FIELD_AURALEVELS                     = OBJECT_END + 0x0070, // Size: 14, Type: BYTES, Flags: PUBLIC -    UNIT_FIELD_AURAAPPLICATIONS               = OBJECT_END + 0x007E, // Size: 14, Type: BYTES, Flags: PUBLIC -    UNIT_FIELD_AURASTATE                      = OBJECT_END + 0x008C, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_BASEATTACKTIME                 = OBJECT_END + 0x008D, // Size: 2, Type: INT, Flags: PUBLIC -    UNIT_FIELD_RANGEDATTACKTIME               = OBJECT_END + 0x008F, // Size: 1, Type: INT, Flags: PRIVATE -    UNIT_FIELD_BOUNDINGRADIUS                 = OBJECT_END + 0x0090, // Size: 1, Type: FLOAT, Flags: PUBLIC -    UNIT_FIELD_COMBATREACH                    = OBJECT_END + 0x0091, // Size: 1, Type: FLOAT, Flags: PUBLIC -    UNIT_FIELD_DISPLAYID                      = OBJECT_END + 0x0092, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_NATIVEDISPLAYID                = OBJECT_END + 0x0093, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MOUNTDISPLAYID                 = OBJECT_END + 0x0094, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_MINDAMAGE                      = OBJECT_END + 0x0095, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 -    UNIT_FIELD_MAXDAMAGE                      = OBJECT_END + 0x0096, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 -    UNIT_FIELD_MINOFFHANDDAMAGE               = OBJECT_END + 0x0097, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 -    UNIT_FIELD_MAXOFFHANDDAMAGE               = OBJECT_END + 0x0098, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 -    UNIT_FIELD_BYTES_1                        = OBJECT_END + 0x0099, // Size: 1, Type: BYTES, Flags: PUBLIC -    UNIT_FIELD_PETNUMBER                      = OBJECT_END + 0x009A, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_PET_NAME_TIMESTAMP             = OBJECT_END + 0x009B, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_PETEXPERIENCE                  = OBJECT_END + 0x009C, // Size: 1, Type: INT, Flags: OWNER_ONLY -    UNIT_FIELD_PETNEXTLEVELEXP                = OBJECT_END + 0x009D, // Size: 1, Type: INT, Flags: OWNER_ONLY -    UNIT_DYNAMIC_FLAGS                        = OBJECT_END + 0x009E, // Size: 1, Type: INT, Flags: DYNAMIC -    UNIT_CHANNEL_SPELL                        = OBJECT_END + 0x009F, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_MOD_CAST_SPEED                       = OBJECT_END + 0x00A0, // Size: 1, Type: FLOAT, Flags: PUBLIC -    UNIT_CREATED_BY_SPELL                     = OBJECT_END + 0x00A1, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_NPC_FLAGS                            = OBJECT_END + 0x00A2, // Size: 1, Type: INT, Flags: DYNAMIC -    UNIT_NPC_EMOTESTATE                       = OBJECT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_TRAINING_POINTS                      = OBJECT_END + 0x00A4, // Size: 1, Type: TWO_SHORT, Flags: OWNER_ONLY -    UNIT_FIELD_STAT0                          = OBJECT_END + 0x00A5, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_STAT1                          = OBJECT_END + 0x00A6, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_STAT2                          = OBJECT_END + 0x00A7, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_STAT3                          = OBJECT_END + 0x00A8, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_STAT4                          = OBJECT_END + 0x00A9, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POSSTAT0                       = OBJECT_END + 0x00AA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POSSTAT1                       = OBJECT_END + 0x00AB, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POSSTAT2                       = OBJECT_END + 0x00AC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POSSTAT3                       = OBJECT_END + 0x00AD, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POSSTAT4                       = OBJECT_END + 0x00AE, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_NEGSTAT0                       = OBJECT_END + 0x00AF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_NEGSTAT1                       = OBJECT_END + 0x00B0, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_NEGSTAT2                       = OBJECT_END + 0x00B1, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_NEGSTAT3                       = OBJECT_END + 0x00B2, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_NEGSTAT4                       = OBJECT_END + 0x00B3, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_RESISTANCES                    = OBJECT_END + 0x00B4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3 -    UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE     = OBJECT_END + 0x00BB, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE     = OBJECT_END + 0x00C2, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_BASE_MANA                      = OBJECT_END + 0x00C9, // Size: 1, Type: INT, Flags: PUBLIC -    UNIT_FIELD_BASE_HEALTH                    = OBJECT_END + 0x00CA, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_BYTES_2                        = OBJECT_END + 0x00CB, // Size: 1, Type: BYTES, Flags: PUBLIC -    UNIT_FIELD_ATTACK_POWER                   = OBJECT_END + 0x00CC, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_ATTACK_POWER_MODS              = OBJECT_END + 0x00CD, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_ATTACK_POWER_MULTIPLIER        = OBJECT_END + 0x00CE, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_RANGED_ATTACK_POWER            = OBJECT_END + 0x00CF, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_RANGED_ATTACK_POWER_MODS       = OBJECT_END + 0x00D0, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x00D1, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_MINRANGEDDAMAGE                = OBJECT_END + 0x00D2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_MAXRANGEDDAMAGE                = OBJECT_END + 0x00D3, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POWER_COST_MODIFIER            = OBJECT_END + 0x00D4, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_POWER_COST_MULTIPLIER          = OBJECT_END + 0x00DB, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_MAXHEALTHMODIFIER              = OBJECT_END + 0x00E2, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY -    UNIT_FIELD_PADDING                        = OBJECT_END + 0x00E3, // Size: 1, Type: INT, Flags: NONE -    UNIT_END                                  = OBJECT_END + 0x00E4, +    UNIT_FIELD_BYTES_0                        = OBJECT_END + 0x0010, // Size: 1, Type: BYTES, Flags: PUBLIC +    UNIT_FIELD_HEALTH                         = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER1                         = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER2                         = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER3                         = OBJECT_END + 0x0014, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER4                         = OBJECT_END + 0x0015, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER5                         = OBJECT_END + 0x0016, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER6                         = OBJECT_END + 0x0017, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER7                         = OBJECT_END + 0x0018, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXHEALTH                      = OBJECT_END + 0x0019, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER1                      = OBJECT_END + 0x001A, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER2                      = OBJECT_END + 0x001B, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER3                      = OBJECT_END + 0x001C, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER4                      = OBJECT_END + 0x001D, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER5                      = OBJECT_END + 0x001E, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER6                      = OBJECT_END + 0x001F, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MAXPOWER7                      = OBJECT_END + 0x0020, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_POWER_REGEN_FLAT_MODIFIER      = OBJECT_END + 0x0021, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x0028, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_LEVEL                          = OBJECT_END + 0x002F, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_FACTIONTEMPLATE                = OBJECT_END + 0x0030, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_VIRTUAL_ITEM_SLOT_ID                 = OBJECT_END + 0x0031, // Size: 3, Type: INT, Flags: PUBLIC +    UNIT_FIELD_FLAGS                          = OBJECT_END + 0x0034, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_FLAGS_2                        = OBJECT_END + 0x0035, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_AURASTATE                      = OBJECT_END + 0x0036, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_BASEATTACKTIME                 = OBJECT_END + 0x0037, // Size: 2, Type: INT, Flags: PUBLIC +    UNIT_FIELD_RANGEDATTACKTIME               = OBJECT_END + 0x0039, // Size: 1, Type: INT, Flags: PRIVATE +    UNIT_FIELD_BOUNDINGRADIUS                 = OBJECT_END + 0x003A, // Size: 1, Type: FLOAT, Flags: PUBLIC +    UNIT_FIELD_COMBATREACH                    = OBJECT_END + 0x003B, // Size: 1, Type: FLOAT, Flags: PUBLIC +    UNIT_FIELD_DISPLAYID                      = OBJECT_END + 0x003C, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_NATIVEDISPLAYID                = OBJECT_END + 0x003D, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MOUNTDISPLAYID                 = OBJECT_END + 0x003E, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_MINDAMAGE                      = OBJECT_END + 0x003F, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 +    UNIT_FIELD_MAXDAMAGE                      = OBJECT_END + 0x0040, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 +    UNIT_FIELD_MINOFFHANDDAMAGE               = OBJECT_END + 0x0041, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 +    UNIT_FIELD_MAXOFFHANDDAMAGE               = OBJECT_END + 0x0042, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY, UNK3 +    UNIT_FIELD_BYTES_1                        = OBJECT_END + 0x0043, // Size: 1, Type: BYTES, Flags: PUBLIC +    UNIT_FIELD_PETNUMBER                      = OBJECT_END + 0x0044, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_PET_NAME_TIMESTAMP             = OBJECT_END + 0x0045, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_PETEXPERIENCE                  = OBJECT_END + 0x0046, // Size: 1, Type: INT, Flags: OWNER_ONLY +    UNIT_FIELD_PETNEXTLEVELEXP                = OBJECT_END + 0x0047, // Size: 1, Type: INT, Flags: OWNER_ONLY +    UNIT_DYNAMIC_FLAGS                        = OBJECT_END + 0x0048, // Size: 1, Type: INT, Flags: DYNAMIC +    UNIT_CHANNEL_SPELL                        = OBJECT_END + 0x0049, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_MOD_CAST_SPEED                       = OBJECT_END + 0x004A, // Size: 1, Type: FLOAT, Flags: PUBLIC +    UNIT_CREATED_BY_SPELL                     = OBJECT_END + 0x004B, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_NPC_FLAGS                            = OBJECT_END + 0x004C, // Size: 1, Type: INT, Flags: DYNAMIC +    UNIT_NPC_EMOTESTATE                       = OBJECT_END + 0x004D, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_STAT0                          = OBJECT_END + 0x004E, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_STAT1                          = OBJECT_END + 0x004F, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_STAT2                          = OBJECT_END + 0x0050, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_STAT3                          = OBJECT_END + 0x0051, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_STAT4                          = OBJECT_END + 0x0052, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POSSTAT0                       = OBJECT_END + 0x0053, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POSSTAT1                       = OBJECT_END + 0x0054, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POSSTAT2                       = OBJECT_END + 0x0055, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POSSTAT3                       = OBJECT_END + 0x0056, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POSSTAT4                       = OBJECT_END + 0x0057, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_NEGSTAT0                       = OBJECT_END + 0x0058, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_NEGSTAT1                       = OBJECT_END + 0x0059, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_NEGSTAT2                       = OBJECT_END + 0x005A, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_NEGSTAT3                       = OBJECT_END + 0x005B, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_NEGSTAT4                       = OBJECT_END + 0x005C, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_RESISTANCES                    = OBJECT_END + 0x005D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY, UNK3 +    UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE     = OBJECT_END + 0x0064, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE     = OBJECT_END + 0x006B, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_BASE_MANA                      = OBJECT_END + 0x0072, // Size: 1, Type: INT, Flags: PUBLIC +    UNIT_FIELD_BASE_HEALTH                    = OBJECT_END + 0x0073, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_BYTES_2                        = OBJECT_END + 0x0074, // Size: 1, Type: BYTES, Flags: PUBLIC +    UNIT_FIELD_ATTACK_POWER                   = OBJECT_END + 0x0075, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_ATTACK_POWER_MODS              = OBJECT_END + 0x0076, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_ATTACK_POWER_MULTIPLIER        = OBJECT_END + 0x0077, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_RANGED_ATTACK_POWER            = OBJECT_END + 0x0078, // Size: 1, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_RANGED_ATTACK_POWER_MODS       = OBJECT_END + 0x0079, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x007A, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_MINRANGEDDAMAGE                = OBJECT_END + 0x007B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_MAXRANGEDDAMAGE                = OBJECT_END + 0x007C, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POWER_COST_MODIFIER            = OBJECT_END + 0x007D, // Size: 7, Type: INT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_POWER_COST_MULTIPLIER          = OBJECT_END + 0x0084, // Size: 7, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_MAXHEALTHMODIFIER              = OBJECT_END + 0x008B, // Size: 1, Type: FLOAT, Flags: PRIVATE, OWNER_ONLY +    UNIT_FIELD_HOVERHEIGHT                    = OBJECT_END + 0x008C, // Size: 1, Type: FLOAT, Flags: PUBLIC +    UNIT_FIELD_PADDING                        = OBJECT_END + 0x008D, // Size: 1, Type: INT, Flags: NONE +    UNIT_END                                  = OBJECT_END + 0x008E,      PLAYER_DUEL_ARBITER                       = UNIT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC      PLAYER_FLAGS                              = UNIT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC @@ -262,160 +287,184 @@ enum EUnitFields      PLAYER_QUEST_LOG_25_3                     = UNIT_END + 0x006C, // Size: 1, Type: BYTES, Flags: PRIVATE      PLAYER_QUEST_LOG_25_4                     = UNIT_END + 0x006D, // Size: 1, Type: INT, Flags: PRIVATE      PLAYER_VISIBLE_ITEM_1_CREATOR             = UNIT_END + 0x006E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_1_0                   = UNIT_END + 0x0070, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_1_PROPERTIES          = UNIT_END + 0x007C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_1_PAD                 = UNIT_END + 0x007D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_2_CREATOR             = UNIT_END + 0x007E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_2_0                   = UNIT_END + 0x0080, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_2_PROPERTIES          = UNIT_END + 0x008C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_2_PAD                 = UNIT_END + 0x008D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_3_CREATOR             = UNIT_END + 0x008E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_3_0                   = UNIT_END + 0x0090, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_3_PROPERTIES          = UNIT_END + 0x009C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_3_PAD                 = UNIT_END + 0x009D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_4_CREATOR             = UNIT_END + 0x009E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_4_0                   = UNIT_END + 0x00A0, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_4_PROPERTIES          = UNIT_END + 0x00AC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_4_PAD                 = UNIT_END + 0x00AD, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_5_CREATOR             = UNIT_END + 0x00AE, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_5_0                   = UNIT_END + 0x00B0, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_5_PROPERTIES          = UNIT_END + 0x00BC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_5_PAD                 = UNIT_END + 0x00BD, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_6_CREATOR             = UNIT_END + 0x00BE, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_6_0                   = UNIT_END + 0x00C0, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_6_PROPERTIES          = UNIT_END + 0x00CC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_6_PAD                 = UNIT_END + 0x00CD, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_7_CREATOR             = UNIT_END + 0x00CE, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_7_0                   = UNIT_END + 0x00D0, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_7_PROPERTIES          = UNIT_END + 0x00DC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_7_PAD                 = UNIT_END + 0x00DD, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_8_CREATOR             = UNIT_END + 0x00DE, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_8_0                   = UNIT_END + 0x00E0, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_8_PROPERTIES          = UNIT_END + 0x00EC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_8_PAD                 = UNIT_END + 0x00ED, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_9_CREATOR             = UNIT_END + 0x00EE, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_9_0                   = UNIT_END + 0x00F0, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_9_PROPERTIES          = UNIT_END + 0x00FC, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_9_PAD                 = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_10_CREATOR            = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_10_0                  = UNIT_END + 0x0100, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_10_PROPERTIES         = UNIT_END + 0x010C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_10_PAD                = UNIT_END + 0x010D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_11_CREATOR            = UNIT_END + 0x010E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_11_0                  = UNIT_END + 0x0110, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_11_PROPERTIES         = UNIT_END + 0x011C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_11_PAD                = UNIT_END + 0x011D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_12_CREATOR            = UNIT_END + 0x011E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_12_0                  = UNIT_END + 0x0120, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_12_PROPERTIES         = UNIT_END + 0x012C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_12_PAD                = UNIT_END + 0x012D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_13_CREATOR            = UNIT_END + 0x012E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_13_0                  = UNIT_END + 0x0130, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_13_PROPERTIES         = UNIT_END + 0x013C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_13_PAD                = UNIT_END + 0x013D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_14_CREATOR            = UNIT_END + 0x013E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_14_0                  = UNIT_END + 0x0140, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_14_PROPERTIES         = UNIT_END + 0x014C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_14_PAD                = UNIT_END + 0x014D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_15_CREATOR            = UNIT_END + 0x014E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_15_0                  = UNIT_END + 0x0150, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_15_PROPERTIES         = UNIT_END + 0x015C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_15_PAD                = UNIT_END + 0x015D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_16_CREATOR            = UNIT_END + 0x015E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_16_0                  = UNIT_END + 0x0160, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_16_PROPERTIES         = UNIT_END + 0x016C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_16_PAD                = UNIT_END + 0x016D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_17_CREATOR            = UNIT_END + 0x016E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_17_0                  = UNIT_END + 0x0170, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_17_PROPERTIES         = UNIT_END + 0x017C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_17_PAD                = UNIT_END + 0x017D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_18_CREATOR            = UNIT_END + 0x017E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_18_0                  = UNIT_END + 0x0180, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_18_PROPERTIES         = UNIT_END + 0x018C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_18_PAD                = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_19_CREATOR            = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_19_0                  = UNIT_END + 0x0190, // Size: 12, Type: INT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_19_PROPERTIES         = UNIT_END + 0x019C, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC -    PLAYER_VISIBLE_ITEM_19_PAD                = UNIT_END + 0x019D, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_CHOSEN_TITLE                       = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC -    PLAYER_FIELD_PAD_0                        = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: NONE -    PLAYER_FIELD_INV_SLOT_HEAD                = UNIT_END + 0x01A0, // Size: 46, Type: LONG, Flags: PRIVATE -    PLAYER_FIELD_PACK_SLOT_1                  = UNIT_END + 0x01CE, // Size: 32, Type: LONG, Flags: PRIVATE -    PLAYER_FIELD_BANK_SLOT_1                  = UNIT_END + 0x01EE, // Size: 56, Type: LONG, Flags: PRIVATE -    PLAYER_FIELD_BANKBAG_SLOT_1               = UNIT_END + 0x0226, // Size: 14, Type: LONG, Flags: PRIVATE -    PLAYER_FIELD_VENDORBUYBACK_SLOT_1         = UNIT_END + 0x0234, // Size: 24, Type: LONG, Flags: PRIVATE -    PLAYER_FIELD_KEYRING_SLOT_1               = UNIT_END + 0x024C, // Size: 64, Type: LONG, Flags: PRIVATE -    PLAYER_FIELD_VANITYPET_SLOT_1             = UNIT_END + 0x028C, // Size: 36, Type: LONG, Flags: PRIVATE -    PLAYER_FARSIGHT                           = UNIT_END + 0x02B0, // Size: 2, Type: LONG, Flags: PRIVATE -    PLAYER__FIELD_KNOWN_TITLES                = UNIT_END + 0x02B2, // Size: 2, Type: LONG, Flags: PRIVATE -    PLAYER_XP                                 = UNIT_END + 0x02B4, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_NEXT_LEVEL_XP                      = UNIT_END + 0x02B5, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_SKILL_INFO_1_1                     = UNIT_END + 0x02B6, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE -    PLAYER_CHARACTER_POINTS1                  = UNIT_END + 0x0436, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_CHARACTER_POINTS2                  = UNIT_END + 0x0437, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_TRACK_CREATURES                    = UNIT_END + 0x0438, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_TRACK_RESOURCES                    = UNIT_END + 0x0439, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_BLOCK_PERCENTAGE                   = UNIT_END + 0x043A, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_DODGE_PERCENTAGE                   = UNIT_END + 0x043B, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_PARRY_PERCENTAGE                   = UNIT_END + 0x043C, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_EXPERTISE                          = UNIT_END + 0x043D, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_OFFHAND_EXPERTISE                  = UNIT_END + 0x043E, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_CRIT_PERCENTAGE                    = UNIT_END + 0x043F, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_RANGED_CRIT_PERCENTAGE             = UNIT_END + 0x0440, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_OFFHAND_CRIT_PERCENTAGE            = UNIT_END + 0x0441, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_SPELL_CRIT_PERCENTAGE1             = UNIT_END + 0x0442, // Size: 7, Type: FLOAT, Flags: PRIVATE -    PLAYER_SHIELD_BLOCK                       = UNIT_END + 0x0449, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_EXPLORED_ZONES_1                   = UNIT_END + 0x044A, // Size: 128, Type: BYTES, Flags: PRIVATE -    PLAYER_REST_STATE_EXPERIENCE              = UNIT_END + 0x04CA, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_COINAGE                      = UNIT_END + 0x04CB, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_DAMAGE_DONE_POS          = UNIT_END + 0x04CC, // Size: 7, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_DAMAGE_DONE_NEG          = UNIT_END + 0x04D3, // Size: 7, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_DAMAGE_DONE_PCT          = UNIT_END + 0x04DA, // Size: 7, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_HEALING_DONE_POS         = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_TARGET_RESISTANCE        = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_BYTES                        = UNIT_END + 0x04E4, // Size: 1, Type: BYTES, Flags: PRIVATE -    PLAYER_AMMO_ID                            = UNIT_END + 0x04E5, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_SELF_RES_SPELL                     = UNIT_END + 0x04E6, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_PVP_MEDALS                   = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_BUYBACK_PRICE_1              = UNIT_END + 0x04E8, // Size: 12, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_BUYBACK_TIMESTAMP_1          = UNIT_END + 0x04F4, // Size: 12, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_KILLS                        = UNIT_END + 0x0500, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE -    PLAYER_FIELD_TODAY_CONTRIBUTION           = UNIT_END + 0x0501, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_YESTERDAY_CONTRIBUTION       = UNIT_END + 0x0502, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_LIFETIME_HONORBALE_KILLS     = UNIT_END + 0x0503, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_BYTES2                       = UNIT_END + 0x0504, // Size: 1, Type: BYTES, Flags: PRIVATE -    PLAYER_FIELD_WATCHED_FACTION_INDEX        = UNIT_END + 0x0505, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_COMBAT_RATING_1              = UNIT_END + 0x0506, // Size: 24, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_ARENA_TEAM_INFO_1_1          = UNIT_END + 0x051E, // Size: 18, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_HONOR_CURRENCY               = UNIT_END + 0x0530, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_ARENA_CURRENCY               = UNIT_END + 0x0531, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_MOD_MANA_REGEN               = UNIT_END + 0x0532, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_FIELD_MOD_MANA_REGEN_INTERRUPT     = UNIT_END + 0x0533, // Size: 1, Type: FLOAT, Flags: PRIVATE -    PLAYER_FIELD_MAX_LEVEL                    = UNIT_END + 0x0534, // Size: 1, Type: INT, Flags: PRIVATE -    PLAYER_FIELD_DAILY_QUESTS_1               = UNIT_END + 0x0535, // Size: 25, Type: INT, Flags: PRIVATE -    PLAYER_END                                = UNIT_END + 0x054E, +    PLAYER_VISIBLE_ITEM_1_0                   = UNIT_END + 0x0070, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_1_PROPERTIES          = UNIT_END + 0x007D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_1_SEED                = UNIT_END + 0x007E, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_1_PAD                 = UNIT_END + 0x007F, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_2_CREATOR             = UNIT_END + 0x0080, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_2_0                   = UNIT_END + 0x0082, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_2_PROPERTIES          = UNIT_END + 0x008F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_2_SEED                = UNIT_END + 0x0090, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_2_PAD                 = UNIT_END + 0x0091, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_3_CREATOR             = UNIT_END + 0x0092, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_3_0                   = UNIT_END + 0x0094, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_3_PROPERTIES          = UNIT_END + 0x00A1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_3_SEED                = UNIT_END + 0x00A2, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_3_PAD                 = UNIT_END + 0x00A3, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_4_CREATOR             = UNIT_END + 0x00A4, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_4_0                   = UNIT_END + 0x00A6, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_4_PROPERTIES          = UNIT_END + 0x00B3, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_4_SEED                = UNIT_END + 0x00B4, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_4_PAD                 = UNIT_END + 0x00B5, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_5_CREATOR             = UNIT_END + 0x00B6, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_5_0                   = UNIT_END + 0x00B8, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_5_PROPERTIES          = UNIT_END + 0x00C5, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_5_SEED                = UNIT_END + 0x00C6, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_5_PAD                 = UNIT_END + 0x00C7, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_6_CREATOR             = UNIT_END + 0x00C8, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_6_0                   = UNIT_END + 0x00CA, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_6_PROPERTIES          = UNIT_END + 0x00D7, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_6_SEED                = UNIT_END + 0x00D8, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_6_PAD                 = UNIT_END + 0x00D9, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_7_CREATOR             = UNIT_END + 0x00DA, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_7_0                   = UNIT_END + 0x00DC, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_7_PROPERTIES          = UNIT_END + 0x00E9, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_7_SEED                = UNIT_END + 0x00EA, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_7_PAD                 = UNIT_END + 0x00EB, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_8_CREATOR             = UNIT_END + 0x00EC, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_8_0                   = UNIT_END + 0x00EE, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_8_PROPERTIES          = UNIT_END + 0x00FB, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_8_SEED                = UNIT_END + 0x00FC, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_8_PAD                 = UNIT_END + 0x00FD, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_9_CREATOR             = UNIT_END + 0x00FE, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_9_0                   = UNIT_END + 0x0100, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_9_PROPERTIES          = UNIT_END + 0x010D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_9_SEED                = UNIT_END + 0x010E, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_9_PAD                 = UNIT_END + 0x010F, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_10_CREATOR            = UNIT_END + 0x0110, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_10_0                  = UNIT_END + 0x0112, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_10_PROPERTIES         = UNIT_END + 0x011F, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_10_SEED               = UNIT_END + 0x0120, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_10_PAD                = UNIT_END + 0x0121, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_11_CREATOR            = UNIT_END + 0x0122, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_11_0                  = UNIT_END + 0x0124, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_11_PROPERTIES         = UNIT_END + 0x0131, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_11_SEED               = UNIT_END + 0x0132, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_11_PAD                = UNIT_END + 0x0133, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_12_CREATOR            = UNIT_END + 0x0134, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_12_0                  = UNIT_END + 0x0136, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_12_PROPERTIES         = UNIT_END + 0x0143, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_12_SEED               = UNIT_END + 0x0144, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_12_PAD                = UNIT_END + 0x0145, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_13_CREATOR            = UNIT_END + 0x0146, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_13_0                  = UNIT_END + 0x0148, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_13_PROPERTIES         = UNIT_END + 0x0155, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_13_SEED               = UNIT_END + 0x0156, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_13_PAD                = UNIT_END + 0x0157, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_14_CREATOR            = UNIT_END + 0x0158, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_14_0                  = UNIT_END + 0x015A, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_14_PROPERTIES         = UNIT_END + 0x0167, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_14_SEED               = UNIT_END + 0x0168, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_14_PAD                = UNIT_END + 0x0169, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_15_CREATOR            = UNIT_END + 0x016A, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_15_0                  = UNIT_END + 0x016C, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_15_PROPERTIES         = UNIT_END + 0x0179, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_15_SEED               = UNIT_END + 0x017A, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_15_PAD                = UNIT_END + 0x017B, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_16_CREATOR            = UNIT_END + 0x017C, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_16_0                  = UNIT_END + 0x017E, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_16_PROPERTIES         = UNIT_END + 0x018B, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_16_SEED               = UNIT_END + 0x018C, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_16_PAD                = UNIT_END + 0x018D, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_17_CREATOR            = UNIT_END + 0x018E, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_17_0                  = UNIT_END + 0x0190, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_17_PROPERTIES         = UNIT_END + 0x019D, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_17_SEED               = UNIT_END + 0x019E, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_17_PAD                = UNIT_END + 0x019F, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_18_CREATOR            = UNIT_END + 0x01A0, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_18_0                  = UNIT_END + 0x01A2, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_18_PROPERTIES         = UNIT_END + 0x01AF, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_18_SEED               = UNIT_END + 0x01B0, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_18_PAD                = UNIT_END + 0x01B1, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_19_CREATOR            = UNIT_END + 0x01B2, // Size: 2, Type: LONG, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_19_0                  = UNIT_END + 0x01B4, // Size: 13, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_19_PROPERTIES         = UNIT_END + 0x01C1, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_19_SEED               = UNIT_END + 0x01C2, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_VISIBLE_ITEM_19_PAD                = UNIT_END + 0x01C3, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_CHOSEN_TITLE                       = UNIT_END + 0x01C4, // Size: 1, Type: INT, Flags: PUBLIC +    PLAYER_FIELD_PAD_0                        = UNIT_END + 0x01C5, // Size: 1, Type: INT, Flags: NONE +    PLAYER_FIELD_INV_SLOT_HEAD                = UNIT_END + 0x01C6, // Size: 46, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_PACK_SLOT_1                  = UNIT_END + 0x01F4, // Size: 32, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_BANK_SLOT_1                  = UNIT_END + 0x0214, // Size: 56, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_BANKBAG_SLOT_1               = UNIT_END + 0x024C, // Size: 14, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_VENDORBUYBACK_SLOT_1         = UNIT_END + 0x025A, // Size: 24, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_KEYRING_SLOT_1               = UNIT_END + 0x0272, // Size: 64, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_VANITYPET_SLOT_1             = UNIT_END + 0x02B2, // Size: 36, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_CURRENCYTOKEN_SLOT_1         = UNIT_END + 0x02D6, // Size: 64, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_QUESTBAG_SLOT_1              = UNIT_END + 0x0316, // Size: 64, Type: LONG, Flags: PRIVATE +    PLAYER_FARSIGHT                           = UNIT_END + 0x0356, // Size: 2, Type: LONG, Flags: PRIVATE +    PLAYER__FIELD_KNOWN_TITLES                = UNIT_END + 0x0358, // Size: 2, Type: LONG, Flags: PRIVATE +    PLAYER__FIELD_KNOWN_TITLES1               = UNIT_END + 0x035A, // Size: 2, Type: LONG, Flags: PRIVATE +    PLAYER_FIELD_KNOWN_CURRENCIES             = UNIT_END + 0x035C, // Size: 2, Type: LONG, Flags: PRIVATE +    PLAYER_XP                                 = UNIT_END + 0x035E, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_NEXT_LEVEL_XP                      = UNIT_END + 0x035F, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_SKILL_INFO_1_1                     = UNIT_END + 0x0360, // Size: 384, Type: TWO_SHORT, Flags: PRIVATE +    PLAYER_CHARACTER_POINTS1                  = UNIT_END + 0x04E0, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_CHARACTER_POINTS2                  = UNIT_END + 0x04E1, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_TRACK_CREATURES                    = UNIT_END + 0x04E2, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_TRACK_RESOURCES                    = UNIT_END + 0x04E3, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_BLOCK_PERCENTAGE                   = UNIT_END + 0x04E4, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_DODGE_PERCENTAGE                   = UNIT_END + 0x04E5, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_PARRY_PERCENTAGE                   = UNIT_END + 0x04E6, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_EXPERTISE                          = UNIT_END + 0x04E7, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_OFFHAND_EXPERTISE                  = UNIT_END + 0x04E8, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_CRIT_PERCENTAGE                    = UNIT_END + 0x04E9, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_RANGED_CRIT_PERCENTAGE             = UNIT_END + 0x04EA, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_OFFHAND_CRIT_PERCENTAGE            = UNIT_END + 0x04EB, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_SPELL_CRIT_PERCENTAGE1             = UNIT_END + 0x04EC, // Size: 7, Type: FLOAT, Flags: PRIVATE +    PLAYER_SHIELD_BLOCK                       = UNIT_END + 0x04F3, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE       = UNIT_END + 0x04F4, // Size: 1, Type: FLOAT, Flags: PRIVATE +    PLAYER_EXPLORED_ZONES_1                   = UNIT_END + 0x04F5, // Size: 128, Type: BYTES, Flags: PRIVATE +    PLAYER_REST_STATE_EXPERIENCE              = UNIT_END + 0x0575, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_COINAGE                      = UNIT_END + 0x0576, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MOD_DAMAGE_DONE_POS          = UNIT_END + 0x0577, // Size: 7, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MOD_DAMAGE_DONE_NEG          = UNIT_END + 0x057E, // Size: 7, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MOD_DAMAGE_DONE_PCT          = UNIT_END + 0x0585, // Size: 7, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MOD_HEALING_DONE_POS         = UNIT_END + 0x058C, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MOD_TARGET_RESISTANCE        = UNIT_END + 0x058D, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x058E, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_BYTES                        = UNIT_END + 0x058F, // Size: 1, Type: BYTES, Flags: PRIVATE +    PLAYER_AMMO_ID                            = UNIT_END + 0x0590, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_SELF_RES_SPELL                     = UNIT_END + 0x0591, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_PVP_MEDALS                   = UNIT_END + 0x0592, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_BUYBACK_PRICE_1              = UNIT_END + 0x0593, // Size: 12, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_BUYBACK_TIMESTAMP_1          = UNIT_END + 0x059F, // Size: 12, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_KILLS                        = UNIT_END + 0x05AB, // Size: 1, Type: TWO_SHORT, Flags: PRIVATE +    PLAYER_FIELD_TODAY_CONTRIBUTION           = UNIT_END + 0x05AC, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_YESTERDAY_CONTRIBUTION       = UNIT_END + 0x05AD, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_LIFETIME_HONORBALE_KILLS     = UNIT_END + 0x05AE, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_BYTES2                       = UNIT_END + 0x05AF, // Size: 1, Type: BYTES, Flags: PRIVATE +    PLAYER_FIELD_WATCHED_FACTION_INDEX        = UNIT_END + 0x05B0, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_COMBAT_RATING_1              = UNIT_END + 0x05B1, // Size: 25, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_ARENA_TEAM_INFO_1_1          = UNIT_END + 0x05CA, // Size: 18, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_HONOR_CURRENCY               = UNIT_END + 0x05DC, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_ARENA_CURRENCY               = UNIT_END + 0x05DD, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_MAX_LEVEL                    = UNIT_END + 0x05DE, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_DAILY_QUESTS_1               = UNIT_END + 0x05DF, // Size: 25, Type: INT, Flags: PRIVATE +    PLAYER_RUNE_REGEN_1                       = UNIT_END + 0x05F8, // Size: 4, Type: FLOAT, Flags: PRIVATE +    PLAYER_NO_REAGENT_COST_1                  = UNIT_END + 0x05FC, // Size: 3, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_GLYPH_SLOTS_1                = UNIT_END + 0x05FF, // Size: 8, Type: INT, Flags: PRIVATE +    PLAYER_FIELD_GLYPHS_1                     = UNIT_END + 0x0607, // Size: 8, Type: INT, Flags: PRIVATE +    PLAYER_GLYPHS_ENABLED                     = UNIT_END + 0x060F, // Size: 1, Type: INT, Flags: PRIVATE +    PLAYER_END                                = UNIT_END + 0x0610,  };  enum EGameObjectFields  {      OBJECT_FIELD_CREATED_BY                   = OBJECT_END + 0x0000, // Size: 2, Type: LONG, Flags: PUBLIC      GAMEOBJECT_DISPLAYID                      = OBJECT_END + 0x0002, // Size: 1, Type: INT, Flags: PUBLIC -    GAMEOBJECT_FLAGS                          = OBJECT_END + 0x0003, // Size: 1, Type: INT, Flags: PUBLIC -    GAMEOBJECT_ROTATION                       = OBJECT_END + 0x0004, // Size: 4, Type: FLOAT, Flags: PUBLIC -    GAMEOBJECT_STATE                          = OBJECT_END + 0x0008, // Size: 1, Type: INT, Flags: PUBLIC -    GAMEOBJECT_POS_X                          = OBJECT_END + 0x0009, // Size: 1, Type: FLOAT, Flags: PUBLIC -    GAMEOBJECT_POS_Y                          = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC -    GAMEOBJECT_POS_Z                          = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC -    GAMEOBJECT_FACING                         = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC -    GAMEOBJECT_DYN_FLAGS                      = OBJECT_END + 0x000D, // Size: 1, Type: INT, Flags: DYNAMIC -    GAMEOBJECT_FACTION                        = OBJECT_END + 0x000E, // Size: 1, Type: INT, Flags: PUBLIC -    GAMEOBJECT_TYPE_ID                        = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC +    GAMEOBJECT_FLAGS                          = OBJECT_END + 0x0003, // Size: 1, Type: TWO_SHORT, Flags: PUBLIC +    GAMEOBJECT_ROTATION                       = OBJECT_END + 0x0004, // Size: 2, Type: LONG, Flags: PUBLIC +    GAMEOBJECT_PARENTROTATION                 = OBJECT_END + 0x0006, // Size: 4, Type: FLOAT, Flags: PUBLIC +    GAMEOBJECT_POS_X                          = OBJECT_END + 0x000A, // Size: 1, Type: FLOAT, Flags: PUBLIC +    GAMEOBJECT_POS_Y                          = OBJECT_END + 0x000B, // Size: 1, Type: FLOAT, Flags: PUBLIC +    GAMEOBJECT_POS_Z                          = OBJECT_END + 0x000C, // Size: 1, Type: FLOAT, Flags: PUBLIC +    GAMEOBJECT_FACING                         = OBJECT_END + 0x000D, // Size: 1, Type: FLOAT, Flags: PUBLIC +    GAMEOBJECT_DYNAMIC                        = OBJECT_END + 0x000E, // Size: 1, Type: TWO_SHORT, Flags: DYNAMIC +    GAMEOBJECT_FACTION                        = OBJECT_END + 0x000F, // Size: 1, Type: INT, Flags: PUBLIC      GAMEOBJECT_LEVEL                          = OBJECT_END + 0x0010, // Size: 1, Type: INT, Flags: PUBLIC -    GAMEOBJECT_ARTKIT                         = OBJECT_END + 0x0011, // Size: 1, Type: INT, Flags: PUBLIC -    GAMEOBJECT_ANIMPROGRESS                   = OBJECT_END + 0x0012, // Size: 1, Type: INT, Flags: DYNAMIC -    GAMEOBJECT_PADDING                        = OBJECT_END + 0x0013, // Size: 1, Type: INT, Flags: NONE -    GAMEOBJECT_END                            = OBJECT_END + 0x0014, +    GAMEOBJECT_BYTES_1                        = OBJECT_END + 0x0011, // Size: 1, Type: BYTES, Flags: PUBLIC +    GAMEOBJECT_END                            = OBJECT_END + 0x0012,  };  enum EDynamicObjectFields diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp new file mode 100644 index 00000000000..4e1153a166b --- /dev/null +++ b/src/game/Vehicle.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 "Common.h" +#include "Log.h" +#include "WorldSession.h" +#include "WorldPacket.h" +#include "ObjectMgr.h" +#include "SpellMgr.h" +#include "Vehicle.h" +#include "MapManager.h" +#include "SpellAuras.h" +#include "Unit.h" +#include "Util.h" + +Vehicle::Vehicle() : Creature(), m_vehicleId(0) +{ +    m_isVehicle = true; +    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_LIVING | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_VEHICLE); +} + +Vehicle::~Vehicle() +{ +    if(m_uint32Values)                                      // only for fully created Object +        ObjectAccessor::Instance().RemoveObject(this); +} + +void Vehicle::AddToWorld() +{ +    ///- Register the vehicle for guid lookup +    if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); +    Unit::AddToWorld(); +} + +void Vehicle::RemoveFromWorld() +{ +    ///- Remove the vehicle from the accessor +    if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); +    ///- Don't call the function for Creature, normal mobs + totems go in a different storage +    Unit::RemoveFromWorld(); +} + +void Vehicle::setDeathState(DeathState s)                       // overwrite virtual Creature::setDeathState and Unit::setDeathState +{ +    Creature::setDeathState(s); +} + +void Vehicle::Update(uint32 diff) +{ +    Creature::Update(diff); +} + +bool Vehicle::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team) +{ +    SetMapId(map->GetId()); +    SetInstanceId(map->GetInstanceId()); + +    Object::_Create(guidlow, Entry, HIGHGUID_VEHICLE); + +    if(!InitEntry(Entry, team)) +        return false; + +    m_defaultMovementType = IDLE_MOTION_TYPE; + +    AIM_Initialize(); + +    SetVehicleId(vehicleId); + +    SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); +    SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); + +    CreatureInfo const *ci = GetCreatureInfo(); +    setFaction(team == ALLIANCE ? ci->faction_A : ci->faction_H); +    SetMaxHealth(ci->maxhealth); +    SelectLevel(ci); +    SetHealth(GetMaxHealth()); + +    return true; +} + +void Vehicle::Dismiss() +{ +    SendObjectDeSpawnAnim(GetGUID()); +    CombatStop(); +    CleanupsBeforeDelete(); +    AddObjectToRemoveList(); +} diff --git a/src/game/Vehicle.h b/src/game/Vehicle.h new file mode 100644 index 00000000000..7fd8b60c40a --- /dev/null +++ b/src/game/Vehicle.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 + */ + +#ifndef MANGOSSERVER_VEHICLE_H +#define MANGOSSERVER_VEHICLE_H + +#include "ObjectDefines.h" +#include "Creature.h" +#include "Unit.h" + +class Vehicle : public Creature +{ +    public: +        explicit Vehicle(); +        virtual ~Vehicle(); + +        void AddToWorld(); +        void RemoveFromWorld(); + +        bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 vehicleId, uint32 team); + +        void setDeathState(DeathState s);                   // overwrite virtual Creature::setDeathState and Unit::setDeathState +        void Update(uint32 diff);                           // overwrite virtual Creature::Update and Unit::Update + +        uint32 GetVehicleId() { return m_vehicleId; } +        void SetVehicleId(uint32 vehicleid) { m_vehicleId = vehicleid; } + +        void Dismiss(); + +    protected: +        uint32 m_vehicleId; + +    private: +        void SaveToDB(uint32, uint8)                        // overwrited of Creature::SaveToDB     - don't must be called +        { +            assert(false); +        } +        void DeleteFromDB()                                 // overwrited of Creature::DeleteFromDB - don't must be called +        { +            assert(false); +        } +}; +#endif diff --git a/src/game/World.cpp b/src/game/World.cpp index 7769c9a7942..1bb4e91932a 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -232,7 +232,7 @@ World::AddSession_ (WorldSession* s)      uint32 Sessions = GetActiveAndQueuedSessionCount ();      uint32 pLimit = GetPlayerAmountLimit (); -    uint32 QueueSize = GetQueueSize (); //number of players in the queue +    uint32 QueueSize = GetQueueSize ();                     //number of players in the queue      //so we don't count the user trying to      //login as a session and queue the socket that we are using @@ -249,10 +249,10 @@ World::AddSession_ (WorldSession* s)      WorldPacket packet(SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);      packet << uint8 (AUTH_OK); -    packet << uint32 (0); // unknown random value... -    packet << uint8 (0); -    packet << uint32 (0); -    packet << uint8 (s->Expansion()); // 0 - normal, 1 - TBC, must be set in database manually for each account +    packet << uint32 (0);                                   // BillingTimeRemaining +    packet << uint8 (0);                                    // BillingPlanFlags +    packet << uint32 (0);                                   // BillingTimeRested +    packet << uint8 (s->Expansion());                       // 0 - normal, 1 - TBC, must be set in database manually for each account      s->SendPacket (&packet);      UpdateMaxSessionCounters (); @@ -260,7 +260,7 @@ World::AddSession_ (WorldSession* s)      // Updates the population      if (pLimit > 0)      { -        float popu = GetActiveSessionCount (); //updated number of users on the server +        float popu = GetActiveSessionCount ();              //updated number of users on the server          popu /= pLimit;          popu *= 2;          loginDatabase.PExecute ("UPDATE realmlist SET population = '%f' WHERE id = '%d'", popu, realmID); @@ -287,10 +287,10 @@ void World::AddQueuedPlayer(WorldSession* sess)      // The 1st SMSG_AUTH_RESPONSE needs to contain other info too.      WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1);      packet << uint8 (AUTH_WAIT_QUEUE); -    packet << uint32 (0); // unknown random value... -    packet << uint8 (0); -    packet << uint32 (0); -    packet << uint8 (sess->Expansion () ? 1 : 0); // 0 - normal, 1 - TBC, must be set in database manually for each account +    packet << uint32 (0);                                   // BillingTimeRemaining +    packet << uint8 (0);                                    // BillingPlanFlags +    packet << uint32 (0);                                   // BillingTimeRested +    packet << uint8 (sess->Expansion () ? 1 : 0);                    // 0 - normal, 1 - TBC, must be set in database manually for each account      packet << uint32(GetQueuePos (sess));      sess->SendPacket (&packet); @@ -408,24 +408,30 @@ void World::LoadConfigSettings(bool reload)      rate_values[RATE_HEALTH]      = sConfig.GetFloatDefault("Rate.Health", 1);      if(rate_values[RATE_HEALTH] < 0)      { -        sLog.outError("Rate.Health (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_HEALTH]); +        sLog.outError("Rate.Health (%f) must be > 0. Using 1 instead.",rate_values[RATE_HEALTH]);          rate_values[RATE_HEALTH] = 1;      }      rate_values[RATE_POWER_MANA]  = sConfig.GetFloatDefault("Rate.Mana", 1);      if(rate_values[RATE_POWER_MANA] < 0)      { -        sLog.outError("Rate.Mana (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]); +        sLog.outError("Rate.Mana (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_MANA]);          rate_values[RATE_POWER_MANA] = 1;      }      rate_values[RATE_POWER_RAGE_INCOME] = sConfig.GetFloatDefault("Rate.Rage.Income", 1);      rate_values[RATE_POWER_RAGE_LOSS]   = sConfig.GetFloatDefault("Rate.Rage.Loss", 1);      if(rate_values[RATE_POWER_RAGE_LOSS] < 0)      { -        sLog.outError("Rate.Rage.Loss (%f) mustbe > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]); +        sLog.outError("Rate.Rage.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RAGE_LOSS]);          rate_values[RATE_POWER_RAGE_LOSS] = 1;      } +    rate_values[RATE_POWER_RUNICPOWER_INCOME] = sConfig.GetFloatDefault("Rate.RunicPower.Income", 1); +    rate_values[RATE_POWER_RUNICPOWER_LOSS]   = sConfig.GetFloatDefault("Rate.RunicPower.Loss", 1); +    if(rate_values[RATE_POWER_RUNICPOWER_LOSS] < 0) +    { +        sLog.outError("Rate.RunicPower.Loss (%f) must be > 0. Using 1 instead.",rate_values[RATE_POWER_RUNICPOWER_LOSS]); +        rate_values[RATE_POWER_RUNICPOWER_LOSS] = 1; +    }      rate_values[RATE_POWER_FOCUS] = sConfig.GetFloatDefault("Rate.Focus", 1.0f); -    rate_values[RATE_LOYALTY]     = sConfig.GetFloatDefault("Rate.Loyalty", 1.0f);      rate_values[RATE_SKILL_DISCOVERY] = sConfig.GetFloatDefault("Rate.Skill.Discovery", 1.0f);      rate_values[RATE_DROP_ITEM_POOR]       = sConfig.GetFloatDefault("Rate.Drop.Item.Poor", 1.0f);      rate_values[RATE_DROP_ITEM_NORMAL]     = sConfig.GetFloatDefault("Rate.Drop.Item.Normal", 1.0f); @@ -617,6 +623,15 @@ void World::LoadConfigSettings(bool reload)          m_configs[CONFIG_CHARACTERS_PER_ACCOUNT] = m_configs[CONFIG_CHARACTERS_PER_REALM];      } +    m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = sConfig.GetIntDefault("HeroicCharactersPerRealm", 1); +    if(m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] < 0 || m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] > 10) +    { +        sLog.outError("HeroicCharactersPerRealm (%i) must be in range 0..10. Set to 1.",m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM]); +        m_configs[CONFIG_HEROIC_CHARACTERS_PER_REALM] = 1; +    } + +    m_configs[CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING] = sConfig.GetIntDefault("MinLevelForHeroicCharacterCreating", 55); +      m_configs[CONFIG_SKIP_CINEMATICS] = sConfig.GetIntDefault("SkipCinematics", 0);      if(m_configs[CONFIG_SKIP_CINEMATICS] < 0 || m_configs[CONFIG_SKIP_CINEMATICS] > 2)      { @@ -651,6 +666,20 @@ void World::LoadConfigSettings(bool reload)          m_configs[CONFIG_START_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL];      } +    m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = sConfig.GetIntDefault("StartHeroicPlayerLevel", 55); +    if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] < 1) +    { +        sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to 55.", +            m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); +        m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = 55; +    } +    else if(m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] > m_configs[CONFIG_MAX_PLAYER_LEVEL]) +    { +        sLog.outError("StartHeroicPlayerLevel (%i) must be in range 1..MaxPlayerLevel(%u). Set to %u.", +            m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL],m_configs[CONFIG_MAX_PLAYER_LEVEL]); +        m_configs[CONFIG_START_HEROIC_PLAYER_LEVEL] = m_configs[CONFIG_MAX_PLAYER_LEVEL]; +    } +      m_configs[CONFIG_START_PLAYER_MONEY] = sConfig.GetIntDefault("StartPlayerMoney", 0);      if(m_configs[CONFIG_START_PLAYER_MONEY] < 0)      { @@ -712,8 +741,9 @@ void World::LoadConfigSettings(bool reload)      m_configs[CONFIG_INSTANCE_IGNORE_RAID]  = sConfig.GetBoolDefault("Instance.IgnoreRaid", false);      m_configs[CONFIG_BATTLEGROUND_CAST_DESERTER]              = sConfig.GetBoolDefault("Battleground.CastDeserter", true); -    m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE]     = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", true); +    m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE]     = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", false);      m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false); +    m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE]            = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false);      m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true);      m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR]  = sConfig.GetIntDefault("Instance.ResetTimeHour", 4); @@ -723,17 +753,17 @@ void World::LoadConfigSettings(bool reload)      m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9);      if(m_configs[CONFIG_MIN_PETITION_SIGNS] > 9)      { -        sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.",m_configs[CONFIG_MIN_PETITION_SIGNS]); +        sLog.outError("MinPetitionSigns (%i) must be in range 0..9. Set to 9.", m_configs[CONFIG_MIN_PETITION_SIGNS]);          m_configs[CONFIG_MIN_PETITION_SIGNS] = 9;      } -    m_configs[CONFIG_GM_LOGIN_STATE]       = sConfig.GetIntDefault("GM.LoginState",2); -    m_configs[CONFIG_GM_ACCEPT_TICKETS]    = sConfig.GetIntDefault("GM.AcceptTickets",2); -    m_configs[CONFIG_GM_CHAT]              = sConfig.GetIntDefault("GM.Chat",2); -    m_configs[CONFIG_GM_WISPERING_TO]      = sConfig.GetIntDefault("GM.WhisperingTo",2); +    m_configs[CONFIG_GM_LOGIN_STATE]       = sConfig.GetIntDefault("GM.LoginState", 2); +    m_configs[CONFIG_GM_ACCEPT_TICKETS]    = sConfig.GetIntDefault("GM.AcceptTickets", 2); +    m_configs[CONFIG_GM_CHAT]              = sConfig.GetIntDefault("GM.Chat", 2); +    m_configs[CONFIG_GM_WISPERING_TO]      = sConfig.GetIntDefault("GM.WhisperingTo", 2); -    m_configs[CONFIG_GM_IN_GM_LIST]        = sConfig.GetBoolDefault("GM.InGMList",false); -    m_configs[CONFIG_GM_IN_WHO_LIST]       = sConfig.GetBoolDefault("GM.InWhoList",false); +    m_configs[CONFIG_GM_IN_GM_LIST]        = sConfig.GetBoolDefault("GM.InGMList", false); +    m_configs[CONFIG_GM_IN_WHO_LIST]       = sConfig.GetBoolDefault("GM.InWhoList", false);      m_configs[CONFIG_GM_LOG_TRADE]         = sConfig.GetBoolDefault("GM.LogTrade", false);      m_configs[CONFIG_START_GM_LEVEL] = sConfig.GetIntDefault("GM.StartLevel", 1); @@ -774,6 +804,7 @@ void World::LoadConfigSettings(bool reload)      m_configs[CONFIG_SKILL_CHANCE_SKINNING_STEPS]   = sConfig.GetIntDefault("SkillChance.SkinningSteps",75);      m_configs[CONFIG_SKILL_PROSPECTING] = sConfig.GetBoolDefault("SkillChance.Prospecting",false); +    m_configs[CONFIG_SKILL_MILLING] = sConfig.GetBoolDefault("SkillChance.Milling",false);      m_configs[CONFIG_SKILL_GAIN_CRAFTING]  = sConfig.GetIntDefault("SkillGain.Crafting", 1);      if(m_configs[CONFIG_SKILL_GAIN_CRAFTING] < 0) @@ -1060,12 +1091,18 @@ void World::SetInitialWorldSettings()      sLog.outString( "Loading InstanceTemplate" );      objmgr.LoadInstanceTemplate(); +    sLog.outString( "Loading AchievementCriteriaList..." ); +    objmgr.LoadAchievementCriteriaList(); + +    sLog.outString( "Loading completed achievements..." ); +    objmgr.LoadCompletedAchievements(); +      sLog.outString( "Loading SkillLineAbilityMultiMap Data..." );      spellmgr.LoadSkillLineAbilityMap();      ///- Clean up and pack instances      sLog.outString( "Cleaning up instances..." ); -    sInstanceSaveManager.CleanupInstances();                              // must be called before `creature_respawn`/`gameobject_respawn` tables +    sInstanceSaveManager.CleanupInstances();                // must be called before `creature_respawn`/`gameobject_respawn` tables      sLog.outString( "Packing instances..." );      sInstanceSaveManager.PackInstances(); @@ -1191,6 +1228,9 @@ void World::SetInitialWorldSettings()      sLog.outString( "Loading spell pet auras..." );      spellmgr.LoadSpellPetAuras(); +    sLog.outString( "Loading pet levelup spells..." ); +    spellmgr.LoadPetLevelupSpellMap(); +      sLog.outString( "Loading spell extra attributes...(TODO)" );      spellmgr.LoadSpellCustomAttr(); @@ -1670,6 +1710,9 @@ void World::ScriptsProcess()                  case HIGHGUID_PET:                      source = HashMapHolder<Pet>::Find(step.sourceGUID);                      break; +                case HIGHGUID_VEHICLE: +                    source = HashMapHolder<Vehicle>::Find(step.sourceGUID); +                    break;                  case HIGHGUID_PLAYER:                      source = HashMapHolder<Player>::Find(step.sourceGUID);                      break; @@ -1699,6 +1742,9 @@ void World::ScriptsProcess()                  case HIGHGUID_PET:                      target = HashMapHolder<Pet>::Find(step.targetGUID);                      break; +                case HIGHGUID_VEHICLE: +                    target = HashMapHolder<Vehicle>::Find(step.targetGUID); +                    break;                  case HIGHGUID_PLAYER:                       // empty GUID case also                      target = HashMapHolder<Player>::Find(step.targetGUID);                      break; diff --git a/src/game/World.h b/src/game/World.h index 4dab7b97b88..1b4fbe6d035 100644 --- a/src/game/World.h +++ b/src/game/World.h @@ -102,9 +102,12 @@ enum WorldConfigs      CONFIG_CHARACTERS_CREATING_DISABLED,      CONFIG_CHARACTERS_PER_ACCOUNT,      CONFIG_CHARACTERS_PER_REALM, +    CONFIG_HEROIC_CHARACTERS_PER_REALM, +    CONFIG_MIN_LEVEL_FOR_HEROIC_CHARACTER_CREATING,      CONFIG_SKIP_CINEMATICS,      CONFIG_MAX_PLAYER_LEVEL,      CONFIG_START_PLAYER_LEVEL, +    CONFIG_START_HEROIC_PLAYER_LEVEL,      CONFIG_START_PLAYER_MONEY,      CONFIG_MAX_HONOR_POINTS,      CONFIG_START_HONOR_POINTS, @@ -182,7 +185,9 @@ enum WorldConfigs      CONFIG_ARENA_RATING_DISCARD_TIMER,      CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS,      CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS, +    CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE,      CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER, +    CONFIG_SKILL_MILLING,      CONFIG_MAX_WHO,      CONFIG_BG_START_MUSIC, @@ -208,6 +213,8 @@ enum Rates      RATE_POWER_MANA,      RATE_POWER_RAGE_INCOME,      RATE_POWER_RAGE_LOSS, +    RATE_POWER_RUNICPOWER_INCOME, +    RATE_POWER_RUNICPOWER_LOSS,      RATE_POWER_FOCUS,      RATE_SKILL_DISCOVERY,      RATE_DROP_ITEM_POOR, @@ -251,7 +258,6 @@ enum Rates      RATE_MINING_AMOUNT,      RATE_MINING_NEXT,      RATE_TALENT, -    RATE_LOYALTY,      RATE_CORPSE_DECAY_LOOTED,      RATE_INSTANCE_RESET_TIME,      RATE_TARGET_POS_RECALCULATION_RANGE, diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 47e1334198e..d49fe1cda83 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -525,3 +525,90 @@ void WorldSession::SendAuthWaitQue(uint32 position)          SendPacket(&packet);      }  } + +void WorldSession::LoadAccountData() +{ +    for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) +    { +        AccountData data; +        m_accountData[i] = data; +    } + +    QueryResult *result = CharacterDatabase.PQuery("SELECT type, time, data FROM account_data WHERE account='%u'", GetAccountId()); + +    if(!result) +        return; + +    do  +    { +        Field *fields = result->Fetch(); + +        uint32 type = fields[0].GetUInt32(); +        if(type < NUM_ACCOUNT_DATA_TYPES) +        { +            m_accountData[type].Time = fields[1].GetUInt32(); +            m_accountData[type].Data = fields[2].GetCppString(); +        } +    } while (result->NextRow()); + +    delete result; +} + +void WorldSession::SetAccountData(uint32 type, time_t time_, std::string data) +{ +    m_accountData[type].Time = time_; +    m_accountData[type].Data = data; + +    uint32 acc = GetAccountId(); +    CharacterDatabase.PExecute("DELETE FROM account_data WHERE account='%u' AND type='%u'", acc, type); +    CharacterDatabase.escape_string(data); +    CharacterDatabase.PExecute("INSERT INTO account_data VALUES ('%u','%u','%u','%s')", acc, type, (uint32)time_, data.c_str()); +} + +void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) +{ +    CHECK_PACKET_SIZE(data, data.rpos()+4+2+4+4+4+4+4); +    data >> mi->flags; +    data >> mi->unk1; +    data >> mi->time; +    data >> mi->x; +    data >> mi->y; +    data >> mi->z; +    data >> mi->o; + +    if(mi->flags & MOVEMENTFLAG_ONTRANSPORT) +    { +        CHECK_PACKET_SIZE(data, data.rpos()+8+4+4+4+4+4+1); +        data >> mi->t_guid; +        data >> mi->t_x; +        data >> mi->t_y; +        data >> mi->t_z; +        data >> mi->t_o; +        data >> mi->t_time; +        data >> mi->t_seat; +    } + +    if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20)) +    { +        CHECK_PACKET_SIZE(data, data.rpos()+4); +        data >> mi->s_pitch; +    } + +    CHECK_PACKET_SIZE(data, data.rpos()+4); +    data >> mi->fallTime; + +    if(mi->flags & MOVEMENTFLAG_JUMPING) +    { +        CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4); +        data >> mi->j_unk; +        data >> mi->j_sinAngle; +        data >> mi->j_cosAngle; +        data >> mi->j_xyspeed; +    } + +    if(mi->flags & MOVEMENTFLAG_SPLINE) +    { +        CHECK_PACKET_SIZE(data, data.rpos()+4); +        data >> mi->u_unk1; +    } +} diff --git a/src/game/WorldSession.h b/src/game/WorldSession.h index 0ccb8dd9fbb..034036db887 100644 --- a/src/game/WorldSession.h +++ b/src/game/WorldSession.h @@ -47,6 +47,16 @@ class CharacterHandler;  #define CHECK_PACKET_SIZE(P,S) if((P).size() < (S)) return SizeError((P),(S)); +#define NUM_ACCOUNT_DATA_TYPES 8 + +struct AccountData +{ +    AccountData() : Time(NULL), Data("") {} + +    time_t Time; +    std::string Data; +}; +  enum PartyOperation  {      PARTY_OP_INVITE = 0, @@ -81,6 +91,8 @@ class TRINITY_DLL_SPEC WorldSession          void SizeError(WorldPacket const& packet, uint32 size) const; +        void ReadMovementInfo(WorldPacket &data, MovementInfo *mi); +          void SendPacket(WorldPacket const* packet);          void SendNotification(const char *format,...) ATTR_PRINTF(2,3);          void SendNotification(int32 string_id,...); @@ -153,6 +165,11 @@ class TRINITY_DLL_SPEC WorldSession          //pet          void SendPetNameQuery(uint64 guid, uint32 petnumber); +        // Account Data +        AccountData *GetAccountData(uint32 type) { return &m_accountData[type]; } +        void SetAccountData(uint32 type, time_t time_, std::string data); +        void LoadAccountData(); +          //mail                                                              //used with item_page table          bool SendItemInfo( uint32 itemid, WorldPacket data ); @@ -309,6 +326,7 @@ class TRINITY_DLL_SPEC WorldSession          void HandleGameObjectUseOpcode(WorldPacket& recPacket);          void HandleMeetingStoneInfo(WorldPacket& recPacket); +        void HandleGameobjectReportUse(WorldPacket& recvPacket);          void HandleNameQueryOpcode(WorldPacket& recvPacket); @@ -324,7 +342,8 @@ class TRINITY_DLL_SPEC WorldSession          void HandleMovementOpcodes(WorldPacket& recvPacket);          void HandlePossessedMovement(WorldPacket& recv_data, MovementInfo& movementInfo, uint32& MovementFlags);          void HandleSetActiveMoverOpcode(WorldPacket &recv_data); -        void HandleNotActiveMoverOpcode(WorldPacket &recv_data); +        void HandleMoveNotActiveMover(WorldPacket &recv_data); +        void HandleDismissControlledVehicle(WorldPacket &recv_data);          void HandleMoveTimeSkippedOpcode(WorldPacket &recv_data);          void HandleRequestRaidInfoOpcode( WorldPacket & recv_data ); @@ -385,7 +404,7 @@ class TRINITY_DLL_SPEC WorldSession          void HandleGuildSaveEmblemOpcode(WorldPacket& recvPacket);          void HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvPacket); -        void HandleTaxiQueryAvailableNodesOpcode(WorldPacket& recvPacket); +        void HandleTaxiQueryAvailableNodes(WorldPacket& recvPacket);          void HandleActivateTaxiOpcode(WorldPacket& recvPacket);          void HandleActivateTaxiFarOpcode(WorldPacket& recvPacket);          void HandleTaxiNextDestinationOpcode(WorldPacket& recvPacket); @@ -429,6 +448,7 @@ class TRINITY_DLL_SPEC WorldSession          void HandleAuctionRemoveItem( WorldPacket & recv_data );          void HandleAuctionListOwnerItems( WorldPacket & recv_data );          void HandleAuctionPlaceBid( WorldPacket & recv_data ); +        void HandleAuctionListPendingSales( WorldPacket & recv_data );          void HandleGetMail( WorldPacket & recv_data );          void HandleSendMail( WorldPacket & recv_data ); @@ -543,6 +563,7 @@ class TRINITY_DLL_SPEC WorldSession          void HandlePetUnlearnOpcode( WorldPacket& recvPacket );          void HandlePetSpellAutocastOpcode( WorldPacket& recvPacket );          void HandlePetCastSpellOpcode( WorldPacket& recvPacket ); +        void HandlePetLearnTalent( WorldPacket& recvPacket );          void HandleSetActionBar(WorldPacket& recv_data); @@ -579,10 +600,9 @@ class TRINITY_DLL_SPEC WorldSession          void HandleLfmSetNoneOpcode(WorldPacket& recv_data);          void HandleLfmSetOpcode(WorldPacket& recv_data);          void HandleLfgSetCommentOpcode(WorldPacket& recv_data); -        void HandleNewUnknownOpcode(WorldPacket& recv_data);          void HandleChooseTitleOpcode(WorldPacket& recv_data);          void HandleRealmStateRequestOpcode(WorldPacket& recv_data); -        void HandleAllowMoveAckOpcode(WorldPacket& recv_data); +        void HandleTimeSyncResp(WorldPacket& recv_data);          void HandleWhoisOpcode(WorldPacket& recv_data);          void HandleResetInstancesOpcode(WorldPacket& recv_data); @@ -628,6 +648,29 @@ class TRINITY_DLL_SPEC WorldSession          void HandleGuildBankBuyTab(WorldPacket& recv_data);          void HandleGuildBankTabText(WorldPacket& recv_data);          void HandleGuildBankSetTabText(WorldPacket& recv_data); + +        // Calendar +        void HandleCalendarGetCalendar(WorldPacket& recv_data); +        void HandleCalendarGetEvent(WorldPacket& recv_data); +        void HandleCalendarGuildFilter(WorldPacket& recv_data); +        void HandleCalendarArenaTeam(WorldPacket& recv_data); +        void HandleCalendarAddEvent(WorldPacket& recv_data); +        void HandleCalendarUpdateEvent(WorldPacket& recv_data); +        void HandleCalendarRemoveEvent(WorldPacket& recv_data); +        void HandleCalendarCopyEvent(WorldPacket& recv_data); +        void HandleCalendarEventInvite(WorldPacket& recv_data); +        void HandleCalendarEventRsvp(WorldPacket& recv_data); +        void HandleCalendarEventRemoveInvite(WorldPacket& recv_data); +        void HandleCalendarEventStatus(WorldPacket& recv_data); +        void HandleCalendarEventModeratorStatus(WorldPacket& recv_data); +        void HandleCalendarComplain(WorldPacket& recv_data); +        void HandleCalendarGetNumPending(WorldPacket& recv_data); + +        void HandleSpellClick(WorldPacket& recv_data); +        void HandleAlterAppearance(WorldPacket& recv_data); +        void HandleRemoveGlyph(WorldPacket& recv_data); +        void HandleCharCustomize(WorldPacket& recv_data); +        void HandleInspectAchievements(WorldPacket& recv_data);      private:          // private trade methods          void moveItems(Item* myItems[], Item* hisItems[]); @@ -650,6 +693,7 @@ class TRINITY_DLL_SPEC WorldSession          LocaleConstant m_sessionDbcLocale;          int m_sessionDbLocaleIndex;          uint32 m_latency; +        AccountData m_accountData[NUM_ACCOUNT_DATA_TYPES];          ZThread::LockedQueue<WorldPacket*,ZThread::FastMutex> _recvQueue;  }; diff --git a/src/game/WorldSocket.cpp b/src/game/WorldSocket.cpp index 01d5a0e5490..2ae97819116 100644 --- a/src/game/WorldSocket.cpp +++ b/src/game/WorldSocket.cpp @@ -54,8 +54,48 @@  struct ServerPktHeader  { -    uint16 size; -    uint16 cmd; +    /** +     * size is the length of the payload _plus_ the length of the opcode +     */ +    ServerPktHeader(uint32 size, uint16 cmd) : size(size) +    { +        uint8 headerIndex=0; +        if(isLargePacket()) +        { +            sLog.outDebug("initializing large server to client packet. Size: %u, cmd: %u", size, cmd); +            header= new uint8[5]; +            header[headerIndex++] = 0x80|(0xFF &(size>>16)); +        } +        else +        { +            header= new uint8[4]; +        } + +        header[headerIndex++] = 0xFF &(size>>8); +        header[headerIndex++] = 0xFF &size; + +        header[headerIndex++] = 0xFF & cmd; +        header[headerIndex++] = 0xFF & (cmd>>8); +    } + +    ~ServerPktHeader() +    { +        delete[] header; +    } + +    uint8 getHeaderLength() +    { +        // cmd = 2 bytes, size= 2||3bytes +        return 2+(isLargePacket()?3:2); +    } + +    bool isLargePacket() +    { +        return size > 0x7FFF; +    } + +    const uint32 size; +    uint8 *header;  };  struct ClientPktHeader @@ -639,7 +679,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)      // NOTE: ATM the socket is singlethread, have this in mind ...      uint8 digest[20];      uint32 clientSeed; -    uint32 unk2; +    uint32 unk2, unk3;      uint32 BuiltNumberClient;      uint32 id, security;      //uint8 expansion = 0; @@ -661,6 +701,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)      recvPacket >> BuiltNumberClient;                        // for now no use      recvPacket >> unk2;      recvPacket >> account; +    recvPacket >> unk3;      if (recvPacket.size () < (4 + 4 + (account.size () + 1) + 4 + 20))      { @@ -880,6 +921,8 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket)      m_Crypt.SetKey (&K);      m_Crypt.Init (); +    m_Session->LoadAccountData(); +      // In case needed sometime the second arg is in microseconds 1 000 000 = 1 sec      ACE_OS::sleep (ACE_Time_Value (0, 10000)); @@ -963,23 +1006,17 @@ int WorldSocket::HandlePing (WorldPacket& recvPacket)  int WorldSocket::iSendPacket (const WorldPacket& pct)  { -    if (m_OutBuffer->space () < pct.size () + sizeof (ServerPktHeader)) +    ServerPktHeader header(pct.size()+2, pct.GetOpcode()); +    if (m_OutBuffer->space () < pct.size () + header.getHeaderLength())      {          errno = ENOBUFS;          return -1;      } -    ServerPktHeader header; - -    header.cmd = pct.GetOpcode (); -    EndianConvert(header.cmd); - -    header.size = (uint16) pct.size () + 2; -    EndianConvertReverse(header.size); -    m_Crypt.EncryptSend ((uint8*) & header, sizeof (header)); +    m_Crypt.EncryptSend ( header.header, header.getHeaderLength()); -    if (m_OutBuffer->copy ((char*) & header, sizeof (header)) == -1) +    if (m_OutBuffer->copy ((char*) header.header, header.getHeaderLength()) == -1)          ACE_ASSERT (false);      if (!pct.empty ()) diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index 878c4f5a711..8ec580f0c9f 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -63,6 +63,7 @@ bool ChatHandler::HandleDebugSpellFailCommand(const char* args)      uint8 failnum = (uint8)atoi(px);      WorldPacket data(SMSG_CAST_FAILED, 5); +    data << uint8(0);      data << uint32(133);      data << uint8(failnum);      m_session->SendPacket(&data); @@ -569,4 +570,54 @@ bool ChatHandler::HandleDebugHostilRefList(const char * /*args*/)      }      SendSysMessage("End of hostil reference list.");      return true; +} + +bool ChatHandler::HandleSpawnVehicle(const char* args) +{ +    if(!args) +        return false; + +    char* e = strtok((char*)args, " "); +    char* i = strtok(NULL, " "); + +    if (!e || !i) +        return false; + +    uint32 entry = (uint32)atoi(e); +    uint32 id = (uint32)atoi(i); + +    CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); + +    if(!ci) +        return false; + +    VehicleEntry const *ve = sVehicleStore.LookupEntry(id); + +    if(!ve) +        return false; + +    Vehicle *v = new Vehicle; +    Map *map = m_session->GetPlayer()->GetMap(); +    if(!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam())) +    { +        delete v; +        return false; +    } + +    float px, py, pz; +    m_session->GetPlayer()->GetClosePoint(px, py, pz, m_session->GetPlayer()->GetObjectSize()); + +    v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation()); + +    if(!v->IsPositionValid()) +    { +        sLog.outError("ERROR: Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)", +            v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY()); +        delete v; +        return false; +    } + +    map->Add((Creature*)v); + +    return true;  }
\ No newline at end of file diff --git a/src/game/tools.cpp b/src/game/tools.cpp deleted file mode 100644 index 7abc016df48..00000000000 --- a/src/game/tools.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/> - * - * Copyright (C) 2008 Trinity <http://www.trinitycore.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 "Tools.h" - -// THIS CAN BE A LOT FASTER -bool readGUID(WorldPacket & data, uint64& guid) -{ -    if(data.rpos()+1 > data.size()) -        return false; - -    uint8 guidmark=0; -    uint8 bit; -    uint8 shiftdata=0x1; -    uint64 Temp=0; - -    guid = 0; - -    data >> guidmark; -    for(int i=0;i<8;i++) -    { -        if(guidmark & shiftdata) -        { -            Temp = 0; - -            if(data.rpos()+1 > data.size()) -                return false; - -            data >> bit; -            Temp = bit; -            Temp <<= i*8; -            guid |= Temp; -        } -        shiftdata=shiftdata<<1; -    } - -    return true; -} - -void  writeGUID(WorldPacket & data, uint64 & guid) -{ -    uint8 RAWmask = 0; -    uint8 PackedGuid[8] = {0,0,0,0,0,0,0,0}; - -    int j = 1; -    uint8 * test = (uint8*)&guid; - -    if (*test) -    { -        PackedGuid[j] = *test; -        RAWmask |= 1; -        ++j; -    } -    if (*(test+1)) -    { -        PackedGuid[j] = *(test+1); -        RAWmask |= 2; -        ++j; -    } -    if (*(test+2)) -    { -        PackedGuid[j] = *(test+2); -        RAWmask |= 4; -        ++j; -    } -    if (*(test+3)) -    { -        PackedGuid[j] = *(test+3); -        RAWmask |= 8; -        ++j; -    } -    if (*(test+4)) -    { -        PackedGuid[j] = *(test+4); -        RAWmask |= 16; -        ++j; -    } -    if (*(test+5)) -    { -        PackedGuid[j] = *(test+5); -        RAWmask |= 32; -        ++j; -    } -    if (*(test+6)) -    { -        PackedGuid[j] = *(test+6); -        RAWmask |= 64; -        ++j; -    } -    if (*(test+7)) -    { -        PackedGuid[j] = *(test+7); -        RAWmask |= 128; -        ++j; -    } -    PackedGuid[0] = RAWmask; - -    data.append(PackedGuid,j); -} diff --git a/src/trinitycore/CliRunnable.cpp b/src/mangosd/CliRunnable.cpp index 7fe2ab784a6..7fe2ab784a6 100644 --- a/src/trinitycore/CliRunnable.cpp +++ b/src/mangosd/CliRunnable.cpp diff --git a/src/trinitycore/CliRunnable.h b/src/mangosd/CliRunnable.h index c3c1792b6e8..c3c1792b6e8 100644 --- a/src/trinitycore/CliRunnable.h +++ b/src/mangosd/CliRunnable.h diff --git a/src/trinitycore/Main.cpp b/src/mangosd/Main.cpp index 3767e73b844..1e4230db1a3 100644 --- a/src/trinitycore/Main.cpp +++ b/src/mangosd/Main.cpp @@ -29,7 +29,7 @@  #include "Master.h"  #ifndef _TRINITY_CORE_CONFIG -# define _TRINITY_CORE_CONFIG  "trinitycore.conf" +# define _TRINITY_CORE_CONFIG  "TrinityCore.conf"  #endif //_TRINITY_CORE_CONFIG  // Format is YYYYMMDDRR where RR is the change in the conf file @@ -40,7 +40,7 @@  #ifdef WIN32  #include "ServiceWin32.h" -char serviceName[] = "Trinityd"; +char serviceName[] = "TrinityCore";  char serviceLongName[] = "Trinity core service";  char serviceDescription[] = "Massive Network Game Object Server";  /* diff --git a/src/trinitycore/Makefile.am b/src/mangosd/Makefile.am index ad1b78d9033..ad1b78d9033 100644 --- a/src/trinitycore/Makefile.am +++ b/src/mangosd/Makefile.am diff --git a/src/trinitycore/Master.cpp b/src/mangosd/Master.cpp index eea1606256c..eea1606256c 100644 --- a/src/trinitycore/Master.cpp +++ b/src/mangosd/Master.cpp diff --git a/src/trinitycore/Master.h b/src/mangosd/Master.h index 2485dd456b1..2485dd456b1 100644 --- a/src/trinitycore/Master.h +++ b/src/mangosd/Master.h diff --git a/src/trinitycore/RASocket.cpp b/src/mangosd/RASocket.cpp index f953dc3f592..f953dc3f592 100644 --- a/src/trinitycore/RASocket.cpp +++ b/src/mangosd/RASocket.cpp diff --git a/src/trinitycore/RASocket.h b/src/mangosd/RASocket.h index a164c9d3aa2..a164c9d3aa2 100644 --- a/src/trinitycore/RASocket.h +++ b/src/mangosd/RASocket.h diff --git a/src/trinitycore/TrinityCore.ico b/src/mangosd/TrinityCore.ico Binary files differindex 6f0a5721957..6f0a5721957 100644 --- a/src/trinitycore/TrinityCore.ico +++ b/src/mangosd/TrinityCore.ico diff --git a/src/trinitycore/WorldRunnable.cpp b/src/mangosd/WorldRunnable.cpp index b57dbc6bce2..b57dbc6bce2 100644 --- a/src/trinitycore/WorldRunnable.cpp +++ b/src/mangosd/WorldRunnable.cpp diff --git a/src/trinitycore/WorldRunnable.h b/src/mangosd/WorldRunnable.h index 8891186dec4..8891186dec4 100644 --- a/src/trinitycore/WorldRunnable.h +++ b/src/mangosd/WorldRunnable.h diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.in new file mode 100644 index 00000000000..7f94d626c26 --- /dev/null +++ b/src/mangosd/mangosd.conf.dist.in @@ -0,0 +1,1299 @@ +########################################## +# Trinity Core worldd configuration file # +########################################## +ConfVersion=2008080101 + +################################################################################################################### +# CONNECTIONS AND DIRECTORIES +# +#    RealmID +#        RealmID must match the realmlist inside the realmd database +# +#    DataDir +#        Data directory setting. +#        Important: DataDir needs to be quoted, as it is a string which may contain space characters. +#        Example: "@prefix@/share/trinitycore" +# +#    LogsDir +#        Logs directory setting. +#        Important: Logs dir must exists, or all logs need to be disabled +#        Default: "" - no log directory prefix, if used log names isn't absolute path +#        then logs will be stored in current directory for run program. +# +# +#    LoginDatabaseInfo +#    WorldDatabaseInfo +#    CharacterDatabaseInfo +#        Database connection settings for the world server. +#        Default: hostname;port;username;password;database +#                 .;somenumber;username;password;database - use named pipes at Windows +#                    Named pipes: mySQL required adding "enable-named-pipe" to [mysqld] section my.ini +#                .;/path/to/unix_socket;username;password;database - use Unix sockets at Unix/Linux +#                    Unix sockets: experimental, not tested +# +#    MaxPingTime +#        Settings for maximum database-ping interval (minutes between pings) +# +#    WorldServerPort +#        Default WorldServerPort +# +#    BindIP +#        Bind World Server to IP/hostname +# +################################################################################################################### + +RealmID = 1 +DataDir = "." +LogsDir = "" +LoginDatabaseInfo     = "127.0.0.1;3306;trinity;trinity;realmd" +WorldDatabaseInfo     = "127.0.0.1;3306;trinity;trinity;world" +CharacterDatabaseInfo = "127.0.0.1;3306;trinity;trinity;characters" +MaxPingTime = 30 +WorldServerPort = 8085 +BindIP = "0.0.0.0" + +################################################################################################################### +# SCRIPTING SETTINGS +# +# Locale +#     Setting for current (DBC) locale to use +# +# EventAI Error reporting +# 0 - Only startup (Default) +# 1 - Startup errors and Runtime event errors +# 2 - Startup errors, Runtime event errors, and Creation errors +################################################################################################################### + +Locale = 0 +EAIErrorLevel = 2 + +################################################################################################################### +# PERFORMANCE SETINGS +# +#    UseProcessors +#        Used processors mask for multi-processors system (Used only at Windows) +#        Default: 0 (selected by OS) +#                 number (bitmask value of selected processors) +# +#    ProcessPriority +#        Process priority setting (Used only at Windows) +#        Default: 1 (HIGH) +#                 0 (Normal) +# +#    Compression +#        Compression level for update packages sent to client (1..9) +#        Default: 1 (speed) +#                 9 (best compression) +# +#    PlayerLimit +#        Maximum number of players in the world. Excluding Mods, GM's and Admins +#        Default: 100 +#                 0 (for infinite players) +#                -1 (for Mods, GM's and Admins only) +#                -2 (for GM's and Admins only) +#                -3 (for Admins only) +# +#    SaveRespawnTimeImmediately +#        Save respawn time for creatures at death and for gameobjects at use/open +#        Default: 1 (save creature/gameobject respawn time without waiting grid unload) +#                 0 (save creature/gameobject respawn time at grid unload) +# +#    MaxOverspeedPings +#        Maximum overspeed ping count before player kick (minimum is 2, 0 used for disable check) +#        Default: 2 +# +#    GridUnload +#        Unload grids (if you have lot memory you can disable it to speed up player move to new grids second time) +#        Default: 1 (unload grids) +#                 0 (do not unload grids) +# +#    SocketSelectTime +#        Socket select time (in milliseconds) +#        Default: 10000 +# +#    GridCleanUpDelay +#        Grid clean up delay (in milliseconds) +#        Default: 300000 (5 min) +# +#    MapUpdateInterval +#        Map update interval (in milliseconds) +#        Default: 100 +# +#    ChangeWeatherInterval +#        Weather update interval (in milliseconds) +#        Default: 600000 (10 min) +# +#    PlayerSaveInterval +#        Player save interval (in milliseconds) +#        Default: 900000 (15 min) +# +#    vmap.enableLOS +#    vmap.enableHeight +#        Enable/Disable VMmap support for line of sight and height calculation +#        Default: 1 (true) +#                 0 (false) +# +#    vmap.ignoreMapIds +#        Map id that will be ignored by VMaps +#        List of ids with delimiter ',' +#        If more then one id is defined and spaces are included, the string has to be enclosed by " +#        Example: "369,0,1,530" +# +#    vmap.ignoreSpellIds +#        These spells are ignored for LoS calculation +#        List of ids with delimiter ',' +# +#    DetectPosCollision +#        Check final move position, summon position, etc for visible collision with other objects or +#        wall (wall only if vmaps are enabled) +#        Default: 1 (enable, required more CPU power usage) +#                 0 (disable, less nice position selection but will less CPU power usage) +# +#    TargetPosRecalculateRange +#        Max distance from movement target point (+moving unit size) and targeted object (+size) +#        after that new target movmeent point calculated. Max: melee attack range (5), min: contact range (0.5) +#        More distance let have better performence, less distance let have more sensitive reaction at target move. +#        Default: 1.5 +# +#    UpdateUptimeInterval +#        Update realm uptime period in minutes (for save data in 'uptime' table). Must be > 0 +#        Default: 10 (minutes) +# +#    MaxCoreStuckTime +#        Periodically check if the process got freezed, if this is the case force crash after the specified +#        amount of seconds. Must be > 0. Recommended > 10 secs if you use this. +#        Default: 0 (Disabled) +# +#    AddonChannel +#        Permit/disable the use of the addon channel through the server +#        (some client side addons can stop work correctly with disabled addon channel) +#        Default: 1 (permit addon channel) +#                 0 (do not permit addon channel) +# +################################################################################################################### + +UseProcessors = 0 +ProcessPriority = 1 +Compression = 1 +PlayerLimit = 100 +SaveRespawnTimeImmediately = 1 +MaxOverspeedPings = 2 +GridUnload = 1 +SocketSelectTime = 10000 +GridCleanUpDelay = 300000 +MapUpdateInterval = 100 +ChangeWeatherInterval = 600000 +PlayerSaveInterval = 900000 +vmap.enableLOS = 0 +vmap.enableHeight = 0 +vmap.ignoreMapIds = "369" +vmap.ignoreSpellIds = "7720" +DetectPosCollision = 1 +TargetPosRecalculateRange = 1.5 +UpdateUptimeInterval = 10 +MaxCoreStuckTime = 0 +AddonChannel = 1 + +################################################################################################################### +# SERVER LOGGING +# +#    LogSQL +#        Enable logging of GM commands - all SQL code will be written to a log file +#        All commands are written to a file: YYYY-MM-DD_logSQL.sql +#        If a new day starts (00:00:00) then a new file is created - the old file will not be deleted. +#        Default: 1 - Write SQL code to logfile +#                 0 - Do not log +# +#    PidFile +#        World daemon PID file +#        Default: ""             - do not create PID file +#                 "./worldd.pid" - create PID file (recommended name) +# +#    LogLevel +#        Server console level of logging +#        0 = Minimum; 1 = Basic&Error; 2 = Detail; 3 = Full/Debug +#        Default: 3 +# +#    LogTime +#        Include time in server console output [hh:mm:ss] +#        Default: 0 (no time) +#                 1 (print time) +# +#    LogFile +#        Logfile name +#        Default: "Server.log" +#                 "" - Empty name disable creating log file +# +#    LogTimestamp +#        Logfile with timestamp of server start in name +#        Default: 0 - no timestamp in name +#                 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +#    LogFileLevel +#        Server file level of logging +#        0 = Minimum; 1 = Error; 2 = Detail; 3 = Full/Debug +#        Default: 0 +# +#    LogFilter_TransportMoves +#    LogFilter_CreatureMoves +#    LogFilter_VisibilityChanges +#        Log filters +#        Default: 1 - not include with any log level +#                 0 - include in log if log level permit +# +#    WorldLogFile +#        Packet logging file for the worldserver +#        Default: "world.log" +# +#    DBErrorLogFile +#        Log file of DB errors detected at server run +#        Default: "DBErrors.log" +# +#    CharLogFile +#        Character operations logfile name +#        Default: "Char.log" +#                 "" - Empty name disable creating log file +# +#    CharLogTimestamp +#        Logfile with timestamp of server start in name +#        Default: 0 - no timestamp in name +#                 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +#    CharLogDump +#        Write character dump before deleting in Char.log +#        For restoration, cut character data from log starting from +#        line == START DUMP == to line == END DUMP == (without its) in file and load it using loadpdump command +#        Default: 0 - don't include dumping chars to log +#                 1 - include dumping chars to log +# +#    GmLogFile +#        Log file of gm commands +#        Default: "gm_commands.log" +#                 "" - Empty name for disable +# +#    GmLogTimestamp +#        GM Logfile with timestamp of server start in name +#        Default: 0 - no timestamp in name +#                 1 - add timestamp in name in form Logname_YYYY-MM-DD_HH-MM-SS.Ext for Logname.Ext +# +#    GmLogPerAccount +#        GM Logfiles with GM account id (Note: logs not created if GmLogFile not set) +#        Default: 0 - add gm log data to single log file +#                 1 - add gm log data to account specific log files with name +#                     in form Logname_#ID_YYYY-MM-DD_HH-MM-SS.Ext +#                     or form Logname_#ID.Ext +# +#    RaLogFile +#        Log file of RA commands +#        Default: "Ra.log" +#                 "" - Empty name for disable +# +#    LogColors +#        Color for messages (format "normal_color details_color debug_color error_color") +#        Colors: 0 - BLACK, 1 - RED, 2 - GREEN,  3 - BROWN, 4 - BLUE, 5 - MAGENTA, 6 -  CYAN, 7 - GREY, +#                8 - YELLOW, 9 - LRED, 10 - LGREEN, 11 - LBLUE, 12 - LMAGENTA, 13 - LCYAN, 14 - WHITE +#        Default: "" - none colors +#        Example: "13 7 11 9" +# +################################################################################################################### + +LogSQL = 1 +PidFile = "" +LogLevel = 1 +LogTime = 0 +LogFile = "Server.log" +LogTimestamp = 0 +LogFileLevel = 0 +LogFilter_TransportMoves = 1 +LogFilter_CreatureMoves = 1 +LogFilter_VisibilityChanges = 1 +WorldLogFile = "" +DBErrorLogFile = "db_errors.log" +CharLogFile = "characters.log" +CharLogTimestamp = 0 +CharLogDump = 0 +GmLogFile = "gm_commands.log" +GmLogTimestamp = 0 +GmLogPerAccount = 0 +RaLogFile = "ra_commands.log" +LogColors = "" + +################################################################################################################### +# SERVER SETTINGS +# +#    GameType +#        Server realm style +#        0 = NORMAL;1 = PVP; 4 = NORMAL; 6 = RP; 8 = RPPVP +#        also custom type: 16 FFA_PVP (free for all pvp mode like arena PvP in all zones except rest +#        activated places and sanctuaries) +# +#    RealmZone +#        Server realm zone (set allowed alphabet in character names/etc). See also Strict*Names options. +# +#    1 Development    - any language (Default) +#    2 United States  - extended-Latin +#    3 Oceanic        - extended-Latin +#    4 Latin America  - extended-Latin +#    5 Tournament     - basic-Latin at create, any at login +#    6 Korea          - East-Asian +#    7 Tournament     - basic-Latin at create, any at login +#    8 English        - extended-Latin +#    9 German         - extended-Latin +#    10 French        - extended-Latin +#    11 Spanish       - extended-Latin +#    12 Russian       - Cyrillic +#    13 Tournament    - basic-Latin at create, any at login +#    14 Taiwan        - East-Asian +#    15 Tournament    - basic-Latin at create, any at login +#    16 China         - East-Asian +#    17 CN1           - basic-Latin at create, any at login +#    18 CN2           - basic-Latin at create, any at login +#    19 CN3           - basic-Latin at create, any at login +#    20 CN4           - basic-Latin at create, any at login +#    21 CN5           - basic-Latin at create, any at login +#    22 CN6           - basic-Latin at create, any at login +#    23 CN7           - basic-Latin at create, any at login +#    24 CN8           - basic-Latin at create, any at login +#    25 Tournament    - basic-Latin at create, any at login +#    26 Test Server   - any language +#    27 Tournament    - basic-Latin at create, any at login +#    28 QA Server     - any language +#    29 CN9           - basic-Latin at create, any at login +# +#    Expansion +#        Allow server use content from expansion +#                 2 - check expansion 2 maps existence, and if client support expansion 2 and account have +#                     expansion 2 setting then allow visit expansion 2 maps, allow create new class character) +#        Default: 1 - check expansion 1 maps existence, and if client support expansion 1 and account have +#                     expansion 1 setting then allow visit expansion 1 maps, allow create new races character) +#                 0 - not check expansion maps existence, not allow wisit its, not allow create new race or new class +#                     characters, ignore account expansion setting) +# +#    DBC.Locale +#        DBC Language Settings +#        0 = English; 1 = Korean; 2 = French; 3 = German; 4 = Chinese; 5 = Taiwanese; 6 = Spanish; 7 = Spanish Mexico +#        8 = Russian; 255 = Auto Detect (Default) +# +#    DeclinedNames +#    Allow russian clients to set and use declined names +#    Default: 0 - do not use declined names, except when the Russian RealmZone is set +#         1 - use declined names +# +#    StrictPlayerNames +#        Limit player name to language specific symbols set, not allow create characters, and set rename request and disconnect at not allowed symbols name +#        Default: 0 disable (but limited server timezone dependent client check) +#                 1 basic latin characters  (strict) +#                 2 realm zone specific (strict). See RealmZone setting. +#                   Note: In any case if you want correctly see character name at client this client must have apporopriate fonts +#                   (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts). +#                 3 basic latin characters + server timezone specific +# +#    StrictCharterNames +#        Limit guild/arena team charter names to language specific symbols set, not allow create charters with allowed symbols in name +#        Default: 0 disable +#                 1 basic latin characters  (strict) +#                 2 realm zone specific (strict). See RealmZone setting. +#                   Note: In any case if you want correctly see character name at client this client must have apporopriate fonts +#                   (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts). +#                 3 basic latin characters + server timezone specific +# +#    StrictPetNames +#        Limit pet names to language specific symbols set +#        Default: 0 disable +#                 1 basic latin characters  (strict) +#                 2 realm zone specific (strict). See RealmZone setting. +#                   Note: In any case if you want correctly see character name at client this client must have apporopriate fonts +#                   (included in client by default, with active official localization or custom localization fonts in clientdir/Fonts). +#                 3 basic latin characters + server timezone specific +# +#    CharactersCreatingDisabled +#        Disable characters creating for specific team or any (non-player accounts not affected) +#        Default: 0 - enabled +#                 1 - disabled only for Alliance +#                 2 - disabled only for Horde +#                 3 - disabled for both teams +# +#    MaxWhoListReturns +#        Set the maximum number of players returned in the /who list and interface. +#        Default: 49 (stable) +# +#    CharactersPerAccount +#        Limit numbers of characters per account (at all realms). +#        Note: this setting limit character creating at _current_ realm base at characters amount at all realms +#        Default: 50 +#                The number must be >= CharactersPerRealm +# +#    CharactersPerRealm +#        Limit numbers of characters for account at realm +#        Default: 10 (client limitation) +#                The number must be between 1 and 10 +# +#    HeroicCharactersPerRealm +#        Limit numbers of heroic class characters for account at realm +#        Default: 1 +#                The number must be between 0 (not allowed) and 10 +# +#    MinLevelForHeroicCharacterCreating +#        Limit creating heroic characters only for account with another character of specific level (ignored for GM accounts) +#                 0  - not require any existed chaarcter +#                 1  - require at least any character existed +#        Default: 55 - default requirement +# +# +#    SkipCinematics +#        Disable in-game script movie at first character's login(allows to prevent buggy intro in case of custom start location coordinates) +#        Default: 0 - show intro for each new characrer +#                 1 - show intro only for first character of selected race +#                 2 - disable intro show in all cases +# +#    MaxPlayerLevel +#        Max level that can be reached by player for experience (in range from 1 to 100). +#        Change not recommended +#        Default: 80 +# +#    StartPlayerLevel +#        Staring level that have character at creating (in range 1 to MaxPlayerLevel) +#        Default: 1 +# +#    StartHeroicPlayerLevel +#        Staring level that have character of heroic class at creating (in range 1 to MaxPlayerLevel) +#        Default: 55 +# +#    StartPlayerMoney +#        Amount of money that new players will start with. +#        If you want to start with silver, use for example 100 (100 copper = 1 silver) +#        Default: 0 +# +#    MaxHonorPoints +#        Max honor points that player can have. +#        Default: 75000 +# +#    StartHonorPoints +#        Amount of honor that new players will start with +#        Default: 0 +# +#    MaxArenaPoints +#        Max arena points that player can have. +#        Default: 5000 +# +#    StartArenaPoints +#        Amount of arena points that new players will start with +#        Default: 0 +# +#    InstantLogout +#        Enable or disable instant logout for security level (0..4) or high (NOT in combat/while dueling/while falling) +#        Default: 1 (Mods/GMs/Admins) +# +#    DisableWaterBreath +#        Disable/enable waterbreathing for security level (0..4) or high +#        Default: 4 (None) +# +#    AllFlightPaths +#        Players will start with all flight paths (Note: ALL flight paths, not only player's team) +#        Default: 0 (true) +#                 1 (false) +# +#    AlwaysMaxSkillForLevel +#        Players will automatically gain max level dependent (weapon/defense) skill when logging in, leveling up etc. +#        Default: 0 (false) +#                 1 (true) +# +#    ActivateWeather +#        Activate weather system +#        Default: 1 (true) +#                 0 (false) +# +#    Battleground.CastDeserter +#        Cast or not Deserter spell at player who leave battleground in progress +#        Default: 1 (true) +#                 0 (false) +# +#    Battleground.QueueAnnouncer.Enable +#        Enable queue announcer posting to chat +#        Default: 0 (false) +#                 1 (true) +# +#    Battleground.QueueAnnouncer.PlayerOnly +#        Enable queue announcer posting to chat +#        Default: 0 (false) +#                 1 (true) +# +#    Arena.QueueAnnouncer.Enable: Enable queue announcer posting to chat +#        Default: 0 (false) +#                 1 (true) +# +#    CastUnstuck +#        Allow cast or not Unstuck spell at .start or client Help option use +#        Default: 1 (true) +#                 0 (false) +# +#    Instance.IgnoreLevel +#        Ignore level requirement to enter instance +#        Default: 0 (false) +#                 1 (true) +# +#    Instance.IgnoreRaid +#        Ignore raid requirement to enter instance +#        Default: 0 (false) +#                 1 (true) +# +#    Instance.ResetTimeHour +#        The hour of the day (0-23) when the global instance resets occur. +#        Default: 4 +# +#    Instance.UnloadDelay +#        Unload the instance map from memory after some time if no players are inside. +#        Default: 1800000 (miliseconds, i.e 30 minutes) +#                 0 (instance maps are kept in memory until they are reset) +# +#    Quests.LowLevelHideDiff +#        Quest level difference to hide for player low level quests: +#        if player_level > quest_level + LowLevelQuestsHideDiff then quest "!" mark not show for quest giver +#        Default: 4 +#                -1 (show all available quests marks) +# +#    Quests.HighLevelHideDiff +#        Quest level difference to hide for player high level quests: +#        if player_level < quest_min_level - HighLevelQuestsHideDiff then quest "!" mark not show for quest giver +#        Default: 7 +#                -1 (show all available quests marks) +# +#    MaxPrimaryTradeSkill +#        Max count that player can learn the primary trade skill. +#        Default: 2 +#        Max : 10 +# +#    MinPetitionSigns +#        Min signatures count to creating guild (0..9). +#        Default: 9 +# +#    MaxGroupXPDistance +#        Max distance to creature for group memeber to get XP at creature death. +#        Default: 74 +# +#    MailDeliveryDelay +#        Mail delivery delay time for item sending +#        Default: 3600 sec (1 hour) +# +#    SkillChance.Prospecting +#        For prospecting skillup impossible by default, but can be allowed as custom setting +#        Default: 0 - no skilups +#                 1 - skilups possible +# +#    SkillChance.Milling +#        For milling skillup impossible by default, but can be allowed as custom setting +#        Default: 0 - no skilups +#                 1 - skilups possible +# +#    Event.Announce +#        Default: 0 (false) +#                 1 (true) +# +#    BeepAtStart +#        Beep at core start finished (mostly work only at Unix/Linux systems) +#        Default: 1 (true) +#                 0 (false) +# +#    Motd +#        Message of the Day. Displayed at worldlogin for every user ('@' for a newline). +# +################################################################################################################### + +GameType = 1 +RealmZone = 1 +Expansion = 2 +DBC.Locale = 255 +DeclinedNames = 0 +StrictPlayerNames = 0 +StrictCharterNames = 0 +StrictPetNames = 0 +MaxWhoListReturns = 49 +CharactersCreatingDisabled = 0 +CharactersPerAccount = 50 +CharactersPerRealm = 10 +HeroicCharactersPerRealm = 1 +MinLevelForHeroicCharacterCreating = 55 +SkipCinematics = 0 +MaxPlayerLevel = 80 +StartPlayerLevel = 1 +StartHeroicPlayerLevel = 55 +StartPlayerMoney = 0 +MaxHonorPoints = 75000 +StartHonorPoints = 0 +MaxArenaPoints = 5000 +StartArenaPoints = 0 +InstantLogout = 1 +DisableWaterBreath = 4 +AllFlightPaths = 0 +AlwaysMaxSkillForLevel = 0 +ActivateWeather = 1 +Battleground.CastDeserter = 1 +Battleground.QueueAnnouncer.Enable = 0 +Battleground.QueueAnnouncer.PlayerOnly = 0 +Arena.QueueAnnouncer.Enable = 0 +CastUnstuck = 1 +Instance.IgnoreLevel = 0 +Instance.IgnoreRaid = 0 +Instance.ResetTimeHour = 4 +Instance.UnloadDelay = 1800000 +Quests.LowLevelHideDiff = 4 +Quests.HighLevelHideDiff = 7 +MaxPrimaryTradeSkill = 2 +MinPetitionSigns = 9 +MaxGroupXPDistance = 74 +MailDeliveryDelay = 3600 +SkillChance.Prospecting = 0 +SkillChance.Milling = 0 +Event.Announce = 0 +BeepAtStart = 1 +Motd = "Welcome to a Trinity Core server." + +################################################################################################################### +# PLAYER INTERACTION +# +#    AllowTwoSide.Accounts +#        Allow or not accounts to create characters in the 2 teams in any game type. +#        Default: 0 (Not allowed) +#                 1 (Allowed) +# +#    AllowTwoSide.Interaction.Chat +#    AllowTwoSide.Interaction.Channel +#    AllowTwoSide.Interaction.Group +#    AllowTwoSide.Interaction.Guild +#    AllowTwoSide.Interaction.Auction +#    AllowTwoSide.Interaction.Mail +#        Allow or not common :chat(say,yell);channel(chat)group(join)guild(join);merge all auction houses for players from +#        different teams, send mail to different team. +#        Default: 0 (Not allowed) +#                 1 (Allowed) +# +#    AllowTwoSide.WhoList +#        Allow or not show player from both team in who list. +#        Default: 0 (Not allowed) +#                 1 (Allowed) +# +#    AllowTwoSide.AddFriend +#        Allow or not adding friends from other team in friend list. +#        Default: 0 (Not allowed) +#                 1 (Allowed) +# +#    TalentsInspecting +#        Allow other players see character talents in inspect dialog (Characters in Gamemaster mode can +#        inspect talents always) +#        Default: 1 (allow) +#                 0 (not allow) +# +################################################################################################################### + +AllowTwoSide.Accounts = 0 +AllowTwoSide.Interaction.Chat = 0 +AllowTwoSide.Interaction.Channel = 0 +AllowTwoSide.Interaction.Group = 0 +AllowTwoSide.Interaction.Guild = 0 +AllowTwoSide.Interaction.Auction = 0 +AllowTwoSide.Interaction.Mail = 0 +AllowTwoSide.WhoList = 0 +AllowTwoSide.AddFriend = 0 +TalentsInspecting = 1 + +################################################################################################################### +# CREATURE SETTINGS +# +#    ThreatRadius +#        Radius for creature to evade after being pulled away from combat start point +#        If ThreatRadius is less than creature aggro radius then aggro radius will be used +#        Default: 100 yards +# +#    Rate.Creature.Aggro +#        Aggro radius percent or off. +#        Default: 1   - 100% +#                 1.5 - 150% +#                 0   - off (0%) +# +#    CreatureFamilyAssistanceRadius +#        Creature family assistance radius +#        Default: 10 +#                 0   - off +# +#    CreatureFamilyAssistanceDelay +#        Reaction time for creature assistance call +#        Default: 1500 (1.5s) +# +#    WorldBossLevelDiff +#        Difference for boss dynamic level with target +#        Default: 3 +# +#    Corpse.Decay.NORMAL +#    Corpse.Decay.RARE +#    Corpse.Decay.ELITE +#    Corpse.Decay.RAREELITE +#    Corpse.Decay.WORLDBOSS +#        Seconds until creature corpse will decay without being looted or skinned. +#        Default: 60, 300, 300, 300, 3600 +# +#    Rate.Corpse.Decay.Looted +#         Controls how long the creature corpse stays after it had been looted, as a multiplier of its Corpse.Decay.* config. +#         Default: 0.1 +# +#    Rate.Creature.Normal.Damage +#    Rate.Creature.Elite.Elite.Damage +#    Rate.Creature.Elite.RAREELITE.Damage +#    Rate.Creature.Elite.WORLDBOSS.Damage +#    Rate.Creature.Elite.RARE.Damage +#        Creature Damage Rates. +#        Examples: 2 - creatures will damage 2x, 1.7 - 1.7x. +# +#    Rate.Creature.Normal.SpellDamage +#    Rate.Creature.Elite.Elite.SpellDamage +#    Rate.Creature.Elite.RAREELITE.SpellDamage +#    Rate.Creature.Elite.WORLDBOSS.SpellDamag +#    Rate.Creature.Elite.RARE.SpellDamage +#        Creature Spell Damage Rates. +#        Examples: 2 - creatures will damage with spells 2x, 1.7 - 1.7x. +# +#    Rate.Creature.Normal.HP +#    Rate.Creature.Elite.Elite.HP +#    Rate.Creature.Elite.RAREELITE.HP +#    Rate.Creature.Elite.WORLDBOSS.HP +#    Rate.Creature.Elite.RARE.HP +#        Creature Health Ammount Modifier. +#        Examples: 2 - creatures have 2x health, 1.7 - 1.7x. +# +#    ListenRange.Say +#        Distance from player to listen text that creature (or other world object) say +#        Default: 25 +# +#    ListenRange.TextEmote +#        Distance from player to listen textemote that creature (or other world object) say +#        Default: 25 +# +#    ListenRange.Yell +#        Distance from player to listen text that creature (or other world object) yell +#        Default: 300 +# +################################################################################################################### + +ThreatRadius = 100 +Rate.Creature.Aggro = 1 +CreatureFamilyAssistanceRadius = 10 +CreatureFamilyAssistanceDelay = 1500 +WorldBossLevelDiff = 3 +Corpse.Decay.NORMAL = 60 +Corpse.Decay.RARE = 300 +Corpse.Decay.ELITE = 300 +Corpse.Decay.RAREELITE = 300 +Corpse.Decay.WORLDBOSS = 3600 +Rate.Corpse.Decay.Looted = 0.1 +Rate.Creature.Normal.Damage = 1 +Rate.Creature.Elite.Elite.Damage = 1 +Rate.Creature.Elite.RAREELITE.Damage = 1 +Rate.Creature.Elite.WORLDBOSS.Damage = 1 +Rate.Creature.Elite.RARE.Damage = 1 +Rate.Creature.Normal.SpellDamage = 1 +Rate.Creature.Elite.Elite.SpellDamage = 1 +Rate.Creature.Elite.RAREELITE.SpellDamage = 1 +Rate.Creature.Elite.WORLDBOSS.SpellDamage = 1 +Rate.Creature.Elite.RARE.SpellDamage = 1 +Rate.Creature.Normal.HP = 1 +Rate.Creature.Elite.Elite.HP = 1 +Rate.Creature.Elite.RAREELITE.HP = 1 +Rate.Creature.Elite.WORLDBOSS.HP = 1 +Rate.Creature.Elite.RARE.HP = 1 +ListenRange.Say = 40 +ListenRange.TextEmote = 40 +ListenRange.Yell = 300 + +################################################################################################################### +# CHAT SETTINGS +# +#    ChatFakeMessagePreventing +#        Chat protection from creating fake messages using a lot spaces (other invisible symbols), +#        not applied to addon language messages, but can prevent working old addons +#        that use normal languages for sending data to another clients. +#        Default: 0 (disible fake messages preventing) +#                 1 (enabled fake messages preventing) +# +#    ChatFlood.MessageCount +#        Chat anti-flood protection, haste message count to activate protection +#        Default: 10 +#                 0 (disible anti-flood protection) +# +#    ChatFlood.MessageDelay +#        Chat anti-flood protection, minimum message delay to count message +#        Default: 1 (in secs) +# +#    ChatFlood.MuteTime +#        Chat anti-flood protection, mute time at activation flood protection (not saved) +#        Default: 10 (in secs) +# +#    Channel.RestrictedLfg +#        Restrict use LookupForGroup channel only registered in LFG tool players +#        Default: 1 (allow join to channel only if active in LFG) +#                 0 (allow join to channel in any time) +# +#    Channel.SilentlyGMJoin +#        Silently join GM characters (security level > 1) to channels +#        Default: 0 (join announcement in normal way) +#                 1 (GM join without announcement) +# +################################################################################################################### + +ChatFakeMessagePreventing = 0 +ChatFlood.MessageCount = 10 +ChatFlood.MessageDelay = 1 +ChatFlood.MuteTime = 10 +Channel.RestrictedLfg = 1 +Channel.SilentlyGMJoin = 0 + +################################################################################################################### +# GAME MASTER SETTINGS +# +#    GM.LoginState +#        GM mode at login +#        Default: 2 (last save state) +#                 0 (disable) +#                 1 (enable) +# +#    GM.AcceptTickets +#        Is GM accepting tickets from player by default or not. +#        Default: 2 (last save state) +#                 0 (disable) +#                 1 (enable) +# +#    GM.Chat +#        GM chat mode at login +#        Default: 2 (last save state) +#                 0 (disable) +#                 1 (enable) +# +#    GM.WhisperingTo +#        Is GM accepting whispers from player by default or not. +#        Default: 2 (last save state) +#                 0 (disable) +#                 1 (enable) +# +#    GM.InGMList +#        Is GM showed in GM list (if visible) in non-GM state (.gmoff) +#        Default: 0 (false) +#                 1 (true) +# +#    GM.InWhoList +#        Is GM showed in who list (if visible). +#        Default: 0 (false) +#                 1 (true) +# +#    GM.LogTrade +#        Include GM trade and trade slot enchanting operations in GM log if it enable +#        Default: 1 (include) +#                 0 (not include) +# +#    GM.StartLevel +#        GM starting level (1-100) +#        Default: 1 +# +################################################################################################################### + +GM.LoginState     = 2 +GM.AcceptTickets  = 2 +GM.Chat           = 2 +GM.WhisperingTo   = 2 +GM.InGMList       = 0 +GM.InWhoList      = 0 +GM.LogTrade       = 1 +GM.StartLevel     = 70 + +################################################################################################################### +# VISIBILITY AND RADIUSES +# +#    Visibility.GroupMode +#        Group visibility modes +#        Default: 0 (standard setting: only members from same group can 100% auto detect invisible player) +#                 1 (raid members 100% auto detect invisible player from same raid) +#                 2 (players from same team can 100% auto detect invisible player) +# +#    Visibility.Distance.Creature +#    Visibility.Distance.Player +#        Visibility distance for different in game object +#        Max limited by active player zone: ~ 333 +#        Min limit dependent from objects +#        Default: 132 (cell size) +#        Min limit is max aggro radius (45) * Rate.Creature.Aggro +# +#    Visibility.Distance.Object +#        Visible distance for gameobject, dynobject, bodies, corpses, bones +#        Min limit is iteraction distance (5) +# +#    Visibility.Distance.InFlight +#        Visible distance for player in flight +#        Min limit is 0 (not show any objects) +# +#    Visibility.Distance.Grey.Unit +#        Visibility grey distance for creatures/players (fast changing objects) +#        addition to appropriate object type Visibility.Distance.* use in case visibility removing to +#        object (except corpse around distences) If � is distance and G is grey distance then object +#        make visible if distance to it <= D but make non visible if distance > D+G +#        Default: 1 (yard) +# +#    Visibility.Distance.Grey.Object +#        Visibility grey distance for dynobjects/gameobjects/corpses/creature bodies +#        Default: 10 (yards) +# +# +################################################################################################################### + +Visibility.GroupMode = 0 +Visibility.Distance.Creature      = 132 +Visibility.Distance.Player        = 132 +Visibility.Distance.Object        = 132 +Visibility.Distance.InFlight      = 132 +Visibility.Distance.Grey.Unit   = 1 +Visibility.Distance.Grey.Object = 10 + +################################################################################################################### +# SERVER RATES +# +#    Rate.Health +#    Rate.Mana +#    Rate.Rage.Income +#    Rate.Rage.Loss +#    Rate.RunicPower.Income +#    Rate.RunicPower.Loss +#    Rate.Focus +#        Health and power regeneration and rage income from damage. +#        Default: 1 +# +#    Rate.Skill.Discovery +#         Skill Discovery Rates +#         Default: 1 +# +#    Rate.Drop.Item.Poor +#    Rate.Drop.Item.Normal +#    Rate.Drop.Item.Uncommon +#    Rate.Drop.Item.Rare +#    Rate.Drop.Item.Epic +#    Rate.Drop.Item.Legendary +#    Rate.Drop.Item.Artifact +#    Rate.Drop.Item.Referenced +#    Rate.Drop.Money +#         Drop rates (items by quality and money) +#         Default: 1 +# +#    Rate.Drop.Money +#         Drop rates +#         Default: 1 +# +#    Rate.XP.Kill +#    Rate.XP.Quest +#    Rate.XP.Explore +#        XP rates +#        Default: 1 +# +#    Rate.XP.PastLevel70 +#        XP needed per level past 70 (Rates below 1 not recommended) +#        Default: 1 +# +#    Rate.Rest.InGame +#    Rate.Rest.Offline.InTavernOrCity +#    Rate.Rest.Offline.InWilderness +#        Resting points grow rates (1 - normal, 2 - double rate, 0.5 - half rate, etc) from standard values +# +#    Rate.Damage.Fall +#        Damage after fall rate. (1 - standard, 2 - double damage, 0.5 - half damage, etc) +# +#    Rate.Auction.Time +#    Rate.Auction.Deposit +#    Rate.Auction.Cut +#        Auction rates (auction time, deposit get at auction start, auction cut from price at auction end) +# +#    Rate.Honor +#        Honor gain rate +# +#    Rate.Mining.Amount +#    Rate.Mining.Next +#        Mining Rates (Mining.Amount changes minimum/maximum usetimes of a deposit, +#        Mining.Next changes chance to have next use of a deposit) +# +#    Rate.Talent +#        Talent Point rates +#        Default: 1 +# +#    Rate.Reputation.Gain +#         Reputation Gain rate +#         Default: 1 +# +#    Rate.InstanceResetTime +#        Multiplier for the number of days in between global raid/heroic instance resets. +#        Default: 1 +# +#    SkillGain.Crafting +#    SkillGain.Defense +#    SkillGain.Gathering +#    SkillGain.Weapon +#         crafting/defense/gathering/weapon skills gain at skill grow (1,2,...) +#         Default: 1 +# +#    SkillChance.Orange +#    SkillChance.Yellow +#    SkillChance.Green +#    SkillChance.Grey +#        Skill chance values (0..100) +#        Default: 100-75-25-0 +# +#    SkillChance.MiningSteps +#    SkillChance.SkinningSteps +#         For skinning and Mining chance decrease with skill level. +#         Default: 0  - no decrease +#                  75 - in 2 times each 75 skill points +# +#    DurabilityLossChance.Damage +#         Chance lost one from equiped items durability point at damage apply or receive. +#         Default: 0.5 (100/0.5 = 200) Each 200 damage apply one from 19 possible equipped items +# +#    DurabilityLossChance.Absorb +#         Chance lost one from armor items durability point at damage absorb. +#         Default: 0.5 (100/0.5 = 200) Each 200 absorbs apply one from 15 possible armor equipped items +# +#    DurabilityLossChance.Parry +#         Chance lost weapon durability point at parry. +#         Default: 0.05 (100/0.05 = 2000) Each 2000 parry attacks main weapon lost point +# +#    DurabilityLossChance.Block +#         Chance lost sheild durability point at damage block. +#         Default: 0.05 (100/0.05 = 2000) Each 2000 partly or full blocked attacks shield lost point +# +#    Death.SicknessLevel +#         Starting Character start gain sickness at spirit resurrection (1 min) +#         Default: 11 +#                  -10 - character will have full time (10min) sickness at 1 level +#                  maxplayerlevel+1 - chaarcter will not have sickess at any level +# +#    Death.CorpseReclaimDelay.PvP +#    Death.CorpseReclaimDelay.PvE +#         Enabled/disabled increase corpse reclaim delay at often PvP/PvE deaths +#         Default: 1 (enabled) +#                  0 (disabled) +# +################################################################################################################### + +Rate.Health = 1 +Rate.Mana = 1 +Rate.Rage.Income = 1 +Rate.Rage.Loss = 1 +Rate.RunicPower.Income = 1 +Rate.RunicPower.Loss = 1 +Rate.Focus = 1 +Rate.Skill.Discovery = 1 +Rate.Drop.Item.Poor = 1 +Rate.Drop.Item.Normal = 1 +Rate.Drop.Item.Uncommon = 1 +Rate.Drop.Item.Rare = 1 +Rate.Drop.Item.Epic = 1 +Rate.Drop.Item.Legendary = 1 +Rate.Drop.Item.Artifact = 1 +Rate.Drop.Item.Referenced = 1 +Rate.Drop.Money = 1 +Rate.XP.Kill    = 1 +Rate.XP.Quest   = 1 +Rate.XP.Explore = 1 +Rate.XP.PastLevel70 = 1 +Rate.Rest.InGame = 1 +Rate.Rest.Offline.InTavernOrCity = 1 +Rate.Rest.Offline.InWilderness = 1 +Rate.Damage.Fall = 1 +Rate.Auction.Time = 1 +Rate.Auction.Deposit = 1 +Rate.Auction.Cut = 1 +Rate.Honor = 1 +Rate.Mining.Amount = 1 +Rate.Mining.Next   = 1 +Rate.Talent = 1 +Rate.Reputation.Gain = 1 +Rate.InstanceResetTime = 1 +SkillGain.Crafting = 1 +SkillGain.Defense = 1 +SkillGain.Gathering = 1 +SkillGain.Weapon = 1 +SkillChance.Orange = 100 +SkillChance.Yellow = 75 +SkillChance.Green  = 25 +SkillChance.Grey   = 0 +SkillChance.MiningSteps   = 0 +SkillChance.SkinningSteps = 0 +DurabilityLossChance.Damage = 0.5 +DurabilityLossChance.Absorb = 0.5 +DurabilityLossChance.Parry  = 0.05 +DurabilityLossChance.Block  = 0.05 +Death.SicknessLevel = 11 +Death.CorpseReclaimDelay.PvP = 1 +Death.CorpseReclaimDelay.PvE = 1 + +################################################################################################################### +# +# Rated arena matches config +# +# MaxRatingDifference: the maximum rating difference between two groups in rated matches +#             Default: 0 (disable, rating difference is discarded) +# +# RatingDiscardTimer: after the specified milliseconds has passed, +#                     rating information will be discarded when selecting teams for matches +#                     also initiates an update by this timer +#             Default: 60000 +# +# AutoDistributePoints: set if arena points should be distributed automatically, or by GM command +#             Default: 0 (disable) (recommended): use gm command or sql query to distribute the points +#                      1 (enable): arena points are distributed automatically +# +# AutoDistributeInterval: how often should the distribution take place +#                         if automatic distribution is enabled +#                         in days +#             Default: 7 (weekly) +# +################################################################################################################### + +Arena.MaxRatingDifference = 0 +Arena.RatingDiscardTimer = 60000 +Arena.AutoDistributePoints = 0 +Arena.AutoDistributeInterval = 7 + +################################################################################################################### +# +# Battleground config +# +# PrematureFinishTimer: the time to end the bg if there are less than minplayersperteam on one side +#                       in milliseconds +#              Default: 300000 +#                       0 - disable +# +################################################################################################################### + +BattleGround.PrematureFinishTimer = 300000 + + +################################################################################################################### +# +# NETWORK CONFIG +# +#    Network.Threads +#         Number of threads for network, recommend 1 thread per 1000 connections. +#         Default: 1 +# +#    Network.OutKBuff +#         The size of the output kernel buffer used ( SO_SNDBUF socket option, tcp manual ). +#         Default: -1 (Use system default setting) +# +#    Network.OutUBuff +#         Userspace buffer for output. This is amount of memory reserved per each connection. +#         Default: 65536 +# +#    Network.TcpNoDelay: +#         TCP Nagle algorithm setting +#         Default: 0 (enable Nagle algorithm, less traffic, more latency) +#                  1 (TCP_NO_DELAY, disable Nagle algorithm, more traffic but less latency) +# +################################################################################################################### + +Network.Threads = 1 +Network.OutKBuff = -1 +Network.OutUBuff = 65536 +Network.TcpNodelay = 1 + +################################################################################################################### +# CONSOLE AND REMOTE ACCESS +# +#    Console.Enable +#        Enable console +#        Default: 1 - on +#                 0 - off +# +#    Ra.Enable +#        Enable remote console +#        Default: 0 - off +#                 1 - on +# +#    Ra.IP +#        Default remote console ip address, use 0.0.0.0 for every address +# +#    Ra.Port +#        Default remote console port +# +#    Ra.MinLevel +#        Minimum level that's required to login,3 by default +# +#    Ra.Secure +#        Kick client on wrong pass +# +################################################################################################################### + +Console.Enable = 1 +Ra.Enable = 0 +Ra.IP = 0.0.0.0 +Ra.Port = 3443 +Ra.MinLevel = 3 +Ra.Secure = 1 + +################################################################################################################### +# CUSTOM SERVER OPTIONS +# +#	PlayerStart.AllReputation +#		Players will start with most of the high level reputations that are needed for items, mounts etc. +#		If there are any reputation faction you want to be added, just tell me. +# +#	PlayerStart.AllSpells +#		If enabled, players will start with all their class spells (not talents). Useful for instant 70 servers. +#		You must import playercreateinfo_spell_custom.sql, it's included in the SQL folder. +#		Default: 0 - off +#				 1 - on +# +#	PlayerStart.MapsExplored +#		Players will start with all maps explored if enabled +# +#	MusicInBattleground +#		If enabled, "L70ETC - Power of the horde" will be played when BG starts ;) +# +#	HonorPointsAfterDuel +#		The amount of honor points the duel winner will get after a duel. +#		Default: 0 - disable +# +#	AlwaysMaxWeaponSkill +#		Players will automatically gain max weapon/defense skill when logging in, leveling up etc. +# +#	PvPToken.Enable +#		Enable/disable PvP Token System. Players will get a token after slaying another player that gives honor. +# +#	PvPToken.MapAllowType +#		Where players can receive the pvp token +#		4 - In all maps +#		3 - In battlegrounds only +#		2 - In FFA areas only (gurubashi arena etc) +#		1 - In battlegrounds AND FFA areas only +# +#	PvPToken.ItemID +#		The item players will get after killing someone if PvP Token system is enabled. +#		Default: 29434 - Badge of justice +# +#	PvPToken.ItemCount +#		Modify the item ID count - Default: 1 +# +#	NoResetTalentsCost +#		Enable or disable no cost when reseting talents +# +#   ForbiddenMaps +#       map ids that users below SEC_GAMEMASTER cannot enter, with delimiter ',' +#       Default: "" +#       example: "538,90" +#       Note that it's HIGHLY DISCOURAGED to forbid starting maps (0, 1, 530)! +# +################################################################################################################### + +PlayerStart.AllReputation = 0 +PlayerStart.AllSpells = 0 +PlayerStart.MapsExplored = 0 +MusicInBattleground = 0 +HonorPointsAfterDuel = 0 +AlwaysMaxWeaponSkill = 0 +PvPToken.Enable = 0 +PvPToken.MapAllowType = 4 +PvPToken.ItemID = 29434 +PvPToken.ItemCount = 1 +NoResetTalentsCost = 0 + diff --git a/src/trinitycore/TrinityCore.rc b/src/mangosd/mangosd.rc index 4e6510c0407..4e6510c0407 100644 --- a/src/trinitycore/TrinityCore.rc +++ b/src/mangosd/mangosd.rc diff --git a/src/trinitycore/monitor-mangosd b/src/mangosd/monitor-mangosd index a740ae5e8fa..a740ae5e8fa 100644 --- a/src/trinitycore/monitor-mangosd +++ b/src/mangosd/monitor-mangosd diff --git a/src/trinitycore/resource.h b/src/mangosd/resource.h index 7e7d8e4b76f..7e7d8e4b76f 100644 --- a/src/trinitycore/resource.h +++ b/src/mangosd/resource.h diff --git a/src/trinitycore/run-mangosd b/src/mangosd/run-mangosd index f307bd9e1ad..f307bd9e1ad 100644 --- a/src/trinitycore/run-mangosd +++ b/src/mangosd/run-mangosd diff --git a/src/trinityrealm/AuthCodes.h b/src/realmd/AuthCodes.h index 768f51efb59..f322d7fea17 100644 --- a/src/trinityrealm/AuthCodes.h +++ b/src/realmd/AuthCodes.h @@ -68,8 +68,8 @@ enum LoginResult  // we need to stick to 1 version or half of the stuff will work for someone  // others will not and opposite -// will only support WoW and WoW:TBC 2.4.3 client build 8606... +// will only support WoW, WoW:TBC and WoW:WotLK 3.0.3 client build 9183... -#define EXPECTED_TRINITY_CLIENT_BUILD        {8606, 0} +#define EXPECTED_TRINITY_CLIENT_BUILD        {9183, 0}  #endif diff --git a/src/trinityrealm/AuthSocket.cpp b/src/realmd/AuthSocket.cpp index 7168bcf700b..7168bcf700b 100644 --- a/src/trinityrealm/AuthSocket.cpp +++ b/src/realmd/AuthSocket.cpp diff --git a/src/trinityrealm/AuthSocket.h b/src/realmd/AuthSocket.h index f704283c215..f704283c215 100644 --- a/src/trinityrealm/AuthSocket.h +++ b/src/realmd/AuthSocket.h diff --git a/src/trinityrealm/Main.cpp b/src/realmd/Main.cpp index 0e2f68f76c6..8ba1db3c029 100644 --- a/src/trinityrealm/Main.cpp +++ b/src/realmd/Main.cpp @@ -40,12 +40,12 @@  #endif  #ifndef _TRINITY_REALM_CONFIG -# define _TRINITY_REALM_CONFIG  "trinityrealm.conf" +# define _TRINITY_REALM_CONFIG  "TrinityRealm.conf"  #endif //_TRINITY_REALM_CONFIG  #ifdef WIN32  #include "ServiceWin32.h" -char serviceName[] = "realmd"; +char serviceName[] = "TrinityRealm";  char serviceLongName[] = "Trinity realm service";  char serviceDescription[] = "Massive Network Game Object Server";  /* diff --git a/src/trinityrealm/Makefile.am b/src/realmd/Makefile.am index 9baeed6c2b1..9baeed6c2b1 100644 --- a/src/trinityrealm/Makefile.am +++ b/src/realmd/Makefile.am diff --git a/src/trinityrealm/RealmList.cpp b/src/realmd/RealmList.cpp index 97fdfbdd91f..97fdfbdd91f 100644 --- a/src/trinityrealm/RealmList.cpp +++ b/src/realmd/RealmList.cpp diff --git a/src/trinityrealm/RealmList.h b/src/realmd/RealmList.h index 9cb5380bd25..9cb5380bd25 100644 --- a/src/trinityrealm/RealmList.h +++ b/src/realmd/RealmList.h diff --git a/src/trinityrealm/TrinityRealm.rc b/src/realmd/Realmd.rc index 33c7eef719a..33c7eef719a 100644 --- a/src/trinityrealm/TrinityRealm.rc +++ b/src/realmd/Realmd.rc diff --git a/src/trinityrealm/TrinityRealm.ico b/src/realmd/TrinityRealm.ico Binary files differindex da318f48a8c..da318f48a8c 100644 --- a/src/trinityrealm/TrinityRealm.ico +++ b/src/realmd/TrinityRealm.ico diff --git a/src/trinityrealm/trinityrealm.conf.dist b/src/realmd/realmd.conf.dist.in index 72ef1c9012e..72ef1c9012e 100644 --- a/src/trinityrealm/trinityrealm.conf.dist +++ b/src/realmd/realmd.conf.dist.in diff --git a/src/trinityrealm/resource.h b/src/realmd/resource.h index 7e7d8e4b76f..7e7d8e4b76f 100644 --- a/src/trinityrealm/resource.h +++ b/src/realmd/resource.h diff --git a/src/shared/Auth/AuthCrypt.cpp b/src/shared/Auth/AuthCrypt.cpp index 7941b33ed8c..199e7192537 100644 --- a/src/shared/Auth/AuthCrypt.cpp +++ b/src/shared/Auth/AuthCrypt.cpp @@ -50,9 +50,8 @@ void AuthCrypt::DecryptRecv(uint8 *data, size_t len)  void AuthCrypt::EncryptSend(uint8 *data, size_t len)  {      if (!_initialized) return; -    if (len < CRYPTED_SEND_LEN) return; -    for (size_t t = 0; t < CRYPTED_SEND_LEN; t++) +    for (size_t t = 0; t < len; t++)      {          _send_i %= _key.size();          uint8 x = (data[t] ^ _key[_send_i]) + _send_j; diff --git a/src/shared/Auth/AuthCrypt.h b/src/shared/Auth/AuthCrypt.h index f3a0cac40fa..366cce5635f 100644 --- a/src/shared/Auth/AuthCrypt.h +++ b/src/shared/Auth/AuthCrypt.h @@ -32,7 +32,6 @@ class AuthCrypt          AuthCrypt();          ~AuthCrypt(); -        const static size_t CRYPTED_SEND_LEN = 4;          const static size_t CRYPTED_RECV_LEN = 6;          void Init(); diff --git a/src/shared/ByteBuffer.h b/src/shared/ByteBuffer.h index 9bdd6067fbc..efd704a4904 100644 --- a/src/shared/ByteBuffer.h +++ b/src/shared/ByteBuffer.h @@ -243,6 +243,32 @@ class ByteBuffer              _rpos += len;          } +        bool readPackGUID(uint64& guid) +        { +            if(rpos()+1 > size()) +                return false; + +            guid = 0; + +            uint8 guidmark=0; +            (*this) >> guidmark; + +            for(int i=0;i<8;i++) +            { +                if(guidmark & (uint8(1) << i)) +                { +                    if(rpos()+1 > size()) +                        return false; + +                    uint8 bit; +                    (*this) >> bit; +                    guid |= (uint64(bit) << (i*8)); +                } +            } + +            return true; +        } +          const uint8 *contents() const { return &_storage[0]; }          size_t size() const { return _storage.size(); } diff --git a/src/shared/Database/DBCEnums.h b/src/shared/Database/DBCEnums.h index 1d54616a2b5..4f406c9cc63 100644 --- a/src/shared/Database/DBCEnums.h +++ b/src/shared/Database/DBCEnums.h @@ -34,28 +34,190 @@ enum AreaTeams      AREATEAM_HORDE = 4  }; +enum AchievementFactionFlags +{ +    ACHIEVEMENT_FACTION_FLAG_HORDE    = 0x00000000, +    ACHIEVEMENT_FACTION_FLAG_ALLIANCE = 0x00000001, +}; + +enum AchievementFlags +{ +    ACHIEVEMENT_FLAG_COUNTER          = 0x00000001, +    ACHIEVEMENT_FLAG_REACH_LEVEL      = 0x00000004, +    ACHIEVEMENT_FLAG_RERERED_MAX      = 0x00000010,         // displays the maximum criteria of a refered achievement +    ACHIEVEMENT_FLAG_AVERAGE          = 0x00000040, +    ACHIEVEMENT_FLAG_REALM_FIRST_REACH= 0x00000100, +    ACHIEVEMENT_FLAG_REALM_FIRST_KILL = 0x00000200, +}; + +enum AchievementCriteriaCondition +{ +    ACHIEVEMENT_CRITERIA_CONDITION_NONE      = 0, +    ACHIEVEMENT_CRITERIA_CONDITION_NO_DEATH  = 1, +    ACHIEVEMENT_CRITERIA_CONDITION_UNK1      = 2,           // only used in "Complete a daily quest every day for five consecutive days" +    ACHIEVEMENT_CRITERIA_CONDITION_MAP       = 3,           // requires you to be on specific map +    ACHIEVEMENT_CRITERIA_CONDITION_NO_LOOSE  = 4,           // only used in "Win 10 arenas without losing" +    ACHIEVEMENT_CRITERIA_CONDITION_UNK2      = 9,           // unk +    ACHIEVEMENT_CRITERIA_CONDITION_UNK3      = 13,          // unk +}; + +enum AchievementCriteriaCompletionFlags +{ +    // some Achievements (like 698) have several criteria but only one has to be fulfilled. These are identified by this flag. +    ACHIEVEMENT_CRITERIA_COMPLETE_FLAG_ALL = 2, +}; + +enum AchievementCriteriaGroupFlags +{ +    // you mustn't be in a group while fulfilling this achievement +    ACHIEVEMENT_CRITERIA_GROUP_NOT_IN_GROUP = 2, +}; + +enum AchievementCriteriaTypes +{ +    ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0, +    ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1, +    ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5, +    ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9, +    // you have to complete a daily quest x times in a row +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11, +    ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15, +    ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16, +    // TODO: this can be both arena and total deaths. Where is this difference in the dbc? +    ACHIEVEMENT_CRITERIA_TYPE_DEATH= 17, +    ACHIEVEMENT_CRITERIA_TYPE_DEATH_IN_DUNGEON = 18, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19, +    ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20, +    ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_PLAYER = 23, +    ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24, +    ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26, +    ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27, +    ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28, +    ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29, +    ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE = 30, +    ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31, +    ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32, +    ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33, +    ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34, +    // TODO: this criteria has additional conditions which can not be found in the dbcs +    ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL = 35, +    ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36, +    // TODO: the archievements 1162 and 1163 requires a special rating which can't be found in the dbc +    ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38, +    ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39, +    ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40, +    ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41, +    ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM= 42, +    ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43, +    ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44, +    ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45, +    ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46, +    ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47, +    // noted: rewarded as soon as the player payed, not at taking place at the seat +    ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP= 48, +    ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49, +    // TODO: itemlevel is mentioned in text but not present in dbc +    ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT = 50, +    ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED_ON_LOOT= 51, +    ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52, +    ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53, +    ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54, +    ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55, +    // TODO: in some cases map not present, and in some cases need do without die +    ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56, +    ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57, +    ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_VENDORS = 59, +    ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TALENTS = 60, +    ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS = 61, +    ACHIEVEMENT_CRITERIA_TYPE_MONEY_FROM_QUEST_REWARD = 62, +    ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING = 63, +    ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_AT_BARBER = 65, +    ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_MAIL = 66, +    ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67, +    ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68, +    ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69, +    ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70, +    ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72, +    // TODO: title id is not mentioned in dbc +    ACHIEVEMENT_CRITERIA_TYPE_EARNED_PVP_TITLE = 74, +    ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75, +    ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76, +    ACHIEVEMENT_CRITERIA_TYPE_LOSE_DUEL = 77, +    // TODO: creature type (demon, undead etc.) is not stored in dbc +    ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE_TYPE = 78, +    ACHIEVEMENT_CRITERIA_TYPE_GOLD_EARNED_BY_AUCTIONS= 80, +    ACHIEVEMENT_CRITERIA_TYPE_CREATE_AUCTION= 82, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID= 83, +    ACHIEVEMENT_CRITERIA_TYPE_WON_AUCTIONS= 84, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_SOLD = 85, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_GOLD_VALUE_OWNED = 86, +    ACHIEVEMENT_CRITERIA_TYPE_GAIN_REVERED_REPUTATION = 87, +    ACHIEVEMENT_CRITERIA_TYPE_GAIN_HONORED_REPUTATION = 88, +    ACHIEVEMENT_CRITERIA_TYPE_KNOWN_FACTIONS = 89, +    ACHIEVEMENT_CRITERIA_TYPE_LOOT_EPIC_ITEM = 90, +    ACHIEVEMENT_CRITERIA_TYPE_RECEIVE_EPIC_ITEM = 91, +    ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED = 93, +    ACHIEVEMENT_CRITERIA_TYPE_ROLL_GREED = 94, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALTH = 95, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_ARMOR = 99, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_DEALT = 101, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED = 102, +    ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED = 103, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEAL_CASTED = 104, +    ACHIEVEMENT_CRITERIA_TYPE_TOTAL_HEALING_RECEIVED = 105, +    ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HEALING_RECEIVED = 106, +    ACHIEVEMENT_CRITERIA_TYPE_QUEST_ABANDONED = 107, +    ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN = 108, +    ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109, +    // TODO: target entry is missing +    ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110, +    ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112, +    ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113, +    ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS = 114, +    // 0..114 => 115 criteria types total +    ACHIEVEMENT_CRITERIA_TYPE_TOTAL = 115, +}; +  enum AreaFlags  {      AREA_FLAG_SNOW             = 0x00000001,                // snow (only Dun Morogh, Naxxramas, Razorfen Downs and Winterspring) -    AREA_FLAG_UNK1             = 0x00000002,                // unknown, (only Naxxramas and Razorfen Downs) -    AREA_FLAG_UNK2             = 0x00000004,                // Only used on development map -    AREA_FLAG_SLAVE_CAPITAL    = 0x00000008,                // slave capital city flag? -    AREA_FLAG_UNK3             = 0x00000010,                // unknown +    AREA_FLAG_UNK1             = 0x00000002,                // may be necropolis? +    AREA_FLAG_UNK2             = 0x00000004,                // Only used for areas on map 571 (development before) +    AREA_FLAG_SLAVE_CAPITAL    = 0x00000008,                // city and city subsones +    AREA_FLAG_UNK3             = 0x00000010,                // can't find common meaning      AREA_FLAG_SLAVE_CAPITAL2   = 0x00000020,                // slave capital city flag?      AREA_FLAG_UNK4             = 0x00000040,                // many zones have this flag      AREA_FLAG_ARENA            = 0x00000080,                // arena, both instanced and world arenas      AREA_FLAG_CAPITAL          = 0x00000100,                // main capital city flag      AREA_FLAG_CITY             = 0x00000200,                // only for one zone named "City" (where it located?) -    AREA_FLAG_OUTLAND          = 0x00000400,                // outland zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag) +    AREA_FLAG_OUTLAND          = 0x00000400,                // expansion zones? (only Eye of the Storm not have this flag, but have 0x00004000 flag)      AREA_FLAG_SANCTUARY        = 0x00000800,                // sanctuary area (PvP disabled)      AREA_FLAG_NEED_FLY         = 0x00001000,                // only Netherwing Ledge, Socrethar's Seat, Tempest Keep, The Arcatraz, The Botanica, The Mechanar, Sorrow Wing Point, Dragonspine Ridge, Netherwing Mines, Dragonmaw Base Camp, Dragonmaw Skyway -    AREA_FLAG_UNUSED1          = 0x00002000,                // not used now (no area/zones with this flag set in 2.4.2) -    AREA_FLAG_OUTLAND2         = 0x00004000,                // outland zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag) +    AREA_FLAG_UNUSED1          = 0x00002000,                // not used now (no area/zones with this flag set in 3.0.3) +    AREA_FLAG_OUTLAND2         = 0x00004000,                // expansion zones? (only Circle of Blood Arena not have this flag, but have 0x00000400 flag)      AREA_FLAG_PVP              = 0x00008000,                // pvp objective area? (Death's Door also has this flag although it's no pvp object area)      AREA_FLAG_ARENA_INSTANCE   = 0x00010000,                // used by instanced arenas only -    AREA_FLAG_UNUSED2          = 0x00020000,                // not used now (no area/zones with this flag set in 2.4.2) -    AREA_FLAG_UNK5             = 0x00040000,                // just used for Amani Pass, Hatchet Hills -    AREA_FLAG_LOWLEVEL         = 0x00100000                 // used for some starting areas with area_level <=15 +    AREA_FLAG_UNUSED2          = 0x00020000,                // not used now (no area/zones with this flag set in 3.0.3) +    AREA_FLAG_UNK5             = 0x00040000,                // only used for Amani Pass, Hatchet Hills +    AREA_FLAG_UNK6             = 0x00080000,                // Valgarde and Acherus: The Ebon Hold +    AREA_FLAG_LOWLEVEL         = 0x00100000,                // used for some starting areas with area_level <=15 +    AREA_FLAG_TOWN             = 0x00200000,                // small towns with Inn +    AREA_FLAG_UNK7             = 0x00400000,                // Warsong Hold, Acherus: The Ebon Hold, New Agamand Inn, Vengeance Landing Inn +    AREA_FLAG_UNK8             = 0x00800000,                // Westguard Inn, Acherus: The Ebon Hold, Valgarde +    AREA_FLAG_OUTDOOR_PVP      = 0x01000000,                // Wintergrasp and it's subzones +    AREA_FLAG_UNK9             = 0x02000000,                // unknown +    AREA_FLAG_UNK10            = 0x04000000,                // unknown +    AREA_FLAG_OUTDOOR_PVP2     = 0x08000000                 // Wintergrasp and it's subzones  };  enum FactionTemplateFlags @@ -109,4 +271,51 @@ enum TotemCategoryType      TOTEM_CATEGORY_TYPE_SPANNER = 24  }; +// SummonProperties.dbc, col 1 +/*enum SummonGroup +{ +    SUMMON_GROUP_UNKNOWN1       = 0,                        // 1160 spells in 3.0.3 +    SUMMON_GROUP_UNKNOWN2       = 1,                        // 861 spells in 3.0.3 +    SUMMON_GROUP_PETS           = 2,                        // 52 spells in 3.0.3, pets mostly +    SUMMON_GROUP_CONTROLLABLE   = 3,                        // 13 spells in 3.0.3, mostly controllable +    SUMMON_GROUP_UNKNOWN3       = 4                         // 86 spells in 3.0.3, taxi/mounts +}; + +// SummonProperties.dbc, col 3 +enum SummonType +{ +    SUMMON_TYPE_UNKNOWN         = 0,                        // different summons, 1330 spells in 3.0.3 +    SUMMON_TYPE_SUMMON          = 1,                        // generic summons, 49 spells in 3.0.3 +    SUMMON_TYPE_GUARDIAN        = 2,                        // summon guardian, 393 spells in 3.0.3 +    SUMMON_TYPE_ARMY            = 3,                        // summon army, 5 spells in 3.0.3 +    SUMMON_TYPE_TOTEM           = 4,                        // summon totem, 169 spells in 3.0.3 +    SUMMON_TYPE_CRITTER         = 5,                        // critter/minipet, 195 spells in 3.0.3 +    SUMMON_TYPE_DK              = 6,                        // summon DRW/Ghoul, 2 spells in 3.0.3 +    SUMMON_TYPE_BOMB            = 7,                        // summon bot/bomb, 4 spells in 3.0.3 +    SUMMON_TYPE_PHASING         = 8,                        // something todo with DK prequest line, 2 spells in 3.0.3 +    SUMMON_TYPE_SIEGE_VEH       = 9,                        // summon different vehicles, 14 spells in 3.0.3 +    SUMMON_TYPE_DRAKE_VEH       = 10,                       // summon drake (vehicle), 3 spells +    SUMMON_TYPE_LIGHTWELL       = 11                        // summon lightwell, 6 spells in 3.0.3 +}; + +// SummonProperties.dbc, col 5 +enum SummonFlags +{ +    SUMMON_FLAG_NONE            = 0x0000,                   // 1342 spells in 3.0.3 +    SUMMON_FLAG_UNK1            = 0x0001,                   // 75 spells in 3.0.3, something unfriendly +    SUMMON_FLAG_UNK2            = 0x0002,                   // 616 spells in 3.0.3, something friendly +    SUMMON_FLAG_UNK3            = 0x0004,                   // 22 spells in 3.0.3, no idea... +    SUMMON_FLAG_UNK4            = 0x0008,                   // 49 spells in 3.0.3, some mounts +    SUMMON_FLAG_UNK5            = 0x0010,                   // 25 spells in 3.0.3, quest related? +    SUMMON_FLAG_UNK6            = 0x0020,                   // 0 spells in 3.0.3, unused +    SUMMON_FLAG_UNK7            = 0x0040,                   // 12 spells in 3.0.3, no idea +    SUMMON_FLAG_UNK8            = 0x0080,                   // 4 spells in 3.0.3, no idea +    SUMMON_FLAG_UNK9            = 0x0100,                   // 51 spells in 3.0.3, no idea, many quest related +    SUMMON_FLAG_UNK10           = 0x0200,                   // 51 spells in 3.0.3, something defensive +    SUMMON_FLAG_UNK11           = 0x0400,                   // 3 spells, requires something near? +    SUMMON_FLAG_UNK12           = 0x0800,                   // 30 spells in 3.0.3, no idea +    SUMMON_FLAG_UNK13           = 0x1000,                   // 8 spells in 3.0.3, siege vehicle +    SUMMON_FLAG_UNK14           = 0x2000,                   // 2 spells in 3.0.3, escort? +}; +*/  #endif diff --git a/src/shared/Database/DBCStores.cpp b/src/shared/Database/DBCStores.cpp index fb132c75768..c183f8356b4 100644 --- a/src/shared/Database/DBCStores.cpp +++ b/src/shared/Database/DBCStores.cpp @@ -35,9 +35,12 @@ DBCStorage <AreaTableEntry> sAreaStore(AreaTableEntryfmt);  static AreaFlagByAreaID sAreaFlagByAreaID;  static AreaFlagByMapID  sAreaFlagByMapID;                   // for instances without generated *.map files +DBCStorage <AchievementEntry> sAchievementStore(Achievementfmt); +DBCStorage <AchievementCriteriaEntry> sAchievementCriteriaStore(AchievementCriteriafmt);  DBCStorage <AreaTriggerEntry> sAreaTriggerStore(AreaTriggerEntryfmt);  DBCStorage <BankBagSlotPricesEntry> sBankBagSlotPricesStore(BankBagSlotPricesEntryfmt);  DBCStorage <BattlemasterListEntry> sBattlemasterListStore(BattlemasterListEntryfmt); +DBCStorage <BarberShopStyleEntry> sBarberShopStyleStore(BarberShopStyleEntryfmt);  DBCStorage <CharStartOutfitEntry> sCharStartOutfitStore(CharStartOutfitEntryfmt);  DBCStorage <CharTitlesEntry> sCharTitlesStore(CharTitlesEntryfmt);  DBCStorage <ChatChannelsEntry> sChatChannelsStore(ChatChannelsEntryfmt); @@ -58,7 +61,10 @@ DBCStorage <FactionEntry> sFactionStore(FactionEntryfmt);  DBCStorage <FactionTemplateEntry> sFactionTemplateStore(FactionTemplateEntryfmt);  DBCStorage <GemPropertiesEntry> sGemPropertiesStore(GemPropertiesEntryfmt); +DBCStorage <GlyphPropertiesEntry> sGlyphPropertiesStore(GlyphPropertiesfmt); +DBCStorage <GlyphSlotEntry> sGlyphSlotStore(GlyphSlotfmt); +DBCStorage <GtBarberShopCostBaseEntry>    sGtBarberShopCostBaseStore(GtBarberShopCostBasefmt);  DBCStorage <GtCombatRatingsEntry>         sGtCombatRatingsStore(GtCombatRatingsfmt);  DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore(GtChanceToMeleeCritBasefmt);  DBCStorage <GtChanceToMeleeCritEntry>     sGtChanceToMeleeCritStore(GtChanceToMeleeCritfmt); @@ -84,6 +90,8 @@ DBCStorage <MapEntry> sMapStore(MapEntryfmt);  DBCStorage <QuestSortEntry> sQuestSortStore(QuestSortEntryfmt);  DBCStorage <RandomPropertiesPointsEntry> sRandomPropertiesPointsStore(RandomPropertiesPointsfmt); +DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore(ScalingStatDistributionfmt); +DBCStorage <ScalingStatValuesEntry> sScalingStatValuesStore(ScalingStatValuesfmt);  DBCStorage <SkillLineEntry> sSkillLineStore(SkillLinefmt);  DBCStorage <SkillLineAbilityEntry> sSkillLineAbilityStore(SkillLineAbilityfmt); @@ -101,8 +109,10 @@ DBCStorage <SpellDurationEntry> sSpellDurationStore(SpellDurationfmt);  DBCStorage <SpellFocusObjectEntry> sSpellFocusObjectStore(SpellFocusObjectfmt);  DBCStorage <SpellRadiusEntry> sSpellRadiusStore(SpellRadiusfmt);  DBCStorage <SpellRangeEntry> sSpellRangeStore(SpellRangefmt); +DBCStorage <SpellRuneCostEntry> sSpellRuneCostStore(SpellRuneCostfmt);  DBCStorage <SpellShapeshiftEntry> sSpellShapeshiftStore(SpellShapeshiftfmt);  DBCStorage <StableSlotPricesEntry> sStableSlotPricesStore(StableSlotPricesfmt); +//DBCStorage <SummonPropertiesEntry> sSummonPropertiesStore(SummonPropertiesfmt);  DBCStorage <TalentEntry> sTalentStore(TalentEntryfmt);  TalentSpellPosMap sTalentSpellPosMap;  DBCStorage <TalentTabEntry> sTalentTabStore(TalentTabEntryfmt); @@ -125,8 +135,11 @@ TaxiPathNodesByPath sTaxiPathNodesByPath;  static DBCStorage <TaxiPathNodeEntry> sTaxiPathNodeStore(TaxiPathNodeEntryfmt);  DBCStorage <TotemCategoryEntry> sTotemCategoryStore(TotemCategoryEntryfmt); +DBCStorage <VehicleEntry> sVehicleStore(VehicleEntryfmt); +DBCStorage <VehicleSeatEntry> sVehicleSeatStore(VehicleSeatEntryfmt);  DBCStorage <WorldMapAreaEntry>  sWorldMapAreaStore(WorldMapAreaEntryfmt);  DBCStorage <WorldSafeLocsEntry> sWorldSafeLocsStore(WorldSafeLocsEntryfmt); +DBCStorage <WorldMapOverlayEntry> sWorldMapOverlayStore(WorldMapOverlayEntryfmt);  typedef std::list<std::string> StoreProblemList; @@ -178,7 +191,7 @@ void LoadDBCStores(const std::string& dataPath)  {      std::string dbcPath = dataPath+"dbc/"; -    const uint32 DBCFilesCount = 56; +    const uint32 DBCFilesCount = 66;      barGoLink bar( DBCFilesCount ); @@ -196,16 +209,19 @@ void LoadDBCStores(const std::string& dataPath)              sAreaFlagByAreaID.insert(AreaFlagByAreaID::value_type(uint16(area->ID),area->exploreFlag));              // fill MapId->DBC records ( skip sub zones and continents ) -            if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 ) +            if(area->zone==0 && area->mapid != 0 && area->mapid != 1 && area->mapid != 530 && area->mapid != 571 )                  sAreaFlagByMapID.insert(AreaFlagByMapID::value_type(area->mapid,area->exploreFlag));          }      } +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementStore,         dbcPath,"Achievement.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAchievementCriteriaStore, dbcPath,"Achievement_Criteria.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sAreaTriggerStore,         dbcPath,"AreaTrigger.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBankBagSlotPricesStore,   dbcPath,"BankBagSlotPrices.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBattlemasterListStore,    dbcPath,"BattlemasterList.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sBarberShopStyleStore,     dbcPath,"BarberShopStyle.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharStartOutfitStore,     dbcPath,"CharStartOutfit.dbc"); - +          LoadDBC(availableDbcLocales,bar,bad_dbc_files,sCharTitlesStore,          dbcPath,"CharTitles.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChatChannelsStore,        dbcPath,"ChatChannels.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sChrClassesStore,          dbcPath,"ChrClasses.dbc"); @@ -229,7 +245,10 @@ void LoadDBCStores(const std::string& dataPath)      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sFactionTemplateStore,     dbcPath,"FactionTemplate.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGemPropertiesStore,       dbcPath,"GemProperties.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphPropertiesStore,     dbcPath,"GlyphProperties.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGlyphSlotStore,           dbcPath,"GlyphSlot.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtBarberShopCostBaseStore,dbcPath,"gtBarberShopCostBase.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtCombatRatingsStore,     dbcPath,"gtCombatRatings.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sGtChanceToMeleeCritBaseStore, dbcPath,"gtChanceToMeleeCritBase.dbc"); @@ -254,6 +273,8 @@ void LoadDBCStores(const std::string& dataPath)      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sMapStore,                 dbcPath,"Map.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sQuestSortStore,           dbcPath,"QuestSort.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sRandomPropertiesPointsStore, dbcPath,"RandPropPoints.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatDistributionStore, dbcPath,"ScalingStatDistribution.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sScalingStatValuesStore,   dbcPath,"ScalingStatValues.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineStore,           dbcPath,"SkillLine.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSkillLineAbilityStore,    dbcPath,"SkillLineAbility.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSoundEntriesStore,        dbcPath,"SoundEntries.dbc"); @@ -303,8 +324,10 @@ void LoadDBCStores(const std::string& dataPath)      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellItemEnchantmentConditionStore,dbcPath,"SpellItemEnchantmentCondition.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRadiusStore,         dbcPath,"SpellRadius.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRangeStore,          dbcPath,"SpellRange.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellRuneCostStore,       dbcPath,"SpellRuneCost.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSpellShapeshiftStore,     dbcPath,"SpellShapeshiftForm.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sStableSlotPricesStore,    dbcPath,"StableSlotPrices.dbc"); +    //LoadDBC(availableDbcLocales,bar,bad_dbc_files,sSummonPropertiesStore,    dbcPath,"SummonProperties.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTalentStore,              dbcPath,"Talent.dbc");      // create talent spells set @@ -407,7 +430,10 @@ void LoadDBCStores(const std::string& dataPath)      pathLength.resize(pathCount);                           // 0 and some other indexes not used      for(uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i)          if(TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) -            ++pathLength[entry->path]; +        { +            if (pathLength[entry->path] < entry->index + 1) +                pathLength[entry->path] = entry->index + 1; +        }      // Set path length      sTaxiPathNodesByPath.resize(pathCount);                 // 0 and some other indexes not used      for(uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) @@ -419,8 +445,11 @@ void LoadDBCStores(const std::string& dataPath)      sTaxiPathNodeStore.Clear();      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sTotemCategoryStore,       dbcPath,"TotemCategory.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleStore,             dbcPath,"Vehicle.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sVehicleSeatStore,         dbcPath,"VehicleSeat.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapAreaStore,        dbcPath,"WorldMapArea.dbc");      LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldSafeLocsStore,       dbcPath,"WorldSafeLocs.dbc"); +    LoadDBC(availableDbcLocales,bar,bad_dbc_files,sWorldMapOverlayStore,     dbcPath,"WorldMapOverlay.dbc");      // error checks      if(bad_dbc_files.size() >= DBCFilesCount ) @@ -438,20 +467,20 @@ void LoadDBCStores(const std::string& dataPath)          exit(1);      } -    // check at up-to-date DBC files (53085 is last added spell in 2.4.3) -    // check at up-to-date DBC files (17514 is last ID in SkillLineAbilities in 2.4.3) -    // check at up-to-date DBC files (598 is last map added in 2.4.3) -    // check at up-to-date DBC files (1127 is last gem property added in 2.4.3) -    // check at up-to-date DBC files (2425 is last item extended cost added in 2.4.3) -    // check at up-to-date DBC files (71 is last char title added in 2.4.3) -    // check at up-to-date DBC files (1768 is last area added in 2.4.3) -    if( !sSpellStore.LookupEntry(53085)            || -        !sSkillLineAbilityStore.LookupEntry(17514) || -        !sMapStore.LookupEntry(598)                || -        !sGemPropertiesStore.LookupEntry(1127)     || -        !sItemExtendedCostStore.LookupEntry(2425)  || -        !sCharTitlesStore.LookupEntry(71)          || -        !sAreaStore.LookupEntry(1768)              ) +    // check at up-to-date DBC files (54909 is last added spell in 3.0.1) +    // check at up-to-date DBC files (19162 is last added spell in abilities in 3.0.1) +    // check at up-to-date DBC files (619 is last map added in 3.0.1) +    // check at up-to-date DBC files (1361 is last gem property added in 3.0.1) +    // check at up-to-date DBC files (2425 is last item extended cost added in 3.0.1) +    // check at up-to-date DBC files (76 is last char title added in 3.0.1) +    // check at up-to-date DBC files (2311 is last area added in 3.0.1) +    if( !sSpellStore.LookupEntry(54909)            ||  +        !sSkillLineAbilityStore.LookupEntry(19162) ||  +        !sMapStore.LookupEntry(619)                || +        !sGemPropertiesStore.LookupEntry(1361)     ||  +        !sItemExtendedCostStore.LookupEntry(2425)  ||  +        !sCharTitlesStore.LookupEntry(76)          || +        !sAreaStore.LookupEntry(2311)              )      {          sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client.");          exit(1); @@ -537,7 +566,7 @@ uint32 GetAreaFlagByMapId(uint32 mapid)  uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId)  { -    if(mapid != 530)                                        // speed for most cases +    if(mapid != 530 || mapid != 571)                        // speed for most cases          return mapid;      if(WorldMapAreaEntry const* wma = sWorldMapAreaStore.LookupEntry(zoneId)) diff --git a/src/shared/Database/DBCStores.h b/src/shared/Database/DBCStores.h index 98a54fbeccf..8f53fef84ef 100644 --- a/src/shared/Database/DBCStores.h +++ b/src/shared/Database/DBCStores.h @@ -132,9 +132,12 @@ class DBCStorage          StringPoolList m_stringPoolList;  }; +extern DBCStorage <AchievementEntry>             sAchievementStore; +extern DBCStorage <AchievementCriteriaEntry>     sAchievementCriteriaStore;  extern DBCStorage <AreaTableEntry>               sAreaStore;// recommend access using functions  extern DBCStorage <AreaTriggerEntry>             sAreaTriggerStore;  extern DBCStorage <BankBagSlotPricesEntry>       sBankBagSlotPricesStore; +extern DBCStorage <BarberShopStyleEntry>         sBarberShopStyleStore;  extern DBCStorage <BattlemasterListEntry>        sBattlemasterListStore;  //extern DBCStorage <ChatChannelsEntry>           sChatChannelsStore; -- accessed using function, no usable index  extern DBCStorage <CharStartOutfitEntry>         sCharStartOutfitStore; @@ -150,7 +153,10 @@ extern DBCStorage <EmotesTextEntry>              sEmotesTextStore;  extern DBCStorage <FactionEntry>                 sFactionStore;  extern DBCStorage <FactionTemplateEntry>         sFactionTemplateStore;  extern DBCStorage <GemPropertiesEntry>           sGemPropertiesStore; +extern DBCStorage <GlyphPropertiesEntry>         sGlyphPropertiesStore; +extern DBCStorage <GlyphSlotEntry>               sGlyphSlotStore; +extern DBCStorage <GtBarberShopCostBaseEntry>    sGtBarberShopCostBaseStore;  extern DBCStorage <GtCombatRatingsEntry>         sGtCombatRatingsStore;  extern DBCStorage <GtChanceToMeleeCritBaseEntry> sGtChanceToMeleeCritBaseStore;  extern DBCStorage <GtChanceToMeleeCritEntry>     sGtChanceToMeleeCritStore; @@ -171,6 +177,8 @@ extern DBCStorage <MailTemplateEntry>            sMailTemplateStore;  extern DBCStorage <MapEntry>                     sMapStore;  extern DBCStorage <QuestSortEntry>               sQuestSortStore;  extern DBCStorage <RandomPropertiesPointsEntry>  sRandomPropertiesPointsStore; +extern DBCStorage <ScalingStatDistributionEntry> sScalingStatDistributionStore; +extern DBCStorage <ScalingStatValuesEntry>       sScalingStatValuesStore;  extern DBCStorage <SkillLineEntry>               sSkillLineStore;  extern DBCStorage <SkillLineAbilityEntry>        sSkillLineAbilityStore;  extern DBCStorage <SoundEntriesEntry>            sSoundEntriesStore; @@ -183,9 +191,11 @@ extern SpellCategoryStore                        sSpellCategoryStore;  extern PetFamilySpellsStore                      sPetFamilySpellsStore;  extern DBCStorage <SpellRadiusEntry>             sSpellRadiusStore;  extern DBCStorage <SpellRangeEntry>              sSpellRangeStore; +extern DBCStorage <SpellRuneCostEntry>           sSpellRuneCostStore;  extern DBCStorage <SpellShapeshiftEntry>         sSpellShapeshiftStore;  extern DBCStorage <SpellEntry>                   sSpellStore;  extern DBCStorage <StableSlotPricesEntry>        sStableSlotPricesStore; +//extern DBCStorage <SummonPropertiesEntry>        sSummonPropertiesStore;  extern DBCStorage <TalentEntry>                  sTalentStore;  extern DBCStorage <TalentTabEntry>               sTalentTabStore;  extern DBCStorage <TaxiNodesEntry>               sTaxiNodesStore; @@ -194,8 +204,11 @@ extern TaxiMask                                  sTaxiNodesMask;  extern TaxiPathSetBySource                       sTaxiPathSetBySource;  extern TaxiPathNodesByPath                       sTaxiPathNodesByPath;  extern DBCStorage <TotemCategoryEntry>           sTotemCategoryStore; +extern DBCStorage <VehicleEntry>                 sVehicleStore; +extern DBCStorage <VehicleSeatEntry>             sVehicleSeatStore;  //extern DBCStorage <WorldMapAreaEntry>           sWorldMapAreaStore; -- use Zone2MapCoordinates and Map2ZoneCoordinates  extern DBCStorage <WorldSafeLocsEntry>           sWorldSafeLocsStore; +extern DBCStorage <WorldMapOverlayEntry>         sWorldMapOverlayStore;  void LoadDBCStores(const std::string& dataPath); diff --git a/src/shared/Database/DBCStructure.h b/src/shared/Database/DBCStructure.h index 99d789f133f..c01b2f440fc 100644 --- a/src/shared/Database/DBCStructure.h +++ b/src/shared/Database/DBCStructure.h @@ -37,57 +37,507 @@  #pragma pack(push,1)  #endif -struct AreaTableEntry +struct AchievementEntry +{ +    uint32    ID;                                           // 0 +    uint32    factionFlag;                                  // 1 -1=all, 0=horde, 1=alliance +    uint32    mapID;                                        // 2 -1=none +    //uint32 parentAchievement;                             // 3 its Achievement parent (can`t start while parent uncomplete, use its Criteria if don`t have own, use its progress on begin) +    //char *name[16];                                       // 4-19 +    //uint32 name_flags;                                    // 20 +    //char *description[16];                                // 21-36 +    //uint32 desc_flags;                                    // 37 +    uint32    categoryId;                                   // 38 +    uint32    points;                                       // 39 reward points +    //uint32 OrderInCategory;                               // 40 +    uint32    flags;                                        // 41 +    //uint32    icon;                                       // 42 icon (from SpellIcon.dbc) +    //char *titleReward[16];                                // 43-58 +    //uint32 titleReward_flags;                             // 59 +    //uint32 count;                                         // 60 - need this count Criteria for complete +    uint32 refAchievement;                                  // 61 - related achievement? +}; + +struct AchievementCategoryEntry  {      uint32    ID;                                           // 0 -    uint32    mapid;                                        // 1 -    uint32    zone;                                         // 2 if 0 then it's zone, else it's zone id of this area -    uint32    exploreFlag;                                  // 3, main index -    uint32    flags;                                        // 4, unknown value but 312 for all cities +    uint32    parentCategory;                               // 1 -1 for main category +    //char *name[16];                                       // 2-17 +    //uint32 name_flags;                                    // 18 +    //uint32    sortOrder;                                  // 19 +}; + +struct AchievementCriteriaEntry +{ +    uint32  ID;                                             // 0 +    uint32  referredAchievement;                            // 1 +    uint32  requiredType;                                   // 2 +    union +    { +        // ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0 +        // TODO: also used for player deaths.. +        struct +        { +            uint32  creatureID;                             // 3 +            uint32  creatureCount;                          // 4 +        } kill_creature; + +        // ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1 +        // TODO: there are further criterias instead just winning +        struct +        { +            uint32  bgMapID;                                // 3 +            uint32  winCount;                               // 4 +        } win_bg; + +        // ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL = 5 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  level;                                  // 4 +        } reach_level; + +        // ACHIEVEMENT_CRITERIA_TYPE_REACH_SKILL_LEVEL = 7 +        struct +        { +            uint32  skillID;                                // 3 +            uint32  skillLevel;                             // 4 +        } reach_skill_level; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_ACHIEVEMENT = 8 +        struct +        { +            uint32  linkedAchievement;                      // 3 +        } complete_achievement; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT = 9 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  totalQuestCount;                        // 4 +        } complete_quest_count; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY = 10 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  numberOfDays;                           // 4 +        } complete_daily_quest_daily; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE = 11 +        struct +        { +            uint32  zoneID;                                 // 3 +            uint32  questCount;                             // 4 +        } complete_quests_in_zone; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST = 14 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  questCount;                             // 4 +        } complete_daily_quest; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_BATTLEGROUND= 15 +        struct +        { +            uint32  mapID;                                  // 3 +        } complete_battleground; + +        // ACHIEVEMENT_CRITERIA_TYPE_DEATH_AT_MAP= 16 +        struct +        { +            uint32  mapID;                                  // 3 +        } death_at_map; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID = 19 +        struct +        { +            uint32  groupSize;                              // 3 can be 5, 10 or 25 +        } complete_raid; + +        // ACHIEVEMENT_CRITERIA_TYPE_KILLED_BY_CREATURE = 20 +        struct +        { +            uint32  creatureEntry;                          // 3 +        } killed_by_creature; + +        // ACHIEVEMENT_CRITERIA_TYPE_FALL_WITHOUT_DYING = 24 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  fallHeight;                             // 4 +        } fall_without_dying; + +        // ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM = 26 +        struct +        { +            uint32 type; // 0 - fatigue, 1 - drowning, 2 - falling, 3 - ??, 5 - fire and lava +        } deaths; + +        // ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST = 27 +        struct +        { +            uint32  questID;                                // 3 +            uint32  questCount;                             // 4 +        } complete_quest; + +        // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET = 28 +        // ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET2= 69 +        struct +        { +            uint32  spellID;                                // 3 +            uint32  spellCount;                             // 4 +        } be_spell_target; + +        // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL= 29 +        // ACHIEVEMENT_CRITERIA_TYPE_CAST_SPELL2 = 110 +        struct +        { +            uint32  spellID;                                // 3 +            uint32  castCount;                              // 4 +        } cast_spell; + +        // ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA = 31 +        struct +        { +            uint32  areaID;                                 // 3 Reference to AreaTable.dbc +            uint32  killCount;                              // 4 +        } honorable_kill_at_area; + +        // ACHIEVEMENT_CRITERIA_TYPE_WIN_ARENA = 32 +        struct +        { +            uint32  mapID;                                  // 3 Reference to Map.dbc +        } win_arena; + +        // ACHIEVEMENT_CRITERIA_TYPE_PLAY_ARENA = 33 +        struct +        { +            uint32  mapID;                                  // 3 Reference to Map.dbc +        } play_arena; + +        // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL = 34 +        struct +        { +            uint32  spellID;                                // 3 Reference to Map.dbc +        } learn_spell; + +        // ACHIEVEMENT_CRITERIA_TYPE_OWN_ITEM = 36 +        struct +        { +            uint32  itemID;                                 // 3 +            uint32  itemCount;                              // 4 +        } own_item; + +        // ACHIEVEMENT_CRITERIA_TYPE_WIN_RATED_ARENA = 37 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  count;                                  // 4 +            uint32  flag;                                   // 5 4=in a row +        } win_rated_arena; + +        // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_TEAM_RATING = 38 +        struct +        { +            uint32  teamtype;                               // 3 {2,3,5} +        } highest_team_rating; + +        // ACHIEVEMENT_CRITERIA_TYPE_REACH_TEAM_RATING = 39 +        struct +        { +            uint32  teamtype;                               // 3 {2,3,5} +            uint32  teamrating;                             // 4 +        } reach_team_rating; + +        // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LEVEL = 40 +        struct +        { +            uint32  skillID;                                // 3 +            uint32  skillLevel;                             // 4 apprentice=1, journeyman=2, expert=3, artisan=4, master=5, grand master=6 +        } learn_skill_level; + +        // ACHIEVEMENT_CRITERIA_TYPE_USE_ITEM = 41 +        struct +        { +            uint32  itemID;                                 // 3 +            uint32  itemCount;                              // 4 +        } use_item; + +        // ACHIEVEMENT_CRITERIA_TYPE_LOOT_ITEM = 42 +        struct +        { +            uint32  itemID;                                 // 3 +            uint32  itemCount;                              // 4 +        } loot_item; + +        // ACHIEVEMENT_CRITERIA_TYPE_EXPLORE_AREA = 43 +        struct +        { +            // TODO: This rank is _NOT_ the index from AreaTable.dbc +            uint32  areaReference;                          // 3 +        } explore_area; + +        // ACHIEVEMENT_CRITERIA_TYPE_OWN_RANK= 44 +        struct +        { +            // TODO: This rank is _NOT_ the index from CharTitles.dbc +            uint32  rank;                                   // 3 +        } own_rank; + +        // ACHIEVEMENT_CRITERIA_TYPE_BUY_BANK_SLOT= 45 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  numberOfSlots;                          // 4 +        } buy_bank_slot; + +        // ACHIEVEMENT_CRITERIA_TYPE_GAIN_REPUTATION= 46 +        struct +        { +            uint32  factionID;                              // 3 +            uint32  reputationAmount;                       // 4 Total reputation amount, so 42000 = exalted +        } gain_reputation; + +        // ACHIEVEMENT_CRITERIA_TYPE_GAIN_EXALTED_REPUTATION= 47 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  numberOfExaltedFactions;                // 4 +        } gain_exalted_reputation; + +        // ACHIEVEMENT_CRITERIA_TYPE_VISIT_BARBER_SHOP = 48 +        struct +        { +            uint32 unused;                                  // 3 +            uint32 numberOfVisits;                          // 4 +        } visit_barber; + +        // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_EPIC_ITEM = 49 +        // TODO: where is the required itemlevel stored? +        struct +        { +            uint32  itemSlot;                               // 3 +        } equip_epic_item; + +        // ACHIEVEMENT_CRITERIA_TYPE_ROLL_NEED_ON_LOOT= 50 +        struct +        { +            uint32  rollValue;                              // 3 +            uint32  count;                                  // 4 +        } roll_need_on_loot; + +        // ACHIEVEMENT_CRITERIA_TYPE_HK_CLASS = 52 +        struct +        { +            uint32  classID;                                // 3 +            uint32  count;                                  // 4 +        } hk_class; + +        // ACHIEVEMENT_CRITERIA_TYPE_HK_RACE = 53 +        struct +        { +            uint32  raceID;                                 // 3 +            uint32  count;                                  // 4 +        } hk_race; + +        // ACHIEVEMENT_CRITERIA_TYPE_DO_EMOTE = 54 +        // TODO: where is the information about the target stored? +        struct +        { +            uint32  emoteID;                                // 3 +        } do_emote; +        // ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE = 13 +        // ACHIEVEMENT_CRITERIA_TYPE_HEALING_DONE = 55 +        // ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS = 56 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  count;                                  // 4 +            uint32  flag;                                   // 5 =3 for battleground healing +            uint32  mapid;                                  // 6 +        } healing_done; + +        // ACHIEVEMENT_CRITERIA_TYPE_EQUIP_ITEM = 57 +        struct +        { +            uint32  itemID;                                 // 3 +        } equip_item; + + +        // ACHIEVEMENT_CRITERIA_TYPE_LOOT_MONEY = 67 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  goldInCopper;                           // 4 +        } loot_money; + +        // ACHIEVEMENT_CRITERIA_TYPE_USE_GAMEOBJECT = 68 +        struct +        { +            uint32  goEntry;                                // 3 +            uint32  useCount;                               // 4 +        } use_gameobject; + +        // ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL= 70 +        // TODO: are those special criteria stored in the dbc or do we have to add another sql table? +        struct +        { +            uint32  unused;                                 // 3 +            uint32  killCount;                              // 4 +        } special_pvp_kill; + +        // ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT = 72 +        struct +        { +            uint32  goEntry;                                // 3 +            uint32  lootCount;                              // 4 +        } fish_in_gameobject; + +        // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS= 75 +        struct +        { +            uint32  skillLine;                              // 3 +            uint32  spellCount;                             // 4 +        } learn_skilline_spell; + +        // ACHIEVEMENT_CRITERIA_TYPE_WIN_DUEL = 76 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  duelCount;                              // 4 +        } win_duel; + +        // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_POWER = 96 +        struct +        { +            uint32  powerType;                              // 3 mana=0, 1=rage, 3=energy, 6=runic power +        } highest_power; + +        // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_STAT = 97 +        struct +        { +            uint32  statType;                               // 3 4=spirit, 3=int, 2=stamina, 1=agi, 0=strength +        } highest_stat; + +        // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_SPELLPOWER = 98 +        struct +        { +            uint32  spellSchool;                            // 3 +        } highest_spellpower; + +        // ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING = 100 +        struct +        { +            uint32  ratingType;                             // 3 +        } highest_rating; + +        // ACHIEVEMENT_CRITERIA_TYPE_LOOT_TYPE = 109 +        struct +        { +            uint32  lootType;                               // 3 3=fishing, 2=pickpocket, 4=disentchant +            uint32  lootTypeCount;                          // 4 +        } loot_type; + +        // ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE= 112 +        struct +        { +            uint32  skillLine;                              // 3 +            uint32  spellCount;                             // 4 +        } learn_skill_line; + +        // ACHIEVEMENT_CRITERIA_TYPE_EARN_HONORABLE_KILL = 113 +        struct +        { +            uint32  unused;                                 // 3 +            uint32  killCount;                              // 4 +        } honorable_kill; + +        struct +        { +            uint32  field3;                                 // 3 main requirement +            uint32  field4;                                 // 4 main requirement count +            uint32  additionalRequirement1_type;            // 5 additional requirement 1 type +            uint32  additionalRequirement1_value;           // 6 additional requirement 1 value +            uint32  additionalRequirement2_type;            // 7 additional requirement 2 type +            uint32  additionalRequirement2_value;           // 8 additional requirement 1 value +        } raw; +    }; +    //char*  name[16];                                      // 9-24 +    //uint32 name_flags;                                    // 25 +    uint32  completionFlag;                                 // 26 +    uint32  groupFlag;                                      // 27 +    //uint32 unk1;                                          // 28 +    uint32  timeLimit;                                      // 29 time limit in seconds +    //uint32 showOrder;                                     // 30 show order +}; + +struct AreaTableEntry +{ +    uint32  ID;                                             // 0 +    uint32  mapid;                                          // 1 +    uint32  zone;                                           // 2 if 0 then it's zone, else it's zone id of this area +    uint32  exploreFlag;                                    // 3, main index +    uint32  flags;                                          // 4, unknown value but 312 for all cities                                                              // 5-9 unused -    int32     area_level;                                   // 10 -    char*     area_name[16];                                // 11-26 +    int32   area_level;                                     // 10 +    char*   area_name[16];                                  // 11-26                                                              // 27, string flags, unused -    uint32    team;                                         // 28 +    uint32  team;                                           // 28  };  struct AreaTriggerEntry  { -    uint32    id;                                           // 0 -    uint32    mapid;                                        // 1 -    float     x;                                            // 2 -    float     y;                                            // 3 -    float     z;                                            // 4 -    float     radius;                                       // 5 -    float     box_x;                                        // 6 extent x edge -    float     box_y;                                        // 7 extent y edge -    float     box_z;                                        // 8 extent z edge -    float     box_orientation;                              // 9 extent rotation by about z axis +    uint32  id;                                             // 0        m_ID +    uint32  mapid;                                          // 1        m_ContinentID +    float   x;                                              // 2        m_x +    float   y;                                              // 3        m_y +    float   z;                                              // 4        m_z +    float   radius;                                         // 5        m_radius +    float   box_x;                                          // 6        m_box_length +    float   box_y;                                          // 7        m_box_width +    float   box_z;                                          // 8        m_box_heigh +    float   box_orientation;                                // 9        m_box_yaw  };  struct BankBagSlotPricesEntry  { -    uint32      ID; -    uint32      price; +    uint32  ID; +    uint32  price; +}; + +struct BarberShopStyleEntry +{ +    uint32  Id;                                             // 0 +    uint32  type;                                           // 1 value 0 -> hair, value 2 -> facialhair +    //char*   name[16];                                     // 2-17 name of hair style +    //uint32  name_flags;                                   // 18 +    //uint32  unk_name[16];                                 // 19-34, all empty +    //uint32  unk_flags;                                    // 35 +    //float   CostMultiplier;                               // 36 values 1 and 0.75 +    uint32  race;                                           // 37 race +    uint32  gender;                                         // 38 0 -> male, 1 -> female +    uint32  hair_id;                                        // 39 real ID to hair/facial hair  };  struct BattlemasterListEntry  { -    uint32      id;                                         // 0 -    uint32      mapid[3];                                   // 1-3 mapid -                                                            // 4-8 unused -    uint32      type;                                       // 9 (3 - BG, 4 - arena) -    uint32      minlvl;                                     // 10 -    uint32      maxlvl;                                     // 11 -    uint32      maxplayersperteam;                          // 12 -                                                            // 13-14 unused -    char*       name[16];                                   // 15-30 -                                                            // 31 string flag, unused -                                                            // 32 unused +    uint32  id;                                             // 0 +    int32   mapid[8];                                       // 1-8 mapid +    uint32  type;                                           // 9 (3 - BG, 4 - arena) +    uint32  minlvl;                                         // 10 +    uint32  maxlvl;                                         // 11 +    uint32  maxplayersperteam;                              // 12 +                                                            // 13 minplayers +                                                            // 14 0 or 9 +                                                            // 15 +    char*   name[16];                                       // 16-31 +                                                            // 32 string flag, unused +                                                            // 33 unused  }; -#define MAX_OUTFIT_ITEMS 12 -// #define MAX_OUTFIT_ITEMS 24                              // 12->24 in 3.0.x +#define MAX_OUTFIT_ITEMS 24  struct CharStartOutfitEntry  { @@ -103,20 +553,20 @@ struct CharStartOutfitEntry  struct CharTitlesEntry  { -    uint32      ID;                                         // 0, title ids, for example in Quest::GetCharTitleId() +    uint32  ID;                                             // 0, title ids, for example in Quest::GetCharTitleId()      //uint32      unk1;                                     // 1 flags?      //char*       name[16];                                 // 2-17, unused                                                              // 18 string flag, unused      //char*       name2[16];                                // 19-34, unused                                                              // 35 string flag, unused -    uint32      bit_index;                                  // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES +    uint32  bit_index;                                      // 36 used in PLAYER_CHOSEN_TITLE and 1<<index in PLAYER__FIELD_KNOWN_TITLES  };  struct ChatChannelsEntry  { -    uint32      ChannelID;                                  // 0 -    uint32      flags;                                      // 1 -    char*       pattern[16];                                // 3-18 +    uint32  ChannelID;                                      // 0 +    uint32  flags;                                          // 1 +    char*   pattern[16];                                    // 3-18                                                              // 19 string flags, unused      //char*       name[16];                                 // 20-35 unused                                                              // 36 string flag, unused @@ -124,20 +574,21 @@ struct ChatChannelsEntry  struct ChrClassesEntry  { -    uint32      ClassID;                                    // 0 -                                                            // 1-2, unused -    uint32      powerType;                                  // 3 -                                                            // 4, unused +    uint32  ClassID;                                        // 0 +                                                            // 1, unused +    uint32  powerType;                                      // 2 +                                                            // 3-4, unused      //char*       name[16];                                 // 5-20 unused -    char*       name[16];                                   // 5-20 unused                                                              // 21 string flag, unused      //char*       nameFemale[16];                           // 21-36 unused, if different from base (male) case                                                              // 37 string flag, unused      //char*       nameNeutralGender[16];                    // 38-53 unused, if different from base (male) case                                                              // 54 string flag, unused                                                              // 55, unused -    uint32      spellfamily;                                // 56 +    uint32  spellfamily;                                    // 56                                                              // 57, unused +    uint32  CinematicSequence;                              // 58 id from CinematicSequences.dbc +    uint32  addon;                                          // 59 (0 - original race, 1 - tbc addon, ...)  };  struct ChrRacesEntry @@ -151,7 +602,7 @@ struct ChrRacesEntry                                                              // 6-7 unused      uint32      TeamID;                                     // 8 (7-Alliance 1-Horde)                                                              // 9-12 unused -    uint32      startmovie;                                 // 13 id from CinematicCamera.dbc +    uint32      CinematicSequence;                          // 13 id from CinematicSequences.dbc      char*       name[16];                                   // 14-29 used for DBC language detection/selection                                                              // 30 string flags, unused      //char*       nameFemale[16];                           // 31-46, if different from base (male) case @@ -164,30 +615,43 @@ struct ChrRacesEntry  struct CreatureDisplayInfoEntry  { -    uint32      Displayid;                                  // 0 -                                                            // 1-3,unused -    float       scale;                                      // 4 -                                                            // 5-13,unused +    uint32      Displayid;                                  // 0        m_ID +                                                            // 1        m_modelID +                                                            // 2        m_soundID +                                                            // 3        m_extendedDisplayInfoID +    float       scale;                                      // 4        m_creatureModelScale +                                                            // 5        m_creatureModelAlpha +                                                            // 6-8      m_textureVariation[3] +                                                            // 9        m_portraitTextureName +                                                            // 10       m_sizeClass +                                                            // 11       m_bloodID +                                                            // 12       m_NPCSoundID +                                                            // 13       m_particleColorID +                                                            // 14       m_creatureGeosetData +                                                            // 15       m_objectEffectPackageID  };  struct CreatureFamilyEntry  { -    uint32    ID;                                           // 0 -    float     minScale;                                     // 1 -    uint32    minScaleLevel;                                // 2 0/1 -    float     maxScale;                                     // 3 -    uint32    maxScaleLevel;                                // 4 0/60 -    uint32    skillLine[2];                                 // 5-6 -    uint32    petFoodMask;                                  // 7 -    char*     Name[16];                                     // 8-23 -                                                            // 24 string flags, unused -                                                            // 25 icon, unused +    uint32  ID;                                             // 0        m_ID +    float   minScale;                                       // 1        m_minScale +    uint32  minScaleLevel;                                  // 2        m_minScaleLevel +    float   maxScale;                                       // 3        m_maxScale +    uint32  maxScaleLevel;                                  // 4        m_maxScaleLevel +    uint32  skillLine[2];                                   // 5-6      m_skillLine +    uint32  petFoodMask;                                    // 7        m_petFoodMask +    int32   petTalentType;                                  // 8        m_petTalentType +                                                            // 9        m_categoryEnumID +    char*   Name[16];                                       // 10-25    m_name_lang +                                                            // 26 string flags +                                                            // 27       m_iconFile  };  struct CreatureSpellDataEntry  { -    uint32    ID;                                           // 0 -    //uint32    spellId[4];                                 // 1-4 hunter pet learned spell (for later use) +    uint32    ID;                                           // 0        m_ID +    //uint32    spellId[4];                                 // 1-4      m_spells[4] +    //uint32    availability[4];                            // 4-7      m_availability[4]  };  struct DurabilityCostsEntry @@ -204,41 +668,35 @@ struct DurabilityQualityEntry  struct EmotesTextEntry  { -    uint32    Id; -    uint32    textid; +    uint32  Id; +    uint32  textid;  };  struct FactionEntry  { -    uint32      ID;                                         // 0 -    int32       reputationListID;                           // 1 -    uint32      BaseRepRaceMask[4];                         // 2-5 Base reputation race masks (see enum Races) -    uint32      BaseRepClassMask[4];                        // 6-9 Base reputation class masks (see enum Classes) -    int32       BaseRepValue[4];                            // 10-13 Base reputation values -    uint32      ReputationFlags[4];                         // 14-17 Default flags to apply -    uint32      team;                                       // 18 enum Team -    char*       name[16];                                   // 19-34 -                                                            // 35 string flags, unused -    //char*     description[16];                            // 36-51 unused -                                                            // 52 string flags, unused +    uint32      ID;                                         // 0        m_ID +    int32       reputationListID;                           // 1        m_reputationIndex +    uint32      BaseRepRaceMask[4];                         // 2-5      m_reputationRaceMask +    uint32      BaseRepClassMask[4];                        // 6-9      m_reputationClassMask +    int32       BaseRepValue[4];                            // 10-13    m_reputationBase +    uint32      ReputationFlags[4];                         // 14-17    m_reputationFlags +    uint32      team;                                       // 18       m_parentFactionID +    char*       name[16];                                   // 19-34    m_name_lang +                                                            // 35 string flags +    //char*     description[16];                            // 36-51    m_description_lang +                                                            // 52 string flags  };  struct FactionTemplateEntry  { -    uint32      ID;                                         // 0 -    uint32      faction;                                    // 1 -    uint32      factionFlags;                               // 2 specific flags for that faction -    uint32      ourMask;                                    // 3 if mask set (see FactionMasks) then faction included in masked team -    uint32      friendlyMask;                               // 4 if mask set (see FactionMasks) then faction friendly to masked team -    uint32      hostileMask;                                // 5 if mask set (see FactionMasks) then faction hostile to masked team -    uint32      enemyFaction1;                              // 6 -    uint32      enemyFaction2;                              // 7 -    uint32      enemyFaction3;                              // 8 -    uint32      enemyFaction4;                              // 9 -    uint32      friendFaction1;                             // 10 -    uint32      friendFaction2;                             // 11 -    uint32      friendFaction3;                             // 12 -    uint32      friendFaction4;                             // 13 +    uint32      ID;                                         // 0        m_ID +    uint32      faction;                                    // 1        m_faction +    uint32      factionFlags;                               // 2        m_flags +    uint32      ourMask;                                    // 3        m_factionGroup +    uint32      friendlyMask;                               // 4        m_friendGroup +    uint32      hostileMask;                                // 5        m_enemyGroup +    uint32      enemyFaction[4];                            // 6        m_enemies[4] +    uint32      friendFaction[4];                           // 10       m_friend[4]      //-------------------------------------------------------  end structure      // helpers @@ -246,9 +704,9 @@ struct FactionTemplateEntry      {          if(ID == entry.ID)              return true; -        if(enemyFaction1  == entry.faction || enemyFaction2  == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction ) +        if(enemyFaction[0]  == entry.faction || enemyFaction[1]  == entry.faction || enemyFaction[2] == entry.faction || enemyFaction[3] == entry.faction )              return false; -        if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction ) +        if(friendFaction[0] == entry.faction || friendFaction[1] == entry.faction || friendFaction[2] == entry.faction || friendFaction[3] == entry.faction )              return true;          return (friendlyMask & entry.ourMask) || (ourMask & entry.friendlyMask);      } @@ -256,14 +714,14 @@ struct FactionTemplateEntry      {          if(ID == entry.ID)              return false; -        if(enemyFaction1  == entry.faction || enemyFaction2  == entry.faction || enemyFaction3 == entry.faction || enemyFaction4 == entry.faction ) +        if(enemyFaction[0]  == entry.faction || enemyFaction[1]  == entry.faction || enemyFaction[2] == entry.faction || enemyFaction[3] == entry.faction )              return true; -        if(friendFaction1 == entry.faction || friendFaction2 == entry.faction || friendFaction3 == entry.faction || friendFaction4 == entry.faction ) +        if(friendFaction[0] == entry.faction || friendFaction[1] == entry.faction || friendFaction[2] == entry.faction || friendFaction[3] == entry.faction )              return false;          return (hostileMask & entry.ourMask) != 0;      }      bool IsHostileToPlayers() const { return (hostileMask & FACTION_MASK_PLAYER) !=0; } -    bool IsNeutralToAll() const { return hostileMask == 0 && friendlyMask == 0 && enemyFaction1==0 && enemyFaction2==0 && enemyFaction3==0 && enemyFaction4==0; } +    bool IsNeutralToAll() const { return hostileMask == 0 && friendlyMask == 0 && enemyFaction[0]==0 && enemyFaction[1]==0 && enemyFaction[2]==0 && enemyFaction[3]==0; }      bool IsContestedGuardFaction() const { return (factionFlags & FACTION_TEMPLATE_FLAG_CONTESTED_GUARD)!=0; }  }; @@ -274,9 +732,29 @@ struct GemPropertiesEntry      uint32      color;  }; +struct GlyphPropertiesEntry +{ +    uint32  Id; +    uint32  SpellId; +    uint32  TypeFlags; +    uint32  Unk1;                                           // GlyphIconId (SpellIcon.dbc) +}; + +struct GlyphSlotEntry +{ +    uint32  Id; +    uint32  TypeFlags; +    uint32  Order; +}; +  // All Gt* DBC store data for 100 levels, some by 100 per class/race  #define GT_MAX_LEVEL    100 +struct GtBarberShopCostBaseEntry +{ +    float   cost; +}; +  struct GtCombatRatingsEntry  {      float    ratio; @@ -324,24 +802,38 @@ struct GtRegenMPPerSptEntry  struct ItemEntry  { -   uint32 ID; -   uint32 DisplayId; -   uint32 InventoryType; -   uint32 Sheath; +   uint32   ID; +   //uint32   Class; +   //uint32   SubClass; +   //uint32   Unk0; +   //uint32   Material; +   uint32   DisplayId; +   uint32   InventoryType; +   uint32   Sheath;  };  struct ItemDisplayInfoEntry  { -    uint32      ID; -    uint32      randomPropertyChance; +    uint32      ID;                                         // 0        m_ID +                                                            // 1        m_modelName[2] +                                                            // 2        m_modelTexture[2] +                                                            // 3        m_inventoryIcon +                                                            // 4        m_geosetGroup[3] +                                                            // 5        m_flags +                                                            // 6        m_spellVisualID +                                                            // 7        m_groupSoundIndex +                                                            // 8        m_helmetGeosetVis[2] +                                                            // 9        m_texture[2] +                                                            // 10       m_itemVisual[8] +                                                            // 11       m_particleColorID  };  //struct ItemCondExtCostsEntry  //{  //    uint32      ID; -//    uint32      condExtendedCost;                           // ItemPrototype::CondExtendedCost -//    uint32      itemextendedcostentry;                      // ItemPrototype::ExtendedCost -//    uint32      arenaseason;                                // arena season number(1-4) +//    uint32      condExtendedCost;                         // ItemPrototype::CondExtendedCost +//    uint32      itemextendedcostentry;                    // ItemPrototype::ExtendedCost +//    uint32      arenaseason;                              // arena season number(1-4)  //};  struct ItemExtendedCostEntry @@ -356,47 +848,42 @@ struct ItemExtendedCostEntry  struct ItemRandomPropertiesEntry  { -    uint32    ID;                                           // 0 -    //char*     internalName                                // 1   unused -    uint32    enchant_id[3];                                // 2-4 -                                                            // 5-6 unused, 0 only values, reserved for additional enchantments? -    //char*     nameSuffix[16]                              // 7-22, unused -                                                            // 23 nameSufix flags, unused +    uint32    ID;                                           // 0        m_ID +    //char*     internalName                                // 1        m_Name +    uint32    enchant_id[5];                                // 2-6      m_Enchantment +    //char*     nameSuffix[16]                              // 7-22     m_name_lang +                                                            // 23 name flags  };  struct ItemRandomSuffixEntry  { -    uint32    ID;                                           // 0 -    //char*     name[16]                                    // 1-16 unused -                                                            // 17, name flags, unused -                                                            // 18  unused -    uint32    enchant_id[3];                                // 19-21 -    uint32    prefix[3];                                    // 22-24 +    uint32    ID;                                           // 0        m_ID +    //char*     name[16]                                    // 1-16     m_name_lang +                                                            // 17, name flags +                                                            // 18       m_internalName +    uint32    enchant_id[5];                                // 19-21    m_enchantment +    uint32    prefix[5];                                    // 22-24    m_allocationPct  };  struct ItemSetEntry  { -    //uint32    id                                          // 0 item set ID -    char*     name[16];                                     // 1-16 +    //uint32    id                                          // 0        m_ID +    char*     name[16];                                     // 1-16     m_name_lang                                                              // 17 string flags, unused -                                                            // 18-28 items from set, but not have all items listed, use ItemPrototype::ItemSet instead -                                                            // 29-34 unused -    uint32    spells[8];                                    // 35-42 -    uint32    items_to_triggerspell[8];                     // 43-50 -    uint32    required_skill_id;                            // 51 -    uint32    required_skill_value;                         // 52 +    //uint32    itemId[17];                                 // 18-34    m_itemID +    uint32    spells[8];                                    // 35-42    m_setSpellID +    uint32    items_to_triggerspell[8];                     // 43-50    m_setThreshold +    uint32    required_skill_id;                            // 51       m_requiredSkill +    uint32    required_skill_value;                         // 52       m_requiredSkillRank  };  struct LockEntry  { -    uint32      ID;                                         // 0 -    uint32      keytype[5];                                 // 1-5 -                                                            // 6-8, not used -    uint32      key[5];                                     // 9-13 -                                                            // 14-16, not used -    uint32      requiredminingskill;                        // 17 -    uint32      requiredlockskill;                          // 18 -                                                            // 19-32, not used +    uint32      ID;                                         // 0        m_ID +    uint32      Type[8];                                    // 1-8      m_Type +    uint32      Index[8];                                   // 9-16     m_Index +    uint32      Skill[8];                                   // 17-24    m_Skill +    //uint32      Action[8];                                // 25-32    m_Action  };  struct MailTemplateEntry @@ -409,35 +896,34 @@ struct MailTemplateEntry  struct MapEntry  { -    uint32      MapID;                                      // 0 +    uint32  MapID;                                          // 0      //char*       internalname;                             // 1 unused -    uint32      map_type;                                   // 2 -                                                            // 3 unused -    char*       name[16];                                   // 4-19 +    uint32  map_type;                                       // 2 +                                                            // 3 0 or 1 for battlegrounds (not arenas) +    char*   name[16];                                       // 4-19                                                              // 20 name flags, unused -                                                            // 21-23 unused (something PvPZone related - levels?) -                                                            // 24-26 -    uint32      linked_zone;                                // 27 common zone for instance and continent map -    //char*     hordeIntro                                  // 28-43 text for PvP Zones -                                                            // 44 intro text flags -    //char*     allianceIntro                               // 45-60 text for PvP Zones -                                                            // 46 intro text flags -                                                            // 47-61 not used -    uint32      multimap_id;                                // 62 -                                                            // 63-65 not used -    //chat*     unknownText1                                // 66-81 unknown empty text fields, possible normal Intro text. -                                                            // 82 text flags -    //chat*     heroicIntroText                             // 83-98 heroic mode requirement text -                                                            // 99 text flags -    //chat*     unknownText2                                // 100-115 unknown empty text fields -                                                            // 116 text flags -    int32       entrance_map;                               // 117 map_id of entrance map -    float       entrance_x;                                 // 118 entrance x coordinate (if exist single entry) -    float       entrance_y;                                 // 119 entrance y coordinate (if exist single entry) -    uint32 resetTimeRaid;                                   // 120 -    uint32 resetTimeHeroic;                                 // 121 -                                                            // 122-123 -    uint32      addon;                                      // 124 (0-original maps,1-tbc addon) +    uint32  linked_zone;                                    // 21 common zone for instance and continent map +    //char*     hordeIntro[16];                             // 23-37 text for PvP Zones +                                                            // 38 intro text flags +    //char*     allianceIntro[16];                          // 39-54 text for PvP Zones +                                                            // 55 intro text flags +    uint32  multimap_id;                                    // 56 +                                                            // 57 +    //chat*     unknownText1[16];                           // 58-73 unknown empty text fields, possible normal Intro text. +                                                            // 74 text flags +    //chat*     heroicIntroText[16];                        // 75-90 heroic mode requirement text +                                                            // 91 text flags +    //chat*     unknownText2[16];                           // 92-107 unknown empty text fields +                                                            // 108 text flags +    int32   entrance_map;                                   // 109 map_id of entrance map +    float   entrance_x;                                     // 110 entrance x coordinate (if exist single entry) +    float   entrance_y;                                     // 111 entrance y coordinate (if exist single entry) +    uint32  resetTimeRaid;                                  // 112 +    uint32  resetTimeHeroic;                                // 113 +                                                            // 114 all 0 +                                                            // 115 -1, 0 and 720 +    uint32  addon;                                          // 116 (0-original maps,1-tbc addon) +                                                            // 117 some kind of time?      // Helpers      uint32 Expansion() const { return addon; } @@ -454,17 +940,22 @@ struct MapEntry      bool IsMountAllowed() const      { -        return !IsDungeon() ||  +        return !IsDungeon() ||              MapID==568 || MapID==309 || MapID==209 || MapID==534 ||              MapID==560 || MapID==509 || MapID==269;      } + +    bool IsContinent() const +    { +        return MapID == 0 || MapID == 1 || MapID == 530 || MapID == 571; +    }  };  struct QuestSortEntry  { -    uint32      id;                                         // 0, sort id -    //char*       name[16];                                 // 1-16, unused -                                                            // 17 name flags, unused +    uint32      id;                                         // 0        m_ID +    //char*       name[16];                                 // 1-16     m_SortName_lang +                                                            // 17 name flags  };  struct RandomPropertiesPointsEntry @@ -476,172 +967,201 @@ struct RandomPropertiesPointsEntry      uint32    UncommonPropertiesPoints[5];                  // 12-16  }; +struct ScalingStatDistributionEntry +{ +    uint32  Id; +    uint32  StatMod[10]; +    uint32  Modifier[10]; +    uint32  MaxLevel; +}; + +struct ScalingStatValuesEntry +{ +    uint32  Id; +    uint32  Level; +    uint32  Multiplier[17]; +}; +  //struct SkillLineCategoryEntry{ -//    uint32    id;                                           // 0 hidden key -//    char*     name[16];                                     // 1 - 17 Category name -//                                                                  // 18 string flag -//    uint32    displayOrder;                                 // Display order in character tab +//    uint32    id;                                         // 0      m_ID +//    char*     name[16];                                   // 1-17   m_name_lang +//                                                          // 18 string flag +//    uint32    displayOrder;                               // 19     m_sortIndex  //};  //struct SkillRaceClassInfoEntry{ -//    uint32    id;                                           // 0 -//    uint32    skillId;                                      // 1 present some refrences to unknown skill -//    uint32    raceMask;                                     // 2 -//    uint32    classMask;                                    // 3 -//    uint32    flags;                                        // 4 mask for some thing -//    uint32    reqLevel;                                     // 5 -//    uint32    skillTierId;                                  // 6 -//    uint32    skillCostID;                                  // 7 +//    uint32    id;                                         // 0      m_ID +//    uint32    skillId;                                    // 1      m_skillID +//    uint32    raceMask;                                   // 2      m_raceMask +//    uint32    classMask;                                  // 3      m_classMask +//    uint32    flags;                                      // 4      m_flags +//    uint32    reqLevel;                                   // 5      m_minLevel +//    uint32    skillTierId;                                // 6      m_skillTierID +//    uint32    skillCostID;                                // 7      m_skillCostIndex  //};  //struct SkillTiersEntry{ -//    uint32    id;                                           // 0 -//    uint32    skillValue[16];                               // 1-17 unknown possibly add value on learn? -//    uint32    maxSkillValue[16];                            // Max value for rank +//    uint32    id;                                         // 0      m_ID +//    uint32    skillValue[16];                             // 1-17   m_cost +//    uint32    maxSkillValue[16];                          // 18-32  m_valueMax  //};  struct SkillLineEntry  { -    uint32    id;                                           // 0 -    uint32    categoryId;                                   // 1 (index from SkillLineCategory.dbc) -    //uint32    skillCostID;                                // 2 not used -    char*     name[16];                                     // 3-18 -                                                            // 19 string flags, not used -    //char*     description[16];                            // 20-35, not used -                                                            // 36 string flags, not used -    uint32    spellIcon;                                    // 37 +    uint32    id;                                           // 0        m_ID +    int32     categoryId;                                   // 1        m_categoryID +    //uint32    skillCostID;                                // 2        m_skillCostsID +    char*     name[16];                                     // 3-18     m_displayName_lang +                                                            // 19 string flags +    //char*     description[16];                            // 20-35    m_description_lang +                                                            // 36 string flags +    uint32    spellIcon;                                    // 37       m_spellIconID +    //char*     alternateVerb[16];                          // 38-53    m_alternateVerb_lang +                                                            // 54 string flags +                                                            // 55       m_canLink  };  struct SkillLineAbilityEntry  { -    uint32    id;                                           // 0, INDEX -    uint32    skillId;                                      // 1 -    uint32    spellId;                                      // 2 -    uint32    racemask;                                     // 3 -    uint32    classmask;                                    // 4 -    //uint32    racemaskNot;                                // 5 always 0 in 2.4.2 -    //uint32    classmaskNot;                               // 6 always 0 in 2.4.2 -    uint32    req_skill_value;                              // 7 for trade skill.not for training. -    uint32    forward_spellid;                              // 8 -    uint32    learnOnGetSkill;                              // 9 can be 1 or 2 for spells learned on get skill -    uint32    max_value;                                    // 10 -    uint32    min_value;                                    // 11 -                                                            // 12-13, unknown, always 0 -    uint32    reqtrainpoints;                               // 14 +    uint32    id;                                           // 0        m_ID +    uint32    skillId;                                      // 1        m_skillLine +    uint32    spellId;                                      // 2        m_spell +    uint32    racemask;                                     // 3        m_raceMask +    uint32    classmask;                                    // 4        m_classMask +    //uint32    racemaskNot;                                // 5        m_excludeRace +    //uint32    classmaskNot;                               // 6        m_excludeClass +    uint32    req_skill_value;                              // 7        m_minSkillLineRank +    uint32    forward_spellid;                              // 8        m_supercededBySpell +    uint32    learnOnGetSkill;                              // 9        m_acquireMethod +    uint32    max_value;                                    // 10       m_trivialSkillLineRankHigh +    uint32    min_value;                                    // 11       m_trivialSkillLineRankLow +    //uint32    characterPoints[2];                         // 12-13    m_characterPoints[2]  };  struct SoundEntriesEntry  { -    uint32    Id;                                           // 0, sound id -    //uint32    Type;                                       // 1, sound type (10 generally for creature, etc) -    //char*     InternalName;                               // 2, internal name, for use in lookup command for example -    //char*     FileName[10];                               // 3-12, file names -    //uint32    Unk13[10];                                  // 13-22, linked with file names? -    //char*     Path;                                       // 23 -                                                            // 24-28, unknown +    uint32    Id;                                           // 0        m_ID +    //uint32    Type;                                       // 1        m_soundType +    //char*     InternalName;                               // 2        m_name +    //char*     FileName[10];                               // 3-12     m_File[10] +    //uint32    Unk13[10];                                  // 13-22    m_Freq[10] +    //char*     Path;                                       // 23       m_DirectoryBase +                                                            // 24       m_volumeFloat +                                                            // 25       m_flags +                                                            // 26       m_minDistance +                                                            // 27       m_distanceCutoff +                                                            // 28       m_EAXDef  };  struct SpellEntry  { -    uint32    Id;                                           // 0 normally counted from 0 field (but some tools start counting from 1, check this before tool use for data view!) -    uint32    Category;                                     // 1 -    //uint32     castUI                                     // 2 not used -    uint32    Dispel;                                       // 3 -    uint32    Mechanic;                                     // 4 -    uint32    Attributes;                                   // 5 -    uint32    AttributesEx;                                 // 6 -    uint32    AttributesEx2;                                // 7 -    uint32    AttributesEx3;                                // 8 -    uint32    AttributesEx4;                                // 9 -    uint32    AttributesEx5;                                // 10 -    //uint32    AttributesEx6;                              // 11 not used -    uint32    Stances;                                      // 12 -    uint32    StancesNot;                                   // 13 -    uint32    Targets;                                      // 14 -    uint32    TargetCreatureType;                           // 15 -    uint32    RequiresSpellFocus;                           // 16 -    uint32    FacingCasterFlags;                            // 17 -    uint32    CasterAuraState;                              // 18 -    uint32    TargetAuraState;                              // 19 -    uint32    CasterAuraStateNot;                           // 20 -    uint32    TargetAuraStateNot;                           // 21 -    uint32    CastingTimeIndex;                             // 22 -    uint32    RecoveryTime;                                 // 23 -    uint32    CategoryRecoveryTime;                         // 24 -    uint32    InterruptFlags;                               // 25 -    uint32    AuraInterruptFlags;                           // 26 -    uint32    ChannelInterruptFlags;                        // 27 -    uint32    procFlags;                                    // 28 -    uint32    procChance;                                   // 29 -    uint32    procCharges;                                  // 30 -    uint32    maxLevel;                                     // 31 -    uint32    baseLevel;                                    // 32 -    uint32    spellLevel;                                   // 33 -    uint32    DurationIndex;                                // 34 -    uint32    powerType;                                    // 35 -    uint32    manaCost;                                     // 36 -    uint32    manaCostPerlevel;                             // 37 -    uint32    manaPerSecond;                                // 38 -    uint32    manaPerSecondPerLevel;                        // 39 -    uint32    rangeIndex;                                   // 40 -    float     speed;                                        // 41 -    //uint32    modalNextSpell;                             // 42 -    uint32    StackAmount;                                  // 43 -    uint32    Totem[2];                                     // 44-45 -    int32     Reagent[8];                                   // 46-53 -    uint32    ReagentCount[8];                              // 54-61 -    int32     EquippedItemClass;                            // 62 (value) -    int32     EquippedItemSubClassMask;                     // 63 (mask) -    int32     EquippedItemInventoryTypeMask;                // 64 (mask) -    uint32    Effect[3];                                    // 65-67 -    int32     EffectDieSides[3];                            // 68-70 -    uint32    EffectBaseDice[3];                            // 71-73 -    float     EffectDicePerLevel[3];                        // 74-76 -    float     EffectRealPointsPerLevel[3];                  // 77-79 -    int32     EffectBasePoints[3];                          // 80-82 (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) -    uint32    EffectMechanic[3];                            // 83-85 -    uint32    EffectImplicitTargetA[3];                     // 86-88 -    uint32    EffectImplicitTargetB[3];                     // 89-91 -    uint32    EffectRadiusIndex[3];                         // 92-94 - spellradius.dbc -    uint32    EffectApplyAuraName[3];                       // 95-97 -    uint32    EffectAmplitude[3];                           // 98-100 -    float     EffectMultipleValue[3];                       // 101-103 -    uint32    EffectChainTarget[3];                         // 104-106 -    uint32    EffectItemType[3];                            // 107-109 -    int32     EffectMiscValue[3];                           // 110-112 -    int32     EffectMiscValueB[3];                          // 113-115 -    uint32    EffectTriggerSpell[3];                        // 116-118 -    float     EffectPointsPerComboPoint[3];                 // 119-121 -    uint32    SpellVisual;                                  // 122 -                                                            // 123 not used -    uint32    SpellIconID;                                  // 124 -    uint32    activeIconID;                                 // 125 -    //uint32    spellPriority;                              // 126 -    char*     SpellName[16];                                // 127-142 -    //uint32    SpellNameFlag;                              // 143 -    char*     Rank[16];                                     // 144-159 -    //uint32    RankFlags;                                  // 160 -    //char*     Description[16];                            // 161-176 not used -    //uint32    DescriptionFlags;                           // 177     not used -    //char*     ToolTip[16];                                // 178-193 not used -    //uint32    ToolTipFlags;                               // 194     not used -    uint32    ManaCostPercentage;                           // 195 -    uint32    StartRecoveryCategory;                        // 196 -    uint32    StartRecoveryTime;                            // 197 -    uint32    MaxTargetLevel;                               // 198 -    uint32    SpellFamilyName;                              // 199 -    uint64    SpellFamilyFlags;                             // 200+201 -    uint32    MaxAffectedTargets;                           // 202 -    uint32    DmgClass;                                     // 203 defenseType -    uint32    PreventionType;                               // 204 -    //uint32    StanceBarOrder;                             // 205 not used -    float     DmgMultiplier[3];                             // 206-208 -    //uint32    MinFactionId;                               // 209 not used, and 0 in 2.4.2 -    //uint32    MinReputation;                              // 210 not used, and 0 in 2.4.2 -    //uint32    RequiredAuraVision;                         // 211 not used -    uint32    TotemCategory[2];                             // 212-213 -    uint32    AreaId;                                       // 214 -    uint32    SchoolMask;                                   // 215 school mask +    uint32    Id;                                           // 0        m_ID +    uint32    Category;                                     // 1        m_category +    uint32    Dispel;                                       // 2        m_dispelType +    uint32    Mechanic;                                     // 3        m_mechanic +    uint32    Attributes;                                   // 4        m_attribute +    uint32    AttributesEx;                                 // 5        m_attributesEx +    uint32    AttributesEx2;                                // 6        m_attributesExB +    uint32    AttributesEx3;                                // 7        m_attributesExC +    uint32    AttributesEx4;                                // 8        m_attributesExD +    uint32    AttributesEx5;                                // 9        m_attributesExE +    //uint32    AttributesEx6;                              // 10       m_attributesExF not used +    uint32    Stances;                                      // 11       m_shapeshiftMask +    uint32    StancesNot;                                   // 12       m_shapeshiftExclude +    uint32    Targets;                                      // 13       m_targets +    uint32    TargetCreatureType;                           // 14       m_targetCreatureType +    uint32    RequiresSpellFocus;                           // 15       m_requiresSpellFocus +    uint32    FacingCasterFlags;                            // 16       m_facingCasterFlags +    uint32    CasterAuraState;                              // 17       m_casterAuraState +    uint32    TargetAuraState;                              // 18       m_targetAuraState +    uint32    CasterAuraStateNot;                           // 19       m_excludeCasterAuraState +    uint32    TargetAuraStateNot;                           // 20       m_excludeTargetAuraState +    //uint32    casterAuraSpell;                            // 21       m_casterAuraSpell not used +    //uint32    targetAuraSpell;                            // 22       m_targetAuraSpell not used +    //uint32    excludeCasterAuraSpell;                     // 23       m_excludeCasterAuraSpell not used +    //uint32    excludeTargetAuraSpell;                     // 24       m_excludeTargetAuraSpell not used +    uint32    CastingTimeIndex;                             // 25       m_castingTimeIndex +    uint32    RecoveryTime;                                 // 26       m_recoveryTime +    uint32    CategoryRecoveryTime;                         // 27       m_categoryRecoveryTime +    uint32    InterruptFlags;                               // 28       m_interruptFlags +    uint32    AuraInterruptFlags;                           // 29       m_auraInterruptFlags +    uint32    ChannelInterruptFlags;                        // 30       m_channelInterruptFlags +    uint32    procFlags;                                    // 31       m_procTypeMask +    uint32    procChance;                                   // 32       m_procChance +    uint32    procCharges;                                  // 33       m_procCharges +    uint32    maxLevel;                                     // 34       m_maxLevel +    uint32    baseLevel;                                    // 35       m_baseLevel +    uint32    spellLevel;                                   // 36       m_spellLevel +    uint32    DurationIndex;                                // 37       m_durationIndex +    uint32    powerType;                                    // 38       m_powerType +    uint32    manaCost;                                     // 39       m_manaCost +    uint32    manaCostPerlevel;                             // 40       m_manaCostPerLevel +    uint32    manaPerSecond;                                // 41       m_manaPerSecond +    uint32    manaPerSecondPerLevel;                        // 42       m_manaPerSecondPerLeve +    uint32    rangeIndex;                                   // 43       m_rangeIndex +    float     speed;                                        // 44       m_speed +    //uint32    modalNextSpell;                             // 45       m_modalNextSpell not used +    uint32    StackAmount;                                  // 46       m_cumulativeAura +    uint32    Totem[2];                                     // 47-48    m_totem +    int32     Reagent[8];                                   // 49-56    m_reagent +    uint32    ReagentCount[8];                              // 57-64    m_reagentCount +    int32     EquippedItemClass;                            // 65       m_equippedItemClass (value) +    int32     EquippedItemSubClassMask;                     // 66       m_equippedItemSubclass (mask) +    int32     EquippedItemInventoryTypeMask;                // 67       m_equippedItemInvTypes (mask) +    uint32    Effect[3];                                    // 68-70    m_effect +    int32     EffectDieSides[3];                            // 71-73    m_effectDieSides +    uint32    EffectBaseDice[3];                            // 74-76    m_effectBaseDice +    float     EffectDicePerLevel[3];                        // 77-79    m_effectDicePerLevel +    float     EffectRealPointsPerLevel[3];                  // 80-82    m_effectRealPointsPerLevel +    int32     EffectBasePoints[3];                          // 83-85    m_effectBasePoints (don't must be used in spell/auras explicitly, must be used cached Spell::m_currentBasePoints) +    uint32    EffectMechanic[3];                            // 86-88    m_effectMechanic +    uint32    EffectImplicitTargetA[3];                     // 89-91    m_implicitTargetA +    uint32    EffectImplicitTargetB[3];                     // 92-94    m_implicitTargetB +    uint32    EffectRadiusIndex[3];                         // 95-97    m_effectRadiusIndex - spellradius.dbc +    uint32    EffectApplyAuraName[3];                       // 98-100   m_effectAura +    uint32    EffectAmplitude[3];                           // 101-103  m_effectAuraPeriod +    float     EffectMultipleValue[3];                       // 104-106  m_effectAmplitude +    uint32    EffectChainTarget[3];                         // 107-109  m_effectChainTargets +    uint32    EffectItemType[3];                            // 110-112  m_effectItemType +    int32     EffectMiscValue[3];                           // 113-115  m_effectMiscValue +    int32     EffectMiscValueB[3];                          // 116-118  m_effectMiscValueB +    uint32    EffectTriggerSpell[3];                        // 119-121  m_effectTriggerSpell +    float     EffectPointsPerComboPoint[3];                 // 122-124  m_effectPointsPerCombo +    uint32    EffectSpellClassMaskA[3];                     // 125-127  m_effectSpellClassMaskA +    uint32    EffectSpellClassMaskB[3];                     // 128-130  m_effectSpellClassMaskB +    uint32    EffectSpellClassMaskC[3];                     // 131-133  m_effectSpellClassMaskC +    uint32    SpellVisual[2];                               // 134-135  m_spellVisualID +    uint32    SpellIconID;                                  // 136      m_spellIconID +    uint32    activeIconID;                                 // 137      m_activeIconID +    //uint32    spellPriority;                              // 138      m_spellPriority not used +    char*     SpellName[16];                                // 139-154  m_name_lang +    //uint32    SpellNameFlag;                              // 155 not used +    char*     Rank[16];                                     // 156-171  m_nameSubtext_lang +    //uint32    RankFlags;                                  // 172 not used +    //char*     Description[16];                            // 173-188  m_description_lang not used +    //uint32    DescriptionFlags;                           // 189 not used +    //char*     ToolTip[16];                                // 190-205  m_auraDescription_lang not used +    //uint32    ToolTipFlags;                               // 206 not used +    uint32    ManaCostPercentage;                           // 207      m_manaCostPct +    uint32    StartRecoveryCategory;                        // 208      m_startRecoveryCategory +    uint32    StartRecoveryTime;                            // 209      m_startRecoveryTime +    uint32    MaxTargetLevel;                               // 210      m_maxTargetLevel +    uint32    SpellFamilyName;                              // 211      m_spellClassSet +    uint64    SpellFamilyFlags;                             // 212-213  m_spellClassMask NOTE: size is 12 bytes!!! +    uint32    SpellFamilyFlags2;                            // 214      addition to m_spellClassMask +    uint32    MaxAffectedTargets;                           // 215      m_maxTargets +    uint32    DmgClass;                                     // 216      m_defenseType +    uint32    PreventionType;                               // 217      m_preventionType +    //uint32    StanceBarOrder;                             // 218      m_stanceBarOrder not used +    float     DmgMultiplier[3];                             // 219-221  m_effectChainAmplitude +    //uint32    MinFactionId;                               // 222      m_minFactionID not used +    //uint32    MinReputation;                              // 223      m_minReputation not used +    //uint32    RequiredAuraVision;                         // 224      m_requiredAuraVision not used +    uint32    TotemCategory[2];                             // 225-226  m_requiredTotemCategoryID +    int32     AreaId;                                       // 227      m_requiredAreasID +    uint32    SchoolMask;                                   // 228      m_schoolMask +    uint32    runeCostID;                                   // 229      m_runeCostID +    //uint32    spellMissileID;                             // 230      m_spellMissileID not used      private:          // prevent creating custom entries (copy data from original in fact) @@ -690,6 +1210,16 @@ struct SpellRangeEntry      uint32    type;  }; +struct SpellRuneCostEntry +{ +    uint32  ID;                                             // 0 +    uint32  RuneCost[3];                                    // 1-3 (0=blood, 1=frost, 2=unholy) +    uint32  runePowerGain;                                  // 4 + +    bool NoRuneCost() const { return RuneCost[0] == 0 && RuneCost[1] == 0 && RuneCost[2] == 0; } +    bool NoRunicPowerGain() const { return runePowerGain == 0; } +}; +  struct SpellShapeshiftEntry  {      uint32 ID;                                              // 0 @@ -722,26 +1252,31 @@ struct SpellDurationEntry  struct SpellItemEnchantmentEntry  { -    uint32      ID;                                         // 0 -    uint32      type[3];                                    // 1-3 -    uint32      amount[3];                                  // 4-6 -    //uint32    amount2[3]                                  // 7-9 always same as similar `amount` value -    uint32      spellid[3];                                 // 10-12 -    char*       description[16];                            // 13-29 -                                                            // 30 description flags -    uint32      aura_id;                                    // 31 -    uint32      slot;                                       // 32 -    uint32      GemID;                                      // 33 -    uint32      EnchantmentCondition;                       // 34 +    uint32      ID;                                         // 0        m_ID +    //uint32      charges;                                  // 1        m_charges +    uint32      type[3];                                    // 2-4      m_effect[3] +    uint32      amount[3];                                  // 5-7      m_effectPointsMin[3] +    //uint32      amount2[3]                                // 8-10     m_effectPointsMax[3] +    uint32      spellid[3];                                 // 11-13    m_effectArg[3] +    char*       description[16];                            // 14-30    m_name_lang[16] +    //uint32      descriptionFlags;                         // 31 name flags +    uint32      aura_id;                                    // 32       m_itemVisual +    uint32      slot;                                       // 33       m_flags +    uint32      GemID;                                      // 34       m_src_itemID +    uint32      EnchantmentCondition;                       // 35       m_condition_id +    //uint32      requiredSkill;                            // 36       m_requiredSkillID +    //uint32      requiredSkillValue;                       // 37       m_requiredSkillRank  };  struct SpellItemEnchantmentConditionEntry  { -    uint32  ID; -    uint8   Color[5]; -    uint8   Comparator[5]; -    uint8   CompareColor[5]; -    uint32  Value[5]; +    uint32  ID;                                             // 0        m_ID +    uint8   Color[5];                                       // 1-5      m_lt_operandType[5] +    //uint32  LT_Operand[5];                                // 6-10     m_lt_operand[5] +    uint8   Comparator[5];                                  // 11-15    m_operator[5] +    uint8   CompareColor[5];                                // 15-20    m_rt_operandType[5] +    uint32  Value[5];                                       // 21-25    m_rt_operand[5] +    //uint8   Logic[5]                                      // 25-30    m_logic[5]  };  struct StableSlotPricesEntry @@ -750,6 +1285,16 @@ struct StableSlotPricesEntry      uint32 Price;  }; +/*struct SummonPropertiesEntry +{ +    uint32  Id;                                             // 0 +    uint32  Group;                                          // 1, 0 - can't be controlled?, 1 - something guardian?, 2 - pet?, 3 - something controllable?, 4 - taxi/mount? +    uint32  Unk2;                                           // 2, 14 rows > 0 +    uint32  Type;                                           // 3, see enum +    uint32  Slot;                                           // 4, 0-6 +    uint32  Flags;                                          // 5 +};*/ +  struct TalentEntry  {      uint32    TalentID;                                     // 0 @@ -761,53 +1306,59 @@ struct TalentEntry      uint32    DependsOn;                                    // 13 index in Talent.dbc (TalentEntry)                                                              // 14-15 not used      uint32    DependsOnRank;                                // 16 -                                                            // 17-19 not used -    uint32    DependsOnSpell;                               // 20 req.spell +                                                            // 17-18 not used +    //uint32  unk1;                                         // 19, 0 or 1 +    //uint32  unk2;                                         // 20, all 0 +    //uint32  unkFlags1;                                    // 21, related to hunter pet talents +    //uint32  unkFlags2;                                    // 22, related to hunter pet talents  };  struct TalentTabEntry  { -    uint32    TalentTabID;                                  // 0 -    //char*   name[16];                                     // 1-16, unused +    uint32  TalentTabID;                                    // 0 +    //char* name[16];                                       // 1-16, unused      //uint32  nameFlags;                                    // 17, unused      //unit32  spellicon;                                    // 18                                                              // 19 not used -    uint32    ClassMask;                                    // 20 -    uint32    tabpage;                                      // 21 -    //char*   internalname;                                 // 22 +    uint32  ClassMask;                                      // 20 +    uint32  petTalentMask;                                  // 21 +    uint32  tabpage;                                        // 22 +    //char* internalname;                                   // 23  };  struct TaxiNodesEntry  { -    uint32    ID;                                           // 0 -    uint32    map_id;                                       // 1 -    float     x;                                            // 2 -    float     y;                                            // 3 -    float     z;                                            // 4 -    //char*     name[16];                                   // 5-21 -                                                            // 22 string flags, unused -    uint32    horde_mount_type;                             // 23 -    uint32    alliance_mount_type;                          // 24 +    uint32    ID;                                           // 0        m_ID +    uint32    map_id;                                       // 1        m_ContinentID +    float     x;                                            // 2        m_x +    float     y;                                            // 3        m_y +    float     z;                                            // 4        m_z +    //char*     name[16];                                   // 5-21     m_Name_lang +                                                            // 22 string flags +    uint32    MountCreatureID[2];                           // 23-24    m_MountCreatureID[2]  };  struct TaxiPathEntry  { -    uint32    ID; -    uint32    from; -    uint32    to; -    uint32    price; +    uint32    ID;                                           // 0        m_ID +    uint32    from;                                         // 1        m_FromTaxiNode +    uint32    to;                                           // 2        m_ToTaxiNode +    uint32    price;                                        // 3        m_Cost  };  struct TaxiPathNodeEntry  { -    uint32    path; -    uint32    index; -    uint32    mapid; -    float     x; -    float     y; -    float     z; -    uint32    actionFlag; -    uint32    delay; +                                                            // 0        m_ID +    uint32    path;                                         // 1        m_PathID +    uint32    index;                                        // 2        m_NodeIndex +    uint32    mapid;                                        // 3        m_ContinentID +    float     x;                                            // 4        m_LocX +    float     y;                                            // 5        m_LocY +    float     z;                                            // 6        m_LocZ +    uint32    actionFlag;                                   // 7        m_flags +    uint32    delay;                                        // 8        m_delay +                                                            // 9        m_arrivalEventID +                                                            // 10       m_departureEventID  };  struct TotemCategoryEntry @@ -819,16 +1370,100 @@ struct TotemCategoryEntry      uint32    categoryMask;                                 // 19 (compatibility mask for same type: different for totems, compatible from high to low for rods)  }; +struct VehicleEntry +{ +    uint32  m_ID;                                           // 0 +    uint32  m_flags;                                        // 1 +    float   m_turnSpeed;                                    // 2 +    float   m_pitchSpeed;                                   // 3 +    float   m_pitchMin;                                     // 4 +    float   m_pitchMax;                                     // 5 +    uint32  m_seatID[8];                                    // 6-13 +    float   m_mouseLookOffsetPitch;                         // 14 +    float   m_cameraFadeDistScalarMin;                      // 15 +    float   m_cameraFadeDistScalarMax;                      // 16 +    float   m_cameraPitchOffset;                            // 17 +    int     m_powerType[3];                                 // 18-20 +    int     m_powerToken[3];                                // 21-23 +    float   m_facingLimitRight;                             // 24 +    float   m_facingLimitLeft;                              // 25 +    float   m_msslTrgtTurnLingering;                        // 26 +    float   m_msslTrgtPitchLingering;                       // 27 +    float   m_msslTrgtMouseLingering;                       // 28 +    float   m_msslTrgtEndOpacity;                           // 29 +    float   m_msslTrgtArcSpeed;                             // 30 +    float   m_msslTrgtArcRepeat;                            // 31 +    float   m_msslTrgtArcWidth;                             // 32 +    float   m_msslTrgtImpactRadius[2];                      // 33-34 +    char*   m_msslTrgtArcTexture;                           // 35 +    char*   m_msslTrgtImpactTexture;                        // 36 +    char*   m_msslTrgtImpactModel[2];                       // 37-38 +    float   m_cameraYawOffset;                              // 39 +    uint32  m_uiLocomotionType;                             // 40 +    float   m_msslTrgtImpactTexRadius;                      // 41 +    uint32  m_uiSeatIndicatorType;                          // 42 +}; + +struct VehicleSeatEntry  +{ +    uint32  m_ID;                                           // 0 +    uint32  m_flags;                                        // 1 +    int32   m_attachmentID;                                 // 2 +    float   m_attachmentOffsetX;                            // 3 +    float   m_attachmentOffsetY;                            // 4 +    float   m_attachmentOffsetZ;                            // 5 +    float   m_enterPreDelay;                                // 6 +    float   m_enterSpeed;                                   // 7 +    float   m_enterGravity;                                 // 8 +    float   m_enterMinDuration;                             // 9 +    float   m_enterMaxDuration;                             // 10 +    float   m_enterMinArcHeight;                            // 11 +    float   m_enterMaxArcHeight;                            // 12 +    int32   m_enterAnimStart;                               // 13 +    int32   m_enterAnimLoop;                                // 14 +    int32   m_rideAnimStart;                                // 15 +    int32   m_rideAnimLoop;                                 // 16 +    int32   m_rideUpperAnimStart;                           // 17 +    int32   m_rideUpperAnimLoop;                            // 18 +    float   m_exitPreDelay;                                 // 19 +    float   m_exitSpeed;                                    // 20 +    float   m_exitGravity;                                  // 21 +    float   m_exitMinDuration;                              // 22 +    float   m_exitMaxDuration;                              // 23 +    float   m_exitMinArcHeight;                             // 24 +    float   m_exitMaxArcHeight;                             // 25 +    int32   m_exitAnimStart;                                // 26 +    int32   m_exitAnimLoop;                                 // 27 +    int32   m_exitAnimEnd;                                  // 28 +    float   m_passengerYaw;                                 // 29 +    float   m_passengerPitch;                               // 30 +    float   m_passengerRoll;                                // 31 +    int32   m_passengerAttachmentID;                        // 32 +    int32   m_vehicleEnterAnim;                             // 33 +    int32   m_vehicleExitAnim;                              // 34 +    int32   m_vehicleRideAnimLoop;                          // 35 +    int32   m_vehicleEnterAnimBone;                         // 36 +    int32   m_vehicleExitAnimBone;                          // 37 +    int32   m_vehicleRideAnimLoopBone;                      // 38 +    float   m_vehicleEnterAnimDelay;                        // 39 +    float   m_vehicleExitAnimDelay;                         // 40 +    uint32  m_vehicleAbilityDisplay;                        // 41 +    uint32  m_enterUISoundID;                               // 42 +    uint32  m_exitUISoundID;                                // 43 +    int32   m_uiSkin;                                       // 44 +    uint32  m_flagsB;                                       // 45 +}; +  struct WorldMapAreaEntry  { -    //uint32    ID;                                         // 0 -    uint32    map_id;                                       // 1 -    uint32    area_id;                                      // 2 index (continent 0 areas ignored) -    //char*   internal_name                                 // 3 -    float     y1;                                           // 4 -    float     y2;                                           // 5 -    float     x1;                                           // 6 -    float     x2;                                           // 7 +    //uint32  ID;                                           // 0 +    uint32  map_id;                                         // 1 +    uint32  area_id;                                        // 2 index (continent 0 areas ignored) +    //char* internal_name                                   // 3 +    float   y1;                                             // 4 +    float   y2;                                             // 5 +    float   x1;                                             // 6 +    float   x2;                                             // 7      int32   virtual_map_id;                                 // 8 -1 (map_id have correct map) other: virtual map where zone show (map_id - where zone in fact internally)  }; @@ -843,6 +1478,12 @@ struct WorldSafeLocsEntry                                                              // 21 name flags, unused  }; +struct WorldMapOverlayEntry +{ +    uint32    ID;                                           // 0 +    uint32    areatableID;                                  // 2 +}; +  // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform  #if defined( __GNUC__ )  #pragma pack() @@ -888,6 +1529,6 @@ struct TaxiPathNode  typedef std::vector<TaxiPathNode> TaxiPathNodeList;  typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; -#define TaxiMaskSize 16 +#define TaxiMaskSize 12  typedef uint32 TaxiMask[TaxiMaskSize];  #endif diff --git a/src/shared/Database/DBCfmt.cpp b/src/shared/Database/DBCfmt.cpp index 57a81921d62..edcf7e2b2be 100644 --- a/src/shared/Database/DBCfmt.cpp +++ b/src/shared/Database/DBCfmt.cpp @@ -10,29 +10,29 @@   *   * 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 + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */ -const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxx"; +const char Achievementfmt[]="niixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxxxxxxxxxi"; +const char AchievementCriteriafmt[]="niiiiiiiixxxxxxxxxxxxxxxxxiixix"; +const char AreaTableEntryfmt[]="iiinixxxxxissssssssssssssssxixxxxxxx";  const char AreaTriggerEntryfmt[]="niffffffff";  const char BankBagSlotPricesEntryfmt[]="ni"; -const char BattlemasterListEntryfmt[]="niiixxxxxiiiixxssssssssssssssssxx"; -const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxx"; -// 3*12 new item fields in 3.0.x -//const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char BarberShopStyleEntryfmt[]="nixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiii"; +const char BattlemasterListEntryfmt[]="niiiiiiiiiiiixxxssssssssssssssssxx"; +const char CharStartOutfitEntryfmt[]="diiiiiiiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";  const char CharTitlesEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi";  const char ChatChannelsEntryfmt[]="iixssssssssssssssssxxxxxxxxxxxxxxxxxx";                                                              // ChatChannelsEntryfmt, index not used (more compact store) -//const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; -const char ChrClassesEntryfmt[]="nxixssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxix"; +const char ChrClassesEntryfmt[]="nxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixii";  const char ChrRacesEntryfmt[]="nxixiixxixxxxissssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxi"; -const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxx"; -const char CreatureFamilyfmt[]="nfifiiiissssssssssssssssxx"; +const char CreatureDisplayInfofmt[]="nxxxfxxxxxxxxxxx"; +const char CreatureFamilyfmt[]="nfifiiiiixssssssssssssssssxx";  const char CreatureSpellDatafmt[]="nxxxxxxxx";  const char DurabilityCostsfmt[]="niiiiiiiiiiiiiiiiiiiiiiiiiiiii";  const char DurabilityQualityfmt[]="nf"; @@ -40,6 +40,9 @@ const char EmoteEntryfmt[]="nxixxxxxxxxxxxxxxxx";  const char FactionEntryfmt[]="niiiiiiiiiiiiiiiiiissssssssssssssssxxxxxxxxxxxxxxxxxx";  const char FactionTemplateEntryfmt[]="niiiiiiiiiiiii";  const char GemPropertiesEntryfmt[]="nixxi"; +const char GlyphPropertiesfmt[]="niii"; +const char GlyphSlotfmt[]="nii"; +const char GtBarberShopCostBasefmt[]="f";  const char GtCombatRatingsfmt[]="f";  const char GtChanceToMeleeCritBasefmt[]="f";  const char GtChanceToMeleeCritfmt[]="f"; @@ -49,36 +52,44 @@ const char GtOCTRegenHPfmt[]="f";  //const char GtOCTRegenMPfmt[]="f";  const char GtRegenHPPerSptfmt[]="f";  const char GtRegenMPPerSptfmt[]="f"; -const char Itemfmt[]="niii"; +const char Itemfmt[]="nxxxxiii";  //const char ItemDisplayTemplateEntryfmt[]="nxxxxxxxxxxixxxxxxxxxxx";  //const char ItemCondExtCostsEntryfmt[]="xiii"; -const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiii"; -const char ItemRandomPropertiesfmt[]="nxiiixxxxxxxxxxxxxxxxxxx"; -const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiii"; +const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiix"; +const char ItemRandomPropertiesfmt[]="nxiiiiixxxxxxxxxxxxxxxxx"; +const char ItemRandomSuffixfmt[]="nxxxxxxxxxxxxxxxxxxiiiiiiiiii";  const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii"; -const char LockEntryfmt[]="niiiiixxxiiiiixxxiixxxxxxxxxxxxxx"; +const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx";  const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char MapEntryfmt[]="nxixssssssssssssssssxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxi"; +const char MapEntryfmt[]="nxixssssssssssssssssxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiffiixxix";  const char QuestSortEntryfmt[]="nxxxxxxxxxxxxxxxxx";  const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; -const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxi"; -const char SkillLineAbilityfmt[]="niiiixxiiiiixxi"; +const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiii"; +const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiii"; +const char SkillLinefmt[]="nixssssssssssssssssxxxxxxxxxxxxxxxxxxixxxxxxxxxxxxxxxxxx"; +const char SkillLineAbilityfmt[]="niiiixxiiiiixx";  const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxx";  const char SpellCastTimefmt[]="nixx";  const char SpellDurationfmt[]="niii"; -const char SpellEntryfmt[]="nixiiiiiiiixiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffixiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiixfffxxxiiii"; +const char SpellEntryfmt[]="niiiiiiiiixiiiiiiiiiixxxxiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffffffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiix";  const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; -const char SpellItemEnchantmentfmt[]="niiiiiixxxiiissssssssssssssssxiiii"; +const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiixx";  const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";  const char SpellRadiusfmt[]="nfxf"; -const char SpellRangefmt[]="nffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char SpellRangefmt[]="nfxfxixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char SpellRuneCostfmt[]="niiii";  const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";  const char StableSlotPricesfmt[] = "ni"; -const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxi"; -const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiix"; +//const char SummonPropertiesfmt[] = "niiiii"; +const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; +const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix";  const char TaxiNodesEntryfmt[]="nifffxxxxxxxxxxxxxxxxxii";  const char TaxiPathEntryfmt[]="niii";  const char TaxiPathNodeEntryfmt[]="diiifffiixx";  const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; -const char WorldMapAreaEntryfmt[]="xinxffffi"; +const char VehicleEntryfmt[]="niffffiiiiiiiiffffiiiiiifffffffffffssssfifi"; +const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiii"; +const char WorldMapAreaEntryfmt[]="xinxffffix";  const char WorldSafeLocsEntryfmt[]="nifffxxxxxxxxxxxxxxxxx"; +const char WorldMapOverlayEntryfmt[]="nxixxxxxxxxxxxxxx"; + diff --git a/src/shared/Database/Database.h b/src/shared/Database/Database.h index 30d7193801e..dd6d02d36dd 100644 --- a/src/shared/Database/Database.h +++ b/src/shared/Database/Database.h @@ -33,7 +33,7 @@ class SqlQueryHolder;  typedef UNORDERED_MAP<ZThread::ThreadImpl*, SqlTransaction*> TransactionQueues;  typedef UNORDERED_MAP<ZThread::ThreadImpl*, SqlResultQueue*> QueryQueues; -#define MAX_QUERY_LEN   1024 +#define MAX_QUERY_LEN   32*1024  class TRINITY_DLL_SPEC Database  { diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index 4845841b6d6..64ef4e3d6ad 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -32,11 +32,11 @@ const char CreatureInfodstfmt[]="iiiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiiiiiiiii  const char CreatureDataAddonInfofmt[]="iiiiiiiis";  const char CreatureModelfmt[]="iffbi";  const char CreatureInfoAddonInfofmt[]="iiiiiiiis"; -const char EquipmentInfofmt[]="iiiiiiiiii"; +const char EquipmentInfofmt[]="iiii";  const char GameObjectInfosrcfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiis";  const char GameObjectInfodstfmt[]="iiissiifiiiiiiiiiiiiiiiiiiiiiiiii"; -const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifsiiiii"; -const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiii"; +const char ItemPrototypesrcfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiisiiii"; +const char ItemPrototypedstfmt[]="iiiisiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiffiffiffiffiffiiiiiiiiiifiiifiiiiiifiiiiiifiiiiiifiiiiiifiiiisiiiiiiiiiiiiiiiiiiiiiiiiifiiiiiii";  const char PageTextfmt[]="isi";  const char SpellThreatfmt[]="ii";  const char InstanceTemplatesrcfmt[]="iiiiiiffffs"; diff --git a/src/shared/Makefile.am b/src/shared/Makefile.am index 54aef015e46..9c87d7bab40 100644 --- a/src/shared/Makefile.am +++ b/src/shared/Makefile.am @@ -18,93 +18,49 @@  ## Process this file with automake to produce Makefile.in -## TODO move vmaps in src dir instead of src/shared -  ## Sub-directories to parse -SUBDIRS = vmap +SUBDIRS = Auth Config Database vmap + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = $(MANGOS_INCLUDES) -I$(top_builddir)/src/shared -I$(srcdir) -I$(srcdir)/../../dep/include -I$(srcdir)/../framework -I$(srcdir)/../shared -I$(srcdir)/../../dep/include/g3dlite  -DSYSCONFDIR=\"$(sysconfdir)/\" +## AM_CPPFLAGS += -I$(srcdir)/../game -I$(srcdir)/../realmd  ## Build MaNGOS shared library and its parts as convenience library.  #  All libraries will be convenience libraries. Might be changed to shared  #  later. -noinst_LIBRARIES = libshared.a - -libshared_a_CPPFLAGS = \ -$(MYSQL_INCLUDES) \ -$(POSTGRE_INCLUDES) \ -$(TRINI_INCLUDES) \ --I$(top_srcdir)/dep/include \ --I$(top_srcdir)/src/framework +noinst_LIBRARIES = libmangosshared.a  #  libmangosshared library will later be reused by ... -libshared_a_SOURCES = \ -$(srcdir)/Base.cpp \ -$(srcdir)/Base.h \ -$(srcdir)/ByteBuffer.h \ -$(srcdir)/Common.cpp \ -$(srcdir)/Common.h \ -$(srcdir)/Errors.h \ -$(srcdir)/Log.cpp \ -$(srcdir)/Log.h \ -$(srcdir)/Mthread.cpp \ -$(srcdir)/Mthread.h \ -$(srcdir)/ProgressBar.cpp \ -$(srcdir)/ProgressBar.h \ -$(srcdir)/Timer.h \ -$(srcdir)/Util.cpp \ -$(srcdir)/Util.h \ -$(srcdir)/WorldPacket.h \ -$(srcdir)/SystemConfig.h \ -$(srcdir)../game/IRCConf.h \ -$(srcdir)/Auth/AuthCrypt.cpp \ -$(srcdir)/Auth/AuthCrypt.h \ -$(srcdir)/Auth/BigNumber.cpp \ -$(srcdir)/Auth/BigNumber.h \ -$(srcdir)/Auth/Hmac.cpp \ -$(srcdir)/Auth/Hmac.h \ -$(srcdir)/Auth/Sha1.cpp \ -$(srcdir)/Auth/Sha1.h \ -$(srcdir)/Auth/md5.c \ -$(srcdir)/Auth/md5.h \ -$(srcdir)/Config/dotconfpp/dotconfpp.cpp \ -$(srcdir)/Config/dotconfpp/dotconfpp.h \ -$(srcdir)/Config/dotconfpp/mempool.cpp \ -$(srcdir)/Config/dotconfpp/mempool.h \ -$(srcdir)/Config/Config.cpp \ -$(srcdir)/Config/Config.h \ -$(srcdir)/Config/ConfigEnv.h \ -$(srcdir)/Database/DBCStores.cpp \ -$(srcdir)/Database/DBCStores.h \ -$(srcdir)/Database/DBCStructure.h \ -$(srcdir)/Database/DBCfmt.cpp \ -$(srcdir)/Database/Database.cpp \ -$(srcdir)/Database/Database.h \ -$(srcdir)/Database/DatabaseEnv.h \ -$(srcdir)/Database/DatabaseImpl.h \ -$(srcdir)/Database/DatabaseMysql.cpp \ -$(srcdir)/Database/DatabasePostgre.cpp \ -$(srcdir)/Database/DatabaseMysql.h \ -$(srcdir)/Database/DatabasePostgre.h \ -$(srcdir)/Database/DatabaseSqlite.cpp \ -$(srcdir)/Database/DatabaseSqlite.h \ -$(srcdir)/Database/Field.cpp \ -$(srcdir)/Database/Field.h \ -$(srcdir)/Database/MySQLDelayThread.h \ -$(srcdir)/Database/PGSQLDelayThread.h \ -$(srcdir)/Database/QueryResult.h \ -$(srcdir)/Database/QueryResultMysql.cpp \ -$(srcdir)/Database/QueryResultMysql.h \ -$(srcdir)/Database/QueryResultPostgre.cpp \ -$(srcdir)/Database/QueryResultPostgre.h \ -$(srcdir)/Database/QueryResultSqlite.cpp \ -$(srcdir)/Database/QueryResultSqlite.h \ -$(srcdir)/Database/SQLStorage.cpp \ -$(srcdir)/Database/SQLStorage.h \ -$(srcdir)/Database/SqlDelayThread.cpp \ -$(srcdir)/Database/SqlDelayThread.h \ -$(srcdir)/Database/SqlOperations.cpp \ -$(srcdir)/Database/SqlOperations.h \ -$(srcdir)/Database/dbcfile.cpp \ -$(srcdir)/Database/dbcfile.h +libmangosshared_a_SOURCES = \ +    Base.cpp \ +    Base.h \ +    ByteBuffer.h \ +    Common.cpp \ +    Common.h \ +    Errors.h \ +    Log.cpp \ +    Log.h \ +    MemoryLeaks.cpp \ +    MemoryLeaks.h \ +    ProgressBar.cpp \ +    ProgressBar.h \ +    Timer.h \ +    Util.cpp \ +    Util.h \ +    WorldPacket.h \ +    revision_nr.h \ +    revision.h + +# Get revision (git or svn) +REVISION_FILE = revision.h + +BUILT_SOURCES = $(REVISION_FILE) +CLEANFILES = $(REVISION_FILE) + +FORCE: + +$(REVISION_FILE) : $(top_builddir)/src/tools/genrevision/genrevision FORCE +	$(top_builddir)/src/tools/genrevision/genrevision $(top_srcdir)  ## Additional files to include when running 'make dist'  #  Disabled packet logger diff --git a/src/shared/MemoryLeaks.h b/src/shared/MemoryLeaks.h new file mode 100644 index 00000000000..fceb9d6f444 --- /dev/null +++ b/src/shared/MemoryLeaks.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 + */ + +#ifndef MANGOSSERVER_MEMORY_H +#define MANGOSSERVER_MEMORY_H + +#include "Platform/CompilerDefs.h" + +#if COMPILER == COMPILER_MICROSOFT + +#ifndef _WIN64 +// Visual Leak Detector support enabled +//#include <vld/vld.h> +// standard Visual Studio leak check disabled, +//#  define _CRTDBG_MAP_ALLOC +//#  include <stdlib.h> +//#  include <crtdbg.h> +#else +#  define _CRTDBG_MAP_ALLOC +#  include <stdlib.h> +#  include <crtdbg.h> +#endif + +#endif + + +#include "Policies/Singleton.h" + +struct MemoryManager : public MaNGOS::Singleton < MemoryManager > +{ +    MemoryManager(); +}; +#endif diff --git a/src/shared/SystemConfig.h.in b/src/shared/SystemConfig.h.in index 262aa9e6355..51209d0454b 100644 --- a/src/shared/SystemConfig.h.in +++ b/src/shared/SystemConfig.h.in @@ -11,23 +11,66 @@   *   * 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 + * 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 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA   */ -// THIS FILE IS DEPRECATED -  #ifndef TRINITY_SYSTEMCONFIG_H  #define TRINITY_SYSTEMCONFIG_H +#ifndef _PACKAGENAME +#define _PACKAGENAME "Trinity" +#endif +  #include "Platform/Define.h" -// THIS IS TEMP :) -#define _FULLVERSION "Trinity" +#ifndef _VERSION +#if PLATFORM == PLATFORM_WINDOWS +# define _VERSION(REVD,REVT,REVN,REVH) "0.13.0-DEV" " (" REVD " " REVT " Revision " REVN " - " REVH ")" +#else +# define _VERSION(REVD,REVT,REVN,REVH) "@VERSION@" " (" REVD " " REVT " Revision " REVN " - " REVH ")" +#endif +#endif + +// Format is YYYYMMDDRR where RR is the change in the conf file +// for that day. +#ifndef _MANGOSDCONFVERSION +# define _MANGOSDCONFVERSION 2008022901 +#endif +#ifndef _REALMDCONFVERSION +# define _REALMDCONFVERSION 2007062001 +#endif + +#if MANGOS_ENDIAN == MANGOS_BIGENDIAN +# define _ENDIAN_STRING "big-endian" +#else +# define _ENDIAN_STRING "little-endian" +#endif + +// The path to config files +#ifndef SYSCONFDIR +#  define SYSCONFDIR        "" +#endif + +#if PLATFORM == PLATFORM_WINDOWS +# ifdef _WIN64 +#  define _ENDIAN_PLATFORM "Win64 (" _ENDIAN_STRING ")" +# else +#  define _ENDIAN_PLATFORM "Win32 (" _ENDIAN_STRING ")" +# endif +# define _MANGOSD_CONFIG  SYSCONFDIR"mangosd.conf" +# define _REALMD_CONFIG   SYSCONFDIR"realmd.conf" +#else +# define _ENDIAN_PLATFORM "Unix (" _ENDIAN_STRING ")" +# define _MANGOSD_CONFIG  SYSCONFDIR"mangosd.conf" +# define _REALMD_CONFIG  SYSCONFDIR"realmd.conf" +#endif + +#define _FULLVERSION(REVD,REVT,REVN,REVH) _PACKAGENAME "/" _VERSION(REVD,REVT,REVN,REVH) " for " _ENDIAN_PLATFORM  #define DEFAULT_PLAYER_LIMIT 100  #define DEFAULT_WORLDSERVER_PORT 8085                       //8129 diff --git a/src/shared/Util.h b/src/shared/Util.h index b99cdb13bde..95bc8ec1028 100644 --- a/src/shared/Util.h +++ b/src/shared/Util.h @@ -287,20 +287,20 @@ bool consoleToUtf8(const std::string& conStr,std::string& utf8str);  bool Utf8FitTo(const std::string& str, std::wstring search);  #if PLATFORM == PLATFORM_WINDOWS -#define UTF8PRINTF(OUT,FRM,RESERR)                      \ -{                                                       \ -    char temp_buf[6000];                                \ -    va_list ap;                                         \ -    va_start(ap, FRM);                                  \ -    size_t temp_len = vsnprintf(temp_buf,6000,FRM,ap);  \ -    va_end(ap);                                         \ -                                                        \ -    wchar_t wtemp_buf[6000];                            \ -    size_t wtemp_len = 6000-1;                          \ +#define UTF8PRINTF(OUT,FRM,RESERR)                         \ +{                                                          \ +    char temp_buf[32*1024];                                \ +    va_list ap;                                            \ +    va_start(ap, FRM);                                     \ +    size_t temp_len = vsnprintf(temp_buf,32*1024,FRM,ap);  \ +    va_end(ap);                                            \ +                                                           \ +    wchar_t wtemp_buf[32*1024];                            \ +    size_t wtemp_len = 32*1024-1;                          \      if(!Utf8toWStr(temp_buf,temp_len,wtemp_buf,wtemp_len)) \ -        return RESERR;                                  \ +        return RESERR;                                     \      CharToOemBuffW(&wtemp_buf[0],&temp_buf[0],wtemp_len+1);\ -    fprintf(OUT,temp_buf);                              \ +    fprintf(OUT,temp_buf);                                 \  }  #else  #define UTF8PRINTF(OUT,FRM,RESERR)                      \ diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h new file mode 100644 index 00000000000..5d8d14cb83b --- /dev/null +++ b/src/shared/revision_nr.h @@ -0,0 +1,4 @@ +#ifndef __REVISION_NR_H__ +#define __REVISION_NR_H__ + #define REVISION_NR "6963" +#endif // __REVISION_NR_H__ diff --git a/src/shared/vmap/TileAssembler.cpp b/src/shared/vmap/TileAssembler.cpp index 198806601fa..c8f0b10e76d 100644 --- a/src/shared/vmap/TileAssembler.cpp +++ b/src/shared/vmap/TileAssembler.cpp @@ -75,12 +75,12 @@ namespace VMAP          addWorldAreaMapId(0);                               //Azeroth          addWorldAreaMapId(1);                               //Kalimdor          addWorldAreaMapId(530);                             //Expansion01 +        addWorldAreaMapId(571);                             //Expansion02      }      //=================================================================      std::string getModNameFromModPosName(const std::string& pModPosName)      { -          size_t spos = pModPosName.find_first_of('#');          std::string modelFileName = pModPosName.substr(0,spos);          return(modelFileName); @@ -142,7 +142,6 @@ namespace VMAP      //=================================================================      bool TileAssembler::convertWorld()      { -          #ifdef _ASSEMBLER_DEBUG          #   ifdef _DEBUG          ::g_df = fopen("../TileAssembler_debug.txt", "wb"); diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am new file mode 100644 index 00000000000..7b68544e185 --- /dev/null +++ b/src/tools/Makefile.am @@ -0,0 +1,23 @@ +# Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> +# +# 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 + +## Process this file with automake to produce Makefile.in + +## Sub-directories to parse +SUBDIRS = genrevision + +## Additional files to include when running 'make dist' +#  Nothing yet. diff --git a/src/tools/genrevision/Makefile.am b/src/tools/genrevision/Makefile.am new file mode 100644 index 00000000000..814c6079010 --- /dev/null +++ b/src/tools/genrevision/Makefile.am @@ -0,0 +1,35 @@ +# Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> +# +# 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 + +## Process this file with automake to produce Makefile.in + +## CPP flags for includes, defines, etc. +AM_CPPFLAGS = -I$(srcdir) + +## Build world list daemon as standalone program +bin_PROGRAMS = genrevision +genrevision_SOURCES = \ +	genrevision.cpp + +## Link world daemon against the shared library +genrevision_LDADD = +genrevision_LDFLAGS = -L$(libdir) + +## Additional files to include when running 'make dist' +#  Include world daemon configuration +#EXTRA_DIST = + +## Additional files to install diff --git a/src/tools/genrevision/genrevision.cpp b/src/tools/genrevision/genrevision.cpp new file mode 100644 index 00000000000..a9e39d93c26 --- /dev/null +++ b/src/tools/genrevision/genrevision.cpp @@ -0,0 +1,308 @@ +/* + * Copyright (C) 2005-2008 MaNGOS <http://getmangos.com/> + * + * 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 <fstream> +#include <sstream> +#include <time.h> +#include <stdio.h> +#include <string.h> + +#pragma warning(disable:4996) + +struct RawData +{ +    char rev_str[200]; +    char date_str[200]; +    char time_str[200]; +}; + +void extractDataFromSvn(FILE* EntriesFile, bool url, RawData& data) +{ +    char buf[200]; + +    char repo_str[200]; +    char num_str[200]; + +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); sscanf(buf,"%s",num_str); +    fgets(buf,200,EntriesFile); sscanf(buf,"%s",repo_str); +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); +    fgets(buf,200,EntriesFile); sscanf(buf,"%10sT%8s",data.date_str,data.time_str); + +    if(url) +        sprintf(data.rev_str,"%s at %s",num_str,repo_str); +    else +        strcpy(data.rev_str,num_str); +} + +void extractDataFromGit(FILE* EntriesFile, std::string path, bool url, RawData& data) +{ +    char buf[200]; + +    char hash_str[200]; +    char branch_str[200]; +    char url_str[200]; + +    bool found = false; +    while(fgets(buf,200,EntriesFile)) +    { +        if(sscanf(buf,"%s\t\tbranch %s of %s",hash_str,branch_str,url_str)==3) +        { +            found = true; +            break; +        } +    } + +    if(!found) +    { +        strcpy(data.rev_str,"*"); +        strcpy(data.date_str,"*"); +        strcpy(data.time_str,"*"); +        return; +    } + +    if(url) +    { +        char* host_str = NULL; +        char* acc_str  = NULL; +        char* repo_str = NULL; + +        // parse URL like git@github.com:mangos/mangos +        char url_buf[200]; +        int res = sscanf(url_str,"git@%s",url_buf); +        if(res) +        { +            host_str = strtok(url_buf,":"); +            acc_str  = strtok(NULL,"/"); +            repo_str = strtok(NULL," "); +        } +        else +        { +            res = sscanf(url_str,"git://%s",url_buf); +            if(res) +            { +                host_str = strtok(url_buf,"/"); +                acc_str  = strtok(NULL,"/"); +                repo_str = strtok(NULL,"."); +            } +        } + +        // can generate nice link +        if(res) +            sprintf(data.rev_str,"http://%s/%s/%s/commit/%s",host_str,acc_str,repo_str,hash_str); +        // unknonw URL format, use as-is +        else +            sprintf(data.rev_str,"%s at %s",hash_str,url_str); +    } +    else +        strcpy(data.rev_str,hash_str); + +    time_t rev_time = 0; +    // extracting date/time +    FILE* LogFile = fopen((path+".git/logs/HEAD").c_str(), "r"); +    if(LogFile) +    { +        while(fgets(buf,200,LogFile)) +        { +            char buf2[200]; +            char new_hash[200]; +            int unix_time = 0; +            int res2 = sscanf(buf,"%s %s %s %s %i",buf2,new_hash,buf2,buf2,&unix_time); +            if(res2!=5) +                continue; + +            if(strcmp(hash_str,new_hash)) +                continue; + +            rev_time = unix_time; +            break; +        } + +        fclose(LogFile); + +        if(rev_time) +        { +            tm* aTm = localtime(&rev_time); +            //       YYYY   year +            //       MM     month (2 digits 01-12) +            //       DD     day (2 digits 01-31) +            //       HH     hour (2 digits 00-23) +            //       MM     minutes (2 digits 00-59) +            //       SS     seconds (2 digits 00-59) +            sprintf(data.date_str,"%04d-%02d-%02d",aTm->tm_year+1900,aTm->tm_mon+1,aTm->tm_mday); +            sprintf(data.time_str,"%02d:%02d:%02d",aTm->tm_hour,aTm->tm_min,aTm->tm_sec); +        } +        else +        { +            strcpy(data.date_str,"*"); +            strcpy(data.time_str,"*"); +        } +    } +    else +    { +        strcpy(data.date_str,"*"); +        strcpy(data.time_str,"*"); +    } +} + +bool extractDataFromSvn(std::string filename, bool url, RawData& data) +{ +    FILE* EntriesFile = fopen(filename.c_str(), "r"); +    if(!EntriesFile) +        return false; + +    extractDataFromSvn(EntriesFile,url,data); +    fclose(EntriesFile); +    return true; +} + +bool extractDataFromGit(std::string filename, std::string path, bool url, RawData& data) +{ +    FILE* EntriesFile = fopen(filename.c_str(), "r"); +    if(!EntriesFile) +        return false; + +    extractDataFromGit(EntriesFile,path,url,data); +    fclose(EntriesFile); +    return true; +} + +std::string generateHeader(char const* rev_str, char const* date_str, char const* time_str) +{ +    std::ostringstream newData; +    newData << "#ifndef __REVISION_H__" << std::endl; +    newData << "#define __REVISION_H__"  << std::endl; +    newData << " #define REVISION_ID \"" << rev_str << "\"" << std::endl; +    newData << " #define REVISION_DATE \"" << date_str << "\"" << std::endl; +    newData << " #define REVISION_TIME \"" << time_str << "\""<< std::endl; +    newData << "#endif // __REVISION_H__" << std::endl; +    return newData.str(); +} + +int main(int argc, char **argv) +{ +    bool use_url = false; +    bool svn_prefered = false; +    std::string path; + +    // Call: tool {options} [path] +    //    -g use git prefered (default) +    //    -s use svn prefered +    //    -r use only revision (without repo URL) (default) +    //    -u include repositire URL as commit URL or "rev at URL" +    for(int k = 1; k <= argc; ++k) +    { +        if(!argv[k] || !*argv[k]) +            break; + +        if(argv[k][0]!='-') +        { +            path = argv[k]; +            if(path.size() > 0 && (path[path.size()-1]!='/' || path[path.size()-1]!='\\')) +                path += '/'; +            break; +        } + +        switch(argv[k][1]) +        { +            case 'g': +                svn_prefered = false; +                continue; +            case 'r': +                use_url = false; +                continue; +            case 's': +                svn_prefered = true; +                continue; +            case 'u': +                use_url = true; +                continue; +            default: +                printf("Unknown option %s",argv[k]); +                return 1; +        } +    } + +    /// new data extraction +    std::string newData; + +    { +        RawData data; + +        bool res = false; + +        if(svn_prefered) +        { +            /// SVN data +            res = extractDataFromSvn(path+".svn/entries",use_url,data); +            if (!res) +                res = extractDataFromSvn(path+"_svn/entries",use_url,data); +            // GIT data +            if (!res) +                res = extractDataFromGit(path+".git/FETCH_HEAD",path,use_url,data); +        } +        else +        { +            // GIT data +            res = extractDataFromGit(path+".git/FETCH_HEAD",path,use_url,data); +            /// SVN data +            if (!res) +                res = extractDataFromSvn(path+".svn/entries",use_url,data); +            if (!res) +                res = extractDataFromSvn(path+"_svn/entries",use_url,data); +        } + +        if(res) +            newData = generateHeader(data.rev_str,data.date_str,data.time_str); +        else +            newData = generateHeader("*", "*", "*"); +    } + +    /// get existed header data for compare +    std::string oldData; + +    if(FILE* HeaderFile = fopen("revision.h","rb")) +    { +        while(!feof(HeaderFile)) +        { +            int c = fgetc(HeaderFile); +            if(c < 0) +                break; +            oldData += (char)c; +        } + +        fclose(HeaderFile); +    } + +    /// update header only if different data +    if(newData != oldData) +    { +        if(FILE* OutputFile = fopen("revision.h","wb")) +        { +            fprintf(OutputFile,"%s",newData.c_str()); +            fclose(OutputFile); +        } +    } + +    return 0; +}  | 
