Core/Scenes: Implemented spell created SceneObjects

This commit is contained in:
Shauren
2021-10-11 12:59:19 +02:00
parent 8492c273dd
commit d7302ffd14
17 changed files with 435 additions and 16 deletions

View File

@@ -145,7 +145,6 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
uint16 objectTypeMask = m_objectType;
CreateObjectBits flags = m_updateFlag;
/** lower flag1 **/
if (target == this) // building packet for yourself
{
flags.ThisIsYou = true;
@@ -161,6 +160,7 @@ void Object::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c
case HighGuid::Corpse:
case HighGuid::DynamicObject:
case HighGuid::AreaTrigger:
case HighGuid::SceneObject:
case HighGuid::Conversation:
updateType = UPDATETYPE_CREATE_OBJECT2;
break;
@@ -620,11 +620,11 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags) const
// *data << ObjectGuid(ReplaceObject);
//}
//if (flags.SceneObject)
//{
// data->WriteBit(HasLocalScriptData);
// data->WriteBit(HasPetBattleFullUpdate);
// data->FlushBits();
if (flags.SceneObject)
{
data->WriteBit(false); // HasLocalScriptData
data->WriteBit(false); // HasPetBattleFullUpdate
data->FlushBits();
// if (HasLocalScriptData)
// {
@@ -728,7 +728,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, CreateObjectBits flags) const
// data->WriteBit(CanAwardXP);
// data->FlushBits();
// }
//}
}
if (flags.ActivePlayer)
{

View File

@@ -24053,6 +24053,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(SceneObject* target, UpdateData& data, std::set<Unit*>& visibleNow);
template void Player::UpdateVisibilityOf(Conversation* target, UpdateData& data, std::set<Unit*>& visibleNow);
void Player::UpdateObjectVisibility(bool forced)

View File

@@ -0,0 +1,193 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* 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 "SceneObject.h"
#include "GameTime.h"
#include "Map.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "PhasingHandler.h"
#include "SpellAuras.h"
#include "Unit.h"
#include "UpdateData.h"
#include "Util.h"
SceneObject::SceneObject() : WorldObject(false)
{
m_objectType |= TYPEMASK_SCENEOBJECT;
m_objectTypeId = TYPEID_SCENEOBJECT;
m_updateFlag.Stationary = true;
m_updateFlag.SceneObject = true;
}
SceneObject::~SceneObject() = default;
void SceneObject::AddToWorld()
{
if (!IsInWorld())
{
GetMap()->GetObjectsStore().Insert<SceneObject>(GetGUID(), this);
WorldObject::AddToWorld();
}
}
void SceneObject::RemoveFromWorld()
{
if (IsInWorld())
{
WorldObject::RemoveFromWorld();
GetMap()->GetObjectsStore().Remove<SceneObject>(GetGUID());
}
}
void SceneObject::Update(uint32 diff)
{
WorldObject::Update(diff);
if (ShouldBeRemoved())
Remove();
}
void SceneObject::Remove()
{
if (IsInWorld())
AddObjectToRemoveList();
}
bool SceneObject::ShouldBeRemoved() const
{
Unit* creator = ObjectAccessor::GetUnit(*this, GetOwnerGUID());
if (!creator)
return true;
if (!_createdBySpellCast.IsEmpty())
{
// search for a dummy aura on creator
Aura const* linkedAura = creator->GetAura(_createdBySpellCast.GetEntry(), [this](Aura const* aura)
{
return aura->GetCastId() == _createdBySpellCast;
});
if (!linkedAura)
return true;
}
return false;
}
SceneObject* SceneObject::CreateSceneObject(uint32 sceneId, Unit* creator, Position const& pos, ObjectGuid privateObjectOwner)
{
SceneTemplate const* sceneTemplate = sObjectMgr->GetSceneTemplate(sceneId);
if (!sceneTemplate)
return nullptr;
ObjectGuid::LowType lowGuid = creator->GetMap()->GenerateLowGuid<HighGuid::SceneObject>();
SceneObject* sceneObject = new SceneObject();
if (!sceneObject->Create(lowGuid, SceneType::Normal, sceneId, sceneTemplate ? sceneTemplate->ScenePackageId : 0, creator->GetMap(), creator, pos, privateObjectOwner))
{
delete sceneObject;
return nullptr;
}
return sceneObject;
}
bool SceneObject::Create(ObjectGuid::LowType lowGuid, SceneType type, uint32 sceneId, uint32 scriptPackageId, Map* map, Unit* creator,
Position const& pos, ObjectGuid privateObjectOwner)
{
SetMap(map);
Relocate(pos);
RelocateStationaryPosition(pos);
SetPrivateObjectOwner(privateObjectOwner);
Object::_Create(ObjectGuid::Create<HighGuid::SceneObject>(GetMapId(), sceneId, lowGuid));
PhasingHandler::InheritPhaseShift(this, creator);
SetEntry(scriptPackageId);
SetObjectScale(1.0f);
SetUpdateFieldValue(m_values.ModifyValue(&SceneObject::m_sceneObjectData).ModifyValue(&UF::SceneObjectData::ScriptPackageID), scriptPackageId);
SetUpdateFieldValue(m_values.ModifyValue(&SceneObject::m_sceneObjectData).ModifyValue(&UF::SceneObjectData::RndSeedVal), GameTime::GetGameTimeMS());
SetUpdateFieldValue(m_values.ModifyValue(&SceneObject::m_sceneObjectData).ModifyValue(&UF::SceneObjectData::CreatedBy), creator->GetGUID());
SetUpdateFieldValue(m_values.ModifyValue(&SceneObject::m_sceneObjectData).ModifyValue(&UF::SceneObjectData::SceneType), AsUnderlyingType(type));
if (!GetMap()->AddToMap(this))
return false;
return true;
}
void SceneObject::BuildValuesCreate(ByteBuffer* data, Player const* target) const
{
UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
std::size_t sizePos = data->wpos();
*data << uint32(0);
*data << uint8(flags);
m_objectData->WriteCreate(*data, flags, this, target);
m_sceneObjectData->WriteCreate(*data, flags, this, target);
data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
}
void SceneObject::BuildValuesUpdate(ByteBuffer* data, Player const* target) const
{
UF::UpdateFieldFlag flags = GetUpdateFieldFlagsFor(target);
std::size_t sizePos = data->wpos();
*data << uint32(0);
*data << uint32(m_values.GetChangedObjectTypeMask());
if (m_values.HasChanged(TYPEID_OBJECT))
m_objectData->WriteUpdate(*data, flags, this, target);
if (m_values.HasChanged(TYPEID_SCENEOBJECT))
m_sceneObjectData->WriteUpdate(*data, flags, this, target);
data->put<uint32>(sizePos, data->wpos() - sizePos - 4);
}
void SceneObject::BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
UF::SceneObjectData::Mask const& requestedSceneObjectMask, Player const* target) const
{
UpdateMask<NUM_CLIENT_OBJECT_TYPES> valuesMask;
if (requestedObjectMask.IsAnySet())
valuesMask.Set(TYPEID_OBJECT);
if (requestedSceneObjectMask.IsAnySet())
valuesMask.Set(TYPEID_SCENEOBJECT);
ByteBuffer buffer = PrepareValuesUpdateBuffer();
std::size_t sizePos = buffer.wpos();
buffer << uint32(0);
buffer << uint32(valuesMask.GetBlock(0));
if (valuesMask[TYPEID_OBJECT])
m_objectData->WriteUpdate(buffer, requestedObjectMask, true, this, target);
if (valuesMask[TYPEID_SCENEOBJECT])
m_sceneObjectData->WriteUpdate(buffer, requestedSceneObjectMask, true, this, target);
buffer.put<uint32>(sizePos, buffer.wpos() - sizePos - 4);
data->AddUpdateBlock(buffer);
}
void SceneObject::ClearUpdateMask(bool remove)
{
m_values.ClearChangesMask(&SceneObject::m_sceneObjectData);
Object::ClearUpdateMask(remove);
}

