aboutsummaryrefslogtreecommitdiff
path: root/src/server/game
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/game')
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp2
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp2
-rw-r--r--src/server/game/Entities/Creature/GossipDef.cpp2
-rw-r--r--src/server/game/Entities/Player/Player.cpp8
-rw-r--r--src/server/game/Entities/Player/Player.h2
-rw-r--r--src/server/game/Entities/Unit/Unit.h7
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp2
-rw-r--r--src/server/game/Globals/ObjectMgr.h14
-rw-r--r--src/server/game/Handlers/QuestHandler.cpp82
-rw-r--r--src/server/game/Scripting/ScriptMgr.h31
11 files changed, 104 insertions, 50 deletions
diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
index 0a03c8ee336..5883270e9a0 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp
@@ -387,7 +387,7 @@ void ScriptedAI::SetCombatMovement(bool allowMovement)
_isCombatMovementAllowed = allowMovement;
}
-enum eNPCs
+enum NPCs
{
NPC_BROODLORD = 12017,
NPC_VOID_REAVER = 19516,
diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
index 4fb7232711c..ef15ef27ec4 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp
@@ -14,7 +14,7 @@ EndScriptData */
#include "Group.h"
#include "Player.h"
-enum ePoints
+enum Points
{
POINT_LAST_POINT = 0xFFFFFF,
POINT_HOME = 0xFFFFFE
diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
index 1c76399aa5c..8f46896f6e8 100644
--- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
+++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp
@@ -16,7 +16,7 @@ EndScriptData */
const float MAX_PLAYER_DISTANCE = 100.0f;
-enum ePoints
+enum Points
{
POINT_COMBAT_START = 0xFFFFFF
};
diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp
index 3cefc5881e9..c6119fc8a66 100644
--- a/src/server/game/Entities/Creature/GossipDef.cpp
+++ b/src/server/game/Entities/Creature/GossipDef.cpp
@@ -386,7 +386,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, uint64 npcGUID,
WorldPacket data(SMSG_QUESTGIVER_QUEST_DETAILS, 100); // guess size
data << uint64(npcGUID);
- data << uint64(0); // either 0 or a npc guid (quest giver)
+ data << uint64(_session->GetPlayer()->GetDivider());
data << uint32(quest->GetQuestId());
data << questTitle;
data << questDetails;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index f1282039323..77eb9152daa 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2150,7 +2150,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
ExitVehicle();
// reset movement flags at teleport, because player will continue move with these flags after teleport
- SetUnitMovementFlags(0);
+ SetUnitMovementFlags(GetUnitMovementFlags() & MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE);
m_movementInfo.ResetJump();
m_movementInfo.bits.hasPitch = false;
m_movementInfo.bits.hasSplineElevation = false;
@@ -16771,11 +16771,11 @@ void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver)
}
}
-void Player::SendPushToPartyResponse(Player* player, uint32 msg)
+void Player::SendPushToPartyResponse(Player* player, uint8 msg)
{
if (player)
{
- WorldPacket data(MSG_QUEST_PUSH_RESULT, (8+1));
+ WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 1);
data << uint64(player->GetGUID());
data << uint8(msg); // valid values: 0-8
GetSession()->SendPacket(&data);
@@ -19023,7 +19023,7 @@ bool Player::Satisfy(AccessRequirement const* ar, uint32 target_map, bool report
bool Player::CheckInstanceLoginValid()
{
- if (!GetMap())
+ if (!FindMap())
return false;
if (!GetMap()->IsDungeon() || IsGameMaster())
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 49cd037bd46..8a1f09b9312 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -1608,7 +1608,7 @@ class Player : public Unit, public GridObject<Player>
void SendQuestTimerFailed(uint32 quest_id);
void SendCanTakeQuestResponse(uint32 msg) const;
void SendQuestConfirmAccept(Quest const* quest, Player* pReceiver);
- void SendPushToPartyResponse(Player* player, uint32 msg);
+ void SendPushToPartyResponse(Player* player, uint8 msg);
void SendQuestUpdateAddCreatureOrGo(Quest const* quest, uint64 guid, uint32 creatureOrGO_idx, uint16 old_count, uint16 add_count);
void SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint16 add_count);
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index bd4b5b85de6..c595a0070c5 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -755,8 +755,13 @@ enum MovementFlags
/// @todo if needed: add more flags to this masks that are exclusive to players
MOVEMENTFLAG_MASK_PLAYER_ONLY =
- MOVEMENTFLAG_FLYING
+ MOVEMENTFLAG_FLYING,
+
+ /// Movement flags that have change status opcodes associated for players
+ MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT |
+ MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER
};
+
enum MovementFlags2
{
MOVEMENTFLAG2_NONE = 0x00000000,
diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp
index 5d090d883db..949f3b61dd0 100644
--- a/src/server/game/Globals/ObjectMgr.cpp
+++ b/src/server/game/Globals/ObjectMgr.cpp
@@ -2026,7 +2026,7 @@ uint64 ObjectMgr::GetPlayerGUIDByName(std::string const& name) const
return guid;
}
-bool ObjectMgr::GetPlayerNameByGUID(uint64 guid, std::string &name) const
+bool ObjectMgr::GetPlayerNameByGUID(uint64 guid, std::string& name) const
{
// prevent DB access for online player
if (Player* player = ObjectAccessor::FindPlayer(guid))
diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h
index 793f32de6bf..4666971923d 100644
--- a/src/server/game/Globals/ObjectMgr.h
+++ b/src/server/game/Globals/ObjectMgr.h
@@ -712,7 +712,19 @@ class ObjectMgr
void GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo* info) const;
uint64 GetPlayerGUIDByName(std::string const& name) const;
- bool GetPlayerNameByGUID(uint64 guid, std::string &name) const;
+
+ /**
+ * Retrieves the player name by guid.
+ *
+ * If the player is online, the name is retrieved immediately otherwise
+ * a database query is done.
+ *
+ * @param guid player full guid
+ * @param name returned name
+ *
+ * @return true if player was found, false otherwise
+ */
+ bool GetPlayerNameByGUID(uint64 guid, std::string& name) const;
uint32 GetPlayerTeamByGUID(uint64 guid) const;
uint32 GetPlayerAccountIdByGUID(uint64 guid) const;
uint32 GetPlayerAccountIdByPlayerName(std::string const& name) const;
diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp
index 12644ad2751..31adc0ac72c 100644
--- a/src/server/game/Handlers/QuestHandler.cpp
+++ b/src/server/game/Handlers/QuestHandler.cpp
@@ -120,15 +120,37 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
Object* object = ObjectAccessor::GetObjectByTypeMask(*_player, guid, TYPEMASK_UNIT|TYPEMASK_GAMEOBJECT|TYPEMASK_ITEM|TYPEMASK_PLAYER);
+#define CLOSE_GOSSIP_CLEAR_DIVIDER() \
+ do { \
+ _player->PlayerTalkClass->SendCloseGossip(); \
+ _player->SetDivider(0); \
+ } while (0)
+
// no or incorrect quest giver
- if (!object || (object->GetTypeId() != TYPEID_PLAYER && !object->hasQuest(questId)) ||
- (object->GetTypeId() == TYPEID_PLAYER && object != _player && !object->ToPlayer()->CanShareQuest(questId)))
+ if (!object)
{
- _player->PlayerTalkClass->SendCloseGossip();
- _player->SetDivider(0);
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
return;
}
+ if (Player* playerQuestObject = object->ToPlayer())
+ {
+ if ((_player->GetDivider() && _player->GetDivider() != guid) ||
+ ((object != _player && !playerQuestObject->CanShareQuest(questId))))
+ {
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
+ return;
+ }
+ }
+ else
+ {
+ if (!object->hasQuest(questId))
+ {
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
+ return;
+ }
+ }
+
// some kind of WPE protection
if (!_player->CanInteractWithQuestGiver(object))
return;
@@ -138,8 +160,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
// prevent cheating
if (!GetPlayer()->CanTakeQuest(quest, true))
{
- _player->PlayerTalkClass->SendCloseGossip();
- _player->SetDivider(0);
+ CLOSE_GOSSIP_CLEAR_DIVIDER();
return;
}
@@ -188,18 +209,19 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
{
case TYPEID_UNIT:
sScriptMgr->OnQuestAccept(_player, (object->ToCreature()), quest);
- (object->ToCreature())->AI()->sQuestAccept(_player, quest);
+ object->ToCreature()->AI()->sQuestAccept(_player, quest);
break;
case TYPEID_ITEM:
case TYPEID_CONTAINER:
{
- sScriptMgr->OnQuestAccept(_player, ((Item*)object), quest);
+ Item* item = (Item*)object;
+ sScriptMgr->OnQuestAccept(_player, item, quest);
// destroy not required for quest finish quest starting item
bool destroyItem = true;
for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i)
{
- if ((quest->RequiredItemId[i] == ((Item*)object)->GetEntry()) && (((Item*)object)->GetTemplate()->MaxCount > 0))
+ if (quest->RequiredItemId[i] == item->GetEntry() && item->GetTemplate()->MaxCount > 0)
{
destroyItem = false;
break;
@@ -207,13 +229,13 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
}
if (destroyItem)
- _player->DestroyItem(((Item*)object)->GetBagSlot(), ((Item*)object)->GetSlot(), true);
+ _player->DestroyItem(item->GetBagSlot(), item->GetSlot(), true);
break;
}
case TYPEID_GAMEOBJECT:
- sScriptMgr->OnQuestAccept(_player, ((GameObject*)object), quest);
- (object->ToGameObject())->AI()->QuestAccept(_player, quest);
+ sScriptMgr->OnQuestAccept(_player, object->ToGameObject(), quest);
+ object->ToGameObject()->AI()->QuestAccept(_player, quest);
break;
default:
break;
@@ -228,6 +250,8 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData)
}
_player->PlayerTalkClass->SendCloseGossip();
+
+#undef CLOSE_GOSSIP_CLEAR_DIVIDER
}
void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket& recvData)
@@ -561,7 +585,10 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
uint32 questId;
recvPacket >> questId;
- TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY questId = %u", questId);
+ if (!_player->CanShareQuest(questId))
+ return;
+
+ TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received CMSG_PUSHQUESTTOPARTY quest = %u", questId);
if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId))
{
@@ -574,8 +601,6 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
if (!player || player == _player) // skip self
continue;
- _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_SHARING_QUEST);
-
if (!player->SatisfyQuestStatus(quest, false))
{
_player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_HAVE_QUEST);
@@ -606,8 +631,22 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
continue;
}
- player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, _player->GetGUID(), true);
- player->SetDivider(_player->GetGUID());
+ _player->SendPushToPartyResponse(player, QUEST_PARTY_MSG_SHARING_QUEST);
+
+ if (quest->IsAutoAccept() && player->CanAddQuest(quest, true) && player->CanTakeQuest(quest, true))
+ {
+ player->AddQuest(quest, _player);
+ if (player->CanCompleteQuest(questId))
+ player->CompleteQuest(questId);
+ }
+
+ if ((quest->IsAutoComplete() && quest->IsRepeatable() && !quest->IsDailyOrWeekly()) || quest->HasFlag(QUEST_FLAGS_AUTOCOMPLETE))
+ player->PlayerTalkClass->SendQuestGiverRequestItems(quest, _player->GetGUID(), player->CanCompleteRepeatableQuest(quest), true);
+ else
+ {
+ player->SetDivider(_player->GetGUID());
+ player->PlayerTalkClass->SendQuestGiverQuestDetails(quest, _player->GetGUID(), true);
+ }
}
}
}
@@ -616,18 +655,19 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket)
void WorldSession::HandleQuestPushResult(WorldPacket& recvPacket)
{
uint64 guid;
+ uint32 questId;
uint8 msg;
- recvPacket >> guid >> msg;
+ recvPacket >> guid >> questId >> msg;
TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: Received MSG_QUEST_PUSH_RESULT");
- if (_player->GetDivider() != 0)
+ if (_player->GetDivider() && _player->GetDivider() == guid)
{
Player* player = ObjectAccessor::FindPlayer(_player->GetDivider());
if (player)
{
- WorldPacket data(MSG_QUEST_PUSH_RESULT, (8+1));
- data << uint64(guid);
+ WorldPacket data(MSG_QUEST_PUSH_RESULT, 8 + 4 + 1);
+ data << uint64(_player->GetGUID());
data << uint8(msg); // valid values: 0-8
player->GetSession()->SendPacket(&data);
_player->SetDivider(0);
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index 85797ac351b..1b8a24daa63 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -194,7 +194,7 @@ class SpellScriptLoader : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Should return a fully valid SpellScript pointer.
virtual SpellScript* GetSpellScript() const { return NULL; }
@@ -335,9 +335,6 @@ template<class TMap> class MapScript : public UpdatableScript<TMap>
// Called when a player leaves the map.
virtual void OnPlayerLeave(TMap* /*map*/, Player* /*player*/) { }
-
- // Called on every map update tick.
- virtual void OnUpdate(TMap* /*map*/, uint32 /*diff*/) { }
};
class WorldMapScript : public ScriptObject, public MapScript<Map>
@@ -355,7 +352,7 @@ class InstanceMapScript : public ScriptObject, public MapScript<InstanceMap>
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Gets an InstanceScript object for this instance.
virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; }
@@ -376,7 +373,7 @@ class ItemScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when a dummy spell effect is triggered on the item.
virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, Item* /*target*/) { return false; }
@@ -416,7 +413,7 @@ class CreatureScript : public UnitScript, public UpdatableScript<Creature>
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when a dummy spell effect is triggered on the creature.
virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, Creature* /*target*/) { return false; }
@@ -457,7 +454,7 @@ class GameObjectScript : public ScriptObject, public UpdatableScript<GameObject>
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when a dummy spell effect is triggered on the gameobject.
virtual bool OnDummyEffect(Unit* /*caster*/, uint32 /*spellId*/, SpellEffIndex /*effIndex*/, GameObject* /*target*/) { return false; }
@@ -504,7 +501,7 @@ class AreaTriggerScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when the area trigger is activated by a player.
virtual bool OnTrigger(Player* /*player*/, AreaTriggerEntry const* /*trigger*/) { return false; }
@@ -518,7 +515,7 @@ class BattlegroundScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Should return a fully valid Battleground object for the type ID.
virtual Battleground* GetBattleground() const = 0;
@@ -532,7 +529,7 @@ class OutdoorPvPScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Should return a fully valid OutdoorPvP object for the type ID.
virtual OutdoorPvP* GetOutdoorPvP() const = 0;
@@ -558,7 +555,7 @@ class WeatherScript : public ScriptObject, public UpdatableScript<Weather>
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when the weather changes in the zone this script is associated with.
virtual void OnChange(Weather* /*weather*/, WeatherState /*state*/, float /*grade*/) { }
@@ -593,7 +590,7 @@ class ConditionScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when a single condition is checked for a player.
virtual bool OnConditionCheck(Condition* /*condition*/, ConditionSourceInfo& /*sourceInfo*/) { return true; }
@@ -641,7 +638,7 @@ class TransportScript : public ScriptObject, public UpdatableScript<Transport>
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when a player boards the transport.
virtual void OnAddPassenger(Transport* /*transport*/, Player* /*player*/) { }
@@ -664,7 +661,7 @@ class AchievementCriteriaScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return true; }
+ bool IsDatabaseBound() const FINAL { return true; }
// Called when an additional criteria is checked.
virtual bool OnCheck(Player* source, Unit* target) = 0;
@@ -766,7 +763,7 @@ class GuildScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return false; }
+ bool IsDatabaseBound() const FINAL { return false; }
// Called when a member is added to the guild.
virtual void OnAddMember(Guild* /*guild*/, Player* /*player*/, uint8& /*plRank*/) { }
@@ -809,7 +806,7 @@ class GroupScript : public ScriptObject
public:
- bool IsDatabaseBound() const { return false; }
+ bool IsDatabaseBound() const FINAL { return false; }
// Called when a member is added to a group.
virtual void OnAddMember(Group* /*group*/, uint64 /*guid*/) { }