From aabde1030c4d37b19fec20b3646b85c29e876063 Mon Sep 17 00:00:00 2001 From: nos4r2zod Date: Wed, 24 Jun 2009 03:42:17 +0400 Subject: [PATCH 01/36] [8074] Fixed typo in money save. Signed-off-by: VladimirMangos --- src/game/Player.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 170f8779f..673ead2c7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -15564,7 +15564,7 @@ void Player::SaveInventoryAndGoldToDB() void Player::SaveGoldToDB() { - CharacterDatabase.PExecute("UPDATE money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow()); + CharacterDatabase.PExecute("UPDATE characters SET money = '%u' WHERE guid = '%u'", GetMoney(), GetGUIDLow()); } void Player::_SaveActions() diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7cce0da81..24d75161c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8073" + #define REVISION_NR "8074" #endif // __REVISION_NR_H__ From 8198da72a9fae4718a14774ce7b66407567748cf Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Wed, 24 Jun 2009 05:28:44 +0400 Subject: [PATCH 02/36] [8075] Effect at remove for aura of spell 42783. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 19 ++++++++++++++++--- src/shared/revision_nr.h | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 5808127e5..442da5011 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -4161,10 +4161,23 @@ void Aura::HandleAuraModStalked(bool apply, bool /*Real*/) void Aura::HandlePeriodicTriggerSpell(bool apply, bool /*Real*/) { m_isPeriodic = apply; - if (m_spellProto->Id == 66 && !apply) + + if (!apply) { - if (m_removeMode == AURA_REMOVE_BY_DEFAULT && m_duration<=0) - m_target->CastSpell(m_target, 32612, true, NULL, this); + switch(m_spellProto->Id) + { + case 66: // Invisibility + if (m_removeMode == AURA_REMOVE_BY_DEFAULT && m_duration<=0) + m_target->CastSpell(m_target, 32612, true, NULL, this); + + return; + case 42783: //Wrath of the Astrom... + if (m_removeMode == AURA_REMOVE_BY_DEFAULT && GetEffIndex() + 1 < 3) + m_target->CastSpell(m_target, m_spellProto->CalculateSimpleValue(GetEffIndex()+1), true); + return; + default: + break; + } } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 24d75161c..539e7691c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8074" + #define REVISION_NR "8075" #endif // __REVISION_NR_H__ From 00fc1d7593a6cfc31f936ffc0d6a4087b86e9183 Mon Sep 17 00:00:00 2001 From: thenecromancer Date: Thu, 25 Jun 2009 06:31:28 +0400 Subject: [PATCH 03/36] [8076] Fixed well known walk-after-taxi bug. Also thanks to jolan, yad02, nos4r2zod for deep reseach problem. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 11 +++-------- src/game/WaypointMovementGenerator.cpp | 5 ++++- src/shared/revision_nr.h | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index e7f2b4947..e0196c9d2 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -11038,15 +11038,10 @@ void Unit::StopMoving() clearUnitState(UNIT_STAT_MOVING); // send explicit stop packet - // rely on vmaps here because for example stormwind is in air - //float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); - //if (fabs(GetPositionZ() - z) < 2.0f) - // Relocate(GetPositionX(), GetPositionY(), z); - Relocate(GetPositionX(), GetPositionY(),GetPositionZ()); + // player expected for correct work MONSTER_MOVE_WALK + SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), 0, GetTypeId()==TYPEID_PLAYER ? MONSTER_MOVE_WALK : MONSTER_MOVE_NONE, 0); - SendMonsterMove(GetPositionX(), GetPositionY(), GetPositionZ(), 0, 0, 0); - - // update position and orientation; + // update position and orientation for near players WorldPacket data; BuildHeartBeatMsg(&data); SendMessageToSet(&data,false); diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 71dd52599..3ee796ed6 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -38,6 +38,7 @@ alter table creature_movement add `wpguid` int(11) default '0'; #include "DestinationHolderImp.h" #include "CreatureAI.h" #include "WaypointManager.h" +#include "WorldPacket.h" #include @@ -261,7 +262,9 @@ void FlightPathMovementGenerator::Finalize(Player & player) if(player.pvpInfo.inHostileArea) player.CastSpell(&player, 2479, true); - player.SetUnitMovementFlags(MONSTER_MOVE_WALK); + // update z position to ground and orientation for landing point + // this prevent cheating with landing point at lags + // when client side flight end early in comparison server side player.StopMoving(); } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 539e7691c..958440da3 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8075" + #define REVISION_NR "8076" #endif // __REVISION_NR_H__ From 21a6a2638607ec4b7d8f4eb40911a22aca4034bc Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 25 Jun 2009 11:03:51 +0400 Subject: [PATCH 04/36] [8077] Resolve mixed store and use 2 different flags values types in single field. * Create new monster move field in Creature class and use it in all cases when expected use MONSTER_MOVE_* flags. * Store and use MOVEMENTFLAG_* values in field in MovementInfo structure of Player class. * Cleanups and fix related code. NOTE: DB in creature_addon store values similar MONSTER_MOVE_* flags, scritps also expected set only this flags. --- src/game/ConfusedMovementGenerator.cpp | 17 ++++--- src/game/Creature.cpp | 42 ++++++++++++++--- src/game/Creature.h | 12 ++++- src/game/FleeingMovementGenerator.cpp | 17 ++++--- src/game/HomeMovementGenerator.cpp | 4 +- src/game/Level3.cpp | 2 +- src/game/MiscHandler.cpp | 4 +- src/game/MovementHandler.cpp | 5 +- src/game/Object.cpp | 37 --------------- src/game/Object.h | 2 - src/game/Player.cpp | 22 +++++++-- src/game/Player.h | 46 ++++++++++++++++-- src/game/PointMovementGenerator.cpp | 2 +- src/game/RandomMovementGenerator.cpp | 23 +++++---- src/game/Spell.cpp | 4 +- src/game/SpellAuras.cpp | 10 ++-- src/game/TargetedMovementGenerator.cpp | 27 ++++++----- src/game/Traveller.h | 6 +-- src/game/Unit.cpp | 65 +++++++++++--------------- src/game/Unit.h | 51 ++------------------ src/game/WaypointMovementGenerator.cpp | 4 +- src/game/World.cpp | 4 +- src/game/WorldSession.cpp | 8 ++-- src/shared/revision_nr.h | 2 +- 24 files changed, 215 insertions(+), 201 deletions(-) diff --git a/src/game/ConfusedMovementGenerator.cpp b/src/game/ConfusedMovementGenerator.cpp index 2d46808c9..84ebdfc6b 100644 --- a/src/game/ConfusedMovementGenerator.cpp +++ b/src/game/ConfusedMovementGenerator.cpp @@ -64,7 +64,6 @@ ConfusedMovementGenerator::Initialize(T &unit) } unit.StopMoving(); - unit.RemoveUnitMovementFlag(MONSTER_MOVE_WALK); unit.addUnitState(UNIT_STAT_CONFUSED); } @@ -72,6 +71,8 @@ template<> void ConfusedMovementGenerator::_InitSpecific(Creature &creature, bool &is_water_ok, bool &is_land_ok) { + creature.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); + is_water_ok = creature.canSwim(); is_land_ok = creature.canWalk(); } @@ -138,17 +139,21 @@ ConfusedMovementGenerator::Update(T &unit, const uint32 &diff) return true; } -template -void -ConfusedMovementGenerator::Finalize(T &unit) +template<> +void ConfusedMovementGenerator::Finalize(Player &unit) { unit.clearUnitState(UNIT_STAT_CONFUSED); } +template<> +void ConfusedMovementGenerator::Finalize(Creature &unit) +{ + unit.clearUnitState(UNIT_STAT_CONFUSED); + unit.AddMonsterMoveFlag(MONSTER_MOVE_WALK); +} + template void ConfusedMovementGenerator::Initialize(Player &player); template void ConfusedMovementGenerator::Initialize(Creature &creature); -template void ConfusedMovementGenerator::Finalize(Player &player); -template void ConfusedMovementGenerator::Finalize(Creature &creature); template void ConfusedMovementGenerator::Reset(Player &player); template void ConfusedMovementGenerator::Reset(Creature &creature); template bool ConfusedMovementGenerator::Update(Player &player, const uint32 &diff); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index e8b2a20d6..98e500d8e 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -109,9 +109,10 @@ lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGrou 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_isPet(false), m_isVehicle(false), m_isTotem(false), -m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false), +m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), +m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), -m_creatureInfo(NULL), m_isActiveObject(false), m_AlreadySearchedAssistance(false) +m_creatureInfo(NULL), m_isActiveObject(false), m_monsterMoveFlags(MONSTER_MOVE_WALK) { m_regenTimer = 200; m_valuesCount = UNIT_END; @@ -122,7 +123,8 @@ m_creatureInfo(NULL), m_isActiveObject(false), m_AlreadySearchedAssistance(false m_CreatureSpellCooldowns.clear(); m_CreatureCategoryCooldowns.clear(); m_GlobalCooldown = 0; - m_unit_movement_flags = MONSTER_MOVE_WALK; + + m_monsterMoveFlags = MONSTER_MOVE_WALK; } Creature::~Creature() @@ -1032,7 +1034,7 @@ void Creature::LoadGossipOptions() m_gossipOptionLoaded = true; } -void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type) +void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, MonsterMovementFlags flags, uint8 type) { /* uint32 timeElap = getMSTime(); if ((timeElap - m_startMove) < m_moveTime) @@ -1052,7 +1054,7 @@ void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint3 m_startMove = getMSTime(); m_moveTime = time;*/ - SendMonsterMove(x, y, z, type, MovementFlags, time); + SendMonsterMove(x, y, z, type, flags, time); } Player *Creature::GetLootRecipient() const @@ -1533,7 +1535,7 @@ void Creature::setDeathState(DeathState s) CreatureInfo const *cinfo = GetCreatureInfo(); SetUInt32Value(UNIT_DYNAMIC_FLAGS, 0); RemoveFlag (UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - AddUnitMovementFlag(MONSTER_MOVE_WALK); + AddMonsterMoveFlag(MONSTER_MOVE_WALK); SetUInt32Value(UNIT_NPC_FLAGS, cinfo->npcflag); clearUnitState(UNIT_STAT_ALL_STATE); i_motionMaster.Clear(); @@ -1938,7 +1940,7 @@ bool Creature::LoadCreaturesAddon(bool reload) SetUInt32Value(UNIT_NPC_EMOTESTATE, cainfo->emote); if (cainfo->move_flags != 0) - SetUnitMovementFlags(cainfo->move_flags); + SetMonsterMoveFlags(MonsterMovementFlags(cainfo->move_flags)); if(cainfo->auras) { @@ -2279,3 +2281,29 @@ void Creature::SetActiveObjectState( bool on ) if(world) map->Add(this); } + +void Creature::SendMonsterMoveWithSpeedToCurrentDestination(Player* player) +{ + float x, y, z; + if(GetMotionMaster()->GetDestination(x, y, z)) + SendMonsterMoveWithSpeed(x, y, z, 0, player); +} + +void Creature::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime, Player* player) +{ + if (!transitTime) + { + if(GetTypeId()==TYPEID_PLAYER) + { + Traveller traveller(*(Player*)this); + transitTime = traveller.GetTotalTrevelTimeTo(x,y,z); + } + else + { + Traveller traveller(*(Creature*)this); + transitTime = traveller.GetTotalTrevelTimeTo(x,y,z); + } + } + //float orientation = (float)atan2((double)dy, (double)dx); + SendMonsterMove(x, y, z, 0, GetMonsterMoveFlags(), transitTime, player); +} diff --git a/src/game/Creature.h b/src/game/Creature.h index 01259c3ea..d2c548e3c 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -517,9 +517,18 @@ class MANGOS_DLL_SPEC Creature : public Unit bool AIM_Initialize(); - void AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type); + void AI_SendMoveToPacket(float x, float y, float z, uint32 time, MonsterMovementFlags MovementFlags, uint8 type); CreatureAI* AI() { return i_AI; } + void AddMonsterMoveFlag(MonsterMovementFlags f) { m_monsterMoveFlags = MonsterMovementFlags(m_monsterMoveFlags | f); } + void RemoveMonsterMoveFlag(MonsterMovementFlags f) { m_monsterMoveFlags = MonsterMovementFlags(m_monsterMoveFlags & ~f); } + bool HasMonsterMoveFlag(MonsterMovementFlags f) const { return m_monsterMoveFlags & f; } + MonsterMovementFlags GetMonsterMoveFlags() const { return m_monsterMoveFlags; } + void SetMonsterMoveFlags(MonsterMovementFlags f) { m_monsterMoveFlags = f; } + + void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); + void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); + uint32 GetShieldBlockValue() const //dunno mob block value { return (getLevel()/2 + uint32(GetStat(STAT_STRENGTH)/20)); @@ -725,6 +734,7 @@ class MANGOS_DLL_SPEC Creature : public Unit GridReference m_gridRef; CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry()) bool m_isActiveObject; + MonsterMovementFlags m_monsterMoveFlags; }; class AssistDelayEvent : public BasicEvent diff --git a/src/game/FleeingMovementGenerator.cpp b/src/game/FleeingMovementGenerator.cpp index f8f193ac9..a74790d9a 100644 --- a/src/game/FleeingMovementGenerator.cpp +++ b/src/game/FleeingMovementGenerator.cpp @@ -285,7 +285,6 @@ FleeingMovementGenerator::Initialize(T &owner) return; _Init(owner); - owner.RemoveUnitMovementFlag(MONSTER_MOVE_WALK); if(Unit * fright = ObjectAccessor::GetUnit(owner, i_frightGUID)) { @@ -313,6 +312,8 @@ FleeingMovementGenerator::_Init(Creature &owner) { if(!&owner) return; + + owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); owner.SetUInt64Value(UNIT_FIELD_TARGET, 0); is_water_ok = owner.canSwim(); is_land_ok = owner.canWalk(); @@ -326,13 +327,19 @@ FleeingMovementGenerator::_Init(Player &) is_land_ok = true; } -template -void -FleeingMovementGenerator::Finalize(T &owner) +template<> +void FleeingMovementGenerator::Finalize(Player &owner) { owner.clearUnitState(UNIT_STAT_FLEEING); } +template<> +void FleeingMovementGenerator::Finalize(Creature &owner) +{ + owner.AddMonsterMoveFlag(MONSTER_MOVE_WALK); + owner.clearUnitState(UNIT_STAT_FLEEING); +} + template void FleeingMovementGenerator::Reset(T &owner) @@ -379,8 +386,6 @@ template bool FleeingMovementGenerator::_getPoint(Player &, float &, flo template bool FleeingMovementGenerator::_getPoint(Creature &, float &, float &, float &); template void FleeingMovementGenerator::_setTargetLocation(Player &); template void FleeingMovementGenerator::_setTargetLocation(Creature &); -template void FleeingMovementGenerator::Finalize(Player &); -template void FleeingMovementGenerator::Finalize(Creature &); template void FleeingMovementGenerator::Reset(Player &); template void FleeingMovementGenerator::Reset(Creature &); template bool FleeingMovementGenerator::Update(Player &, const uint32 &); diff --git a/src/game/HomeMovementGenerator.cpp b/src/game/HomeMovementGenerator.cpp index 5dfbc8345..cc13446f0 100644 --- a/src/game/HomeMovementGenerator.cpp +++ b/src/game/HomeMovementGenerator.cpp @@ -27,7 +27,7 @@ void HomeMovementGenerator::Initialize(Creature & owner) { - owner.RemoveUnitMovementFlag(MONSTER_MOVE_WALK); + owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); _setTargetLocation(owner); } @@ -63,7 +63,7 @@ HomeMovementGenerator::Update(Creature &owner, const uint32& time_diff if (time_diff > i_travel_timer) { - owner.AddUnitMovementFlag(MONSTER_MOVE_WALK); + owner.AddMonsterMoveFlag(MONSTER_MOVE_WALK); // restore orientation of not moving creature at returning to home if(owner.GetDefaultMovementType()==IDLE_MOTION_TYPE) diff --git a/src/game/Level3.cpp b/src/game/Level3.cpp index 818864a51..f63f0077b 100644 --- a/src/game/Level3.cpp +++ b/src/game/Level3.cpp @@ -6057,7 +6057,7 @@ bool ChatHandler::HandleComeToMeCommand(const char *args) uint32 newFlags = atoi(newFlagStr); - caster->SetUnitMovementFlags(newFlags); + caster->SetMonsterMoveFlags(MonsterMovementFlags(newFlags)); Player* pl = m_session->GetPlayer(); diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 95730eb6a..c727e292f 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -276,7 +276,7 @@ void WorldSession::HandleLogoutRequestOpcode( WorldPacket & /*recv_data*/ ) if( GetPlayer()->isInCombat() || //...is in combat GetPlayer()->duel || //...is in Duel //...is jumping ...is falling - GetPlayer()->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING)) + GetPlayer()->m_movementInfo.HasMovementFlag(MovementFlags(MOVEMENTFLAG_JUMPING | MOVEMENTFLAG_FALLING))) { WorldPacket data( SMSG_LOGOUT_RESPONSE, (2+4) ) ; data << (uint8)0xC; @@ -1542,7 +1542,7 @@ void WorldSession::HandleMoveSetCanFlyAckOpcode( WorldPacket & recv_data ) recv_data >> guid >> unk >> flags; - _player->m_movementInfo.flags = flags; + _player->m_movementInfo.SetMovementFlags(MovementFlags(flags)); } void WorldSession::HandleRequestPetInfoOpcode( WorldPacket & /*recv_data */) diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index ef6e0a136..fd38c76bb 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -230,7 +230,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) return; /* handle special cases */ - if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) + if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) { // transports size limited // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped) @@ -272,7 +272,7 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) if (opcode == MSG_MOVE_FALL_LAND && plMover && !plMover->isInFlight()) plMover->HandleFall(movementInfo); - if (plMover && ((movementInfo.flags & MOVEMENTFLAG_SWIMMING) != 0) != plMover->IsInWater()) + if (plMover && (movementInfo.HasMovementFlag(MOVEMENTFLAG_SWIMMING) != plMover->IsInWater())) { // now client not include swimming flag in case jumping under water plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) ); @@ -331,7 +331,6 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) { if(Map *map = mover->GetMap()) map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); - mover->SetUnitMovementFlags(movementInfo.flags); } } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 4f16c3dbd..560d607c0 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1511,43 +1511,6 @@ void WorldObject::BuildMonsterChat(WorldPacket *data, uint8 msgtype, char const* *data << (uint8)0; // ChatTag } -void WorldObject::BuildHeartBeatMsg(WorldPacket *data) const -{ - //Heartbeat message cannot be used for non-units - if (!isType(TYPEMASK_UNIT)) - return; - - data->Initialize(MSG_MOVE_HEARTBEAT, 32); - data->append(GetPackGUID()); - *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags - *data << uint16(0); // 2.3.0 - *data << uint32(getMSTime()); // time - *data << m_positionX; - *data << m_positionY; - *data << m_positionZ; - *data << m_orientation; - *data << uint32(0); -} - -void WorldObject::BuildTeleportAckMsg(WorldPacket *data, float x, float y, float z, float ang) const -{ - //TeleportAck message cannot be used for non-units - if (!isType(TYPEMASK_UNIT)) - return; - - data->Initialize(MSG_MOVE_TELEPORT_ACK, 41); - data->append(GetPackGUID()); - *data << uint32(0); // this value increments every time - *data << uint32(((Unit*)this)->GetUnitMovementFlags()); // movement flags - *data << uint16(0); // 2.3.0 - *data << uint32(getMSTime()); // time - *data << x; - *data << y; - *data << z; - *data << ang; - *data << uint32(0); -} - void WorldObject::SendMessageToSet(WorldPacket *data, bool /*bToSelf*/) { //if object is in world, map for it already created! diff --git a/src/game/Object.h b/src/game/Object.h index 9e4ff7cf6..9e1cdcdd1 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -449,8 +449,6 @@ class MANGOS_DLL_SPEC WorldObject : public Object virtual void SendMessageToSet(WorldPacket *data, bool self); virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self); - void BuildHeartBeatMsg( WorldPacket *data ) const; - void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const; void MonsterSay(const char* text, uint32 language, uint64 TargetGuid); void MonsterYell(const char* text, uint32 language, uint64 TargetGuid); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 673ead2c7..22e94d137 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -449,9 +449,6 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_summon_y = 0.0f; m_summon_z = 0.0f; - //Default movement to run mode - m_unit_movement_flags = 0; - m_mover = this; m_miniPet = 0; @@ -1623,7 +1620,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati } // reset movement flags at teleport, because player will continue move with these flags after teleport - m_movementInfo.flags = 0; + m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE); if ((GetMapId() == mapid) && (!m_transport)) { @@ -17970,7 +17967,7 @@ void Player::SendInitialPacketsBeforeAddToMap() // 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()) - m_movementInfo.flags |= MOVEMENTFLAG_FLYING2; + m_movementInfo.AddMovementFlag(MOVEMENTFLAG_FLYING2); m_mover = this; } @@ -20321,3 +20318,18 @@ void Player::SendClearCooldown( uint32 spell_id, Unit* target ) data << uint64(target->GetGUID()); SendDirectMessage(&data); } + +void Player::BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang ) const +{ + data->Initialize(MSG_MOVE_TELEPORT_ACK, 41); + data->append(GetPackGUID()); + *data << uint32(0); // this value increments every time + *data << uint32(m_movementInfo.GetMovementFlags()); // movement flags + *data << uint16(0); // 2.3.0 + *data << uint32(getMSTime()); // time + *data << x; + *data << y; + *data << z; + *data << ang; + *data << uint32(0); +} \ No newline at end of file diff --git a/src/game/Player.h b/src/game/Player.h index 836eccb8b..af441a59f 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -687,10 +687,42 @@ enum InstanceResetWarningType RAID_INSTANCE_EXPIRED = 5 }; +// used in most movement packets (send and received) +enum MovementFlags +{ + MOVEMENTFLAG_NONE = 0x00000000, + MOVEMENTFLAG_FORWARD = 0x00000001, + MOVEMENTFLAG_BACKWARD = 0x00000002, + MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, + MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, + MOVEMENTFLAG_LEFT = 0x00000010, + MOVEMENTFLAG_RIGHT = 0x00000020, + MOVEMENTFLAG_PITCH_UP = 0x00000040, + MOVEMENTFLAG_PITCH_DOWN = 0x00000080, + MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking + MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures + MOVEMENTFLAG_LEVITATING = 0x00000400, + MOVEMENTFLAG_FLY_UNK1 = 0x00000800, + MOVEMENTFLAG_JUMPING = 0x00001000, + MOVEMENTFLAG_UNK4 = 0x00002000, + MOVEMENTFLAG_FALLING = 0x00004000, + // 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000 + MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also + MOVEMENTFLAG_FLY_UP = 0x00400000, + MOVEMENTFLAG_CAN_FLY = 0x00800000, + MOVEMENTFLAG_FLYING = 0x01000000, + MOVEMENTFLAG_FLYING2 = 0x02000000, // Actual flying mode + MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths + MOVEMENTFLAG_SPLINE2 = 0x08000000, // used for flight paths + MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water + MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive) + MOVEMENTFLAG_UNK3 = 0x40000000 +}; + struct MovementInfo { // common - uint32 flags; + uint32 flags; // see enum MovementFlags uint16 unk1; uint32 time; float x, y, z, o; @@ -710,16 +742,18 @@ struct MovementInfo MovementInfo() { - flags = 0; + flags = MOVEMENTFLAG_NONE; 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; } - uint32 GetMovementFlags() { return flags; } - void AddMovementFlag(uint32 flag) { flags |= flag; } - bool HasMovementFlag(uint32 flag) const { return flags & flag; } + void AddMovementFlag(MovementFlags f) { flags |= f; } + void RemoveMovementFlag(MovementFlags f) { flags &= ~f; } + bool HasMovementFlag(MovementFlags f) const { return flags & f; } + MovementFlags GetMovementFlags() const { return MovementFlags(flags); } + void SetMovementFlags(MovementFlags f) { flags = f; } }; // flags that use in movement check for example at spell casting @@ -1945,6 +1979,8 @@ class MANGOS_DLL_SPEC Player : public Unit } void HandleFall(MovementInfo const& movementInfo); + void BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, float ang) const; + bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); } bool isMovingOrTurning() const { return m_movementInfo.HasMovementFlag(movementOrTurningFlagsMask); } diff --git a/src/game/PointMovementGenerator.cpp b/src/game/PointMovementGenerator.cpp index 57d6f058b..19f596dd2 100644 --- a/src/game/PointMovementGenerator.cpp +++ b/src/game/PointMovementGenerator.cpp @@ -33,7 +33,7 @@ void PointMovementGenerator::Initialize(T &unit) i_destinationHolder.SetDestination(traveller,i_x,i_y,i_z); if (unit.GetTypeId() == TYPEID_UNIT && ((Creature*)&unit)->canFly()) - unit.AddUnitMovementFlag(MONSTER_MOVE_FLY); + ((Creature&)unit).AddMonsterMoveFlag(MONSTER_MOVE_FLY); } template diff --git a/src/game/RandomMovementGenerator.cpp b/src/game/RandomMovementGenerator.cpp index fcd9f7fc7..5cb713cbc 100644 --- a/src/game/RandomMovementGenerator.cpp +++ b/src/game/RandomMovementGenerator.cpp @@ -90,13 +90,13 @@ RandomMovementGenerator::_setRandomLocation(Creature &creature) if (is_air_ok) { i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); - creature.AddUnitMovementFlag(MONSTER_MOVE_FLY); + creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); } //else if (is_water_ok) // Swimming mode to be done with more than this check else { i_nextMoveTime.Reset(urand(500+i_destinationHolder.GetTotalTravelTime(),5000+i_destinationHolder.GetTotalTravelTime())); - creature.SetUnitMovementFlags(MONSTER_MOVE_WALK); + creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK); } } @@ -108,9 +108,13 @@ RandomMovementGenerator::Initialize(Creature &creature) return; if (creature.canFly()) - creature.AddUnitMovementFlag(MONSTER_MOVE_FLY); + creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); + + else if(irand(0,RUNNING_CHANCE_RANDOMMV) > 0) + creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK); else - creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MONSTER_MOVE_WALK : MONSTER_MOVE_NONE); + creature.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); // run with 1/RUNNING_CHANCE_RANDOMMV chance + _setRandomLocation(creature); } @@ -147,14 +151,17 @@ RandomMovementGenerator::Update(Creature &creature, const uint32 &diff if(i_nextMoveTime.Passed()) { if (creature.canFly()) - creature.AddUnitMovementFlag(MONSTER_MOVE_FLY); - else - creature.SetUnitMovementFlags(irand(0,RUNNING_CHANCE_RANDOMMV) > 0 ? MONSTER_MOVE_WALK : MONSTER_MOVE_NONE); + creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); + else if(irand(0,RUNNING_CHANCE_RANDOMMV) > 0) + creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK); + else // run with 1/RUNNING_CHANCE_RANDOMMV chance + creature.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); + _setRandomLocation(creature); } else if(creature.isPet() && creature.GetOwner() && !creature.IsWithinDist(creature.GetOwner(),PET_FOLLOW_DIST+2.5f)) { - creature.SetUnitMovementFlags(MONSTER_MOVE_WALK); + creature.AddMonsterMoveFlag(MONSTER_MOVE_WALK); _setRandomLocation(creature); } } diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 71351659f..51553cabb 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -2579,7 +2579,7 @@ void Spell::update(uint32 difftime) // check if the player caster has moved before the spell finished if ((m_caster->GetTypeId() == TYPEID_PLAYER && m_timer != 0) && (m_castPositionX != m_caster->GetPositionX() || m_castPositionY != m_caster->GetPositionY() || m_castPositionZ != m_caster->GetPositionZ()) && - (m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !m_caster->HasUnitMovementFlag(MOVEMENTFLAG_FALLING))) + (m_spellInfo->Effect[0] != SPELL_EFFECT_STUCK || !((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FALLING))) { // always cancel for channeled spells if( m_spellState == SPELL_STATE_CASTING ) @@ -2611,7 +2611,7 @@ void Spell::update(uint32 difftime) if( m_caster->GetTypeId() == TYPEID_PLAYER ) { // check if player has jumped before the channeling finished - if(m_caster->HasUnitMovementFlag(MOVEMENTFLAG_JUMPING)) + if(((Player*)m_caster)->m_movementInfo.HasMovementFlag(MOVEMENTFLAG_JUMPING)) cancel(); // check for incapacitating player states diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 442da5011..7ccc4eb5a 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3174,7 +3174,7 @@ void Aura::HandleModPossessPet(bool apply, bool Real) { pet->AttackStop(); pet->GetMotionMaster()->MoveFollow(caster, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - pet->SetUnitMovementFlags(MONSTER_MOVE_WALK); + pet->AddMonsterMoveFlag(MONSTER_MOVE_WALK); } } @@ -3415,10 +3415,10 @@ void Aura::HandleAuraModStun(bool apply, bool Real) // Creature specific if(m_target->GetTypeId() != TYPEID_PLAYER) - ((Creature*)m_target)->StopMoving(); + m_target->StopMoving(); else { - ((Player*)m_target)->m_movementInfo.flags = 0; // Clear movement flags + ((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE); m_target->SetStandState(UNIT_STAND_STATE_STAND);// in 1.5 client } @@ -3702,10 +3702,10 @@ void Aura::HandleAuraModRoot(bool apply, bool Real) m_target->SendMessageToSet(&data, true); //Clear unit movement flags - ((Player*)m_target)->m_movementInfo.flags = 0; + ((Player*)m_target)->m_movementInfo.SetMovementFlags(MOVEMENTFLAG_NONE); } else - ((Creature *)m_target)->StopMoving(); + m_target->StopMoving(); } else { diff --git a/src/game/TargetedMovementGenerator.cpp b/src/game/TargetedMovementGenerator.cpp index 6643f2a26..f33cbcfd6 100644 --- a/src/game/TargetedMovementGenerator.cpp +++ b/src/game/TargetedMovementGenerator.cpp @@ -85,24 +85,29 @@ TargetedMovementGenerator::_setTargetLocation(T &owner) i_destinationHolder.SetDestination(traveller, x, y, z); owner.addUnitState(UNIT_STAT_CHASE); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) - owner.AddUnitMovementFlag(MONSTER_MOVE_FLY); + ((Creature&)owner).AddMonsterMoveFlag(MONSTER_MOVE_FLY); } -template -void -TargetedMovementGenerator::Initialize(T &owner) +template<> +void TargetedMovementGenerator::Initialize(Creature &owner) { - if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->HasSearchedAssistance()) - owner.AddUnitMovementFlag(MONSTER_MOVE_WALK); + if (owner.HasSearchedAssistance()) + owner.AddMonsterMoveFlag(MONSTER_MOVE_WALK); else - owner.RemoveUnitMovementFlag(MONSTER_MOVE_WALK); + owner.RemoveMonsterMoveFlag(MONSTER_MOVE_WALK); - if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) - owner.AddUnitMovementFlag(MONSTER_MOVE_FLY); + if (((Creature*)&owner)->canFly()) + owner.AddMonsterMoveFlag(MONSTER_MOVE_FLY); _setTargetLocation(owner); } +template<> +void TargetedMovementGenerator::Initialize(Player &owner) +{ + _setTargetLocation(owner); +} + template void TargetedMovementGenerator::Finalize(T &owner) @@ -150,7 +155,7 @@ TargetedMovementGenerator::Update(T &owner, const uint32 & time_diff) { owner.addUnitState(UNIT_STAT_CHASE); if (owner.GetTypeId() == TYPEID_UNIT && ((Creature*)&owner)->canFly()) - owner.AddUnitMovementFlag(MONSTER_MOVE_FLY); + ((Creature&)owner).AddMonsterMoveFlag(MONSTER_MOVE_FLY); i_destinationHolder.StartTravel(traveller); return true; @@ -199,8 +204,6 @@ TargetedMovementGenerator::GetTarget() const template void TargetedMovementGenerator::_setTargetLocation(Player &); template void TargetedMovementGenerator::_setTargetLocation(Creature &); -template void TargetedMovementGenerator::Initialize(Player &); -template void TargetedMovementGenerator::Initialize(Creature &); template void TargetedMovementGenerator::Finalize(Player &); template void TargetedMovementGenerator::Finalize(Creature &); template void TargetedMovementGenerator::Reset(Player &); diff --git a/src/game/Traveller.h b/src/game/Traveller.h index 0e98d8c0d..deb453dfa 100644 --- a/src/game/Traveller.h +++ b/src/game/Traveller.h @@ -71,9 +71,9 @@ inline uint32 Traveller::GetTotalTrevelTimeTo(float x, float y, float z) template<> inline float Traveller::Speed() { - if(i_traveller.HasUnitMovementFlag(MONSTER_MOVE_WALK)) + if(i_traveller.HasMonsterMoveFlag(MONSTER_MOVE_WALK)) return i_traveller.GetSpeed(MOVE_WALK); - else if(i_traveller.HasUnitMovementFlag(MONSTER_MOVE_FLY)) + else if(i_traveller.HasMonsterMoveFlag(MONSTER_MOVE_FLY)) return i_traveller.GetSpeed(MOVE_FLIGHT); else return i_traveller.GetSpeed(MOVE_RUN); @@ -102,7 +102,7 @@ inline float Traveller::GetMoveDestinationTo(float x, float y, float z template<> inline void Traveller::MoveTo(float x, float y, float z, uint32 t) { - i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetUnitMovementFlags(), 0); + i_traveller.AI_SendMoveToPacket(x, y, z, t, i_traveller.GetMonsterMoveFlags(), 0); } // specialization for players diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index e0196c9d2..697367c53 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -150,7 +150,6 @@ Unit::Unit() m_removedAuras = 0; m_charmInfo = NULL; - m_unit_movement_flags = 0; // remove aurastates allowing special moves for(int i=0; i < MAX_REACTIVE; ++i) @@ -229,33 +228,7 @@ bool Unit::haveOffhandWeapon() const return false; } -void Unit::SendMonsterMoveWithSpeedToCurrentDestination(Player* player) -{ - float x, y, z; - if(GetMotionMaster()->GetDestination(x, y, z)) - SendMonsterMoveWithSpeed(x, y, z, 0, player); -} - -void Unit::SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime, Player* player) -{ - if (!transitTime) - { - if(GetTypeId()==TYPEID_PLAYER) - { - Traveller traveller(*(Player*)this); - transitTime = traveller.GetTotalTrevelTimeTo(x,y,z); - } - else - { - Traveller traveller(*(Creature*)this); - transitTime = traveller.GetTotalTrevelTimeTo(x,y,z); - } - } - //float orientation = (float)atan2((double)dy, (double)dx); - SendMonsterMove(x, y, z, 0, GetUnitMovementFlags(), transitTime, player); -} - -void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player) +void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, MonsterMovementFlags flags, uint32 Time, Player* player) { float moveTime = Time; @@ -286,9 +259,9 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 ty break; } - data << uint32(MovementFlags); + data << uint32(flags); - if(MovementFlags & MONSTER_MOVE_WALK) + if(flags & MONSTER_MOVE_WALK) moveTime *= 1.05f; data << uint32(moveTime); // Time in between points @@ -301,7 +274,7 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 ty SendMessageToSet( &data, true ); } -void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags) +void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, MonsterMovementFlags flags) { uint32 traveltime = uint32(path.GetTotalLength(start, end) * 32); @@ -314,14 +287,32 @@ void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uin data << GetPositionY(); data << GetPositionZ(); data << uint32(getMSTime()); - data << uint8( 0 ); - data << uint32( MovementFlags ); - data << uint32( traveltime ); - data << uint32( pathSize ); - data.append( (char*)path.GetNodes(start), pathSize * 4 * 3 ); + data << uint8(0); + data << uint32(flags); + data << uint32(traveltime); + data << uint32(pathSize); + data.append((char*)path.GetNodes(start), pathSize * 4 * 3); SendMessageToSet(&data, true); } +void Unit::BuildHeartBeatMsg(WorldPacket *data) const +{ + MovementFlags move_flags = GetTypeId()==TYPEID_PLAYER + ? ((Player const*)this)->m_movementInfo.GetMovementFlags() + : MOVEMENTFLAG_NONE; + + data->Initialize(MSG_MOVE_HEARTBEAT, 32); + data->append(GetPackGUID()); + *data << uint32(move_flags); // movement flags + *data << uint16(0); // 2.3.0 + *data << uint32(getMSTime()); // time + *data << float(GetPositionX()); + *data << float(GetPositionY()); + *data << float(GetPositionZ()); + *data << float(GetOrientation()); + *data << uint32(0); +} + void Unit::resetAttackTimer(WeaponAttackType type) { m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); @@ -11726,8 +11717,6 @@ void Unit::NearTeleportTo( float x, float y, float z, float orientation, bool ca GetMap()->CreatureRelocation((Creature*)this, x, y, z, orientation); WorldPacket data; - // Work strange for many spells: triggered active mover set for targeted player to creature - //BuildTeleportAckMsg(&data, x, y, z, orientation); BuildHeartBeatMsg(&data); SendMessageToSet(&data, false); } diff --git a/src/game/Unit.h b/src/game/Unit.h index 081b71e41..4b4b27d34 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -566,37 +566,7 @@ enum NPCFlags UNIT_NPC_FLAG_GUARD = 0x10000000, // custom flag for guards }; -enum MovementFlags -{ - MOVEMENTFLAG_NONE = 0x00000000, - MOVEMENTFLAG_FORWARD = 0x00000001, - MOVEMENTFLAG_BACKWARD = 0x00000002, - MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, - MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, - MOVEMENTFLAG_LEFT = 0x00000010, - MOVEMENTFLAG_RIGHT = 0x00000020, - MOVEMENTFLAG_PITCH_UP = 0x00000040, - MOVEMENTFLAG_PITCH_DOWN = 0x00000080, - MOVEMENTFLAG_WALK_MODE = 0x00000100, // Walking - MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures - MOVEMENTFLAG_LEVITATING = 0x00000400, - MOVEMENTFLAG_FLY_UNK1 = 0x00000800, - MOVEMENTFLAG_JUMPING = 0x00001000, - MOVEMENTFLAG_UNK4 = 0x00002000, - MOVEMENTFLAG_FALLING = 0x00004000, - // 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000 - MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also - MOVEMENTFLAG_FLY_UP = 0x00400000, - MOVEMENTFLAG_CAN_FLY = 0x00800000, - MOVEMENTFLAG_FLYING = 0x01000000, - MOVEMENTFLAG_FLYING2 = 0x02000000, // Actual flying mode - MOVEMENTFLAG_SPLINE = 0x04000000, // used for flight paths - MOVEMENTFLAG_SPLINE2 = 0x08000000, // used for flight paths - MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water - MOVEMENTFLAG_SAFE_FALL = 0x20000000, // active rogue safe fall spell (passive) - MOVEMENTFLAG_UNK3 = 0x40000000 -}; - +// used in SMSG_MONSTER_MOVE enum MonsterMovementFlags { MONSTER_MOVE_NONE = 0x00000000, @@ -1143,10 +1113,10 @@ class MANGOS_DLL_SPEC Unit : public WorldObject void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false); - void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); - void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, uint32 MovementFlags); - void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); - void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); + void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, MonsterMovementFlags flags, uint32 Time, Player* player = NULL); + void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end, MonsterMovementFlags flags); + + void BuildHeartBeatMsg( WorldPacket *data ) const; virtual void MoveOutOfRange(Player &) { }; @@ -1474,16 +1444,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject bool IsStopped() const { return !(hasUnitState(UNIT_STAT_MOVING)); } void StopMoving(); - void AddUnitMovementFlag(uint32 f) { m_unit_movement_flags |= f; } - void RemoveUnitMovementFlag(uint32 f) - { - uint32 oldval = m_unit_movement_flags; - m_unit_movement_flags = oldval & ~f; - } - uint32 HasUnitMovementFlag(uint32 f) const { return m_unit_movement_flags & f; } - uint32 GetUnitMovementFlags() const { return m_unit_movement_flags; } - void SetUnitMovementFlags(uint32 f) { m_unit_movement_flags = f; } - void SetFeared(bool apply, uint64 casterGUID = 0, uint32 spellID = 0, uint32 time = 0); void SetConfused(bool apply, uint64 casterGUID = 0, uint32 spellID = 0); @@ -1558,7 +1518,6 @@ class MANGOS_DLL_SPEC Unit : public WorldObject virtual SpellSchoolMask GetMeleeDamageSchoolMask() const; MotionMaster i_motionMaster; - uint32 m_unit_movement_flags; uint32 m_reactiveTimer[MAX_REACTIVE]; uint32 m_regenTimer; diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cpp index 3ee796ed6..874fadf79 100644 --- a/src/game/WaypointMovementGenerator.cpp +++ b/src/game/WaypointMovementGenerator.cpp @@ -110,7 +110,7 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 // Now we re-set destination to same node and start travel creature.addUnitState(UNIT_STAT_ROAMING); if (creature.canFly()) - creature.AddUnitMovementFlag(MONSTER_MOVE_FLY); + creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); @@ -173,7 +173,7 @@ bool WaypointMovementGenerator::Update(Creature &creature, const uint3 { creature.addUnitState(UNIT_STAT_ROAMING); if (creature.canFly()) - creature.AddUnitMovementFlag(MONSTER_MOVE_FLY); + creature.AddMonsterMoveFlag(MONSTER_MOVE_FLY); const WaypointNode &node = i_path->at(i_currentNode); i_destinationHolder.SetDestination(traveller, node.x, node.y, node.z); i_nextMoveTime.Reset(i_destinationHolder.GetTotalTravelTime()); diff --git a/src/game/World.cpp b/src/game/World.cpp index 1bfe54577..87b06e7b8 100644 --- a/src/game/World.cpp +++ b/src/game/World.cpp @@ -1821,8 +1821,8 @@ void World::ScriptsProcess() sLog.outError("SCRIPT_COMMAND_MOVE_TO call for non-creature (TypeId: %u), skipping.",source->GetTypeId()); break; } - ((Unit *)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 ); - ((Unit *)source)->GetMap()->CreatureRelocation(((Creature *)source), step.script->x, step.script->y, step.script->z, 0); + ((Creature*)source)->SendMonsterMoveWithSpeed(step.script->x, step.script->y, step.script->z, step.script->datalong2 ); + ((Creature*)source)->GetMap()->CreatureRelocation(((Creature*)source), step.script->x, step.script->y, step.script->z, 0); break; case SCRIPT_COMMAND_FLAG_SET: if(!source) diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index 7279352f2..f0d11f587 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -635,7 +635,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) data >> mi->z; data >> mi->o; - if(mi->flags & MOVEMENTFLAG_ONTRANSPORT) + if(mi->HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) { if(!data.readPackGUID(mi->t_guid)) return; @@ -649,7 +649,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) data >> mi->t_seat; } - if((mi->flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2)) || (mi->unk1 & 0x20)) + if((mi->HasMovementFlag(MovementFlags(MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_FLYING2))) || (mi->unk1 & 0x20)) { CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->s_pitch; @@ -658,7 +658,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->fallTime; - if(mi->flags & MOVEMENTFLAG_JUMPING) + if(mi->HasMovementFlag(MOVEMENTFLAG_JUMPING)) { CHECK_PACKET_SIZE(data, data.rpos()+4+4+4+4); data >> mi->j_unk; @@ -667,7 +667,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo *mi) data >> mi->j_xyspeed; } - if(mi->flags & MOVEMENTFLAG_SPLINE) + if(mi->HasMovementFlag(MOVEMENTFLAG_SPLINE)) { CHECK_PACKET_SIZE(data, data.rpos()+4); data >> mi->u_unk1; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 958440da3..97c16489c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8076" + #define REVISION_NR "8077" #endif // __REVISION_NR_H__ From 2719ae2efa428b28efaf2dab3aaa617545ca0be2 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 26 Jun 2009 04:01:31 +0400 Subject: [PATCH 05/36] [8078] Fixed typos in character data loading after recently added new field. * Really use race/class/gender fields instead `data` field values. * Load extra flags (gm mode onm gm fly mode, gm invisibility and etc) from proper field. NOTE: recommedned reset characters.extra_flags field to 0 for all characters. It can be corrupted in time login/logout before this fix. --- src/game/Player.cpp | 17 ++++++++++++----- src/game/Player.h | 1 + src/shared/revision_nr.h | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 22e94d137..0124177f7 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -13942,9 +13942,11 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) // overwrite some data fields uint32 bytes0 = GetUInt32Value(UNIT_FIELD_BYTES_0) & 0xFF000000; - bytes0 |= fields[4].GetUInt8(); - bytes0 |= fields[5].GetUInt8() << 8; - bytes0 |= fields[6].GetUInt8() << 16; + bytes0 |= fields[4].GetUInt8(); // race + bytes0 |= fields[5].GetUInt8() << 8; // class + bytes0 |= fields[6].GetUInt8() << 16; // gender + SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0); + SetUInt32Value(UNIT_FIELD_LEVEL, fields[7].GetUInt8()); SetUInt32Value(PLAYER_XP, fields[8].GetUInt32()); SetUInt32Value(PLAYER_FIELD_COINAGE, fields[9].GetUInt32()); @@ -14205,7 +14207,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) //speed collect rest bonus in offline, in logout, in tavern, city (section/in hour) float bubble1 = 0.125; - if((int32)fields[23].GetUInt32() > 0) + if(time_diff > 0) { float bubble = fields[24].GetUInt32() > 0 ? bubble1*sWorld.getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY) @@ -14229,7 +14231,7 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder ) m_taxi.LoadTaxiMask( fields[18].GetString() ); // must be before InitTaxiNodesForLevel - uint32 extraflags = fields[25].GetUInt32(); + uint32 extraflags = fields[32].GetUInt32(); m_stableSlots = fields[33].GetUInt32(); if(m_stableSlots > MAX_PET_STABLES) @@ -20332,4 +20334,9 @@ void Player::BuildTeleportAckMsg( WorldPacket *data, float x, float y, float z, *data << z; *data << ang; *data << uint32(0); +} + +bool Player::HasMovementFlag( MovementFlags f ) const +{ + return m_movementInfo.HasMovementFlag(f); } \ No newline at end of file diff --git a/src/game/Player.h b/src/game/Player.h index af441a59f..8222060a3 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1970,6 +1970,7 @@ class MANGOS_DLL_SPEC Player : public Unit /*** VARIOUS SYSTEMS ***/ /*********************************************************/ MovementInfo m_movementInfo; + bool HasMovementFlag(MovementFlags f) const; // for script access to m_movementInfo.HasMovementFlag void UpdateFallInformationIfNeed(MovementInfo const& minfo,uint16 opcode); Unit *m_mover; void SetFallInformation(uint32 time, float z) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 97c16489c..714dddb03 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8077" + #define REVISION_NR "8078" #endif // __REVISION_NR_H__ From 95ce1eed1ceab6d8f7bca8298d27df344f1a3200 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Fri, 26 Jun 2009 23:23:26 +0400 Subject: [PATCH 06/36] [8079] Fixed build errors at use old ACE versions (without ace/Stack_Trace.h). --- configure.ac | 2 ++ src/shared/Errors.h | 14 +++++++++++++- src/shared/revision_nr.h | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 3111eacb2..7a1b219ec 100644 --- a/configure.ac +++ b/configure.ac @@ -228,6 +228,8 @@ fi AM_CONDITIONAL([MANGOS_BUILD_ACE], [test X$need_to_build_ace = Xyes]) +# old ace versions not have ace/Stack_Trace.h +AC_CHECK_HEADERS([ace/Stack_Trace.h]) ## Unify all additional includes/libs in one variable. # TODO this looks kinda ugly, but when we add m4 folder I will make it look very pritey ( by Derex ). diff --git a/src/shared/Errors.h b/src/shared/Errors.h index 7dd9dc52d..01d504229 100644 --- a/src/shared/Errors.h +++ b/src/shared/Errors.h @@ -19,9 +19,21 @@ #ifndef MANGOSSERVER_ERRORS_H #define MANGOSSERVER_ERRORS_H -#include "ace/Stack_Trace.h" +#include "Common.h" +#ifndef HAVE_CONFIG_H +#define HAVE_ACE_STACK_TRACE_H 1 +#endif + +#ifdef HAVE_ACE_STACK_TRACE_H +#include "ace/Stack_Trace.h" +#endif + +#ifdef HAVE_ACE_STACK_TRACE_H // old versions ACE not have Stack_Trace.h but used at some oS for better compatibility #define WPAssert( assertion ) { if (!(assertion)) { ACE_Stack_Trace st; fprintf( stderr, "\n%s:%i in %s ASSERTION FAILED:\n %s\n%s\n", __FILE__, __LINE__,__FUNCTION__, #assertion, st.c_str()); assert( #assertion &&0 ); } } +#else +#define WPAssert( assertion ) { if (!(assertion)) { fprintf( stderr, "\n%s:%i in %s ASSERTION FAILED2:\n %s\n", __FILE__, __LINE__,__FUNCTION__, #assertion); assert( #assertion &&0 ); } } +#endif #define WPError( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "%\n%s:%i in %s ERROR:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); assert( false ); } #define WPWarning( assertion, errmsg ) if( ! (assertion) ) { sLog.outError( "\n%s:%i in %s WARNING:\n %s\n", __FILE__, __LINE__, __FUNCTION__, (char *)errmsg ); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 714dddb03..a2a499339 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8078" + #define REVISION_NR "8079" #endif // __REVISION_NR_H__ From a7d9ace55f632be6be955f5bc5587877de52a4ec Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 27 Jun 2009 02:19:37 +0400 Subject: [PATCH 07/36] [8080] Portability fixes for some Unix platforms. * Add #include to some fiels where related functions call. * Avoid template dependent lookup for fields in class LockedQueue. --- dep/src/sockets/SocketHandler.cpp | 1 + dep/src/sockets/StdoutLog.cpp | 2 + dep/src/sockets/TcpSocket.cpp | 1 + src/shared/LockedQueue.h | 53 ++++++++++----------------- src/shared/revision_nr.h | 2 +- src/shared/vmap/CoordModelMapping.cpp | 8 ++++ src/shared/vmap/CoordModelMapping.h | 7 +--- src/shared/vmap/DebugCmdLogger.cpp | 1 + 8 files changed, 34 insertions(+), 41 deletions(-) diff --git a/dep/src/sockets/SocketHandler.cpp b/dep/src/sockets/SocketHandler.cpp index 9ec5412af..f2a4f7c30 100644 --- a/dep/src/sockets/SocketHandler.cpp +++ b/dep/src/sockets/SocketHandler.cpp @@ -33,6 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #endif #endif #include +#include #include #include "SocketHandler.h" diff --git a/dep/src/sockets/StdoutLog.cpp b/dep/src/sockets/StdoutLog.cpp index c01d8b8c2..f9251c326 100644 --- a/dep/src/sockets/StdoutLog.cpp +++ b/dep/src/sockets/StdoutLog.cpp @@ -27,6 +27,8 @@ 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 + #ifdef _MSC_VER #pragma warning(disable:4786) #endif diff --git a/dep/src/sockets/TcpSocket.cpp b/dep/src/sockets/TcpSocket.cpp index 36df37d58..64bb1009e 100644 --- a/dep/src/sockets/TcpSocket.cpp +++ b/dep/src/sockets/TcpSocket.cpp @@ -39,6 +39,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include #include #include +#include #ifdef HAVE_OPENSSL #include #include diff --git a/src/shared/LockedQueue.h b/src/shared/LockedQueue.h index 5109b1716..4087ebff0 100644 --- a/src/shared/LockedQueue.h +++ b/src/shared/LockedQueue.h @@ -27,11 +27,9 @@ namespace ACE_Based { - template > class LockedQueue { - //! Serialize access to the Queue LockType _lock; @@ -54,14 +52,12 @@ namespace ACE_Based */ void add(const T& item) { + ACE_Guard g(this->_lock); - ACE_Guard g(_lock); - - ASSERT(!_canceled); + ASSERT(!this->_canceled); // throw Cancellation_Exception(); - _queue.push_back(item); - + this->_queue.push_back(item); } /** @@ -69,27 +65,25 @@ namespace ACE_Based */ T next() { + ACE_Guard g(this->_lock); - ACE_Guard g(_lock); - - ASSERT (!_queue.empty() || !_canceled); + ASSERT (!_queue.empty() || !this->_canceled); // throw Cancellation_Exception(); - T item = _queue.front(); - _queue.pop_front(); + T item = this->_queue.front(); + this->_queue.pop_front(); return item; - } T front() { - ACE_Guard g(_lock); + ACE_Guard g(this->_lock); - ASSERT (!_queue.empty()); + ASSERT (!this->_queue.empty()); // throw NoSuchElement_Exception(); - return _queue.front(); + return this->_queue.front(); } /** @@ -97,11 +91,9 @@ namespace ACE_Based */ void cancel() { + ACE_Guard g(this->_lock); - ACE_Guard g(_lock); - - _canceled = true; - + this->_canceled = true; } /** @@ -109,15 +101,13 @@ namespace ACE_Based */ bool isCanceled() { - // Faster check since the queue will not become un-canceled - if(_canceled) + if(this->_canceled) return true; - ACE_Guard g(_lock); - - return _canceled; + ACE_Guard g(this->_lock); + return this->_canceled; } /** @@ -125,20 +115,15 @@ namespace ACE_Based */ size_t size() { - - ACE_Guard g(_lock); - return _queue.size(); - + ACE_Guard g(this->_lock); + return this->_queue.size(); } bool empty() { - - ACE_Guard g(_lock); - return _queue.empty(); + ACE_Guard g(this->_lock); + return this->_queue.empty(); } - }; - } #endif diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a2a499339..ce69da771 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8079" + #define REVISION_NR "8080" #endif // __REVISION_NR_H__ diff --git a/src/shared/vmap/CoordModelMapping.cpp b/src/shared/vmap/CoordModelMapping.cpp index 23b89fefd..4b4dc50c9 100644 --- a/src/shared/vmap/CoordModelMapping.cpp +++ b/src/shared/vmap/CoordModelMapping.cpp @@ -19,6 +19,7 @@ #include "CoordModelMapping.h" #include +#include using namespace G3D; @@ -42,6 +43,13 @@ namespace VMAP return(CMappingEntry::getKeyString(iMapId,xPos, yPos)); } + const std::string CMappingEntry::getKeyString( unsigned int pMapId, int pXPos, int pYPos ) + { + char b[100]; + sprintf(b,"%03u_%d_%d", pMapId, pXPos, pYPos); + return(std::string(b)); + } + //============================================================ //============================================================ //============================================================ diff --git a/src/shared/vmap/CoordModelMapping.h b/src/shared/vmap/CoordModelMapping.h index 71b516311..0200caaa7 100644 --- a/src/shared/vmap/CoordModelMapping.h +++ b/src/shared/vmap/CoordModelMapping.h @@ -72,12 +72,7 @@ namespace VMAP const std::string getKeyString() const; inline const G3D::Array& getFilenames() const { return(iFilenames); } - static const std::string getKeyString(unsigned int pMapId, int pXPos, int pYPos) - { - char b[100]; - sprintf(b,"%03u_%d_%d", pMapId, pXPos, pYPos); - return(std::string(b)); - } + static const std::string getKeyString(unsigned int pMapId, int pXPos, int pYPos); }; diff --git a/src/shared/vmap/DebugCmdLogger.cpp b/src/shared/vmap/DebugCmdLogger.cpp index 080afa3fb..036149977 100644 --- a/src/shared/vmap/DebugCmdLogger.cpp +++ b/src/shared/vmap/DebugCmdLogger.cpp @@ -17,6 +17,7 @@ */ #include "DebugCmdLogger.h" +#include using namespace G3D; From 1b085414abaadc672853cd5fe4566f21cab4091a Mon Sep 17 00:00:00 2001 From: Ambient Date: Sat, 27 Jun 2009 05:57:29 +0400 Subject: [PATCH 08/36] [8081] Remove player only targeting limitation for spell 25899, 20911 for triggering part. Signed-off-by: VladimirMangos --- src/game/Unit.cpp | 3 --- src/shared/revision_nr.h | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 697367c53..d2ac9c314 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -5552,9 +5552,6 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, Aura* triggeredByAu case 25899: // Greater Blessing of Sanctuary case 20911: // Blessing of Sanctuary { - if (target->GetTypeId() != TYPEID_PLAYER) - return false; - target = this; switch (target->getPowerType()) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index ce69da771..213a1074d 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8080" + #define REVISION_NR "8081" #endif // __REVISION_NR_H__ From df064ebd9f5b6d3fd0aeacdd328ee010cf54deb3 Mon Sep 17 00:00:00 2001 From: Lightguard Date: Sat, 27 Jun 2009 11:31:22 +0400 Subject: [PATCH 09/36] [8082] Update Diminishing Returns. Signed-off-by: VladimirMangos --- src/game/SharedDefines.h | 16 +++--- src/game/SpellEffects.cpp | 3 +- src/game/SpellMgr.cpp | 111 ++++++++++++++++++++++++-------------- src/game/SpellMgr.h | 1 + src/game/Unit.cpp | 6 +-- src/game/Unit.h | 2 +- src/shared/revision_nr.h | 2 +- 7 files changed, 86 insertions(+), 55 deletions(-) diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index ffa61ecd5..d98938cf2 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -2321,24 +2321,20 @@ enum DiminishingGroup DIMINISHING_NONE, DIMINISHING_CONTROL_STUN, // Player Controlled stuns DIMINISHING_TRIGGER_STUN, // By aura proced stuns, usualy chance on hit talents - DIMINISHING_SLEEP, DIMINISHING_CONTROL_ROOT, // Immobilizing effects from casted spells DIMINISHING_TRIGGER_ROOT, // Immobilizing effects from triggered spells like Frostbite - DIMINISHING_FEAR, // Non-warlock fears + DIMINISHING_FEAR_BLIND, // Fears & blind DIMINISHING_CHARM, - // Mage Specific - DIMINISHING_POLYMORPH, - // Rogue Specific - DIMINISHING_KIDNEYSHOT, // Kidney Shot is not diminished with Cheap Shot + DIMINISHING_POLYMORPH_GOUGE_SAP, // Warlock Specific DIMINISHING_DEATHCOIL, // Death Coil Diminish only with another Death Coil - DIMINISHING_WARLOCK_FEAR, // Also with Sedduction + // Druid Specific + DIMINISHING_CYCLONE, // From 2.3.0 // Shared Class Specific - DIMINISHING_BLIND_CYCLONE, // From 2.3.0 + DIMINISHING_CHEAPSHOT_POUNCE, DIMINISHING_DISARM, // From 2.3.0 DIMINISHING_SILENCE, // From 2.3.0 - DIMINISHING_FREEZE, // Hunter's Freezing Trap - DIMINISHING_KNOCKOUT, // Also with Sap, all Knockout mechanics are here + DIMINISHING_FREEZE_SLEEP, // Hunter's Freezing Trap DIMINISHING_BANISH, // Other // Don't Diminish, but limit duration to 10s diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 957c20506..23020ca16 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -2280,7 +2280,8 @@ void Spell::EffectApplyAura(uint32 i) // Now Reduce spell duration using data received at spell hit int32 duration = Aur->GetAuraMaxDuration(); - unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel); + int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,m_spellInfo); + unitTarget->ApplyDiminishingToDuration(m_diminishGroup, duration, m_caster, m_diminishLevel,limitduration); Aur->setDiminishGroup(m_diminishGroup); // if Aura removed and deleted, do not continue. diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index d40864c9c..ec21bb044 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2717,36 +2717,32 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto { case SPELLFAMILY_ROGUE: { - // Kidney Shot - if (spellproto->SpellFamilyFlags & UI64LIT(0x00000200000)) - return DIMINISHING_KIDNEYSHOT; // Blind - else if (spellproto->SpellFamilyFlags & UI64LIT(0x00001000000)) - return DIMINISHING_BLIND_CYCLONE; - break; - } - case SPELLFAMILY_HUNTER: - { - // Freezing trap - if (spellproto->SpellFamilyFlags & UI64LIT(0x00000000008)) - return DIMINISHING_FREEZE; + if (spellproto->SpellFamilyFlags & UI64LIT(0x00001000000)) + return DIMINISHING_FEAR_BLIND; + // Cheap Shot + else if (spellproto->SpellFamilyFlags & UI64LIT(0x00000000400)) + return DIMINISHING_CHEAPSHOT_POUNCE; break; } case SPELLFAMILY_WARLOCK: { - // Fear - if (spellproto->SpellFamilyFlags & UI64LIT(0x40840000000)) - return DIMINISHING_WARLOCK_FEAR; // Curses/etc - else if (spellproto->SpellFamilyFlags & UI64LIT(0x00080000000)) + if (spellproto->SpellFamilyFlags & UI64LIT(0x00080000000)) return DIMINISHING_LIMITONLY; + // Seduction + else if (spellproto->SpellFamilyFlags & UI64LIT(0x00040000000)) + return DIMINISHING_CHARM; break; } case SPELLFAMILY_DRUID: { // Cyclone if (spellproto->SpellFamilyFlags & UI64LIT(0x02000000000)) - return DIMINISHING_BLIND_CYCLONE; + return DIMINISHING_CYCLONE; + // Pounce + else if (spellproto->SpellFamilyFlags & UI64LIT(0x00000020000)) + return DIMINISHING_CHEAPSHOT_POUNCE; break; } case SPELLFAMILY_WARRIOR: @@ -2756,6 +2752,20 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto return DIMINISHING_LIMITONLY; break; } + case SPELLFAMILY_PALADIN: + { + // Turn Evil + if (spellproto->SpellFamilyFlags & UI64LIT(0x00804000000000)) + return DIMINISHING_FEAR_BLIND; + break; + } + case SPELLFAMILY_DEATHKNIGHT: + { + // Hungering Cold (no flags) + if (spellproto->SpellIconID == 2797) + return DIMINISHING_POLYMORPH_GOUGE_SAP; + break; + } default: break; } @@ -2764,15 +2774,15 @@ DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto uint32 mechanic = GetAllSpellMechanicMask(spellproto); if (mechanic == MECHANIC_NONE) return DIMINISHING_NONE; if (mechanic & (1<SpellFamilyName) + { + case SPELLFAMILY_HUNTER: + { + // Wyvern Sting + if (spellproto->SpellFamilyFlags & UI64LIT(0x0000100000000000)) + return 6000; + break; + } + case SPELLFAMILY_PALADIN: + { + // Repentance - limit to 6 seconds in PvP + if (spellproto->SpellFamilyFlags & UI64LIT(0x00000000004)) + return 6000; + break; + } + default: + break; + } + + return 10000; +} + bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group) { switch(group) { case DIMINISHING_CONTROL_STUN: case DIMINISHING_TRIGGER_STUN: - case DIMINISHING_KIDNEYSHOT: - case DIMINISHING_SLEEP: case DIMINISHING_CONTROL_ROOT: case DIMINISHING_TRIGGER_ROOT: - case DIMINISHING_FEAR: - case DIMINISHING_WARLOCK_FEAR: + case DIMINISHING_FEAR_BLIND: case DIMINISHING_CHARM: - case DIMINISHING_POLYMORPH: - case DIMINISHING_FREEZE: - case DIMINISHING_KNOCKOUT: - case DIMINISHING_BLIND_CYCLONE: + case DIMINISHING_POLYMORPH_GOUGE_SAP: + case DIMINISHING_CHEAPSHOT_POUNCE: + case DIMINISHING_FREEZE_SLEEP: + case DIMINISHING_CYCLONE: case DIMINISHING_BANISH: case DIMINISHING_LIMITONLY: return true; @@ -2810,24 +2846,21 @@ DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group) { switch(group) { - case DIMINISHING_BLIND_CYCLONE: - case DIMINISHING_CONTROL_STUN: + case DIMINISHING_CYCLONE: case DIMINISHING_TRIGGER_STUN: - case DIMINISHING_KIDNEYSHOT: + case DIMINISHING_CONTROL_STUN: + case DIMINISHING_CHEAPSHOT_POUNCE: return DRTYPE_ALL; - case DIMINISHING_SLEEP: case DIMINISHING_CONTROL_ROOT: case DIMINISHING_TRIGGER_ROOT: - case DIMINISHING_FEAR: + case DIMINISHING_FEAR_BLIND: case DIMINISHING_CHARM: - case DIMINISHING_POLYMORPH: + case DIMINISHING_POLYMORPH_GOUGE_SAP: case DIMINISHING_SILENCE: case DIMINISHING_DISARM: case DIMINISHING_DEATHCOIL: - case DIMINISHING_FREEZE: + case DIMINISHING_FREEZE_SLEEP: case DIMINISHING_BANISH: - case DIMINISHING_WARLOCK_FEAR: - case DIMINISHING_KNOCKOUT: return DRTYPE_PLAYER; default: break; diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 69ccc5485..71c8535ef 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -333,6 +333,7 @@ inline uint32 GetDispellMask(DispelType dispel) DiminishingGroup GetDiminishingReturnsGroupForSpell(SpellEntry const* spellproto, bool triggered); bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group); DiminishingReturnsType GetDiminishingReturnsGroupType(DiminishingGroup group); +int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellEntry const* spellproto); // Spell affects related declarations (accessed using SpellMgr functions) struct SpellAffectEntry diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index d2ac9c314..5ddca82d2 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -9847,13 +9847,13 @@ void Unit::IncrDiminishing(DiminishingGroup group) m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2)); } -void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level) +void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level, int32 limitduration) { if(duration == -1 || group == DIMINISHING_NONE || caster->IsFriendlyTo(this) ) return; // Duration of crowd control abilities on pvp target is limited by 10 sec. (2.2.0) - if(duration > 10000 && IsDiminishingReturnsGroupDurationLimited(group)) + if(limitduration > 0 && duration > limitduration) { // test pet/charm masters instead pets/charmeds Unit const* targetOwner = GetCharmerOrOwner(); @@ -9863,7 +9863,7 @@ void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Un Unit const* source = casterOwner ? casterOwner : caster; if(target->GetTypeId() == TYPEID_PLAYER && source->GetTypeId() == TYPEID_PLAYER) - duration = 10000; + duration = limitduration; } float mod = 1.0f; diff --git a/src/game/Unit.h b/src/game/Unit.h index 4b4b27d34..b2b4704ae 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -856,7 +856,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject DiminishingLevels GetDiminishing(DiminishingGroup group); void IncrDiminishing(DiminishingGroup group); - void ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level); + void ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level, int32 limitduration); void ApplyDiminishingAura(DiminishingGroup group, bool apply); void ClearDiminishings() { m_Diminishing.clear(); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 213a1074d..62a8a35f7 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8081" + #define REVISION_NR "8082" #endif // __REVISION_NR_H__ From 97721109ff9c0b01c030bcdf39ac3ee8d760693f Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sat, 27 Jun 2009 23:57:51 +0400 Subject: [PATCH 10/36] [8083] New debug command: .debug setaurastate for test target/caster aura states. Also fix wrong (!args) checks in debug commands. --- src/game/Chat.cpp | 1 + src/game/Chat.h | 3 +- src/game/debugcmds.cpp | 92 ++++++++++++++++++++++++++-------------- src/shared/revision_nr.h | 2 +- 4 files changed, 65 insertions(+), 33 deletions(-) diff --git a/src/game/Chat.cpp b/src/game/Chat.cpp index 34447760c..af7c914a9 100644 --- a/src/game/Chat.cpp +++ b/src/game/Chat.cpp @@ -154,6 +154,7 @@ ChatCommand * ChatHandler::getCommandTable() { "Mod32Value", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugMod32Value, "", NULL }, { "play", SEC_MODERATOR, false, NULL, "", debugPlayCommandTable }, { "send", SEC_ADMINISTRATOR, false, NULL, "", debugSendCommandTable }, + { "setaurastate", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetAuraStateCommand, "", NULL }, { "setitemflag", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetItemFlagCommand, "", NULL }, { "setvalue", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSetValue, "", NULL }, { "spawnvehicle", SEC_ADMINISTRATOR, false, &ChatHandler::HandleDebugSpawnVehicle, "", NULL }, diff --git a/src/game/Chat.h b/src/game/Chat.h index 18ef9ccf2..cd235d4ee 100644 --- a/src/game/Chat.h +++ b/src/game/Chat.h @@ -132,8 +132,9 @@ class ChatHandler bool HandleDebugGetLootRecipient(const char * args); bool HandleDebugGetValue(const char* args); bool HandleDebugMod32Value(const char* args); - bool HandleDebugSetValue(const char* args); + bool HandleDebugSetAuraStateCommand(const char * args); bool HandleDebugSetItemFlagCommand(const char * args); + bool HandleDebugSetValue(const char* args); bool HandleDebugSpawnVehicle(const char * args); bool HandleDebugUpdate(const char* args); bool HandleDebugUpdateWorldStateCommand(const char* args); diff --git a/src/game/debugcmds.cpp b/src/game/debugcmds.cpp index a3b4627b6..feaa83651 100644 --- a/src/game/debugcmds.cpp +++ b/src/game/debugcmds.cpp @@ -33,7 +33,7 @@ bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args) { - if(!args) + if (!*args) return false; char* px = strtok((char*)args, " "); @@ -41,7 +41,7 @@ bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args) return false; uint8 failnum = (uint8)atoi(px); - if(failnum==0 && *px!='0') + if (failnum==0 && *px!='0') return false; char* p1 = strtok(NULL, " "); @@ -66,20 +66,20 @@ bool ChatHandler::HandleDebugSendSpellFailCommand(const char* args) bool ChatHandler::HandleDebugSendPoiCommand(const char* args) { + if (!*args) + return false; + Player *pPlayer = m_session->GetPlayer(); Unit* target = getSelectedUnit(); - if(!target) + if (!target) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); return true; } - if(!args) - return false; - char* icon_text = strtok((char*)args, " "); char* flags_text = strtok(NULL, " "); - if(!icon_text || !flags_text) + if (!icon_text || !flags_text) return false; uint32 icon = atol(icon_text); @@ -92,7 +92,7 @@ bool ChatHandler::HandleDebugSendPoiCommand(const char* args) bool ChatHandler::HandleDebugSendEquipErrorCommand(const char* args) { - if(!args) + if (!*args) return false; uint8 msg = atoi(args); @@ -102,7 +102,7 @@ bool ChatHandler::HandleDebugSendEquipErrorCommand(const char* args) bool ChatHandler::HandleDebugSendSellErrorCommand(const char* args) { - if(!args) + if (!*args) return false; uint8 msg = atoi(args); @@ -112,7 +112,7 @@ bool ChatHandler::HandleDebugSendSellErrorCommand(const char* args) bool ChatHandler::HandleDebugSendBuyErrorCommand(const char* args) { - if(!args) + if (!*args) return false; uint8 msg = atoi(args); @@ -127,7 +127,7 @@ bool ChatHandler::HandleDebugSendOpcodeCommand(const char* /*args*/) unit = m_session->GetPlayer(); std::ifstream ifs("opcode.txt"); - if(ifs.bad()) + if (ifs.bad()) return false; uint32 opcode; @@ -215,7 +215,7 @@ bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args) { // USAGE: .debug play cinematic #cinematicid // #cinematicid - ID decimal number from CinemaicSequences.dbc (1st column) - if( !*args ) + if (!*args) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); @@ -224,7 +224,7 @@ bool ChatHandler::HandleDebugPlayCinematicCommand(const char* args) uint32 dwId = atoi((char*)args); - if(!sCinematicSequencesStore.LookupEntry(dwId)) + if (!sCinematicSequencesStore.LookupEntry(dwId)) { PSendSysMessage(LANG_CINEMATIC_NOT_EXIST, dwId); SetSentErrorMessage(true); @@ -239,7 +239,7 @@ bool ChatHandler::HandleDebugPlayMovieCommand(const char* args) { // USAGE: .debug play movie #movieid // #movieid - ID decimal number from Movie.dbc (1st column) - if( !*args ) + if (!*args) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); @@ -248,7 +248,7 @@ bool ChatHandler::HandleDebugPlayMovieCommand(const char* args) uint32 dwId = atoi((char*)args); - if(!sMovieStore.LookupEntry(dwId)) + if (!sMovieStore.LookupEntry(dwId)) { PSendSysMessage(LANG_MOVIE_NOT_EXIST, dwId); SetSentErrorMessage(true); @@ -264,7 +264,7 @@ bool ChatHandler::HandleDebugPlaySoundCommand(const char* args) { // USAGE: .debug playsound #soundid // #soundid - ID decimal number from SoundEntries.dbc (1st column) - if( !*args ) + if (!*args) { SendSysMessage(LANG_BAD_VALUE); SetSentErrorMessage(true); @@ -273,7 +273,7 @@ bool ChatHandler::HandleDebugPlaySoundCommand(const char* args) uint32 dwSoundId = atoi((char*)args); - if(!sSoundEntriesStore.LookupEntry(dwSoundId)) + if (!sSoundEntriesStore.LookupEntry(dwSoundId)) { PSendSysMessage(LANG_SOUND_NOT_EXIST, dwSoundId); SetSentErrorMessage(true); @@ -281,14 +281,14 @@ bool ChatHandler::HandleDebugPlaySoundCommand(const char* args) } Unit* unit = getSelectedUnit(); - if(!unit) + if (!unit) { SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); SetSentErrorMessage(true); return false; } - if(m_session->GetPlayer()->GetSelection()) + if (m_session->GetPlayer()->GetSelection()) unit->PlayDistanceSound(dwSoundId,m_session->GetPlayer()); else unit->PlayDirectSound(dwSoundId,m_session->GetPlayer()); @@ -300,7 +300,7 @@ bool ChatHandler::HandleDebugPlaySoundCommand(const char* args) //Send notification in channel bool ChatHandler::HandleDebugSendChannelNotifyCommand(const char* args) { - if(!args) + if (!*args) return false; const char *name = "test"; @@ -318,7 +318,7 @@ bool ChatHandler::HandleDebugSendChannelNotifyCommand(const char* args) //Send notification in chat bool ChatHandler::HandleDebugSendChatMsgCommand(const char* args) { - if(!args) + if (!*args) return false; const char *msg = "testtest"; @@ -339,7 +339,7 @@ bool ChatHandler::HandleDebugSendQuestPartyMsgCommand(const char* args) bool ChatHandler::HandleDebugGetLootRecipient(const char* /*args*/) { Creature* target = getSelectedCreature(); - if(!target) + if (!target) return false; PSendSysMessage("loot recipient: %s", target->hasLootRecipient()?(target->GetLootRecipient()?target->GetLootRecipient()->GetName():"offline"):"no loot recipient"); @@ -355,7 +355,7 @@ bool ChatHandler::HandleDebugSendQuestInvalidMsgCommand(const char* args) bool ChatHandler::HandleDebugGetItemState(const char* args) { - if (!args) + if (!*args) return false; std::string state_str = args; @@ -601,7 +601,7 @@ bool ChatHandler::HandleDebugArenaCommand(const char * /*args*/) bool ChatHandler::HandleDebugSpawnVehicle(const char* args) { - if(!args) + if (!*args) return false; char* e = strtok((char*)args, " "); @@ -615,17 +615,17 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args) CreatureInfo const *ci = objmgr.GetCreatureTemplate(entry); - if(!ci) + if (!ci) return false; VehicleEntry const *ve = sVehicleStore.LookupEntry(id); - if(!ve) + 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())) + if (!v->Create(objmgr.GenerateLowGuid(HIGHGUID_VEHICLE), map, entry, id, m_session->GetPlayer()->GetTeam())) { delete v; return false; @@ -636,7 +636,7 @@ bool ChatHandler::HandleDebugSpawnVehicle(const char* args) v->Relocate(px, py, pz, m_session->GetPlayer()->GetOrientation()); - if(!v->IsPositionValid()) + if (!v->IsPositionValid()) { sLog.outError("Vehicle (guidlow %d, entry %d) not created. Suggested coordinates isn't valid (X: %f Y: %f)", v->GetGUIDLow(), v->GetEntry(), v->GetPositionX(), v->GetPositionY()); @@ -661,7 +661,7 @@ bool ChatHandler::HandleDebugSendLargePacketCommand(const char* /*args*/) bool ChatHandler::HandleDebugSendSetPhaseShiftCommand(const char* args) { - if(!args) + if (!*args) return false; uint32 PhaseShift = atoi(args); @@ -671,7 +671,7 @@ bool ChatHandler::HandleDebugSendSetPhaseShiftCommand(const char* args) bool ChatHandler::HandleDebugSetItemFlagCommand(const char* args) { - if(!args) + if (!*args) return false; char* e = strtok((char*)args, " "); @@ -685,7 +685,7 @@ bool ChatHandler::HandleDebugSetItemFlagCommand(const char* args) Item *i = m_session->GetPlayer()->GetItemByGuid(MAKE_NEW_GUID(guid, 0, HIGHGUID_ITEM)); - if(!i) + if (!i) return false; i->SetUInt32Value(ITEM_FIELD_FLAGS, flag); @@ -703,3 +703,33 @@ bool ChatHandler::HandleDebugAnimCommand(const char* args) m_session->GetPlayer()->HandleEmoteCommand(anim_id); return true; } + +bool ChatHandler::HandleDebugSetAuraStateCommand(const char* args) +{ + if (!*args) + { + SendSysMessage(LANG_BAD_VALUE); + SetSentErrorMessage(true); + return false; + } + + Unit* unit = getSelectedUnit(); + if (!unit) + { + SendSysMessage(LANG_SELECT_CHAR_OR_CREATURE); + SetSentErrorMessage(true); + return false; + } + + int32 state = atoi((char*)args); + if (!state) + { + // reset all states + for(int i = 1; i <= 32; ++i) + unit->ModifyAuraState(AuraState(i),false); + return true; + } + + unit->ModifyAuraState(AuraState(abs(state)),state > 0); + return true; +} diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 62a8a35f7..6a6b80c99 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8082" + #define REVISION_NR "8083" #endif // __REVISION_NR_H__ From 2dec2ccbe4e46cc020ba941a16c558ad7e92220d Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Sun, 28 Jun 2009 02:09:35 +0400 Subject: [PATCH 11/36] [8084] Correctly show spell icon disabled state at relogin for spells with cooldown delayed until expire. --- src/game/Player.cpp | 27 +++++++++++++++------------ src/game/Player.h | 2 ++ src/shared/revision_nr.h | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0124177f7..cda974173 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -2535,7 +2535,7 @@ void Player::InitStatsForLevel(bool reapplyMods) void Player::SendInitialSpells() { time_t curTime = time(NULL); - time_t infTime = curTime + MONTH/2; + time_t infTime = curTime + infinityCooldownDelayCheck; uint16 spellCount = 0; @@ -2569,18 +2569,21 @@ void Player::SendInitialSpells() if(!sEntry) continue; - // not send infinity cooldown - if(itr->second.end > infTime) - continue; - data << uint32(itr->first); - time_t cooldown = 0; - if(itr->second.end > curTime) - cooldown = (itr->second.end-curTime)*IN_MILISECONDS; - data << uint16(itr->second.itemid); // cast item id data << uint16(sEntry->Category); // spell category + + // send infinity cooldown in special format + if(itr->second.end >= infTime) + { + data << uint32(1); // cooldown + data << uint32(0x80000000); // category cooldown + continue; + } + + time_t cooldown = itr->second.end > curTime ? (itr->second.end-curTime)*IN_MILISECONDS : 0; + if(sEntry->Category) // may be wrong, but anyway better than nothing... { data << uint32(0); // cooldown @@ -3347,7 +3350,7 @@ void Player::_SaveSpellCooldowns() CharacterDatabase.PExecute("DELETE FROM character_spell_cooldown WHERE guid = '%u'", GetGUIDLow()); time_t curTime = time(NULL); - time_t infTime = curTime + MONTH/2; + time_t infTime = curTime + infinityCooldownDelayCheck; // remove outdated and save active for(SpellCooldowns::iterator itr = m_spellCooldowns.begin();itr != m_spellCooldowns.end();) @@ -17384,8 +17387,8 @@ void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 it { // use +MONTH as infinity mark for spell cooldown (will checked as MONTH/2 at save ans skipped) // but not allow ignore until reset or re-login - catrecTime = catrec > 0 ? curTime+MONTH : 0; - recTime = rec > 0 ? curTime+MONTH : catrecTime; + catrecTime = catrec > 0 ? curTime+infinityCooldownDelay : 0; + recTime = rec > 0 ? curTime+infinityCooldownDelay : catrecTime; } else { diff --git a/src/game/Player.h b/src/game/Player.h index 8222060a3..273adb993 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1462,6 +1462,8 @@ class MANGOS_DLL_SPEC Player : public Unit template T ApplySpellMod(uint32 spellId, SpellModOp op, T &basevalue, Spell const* spell = NULL); void RemoveSpellMods(Spell const* spell); + static uint32 const infinityCooldownDelay = MONTH; // used for set "infinity cooldowns" for spells and check + static uint32 const infinityCooldownDelayCheck = MONTH/2; bool HasSpellCooldown(uint32 spell_id) const { SpellCooldowns::const_iterator itr = m_spellCooldowns.find(spell_id); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6a6b80c99..a6b012d69 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8083" + #define REVISION_NR "8084" #endif // __REVISION_NR_H__ From 7bb9c42e9d70ed462c6c87d9dba3a68665a815cc Mon Sep 17 00:00:00 2001 From: duckman Date: Sun, 28 Jun 2009 04:02:19 +0400 Subject: [PATCH 12/36] [8085] Apply talent rate to all talents points. Signed-off-by: VladimirMangos --- src/game/Player.cpp | 10 ++++------ src/shared/revision_nr.h | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index cda974173..a8e444e6a 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -19452,19 +19452,17 @@ void Player::AutoStoreLoot(uint8 bag, uint8 slot, uint32 loot_id, LootStore cons uint32 Player::CalculateTalentsPoints() const { - uint32 base_talent = getLevel() < 10 ? 0 : uint32((getLevel()-9)*sWorld.getRate(RATE_TALENT)); + uint32 base_talent = getLevel() < 10 ? 0 : getLevel()-9; if(getClass() != CLASS_DEATH_KNIGHT) - return base_talent; + return uint32(base_talent * sWorld.getRate(RATE_TALENT)); - uint32 talentPointsForLevel = - (getLevel() < 56 ? 0 : uint32((getLevel()-55)*sWorld.getRate(RATE_TALENT))) - + m_questRewardTalentCount; + uint32 talentPointsForLevel = getLevel() < 56 ? 0 : getLevel() - 55 + m_questRewardTalentCount; if(talentPointsForLevel > base_talent) talentPointsForLevel = base_talent; - return talentPointsForLevel; + return uint32(talentPointsForLevel * sWorld.getRate(RATE_TALENT)); } bool Player::IsAllowUseFlyMountsHere() const diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a6b012d69..583662128 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8084" + #define REVISION_NR "8085" #endif // __REVISION_NR_H__ From 14a4e0ec537fa848d45917dee215cc36de75e9fc Mon Sep 17 00:00:00 2001 From: Maxxie Date: Sun, 28 Jun 2009 11:14:40 +0400 Subject: [PATCH 13/36] [8086] Restore work spell 11196. Signed-off-by: VladimirMangos --- src/game/SpellAuras.cpp | 4 ++++ src/game/SpellMgr.cpp | 1 + src/shared/revision_nr.h | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 7ccc4eb5a..de02c0983 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -2183,6 +2183,10 @@ void Aura::HandleAuraDummy(bool apply, bool Real) { switch(GetId()) { + // Recently Bandaged + case 11196: + m_target->ApplySpellImmune(GetId(), IMMUNITY_MECHANIC, GetMiscValue(), apply); + return; // Unstable Power case 24658: { diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index ec21bb044..2f188734a 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -331,6 +331,7 @@ bool IsPositiveEffect(uint32 spellId, uint32 effIndex) case 38637: // Nether Exhaustion (red) case 38638: // Nether Exhaustion (green) case 38639: // Nether Exhaustion (blue) + case 11196: // Recently Bandaged return false; // some spells have unclear target modes for selection, so just make effect positive case 27184: diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 583662128..103f5d605 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8085" + #define REVISION_NR "8086" #endif // __REVISION_NR_H__ From 96875173af3f7dcbbc48cd021a60e40b8dd08a85 Mon Sep 17 00:00:00 2001 From: ApoC Date: Sun, 28 Jun 2009 21:00:49 +0200 Subject: [PATCH 14/36] Allow NPCs to apply taunt. Signed-off-by: ApoC --- src/game/SpellAuras.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index de02c0983..18150bfe3 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3861,7 +3861,7 @@ void Aura::HandleModTaunt(bool apply, bool Real) Unit* caster = GetCaster(); - if(!caster || !caster->isAlive() || caster->GetTypeId() != TYPEID_PLAYER) + if(!caster || !caster->isAlive()) return; if(apply) From 2f3aa9bd71da350a89a871ca1f7c98682e042f46 Mon Sep 17 00:00:00 2001 From: NoFantasy Date: Mon, 29 Jun 2009 02:18:21 +0400 Subject: [PATCH 15/36] [8087] Cleanup code. Signed-off-by: VladimirMangos --- src/game/QuestHandler.cpp | 90 +++++++++++++++++++-------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index b9baa025a..5d2300676 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -429,60 +429,56 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) { CHECK_PACKET_SIZE(recvPacket,4); - uint32 quest; - recvPacket >> quest; + uint32 questId; + recvPacket >> questId; - sLog.outDebug( "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", quest ); + sLog.outDebug("WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId); - Quest const *pQuest = objmgr.GetQuestTemplate(quest); - if( pQuest ) + if (Quest const *pQuest = objmgr.GetQuestTemplate(questId)) { - if( _player->GetGroup() ) + if (Group* pGroup = _player->GetGroup()) { - Group *pGroup = _player->GetGroup(); - if( pGroup ) + for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) { - for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next()) + Player *pPlayer = itr->getSource(); + + if (!pPlayer || pPlayer == _player) // skip self + continue; + + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); + + if (!pPlayer->SatisfyQuestStatus(pQuest, false)) { - Player *pPlayer = itr->getSource(); - if (!pPlayer || pPlayer == _player) // skip self - continue; - - _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_SHARING_QUEST); - - if( !pPlayer->SatisfyQuestStatus( pQuest, false ) ) - { - _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_HAVE_QUEST ); - continue; - } - - if( pPlayer->GetQuestStatus( quest ) == QUEST_STATUS_COMPLETE ) - { - _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_FINISH_QUEST ); - continue; - } - - if( !pPlayer->CanTakeQuest( pQuest, false ) ) - { - _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST ); - continue; - } - - if( !pPlayer->SatisfyQuestLog( false ) ) - { - _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_LOG_FULL ); - continue; - } - - if( pPlayer->GetDivider() != 0 ) - { - _player->SendPushToPartyResponse( pPlayer, QUEST_PARTY_MSG_BUSY ); - continue; - } - - pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails( pQuest, _player->GetGUID(), true ); - pPlayer->SetDivider( _player->GetGUID() ); + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_HAVE_QUEST); + continue; } + + if (pPlayer->GetQuestStatus(questId) == QUEST_STATUS_COMPLETE) + { + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_FINISH_QUEST); + continue; + } + + if (!pPlayer->CanTakeQuest(pQuest, false)) + { + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_CANT_TAKE_QUEST); + continue; + } + + if (!pPlayer->SatisfyQuestLog(false)) + { + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_LOG_FULL); + continue; + } + + if (pPlayer->GetDivider() != 0) + { + _player->SendPushToPartyResponse(pPlayer, QUEST_PARTY_MSG_BUSY); + continue; + } + + pPlayer->PlayerTalkClass->SendQuestGiverQuestDetails(pQuest, _player->GetGUID(), true); + pPlayer->SetDivider(_player->GetGUID()); } } } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 103f5d605..8b1147a8f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8086" + #define REVISION_NR "8087" #endif // __REVISION_NR_H__ From 5d0f5f542109e2fbc13e21d12f2f44faa1b747de Mon Sep 17 00:00:00 2001 From: ApoC Date: Mon, 29 Jun 2009 01:10:26 +0200 Subject: [PATCH 16/36] [8088] Fixed min_range checking for spell casts. Skip in check values 0.0f from DBC, this spells do not have min range limitation. This should fix some inappropriate target too close messages. Signed-off-by: ApoC --- src/game/Spell.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 51553cabb..44fe64ac2 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4678,7 +4678,7 @@ SpellCastResult Spell::CheckRange(bool strict) if(dist > max_range) return SPELL_FAILED_OUT_OF_RANGE; //0x5A; - if(dist < min_range) + if(min_range && dist < min_range) return SPELL_FAILED_TOO_CLOSE; if( m_caster->GetTypeId() == TYPEID_PLAYER && (m_spellInfo->FacingCasterFlags & SPELL_FACING_FLAG_INFRONT) && !m_caster->HasInArc( M_PI, target ) ) @@ -4689,7 +4689,7 @@ SpellCastResult Spell::CheckRange(bool strict) { if(!m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, max_range)) return SPELL_FAILED_OUT_OF_RANGE; - if(m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, min_range)) + if(min_range && m_caster->IsWithinDist3d(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, min_range)) return SPELL_FAILED_TOO_CLOSE; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8b1147a8f..20c4fa01a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8087" + #define REVISION_NR "8088" #endif // __REVISION_NR_H__ From 24ee9c7105cbf0405817e6d2fcd65e616483cbaa Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 29 Jun 2009 10:54:21 +0400 Subject: [PATCH 17/36] [8089] Implement SPELL_EFFECT_CHARGE2(149), more correct monster flags use in charge effects. Last fix let for example correct charge for flight creatures... --- src/game/SpellEffects.cpp | 40 +++++++++++++++++++++++++++++++++------ src/shared/revision_nr.h | 2 +- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 23020ca16..14d6f5a06 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -206,7 +206,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &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 + &Spell::EffectCharge2, //149 SPELL_EFFECT_CHARGE2 swoop &Spell::EffectUnused, //150 SPELL_EFFECT_150 unused &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2 &Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend @@ -5904,22 +5904,50 @@ void Spell::EffectSkinning(uint32 /*i*/) void Spell::EffectCharge(uint32 /*i*/) { - if(!unitTarget || !m_caster) + if (!unitTarget) return; float x, y, z; unitTarget->GetContactPoint(m_caster, x, y, z); - if(unitTarget->GetTypeId() != TYPEID_PLAYER) + if (unitTarget->GetTypeId() != TYPEID_PLAYER) ((Creature *)unitTarget)->StopMoving(); // Only send MOVEMENTFLAG_WALK_MODE, client has strange issues with other move flags - m_caster->SendMonsterMove(x, y, z, 0, MONSTER_MOVE_WALK, 1); + m_caster->SendMonsterMove(x, y, z, 0, m_caster->GetTypeId()==TYPEID_PLAYER ? MONSTER_MOVE_WALK : ((Creature*)m_caster)->GetMonsterMoveFlags(), 1); - if(m_caster->GetTypeId() != TYPEID_PLAYER) + if (m_caster->GetTypeId() != TYPEID_PLAYER) m_caster->GetMap()->CreatureRelocation((Creature*)m_caster,x,y,z,m_caster->GetOrientation()); // not all charge effects used in negative spells - if ( !IsPositiveSpell(m_spellInfo->Id)) + if (unitTarget != m_caster && !IsPositiveSpell(m_spellInfo->Id)) + m_caster->Attack(unitTarget,true); +} + +void Spell::EffectCharge2(uint32 /*i*/) +{ + float x, y, z; + if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) + { + x = m_targets.m_destX; + y = m_targets.m_destY; + z = m_targets.m_destZ; + + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + ((Creature *)unitTarget)->StopMoving(); + } + else if (unitTarget && unitTarget != m_caster) + unitTarget->GetContactPoint(m_caster, x, y, z); + else + return; + + // Only send MOVEMENTFLAG_WALK_MODE, client has strange issues with other move flags + m_caster->SendMonsterMove(x, y, z, 0, m_caster->GetTypeId()==TYPEID_PLAYER ? MONSTER_MOVE_WALK : ((Creature*)m_caster)->GetMonsterMoveFlags(), 1); + + if (m_caster->GetTypeId() != TYPEID_PLAYER) + m_caster->GetMap()->CreatureRelocation((Creature*)m_caster,x,y,z,m_caster->GetOrientation()); + + // not all charge effects used in negative spells + if (unitTarget && unitTarget != m_caster && !IsPositiveSpell(m_spellInfo->Id)) m_caster->Attack(unitTarget,true); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 20c4fa01a..175ffdc62 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8088" + #define REVISION_NR "8089" #endif // __REVISION_NR_H__ From f420fdde77e49fc0b52d03cea60614e50c92c386 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 29 Jun 2009 12:05:46 +0400 Subject: [PATCH 18/36] [8090] Fixed build problems. --- src/game/Spell.h | 1 + src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/game/Spell.h b/src/game/Spell.h index ad4084833..01c25060d 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -288,6 +288,7 @@ class Spell void EffectSelfResurrect(uint32 i); void EffectSkinning(uint32 i); void EffectCharge(uint32 i); + void EffectCharge2(uint32 i); void EffectProspecting(uint32 i); void EffectMilling(uint32 i); void EffectRenamePet(uint32 i); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 175ffdc62..a2605425c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8089" + #define REVISION_NR "8090" #endif // __REVISION_NR_H__ From ac7a7417fe6655ae7efd35d0b9885807db891326 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 29 Jun 2009 12:47:40 +0400 Subject: [PATCH 19/36] [8091] Check bag size at item protos loading and item slots at invetory loading. This is single not safe places in work with bag slots in current code. --- src/game/ObjectMgr.cpp | 6 ++++++ src/game/Player.cpp | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index c05a324f6..f6ab57844 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1735,6 +1735,12 @@ void ObjectMgr::LoadItemPrototypes() const_cast(proto)->Stackable = 1000; } + if(proto->ContainerSlots > MAX_BAG_SIZE) + { + sLog.outErrorDb("Item (Entry: %u) has too large value in ContainerSlots (%u), replace by hardcoded limit (%u).",i,proto->ContainerSlots,MAX_BAG_SIZE); + const_cast(proto)->ContainerSlots = MAX_BAG_SIZE; + } + if(proto->StatsCount > MAX_ITEM_PROTO_STATS) { sLog.outErrorDb("Item (Entry: %u) has too large value in statscount (%u), replace by hardcoded limit (%u).",i,proto->StatsCount,MAX_ITEM_PROTO_STATS); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index a8e444e6a..7b90f3fbc 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -14754,7 +14754,7 @@ void Player::_LoadInventory(QueryResult *result, uint32 timediff) item->SetSlot(NULL_SLOT); // the item is in a bag, find the bag std::map::const_iterator itr = bagMap.find(bag_guid); - if(itr != bagMap.end()) + if(itr != bagMap.end() && slot < itr->second->GetBagSize()) itr->second->StoreItem(slot, item, true ); else success = false; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index a2605425c..e3f2e604c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8090" + #define REVISION_NR "8091" #endif // __REVISION_NR_H__ From f80f45e3c4d63fe1aa85b727cfb18b9615e5d5a2 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 29 Jun 2009 13:19:42 +0400 Subject: [PATCH 20/36] [8092] No, one more not safe place found. Patch inspired bug report connected with alt.patch written by Machiavelli. --- src/game/Player.cpp | 297 ++++++++++++++++++++------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 151 insertions(+), 148 deletions(-) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 7b90f3fbc..063ad145b 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -8701,39 +8701,42 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV Item* pItem2 = GetItemByPos( bag, slot ); // ignore move item (this slot will be empty at move) - if(pItem2==pSrcItem) + if (pItem2==pSrcItem) pItem2 = NULL; uint32 need_space; // empty specific slot - check item fit to slot - if( !pItem2 || swap ) + if (!pItem2 || swap) { - if( bag == INVENTORY_SLOT_BAG_0 ) + if (bag == INVENTORY_SLOT_BAG_0) { // keyring case - if(slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS)) + if (slot >= KEYRING_SLOT_START && slot < KEYRING_SLOT_START+GetMaxKeyringSize() && !(pProto->BagFamily & BAG_FAMILY_MASK_KEYS)) 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)) + if (slot >= CURRENCYTOKEN_SLOT_START && slot < CURRENCYTOKEN_SLOT_END && !(pProto->BagFamily & BAG_FAMILY_MASK_CURRENCY_TOKENS)) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; // prevent cheating - if(slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END) + if (slot >= BUYBACK_SLOT_START && slot < BUYBACK_SLOT_END || slot >= PLAYER_SLOT_END) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; } else { Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); - if( !pBag ) + if (!pBag) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; ItemPrototype const* pBagProto = pBag->GetProto(); - if( !pBagProto ) + if (!pBagProto) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - if( !ItemCanGoIntoBag(pProto,pBagProto) ) + if (slot >= pBagProto->ContainerSlots) + return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; + + if (!ItemCanGoIntoBag(pProto,pBagProto)) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; } @@ -8744,22 +8747,22 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV else { // check item type - if(pItem2->GetEntry() != pProto->ItemId) + if (pItem2->GetEntry() != pProto->ItemId) return EQUIP_ERR_ITEM_CANT_STACK; // check free space - if(pItem2->GetCount() >= pProto->GetMaxStackSize()) + if (pItem2->GetCount() >= pProto->GetMaxStackSize()) return EQUIP_ERR_ITEM_CANT_STACK; // free stack space or infinity need_space = pProto->GetMaxStackSize() - pItem2->GetCount(); } - if(need_space > count) + if (need_space > count) need_space = count; ItemPosCount newPosition = ItemPosCount((bag << 8) | slot, need_space); - if(!newPosition.isContainedIn(dest)) + if (!newPosition.isContainedIn(dest)) { dest.push_back(newPosition); count -= need_space; @@ -8770,55 +8773,55 @@ uint8 Player::_CanStoreItem_InSpecificSlot( uint8 bag, uint8 slot, ItemPosCountV uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototype const *pProto, uint32& count, bool merge, bool non_specialized, Item* pSrcItem, uint8 skip_bag, uint8 skip_slot ) const { // skip specific bag already processed in first called _CanStoreItem_InBag - if(bag==skip_bag) + if (bag==skip_bag) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; Bag* pBag = (Bag*)GetItemByPos( INVENTORY_SLOT_BAG_0, bag ); - if( !pBag ) + if (!pBag) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; ItemPrototype const* pBagProto = pBag->GetProto(); - if( !pBagProto ) + if (!pBagProto) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; // specialized bag mode or non-specilized - if( non_specialized != (pBagProto->Class == ITEM_CLASS_CONTAINER && pBagProto->SubClass == ITEM_SUBCLASS_CONTAINER) ) + if (non_specialized != (pBagProto->Class == ITEM_CLASS_CONTAINER && pBagProto->SubClass == ITEM_SUBCLASS_CONTAINER)) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; - if( !ItemCanGoIntoBag(pProto,pBagProto) ) + if (!ItemCanGoIntoBag(pProto,pBagProto)) return EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG; for(uint32 j = 0; j < pBag->GetBagSize(); ++j) { // skip specific slot already processed in first called _CanStoreItem_InSpecificSlot - if(j==skip_slot) + if (j==skip_slot) continue; Item* pItem2 = GetItemByPos( bag, j ); // ignore move item (this slot will be empty at move) - if(pItem2==pSrcItem) + if (pItem2==pSrcItem) pItem2 = NULL; // if merge skip empty, if !merge skip non-empty - if((pItem2!=NULL)!=merge) + if ((pItem2!=NULL)!=merge) continue; - if( pItem2 ) + if (pItem2) { - if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize()) + if (pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize()) { uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount(); if(need_space > count) need_space = count; ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space); - if(!newPosition.isContainedIn(dest)) + if (!newPosition.isContainedIn(dest)) { dest.push_back(newPosition); count -= need_space; - if(count==0) + if (count==0) return EQUIP_ERR_OK; } } @@ -8826,16 +8829,16 @@ uint8 Player::_CanStoreItem_InBag( uint8 bag, ItemPosCountVec &dest, ItemPrototy else { uint32 need_space = pProto->GetMaxStackSize(); - if(need_space > count) + if (need_space > count) need_space = count; ItemPosCount newPosition = ItemPosCount((bag << 8) | j, need_space); - if(!newPosition.isContainedIn(dest)) + if (!newPosition.isContainedIn(dest)) { dest.push_back(newPosition); count -= need_space; - if(count==0) + if (count==0) return EQUIP_ERR_OK; } } @@ -8848,33 +8851,33 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end, for(uint32 j = slot_begin; j < slot_end; ++j) { // skip specific slot already processed in first called _CanStoreItem_InSpecificSlot - if(INVENTORY_SLOT_BAG_0==skip_bag && j==skip_slot) + if (INVENTORY_SLOT_BAG_0==skip_bag && j==skip_slot) continue; Item* pItem2 = GetItemByPos( INVENTORY_SLOT_BAG_0, j ); // ignore move item (this slot will be empty at move) - if(pItem2==pSrcItem) + if (pItem2==pSrcItem) pItem2 = NULL; // if merge skip empty, if !merge skip non-empty - if((pItem2!=NULL)!=merge) + if ((pItem2!=NULL)!=merge) continue; - if( pItem2 ) + if (pItem2) { - if(pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize()) + if (pItem2->GetEntry() == pProto->ItemId && pItem2->GetCount() < pProto->GetMaxStackSize()) { uint32 need_space = pProto->GetMaxStackSize() - pItem2->GetCount(); - if(need_space > count) + if (need_space > count) need_space = count; ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space); - if(!newPosition.isContainedIn(dest)) + if (!newPosition.isContainedIn(dest)) { dest.push_back(newPosition); count -= need_space; - if(count==0) + if (count==0) return EQUIP_ERR_OK; } } @@ -8882,16 +8885,16 @@ uint8 Player::_CanStoreItem_InInventorySlots( uint8 slot_begin, uint8 slot_end, else { uint32 need_space = pProto->GetMaxStackSize(); - if(need_space > count) + if (need_space > count) need_space = count; ItemPosCount newPosition = ItemPosCount((INVENTORY_SLOT_BAG_0 << 8) | j, need_space); - if(!newPosition.isContainedIn(dest)) + if (!newPosition.isContainedIn(dest)) { dest.push_back(newPosition); count -= need_space; - if(count==0) + if (count==0) return EQUIP_ERR_OK; } } @@ -8904,16 +8907,16 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 sLog.outDebug( "STORAGE: CanStoreItem bag = %u, slot = %u, item = %u, count = %u", bag, slot, entry, count); ItemPrototype const *pProto = objmgr.GetItemPrototype(entry); - if( !pProto ) + if (!pProto) { - if(no_space_count) + if (no_space_count) *no_space_count = count; return swap ? EQUIP_ERR_ITEMS_CANT_BE_SWAPPED :EQUIP_ERR_ITEM_NOT_FOUND; } - if(pItem && pItem->IsBindedNotWith(this)) + if (pItem && pItem->IsBindedNotWith(this)) { - if(no_space_count) + if (no_space_count) *no_space_count = count; return EQUIP_ERR_DONT_OWN_THAT_ITEM; } @@ -8921,11 +8924,11 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 // check count of items (skip for auto move for same player from bank) uint32 no_similar_count = 0; // can't store this amount similar items uint8 res = _CanTakeMoreSimilarItems(entry,count,pItem,&no_similar_count); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(count==no_similar_count) + if (count==no_similar_count) { - if(no_space_count) + if (no_space_count) *no_space_count = no_similar_count; return res; } @@ -8933,22 +8936,22 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 } // in specific slot - if( bag != NULL_BAG && slot != NULL_SLOT ) + if (bag != NULL_BAG && slot != NULL_SLOT) { res = _CanStoreItem_InSpecificSlot(bag,slot,dest,pProto,count,swap,pItem); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -8957,45 +8960,45 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 // not specific slot or have space for partly store only in specific slot // in specific bag - if( bag != NULL_BAG ) + if (bag != NULL_BAG) { // search stack in bag for merge to - if( pProto->Stackable != 1 ) + if (pProto->Stackable != 1) { - if( bag == INVENTORY_SLOT_BAG_0 ) // inventory + if (bag == INVENTORY_SLOT_BAG_0) // inventory { res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,true,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + 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,true,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9004,22 +9007,22 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 { // we need check 2 time (specialized/non_specialized), use NULL_BAG to prevent skipping bag res = _CanStoreItem_InBag(bag,dest,pProto,count,true,false,pItem,NULL_BAG,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) res = _CanStoreItem_InBag(bag,dest,pProto,count,true,true,pItem,NULL_BAG,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9027,83 +9030,83 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 } // search free slot in bag for place to - if( bag == INVENTORY_SLOT_BAG_0 ) // inventory + if(bag == INVENTORY_SLOT_BAG_0) // inventory { // search free slot - keyring case - if(pProto->BagFamily & BAG_FAMILY_MASK_KEYS) + if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS) { uint32 keyringSize = GetMaxKeyringSize(); res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_START+keyringSize,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } res = _CanStoreItem_InInventorySlots(CURRENCYTOKEN_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + 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) + 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 (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + 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) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9111,22 +9114,22 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 else // equipped bag { res = _CanStoreItem_InBag(bag,dest,pProto,count,false,false,pItem,NULL_BAG,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) res = _CanStoreItem_InBag(bag,dest,pProto,count,false,true,pItem,NULL_BAG,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9136,58 +9139,58 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 // not specific bag or have space for partly store only in specific bag // search stack for merge to - if( pProto->Stackable != 1 ) + if (pProto->Stackable != 1) { res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,CURRENCYTOKEN_SLOT_END,dest,pProto,count,true,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + 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,true,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } - if( pProto->BagFamily ) + if (pProto->BagFamily) { for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { res = _CanStoreItem_InBag(i,dest,pProto,count,true,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) continue; - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9197,15 +9200,15 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { res = _CanStoreItem_InBag(i,dest,pProto,count,true,true,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) continue; - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9213,45 +9216,45 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 } // search free slot - special bag case - if( pProto->BagFamily ) + if (pProto->BagFamily) { - if(pProto->BagFamily & BAG_FAMILY_MASK_KEYS) + if (pProto->BagFamily & BAG_FAMILY_MASK_KEYS) { uint32 keyringSize = GetMaxKeyringSize(); res = _CanStoreItem_InInventorySlots(KEYRING_SLOT_START,KEYRING_SLOT_START+keyringSize,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + 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) + 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 (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9260,15 +9263,15 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { res = _CanStoreItem_InBag(i,dest,pProto,count,false,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) continue; - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9277,19 +9280,19 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 // search free slot res = _CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START,INVENTORY_SLOT_ITEM_END,dest,pProto,count,false,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) { - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return res; } - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } @@ -9297,21 +9300,21 @@ uint8 Player::_CanStoreItem( uint8 bag, uint8 slot, ItemPosCountVec &dest, uint3 for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i) { res = _CanStoreItem_InBag(i,dest,pProto,count,false,true,pItem,bag,slot); - if(res!=EQUIP_ERR_OK) + if (res!=EQUIP_ERR_OK) continue; - if(count==0) + if (count==0) { - if(no_similar_count==0) + if (no_similar_count==0) return EQUIP_ERR_OK; - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_CANT_CARRY_MORE_OF_THIS; } } - if(no_space_count) + if (no_space_count) *no_space_count = count + no_similar_count; return EQUIP_ERR_INVENTORY_FULL; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index e3f2e604c..55fd6b24a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8091" + #define REVISION_NR "8092" #endif // __REVISION_NR_H__ From cd913c1f9261859e15e3b0810fbc750736a352fa Mon Sep 17 00:00:00 2001 From: ApoC Date: Fri, 22 May 2009 19:31:55 +0200 Subject: [PATCH 21/36] [8093] Fixed effect of spell 25771. Signed-off-by: ApoC --- src/game/SpellAuras.cpp | 6 ++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp index 18150bfe3..eef4b9311 100644 --- a/src/game/SpellAuras.cpp +++ b/src/game/SpellAuras.cpp @@ -3966,6 +3966,12 @@ void Aura::HandleModMechanicImmunity(bool apply, bool /*Real*/) uint32 misc = m_modifier.m_miscvalue; Unit* target = m_target; + // Forbearance + // in DBC wrong mechanic immune since 3.0.x + if (GetId() == 25771) + misc = MECHANIC_IMMUNE_SHIELD; + + if(apply && spellInfo->AttributesEx & SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY) { uint32 mechanic = 1 << m_modifier.m_miscvalue; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 55fd6b24a..bc81ad8d7 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8092" + #define REVISION_NR "8093" #endif // __REVISION_NR_H__ From c8d07d6e7222ecfe63cc72afb3337175bc4ad02e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Mon, 29 Jun 2009 14:48:42 +0400 Subject: [PATCH 22/36] [8094] Overwrite max durability for item at item loading from prototype. --- src/game/Item.cpp | 10 ++++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/game/Item.cpp b/src/game/Item.cpp index 52ed24bdb..0ac47c673 100644 --- a/src/game/Item.cpp +++ b/src/game/Item.cpp @@ -377,6 +377,16 @@ bool Item::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult *result) if(!proto) return false; + // update max durability (and durability) if need + if(proto->MaxDurability!= GetUInt32Value(ITEM_FIELD_MAXDURABILITY)) + { + SetUInt32Value(ITEM_FIELD_MAXDURABILITY,proto->MaxDurability); + if(GetUInt32Value(ITEM_FIELD_DURABILITY) > proto->MaxDurability) + SetUInt32Value(ITEM_FIELD_DURABILITY,proto->MaxDurability); + + need_save = true; + } + // recalculate suffix factor if(GetItemRandomPropertyId() < 0) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index bc81ad8d7..2e4c90e44 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8093" + #define REVISION_NR "8094" #endif // __REVISION_NR_H__ From 1eb308a2eb8e62342185b74fa690c617bb10abe9 Mon Sep 17 00:00:00 2001 From: freghar Date: Mon, 29 Jun 2009 13:59:07 +0200 Subject: [PATCH 23/36] [8095] Added gitignore for src/bindings/ Signed-off-by: freghar --- src/bindings/.gitignore | 14 ++++++++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 src/bindings/.gitignore diff --git a/src/bindings/.gitignore b/src/bindings/.gitignore new file mode 100644 index 000000000..eeddf0dd7 --- /dev/null +++ b/src/bindings/.gitignore @@ -0,0 +1,14 @@ +# +# NOTE! Don't add files that are generated in specific +# subdirectories here. Add them in the ".gitignore" file +# in that subdirectory instead. +# +# NOTE! Please use 'git-ls-files -i --exclude-standard' +# command after changing this file, to see if there are +# any tracked files which get ignored after the change. +# + +# +# Scripting projects +# +#universal diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 2e4c90e44..6ee17294e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8094" + #define REVISION_NR "8095" #endif // __REVISION_NR_H__ From 7d79f8168a3057e41eb387180e670c434246078a Mon Sep 17 00:00:00 2001 From: ApoC Date: Mon, 29 Jun 2009 19:37:32 +0200 Subject: [PATCH 24/36] [8096] Fixed dummy effect for 34665 * Removed dynamic cast * Little effect code clean up Signed-off-by: ApoC --- src/game/SpellEffects.cpp | 35 ++++++++++++++--------------------- src/shared/revision_nr.h | 2 +- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 14d6f5a06..5d39fab2b 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -1042,32 +1042,25 @@ void Spell::EffectDummy(uint32 i) { if(!unitTarget || m_caster->GetTypeId() != TYPEID_PLAYER ) return; - - if(!unitTarget) + // Spell has scriptable target but for sure. + if (unitTarget->GetTypeId() != TYPEID_UNIT) return; - TemporarySummon* tempSummon = dynamic_cast(unitTarget); - if(!tempSummon) - return; + uint32 health = unitTarget->GetHealth(); + float x, y, z, o; - uint32 health = tempSummon->GetHealth(); + unitTarget->GetPosition(x, y, z); + o = unitTarget->GetOrientation(); + ((Creature*)unitTarget)->ForcedDespawn(); - float x = tempSummon->GetPositionX(); - float y = tempSummon->GetPositionY(); - float z = tempSummon->GetPositionZ(); - float o = tempSummon->GetOrientation(); - tempSummon->UnSummon(); - - Creature* pCreature = m_caster->SummonCreature(16992, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000); - if (!pCreature) - return; - - pCreature->SetHealth(health); - ((Player*)m_caster)->RewardPlayerAndGroupAtEvent(16992, pCreature); - - if (pCreature->AI()) - pCreature->AI()->AttackStart(m_caster); + if (Creature* summon = m_caster->SummonCreature(16992, x, y, z, o,TEMPSUMMON_TIMED_OR_DEAD_DESPAWN,180000)) + { + summon->SetHealth(health); + ((Player*)m_caster)->RewardPlayerAndGroupAtEvent(16992, summon); + if (summon->AI()) + summon->AI()->AttackStart(m_caster); + } return; } case 44997: // Converting Sentry diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 6ee17294e..93c4b523a 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8095" + #define REVISION_NR "8096" #endif // __REVISION_NR_H__ From c24e0417940895d301f24a285d6d572597fff37a Mon Sep 17 00:00:00 2001 From: ApoC Date: Mon, 29 Jun 2009 20:23:47 +0200 Subject: [PATCH 25/36] [8097] Updated comment based on research. Signed-off-by: ApoC --- src/game/DBCStructure.h | 4 +++- src/shared/revision_nr.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h index 27646fda2..2fa8f2267 100644 --- a/src/game/DBCStructure.h +++ b/src/game/DBCStructure.h @@ -487,7 +487,9 @@ struct AchievementCriteriaEntry //uint32 name_flags; // 25 uint32 completionFlag; // 26 uint32 groupFlag; // 27 - //uint32 unk1; // 28 + //uint32 unk1; // 28 Alway appears with timed events + // for timed spells it is spell id for + // timed kills it is creature id uint32 timeLimit; // 29 time limit in seconds //uint32 showOrder; // 30 show order }; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 93c4b523a..10f38a9ad 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8096" + #define REVISION_NR "8097" #endif // __REVISION_NR_H__ From 1baec778453df5177d6acf1edae617165f2e9f03 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 30 Jun 2009 07:37:36 +0400 Subject: [PATCH 26/36] [8098] Support uint32 spell ids in code. * Propertly work with uint32 spell ids in player action bar * Fix in same time bug with not save equipment set button with id==0 * Merge misc field in character_action and playercreateinfo_action to action field as 3 byte * Propertly load uint32 spell ids from character_spell * Fixed types for some pet/creature related structure for spell id storing. --- sql/characters.sql | 5 +- sql/mangos.sql | 713 +++++++++--------- .../8098_01_characters_character_action.sql | 10 + ...8098_02_mangos_playercreateinfo_action.sql | 10 + .../8098_03_characters_character_pet.sql | 13 + sql/updates/8098_04_characters_pet_spell.sql | 4 + sql/updates/Makefile.am | 8 + src/game/CharacterHandler.cpp | 2 +- src/game/Creature.h | 6 +- src/game/MiscHandler.cpp | 53 +- src/game/ObjectMgr.cpp | 9 +- src/game/Pet.cpp | 21 +- src/game/Pet.h | 2 +- src/game/PetHandler.cpp | 48 +- src/game/Player.cpp | 123 ++- src/game/Player.h | 53 +- src/game/SpellMgr.cpp | 6 +- src/game/SpellMgr.h | 16 +- src/game/Unit.cpp | 50 +- src/game/Unit.h | 49 +- src/shared/revision_nr.h | 2 +- 21 files changed, 638 insertions(+), 565 deletions(-) create mode 100644 sql/updates/8098_01_characters_character_action.sql create mode 100644 sql/updates/8098_02_mangos_playercreateinfo_action.sql create mode 100644 sql/updates/8098_03_characters_character_pet.sql create mode 100644 sql/updates/8098_04_characters_pet_spell.sql diff --git a/sql/characters.sql b/sql/characters.sql index ea5eb8ff9..8fb7327f2 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_8072_02_characters_characters` bit(1) default NULL + `required_8098_04_characters_pet_spell` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- @@ -305,9 +305,8 @@ DROP TABLE IF EXISTS `character_action`; CREATE TABLE `character_action` ( `guid` int(11) unsigned NOT NULL default '0' COMMENT 'Global Unique Identifier', `button` tinyint(3) unsigned NOT NULL default '0', - `action` smallint(5) unsigned NOT NULL default '0', + `action` int(11) unsigned NOT NULL default '0', `type` tinyint(3) unsigned NOT NULL default '0', - `misc` tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (`guid`,`button`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='Player System'; diff --git a/sql/mangos.sql b/sql/mangos.sql index c2f727eca..6ea0523d6 100644 --- a/sql/mangos.sql +++ b/sql/mangos.sql @@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`; CREATE TABLE `db_version` ( `version` varchar(120) default NULL, `creature_ai_version` varchar(120) default NULL, - `required_8071_01_mangos_command` bit(1) default NULL + `required_8098_02_mangos_playercreateinfo_action` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; -- @@ -9721,9 +9721,8 @@ CREATE TABLE `playercreateinfo_action` ( `race` tinyint(3) unsigned NOT NULL default '0', `class` tinyint(3) unsigned NOT NULL default '0', `button` smallint(5) unsigned NOT NULL default '0', - `action` smallint(5) unsigned NOT NULL default '0', + `action` int(11) unsigned NOT NULL default '0', `type` smallint(5) unsigned NOT NULL default '0', - `misc` smallint(5) unsigned NOT NULL default '0', KEY `playercreateinfo_race_class_index` (`race`,`class`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; @@ -9734,360 +9733,360 @@ CREATE TABLE `playercreateinfo_action` ( LOCK TABLES `playercreateinfo_action` WRITE; /*!40000 ALTER TABLE `playercreateinfo_action` DISABLE KEYS */; INSERT INTO `playercreateinfo_action` VALUES -(1,1,1,78,0,0), -(1,1,0,6603,0,0), -(1,1,11,117,128,0), -(1,2,2,635,0,0), -(1,2,0,6603,0,0), -(1,2,1,21084,0,0), -(1,2,10,159,128,0), -(1,2,11,2070,128,0), -(1,4,1,1752,0,0), -(1,4,2,2098,0,0), -(1,4,3,2764,0,0), -(1,4,0,6603,0,0), -(1,4,11,2070,128,0), -(1,5,1,585,0,0), -(1,5,2,2050,0,0), -(1,5,0,6603,0,0), -(1,5,10,159,128,0), -(1,5,11,2070,128,0), -(1,6,0,6603,0,0), -(1,6,1,49576,0,0), -(1,6,2,45477,0,0), -(1,6,3,45462,0,0), -(1,6,4,45902,0,0), -(1,6,5,47541,0,0), -(1,6,11,59752,0,0), -(1,8,1,133,0,0), -(1,8,2,168,0,0), -(1,8,0,6603,0,0), -(1,8,10,159,128,0), -(1,8,11,2070,128,0), -(1,9,1,686,0,0), -(1,9,2,687,0,0), -(1,9,0,6603,0,0), -(1,9,10,159,128,0), -(1,9,11,4604,128,0), -(2,1,1,78,0,0), -(2,1,0,6603,0,0), -(2,1,11,117,128,0), -(2,3,2,75,0,0), -(2,3,1,2973,0,0), -(2,3,0,6603,0,0), -(2,3,11,117,128,0), -(2,3,10,159,128,0), -(2,4,10,0,128,0), -(2,4,1,1752,0,0), -(2,4,2,2098,0,0), -(2,4,0,6603,0,0), -(2,4,11,117,128,0), -(2,6,0,6603,0,0), -(2,6,1,49576,0,0), -(2,6,2,45477,0,0), -(2,6,3,45462,0,0), -(2,6,4,45902,0,0), -(2,6,5,47541,0,0), -(2,6,10,20572,0,0), -(2,7,2,331,0,0), -(2,7,1,403,0,0), -(2,7,0,6603,0,0), -(2,7,11,117,128,0), -(2,7,10,159,128,0), -(2,9,1,686,0,0), -(2,9,2,687,0,0), -(2,9,0,6603,0,0), -(2,9,11,117,128,0), -(2,9,10,159,128,0), -(3,1,1,78,0,0), -(3,1,0,6603,0,0), -(3,1,11,117,128,0), -(3,2,2,635,0,0), -(3,2,0,6603,0,0), -(3,2,1,21084,0,0), -(3,2,10,159,128,0), -(3,2,11,4540,128,0), -(3,3,2,75,0,0), -(3,3,1,2973,0,0), -(3,3,0,6603,0,0), -(3,3,11,117,128,0), -(3,3,10,159,128,0), -(3,4,1,1752,0,0), -(3,4,2,2098,0,0), -(3,4,3,2764,0,0), -(3,4,0,6603,0,0), -(3,4,11,4540,128,0), -(3,5,1,585,0,0), -(3,5,2,2050,0,0), -(3,5,0,6603,0,0), -(3,5,10,159,128,0), -(3,5,11,4540,128,0), -(3,6,0,6603,0,0), -(3,6,1,49576,0,0), -(3,6,2,45477,0,0), -(3,6,3,45462,0,0), -(3,6,4,45902,0,0), -(3,6,5,47541,0,0), -(3,6,10,2481,0,0), -(4,1,1,78,0,0), -(4,1,0,6603,0,0), -(4,1,11,117,128,0), -(4,3,2,75,0,0), -(4,3,1,2973,0,0), -(4,3,0,6603,0,0), -(4,3,11,117,128,0), -(4,3,10,159,128,0), -(4,4,1,1752,0,0), -(4,4,2,2098,0,0), -(4,4,3,2764,0,0), -(4,4,0,6603,0,0), -(4,4,11,4540,128,0), -(4,5,1,585,0,0), -(4,5,2,2050,0,0), -(4,5,0,6603,0,0), -(4,5,10,159,128,0), -(4,5,11,2070,128,0), -(4,6,0,6603,0,0), -(4,6,1,49576,0,0), -(4,6,2,45477,0,0), -(4,6,3,45462,0,0), -(4,6,4,45902,0,0), -(4,6,5,47541,0,0), -(4,6,10,58984,0,0), -(4,6,83,58984,0,0), -(4,11,1,5176,0,0), -(4,11,2,5185,0,0), -(4,11,0,6603,0,0), -(4,11,10,159,128,0), -(4,11,11,4536,128,0), -(5,1,11,4604,128,0), -(5,1,0,6603,0,0), -(5,1,1,78,0,0), -(5,4,11,4604,128,0), -(5,4,3,2764,0,0), -(5,4,2,2098,0,0), -(5,4,1,1752,0,0), -(5,4,0,6603,0,0), -(5,5,10,159,128,0), -(5,5,2,2050,0,0), -(5,5,1,585,0,0), -(5,5,11,4604,128,0), -(5,5,0,6603,0,0), -(5,6,0,6603,0,0), -(5,6,1,49576,0,0), -(5,6,2,45477,0,0), -(5,6,3,45462,0,0), -(5,6,4,45902,0,0), -(5,6,5,47541,0,0), -(5,6,10,20577,0,0), -(5,8,11,4604,128,0), -(5,8,10,159,128,0), -(5,8,2,168,0,0), -(5,8,1,133,0,0), -(5,8,0,6603,0,0), -(5,9,1,686,0,0), -(5,9,10,159,128,0), -(5,9,2,687,0,0), -(5,9,11,4604,128,0), -(5,9,0,6603,0,0), -(6,1,1,78,0,0), -(6,1,2,20549,0,0), -(6,1,11,4540,128,0), -(6,1,0,6603,0,0), -(6,3,1,2973,0,0), -(6,3,10,159,128,0), -(6,3,2,75,0,0), -(6,3,3,20549,0,0), -(6,3,11,117,128,0), -(6,3,0,6603,0,0), -(6,6,0,6603,0,0), -(6,6,1,49576,0,0), -(6,6,2,45477,0,0), -(6,6,3,45462,0,0), -(6,6,4,45902,0,0), -(6,6,5,47541,0,0), -(6,6,10,20549,0,0), -(6,6,75,20549,0,0), -(6,7,1,403,0,0), -(6,7,10,159,128,0), -(6,7,2,331,0,0), -(6,7,3,20549,0,0), -(6,7,11,4604,128,0), -(6,7,0,6603,0,0), -(6,11,1,5176,0,0), -(6,11,10,159,128,0), -(6,11,2,5185,0,0), -(6,11,3,20549,0,0), -(6,11,11,4536,128,0), -(6,11,0,6603,0,0), -(7,1,11,117,128,0), -(7,1,1,78,0,0), -(7,1,0,6603,0,0), -(7,4,11,117,128,0), -(7,4,3,2764,0,0), -(7,4,1,1752,0,0), -(7,4,2,2098,0,0), -(7,4,0,6603,0,0), -(7,6,0,6603,0,0), -(7,6,1,49576,0,0), -(7,6,2,45477,0,0), -(7,6,3,45462,0,0), -(7,6,4,45902,0,0), -(7,6,5,47541,0,0), -(7,6,10,20589,0,0), -(7,6,72,6603,0,0), -(7,6,83,117,128,0), -(7,6,84,6603,0,0), -(7,6,96,6603,0,0), -(7,6,108,6603,0,0), -(7,8,11,4536,128,0), -(7,8,1,133,0,0), -(7,8,2,168,0,0), -(7,8,10,159,128,0), -(7,8,0,6603,0,0), -(7,9,11,4604,128,0), -(7,9,1,686,0,0), -(7,9,2,687,0,0), -(7,9,10,159,128,0), -(7,9,0,6603,0,0), -(8,1,11,117,128,0), -(8,1,1,78,0,0), -(8,1,3,2764,0,0), -(8,1,0,6603,0,0), -(8,3,10,159,128,0), -(8,3,11,4604,128,0), -(8,3,1,2973,0,0), -(8,3,2,75,0,0), -(8,3,0,6603,0,0), -(8,4,1,1752,0,0), -(8,4,3,2764,0,0), -(8,4,2,2098,0,0), -(8,4,11,117,128,0), -(8,4,0,6603,0,0), -(8,5,1,585,0,0), -(8,5,10,159,128,0), -(8,5,2,2050,0,0), -(8,5,11,4540,128,0), -(8,5,0,6603,0,0), -(8,6,0,6603,0,0), -(8,6,1,49576,0,0), -(8,6,2,45477,0,0), -(8,6,3,45462,0,0), -(8,6,4,45902,0,0), -(8,6,5,47541,0,0), -(8,6,10,50621,0,0), -(8,7,1,403,0,0), -(8,7,10,159,128,0), -(8,7,2,331,0,0), -(8,7,11,117,128,0), -(8,7,0,6603,0,0), -(8,8,1,133,0,0), -(8,8,10,159,128,0), -(8,8,2,168,0,0), -(8,8,11,117,128,0), -(8,8,0,6603,0,0), -(10,2,0,6603,0,0), -(10,2,1,21084,0,0), -(10,2,2,635,0,0), -(10,2,3,28734,0,0), -(10,2,4,28730,0,0), -(10,2,10,159,128,0), -(10,2,11,20857,128,0), -(10,3,0,6603,0,0), -(10,3,1,2973,0,0), -(10,3,2,75,0,0), -(10,3,3,28734,0,0), -(10,3,4,28730,0,0), -(10,3,10,159,128,0), -(10,3,11,20857,128,0), -(10,4,0,6603,0,0), -(10,4,1,1752,0,0), -(10,4,2,2098,0,0), -(10,4,3,2764,0,0), -(10,4,4,28734,0,0), -(10,4,5,25046,0,0), -(10,4,11,20857,128,0), -(10,5,0,6603,0,0), -(10,5,1,585,0,0), -(10,5,2,2050,0,0), -(10,5,3,28734,0,0), -(10,5,4,28730,0,0), -(10,5,10,159,128,0), -(10,5,11,20857,128,0), -(10,6,0,6603,0,0), -(10,6,1,49576,0,0), -(10,6,2,45477,0,0), -(10,6,3,45462,0,0), -(10,6,4,45902,0,0), -(10,6,5,47541,0,0), -(10,6,6,50613,0,0), -(10,8,0,6603,0,0), -(10,8,1,133,0,0), -(10,8,2,168,0,0), -(10,8,3,28734,0,0), -(10,8,4,28730,0,0), -(10,8,10,159,128,0), -(10,8,11,20857,128,0), -(10,9,11,20857,128,0), -(10,9,10,159,128,0), -(10,9,4,28730,0,0), -(10,9,3,28734,0,0), -(10,9,2,687,0,0), -(10,9,1,686,0,0), -(10,9,0,6603,0,0), -(11,1,0,6603,0,0), -(11,1,72,6603,0,0), -(11,1,73,78,0,0), -(11,1,74,28880,0,0), -(11,1,83,4540,128,0), -(11,1,84,6603,0,0), -(11,1,96,6603,0,0), -(11,1,108,6603,0,0), -(11,2,0,6603,0,0), -(11,2,1,21084,0,0), -(11,2,2,635,0,0), -(11,2,3,59542,0,0), -(11,2,10,159,128,0), -(11,2,11,4540,128,0), -(11,2,83,4540,128,0), -(11,3,0,6603,0,0), -(11,3,1,2973,0,0), -(11,3,2,75,0,0), -(11,3,3,59543,0,0), -(11,3,10,159,128,0), -(11,3,11,4540,128,0), -(11,3,72,6603,0,0), -(11,3,73,2973,0,0), -(11,3,74,75,0,0), -(11,3,82,159,128,0), -(11,3,83,4540,128,0), -(11,5,0,6603,0,0), -(11,5,1,585,0,0), -(11,5,2,2050,0,0), -(11,5,3,59544,0,0), -(11,5,10,159,128,0), -(11,5,11,4540,128,0), -(11,5,83,4540,128,0), -(11,6,0,6603,0,0), -(11,6,1,49576,0,0), -(11,6,2,45477,0,0), -(11,6,3,45462,0,0), -(11,6,4,45902,0,0), -(11,6,5,47541,0,0), -(11,6,6,59545,0,0), -(11,7,0,6603,0,0), -(11,7,1,403,0,0), -(11,7,2,331,0,0), -(11,7,3,59547,0,0), -(11,7,10,159,128,0), -(11,7,11,4540,128,0), -(11,8,0,6603,0,0), -(11,8,1,133,0,0), -(11,8,2,168,0,0), -(11,8,3,59548,0,0), -(11,8,10,159,128,0), -(11,8,11,4540,128,0), -(11,8,83,4540,128,0); +(1,1,1,78,0), +(1,1,0,6603,0), +(1,1,11,117,128), +(1,2,2,635,0), +(1,2,0,6603,0), +(1,2,1,21084,0), +(1,2,10,159,128), +(1,2,11,2070,128), +(1,4,1,1752,0), +(1,4,2,2098,0), +(1,4,3,2764,0), +(1,4,0,6603,0), +(1,4,11,2070,128), +(1,5,1,585,0), +(1,5,2,2050,0), +(1,5,0,6603,0), +(1,5,10,159,128), +(1,5,11,2070,128), +(1,6,0,6603,0), +(1,6,1,49576,0), +(1,6,2,45477,0), +(1,6,3,45462,0), +(1,6,4,45902,0), +(1,6,5,47541,0), +(1,6,11,59752,0), +(1,8,1,133,0), +(1,8,2,168,0), +(1,8,0,6603,0), +(1,8,10,159,128), +(1,8,11,2070,128), +(1,9,1,686,0), +(1,9,2,687,0), +(1,9,0,6603,0), +(1,9,10,159,128), +(1,9,11,4604,128), +(2,1,1,78,0), +(2,1,0,6603,0), +(2,1,11,117,128), +(2,3,2,75,0), +(2,3,1,2973,0), +(2,3,0,6603,0), +(2,3,11,117,128), +(2,3,10,159,128), +(2,4,10,0,128), +(2,4,1,1752,0), +(2,4,2,2098,0), +(2,4,0,6603,0), +(2,4,11,117,128), +(2,6,0,6603,0), +(2,6,1,49576,0), +(2,6,2,45477,0), +(2,6,3,45462,0), +(2,6,4,45902,0), +(2,6,5,47541,0), +(2,6,10,20572,0), +(2,7,2,331,0), +(2,7,1,403,0), +(2,7,0,6603,0), +(2,7,11,117,128), +(2,7,10,159,128), +(2,9,1,686,0), +(2,9,2,687,0), +(2,9,0,6603,0), +(2,9,11,117,128), +(2,9,10,159,128), +(3,1,1,78,0), +(3,1,0,6603,0), +(3,1,11,117,128), +(3,2,2,635,0), +(3,2,0,6603,0), +(3,2,1,21084,0), +(3,2,10,159,128), +(3,2,11,4540,128), +(3,3,2,75,0), +(3,3,1,2973,0), +(3,3,0,6603,0), +(3,3,11,117,128), +(3,3,10,159,128), +(3,4,1,1752,0), +(3,4,2,2098,0), +(3,4,3,2764,0), +(3,4,0,6603,0), +(3,4,11,4540,128), +(3,5,1,585,0), +(3,5,2,2050,0), +(3,5,0,6603,0), +(3,5,10,159,128), +(3,5,11,4540,128), +(3,6,0,6603,0), +(3,6,1,49576,0), +(3,6,2,45477,0), +(3,6,3,45462,0), +(3,6,4,45902,0), +(3,6,5,47541,0), +(3,6,10,2481,0), +(4,1,1,78,0), +(4,1,0,6603,0), +(4,1,11,117,128), +(4,3,2,75,0), +(4,3,1,2973,0), +(4,3,0,6603,0), +(4,3,11,117,128), +(4,3,10,159,128), +(4,4,1,1752,0), +(4,4,2,2098,0), +(4,4,3,2764,0), +(4,4,0,6603,0), +(4,4,11,4540,128), +(4,5,1,585,0), +(4,5,2,2050,0), +(4,5,0,6603,0), +(4,5,10,159,128), +(4,5,11,2070,128), +(4,6,0,6603,0), +(4,6,1,49576,0), +(4,6,2,45477,0), +(4,6,3,45462,0), +(4,6,4,45902,0), +(4,6,5,47541,0), +(4,6,10,58984,0), +(4,6,83,58984,0), +(4,11,1,5176,0), +(4,11,2,5185,0), +(4,11,0,6603,0), +(4,11,10,159,128), +(4,11,11,4536,128), +(5,1,11,4604,128), +(5,1,0,6603,0), +(5,1,1,78,0), +(5,4,11,4604,128), +(5,4,3,2764,0), +(5,4,2,2098,0), +(5,4,1,1752,0), +(5,4,0,6603,0), +(5,5,10,159,128), +(5,5,2,2050,0), +(5,5,1,585,0), +(5,5,11,4604,128), +(5,5,0,6603,0), +(5,6,0,6603,0), +(5,6,1,49576,0), +(5,6,2,45477,0), +(5,6,3,45462,0), +(5,6,4,45902,0), +(5,6,5,47541,0), +(5,6,10,20577,0), +(5,8,11,4604,128), +(5,8,10,159,128), +(5,8,2,168,0), +(5,8,1,133,0), +(5,8,0,6603,0), +(5,9,1,686,0), +(5,9,10,159,128), +(5,9,2,687,0), +(5,9,11,4604,128), +(5,9,0,6603,0), +(6,1,1,78,0), +(6,1,2,20549,0), +(6,1,11,4540,128), +(6,1,0,6603,0), +(6,3,1,2973,0), +(6,3,10,159,128), +(6,3,2,75,0), +(6,3,3,20549,0), +(6,3,11,117,128), +(6,3,0,6603,0), +(6,6,0,6603,0), +(6,6,1,49576,0), +(6,6,2,45477,0), +(6,6,3,45462,0), +(6,6,4,45902,0), +(6,6,5,47541,0), +(6,6,10,20549,0), +(6,6,75,20549,0), +(6,7,1,403,0), +(6,7,10,159,128), +(6,7,2,331,0), +(6,7,3,20549,0), +(6,7,11,4604,128), +(6,7,0,6603,0), +(6,11,1,5176,0), +(6,11,10,159,128), +(6,11,2,5185,0), +(6,11,3,20549,0), +(6,11,11,4536,128), +(6,11,0,6603,0), +(7,1,11,117,128), +(7,1,1,78,0), +(7,1,0,6603,0), +(7,4,11,117,128), +(7,4,3,2764,0), +(7,4,1,1752,0), +(7,4,2,2098,0), +(7,4,0,6603,0), +(7,6,0,6603,0), +(7,6,1,49576,0), +(7,6,2,45477,0), +(7,6,3,45462,0), +(7,6,4,45902,0), +(7,6,5,47541,0), +(7,6,10,20589,0), +(7,6,72,6603,0), +(7,6,83,117,128), +(7,6,84,6603,0), +(7,6,96,6603,0), +(7,6,108,6603,0), +(7,8,11,4536,128), +(7,8,1,133,0), +(7,8,2,168,0), +(7,8,10,159,128), +(7,8,0,6603,0), +(7,9,11,4604,128), +(7,9,1,686,0), +(7,9,2,687,0), +(7,9,10,159,128), +(7,9,0,6603,0), +(8,1,11,117,128), +(8,1,1,78,0), +(8,1,3,2764,0), +(8,1,0,6603,0), +(8,3,10,159,128), +(8,3,11,4604,128), +(8,3,1,2973,0), +(8,3,2,75,0), +(8,3,0,6603,0), +(8,4,1,1752,0), +(8,4,3,2764,0), +(8,4,2,2098,0), +(8,4,11,117,128), +(8,4,0,6603,0), +(8,5,1,585,0), +(8,5,10,159,128), +(8,5,2,2050,0), +(8,5,11,4540,128), +(8,5,0,6603,0), +(8,6,0,6603,0), +(8,6,1,49576,0), +(8,6,2,45477,0), +(8,6,3,45462,0), +(8,6,4,45902,0), +(8,6,5,47541,0), +(8,6,10,50621,0), +(8,7,1,403,0), +(8,7,10,159,128), +(8,7,2,331,0), +(8,7,11,117,128), +(8,7,0,6603,0), +(8,8,1,133,0), +(8,8,10,159,128), +(8,8,2,168,0), +(8,8,11,117,128), +(8,8,0,6603,0), +(10,2,0,6603,0), +(10,2,1,21084,0), +(10,2,2,635,0), +(10,2,3,28734,0), +(10,2,4,28730,0), +(10,2,10,159,128), +(10,2,11,20857,128), +(10,3,0,6603,0), +(10,3,1,2973,0), +(10,3,2,75,0), +(10,3,3,28734,0), +(10,3,4,28730,0), +(10,3,10,159,128), +(10,3,11,20857,128), +(10,4,0,6603,0), +(10,4,1,1752,0), +(10,4,2,2098,0), +(10,4,3,2764,0), +(10,4,4,28734,0), +(10,4,5,25046,0), +(10,4,11,20857,128), +(10,5,0,6603,0), +(10,5,1,585,0), +(10,5,2,2050,0), +(10,5,3,28734,0), +(10,5,4,28730,0), +(10,5,10,159,128), +(10,5,11,20857,128), +(10,6,0,6603,0), +(10,6,1,49576,0), +(10,6,2,45477,0), +(10,6,3,45462,0), +(10,6,4,45902,0), +(10,6,5,47541,0), +(10,6,6,50613,0), +(10,8,0,6603,0), +(10,8,1,133,0), +(10,8,2,168,0), +(10,8,3,28734,0), +(10,8,4,28730,0), +(10,8,10,159,128), +(10,8,11,20857,128), +(10,9,11,20857,128), +(10,9,10,159,128), +(10,9,4,28730,0), +(10,9,3,28734,0), +(10,9,2,687,0), +(10,9,1,686,0), +(10,9,0,6603,0), +(11,1,0,6603,0), +(11,1,72,6603,0), +(11,1,73,78,0), +(11,1,74,28880,0), +(11,1,83,4540,128), +(11,1,84,6603,0), +(11,1,96,6603,0), +(11,1,108,6603,0), +(11,2,0,6603,0), +(11,2,1,21084,0), +(11,2,2,635,0), +(11,2,3,59542,0), +(11,2,10,159,128), +(11,2,11,4540,128), +(11,2,83,4540,128), +(11,3,0,6603,0), +(11,3,1,2973,0), +(11,3,2,75,0), +(11,3,3,59543,0), +(11,3,10,159,128), +(11,3,11,4540,128), +(11,3,72,6603,0), +(11,3,73,2973,0), +(11,3,74,75,0), +(11,3,82,159,128), +(11,3,83,4540,128), +(11,5,0,6603,0), +(11,5,1,585,0), +(11,5,2,2050,0), +(11,5,3,59544,0), +(11,5,10,159,128), +(11,5,11,4540,128), +(11,5,83,4540,128), +(11,6,0,6603,0), +(11,6,1,49576,0), +(11,6,2,45477,0), +(11,6,3,45462,0), +(11,6,4,45902,0), +(11,6,5,47541,0), +(11,6,6,59545,0), +(11,7,0,6603,0), +(11,7,1,403,0), +(11,7,2,331,0), +(11,7,3,59547,0), +(11,7,10,159,128), +(11,7,11,4540,128), +(11,8,0,6603,0), +(11,8,1,133,0), +(11,8,2,168,0), +(11,8,3,59548,0), +(11,8,10,159,128), +(11,8,11,4540,128), +(11,8,83,4540,128); /*!40000 ALTER TABLE `playercreateinfo_action` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/8098_01_characters_character_action.sql b/sql/updates/8098_01_characters_character_action.sql new file mode 100644 index 000000000..1ae612ab1 --- /dev/null +++ b/sql/updates/8098_01_characters_character_action.sql @@ -0,0 +1,10 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8072_02_characters_characters required_8098_01_characters_character_action bit; + +ALTER TABLE character_action + CHANGE COLUMN action action int(11) unsigned NOT NULL default '0'; + +UPDATE character_action + SET action = action | ( misc < 16 ); + +ALTER TABLE character_action + DROP COLUMN misc; diff --git a/sql/updates/8098_02_mangos_playercreateinfo_action.sql b/sql/updates/8098_02_mangos_playercreateinfo_action.sql new file mode 100644 index 000000000..f9bd79976 --- /dev/null +++ b/sql/updates/8098_02_mangos_playercreateinfo_action.sql @@ -0,0 +1,10 @@ +ALTER TABLE db_version CHANGE COLUMN required_8071_01_mangos_command required_8098_02_mangos_playercreateinfo_action bit; + +ALTER TABLE playercreateinfo_action + CHANGE COLUMN action action int(11) unsigned NOT NULL default '0'; + +UPDATE playercreateinfo_action + SET action = action | ( misc < 16 ); + +ALTER TABLE playercreateinfo_action + DROP COLUMN misc; diff --git a/sql/updates/8098_03_characters_character_pet.sql b/sql/updates/8098_03_characters_character_pet.sql new file mode 100644 index 000000000..d59e7729b --- /dev/null +++ b/sql/updates/8098_03_characters_character_pet.sql @@ -0,0 +1,13 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8098_01_characters_character_action required_8098_03_characters_character_pet bit; + +UPDATE character_pet + SET abdata = CONCAT( + (SUBSTRING(abdata, 1, length(SUBSTRING_INDEX(abdata, ' ', 1))) >> 8),' ', + SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 1))+2, length(SUBSTRING_INDEX(abdata, ' ', 2))-length(SUBSTRING_INDEX(abdata, ' ', 1))-1),' ', + (SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 2))+2, length(SUBSTRING_INDEX(abdata, ' ', 3))-length(SUBSTRING_INDEX(abdata, ' ', 2))-1) >> 8),' ', + SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 3))+2, length(SUBSTRING_INDEX(abdata, ' ', 4))-length(SUBSTRING_INDEX(abdata, ' ', 3))-1),' ', + (SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 4))+2, length(SUBSTRING_INDEX(abdata, ' ', 5))-length(SUBSTRING_INDEX(abdata, ' ', 4))-1) >> 8),' ', + SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 5))+2, length(SUBSTRING_INDEX(abdata, ' ', 6))-length(SUBSTRING_INDEX(abdata, ' ', 5))-1),' ', + (SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 6))+2, length(SUBSTRING_INDEX(abdata, ' ', 7))-length(SUBSTRING_INDEX(abdata, ' ', 6))-1) >> 8),' ', + SUBSTRING(abdata, length(SUBSTRING_INDEX(abdata, ' ', 7))+2, length(SUBSTRING_INDEX(abdata, ' ', 8))-length(SUBSTRING_INDEX(abdata, ' ', 7))-1),' ' + ); diff --git a/sql/updates/8098_04_characters_pet_spell.sql b/sql/updates/8098_04_characters_pet_spell.sql new file mode 100644 index 000000000..938c97632 --- /dev/null +++ b/sql/updates/8098_04_characters_pet_spell.sql @@ -0,0 +1,4 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8098_03_characters_character_pet required_8098_04_characters_pet_spell bit; + +UPDATE pet_spell + SET active = ( active >> 8); diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 087cdcaf1..48c1adc1f 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -235,6 +235,10 @@ pkgdata_DATA = \ 8071_01_mangos_command.sql \ 8072_01_characters_characters.sql \ 8072_02_characters_characters.sql \ + 8098_01_characters_character_action.sql \ + 8098_02_mangos_playercreateinfo_action.sql \ + 8098_03_characters_character_pet.sql \ + 8098_04_characters_pet_spell.sql \ README ## Additional files to include when running 'make dist' @@ -450,4 +454,8 @@ EXTRA_DIST = \ 8071_01_mangos_command.sql \ 8072_01_characters_characters.sql \ 8072_02_characters_characters.sql \ + 8098_01_characters_character_action.sql \ + 8098_02_mangos_playercreateinfo_action.sql \ + 8098_03_characters_character_pet.sql \ + 8098_04_characters_pet_spell.sql \ README diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index e53ecfdd5..a0799d0bc 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -68,7 +68,7 @@ bool LoginQueryHolder::Initialize() res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADDAILYQUESTSTATUS,"SELECT quest,time FROM character_queststatus_daily WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADREPUTATION, "SELECT faction,standing,flags FROM character_reputation WHERE guid = '%u'", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADINVENTORY, "SELECT data,bag,slot,item,item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag,slot", GUID_LOPART(m_guid)); - res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); + res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADACTIONS, "SELECT button,action,type FROM character_action WHERE guid = '%u' ORDER BY button", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = '%u' AND (checked & 1)=0 AND deliver_time <= '" UI64FMTD "'", GUID_LOPART(m_guid),(uint64)time(NULL)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADMAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = '%u' AND (checked & 1)=0", GUID_LOPART(m_guid)); res &= SetPQuery(PLAYER_LOGIN_QUERY_LOADSOCIALLIST, "SELECT friend,flags,note FROM character_social WHERE guid = '%u' LIMIT 255", GUID_LOPART(m_guid)); diff --git a/src/game/Creature.h b/src/game/Creature.h index d2c548e3c..416f7477a 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -294,7 +294,7 @@ struct CreatureData struct CreatureDataAddonAura { - uint16 spell_id; + uint32 spell_id; uint8 effect_idx; }; @@ -667,10 +667,10 @@ class MANGOS_DLL_SPEC Creature : public Unit virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; } virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const { - if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->active != ACT_ENABLED) + if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED) return 0; else - return m_charmInfo->GetCharmSpell(pos)->spellId; + return m_charmInfo->GetCharmSpell(pos)->GetAction(); } void SetCombatStartPosition(float x, float y, float z) { CombatStartX = x; CombatStartY = y; CombatStartZ = z; } diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index c727e292f..0f0c9e547 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -984,40 +984,41 @@ void WorldSession::HandleSetActionButtonOpcode(WorldPacket& recv_data) CHECK_PACKET_SIZE(recv_data,1+2+1+1); sLog.outDebug( "WORLD: Received CMSG_SET_ACTION_BUTTON" ); - uint8 button, misc, type; - uint16 action; - recv_data >> button >> action >> misc >> type; - sLog.outDetail( "BUTTON: %u ACTION: %u TYPE: %u MISC: %u", button, action, type, misc ); - if(action==0) + uint8 button; + uint32 packetData; + recv_data >> button >> packetData; + + uint32 action = ACTION_BUTTON_ACTION(packetData); + uint8 type = ACTION_BUTTON_TYPE(packetData); + + sLog.outDetail( "BUTTON: %u ACTION: %u TYPE: %u", button, action, type ); + if (!packetData) { sLog.outDetail( "MISC: Remove action from button %u", button ); - GetPlayer()->removeActionButton(button); } else { - if(type==ACTION_BUTTON_MACRO || type==ACTION_BUTTON_CMACRO) + switch(type) { - sLog.outDetail( "MISC: Added Macro %u into button %u", action, button ); - GetPlayer()->addActionButton(button,action,type,misc); + case ACTION_BUTTON_MACRO: + case ACTION_BUTTON_CMACRO: + sLog.outDetail( "MISC: Added Macro %u into button %u", action, button ); + break; + case ACTION_BUTTON_EQSET: + sLog.outDetail( "MISC: Added EquipmentSet %u into button %u", action, button ); + break; + case ACTION_BUTTON_SPELL: + sLog.outDetail( "MISC: Added Spell %u into button %u", action, button ); + break; + case ACTION_BUTTON_ITEM: + sLog.outDetail( "MISC: Added Item %u into button %u", action, button ); + break; + default: + sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button ); + return; } - else if(type==ACTION_BUTTON_EQSET) - { - sLog.outDetail( "MISC: Added EquipmentSet %u into button %u", action, button ); - GetPlayer()->addActionButton(button,action,type,misc); - } - else if(type==ACTION_BUTTON_SPELL) - { - sLog.outDetail( "MISC: Added Spell %u into button %u", action, button ); - GetPlayer()->addActionButton(button,action,type,misc); - } - else if(type==ACTION_BUTTON_ITEM) - { - sLog.outDetail( "MISC: Added Item %u into button %u", action, button ); - GetPlayer()->addActionButton(button,action,type,misc); - } - else - sLog.outError( "MISC: Unknown action button type %u for action %u into button %u", type, action, button ); + GetPlayer()->addActionButton(button,action,type); } } diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index f6ab57844..0d676571b 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -2404,8 +2404,8 @@ void ObjectMgr::LoadPlayerInfo() // Load playercreate actions { - // 0 1 2 3 4 5 - QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type, misc FROM playercreateinfo_action"); + // 0 1 2 3 4 + QueryResult *result = WorldDatabase.Query("SELECT race, class, button, action, type FROM playercreateinfo_action"); uint32 count = 0; @@ -2440,10 +2440,7 @@ void ObjectMgr::LoadPlayerInfo() } PlayerInfo* pInfo = &playerInfo[current_race][current_class]; - pInfo->action[0].push_back(fields[2].GetUInt16()); - pInfo->action[1].push_back(fields[3].GetUInt16()); - pInfo->action[2].push_back(fields[4].GetUInt16()); - pInfo->action[3].push_back(fields[5].GetUInt16()); + pInfo->action.push_back(PlayerCreateInfoAction(fields[2].GetUInt8(),fields[3].GetUInt32(),fields[4].GetUInt8())); bar.step(); ++count; diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 5897c1e1c..5acb7069d 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -422,8 +422,8 @@ void Pet::SavePetToDB(PetSaveMode mode) // save only spell slots from action bar for(uint32 i = ACTION_BAR_INDEX_PET_SPELL_START; i < ACTION_BAR_INDEX_PET_SPELL_END; ++i) { - ss << uint32(m_charmInfo->GetActionBarEntry(i)->Type) << " " - << uint32(m_charmInfo->GetActionBarEntry(i)->SpellOrAction) << " "; + ss << uint32(m_charmInfo->GetActionBarEntry(i)->GetType()) << " " + << uint32(m_charmInfo->GetActionBarEntry(i)->GetAction()) << " "; }; ss << "', " @@ -1102,7 +1102,7 @@ void Pet::_LoadSpells() { Field *fields = result->Fetch(); - addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt16()), PETSPELL_UNCHANGED); + addSpell(fields[0].GetUInt32(), ActiveStates(fields[1].GetUInt8()), PETSPELL_UNCHANGED); } while( result->NextRow() ); @@ -1404,8 +1404,8 @@ bool Pet::learnSpell(uint32 spell_id) Unit* owner = GetOwner(); if(owner && owner->GetTypeId() == TYPEID_PLAYER) { - WorldPacket data(SMSG_PET_LEARNED_SPELL, 2); - data << uint16(spell_id); + WorldPacket data(SMSG_PET_LEARNED_SPELL, 4); + data << uint32(spell_id); ((Player*)owner)->GetSession()->SendPacket(&data); ((Player*)owner)->PetSpellInitialize(); @@ -1461,8 +1461,8 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab) { if(!m_loading) { - WorldPacket data(SMSG_PET_REMOVED_SPELL, 2); - data << uint16(spell_id); + WorldPacket data(SMSG_PET_REMOVED_SPELL, 4); + data << uint32(spell_id); ((Player*)GetOwner())->GetSession()->SendPacket(&data); } } @@ -1527,8 +1527,9 @@ void Pet::CleanupActionBar() { for(int i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) if(UnitActionBarEntry const* ab = m_charmInfo->GetActionBarEntry(i)) - if(ab->SpellOrAction && ab->IsActionBarForSpell() && !HasSpell(ab->SpellOrAction)) - m_charmInfo->SetActionBar(i,0,ACT_DISABLED); + if(uint32 action = ab->GetAction()) + if(ab->IsActionBarForSpell() && !HasSpell(action)) + m_charmInfo->SetActionBar(i,0,ACT_DISABLED); } void Pet::InitPetCreateSpells() @@ -1903,7 +1904,7 @@ void Pet::CastPetAuras(bool current) void Pet::CastPetAura(PetAura const* aura) { - uint16 auraId = aura->GetAura(GetEntry()); + uint32 auraId = aura->GetAura(GetEntry()); if(!auraId) return; diff --git a/src/game/Pet.h b/src/game/Pet.h index 4c3c2bd3d..f41b77710 100644 --- a/src/game/Pet.h +++ b/src/game/Pet.h @@ -69,7 +69,7 @@ enum PetSpellType struct PetSpell { - uint16 active; // use instead enum (not good use *uint16* limited enum in case when value in enum not possitive in *int16*) + uint8 active; // use instead enum (not good use *uint8* limited enum in case when value in enum not possitive in *int8*) PetSpellState state : 8; PetSpellType type : 8; diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index ee5119251..441e40072 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -34,17 +34,18 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) CHECK_PACKET_SIZE(recv_data, 8+2+2+8); uint64 guid1; - uint16 spellid; - uint16 flag; + uint32 data; uint64 guid2; recv_data >> guid1; //pet guid - recv_data >> spellid; - recv_data >> flag; //delete = 0x0700 CastSpell = C100 + recv_data >> data; recv_data >> guid2; //tag guid + uint32 spellid = UNIT_ACTION_BUTTON_ACTION(data); + uint8 flag = UNIT_ACTION_BUTTON_TYPE(data); //delete = 0x07 CastSpell = C1 + // used also for charmed creature Unit* pet= ObjectAccessor::GetUnit(*_player, guid1); - sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), flag, spellid, uint32(GUID_LOPART(guid2)) ); + sLog.outDetail("HandlePetAction.Pet %u flag is %u, spellid is %u, target %u.", uint32(GUID_LOPART(guid1)), uint32(flag), spellid, uint32(GUID_LOPART(guid2)) ); if(!pet) { sLog.outError( "Pet %u not exist.", uint32(GUID_LOPART(guid1)) ); @@ -72,7 +73,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) switch(flag) { - case ACT_COMMAND: //0x0700 + case ACT_COMMAND: //0x07 switch(spellid) { case COMMAND_STAY: //flat=1792 //STAY @@ -121,7 +122,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) pet->SendPetAIReaction(guid1); } } - else // charmed player + else // charmed player { pet->Attack(TargetUnit,true); pet->SendPetAIReaction(guid1); @@ -143,10 +144,10 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) _player->Uncharm(); break; default: - sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid); + sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } break; - case ACT_REACTION: // 0x600 + case ACT_REACTION: // 0x6 switch(spellid) { case REACT_PASSIVE: //passive @@ -156,9 +157,9 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) break; } break; - case ACT_DISABLED: // 0x8100 spell (disabled), ignore - case ACT_PASSIVE: // 0x0100 - case ACT_ENABLED: // 0xC100 spell + case ACT_DISABLED: // 0x81 spell (disabled), ignore + case ACT_PASSIVE: // 0x01 + case ACT_ENABLED: // 0xC1 spell { Unit* unit_target = NULL; if (((Creature*)pet)->GetGlobalCooldown() > 0) @@ -258,7 +259,7 @@ void WorldSession::HandlePetAction( WorldPacket & recv_data ) break; } default: - sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", flag, spellid); + sLog.outError("WORLD: unknown PET flag Action %i and spellid %i.", uint32(flag), spellid); } } @@ -309,9 +310,6 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) sLog.outDetail( "HandlePetSetAction. CMSG_PET_SET_ACTION" ); uint64 petguid; - uint32 position; - uint16 spell_id; - uint16 act_state; uint8 count; recv_data >> petguid; @@ -339,11 +337,16 @@ void WorldSession::HandlePetSetAction( WorldPacket & recv_data ) count = (recv_data.size() == 24) ? 2 : 1; for(uint8 i = 0; i < count; ++i) { - recv_data >> position; - recv_data >> spell_id; - recv_data >> act_state; + uint32 position; + uint32 data; - sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, act_state); + recv_data >> position; + recv_data >> data; + + uint32 spell_id = UNIT_ACTION_BUTTON_ACTION(data); + uint8 act_state = UNIT_ACTION_BUTTON_TYPE(data); + + sLog.outDetail( "Player %s has changed pet spell action. Position: %u, Spell: %u, State: 0x%X", _player->GetName(), position, spell_id, uint32(act_state)); //ignore invalid position if(position >= MAX_UNIT_ACTION_BAR_INDEX) @@ -516,10 +519,9 @@ void WorldSession::HandlePetSpellAutocastOpcode( WorldPacket& recvPacket ) sLog.outDetail("CMSG_PET_SPELL_AUTOCAST"); uint64 guid; - uint16 spellid; - uint16 spellid2; //maybe second spell, automatically toggled off when first toggled on? + uint32 spellid; uint8 state; //1 for on, 0 for off - recvPacket >> guid >> spellid >> spellid2 >> state; + recvPacket >> guid >> spellid >> state; if(!_player->GetPet() && !_player->GetCharm()) return; diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 063ad145b..fa8c35b93 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -650,21 +650,8 @@ bool Player::Create( uint32 guidlow, const std::string& name, uint8 race, uint8 learnDefaultSpells(); // original action bar - std::list::const_iterator action_itr[4]; - for(int i=0; i<4; ++i) - action_itr[i] = info->action[i].begin(); - - for (; action_itr[0]!=info->action[0].end() && action_itr[1]!=info->action[1].end();) - { - uint16 taction[4]; - for(int i=0; i<4 ;++i) - taction[i] = (*action_itr[i]); - - addActionButton((uint8)taction[0], taction[1], (uint8)taction[2], (uint8)taction[3]); - - for(int i=0; i<4 ;++i) - ++action_itr[i]; - } + for (PlayerCreateInfoActions::const_iterator action_itr = info->action.begin(); action_itr != info->action.end(); ++action_itr) + addActionButton(action_itr->button,action_itr->action,action_itr->type); // original items CharStartOutfitEntry const* oEntry = NULL; @@ -5425,65 +5412,69 @@ void Player::SendInitialActionButtons() const sLog.outDetail( "Initializing Action Buttons for '%u'", GetGUIDLow() ); WorldPacket data(SMSG_ACTION_BUTTONS, 1+(MAX_ACTION_BUTTONS*4)); - data << uint8(0); // can be 0, 1, 2 + data << uint8(0); // can be 0, 1, 2 (talent spec) for(int button = 0; button < MAX_ACTION_BUTTONS; ++button) { ActionButtonList::const_iterator itr = m_actionButtons.find(button); if(itr != m_actionButtons.end() && itr->second.uState != ACTIONBUTTON_DELETED) - { - data << uint16(itr->second.action); - data << uint8(itr->second.misc); - data << uint8(itr->second.type); - } + data << uint32(itr->second.packedData); else - { data << uint32(0); - } } GetSession()->SendPacket( &data ); sLog.outDetail( "Action Buttons for '%u' Initialized", GetGUIDLow() ); } -bool Player::addActionButton(const uint8 button, const uint16 action, const uint8 type, const uint8 misc) +ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) { if(button >= MAX_ACTION_BUTTONS) { sLog.outError( "Action %u not added into button %u for player %s: button must be < 132", action, button, GetName() ); - return false; + return NULL; } - // check cheating with adding non-known spells to action bar - if(type==ACTION_BUTTON_SPELL) + if(action >= MAX_ACTION_BUTTON_ACTION_VALUE) { - if(!sSpellStore.LookupEntry(action)) - { - sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() ); - return false; - } - - if(!HasSpell(action)) - { - sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() ); - return false; - } + sLog.outError( "Action %u not added into button %u for player %s: action must be < %u", action, button, GetName(), MAX_ACTION_BUTTON_ACTION_VALUE ); + return NULL; } - ActionButtonList::iterator buttonItr = m_actionButtons.find(button); + switch(type) + { + case ACTION_BUTTON_SPELL: + if(!sSpellStore.LookupEntry(action)) + { + sLog.outError( "Action %u not added into button %u for player %s: spell not exist", action, button, GetName() ); + return NULL; + } - if (buttonItr==m_actionButtons.end()) - { // just add new button - m_actionButtons[button] = ActionButton(action,type,misc); + if(!HasSpell(action)) + { + sLog.outError( "Action %u not added into button %u for player %s: player don't known this spell", action, button, GetName() ); + return NULL; + } + break; + case ACTION_BUTTON_ITEM: + if(!objmgr.GetItemPrototype(action)) + { + sLog.outError( "Action %u not added into button %u for player %s: item not exist", action, button, GetName() ); + return NULL; + } + break; + default: + break; // pther cases not checked at this moment } - else - { // change state of current button - ActionButtonUpdateState uState = buttonItr->second.uState; - buttonItr->second = ActionButton(action,type,misc); - if (uState != ACTIONBUTTON_NEW) buttonItr->second.uState = ACTIONBUTTON_CHANGED; - }; - sLog.outDetail( "Player '%u' Added Action '%u' to Button '%u'", GetGUIDLow(), action, button ); - return true; + + // it create new button (NEW state) if need or return existed + ActionButton& ab = m_actionButtons[button]; + + // set data and update to CHANGED if not NEW + ab.SetActionAndType(action,ActionButtonType(type)); + + sLog.outDetail( "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUIDLow(), action, uint32(type), button ); + return &ab; } void Player::removeActionButton(uint8 button) @@ -14494,7 +14485,7 @@ void Player::_LoadActions(QueryResult *result) { m_actionButtons.clear(); - //QueryResult *result = CharacterDatabase.PQuery("SELECT button,action,type,misc FROM character_action WHERE guid = '%u' ORDER BY button",GetGUIDLow()); + //QueryResult *result = CharacterDatabase.PQuery("SELECT button,action,type FROM character_action WHERE guid = '%u' ORDER BY button",GetGUIDLow()); if(result) { @@ -14503,9 +14494,11 @@ void Player::_LoadActions(QueryResult *result) Field *fields = result->Fetch(); uint8 button = fields[0].GetUInt8(); + uint32 action = fields[1].GetUInt32(); + uint8 type = fields[2].GetUInt8(); - if(addActionButton(button, fields[1].GetUInt16(), fields[2].GetUInt8(), fields[3].GetUInt8())) - m_actionButtons[button].uState = ACTIONBUTTON_UNCHANGED; + if(ActionButton* ab = addActionButton(button, action, type)) + ab->uState = ACTIONBUTTON_UNCHANGED; else { sLog.outError( " ...at loading, and will deleted in DB also"); @@ -15080,7 +15073,7 @@ void Player::_LoadSpells(QueryResult *result) { Field *fields = result->Fetch(); - addSpell(fields[0].GetUInt16(), fields[1].GetBool(), false, false, fields[2].GetBool()); + addSpell(fields[0].GetUInt32(), fields[1].GetBool(), false, false, fields[2].GetBool()); } while( result->NextRow() ); @@ -15579,14 +15572,14 @@ void Player::_SaveActions() switch (itr->second.uState) { case ACTIONBUTTON_NEW: - CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type,misc) VALUES ('%u', '%u', '%u', '%u', '%u')", - GetGUIDLow(), (uint32)itr->first, (uint32)itr->second.action, (uint32)itr->second.type, (uint32)itr->second.misc ); + CharacterDatabase.PExecute("INSERT INTO character_action (guid,button,action,type) VALUES ('%u', '%u', '%u', '%u')", + GetGUIDLow(), (uint32)itr->first, (uint32)itr->second.GetAction(), (uint32)itr->second.GetType() ); itr->second.uState = ACTIONBUTTON_UNCHANGED; ++itr; break; case ACTIONBUTTON_CHANGED: - CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u', misc= '%u' WHERE guid= '%u' AND button= '%u' ", - (uint32)itr->second.action, (uint32)itr->second.type, (uint32)itr->second.misc, GetGUIDLow(), (uint32)itr->first ); + CharacterDatabase.PExecute("UPDATE character_action SET action = '%u', type = '%u' WHERE guid= '%u' AND button= '%u' ", + (uint32)itr->second.GetAction(), (uint32)itr->second.GetType(), GetGUIDLow(), (uint32)itr->first ); itr->second.uState = ACTIONBUTTON_UNCHANGED; ++itr; break; @@ -15597,7 +15590,7 @@ void Player::_SaveActions() default: ++itr; break; - }; + } } } @@ -16401,8 +16394,7 @@ void Player::PetSpellInitialize() if(itr->second.state == PETSPELL_REMOVED) continue; - data << uint16(itr->first); - data << uint16(itr->second.active); // pet spell active state isn't boolean + data << uint32(MAKE_UNIT_ACTION_BUTTON(itr->first,itr->second.active)); ++addlist; } } @@ -16490,7 +16482,7 @@ void Player::CharmSpellInitialize() { for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { - if(charmInfo->GetCharmSpell(i)->spellId) + if(charmInfo->GetCharmSpell(i)->GetAction()) ++addlist; } } @@ -16515,11 +16507,8 @@ void Player::CharmSpellInitialize() for(uint32 i = 0; i < CREATURE_MAX_SPELLS; ++i) { CharmSpellEntry *cspell = charmInfo->GetCharmSpell(i); - if(cspell->spellId) - { - data << uint16(cspell->spellId); - data << uint16(cspell->active); - } + if(cspell->GetAction()) + data << uint32(cspell->packedData); } } diff --git a/src/game/Player.h b/src/game/Player.h index 273adb993..66c119396 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -133,17 +133,6 @@ enum ActionButtonUpdateState ACTIONBUTTON_DELETED = 3 }; -struct ActionButton -{ - ActionButton() : action(0), type(0), misc(0), uState( ACTIONBUTTON_NEW ) {} - ActionButton(uint16 _action, uint8 _type, uint8 _misc) : action(_action), type(_type), misc(_misc), uState( ACTIONBUTTON_NEW ) {} - - uint16 action; - uint8 type; - uint8 misc; - ActionButtonUpdateState uState; -}; - enum ActionButtonType { ACTION_BUTTON_SPELL = 0, @@ -153,6 +142,32 @@ enum ActionButtonType ACTION_BUTTON_ITEM = 128 }; +#define ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) +#define ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) +#define MAX_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1) + +struct ActionButton +{ + ActionButton() : packedData(0), uState( ACTIONBUTTON_NEW ) {} + + uint32 packedData; + ActionButtonUpdateState uState; + + // helpers + ActionButtonType GetType() const { return ActionButtonType(ACTION_BUTTON_TYPE(packedData)); } + uint32 GetAction() const { return ACTION_BUTTON_ACTION(packedData); } + void SetActionAndType(uint32 action, ActionButtonType type) + { + uint32 newData = action | (uint32(type) << 24); + if (newData != packedData) + { + packedData = newData; + if (uState != ACTIONBUTTON_NEW) + uState = ACTIONBUTTON_CHANGED; + } + } +}; + #define MAX_ACTION_BUTTONS 132 //checked in 2.3.0 typedef std::map ActionButtonList; @@ -190,6 +205,18 @@ struct PlayerLevelInfo typedef std::list PlayerCreateInfoSpells; +struct PlayerCreateInfoAction +{ + PlayerCreateInfoAction() : button(0), type(0), action(0) {} + PlayerCreateInfoAction(uint8 _button, uint32 _action, uint8 _type) : button(_button), type(_type), action(_action) {} + + uint8 button; + uint8 type; + uint32 action; +}; + +typedef std::list PlayerCreateInfoActions; + struct PlayerInfo { // existence checked by displayId != 0 // existence checked by displayId != 0 @@ -206,7 +233,7 @@ struct PlayerInfo uint16 displayId_f; PlayerCreateInfoItems item; PlayerCreateInfoSpells spell; - std::list action[4]; + PlayerCreateInfoActions action; PlayerLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1 }; @@ -1513,7 +1540,7 @@ class MANGOS_DLL_SPEC Player : public Unit m_cinematic = cine; } - bool addActionButton(uint8 button, uint16 action, uint8 type, uint8 misc); + ActionButton* addActionButton(uint8 button, uint32 action, uint8 type); void removeActionButton(uint8 button); void SendInitialActionButtons() const; diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 2f188734a..17cc4694e 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -2087,10 +2087,10 @@ void SpellMgr::LoadSpellPetAuras() bar.step(); - uint16 spell = fields[0].GetUInt16(); + uint32 spell = fields[0].GetUInt32(); uint8 eff = fields[1].GetUInt8(); - uint16 pet = fields[2].GetUInt16(); - uint16 aura = fields[3].GetUInt16(); + uint32 pet = fields[2].GetUInt32(); + uint32 aura = fields[3].GetUInt32(); SpellPetAuraMap::iterator itr = mSpellPetAuraMap.find((spell<<8) + eff); if(itr != mSpellPetAuraMap.end()) diff --git a/src/game/SpellMgr.h b/src/game/SpellMgr.h index 71c8535ef..f6b71aeb6 100644 --- a/src/game/SpellMgr.h +++ b/src/game/SpellMgr.h @@ -487,20 +487,20 @@ class PetAura auras.clear(); } - PetAura(uint16 petEntry, uint16 aura, bool _removeOnChangePet, int _damage) : + PetAura(uint32 petEntry, uint32 aura, bool _removeOnChangePet, int _damage) : removeOnChangePet(_removeOnChangePet), damage(_damage) { auras[petEntry] = aura; } - uint16 GetAura(uint16 petEntry) const + uint32 GetAura(uint32 petEntry) const { - std::map::const_iterator itr = auras.find(petEntry); + std::map::const_iterator itr = auras.find(petEntry); if(itr != auras.end()) return itr->second; else { - std::map::const_iterator itr2 = auras.find(0); + std::map::const_iterator itr2 = auras.find(0); if(itr2 != auras.end()) return itr2->second; else @@ -508,7 +508,7 @@ class PetAura } } - void AddAura(uint16 petEntry, uint16 aura) + void AddAura(uint32 petEntry, uint32 aura) { auras[petEntry] = aura; } @@ -524,7 +524,7 @@ class PetAura } private: - std::map auras; + std::map auras; bool removeOnChangePet; int32 damage; }; @@ -633,7 +633,7 @@ class SpellMgr // Accessors (const or static functions) public: // Spell affects - SpellAffectEntry const*GetSpellAffect(uint16 spellId, uint8 effectId) const + SpellAffectEntry const*GetSpellAffect(uint32 spellId, uint8 effectId) const { SpellAffectMap::const_iterator itr = mSpellAffectMap.find((spellId<<8) + effectId); if( itr != mSpellAffectMap.end( ) ) @@ -833,7 +833,7 @@ class SpellMgr return mSkillLineAbilityMap.upper_bound(spell_id); } - PetAura const* GetPetAura(uint16 spell_id, uint8 eff) + PetAura const* GetPetAura(uint32 spell_id, uint8 eff) { SpellPetAuraMap::const_iterator itr = mSpellPetAuraMap.find((spell_id<<8) + eff); if(itr != mSpellPetAuraMap.end()) diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 5ddca82d2..fb91db413 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -10384,10 +10384,7 @@ CharmInfo::CharmInfo(Unit* unit) : m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_reactState(REACT_PASSIVE), m_petnumber(0) { for(int i =0; i<4; ++i) - { - m_charmspells[i].spellId = 0; - m_charmspells[i].active = ACT_DISABLED; - } + m_charmspells[i].SetActionAndType(0,ACT_DISABLED); } void CharmInfo::InitPetActionBar() @@ -10441,18 +10438,22 @@ void CharmInfo::InitCharmCreateSpells() for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) { uint32 spellId = ((Creature*)m_unit)->m_spells[x]; - m_charmspells[x].spellId = spellId; if(!spellId) + { + m_charmspells[x].SetActionAndType(spellId,ACT_DISABLED); continue; + } if (IsPassiveSpell(spellId)) { m_unit->CastSpell(m_unit, spellId, true); - m_charmspells[x].active = ACT_PASSIVE; + m_charmspells[x].SetActionAndType(spellId,ACT_PASSIVE); } else { + m_charmspells[x].SetActionAndType(spellId,ACT_DISABLED); + ActiveStates newstate; bool onlyselfcast = true; SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); @@ -10481,11 +10482,11 @@ bool CharmInfo::AddSpellToActionBar(uint32 spell_id, ActiveStates newstate) // new spell rank can be already listed for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) { - if (PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell()) + if (uint32 action = PetActionBar[i].GetAction()) { - if (spellmgr.GetFirstSpellInChain(PetActionBar[i].SpellOrAction) == first_id) + if (PetActionBar[i].IsActionBarForSpell() && spellmgr.GetFirstSpellInChain(action) == first_id) { - PetActionBar[i].SpellOrAction = spell_id; + PetActionBar[i].SetAction(spell_id); return true; } } @@ -10494,7 +10495,7 @@ bool CharmInfo::AddSpellToActionBar(uint32 spell_id, ActiveStates newstate) // or use empty slot in other case for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) { - if (!PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell()) + if (!PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) { SetActionBar(i,spell_id,newstate == ACT_DECIDE ? ACT_DISABLED : newstate); return true; @@ -10509,9 +10510,9 @@ bool CharmInfo::RemoveSpellFromActionBar(uint32 spell_id) for(uint8 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) { - if (PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell()) + if (uint32 action = PetActionBar[i].GetAction()) { - if (spellmgr.GetFirstSpellInChain(PetActionBar[i].SpellOrAction) == first_id) + if (PetActionBar[i].IsActionBarForSpell() && spellmgr.GetFirstSpellInChain(action) == first_id) { SetActionBar(i,0,ACT_DISABLED); return true; @@ -10528,12 +10529,8 @@ void CharmInfo::ToggleCreatureAutocast(uint32 spellid, bool apply) return; for(uint32 x = 0; x < CREATURE_MAX_SPELLS; ++x) - { - if(spellid == m_charmspells[x].spellId) - { - m_charmspells[x].active = apply ? ACT_ENABLED : ACT_DISABLED; - } - } + if(spellid == m_charmspells[x].GetAction()) + m_charmspells[x].SetType(apply ? ACT_ENABLED : ACT_DISABLED); } void CharmInfo::SetPetNumber(uint32 petnumber, bool statwindow) @@ -10559,12 +10556,14 @@ void CharmInfo::LoadPetActionBar(const std::string& data ) for(iter = tokens.begin(), index = ACTION_BAR_INDEX_PET_SPELL_START; index < ACTION_BAR_INDEX_PET_SPELL_END; ++iter, ++index ) { // use unsigned cast to avoid sign negative format use at long-> ActiveStates (int) conversion - PetActionBar[index].Type = atol((*iter).c_str()); + uint8 type = atol((*iter).c_str()); ++iter; - PetActionBar[index].SpellOrAction = atol((*iter).c_str()); + uint32 action = atol((*iter).c_str()); + + PetActionBar[index].SetActionAndType(action,ActiveStates(type)); // check correctness - if(PetActionBar[index].IsActionBarForSpell() && !sSpellStore.LookupEntry(PetActionBar[index].SpellOrAction)) + if(PetActionBar[index].IsActionBarForSpell() && !sSpellStore.LookupEntry(PetActionBar[index].GetAction())) SetActionBar(index,0,ACT_DISABLED); } } @@ -10572,19 +10571,16 @@ void CharmInfo::LoadPetActionBar(const std::string& data ) void CharmInfo::BuildActionBar( WorldPacket* data ) { for(uint32 i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) - { - *data << uint16(PetActionBar[i].SpellOrAction); - *data << uint16(PetActionBar[i].Type); - } + *data << uint32(PetActionBar[i].packedData); } void CharmInfo::SetSpellAutocast( uint32 spell_id, bool state ) { for(int i = 0; i < MAX_UNIT_ACTION_BAR_INDEX; ++i) { - if(spell_id == PetActionBar[i].SpellOrAction && PetActionBar[i].IsActionBarForSpell()) + if(spell_id == PetActionBar[i].GetAction() && PetActionBar[i].IsActionBarForSpell()) { - PetActionBar[i].Type = state ? ACT_ENABLED : ACT_DISABLED; + PetActionBar[i].SetType(state ? ACT_ENABLED : ACT_DISABLED); break; } } diff --git a/src/game/Unit.h b/src/game/Unit.h index b2b4704ae..fe35362b1 100644 --- a/src/game/Unit.h +++ b/src/game/Unit.h @@ -718,12 +718,12 @@ enum CurrentSpellTypes enum ActiveStates { - 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? + ACT_PASSIVE = 0x01, // 0x01 - passive + ACT_DISABLED = 0x81, // 0x80 - castable + ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable + ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04 + ACT_REACTION = 0x06, // 0x02 | 0x04 + ACT_DECIDE = 0x00 // custom }; enum ReactStates @@ -741,25 +741,43 @@ enum CommandStates COMMAND_ABANDON = 3 }; +#define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) +#define UNIT_ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) +#define MAX_UNIT_ACTION_BUTTON_ACTION_VALUE (0x00FFFFFF+1) +#define MAKE_UNIT_ACTION_BUTTON(A,T) (uint32(A) | (uint32(T) << 24)) + struct UnitActionBarEntry { - UnitActionBarEntry() : SpellOrAction(0), Type(ACT_DISABLED) {} + UnitActionBarEntry() : packedData(uint32(ACT_DISABLED) << 24) {} - uint16 SpellOrAction; - uint16 Type; + uint32 packedData; // helper + ActiveStates GetType() const { return ActiveStates(UNIT_ACTION_BUTTON_TYPE(packedData)); } + uint32 GetAction() const { return UNIT_ACTION_BUTTON_ACTION(packedData); } bool IsActionBarForSpell() const { + ActiveStates Type = GetType(); return Type == ACT_DISABLED || Type == ACT_ENABLED || Type == ACT_PASSIVE; } + + void SetActionAndType(uint32 action, ActiveStates type) + { + packedData = MAKE_UNIT_ACTION_BUTTON(action,type); + } + + void SetType(ActiveStates type) + { + packedData = MAKE_UNIT_ACTION_BUTTON(UNIT_ACTION_BUTTON_ACTION(packedData),type); + } + + void SetAction(uint32 action) + { + packedData = (packedData & 0xFF000000) | UNIT_ACTION_BUTTON_ACTION(action); + } }; -struct CharmSpellEntry -{ - uint16 spellId; - uint16 active; -}; +typedef UnitActionBarEntry CharmSpellEntry; enum ActionBarIndex { @@ -798,8 +816,7 @@ struct CharmInfo void SetSpellAutocast(uint32 spell_id, bool state); void SetActionBar(uint8 index, uint32 spellOrAction,ActiveStates type) { - PetActionBar[index].Type = type; - PetActionBar[index].SpellOrAction = spellOrAction; + PetActionBar[index].SetActionAndType(spellOrAction,type); } UnitActionBarEntry const* GetActionBarEntry(uint8 index) const { return &(PetActionBar[index]); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 10f38a9ad..4766153ff 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8097" + #define REVISION_NR "8098" #endif // __REVISION_NR_H__ From 29493ef7793e7d4ff92a93aa3291c91c91e01e7e Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 30 Jun 2009 12:25:34 +0400 Subject: [PATCH 27/36] [8099] Small not detected uint16 cases for spell ids. --- src/game/SpellMgr.cpp | 4 ++-- src/shared/revision_nr.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 17cc4694e..1de3ec546 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -720,7 +720,7 @@ void SpellMgr::LoadSpellAffects() bar.step(); - uint16 entry = fields[0].GetUInt16(); + uint32 entry = fields[0].GetUInt32(); uint8 effectId = fields[1].GetUInt8(); SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry); @@ -1039,7 +1039,7 @@ void SpellMgr::LoadSpellElixirs() bar.step(); - uint16 entry = fields[0].GetUInt16(); + uint32 entry = fields[0].GetUInt32(); uint8 mask = fields[1].GetUInt8(); SpellEntry const* spellInfo = sSpellStore.LookupEntry(entry); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4766153ff..0bac1055c 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8098" + #define REVISION_NR "8099" #endif // __REVISION_NR_H__ From 2b716341875cc425735104a0c3f22d003202ec84 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 1 Jul 2009 01:12:33 +0400 Subject: [PATCH 28/36] [8100] Include known MaNGOS EULA. --- EULA | 9 +++++++++ src/shared/revision_nr.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 EULA diff --git a/EULA b/EULA new file mode 100644 index 000000000..719f9fdbe --- /dev/null +++ b/EULA @@ -0,0 +1,9 @@ +MaNGOS End-User License Agreement + +MaNGOS has been built with education as the main target, thus you may only use +the source code and binary releases provided by the project for educational +purposes. You are not allowed to use MaNGOS for any commercial purpose, and you +are not allowed to use MaNGOS for hosting MaNGOS servers for public usage. + +By translating the supplied source code into binary form and running the final +executable you agree with MaNGOS EULA. diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 0bac1055c..c9b62f044 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8099" + #define REVISION_NR "8100" #endif // __REVISION_NR_H__ From dc106201480aac140db64e91511e4b6db1c5d7dc Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 1 Jul 2009 06:40:43 +0400 Subject: [PATCH 29/36] [8101] Prevent use talents as quest rewards or spell_learn_spell learned spells. --- src/game/ObjectMgr.cpp | 22 ++++++++++++++++++---- src/game/SpellMgr.cpp | 8 +++++++- src/shared/revision_nr.h | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index 0d676571b..a56a2fa6d 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -3595,13 +3595,20 @@ void ObjectMgr::LoadQuests() qinfo->RewSpell = 0; // no spell reward will display for this quest } - else if(!SpellMgr::IsSpellValid(spellInfo)) + if(!SpellMgr::IsSpellValid(spellInfo)) { - sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is broken, quest can't be done.", + sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is broken, quest will not have a spell reward.", qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell); qinfo->RewSpell = 0; // no spell reward will display for this quest } + if(GetTalentSpellCost(qinfo->RewSpell)) + { + sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is talent, quest will not have a spell reward.", + qinfo->GetQuestId(),qinfo->RewSpell,qinfo->RewSpell); + qinfo->RewSpell = 0; // no spell reward will display for this quest + continue; + } } if(qinfo->RewSpellCast) @@ -3615,13 +3622,20 @@ void ObjectMgr::LoadQuests() qinfo->RewSpellCast = 0; // no spell will be casted on player } - else if(!SpellMgr::IsSpellValid(spellInfo)) + if(!SpellMgr::IsSpellValid(spellInfo)) { - sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u is broken, quest can't be done.", + sLog.outErrorDb("Quest %u has `RewSpellCast` = %u but spell %u is broken, quest will not have a spell reward.", qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast); qinfo->RewSpellCast = 0; // no spell will be casted on player } + if(GetTalentSpellCost(qinfo->RewSpellCast)) + { + sLog.outErrorDb("Quest %u has `RewSpell` = %u but spell %u is talent, quest will not have a spell reward.", + qinfo->GetQuestId(),qinfo->RewSpellCast,qinfo->RewSpellCast); + qinfo->RewSpellCast = 0; // no spell will be casted on player + continue; + } } if(qinfo->RewMailTemplateId) diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp index 1de3ec546..23b2762bc 100644 --- a/src/game/SpellMgr.cpp +++ b/src/game/SpellMgr.cpp @@ -1859,7 +1859,13 @@ void SpellMgr::LoadSpellLearnSpells() if(!sSpellStore.LookupEntry(node.spell)) { - sLog.outErrorDb("Spell %u listed in `spell_learn_spell` does not exist",node.spell); + sLog.outErrorDb("Spell %u listed in `spell_learn_spell` learning not existed spell %u",spell_id,node.spell); + continue; + } + + if(GetTalentSpellCost(node.spell)) + { + sLog.outErrorDb("Spell %u listed in `spell_learn_spell` attempt learning talent spell %u, skipped",spell_id,node.spell); continue; } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index c9b62f044..928a6426f 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8100" + #define REVISION_NR "8101" #endif // __REVISION_NR_H__ From 9f417728284d4bd1ae909c4933e7dfab70484970 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 1 Jul 2009 11:05:55 +0400 Subject: [PATCH 30/36] [8102] Simplify code base at new root method WorldObject::CleanupsBeforeDelete * Call it from Map::AddObjectToRemoveList and remove now not needed explcit calls * Create Gameobject version to make GO with owner more safe for remove --- src/game/BattleGround.cpp | 1 - src/game/GameEventMgr.cpp | 3 --- src/game/GameObject.cpp | 13 ++++++++----- src/game/GameObject.h | 1 + src/game/Level2.cpp | 5 ----- src/game/Map.cpp | 3 ++- src/game/Object.cpp | 13 +++++-------- src/game/Object.h | 2 ++ src/game/Pet.cpp | 1 - src/game/Player.cpp | 1 - src/game/PoolHandler.cpp | 3 --- src/game/TemporarySummon.cpp | 1 - src/game/Totem.cpp | 1 - src/game/Vehicle.cpp | 1 - src/shared/revision_nr.h | 2 +- 15 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/game/BattleGround.cpp b/src/game/BattleGround.cpp index 6cd190e0f..0ffc65ed6 100644 --- a/src/game/BattleGround.cpp +++ b/src/game/BattleGround.cpp @@ -1529,7 +1529,6 @@ bool BattleGround::DelCreature(uint32 type) sLog.outError("Can't find creature guid: %u",GUID_LOPART(m_BgCreatures[type])); return false; } - cr->CleanupsBeforeDelete(); cr->AddObjectToRemoveList(); m_BgCreatures[type] = 0; return true; diff --git a/src/game/GameEventMgr.cpp b/src/game/GameEventMgr.cpp index 3c0847895..b3ebb8935 100644 --- a/src/game/GameEventMgr.cpp +++ b/src/game/GameEventMgr.cpp @@ -599,10 +599,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) objmgr.RemoveCreatureFromGrid(*itr, data); if( Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT), (Creature*)NULL) ) - { - pCreature->CleanupsBeforeDelete(); pCreature->AddObjectToRemoveList(); - } } } diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 04b0351d2..493b4eaca 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -59,15 +59,18 @@ GameObject::GameObject() : WorldObject() } GameObject::~GameObject() +{ + CleanupsBeforeDelete(); +} + +void GameObject::CleanupsBeforeDelete() { if(m_uint32Values) // field array can be not exist if GameOBject not loaded { // Possible crash at access to deleted GO in Unit::m_gameobj - uint64 owner_guid = GetOwnerGUID(); - if(owner_guid) + if(uint64 owner_guid = GetOwnerGUID()) { - Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid); - if(owner) + if(Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid)) owner->RemoveGameObject(this,false); else { @@ -78,7 +81,7 @@ GameObject::~GameObject() ownerType = "pet"; sLog.outError("Delete GameObject (GUID: %u Entry: %u SpellId %u LinkedGO %u) that lost references to owner (GUID %u Type '%s') GO list. Crash possible later.", - GetGUIDLow(), GetGOInfo()->id, m_spellId, GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType); + GetGUIDLow(), GetGOInfo()->id, m_spellId, GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType); } } } diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 8f2e1908f..ff80e214f 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -467,6 +467,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject void AddToWorld(); void RemoveFromWorld(); + void CleanupsBeforeDelete(); bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state); void Update(uint32 p_time); diff --git a/src/game/Level2.cpp b/src/game/Level2.cpp index 7489cc8c5..a22640341 100644 --- a/src/game/Level2.cpp +++ b/src/game/Level2.cpp @@ -1337,7 +1337,6 @@ bool ChatHandler::HandleNpcDeleteCommand(const char* args) // Delete the creature unit->CombatStop(); unit->DeleteFromDB(); - unit->CleanupsBeforeDelete(); unit->AddObjectToRemoveList(); SendSysMessage(LANG_COMMAND_DELCREATMESSAGE); @@ -2783,7 +2782,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args) { wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); wpCreature->DeleteFromDB(); - wpCreature->CleanupsBeforeDelete(); wpCreature->AddObjectToRemoveList(); } @@ -2847,7 +2845,6 @@ bool ChatHandler::HandleWpModifyCommand(const char* args) { wpCreature = m_session->GetPlayer()->GetMap()->GetCreature(MAKE_NEW_GUID(wpGuid, VISUAL_WAYPOINT, HIGHGUID_UNIT)); wpCreature->DeleteFromDB(); - wpCreature->CleanupsBeforeDelete(); wpCreature->AddObjectToRemoveList(); // re-create Creature* wpCreature2 = new Creature; @@ -3127,7 +3124,6 @@ bool ChatHandler::HandleWpShowCommand(const char* args) else { pCreature->DeleteFromDB(); - pCreature->CleanupsBeforeDelete(); pCreature->AddObjectToRemoveList(); } @@ -3325,7 +3321,6 @@ bool ChatHandler::HandleWpShowCommand(const char* args) else { pCreature->DeleteFromDB(); - pCreature->CleanupsBeforeDelete(); pCreature->AddObjectToRemoveList(); } }while(result->NextRow()); diff --git a/src/game/Map.cpp b/src/game/Map.cpp index f8c02b975..35b6c539c 100644 --- a/src/game/Map.cpp +++ b/src/game/Map.cpp @@ -880,7 +880,6 @@ void Map::MoveAllCreaturesInMoveList() if((sLog.getLogFilter() & LOG_FILTER_CREATURE_MOVES)==0) sLog.outDebug("Creature (GUID: %u Entry: %u ) can't be move to unloaded respawn grid.",c->GetGUIDLow(),c->GetEntry()); #endif - c->CleanupsBeforeDelete(); AddObjectToRemoveList(c); } } @@ -2048,6 +2047,8 @@ void Map::AddObjectToRemoveList(WorldObject *obj) { assert(obj->GetMapId()==GetId() && obj->GetInstanceId()==GetInstanceId()); + obj->CleanupsBeforeDelete(); // remove or simplify at least cross referenced links + i_objectsToRemove.insert(obj); //sLog.outDebug("Object (GUID: %u TypeId: %u ) added to removing list.",obj->GetGUIDLow(),obj->GetTypeId()); } diff --git a/src/game/Object.cpp b/src/game/Object.cpp index 560d607c0..fc7826a51 100644 --- a/src/game/Object.cpp +++ b/src/game/Object.cpp @@ -1053,6 +1053,10 @@ WorldObject::WorldObject() { } +void WorldObject::CleanupsBeforeDelete() +{ +} + void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask ) { Object::_Create(guidlow, 0, guidhigh); @@ -1546,14 +1550,7 @@ Map const* WorldObject::GetBaseMap() const void WorldObject::AddObjectToRemoveList() { - Map* map = GetMap(); - if(!map) - { - sLog.outError("Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).",GetTypeId(),GetEntry(),GetGUIDLow(),GetMapId()); - return; - } - - map->AddObjectToRemoveList(this); + GetMap()->AddObjectToRemoveList(this); } Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime) diff --git a/src/game/Object.h b/src/game/Object.h index 9e1cdcdd1..aa53d628c 100644 --- a/src/game/Object.h +++ b/src/game/Object.h @@ -447,6 +447,8 @@ class MANGOS_DLL_SPEC WorldObject : public Object float GetAngle( const float x, const float y ) const; bool HasInArc( const float arcangle, const WorldObject* obj ) const; + virtual void CleanupsBeforeDelete(); // used in destructor or explicitly before mass creature delete to remove cross-references to already deleted units + virtual void SendMessageToSet(WorldPacket *data, bool self); virtual void SendMessageToSetInRange(WorldPacket *data, float dist, bool self); diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp index 5acb7069d..347d5ee5c 100644 --- a/src/game/Pet.cpp +++ b/src/game/Pet.cpp @@ -680,7 +680,6 @@ void Pet::Remove(PetSaveMode mode, bool returnreagent) owner->SetPet(0); } - CleanupsBeforeDelete(); AddObjectToRemoveList(); m_removed = true; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index fa8c35b93..0836685e6 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -16247,7 +16247,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) pet->SavePetToDB(mode); - pet->CleanupsBeforeDelete(); pet->AddObjectToRemoveList(); pet->m_removed = true; diff --git a/src/game/PoolHandler.cpp b/src/game/PoolHandler.cpp index 09a1d4293..dd0834b80 100644 --- a/src/game/PoolHandler.cpp +++ b/src/game/PoolHandler.cpp @@ -127,10 +127,7 @@ void PoolGroup::Despawn1Object(uint32 guid) objmgr.RemoveCreatureFromGrid(guid, data); if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) - { - pCreature->CleanupsBeforeDelete(); pCreature->AddObjectToRemoveList(); - } } } diff --git a/src/game/TemporarySummon.cpp b/src/game/TemporarySummon.cpp index 293ac9d5c..1ba714d63 100644 --- a/src/game/TemporarySummon.cpp +++ b/src/game/TemporarySummon.cpp @@ -165,7 +165,6 @@ void TemporarySummon::UnSummon() { CombatStop(); - CleanupsBeforeDelete(); AddObjectToRemoveList(); Unit* sum = m_summoner ? ObjectAccessor::GetUnit(*this, m_summoner) : NULL; diff --git a/src/game/Totem.cpp b/src/game/Totem.cpp index 98a5b7e12..6ba0e405e 100644 --- a/src/game/Totem.cpp +++ b/src/game/Totem.cpp @@ -122,7 +122,6 @@ void Totem::UnSummon() } } - CleanupsBeforeDelete(); AddObjectToRemoveList(); } diff --git a/src/game/Vehicle.cpp b/src/game/Vehicle.cpp index de587fcbe..c6c6f9279 100644 --- a/src/game/Vehicle.cpp +++ b/src/game/Vehicle.cpp @@ -92,6 +92,5 @@ void Vehicle::Dismiss() { SendObjectDeSpawnAnim(GetGUID()); CombatStop(); - CleanupsBeforeDelete(); AddObjectToRemoveList(); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 928a6426f..d7e5066f2 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8101" + #define REVISION_NR "8102" #endif // __REVISION_NR_H__ From 9f938a9ed4ad356c5e8f9e8137a445e07a1ec077 Mon Sep 17 00:00:00 2001 From: Ambal Date: Wed, 1 Jul 2009 12:04:58 +0400 Subject: [PATCH 31/36] [8103] More wide use IsInWorld checks and delayed at teleport operations. * IsInWorld used to prevent return unexpected not in world objects. * Delayed operations need to process its in world state. Signed-off-by: VladimirMangos --- src/game/AccountMgr.cpp | 2 +- src/game/AchievementMgr.cpp | 5 +- src/game/GameObject.cpp | 8 +- src/game/Group.cpp | 2 +- src/game/LFGHandler.cpp | 10 +++ src/game/MiscHandler.cpp | 4 + src/game/MovementHandler.cpp | 10 ++- src/game/NPCHandler.cpp | 4 +- src/game/ObjectAccessor.cpp | 10 ++- src/game/ObjectAccessor.h | 10 ++- src/game/ObjectGridLoader.cpp | 23 +----- src/game/PetHandler.cpp | 3 + src/game/Player.cpp | 133 +++++++++++++++++++++++++++++++++- src/game/Player.h | 21 ++++++ src/game/Unit.cpp | 7 +- src/game/WorldSession.cpp | 6 ++ src/shared/revision_nr.h | 2 +- 17 files changed, 220 insertions(+), 40 deletions(-) diff --git a/src/game/AccountMgr.cpp b/src/game/AccountMgr.cpp index a10b0575f..b3ed91c7e 100644 --- a/src/game/AccountMgr.cpp +++ b/src/game/AccountMgr.cpp @@ -75,7 +75,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accid) uint64 guid = MAKE_NEW_GUID(guidlo, 0, HIGHGUID_PLAYER); // kick if player currently - if(Player* p = ObjectAccessor::FindPlayer(guid)) + if(Player* p = ObjectAccessor::GetObjectInWorld(guid, (Player*)NULL)) { WorldSession* s = p->GetSession(); s->KickPlayer(); // mark session to remove at next session list update diff --git a/src/game/AchievementMgr.cpp b/src/game/AchievementMgr.cpp index f350d6df5..727ecce6b 100644 --- a/src/game/AchievementMgr.cpp +++ b/src/game/AchievementMgr.cpp @@ -32,6 +32,7 @@ #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "Language.h" +#include "MapManager.h" #include "Policies/SingletonImp.h" @@ -825,8 +826,8 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if(!miscvalue1) continue; - Map const* map = GetPlayer()->GetMap(); - if(!map->IsDungeon()) + Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : MapManager::Instance().FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); + if(!map || !map->IsDungeon()) continue; // search case diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 493b4eaca..cda2b5f3f 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -70,7 +70,13 @@ void GameObject::CleanupsBeforeDelete() // Possible crash at access to deleted GO in Unit::m_gameobj if(uint64 owner_guid = GetOwnerGUID()) { - if(Unit* owner = ObjectAccessor::GetUnit(*this,owner_guid)) + Unit* owner = NULL; + if(IS_PLAYER_GUID(owner_guid)) + owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL); + else + owner = ObjectAccessor::GetUnit(*this,owner_guid); + + if(owner) owner->RemoveGameObject(this,false); else { diff --git a/src/game/Group.cpp b/src/game/Group.cpp index 0e4cb4e87..12e416d0b 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -963,7 +963,7 @@ void Group::SendUpdate() void Group::UpdatePlayerOutOfRange(Player* pPlayer) { - if(!pPlayer) + if(!pPlayer || !pPlayer->IsInWorld()) return; Player *player; diff --git a/src/game/LFGHandler.cpp b/src/game/LFGHandler.cpp index 17792dba5..5175fa4a3 100644 --- a/src/game/LFGHandler.cpp +++ b/src/game/LFGHandler.cpp @@ -40,6 +40,10 @@ static void AttemptJoin(Player* _player) if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam()) continue; + //skip players not in world + if(!plr->IsInWorld()) + continue; + // skip not auto add, not group leader cases if(!plr->GetSession()->LookingForGroup_auto_add || plr->GetGroup() && plr->GetGroup()->GetLeaderGUID()!=plr->GetGUID()) continue; @@ -96,6 +100,9 @@ static void AttemptAddMore(Player* _player) if(!plr || plr==_player || plr->GetTeam() != _player->GetTeam()) continue; + if(!plr->IsInWorld()) + continue; + // skip not auto join or in group if(!plr->GetSession()->LookingForGroup_auto_join || plr->GetGroup() ) continue; @@ -309,6 +316,9 @@ void WorldSession::SendLfgResult(uint32 type, uint32 entry, uint8 lfg_type) if(!plr || plr->GetTeam() != _player->GetTeam()) continue; + if(!plr->IsInWorld()) + continue; + if(!plr->m_lookingForGroup.HaveInSlot(entry, type)) continue; diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp index 0f0c9e547..4fd91ee27 100644 --- a/src/game/MiscHandler.cpp +++ b/src/game/MiscHandler.cpp @@ -170,6 +170,10 @@ void WorldSession::HandleWhoOpcode( WorldPacket & recv_data ) continue; } + //do not process players which are not in world + if(!(itr->second->IsInWorld())) + continue; + // check if target is globally visible for player if (!(itr->second->IsVisibleGloballyFor(_player))) continue; diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cpp index fd38c76bb..1638c9cb0 100644 --- a/src/game/MovementHandler.cpp +++ b/src/game/MovementHandler.cpp @@ -154,6 +154,9 @@ void WorldSession::HandleMoveWorldportAckOpcode() // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); + + //lets process all delayed operations on successful teleport + GetPlayer()->ProcessDelayedOperations(); } void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) @@ -200,6 +203,9 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) // resummon pet GetPlayer()->ResummonPetTemporaryUnSummonedIfAny(); + + //lets process all delayed operations on successful teleport + GetPlayer()->ProcessDelayedOperations(); } void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) @@ -329,8 +335,8 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data ) } else // creature charmed { - if(Map *map = mover->GetMap()) - map->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); + if(mover->IsInWorld()) + mover->GetMap()->CreatureRelocation((Creature*)mover, movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o); } } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index f36fa96b9..e5fb150bd 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -415,7 +415,7 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) uint64 npcGUID; recv_data >> npcGUID; - if(!GetPlayer()->isAlive()) + if(!GetPlayer()->IsInWorld() || !GetPlayer()->isAlive()) return; Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(npcGUID,UNIT_NPC_FLAG_INNKEEPER); @@ -435,7 +435,7 @@ void WorldSession::HandleBinderActivateOpcode( WorldPacket & recv_data ) void WorldSession::SendBindPoint(Creature *npc) { // prevent set homebind to instances in any case - if(sMapStore.LookupEntry(GetPlayer()->GetMapId())->Instanceable()) + if(GetPlayer()->GetMap()->Instanceable()) return; uint32 bindspell = 3286; diff --git a/src/game/ObjectAccessor.cpp b/src/game/ObjectAccessor.cpp index 43c38dde0..43eb02a8a 100644 --- a/src/game/ObjectAccessor.cpp +++ b/src/game/ObjectAccessor.cpp @@ -58,7 +58,7 @@ ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const &u, uint64 guid) if(IS_VEHICLE_GUID(guid)) return GetVehicle(guid); - return u.GetMap()->GetCreature(guid); + return u.IsInWorld() ? u.GetMap()->GetCreature(guid) : NULL; } Unit* @@ -131,7 +131,11 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const &p, uint64 guid, u Player* ObjectAccessor::FindPlayer(uint64 guid) { - return GetObjectInWorld(guid, (Player*)NULL); + Player * plr = GetObjectInWorld(guid, (Player*)NULL); + if(!plr || !plr->IsInWorld()) + return NULL; + + return plr; } Player* @@ -141,7 +145,7 @@ ObjectAccessor::FindPlayerByName(const char *name) HashMapHolder::MapType& m = HashMapHolder::GetContainer(); HashMapHolder::MapType::iterator iter = m.begin(); for(; iter != m.end(); ++iter) - if( ::strcmp(name, iter->second->GetName()) == 0 ) + if(iter->second->IsInWorld() && ( ::strcmp(name, iter->second->GetName()) == 0 )) return iter->second; return NULL; } diff --git a/src/game/ObjectAccessor.h b/src/game/ObjectAccessor.h index c2a37be05..6ed1b26cf 100644 --- a/src/game/ObjectAccessor.h +++ b/src/game/ObjectAccessor.h @@ -102,10 +102,16 @@ class MANGOS_DLL_DECL ObjectAccessor : public MaNGOS::Singleton::Find(guid); + { + Unit * u = (Unit*)HashMapHolder::Find(guid); + if(!u || !u->IsInWorld()) + return NULL; - if (Unit* u = (Unit*)HashMapHolder::Find(guid)) return u; + } + + if (IS_PET_GUID(guid)) + return (Unit*)HashMapHolder::Find(guid); return (Unit*)HashMapHolder::Find(guid); } diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index de73ee183..a3e5145f0 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -254,6 +254,10 @@ template void ObjectGridUnloader::Visit(GridRefManager &m) { + // remove all cross-reference before deleting + for(GridRefManager::iterator iter=m.begin(); iter != m.end(); ++iter) + iter->getSource()->CleanupsBeforeDelete(); + while(!m.isEmpty()) { T *obj = m.getFirst()->getSource(); @@ -267,25 +271,6 @@ ObjectGridUnloader::Visit(GridRefManager &m) } } -template<> -void -ObjectGridUnloader::Visit(CreatureMapType &m) -{ - // remove all cross-reference before deleting - for(CreatureMapType::iterator iter=m.begin(); iter != m.end(); ++iter) - iter->getSource()->CleanupsBeforeDelete(); - - while(!m.isEmpty()) - { - Creature *obj = m.getFirst()->getSource(); - // if option set then object already saved at this moment - if(!sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATLY)) - obj->SaveRespawnTime(); - ///- object will get delinked from the manager when deleted - delete obj; - } -} - void ObjectGridStoper::Stop(GridType &grid) { diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index 441e40072..a9f464b40 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -463,6 +463,9 @@ void WorldSession::HandlePetAbandon( WorldPacket & recv_data ) recv_data >> guid; //pet guid sLog.outDetail( "HandlePetAbandon. CMSG_PET_ABANDON pet guid is %u", GUID_LOPART(guid) ); + if(!_player->IsInWorld()) + return; + // pet/charmed Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if(pet) diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 0836685e6..72b2a7062 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -338,6 +338,11 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa mSemaphoreTeleport_Near = false; mSemaphoreTeleport_Far = false; + m_DelayedOperations = 0; + m_bCanDelayTeleport = false; + m_bHasDelayedTeleport = false; + m_teleport_options = 0; + pTrader = 0; ClearTrade(); @@ -1064,7 +1069,10 @@ void Player::Update( uint32 p_time ) m_nextMailDelivereTime = 0; } + //used to implement delayed far teleports + SetCanDelayTeleport(true); Unit::Update( p_time ); + SetCanDelayTeleport(false); // update player only attacks if(uint32 ranged_att = getAttackTimer(RANGED_ATTACK)) @@ -1326,8 +1334,12 @@ void Player::Update( uint32 p_time ) if(pet && !IsWithinDistInMap(pet, OWNER_MAX_DISTANCE) && (GetCharmGUID() && (pet->GetGUID() != GetCharmGUID()))) { RemovePet(pet, PET_SAVE_NOT_IN_SLOT, true); - return; } + + //we should execute delayed teleports only for alive(!) players + //because we don't want player's ghost teleported from graveyard + if(IsHasDelayedTeleport() && isAlive()) + TeleportTo(m_teleport_dest, m_teleport_options); } void Player::setDeathState(DeathState s) @@ -1611,6 +1623,21 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if ((GetMapId() == mapid) && (!m_transport)) { + //lets reset far teleport flag if it wasn't reset during chained teleports + SetSemaphoreTeleportFar(false); + //setup delayed teleport flag + SetDelayedTeleportFlag(IsCanDelayTeleport()); + //if teleport spell is casted in Unit::Update() func + //then we need to delay it until update process will be finished + if(IsHasDelayedTeleport()) + { + SetSemaphoreTeleportNear(true); + //lets save teleport destination for player + m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_options = options; + return true; + } + if (!(options & TELE_TO_NOT_UNSUMMON_PET)) { //same map, only remove pet if out of range for new position @@ -1652,6 +1679,21 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati Map *map = MapManager::Instance().FindMap(mapid); if (!map || map->CanEnter(this)) { + //lets reset near teleport flag if it wasn't reset during chained teleports + SetSemaphoreTeleportNear(false); + //setup delayed teleport flag + SetDelayedTeleportFlag(IsCanDelayTeleport()); + //if teleport spell is casted in Unit::Update() func + //then we need to delay it until update process will be finished + if(IsHasDelayedTeleport()) + { + SetSemaphoreTeleportFar(true); + //lets save teleport destination for player + m_teleport_dest = WorldLocation(mapid, x, y, z, orientation); + m_teleport_options = options; + return true; + } + SetSelection(0); CombatStop(); @@ -1681,6 +1723,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if(IsNonMeleeSpellCasted(true)) InterruptNonMeleeSpells(true); + //remove auras before removing from map... + RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); + if(!GetSession()->PlayerLogout()) { // send transfer packets @@ -1727,8 +1772,6 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // if the player is saved before worldportack (at logout for example) // this will be used instead of the current location in SaveToDB - RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CHANGE_MAP | AURA_INTERRUPT_FLAG_MOVE | AURA_INTERRUPT_FLAG_TURNING); - // move packet sent by client always after far teleport // code for finish transfer to new map called in WorldSession::HandleMoveWorldportAckOpcode at client packet SetSemaphoreTeleportFar(true); @@ -1739,6 +1782,53 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } +void Player::ProcessDelayedOperations() +{ + if(m_DelayedOperations == 0) + return; + + if(m_DelayedOperations & DELAYED_RESURRECT_PLAYER) + { + ResurrectPlayer(0.0f, false); + + if(GetMaxHealth() > m_resurrectHealth) + SetHealth( m_resurrectHealth ); + else + SetHealth( GetMaxHealth() ); + + if(GetMaxPower(POWER_MANA) > m_resurrectMana) + SetPower(POWER_MANA, m_resurrectMana ); + else + SetPower(POWER_MANA, GetMaxPower(POWER_MANA) ); + + SetPower(POWER_RAGE, 0 ); + SetPower(POWER_ENERGY, GetMaxPower(POWER_ENERGY) ); + + SpawnCorpseBones(); + } + + if(m_DelayedOperations & DELAYED_SAVE_PLAYER) + { + SaveToDB(); + } + + if(m_DelayedOperations & DELAYED_SPELL_CAST_DESERTER) + { + CastSpell(this, 26013, true); // Deserter + } + + //we have executed ALL delayed ops, so clear the flag + m_DelayedOperations = 0; +} + +void Player::ScheduleDelayedOperation(uint32 operation) +{ + if(operation >= DELAYED_END) + return; + + m_DelayedOperations |= operation; +} + void Player::AddToWorld() { ///- Do not add/remove the player from the object storage @@ -12081,7 +12171,11 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest ) } else { - GameObject *pGameObject = GetMap()->GetGameObject(guid); + //we should obtain map pointer from GetMap() in 99% of cases. Special case + //only for quests which cast teleport spells on player + Map * _map = IsInWorld() ? GetMap() : MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); + ASSERT(_map); + GameObject *pGameObject = _map->GetGameObject(guid); if( pGameObject ) { pObject = (Object*)pGameObject; @@ -12415,6 +12509,10 @@ void Player::IncompleteQuest( uint32 quest_id ) void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver, bool announce ) { + //this THING should be here to protect code from quest, which cast on player far teleport as a reward + //should work fine, cause far teleport will be executed in Player::Update() + SetCanDelayTeleport(true); + uint32 quest_id = pQuest->GetQuestId(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i ) @@ -12607,6 +12705,9 @@ void Player::RewardQuest( Quest const *pQuest, uint32 reward, Object* questGiver if( !HasAura(itr->second->spellId,0) ) CastSpell(this,itr->second->spellId,true); } + + //lets remove flag for delayed teleports + SetCanDelayTeleport(false); } void Player::FailQuest( uint32 quest_id ) @@ -15377,6 +15478,13 @@ void Player::SaveToDB() // delay auto save at any saves (manual, in code, or autosave) m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE); + //lets allow only players in world to be saved + if(IsBeingTeleportedFar()) + { + ScheduleDelayedOperation(DELAYED_SAVE_PLAYER); + return; + } + // first save/honor gain after midnight will also update the player's honor fields UpdateHonorFields(); @@ -17641,7 +17749,16 @@ void Player::LeaveBattleground(bool teleportToEntryPoint) if( bg->isBattleGround() && !isGameMaster() && sWorld.getConfig(CONFIG_BATTLEGROUND_CAST_DESERTER) ) { if( bg->GetStatus() == STATUS_IN_PROGRESS || bg->GetStatus() == STATUS_WAIT_JOIN ) + { + //lets check if player was teleported from BG and schedule delayed Deserter spell cast + if(IsBeingTeleportedFar()) + { + ScheduleDelayedOperation(DELAYED_SPELL_CAST_DESERTER); + return; + } + CastSpell(this, 26013, true); // Deserter + } } } } @@ -18868,6 +18985,14 @@ void Player::ResurectUsingRequestData() if(IS_PLAYER_GUID(m_resurrectGUID)) TeleportTo(m_resurrectMap, m_resurrectX, m_resurrectY, m_resurrectZ, GetOrientation()); + //we cannot resurrect player when we triggered far teleport + //player will be resurrected upon teleportation + if(IsBeingTeleportedFar()) + { + ScheduleDelayedOperation(DELAYED_RESURRECT_PLAYER); + return; + } + ResurrectPlayer(0.0f,false); if(GetMaxHealth() > m_resurrectHealth) diff --git a/src/game/Player.h b/src/game/Player.h index 66c119396..714766cdd 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -858,6 +858,14 @@ enum PlayerLoginQueryIndex MAX_PLAYER_LOGIN_QUERY = 21 }; +enum PlayerDelayedOperations +{ + DELAYED_SAVE_PLAYER = 1, + DELAYED_RESURRECT_PLAYER = 2, + DELAYED_SPELL_CAST_DESERTER = 4, + DELAYED_END +}; + // Player summoning auto-decline time (in secs) #define MAX_PLAYER_SUMMON_DELAY (2*MINUTE) #define MAX_MONEY_AMOUNT (0x7FFFFFFF-1) @@ -1757,6 +1765,7 @@ class MANGOS_DLL_SPEC Player : public Unit bool IsBeingTeleportedFar() const { return mSemaphoreTeleport_Far; } void SetSemaphoreTeleportNear(bool semphsetting) { mSemaphoreTeleport_Near = semphsetting; } void SetSemaphoreTeleportFar(bool semphsetting) { mSemaphoreTeleport_Far = semphsetting; } + void ProcessDelayedOperations(); void CheckExploreSystem(void); @@ -2397,6 +2406,13 @@ class MANGOS_DLL_SPEC Player : public Unit int32 CalculateReputationGain(uint32 creatureOrQuestLevel, int32 rep, int32 faction, bool for_quest); void AdjustQuestReqItemCount( Quest const* pQuest, QuestStatusData& questStatusData ); + bool IsCanDelayTeleport() const { return m_bCanDelayTeleport; } + void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; } + bool IsHasDelayedTeleport() const { return m_bHasDelayedTeleport; } + void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; } + + void ScheduleDelayedOperation(uint32 operation); + GridReference m_gridRef; MapReference m_mapRef; @@ -2410,9 +2426,14 @@ class MANGOS_DLL_SPEC Player : public Unit // Current teleport data WorldLocation m_teleport_dest; + uint32 m_teleport_options; bool mSemaphoreTeleport_Near; bool mSemaphoreTeleport_Far; + uint32 m_DelayedOperations; + bool m_bCanDelayTeleport; + bool m_bHasDelayedTeleport; + // Temporary removed pet cache uint32 m_temporaryUnsummonedPetNumber; uint32 m_oldpetspell; diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index fb91db413..7bd089463 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -176,6 +176,9 @@ Unit::~Unit() void Unit::Update( uint32 p_time ) { + if(!IsInWorld()) + return; + /*if(p_time > m_AurasCheck) { m_AurasCheck = 2000; @@ -7248,7 +7251,7 @@ bool Unit::Attack(Unit *victim, bool meleeAttack) return false; // dead units can neither attack nor be attacked - if(!isAlive() || !victim->isAlive()) + if(!isAlive() || !victim->IsInWorld() || !victim->isAlive()) return false; // player cannot attack in mount state @@ -8906,7 +8909,7 @@ bool Unit::isTargetableForAttack() const if(HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE)) return false; - return isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; + return IsInWorld() && isAlive() && !hasUnitState(UNIT_STAT_DIED)&& !isInFlight() /*&& !isStealth()*/; } int32 Unit::ModifyHealth(int32 dVal) diff --git a/src/game/WorldSession.cpp b/src/game/WorldSession.cpp index f0d11f587..89f6bb895 100644 --- a/src/game/WorldSession.cpp +++ b/src/game/WorldSession.cpp @@ -307,7 +307,13 @@ void WorldSession::LogoutPlayer(bool Save) ///- Teleport to home if the player is in an invalid instance if(!_player->m_InstanceValid && !_player->isGameMaster()) + { _player->TeleportTo(_player->m_homebindMapId, _player->m_homebindX, _player->m_homebindY, _player->m_homebindZ, _player->GetOrientation()); + //this is a bad place to call for far teleport because we need player to be in world for successful logout + //maybe we should implement delayed far teleport logout? + while(_player->IsBeingTeleportedFar()) + HandleMoveWorldportAckOpcode(); + } for (int i=0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index d7e5066f2..104d40568 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8102" + #define REVISION_NR "8103" #endif // __REVISION_NR_H__ From 131978c529c4bd57f7c258d2226f94b49860ef0c Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 1 Jul 2009 14:30:06 +0400 Subject: [PATCH 32/36] [8104] Always (except 2 cases) for tables in characters DB InnoDB and utf8. --- sql/characters.sql | 12 ++++++------ sql/updates/8104_01_characters.sql | 8 ++++++++ sql/updates/Makefile.am | 2 ++ src/shared/revision_nr.h | 2 +- 4 files changed, 17 insertions(+), 7 deletions(-) create mode 100644 sql/updates/8104_01_characters.sql diff --git a/sql/characters.sql b/sql/characters.sql index 8fb7327f2..0858b64cb 100644 --- a/sql/characters.sql +++ b/sql/characters.sql @@ -21,7 +21,7 @@ DROP TABLE IF EXISTS `character_db_version`; CREATE TABLE `character_db_version` ( - `required_8098_04_characters_pet_spell` bit(1) default NULL + `required_8104_01_characters` bit(1) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; -- @@ -264,7 +264,7 @@ CREATE TABLE `character_achievement` ( `achievement` int(11) unsigned NOT NULL, `date` bigint(11) unsigned NOT NULL default '0', PRIMARY KEY (`guid`,`achievement`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `character_achievement` @@ -286,7 +286,7 @@ CREATE TABLE `character_achievement_progress` ( `counter` int(11) unsigned NOT NULL, `date` bigint(11) unsigned NOT NULL default '0', PRIMARY KEY (`guid`,`criteria`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8; +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `character_achievement_progress` @@ -359,7 +359,7 @@ CREATE TABLE `character_declinedname` ( `instrumental` varchar(15) NOT NULL default '', `prepositional` varchar(15) NOT NULL default '', PRIMARY KEY (`guid`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; -- -- Dumping data for table `character_declinedname` @@ -559,7 +559,7 @@ CREATE TABLE `character_pet_declinedname` ( `prepositional` varchar(12) NOT NULL default '', PRIMARY KEY (`id`), KEY owner_key (`owner`) -) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; -- -- Dumping data for table `character_pet_declinedname` @@ -1020,7 +1020,7 @@ CREATE TABLE `guild_eventlog` ( `PlayerGuid2` int(11) NOT NULL COMMENT 'Player 2', `NewRank` tinyint(2) NOT NULL COMMENT 'New rank(in case promotion/demotion)', `TimeStamp` bigint(20) NOT NULL COMMENT 'Event UNIX time' -) ENGINE = InnoDB DEFAULT CHARSET = latin1 COMMENT 'Guild Eventlog'; +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'Guild Eventlog'; -- -- Dumping data for table `guild_eventlog` diff --git a/sql/updates/8104_01_characters.sql b/sql/updates/8104_01_characters.sql new file mode 100644 index 000000000..0575ab82d --- /dev/null +++ b/sql/updates/8104_01_characters.sql @@ -0,0 +1,8 @@ +ALTER TABLE character_db_version CHANGE COLUMN required_8098_04_characters_pet_spell required_8104_01_characters bit; + +ALTER TABLE character_achievement ENGINE=InnoDB DEFAULT CHARSET=utf8; +ALTER TABLE character_achievement_progress ENGINE=InnoDB DEFAULT CHARSET=utf8; +ALTER TABLE character_declinedname ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; +ALTER TABLE character_pet_declinedname ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC; +ALTER TABLE guild_eventlog ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT 'Guild Eventlog'; + diff --git a/sql/updates/Makefile.am b/sql/updates/Makefile.am index 48c1adc1f..5969c8cb1 100644 --- a/sql/updates/Makefile.am +++ b/sql/updates/Makefile.am @@ -239,6 +239,7 @@ pkgdata_DATA = \ 8098_02_mangos_playercreateinfo_action.sql \ 8098_03_characters_character_pet.sql \ 8098_04_characters_pet_spell.sql \ + 8104_01_characters.sql \ README ## Additional files to include when running 'make dist' @@ -458,4 +459,5 @@ EXTRA_DIST = \ 8098_02_mangos_playercreateinfo_action.sql \ 8098_03_characters_character_pet.sql \ 8098_04_characters_pet_spell.sql \ + 8104_01_characters.sql \ README diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 104d40568..379744361 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8103" + #define REVISION_NR "8104" #endif // __REVISION_NR_H__ From cac105f83efbb6d80c2b3d58586eb2a07b862960 Mon Sep 17 00:00:00 2001 From: BonDit Date: Wed, 1 Jul 2009 14:50:21 +0400 Subject: [PATCH 33/36] Fixed instance heroic/raid reset cooldown at switch normal/heroic difficalty. Signed-off-by: VladimirMangos --- src/game/InstanceSaveMgr.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index c19462472..375ca5dd9 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -128,7 +128,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) InstanceSaveHashMap::iterator itr = m_instanceSaveById.find( InstanceId ); if(itr != m_instanceSaveById.end()) { - // save the resettime for normal instances only when they get unloaded + // save the resettime for instances only when they get unloaded if(time_t resettime = itr->second->GetResetTimeForDB()) CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId); delete itr->second; @@ -173,12 +173,7 @@ void InstanceSave::SaveToDB() time_t InstanceSave::GetResetTimeForDB() { - // only save the reset time for normal instances - const MapEntry *entry = sMapStore.LookupEntry(GetMapId()); - if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DIFFICULTY_HEROIC) - return 0; - else - return GetResetTime(); + return GetResetTime(); } // to cache or not to cache, that is the question From 3f7351ec25858368dcd1846dff3ac7d8c6484d20 Mon Sep 17 00:00:00 2001 From: Ambal Date: Wed, 1 Jul 2009 14:21:54 +0200 Subject: [PATCH 34/36] [8105] Compile fix under Linux/BSD systems. Signed-off-by: ApoC --- src/game/ObjectGridLoader.cpp | 2 +- src/shared/revision_nr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/game/ObjectGridLoader.cpp b/src/game/ObjectGridLoader.cpp index a3e5145f0..77695e758 100644 --- a/src/game/ObjectGridLoader.cpp +++ b/src/game/ObjectGridLoader.cpp @@ -255,7 +255,7 @@ void ObjectGridUnloader::Visit(GridRefManager &m) { // remove all cross-reference before deleting - for(GridRefManager::iterator iter=m.begin(); iter != m.end(); ++iter) + for(typename GridRefManager::iterator iter=m.begin(); iter != m.end(); ++iter) iter->getSource()->CleanupsBeforeDelete(); while(!m.isEmpty()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 379744361..9e4250f21 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8104" + #define REVISION_NR "8105" #endif // __REVISION_NR_H__ From 8089b3bc91457d2ef565dcf5cc18d766af7dbcdd Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Thu, 2 Jul 2009 00:00:13 +0400 Subject: [PATCH 35/36] [8106] Revert "Fixed instance heroic/raid reset cooldown at switch normal/heroic difficalty." This reverts commit 655bb6125abcba28318b2074e1624bb4eb21cadd. After discussion with Wyk3d fix considered as wrong way. --- src/game/InstanceSaveMgr.cpp | 9 +++++++-- src/shared/revision_nr.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/game/InstanceSaveMgr.cpp b/src/game/InstanceSaveMgr.cpp index 375ca5dd9..c19462472 100644 --- a/src/game/InstanceSaveMgr.cpp +++ b/src/game/InstanceSaveMgr.cpp @@ -128,7 +128,7 @@ void InstanceSaveManager::RemoveInstanceSave(uint32 InstanceId) InstanceSaveHashMap::iterator itr = m_instanceSaveById.find( InstanceId ); if(itr != m_instanceSaveById.end()) { - // save the resettime for instances only when they get unloaded + // save the resettime for normal instances only when they get unloaded if(time_t resettime = itr->second->GetResetTimeForDB()) CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", (uint64)resettime, InstanceId); delete itr->second; @@ -173,7 +173,12 @@ void InstanceSave::SaveToDB() time_t InstanceSave::GetResetTimeForDB() { - return GetResetTime(); + // only save the reset time for normal instances + const MapEntry *entry = sMapStore.LookupEntry(GetMapId()); + if(!entry || entry->map_type == MAP_RAID || GetDifficulty() == DIFFICULTY_HEROIC) + return 0; + else + return GetResetTime(); } // to cache or not to cache, that is the question diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 9e4250f21..8d1dc83e8 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8105" + #define REVISION_NR "8106" #endif // __REVISION_NR_H__ From fbfbdf6d13da758184d525cb40c4db386e89123c Mon Sep 17 00:00:00 2001 From: GriffonHeart Date: Thu, 2 Jul 2009 09:17:50 +0400 Subject: [PATCH 36/36] [8107] Fixed sql queries included in [8098]. Old version break stored action spell ids, but this is not critical damage so restore data at applied damage not done in fix. But it will fix errors at new characters creating. Signed-off-by: VladimirMangos --- sql/updates/8098_01_characters_character_action.sql | 2 +- sql/updates/8098_02_mangos_playercreateinfo_action.sql | 2 +- src/shared/revision_nr.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/updates/8098_01_characters_character_action.sql b/sql/updates/8098_01_characters_character_action.sql index 1ae612ab1..eb5e7bb78 100644 --- a/sql/updates/8098_01_characters_character_action.sql +++ b/sql/updates/8098_01_characters_character_action.sql @@ -4,7 +4,7 @@ ALTER TABLE character_action CHANGE COLUMN action action int(11) unsigned NOT NULL default '0'; UPDATE character_action - SET action = action | ( misc < 16 ); + SET action = action | ( misc << 16 ); ALTER TABLE character_action DROP COLUMN misc; diff --git a/sql/updates/8098_02_mangos_playercreateinfo_action.sql b/sql/updates/8098_02_mangos_playercreateinfo_action.sql index f9bd79976..5a6f6f4f3 100644 --- a/sql/updates/8098_02_mangos_playercreateinfo_action.sql +++ b/sql/updates/8098_02_mangos_playercreateinfo_action.sql @@ -4,7 +4,7 @@ ALTER TABLE playercreateinfo_action CHANGE COLUMN action action int(11) unsigned NOT NULL default '0'; UPDATE playercreateinfo_action - SET action = action | ( misc < 16 ); + SET action = action | ( misc << 16 ); ALTER TABLE playercreateinfo_action DROP COLUMN misc; diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 8d1dc83e8..d8c5088ea 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8106" + #define REVISION_NR "8107" #endif // __REVISION_NR_H__