aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities
diff options
context:
space:
mode:
authorTraesh <Traesh@users.noreply.github.com>2017-05-14 11:40:55 +0200
committerjoschiwald <joschiwald.trinity@gmail.com>2017-05-14 11:40:55 +0200
commitc73ce93f4cf84667d23c2ec7e425f40a845eaf4f (patch)
tree255a3af04144a58e3156491bffd1aa743fb06bfa /src/server/game/Entities
parent3e18fcb8fd4ac8e9700f10eb3b6a1292c0f8beb8 (diff)
Core/Entities : Basic Conversation Implementation (#18010)
Diffstat (limited to 'src/server/game/Entities')
-rw-r--r--src/server/game/Entities/AreaTrigger/AreaTrigger.cpp3
-rw-r--r--src/server/game/Entities/Conversation/Conversation.cpp157
-rw-r--r--src/server/game/Entities/Conversation/Conversation.h91
-rw-r--r--src/server/game/Entities/Object/Object.cpp4
-rw-r--r--src/server/game/Entities/Object/Object.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp1
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)
{