View File

@@ -0,0 +1,76 @@
/*
* This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
*
* 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 SceneObject_h__
#define SceneObject_h__
#include "Object.h"
struct SceneTemplate;
enum class SceneType : uint32
{
Normal = 0,
PetBattle = 1
};
class TC_GAME_API SceneObject : public WorldObject, public GridObject<SceneObject>
{
public:
SceneObject();
~SceneObject();
protected:
void BuildValuesCreate(ByteBuffer* data, Player const* target) const override;
void BuildValuesUpdate(ByteBuffer* data, Player const* target) const override;
void ClearUpdateMask(bool remove) override;
public:
void BuildValuesUpdateForPlayerWithMask(UpdateData* data, UF::ObjectData::Mask const& requestedObjectMask,
UF::SceneObjectData::Mask const& requestedSceneObjectMask, Player const* target) const;
void AddToWorld() override;
void RemoveFromWorld() override;
void Update(uint32 diff) override;
void Remove();
static SceneObject* CreateSceneObject(uint32 sceneId, Unit* creator, Position const& pos, ObjectGuid privateObjectOwner);
bool Create(ObjectGuid::LowType lowGuid, SceneType type, uint32 sceneId, uint32 scriptPackageId, Map* map, Unit* creator,
Position const& pos, ObjectGuid privateObjectOwner);
ObjectGuid GetOwnerGUID() const override { return *m_sceneObjectData->CreatedBy; }
uint32 GetFaction() const override { return 0; }
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); }
void SetCreatedBySpellCast(ObjectGuid castId) { _createdBySpellCast = castId; }
UF::UpdateField<UF::SceneObjectData, 0, TYPEID_SCENEOBJECT> m_sceneObjectData;
private:
bool ShouldBeRemoved() const;
Position _stationaryPosition;
ObjectGuid _createdBySpellCast;
};
#endif // SceneObject_h__

View File

@@ -118,6 +118,7 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid con
case HighGuid::DynamicObject: return GetDynamicObject(p, guid);
case HighGuid::AreaTrigger: return GetAreaTrigger(p, guid);
case HighGuid::Corpse: return GetCorpse(p, guid);
case HighGuid::SceneObject: return GetSceneObject(p, guid);
case HighGuid::Conversation: return GetConversation(p, guid);
default: return nullptr;
}
@@ -157,6 +158,10 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid con
if (typemask & TYPEMASK_AREATRIGGER)
return GetAreaTrigger(p, guid);
break;
case HighGuid::SceneObject:
if (typemask & TYPEMASK_SCENEOBJECT)
return GetSceneObject(p, guid);
break;
case HighGuid::Conversation:
if (typemask & TYPEMASK_CONVERSATION)
return GetConversation(p, guid);
@@ -200,6 +205,11 @@ AreaTrigger* ObjectAccessor::GetAreaTrigger(WorldObject const& u, ObjectGuid con
return u.GetMap()->GetAreaTrigger(guid);
}
SceneObject* ObjectAccessor::GetSceneObject(WorldObject const& u, ObjectGuid const& guid)
{
return u.GetMap()->GetSceneObject(guid);
}
Conversation* ObjectAccessor::GetConversation(WorldObject const& u, ObjectGuid const& guid)
{
return u.GetMap()->GetConversation(guid);

View File

@@ -31,6 +31,7 @@ class Map;
class Object;
class Pet;
class Player;
class SceneObject;
class Transport;
class Unit;
class WorldObject;
@@ -72,6 +73,7 @@ namespace ObjectAccessor
TC_GAME_API Transport* GetTransport(ObjectGuid const& guid);
TC_GAME_API DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API AreaTrigger* GetAreaTrigger(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API SceneObject* GetSceneObject(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API Conversation* GetConversation(WorldObject const& u, ObjectGuid const& guid);
TC_GAME_API Unit* GetUnit(WorldObject const&, ObjectGuid const& guid);
TC_GAME_API Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid);

View File

@@ -30,6 +30,7 @@ class GameObject;
class Pet;
class Player;
class AreaTrigger;
class SceneObject;
class Conversation;
#define MAX_NUMBER_OF_CELLS 8
@@ -58,8 +59,8 @@ class Conversation;
// Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case)
typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes;
typedef TYPELIST_6(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, Conversation) AllGridObjectTypes;
typedef TYPELIST_7(Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger, Conversation) AllMapStoredObjectTypes;
typedef TYPELIST_7(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/, AreaTrigger, SceneObject, Conversation) AllGridObjectTypes;
typedef TYPELIST_8(Creature, GameObject, DynamicObject, Pet, Corpse, AreaTrigger, SceneObject, Conversation) AllMapStoredObjectTypes;
typedef GridRefManager<Corpse> CorpseMapType;
typedef GridRefManager<Creature> CreatureMapType;
@@ -67,6 +68,7 @@ typedef GridRefManager<DynamicObject> DynamicObjectMapType;
typedef GridRefManager<GameObject> GameObjectMapType;
typedef GridRefManager<Player> PlayerMapType;
typedef GridRefManager<AreaTrigger> AreaTriggerMapType;
typedef GridRefManager<SceneObject> SceneObjectMapType;
typedef GridRefManager<Conversation> ConversationMapType;
enum GridMapTypeMask
@@ -77,8 +79,9 @@ enum GridMapTypeMask
GRID_MAP_TYPE_MASK_GAMEOBJECT = 0x08,
GRID_MAP_TYPE_MASK_PLAYER = 0x10,
GRID_MAP_TYPE_MASK_AREATRIGGER = 0x20,
GRID_MAP_TYPE_MASK_CONVERSATION = 0x40,
GRID_MAP_TYPE_MASK_ALL = 0x7F
GRID_MAP_TYPE_MASK_SCENEOBJECT = 0x40,
GRID_MAP_TYPE_MASK_CONVERSATION = 0x80,
GRID_MAP_TYPE_MASK_ALL = 0xFF
};
typedef Grid<Player, AllWorldObjectTypes, AllGridObjectTypes> GridType;

View File

@@ -303,4 +303,5 @@ template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
template void ObjectUpdater::Visit<GameObject>(GameObjectMapType&);
template void ObjectUpdater::Visit<DynamicObject>(DynamicObjectMapType&);
template void ObjectUpdater::Visit<AreaTrigger>(AreaTriggerMapType &);
template void ObjectUpdater::Visit<SceneObject>(SceneObjectMapType &);
template void ObjectUpdater::Visit<Conversation>(ConversationMapType &);

View File

@@ -26,6 +26,7 @@
#include "GameObject.h"
#include "Packet.h"
#include "Player.h"
#include "SceneObject.h"
#include "Spell.h"
#include "SpellInfo.h"
#include "TemporarySummon.h"
@@ -115,6 +116,7 @@ namespace Trinity
void Visit(DynamicObjectMapType &m) { updateObjects<DynamicObject>(m); }
void Visit(CorpseMapType &m) { updateObjects<Corpse>(m); }
void Visit(AreaTriggerMapType &m) { updateObjects<AreaTrigger>(m); }
void Visit(SceneObjectMapType &m) { updateObjects<SceneObject>(m); }
void Visit(ConversationMapType &m) { updateObjects<Conversation>(m); }
};
@@ -259,6 +261,7 @@ namespace Trinity
void Visit(CorpseMapType &m);
void Visit(DynamicObjectMapType &m);
void Visit(AreaTriggerMapType &m);
void Visit(SceneObjectMapType &m);
void Visit(ConversationMapType &m);
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
@@ -281,6 +284,7 @@ namespace Trinity
void Visit(CorpseMapType &m);
void Visit(DynamicObjectMapType &m);
void Visit(AreaTriggerMapType &m);
void Visit(SceneObjectMapType &m);
void Visit(ConversationMapType &m);
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
@@ -304,6 +308,7 @@ namespace Trinity
void Visit(GameObjectMapType &m);
void Visit(DynamicObjectMapType &m);
void Visit(AreaTriggerMapType &m);
void Visit(SceneObjectMapType &m);
void Visit(ConversationMapType &m);
template<class NOT_INTERESTED> void Visit(GridRefManager<NOT_INTERESTED> &) { }
@@ -372,6 +377,15 @@ namespace Trinity
i_do(itr->GetSource());
}
void Visit(SceneObjectMapType& m)
{
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_SCENEOBJECT))
return;
for (SceneObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
if (itr->GetSource()->IsInPhase(_searcher))
i_do(itr->GetSource());
}
void Visit(ConversationMapType &m)
{
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CONVERSATION))

View File

@@ -321,6 +321,29 @@ void Trinity::WorldObjectSearcher<Check>::Visit(AreaTriggerMapType &m)
}
}
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(SceneObjectMapType &m)
{
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_SCENEOBJECT))
return;
// already found
if (i_object)
return;
for (SceneObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
if (!itr->GetSource()->IsInPhase(_searcher))
continue;
if (i_check(itr->GetSource()))
{
i_object = itr->GetSource();
return;
}
}
}
template<class Check>
void Trinity::WorldObjectSearcher<Check>::Visit(ConversationMapType &m)
{
@@ -440,6 +463,22 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(AreaTriggerMapType &m)
}
}
template<class Check>
void Trinity::WorldObjectLastSearcher<Check>::Visit(SceneObjectMapType &m)
{
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_SCENEOBJECT))
return;
for (SceneObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr)
{
if (!itr->GetSource()->IsInPhase(_searcher))
continue;
if (i_check(itr->GetSource()))
i_object = itr->GetSource();
}
}
template<class Check>
void Trinity::WorldObjectLastSearcher<Check>::Visit(ConversationMapType &m)
{
@@ -522,6 +561,17 @@ void Trinity::WorldObjectListSearcher<Check>::Visit(AreaTriggerMapType &m)
Insert(itr->GetSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(SceneObjectMapType &m)
{
if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_SCENEOBJECT))
return;
for (SceneObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr)
if (i_check(itr->GetSource()))
Insert(itr->GetSource());
}
template<class Check>
void Trinity::WorldObjectListSearcher<Check>::Visit(ConversationMapType &m)
{

View File

@@ -30,6 +30,7 @@
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "PhasingHandler.h"
#include "SceneObject.h"
#include "World.h"
#include "ScriptMgr.h"
@@ -285,12 +286,14 @@ void ObjectGridCleaner::Visit(GridRefManager<T> &m)
template void ObjectGridUnloader::Visit(CreatureMapType &);
template void ObjectGridUnloader::Visit(GameObjectMapType &);
template void ObjectGridUnloader::Visit(DynamicObjectMapType &);
template void ObjectGridUnloader::Visit(ConversationMapType &);
template void ObjectGridUnloader::Visit(AreaTriggerMapType&);
template void ObjectGridUnloader::Visit(SceneObjectMapType&);
template void ObjectGridUnloader::Visit(ConversationMapType&);
template void ObjectGridUnloader::Visit(AreaTriggerMapType &);
template void ObjectGridCleaner::Visit(CreatureMapType &);
template void ObjectGridCleaner::Visit<GameObject>(GameObjectMapType &);
template void ObjectGridCleaner::Visit<DynamicObject>(DynamicObjectMapType &);
template void ObjectGridCleaner::Visit<Corpse>(CorpseMapType &);
template void ObjectGridCleaner::Visit<AreaTrigger>(AreaTriggerMapType &);
template void ObjectGridCleaner::Visit<SceneObject>(SceneObjectMapType &);
template void ObjectGridCleaner::Visit<Conversation>(ConversationMapType &);

View File

@@ -40,7 +40,8 @@ class TC_GAME_API ObjectGridLoader
void Visit(AreaTriggerMapType &m);
void Visit(CorpseMapType &) const { }
void Visit(DynamicObjectMapType&) const { }
void Visit(ConversationMapType &) const { }
void Visit(SceneObjectMapType&) const { }
void Visit(ConversationMapType&) const { }
void LoadN(void);

View File

@@ -3823,6 +3823,7 @@ template TC_GAME_API bool Map::AddToMap(Creature*);
template TC_GAME_API bool Map::AddToMap(GameObject*);
template TC_GAME_API bool Map::AddToMap(DynamicObject*);
template TC_GAME_API bool Map::AddToMap(AreaTrigger*);
template TC_GAME_API bool Map::AddToMap(SceneObject*);
template TC_GAME_API bool Map::AddToMap(Conversation*);
template TC_GAME_API void Map::RemoveFromMap(Corpse*, bool);
@@ -3830,6 +3831,7 @@ template TC_GAME_API void Map::RemoveFromMap(Creature*, bool);
template TC_GAME_API void Map::RemoveFromMap(GameObject*, bool);
template TC_GAME_API void Map::RemoveFromMap(DynamicObject*, bool);
template TC_GAME_API void Map::RemoveFromMap(AreaTrigger*, bool);
template TC_GAME_API void Map::RemoveFromMap(SceneObject*, bool);
template TC_GAME_API void Map::RemoveFromMap(Conversation*, bool);
/* ******* Dungeon Instance Maps ******* */
@@ -4421,6 +4423,11 @@ AreaTrigger* Map::GetAreaTrigger(ObjectGuid const& guid)
return _objectsStore.Find<AreaTrigger>(guid);
}
SceneObject* Map::GetSceneObject(ObjectGuid const& guid)
{
return _objectsStore.Find<SceneObject>(guid);
}
Conversation* Map::GetConversation(ObjectGuid const& guid)
{
return _objectsStore.Find<Conversation>(guid);

View File

@@ -442,6 +442,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0, ObjectGuid privateObjectOwner = ObjectGuid::Empty);
void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr);
AreaTrigger* GetAreaTrigger(ObjectGuid const& guid);
SceneObject* GetSceneObject(ObjectGuid const& guid);
Conversation* GetConversation(ObjectGuid const& guid);
Player* GetPlayer(ObjectGuid const& guid);
Corpse* GetCorpse(ObjectGuid const& guid);

