aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Entities/GameObject
diff options
context:
space:
mode:
authorSpp <spp@jorge.gr>2012-02-23 13:06:35 +0100
committerSpp <spp@jorge.gr>2012-02-23 13:06:35 +0100
commit5cff9e071640bc47688b71bb264edd8267ba77c3 (patch)
treec599d12dfb7870d7c34a07490a930b3102c3d8ac /src/server/game/Entities/GameObject
parentf0ca875a216eaab3d213feae8ba75c07795c9304 (diff)
parent9219625243bc9f63e5a152e6cda1043cfaade201 (diff)
Merge branch 'master' into 4.x
Conflicts: sql/base/auth_database.sql src/server/authserver/Server/AuthSocket.cpp src/server/game/AI/CoreAI/CombatAI.cpp src/server/game/AuctionHouse/AuctionHouseMgr.cpp src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp src/server/game/DataStores/DBCStructure.h src/server/game/DataStores/DBCfmt.h src/server/game/Entities/Unit/Unit.cpp src/server/game/Entities/Vehicle/Vehicle.cpp src/server/game/Globals/ObjectMgr.cpp src/server/game/Globals/ObjectMgr.h src/server/game/Handlers/AuctionHouseHandler.cpp src/server/game/Miscellaneous/SharedDefines.h src/server/game/Movement/MotionMaster.cpp src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp src/server/game/Quests/QuestDef.cpp src/server/game/Server/Protocol/Opcodes.cpp src/server/game/Server/WorldSocket.cpp src/server/game/Spells/Spell.cpp src/server/game/Spells/SpellEffects.cpp src/server/game/Spells/SpellInfo.cpp src/server/scripts/Outland/HellfireCitadel/MagtheridonsLair/boss_magtheridon.cpp src/server/scripts/Spells/spell_quest.cpp src/server/shared/Logging/Log.h src/server/worldserver/worldserver.conf.dist src/tools/vmap3_extractor/model.h src/tools/vmap4_extractor/CMakeLists.txt src/tools/vmap4_extractor/dbcfile.cpp src/tools/vmap4_extractor/dbcfile.h src/tools/vmap4_extractor/loadlib/loadlib.h
Diffstat (limited to 'src/server/game/Entities/GameObject')
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.cpp124
-rwxr-xr-xsrc/server/game/Entities/GameObject/GameObject.h10
2 files changed, 121 insertions, 13 deletions
diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp
index 64cc1bb325c..c04dd0b1941 100755
--- a/src/server/game/Entities/GameObject/GameObject.cpp
+++ b/src/server/game/Entities/GameObject/GameObject.cpp
@@ -30,7 +30,10 @@
#include "CreatureAISelector.h"
#include "Group.h"
-GameObject::GameObject() : WorldObject(false), m_goValue(new GameObjectValue), m_AI(NULL)
+#include "GameObjectModel.h"
+#include "DynamicTree.h"
+
+GameObject::GameObject() : WorldObject(false), m_model(NULL), m_goValue(new GameObjectValue), m_AI(NULL)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
@@ -62,6 +65,7 @@ GameObject::~GameObject()
{
delete m_goValue;
delete m_AI;
+ delete m_model;
//if (m_uint32Values) // field array can be not exist if GameOBject not loaded
// CleanupsBeforeDelete();
}
@@ -127,6 +131,13 @@ void GameObject::AddToWorld()
m_zoneScript->OnGameObjectCreate(this);
sObjectAccessor->AddObject(this);
+ bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false);
+ bool toggledState = (GetGOData() ? GetGOData()->go_state == GO_STATE_ACTIVE : false);
+ if (m_model)
+ GetMap()->Insert(*m_model);
+ if ((startOpen && !toggledState) || (!startOpen && toggledState))
+ EnableCollision(false);
+
WorldObject::AddToWorld();
}
}
@@ -140,6 +151,9 @@ void GameObject::RemoveFromWorld()
m_zoneScript->OnGameObjectRemove(this);
RemoveFromOwner();
+ if (m_model)
+ if (GetMap()->Contains(*m_model))
+ GetMap()->Remove(*m_model);
WorldObject::RemoveFromWorld();
sObjectAccessor->RemoveObject(this);
}
@@ -199,15 +213,17 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
// set name for logs usage, doesn't affect anything ingame
SetName(goinfo->name);
- SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId);
+ SetDisplayId(goinfo->displayId);
+ m_model = GameObjectModel::Create(*this);
// GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3
- SetGoState(go_state);
SetGoType(GameobjectTypes(goinfo->type));
+ SetGoState(go_state);
SetGoArtKit(0); // unknown what this is
SetByteValue(GAMEOBJECT_BYTES_1, 2, artKit);
+
switch (goinfo->type)
{
case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING:
@@ -228,13 +244,13 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa
if (GetGOInfo()->trap.stealthed)
{
m_stealth.AddFlag(STEALTH_TRAP);
- m_stealth.AddValue(STEALTH_TRAP, 300);
+ m_stealth.AddValue(STEALTH_TRAP, 70);
}
if (GetGOInfo()->trap.invisible)
{
m_invisibility.AddFlag(INVISIBILITY_TRAP);
- m_invisibility.AddValue(INVISIBILITY_TRAP, 70);
+ m_invisibility.AddValue(INVISIBILITY_TRAP, 300);
}
break;
@@ -850,6 +866,20 @@ bool GameObject::IsAlwaysVisibleFor(WorldObject const* seer) const
if (IsTransport())
return true;
+ if (!seer)
+ return false;
+
+ // Always seen by owner and friendly units
+ if (uint64 guid = GetOwnerGUID())
+ {
+ if (seer->GetGUID() == guid)
+ return true;
+
+ Unit* owner = GetOwner();
+ if (owner && seer->isType(TYPEMASK_UNIT) && owner->IsFriendlyTo(((Unit*)seer)))
+ return true;
+ }
+
return false;
}
@@ -1779,7 +1809,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
{
case GO_DESTRUCTIBLE_INTACT:
RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED | GO_FLAG_DESTROYED);
- SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->displayId);
+ SetDisplayId(m_goInfo->displayId);
if (setHealth)
{
m_goValue->Building.Health = m_goValue->Building.MaxHealth;
@@ -1801,7 +1831,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->DamagedDisplayId)
modelId = modelData->DamagedDisplayId;
- SetUInt32Value(GAMEOBJECT_DISPLAYID, modelId);
+ SetDisplayId(modelId);
if (setHealth)
{
@@ -1834,7 +1864,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->DestroyedDisplayId)
modelId = modelData->DestroyedDisplayId;
- SetUInt32Value(GAMEOBJECT_DISPLAYID, modelId);
+ SetDisplayId(modelId);
if (setHealth)
{
@@ -1852,7 +1882,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
if (modelData->RebuildingDisplayId)
modelId = modelData->RebuildingDisplayId;
- SetUInt32Value(GAMEOBJECT_DISPLAYID, modelId);
+ SetDisplayId(modelId);
// restores to full health
if (setHealth)
@@ -1865,8 +1895,78 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
}
}
-void GameObject::SetLootState(LootState s, Unit* unit)
+void GameObject::SetLootState(LootState state, Unit* unit)
{
- m_lootState = s;
- AI()->OnStateChanged(s, unit);
+ m_lootState = state;
+ AI()->OnStateChanged(state, unit);
+ if (m_model)
+ {
+ // startOpen determines whether we are going to add or remove the LoS on activation
+ bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false);
+
+ if (GetGOData() && GetGOData()->go_state == GO_NOT_READY)
+ startOpen = !startOpen;
+
+ if (state == GO_ACTIVATED || state == GO_JUST_DEACTIVATED)
+ EnableCollision(startOpen);
+ else if (state == GO_READY)
+ EnableCollision(!startOpen);
+ }
+}
+
+void GameObject::SetGoState(GOState state)
+{
+ SetByteValue(GAMEOBJECT_BYTES_1, 0, state);
+ if (m_model)
+ {
+ if (!IsInWorld())
+ return;
+
+ // startOpen determines whether we are going to add or remove the LoS on activation
+ bool startOpen = (GetGoType() == GAMEOBJECT_TYPE_DOOR || GetGoType() == GAMEOBJECT_TYPE_BUTTON ? GetGOInfo()->door.startOpen : false);
+
+ if (GetGOData() && GetGOData()->go_state == GO_NOT_READY)
+ startOpen = !startOpen;
+
+ if (state == GO_STATE_ACTIVE || state == GO_STATE_ACTIVE_ALTERNATIVE)
+ EnableCollision(startOpen);
+ else if (state == GO_STATE_READY)
+ EnableCollision(!startOpen);
+ }
+}
+
+void GameObject::SetDisplayId(uint32 displayid)
+{
+ SetUInt32Value(GAMEOBJECT_DISPLAYID, displayid);
+ UpdateModel();
+}
+
+void GameObject::SetPhaseMask(uint32 newPhaseMask, bool update)
+{
+ WorldObject::SetPhaseMask(newPhaseMask, update);
+ EnableCollision(true);
+}
+
+void GameObject::EnableCollision(bool enable)
+{
+ if (!m_model)
+ return;
+
+ /*if (enable && !GetMap()->Contains(*m_model))
+ GetMap()->Insert(*m_model);*/
+
+ m_model->enable(enable ? GetPhaseMask() : 0);
+}
+
+void GameObject::UpdateModel()
+{
+ if (!IsInWorld())
+ return;
+ if (m_model)
+ if (GetMap()->Contains(*m_model))
+ GetMap()->Remove(*m_model);
+ delete m_model;
+ m_model = GameObjectModel::Create(*this);
+ if (m_model)
+ GetMap()->Insert(*m_model);
}
diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h
index 2329ed10e49..2e40d45541c 100755
--- a/src/server/game/Entities/GameObject/GameObject.h
+++ b/src/server/game/Entities/GameObject/GameObject.h
@@ -610,6 +610,7 @@ enum LootState
};
class Unit;
+class GameObjectModel;
// 5 sec for bobber catch
#define FISHING_BOBBER_READY_TIME 5
@@ -704,13 +705,16 @@ class GameObject : public WorldObject, public GridObject<GameObject>
GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); }
- void SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); }
+ void SetGoState(GOState state);
uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
void SetGoArtKit(uint8 artkit);
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
static void SetGoArtKit(uint8 artkit, GameObject* go, uint32 lowguid = 0);
+ void SetPhaseMask(uint32 newPhaseMask, bool update);
+ void EnableCollision(bool enable);
+
void Use(Unit* user);
LootState getLootState() const { return m_lootState; }
@@ -791,6 +795,9 @@ class GameObject : public WorldObject, public GridObject<GameObject>
GameObjectAI* AI() const { return m_AI; }
std::string GetAIName() const;
+ void SetDisplayId(uint32 displayid);
+
+ GameObjectModel * m_model;
protected:
bool AIM_Initialize();
uint32 m_spellId;
@@ -820,6 +827,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>
private:
void RemoveFromOwner();
void SwitchDoorOrButton(bool activate, bool alternative = false);
+ void UpdateModel(); // updates model in case displayId were changed
//! Object distance/size - overridden from Object::_IsWithinDist. Needs to take in account proper GO size.
bool _IsWithinDist(WorldObject const* obj, float dist2compare, bool /*is3D*/) const