diff options
| author | Traesh <Traesh@users.noreply.github.com> | 2017-05-14 11:40:55 +0200 |
|---|---|---|
| committer | joschiwald <joschiwald.trinity@gmail.com> | 2017-05-14 11:40:55 +0200 |
| commit | c73ce93f4cf84667d23c2ec7e425f40a845eaf4f (patch) | |
| tree | 255a3af04144a58e3156491bffd1aa743fb06bfa /src/server/game/Entities | |
| parent | 3e18fcb8fd4ac8e9700f10eb3b6a1292c0f8beb8 (diff) | |
Core/Entities : Basic Conversation Implementation (#18010)
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/AreaTrigger/AreaTrigger.cpp | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Conversation/Conversation.cpp | 157 | ||||
| -rw-r--r-- | src/server/game/Entities/Conversation/Conversation.h | 91 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Object/Object.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 1 |
6 files changed, 257 insertions, 2 deletions
diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index 99e343cc948..3ea350a583b 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -202,8 +202,7 @@ void AreaTrigger::Remove() _ai->OnRemove(); - RemoveFromWorld(); - AddObjectToRemoveList(); + AddObjectToRemoveList(); // calls RemoveFromWorld } } diff --git a/src/server/game/Entities/Conversation/Conversation.cpp b/src/server/game/Entities/Conversation/Conversation.cpp new file mode 100644 index 00000000000..8e422937d57 --- /dev/null +++ b/src/server/game/Entities/Conversation/Conversation.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Conversation.h" +#include "Unit.h" +#include "UpdateData.h" + +Conversation::Conversation() : WorldObject(false), _duration(0) +{ + m_objectType |= TYPEMASK_CONVERSATION; + m_objectTypeId = TYPEID_CONVERSATION; + + m_updateFlag = UPDATEFLAG_STATIONARY_POSITION; + + m_valuesCount = CONVERSATION_END; + _dynamicValuesCount = CONVERSATION_DYNAMIC_END; +} + +Conversation::~Conversation() +{ +} + +void Conversation::AddToWorld() +{ + ///- Register the Conversation for guid lookup and for caster + if (!IsInWorld()) + { + GetMap()->GetObjectsStore().Insert<Conversation>(GetGUID(), this); + WorldObject::AddToWorld(); + } +} + +void Conversation::RemoveFromWorld() +{ + ///- Remove the Conversation from the accessor and from all lists of objects in world + if (IsInWorld()) + { + WorldObject::RemoveFromWorld(); + GetMap()->GetObjectsStore().Remove<Conversation>(GetGUID()); + } +} + +bool Conversation::IsNeverVisibleFor(WorldObject const* seer) const +{ + if (_participants.find(seer->GetGUID()) == _participants.end()) + return true; + + return WorldObject::IsNeverVisibleFor(seer); +} + +void Conversation::Update(uint32 diff) +{ + if (GetDuration() > int32(diff)) + _duration -= diff; + else + Remove(); // expired + + WorldObject::Update(diff); +} + +void Conversation::Remove() +{ + if (IsInWorld()) + { + AddObjectToRemoveList(); // calls RemoveFromWorld + } +} + +Conversation* Conversation::CreateConversation(uint32 conversationEntry, Unit* creator, Position const& pos, GuidUnorderedSet&& participants, SpellInfo const* spellInfo /*= nullptr*/) +{ + ConversationTemplate const* conversationTemplate = sConversationDataStore->GetConversationTemplate(conversationEntry); + if (!conversationTemplate) + return nullptr; + + ObjectGuid::LowType lowGuid = creator->GetMap()->GenerateLowGuid<HighGuid::Conversation>(); + + Conversation* conversation = new Conversation(); + if (!conversation->Create(lowGuid, conversationEntry, creator->GetMap(), creator, pos, std::move(participants), spellInfo)) + { + delete conversation; + return nullptr; + } + + return conversation; +} + +bool Conversation::Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, Map* map, Unit* creator, Position const& pos, GuidUnorderedSet&& participants, SpellInfo const* /*spellInfo = nullptr*/) +{ + ConversationTemplate const* conversationTemplate = sConversationDataStore->GetConversationTemplate(conversationEntry); + ASSERT(conversationTemplate); + + _creatorGuid = creator->GetGUID(); + _participants = std::move(participants); + + SetMap(map); + Relocate(pos); + + Object::_Create(ObjectGuid::Create<HighGuid::Conversation>(GetMapId(), conversationEntry, lowGuid)); + SetPhaseMask(creator->GetPhaseMask(), false); + CopyPhaseFrom(creator); + + SetEntry(conversationEntry); + SetObjectScale(1.0f); + + SetUInt32Value(CONVERSATION_LAST_LINE_END_TIME, conversationTemplate->LastLineEndTime); + _duration = conversationTemplate->LastLineEndTime; + + uint16 actorsIndex = 0; + for (ConversationActorTemplate const* actor : conversationTemplate->Actors) + { + if (actor) + { + ConversationDynamicFieldActor actorField; + actorField.ActorTemplate = *actor; + actorField.Type = ConversationDynamicFieldActor::ActorType::CreatureActor; + SetDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_ACTORS, actorsIndex++, &actorField); + } + else + ++actorsIndex; + } + + uint16 linesIndex = 0; + for (ConversationLineTemplate const* line : conversationTemplate->Lines) + SetDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_LINES, linesIndex++, line); + + if (!GetMap()->AddToMap(this)) + return false; + + return true; +} + +void Conversation::AddActor(ObjectGuid const& actorGuid, uint16 actorIdx) +{ + ConversationDynamicFieldActor actorField; + actorField.ActorGuid = actorGuid; + actorField.Type = ConversationDynamicFieldActor::ActorType::WorldObjectActor; + SetDynamicStructuredValue(CONVERSATION_DYNAMIC_FIELD_ACTORS, actorIdx, &actorField); +} + +void Conversation::AddParticipant(ObjectGuid const& participantGuid) +{ + _participants.insert(participantGuid); +} diff --git a/src/server/game/Entities/Conversation/Conversation.h b/src/server/game/Entities/Conversation/Conversation.h new file mode 100644 index 00000000000..7b168704f10 --- /dev/null +++ b/src/server/game/Entities/Conversation/Conversation.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITYCORE_CONVERSATION_H +#define TRINITYCORE_CONVERSATION_H + +#include "Object.h" +#include "ConversationDataStore.h" + +class Unit; +class SpellInfo; + +struct ConversationDynamicFieldActor +{ + ConversationDynamicFieldActor() : Type(0), Padding(0) + { + memset(Raw.Data, 0, sizeof(Raw.Data)); + } + + enum ActorType + { + WorldObjectActor = 0, + CreatureActor = 1 + }; + + union + { + ObjectGuid ActorGuid; + + ConversationActorTemplate ActorTemplate; + + struct + { + uint32 Data[4]; + } Raw; + }; + + uint32 Type; + uint32 Padding; +}; + +class TC_GAME_API Conversation : public WorldObject, public GridObject<Conversation> +{ + public: + Conversation(); + ~Conversation(); + + void AddToWorld() override; + void RemoveFromWorld() override; + + bool IsNeverVisibleFor(WorldObject const* seer) const override; + + void Update(uint32 diff) override; + void Remove(); + int32 GetDuration() const { return _duration; } + + static Conversation* CreateConversation(uint32 conversationEntry, Unit* creator, Position const& pos, GuidUnorderedSet&& participants, SpellInfo const* spellInfo = nullptr); + bool Create(ObjectGuid::LowType lowGuid, uint32 conversationEntry, Map* map, Unit* creator, Position const& pos, GuidUnorderedSet&& participants, SpellInfo const* spellInfo = nullptr); + void AddActor(ObjectGuid const& actorGuid, uint16 actorIdx); + void AddParticipant(ObjectGuid const& participantGuid); + + ObjectGuid const& GetCreatorGuid() const { return _creatorGuid; } + + float GetStationaryX() const override { return _stationaryPosition.GetPositionX(); } + float GetStationaryY() const override { return _stationaryPosition.GetPositionY(); } + float GetStationaryZ() const override { return _stationaryPosition.GetPositionZ(); } + float GetStationaryO() const override { return _stationaryPosition.GetOrientation(); } + void RelocateStationaryPosition(Position const& pos) { _stationaryPosition.Relocate(pos); } + + private: + Position _stationaryPosition; + ObjectGuid _creatorGuid; + uint32 _duration; + GuidUnorderedSet _participants; +}; + +#endif // TRINITYCORE_CONVERSATION_H diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index b1dc8e894bf..333a6a3c5d0 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -182,6 +182,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c case HighGuid::Corpse: case HighGuid::DynamicObject: case HighGuid::AreaTrigger: + case HighGuid::Conversation: updateType = UPDATETYPE_CREATE_OBJECT2; break; case HighGuid::Creature: @@ -1012,6 +1013,9 @@ uint32 Object::GetDynamicUpdateFieldData(Player const* target, uint32*& flags) c break; case TYPEID_CONVERSATION: flags = ConversationDynamicUpdateFieldFlags; + + if (ToConversation()->GetCreatorGuid() == target->GetGUID()) + visibleFlag |= UF_FLAG_0x100; break; default: flags = nullptr; diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index f3b4041db3c..5232e9912b2 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -315,6 +315,9 @@ class TC_GAME_API Object AreaTrigger* ToAreaTrigger() { if (GetTypeId() == TYPEID_AREATRIGGER) return reinterpret_cast<AreaTrigger*>(this); else return NULL; } AreaTrigger const* ToAreaTrigger() const { if (GetTypeId() == TYPEID_AREATRIGGER) return reinterpret_cast<AreaTrigger const*>(this); else return NULL; } + Conversation* ToConversation() { if (GetTypeId() == TYPEID_CONVERSATION) return reinterpret_cast<Conversation*>(this); else return NULL; } + Conversation const* ToConversation() const { if (GetTypeId() == TYPEID_CONVERSATION) return reinterpret_cast<Conversation const*>(this); else return NULL; } + protected: Object(); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 41af8b74013..1b41469c373 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -23195,6 +23195,7 @@ template void Player::UpdateVisibilityOf(Corpse* target, UpdateData& data template void Player::UpdateVisibilityOf(GameObject* target, UpdateData& data, std::set<Unit*>& visibleNow); template void Player::UpdateVisibilityOf(DynamicObject* target, UpdateData& data, std::set<Unit*>& visibleNow); template void Player::UpdateVisibilityOf(AreaTrigger* target, UpdateData& data, std::set<Unit*>& visibleNow); +template void Player::UpdateVisibilityOf(Conversation* target, UpdateData& data, std::set<Unit*>& visibleNow); void Player::UpdateObjectVisibility(bool forced) { |