View File

@@ -385,6 +385,8 @@ class TC_GAME_API Spell
void EffectGiveArtifactPower();
void EffectGiveArtifactPowerNoBonus();
void EffectPlaySceneScriptPackage();
void EffectCreateSceneObject();
void EffectCreatePrivateSceneObject();
void EffectPlayScene();
void EffectGiveHonor();
void EffectLearnTransmogSet();

View File

@@ -60,6 +60,7 @@
#include "PhasingHandler.h"
#include "Player.h"
#include "ReputationMgr.h"
#include "SceneObject.h"
#include "ScriptMgr.h"
#include "SharedDefines.h"
#include "SkillExtraItems.h"
@@ -276,8 +277,8 @@ NonDefaultConstructible<SpellEffectHandlerFn> SpellEffectHandlers[TOTAL_SPELL_EF
&Spell::EffectNULL, //193 SPELL_EFFECT_START_PET_BATTLE
&Spell::EffectUnused, //194 SPELL_EFFECT_194
&Spell::EffectPlaySceneScriptPackage, //195 SPELL_EFFECT_PLAY_SCENE_SCRIPT_PACKAGE
&Spell::EffectNULL, //196 SPELL_EFFECT_CREATE_SCENE_OBJECT
&Spell::EffectNULL, //197 SPELL_EFFECT_CREATE_PERSONAL_SCENE_OBJECT
&Spell::EffectCreateSceneObject, //196 SPELL_EFFECT_CREATE_SCENE_OBJECT
&Spell::EffectCreatePrivateSceneObject, //197 SPELL_EFFECT_CREATE_PERSONAL_SCENE_OBJECT
&Spell::EffectPlayScene, //198 SPELL_EFFECT_PLAY_SCENE
&Spell::EffectNULL, //199 SPELL_EFFECT_DESPAWN_SUMMON
&Spell::EffectHealBattlePetPct, //200 SPELL_EFFECT_HEAL_BATTLEPET_PCT
@@ -5770,6 +5771,59 @@ void Spell::EffectPlaySceneScriptPackage()
m_caster->ToPlayer()->GetSceneMgr().PlaySceneByPackageId(effectInfo->MiscValue, SceneFlag::PlayerNonInteractablePhased, destTarget);
}
template<typename TargetInfo>
bool IsUnitTargetSceneObjectAura(Spell const* spell, TargetInfo const& target)
{
if (target.TargetGUID != spell->GetCaster()->GetGUID())
return false;
for (SpellEffectInfo const& spellEffectInfo : spell->GetSpellInfo()->GetEffects())
if (target.EffectMask & (1 << spellEffectInfo.EffectIndex) && spellEffectInfo.IsUnitOwnedAuraEffect())
return true;
return false;
}
void Spell::EffectCreateSceneObject()
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
if (!unitCaster || !m_targets.HasDst())
return;
if (SceneObject* sceneObject = SceneObject::CreateSceneObject(effectInfo->MiscValue, unitCaster, destTarget->GetPosition(), ObjectGuid::Empty))
{
bool hasAuraTargetingCaster = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [this](TargetInfo const& target)
{
return IsUnitTargetSceneObjectAura(this, target);
}) != m_UniqueTargetInfo.end();
if (hasAuraTargetingCaster)
sceneObject->SetCreatedBySpellCast(m_castId);
}
}
void Spell::EffectCreatePrivateSceneObject()
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)
return;
if (!unitCaster || !m_targets.HasDst())
return;
if (SceneObject* sceneObject = SceneObject::CreateSceneObject(effectInfo->MiscValue, unitCaster, destTarget->GetPosition(), unitCaster->GetGUID()))
{
bool hasAuraTargetingCaster = std::find_if(m_UniqueTargetInfo.begin(), m_UniqueTargetInfo.end(), [this](TargetInfo const& target)
{
return IsUnitTargetSceneObjectAura(this, target);
}) != m_UniqueTargetInfo.end();
if (hasAuraTargetingCaster)
sceneObject->SetCreatedBySpellCast(m_castId);
}
}
void Spell::EffectPlayScene()
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT)

View File

@@ -41,4 +41,5 @@ struct TypeList
#define TYPELIST_5(T1, T2, T3, T4, T5) TypeList<T1, TYPELIST_4(T2, T3, T4, T5) >
#define TYPELIST_6(T1, T2, T3, T4, T5, T6) TypeList<T1, TYPELIST_5(T2, T3, T4, T5, T6) >
#define TYPELIST_7(T1, T2, T3, T4, T5, T6, T7) TypeList<T1, TYPELIST_6(T2, T3, T4, T5, T6, T7) >
#define TYPELIST_8(T1, T2, T3, T4, T5, T6, T7, T8) TypeList<T1, TYPELIST_7(T2, T3, T4, T5, T6, T7, T8) >
#endif