diff options
author | megamage <none@none> | 2009-07-16 12:06:07 +0800 |
---|---|---|
committer | megamage <none@none> | 2009-07-16 12:06:07 +0800 |
commit | e152ff8ec5fc3282b0ab3d1740f05886f90335ed (patch) | |
tree | 296587187e967b314a15faa24757365112ff2cff | |
parent | 208087ff6ee592150b1ed387bbc135566a02a359 (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.cpp | 29 | ||||
-rw-r--r-- | src/game/GameObject.h | 142 | ||||
-rw-r--r-- | src/game/LootMgr.cpp | 2 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 22 | ||||
-rw-r--r-- | src/game/Player.cpp | 2 | ||||
-rw-r--r-- | src/game/Spell.cpp | 2 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 6 |
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, |