aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-07-16 12:06:07 +0800
committermegamage <none@none>2009-07-16 12:06:07 +0800
commite152ff8ec5fc3282b0ab3d1740f05886f90335ed (patch)
tree296587187e967b314a15faa24757365112ff2cff
parent208087ff6ee592150b1ed387bbc135566a02a359 (diff)
[8183] Some gameobject despanw related fixes Author: VladimirMangos
* Implement use `consumable` field in gameobject template for gameobject required explcit despawn at use. * Move gameobject template fields cech function from Gameobject to gameobject template class, and update callers. * Cast spells at gameobject use with gameobject guid as original caster guid, as already used in some other cases. (skipped) --HG-- branch : trunk
-rw-r--r--src/game/GameObject.cpp29
-rw-r--r--src/game/GameObject.h142
-rw-r--r--src/game/LootMgr.cpp2
-rw-r--r--src/game/ObjectMgr.cpp22
-rw-r--r--src/game/Player.cpp2
-rw-r--r--src/game/Spell.cpp2
-rw-r--r--src/game/SpellEffects.cpp6
7 files changed, 115 insertions, 90 deletions
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index d1cf9187aac..199e3c2d432 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -94,7 +94,7 @@ void GameObject::CleanupsBeforeDelete()
ownerType = "pet";
sLog.outError("Delete GameObject (GUID: %u Entry: %u SpellId %u LinkedGO %u) that lost references to owner (GUID %u Type '%s') GO list. Crash possible later.",
- GetGUIDLow(), GetGOInfo()->id, m_spellId, GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
+ GetGUIDLow(), GetGOInfo()->id, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType);
}
}
}
@@ -398,7 +398,7 @@ void GameObject::Update(uint32 /*p_time*/)
{
case GAMEOBJECT_TYPE_DOOR:
case GAMEOBJECT_TYPE_BUTTON:
- if (GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
+ if (GetGOInfo()->GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
ResetDoorOrButton();
break;
}
@@ -441,7 +441,7 @@ void GameObject::Update(uint32 /*p_time*/)
}
//burning flags in some battlegrounds, if you find better condition, just add it
- if (GetGoAnimProgress() > 0)
+ if (GetGOInfo()->IsDespawnAtAction() || GetGoAnimProgress() > 0)
{
SendObjectDeSpawnAnim(GetGUID());
//reset flags
@@ -622,7 +622,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, ArtKit) )
return false;
- if(!GetDespawnPossibility())
+ if(!GetGOInfo()->GetDespawnPossibility() && !GetGOInfo()->IsDespawnAtAction())
{
SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN);
m_spawnedByDefault = true;
@@ -670,22 +670,6 @@ GameObject* GameObject::GetGameObject(WorldObject& object, uint64 guid)
return object.GetMap()->GetGameObject(guid);
}
-uint32 GameObject::GetLootId(GameObjectInfo const* ginfo)
-{
- if (!ginfo)
- return 0;
-
- switch(ginfo->type)
- {
- case GAMEOBJECT_TYPE_CHEST:
- return ginfo->chest.lootId;
- case GAMEOBJECT_TYPE_FISHINGHOLE:
- return ginfo->fishinghole.lootId;
- default:
- return 0;
- }
-}
-
/*********************************************************/
/*** QUEST SYSTEM ***/
/*********************************************************/
@@ -801,7 +785,7 @@ bool GameObject::ActivateToQuest( Player *pTarget)const
// scan GO chest with loot including quest items
case GAMEOBJECT_TYPE_CHEST:
{
- if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetLootId(), pTarget))
+ if(LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), pTarget))
{
//TODO: fix this hack
//look for battlegroundAV for some objects which are only activated after mine gots captured by own team
@@ -907,7 +891,7 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f
return;
if(!time_to_restore)
- time_to_restore = GetAutoCloseTime();
+ time_to_restore = GetGOInfo()->GetAutoCloseTime();
SwitchDoorOrButton(true,alternative);
SetLootState(GO_ACTIVATED);
@@ -1382,6 +1366,7 @@ void GameObject::Use(Unit* user)
}
Spell *spell = new Spell(spellCaster, spellInfo, triggered);
+ //Spell *spell = new Spell(spellCaster, spellInfo, triggered,GetGUID());
// spell target is user of GO
SpellCastTargets targets;
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 5d5ee8c7050..763117de167 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -399,6 +399,87 @@ struct GameObjectInfo
} raw;
};
uint32 ScriptId;
+
+ // helpers
+ bool IsDespawnAtAction() const
+ {
+ switch(type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.consumable;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.consumable;
+ default: return false;
+ }
+ }
+
+ uint32 GetLockId() const
+ {
+ switch(type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: return door.lockId;
+ case GAMEOBJECT_TYPE_BUTTON: return button.lockId;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.lockId;
+ case GAMEOBJECT_TYPE_CHEST: return chest.lockId;
+ case GAMEOBJECT_TYPE_TRAP: return trap.lockId;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.lockId;
+ case GAMEOBJECT_TYPE_AREADAMAGE: return areadamage.lockId;
+ case GAMEOBJECT_TYPE_CAMERA: return camera.lockId;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.lockId;
+ case GAMEOBJECT_TYPE_FISHINGHOLE:return fishinghole.lockId;
+ case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.lockId;
+ default: return 0;
+ }
+ }
+
+ bool GetDespawnPossibility() const // despawn at targeting of cast?
+ {
+ switch(type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune;
+ case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune;
+ case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune;
+ case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune;
+ case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune;
+ default: return true;
+ }
+ }
+
+ uint32 GetLinkedGameObjectEntry() const
+ {
+ switch(type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.linkedTrapId;
+ case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.linkedTrapId;
+ case GAMEOBJECT_TYPE_GOOBER: return goober.linkedTrapId;
+ default: return 0;
+ }
+ }
+
+ uint32 GetAutoCloseTime() const
+ {
+ uint32 autoCloseTime = 0;
+ switch(type)
+ {
+ case GAMEOBJECT_TYPE_DOOR: autoCloseTime = door.autoCloseTime; break;
+ case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = button.autoCloseTime; break;
+ case GAMEOBJECT_TYPE_TRAP: autoCloseTime = trap.autoCloseTime; break;
+ case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = goober.autoCloseTime; break;
+ case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = transport.autoCloseTime; break;
+ case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = areadamage.autoCloseTime; break;
+ default: break;
+ }
+ return autoCloseTime / 0x10000;
+ }
+
+ uint32 GetLootId() const
+ {
+ switch(type)
+ {
+ case GAMEOBJECT_TYPE_CHEST: return chest.lootId;
+ case GAMEOBJECT_TYPE_FISHINGHOLE: return fishinghole.lootId;
+ default: return 0;
+ }
+ }
};
class OPvPCapturePoint;
@@ -520,40 +601,6 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB();
- static uint32 GetLootId(GameObjectInfo const* info);
- uint32 GetLootId() const { return GetLootId(GetGOInfo()); }
- uint32 GetLockId() const
- {
- switch(GetGoType())
- {
- case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.lockId;
- case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.lockId;
- case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.lockId;
- case GAMEOBJECT_TYPE_CHEST: return GetGOInfo()->chest.lockId;
- case GAMEOBJECT_TYPE_TRAP: return GetGOInfo()->trap.lockId;
- case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.lockId;
- case GAMEOBJECT_TYPE_AREADAMAGE: return GetGOInfo()->areadamage.lockId;
- case GAMEOBJECT_TYPE_CAMERA: return GetGOInfo()->camera.lockId;
- case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.lockId;
- case GAMEOBJECT_TYPE_FISHINGHOLE:return GetGOInfo()->fishinghole.lockId;
- case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.lockId;
- default: return 0;
- }
- }
-
- bool GetDespawnPossibility() const
- {
- switch(GetGoType())
- {
- case GAMEOBJECT_TYPE_DOOR: return GetGOInfo()->door.noDamageImmune;
- case GAMEOBJECT_TYPE_BUTTON: return GetGOInfo()->button.noDamageImmune;
- case GAMEOBJECT_TYPE_QUESTGIVER: return GetGOInfo()->questgiver.noDamageImmune;
- case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.noDamageImmune;
- case GAMEOBJECT_TYPE_FLAGSTAND: return GetGOInfo()->flagstand.noDamageImmune;
- case GAMEOBJECT_TYPE_FLAGDROP: return GetGOInfo()->flagdrop.noDamageImmune;
- default: return true;
- }
- }
time_t GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const
@@ -624,34 +671,7 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject
void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false);
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
- // 0 = use `gameobject`.`spawntimesecs`
- uint32 GetLinkedGameObjectEntry() const
- {
- switch(GetGoType())
- {
- case GAMEOBJECT_TYPE_CHEST: return GetGOInfo()->chest.linkedTrapId;
- case GAMEOBJECT_TYPE_SPELL_FOCUS: return GetGOInfo()->spellFocus.linkedTrapId;
- case GAMEOBJECT_TYPE_GOOBER: return GetGOInfo()->goober.linkedTrapId;
- default: return 0;
- }
- }
-
- uint32 GetAutoCloseTime() const
- {
- uint32 autoCloseTime = 0;
- switch(GetGoType())
- {
- case GAMEOBJECT_TYPE_DOOR: autoCloseTime = GetGOInfo()->door.autoCloseTime; break;
- case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = GetGOInfo()->button.autoCloseTime; break;
- case GAMEOBJECT_TYPE_TRAP: autoCloseTime = GetGOInfo()->trap.autoCloseTime; break;
- case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = GetGOInfo()->goober.autoCloseTime; break;
- case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = GetGOInfo()->transport.autoCloseTime; break;
- case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = GetGOInfo()->areadamage.autoCloseTime; break;
- default: break;
- }
- return autoCloseTime / 0x10000;
- }
void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target);
diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp
index 0490d133bf2..b54d7b90774 100644
--- a/src/game/LootMgr.cpp
+++ b/src/game/LootMgr.cpp
@@ -1152,7 +1152,7 @@ void LoadLootTemplates_Gameobject()
{
if(GameObjectInfo const* gInfo = sGOStorage.LookupEntry<GameObjectInfo>(i))
{
- if(uint32 lootid = GameObject::GetLootId(gInfo))
+ if(uint32 lootid = gInfo->GetLootId())
{
if(!ids_set.count(lootid))
LootTemplates_Gameobject.ReportNotExistedId(lootid);
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 02764a7dac6..b5e8245c676 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -1525,6 +1525,12 @@ void ObjectMgr::LoadGameobjects()
data.rotation2 = fields[ 9].GetFloat();
data.rotation3 = fields[10].GetFloat();
data.spawntimesecs = fields[11].GetInt32();
+
+ if (data.spawntimesecs==0 && gInfo->IsDespawnAtAction())
+ {
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `spawntimesecs` (0) value, but gameobejct marked as despawnable at action.",guid,data.id);
+ }
+
data.animprogress = fields[12].GetUInt32();
data.ArtKit = 0;
@@ -6140,6 +6146,16 @@ inline void CheckGONoDamageImmuneId(GameObjectInfo const* goInfo,uint32 dataN,ui
goInfo->id,goInfo->type,N,dataN);
}
+inline void CheckGOConsumable(GameObjectInfo const* goInfo,uint32 dataN,uint32 N)
+{
+ // 0/1 correct values
+ if (dataN <= 1)
+ return;
+
+ sLog.outErrorDb("Gameobject (Entry: %u GoType: %u) have data%d=%u but expected boolean (0/1) consumable field value.",
+ goInfo->id,goInfo->type,N,dataN);
+}
+
void ObjectMgr::LoadGameobjectInfo()
{
SQLGameObjectLoader loader;
@@ -6182,6 +6198,8 @@ void ObjectMgr::LoadGameobjectInfo()
if (goInfo->chest.lockId)
CheckGOLockId(goInfo,goInfo->chest.lockId,0);
+ CheckGOConsumable(goInfo,goInfo->chest.consumable,3);
+
if (goInfo->chest.linkedTrapId) // linked trap
CheckGOLinkedTrapId(goInfo,goInfo->chest.linkedTrapId,7);
break;
@@ -6217,6 +6235,8 @@ void ObjectMgr::LoadGameobjectInfo()
if (goInfo->goober.lockId)
CheckGOLockId(goInfo,goInfo->goober.lockId,0);
+ CheckGOConsumable(goInfo,goInfo->goober.consumable,3);
+
if (goInfo->goober.pageId) // pageId
{
if (!sPageTextStore.LookupEntry<PageText>(goInfo->goober.pageId))
@@ -7183,7 +7203,7 @@ void ObjectMgr::LoadGameObjectForQuests()
// scan GO chest with loot including quest items
case GAMEOBJECT_TYPE_CHEST:
{
- uint32 loot_id = GameObject::GetLootId(goInfo);
+ uint32 loot_id = goInfo->GetLootId();
// find quest loot for GO
if(LootTemplates_Gameobject.HaveQuestLootFor(loot_id))
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 004019ec1e6..fd27607a402 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -7564,7 +7564,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (go->getLootState() == GO_READY)
{
- uint32 lootid = go->GetLootId();
+ uint32 lootid = go->GetGOInfo()->GetLootId();
//TODO: fix this big hack
if((go->GetEntry() == BG_AV_OBJECTID_MINE_N || go->GetEntry() == BG_AV_OBJECTID_MINE_S))
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 050e233313b..a501f83710d 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -4827,7 +4827,7 @@ SpellCastResult Spell::CheckCast(bool strict)
uint32 lockId = 0;
if (GameObject* go = m_targets.getGOTarget())
{
- lockId = go->GetLockId();
+ lockId = go->GetGOInfo()->GetLockId();
if (!lockId)
return SPELL_FAILED_BAD_TARGETS;
}
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 2cfb3dad26a..b34fab6afc9 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -3165,7 +3165,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
// these objects must have been spawned by outdoorpvp!
else if(gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr.HandleOpenGo(player, gameObjTarget->GetGUID()))
return;
- lockId = gameObjTarget->GetLockId();
+ lockId = goInfo->GetLockId();
guid = gameObjTarget->GetGUID();
}
else if(itemTarget)
@@ -4625,7 +4625,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
}
}
- if(uint32 linkedEntry = pGameObj->GetLinkedGameObjectEntry())
+ if(uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry())
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map,
@@ -6497,7 +6497,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
data << uint64(pGameObj->GetGUID());
m_caster->SendMessageToSet(&data,true);
- if(uint32 linkedEntry = pGameObj->GetLinkedGameObjectEntry())
+ if(uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry())
{
GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap,