diff options
Diffstat (limited to 'src/game/GameObject.cpp')
-rw-r--r-- | src/game/GameObject.cpp | 241 |
1 files changed, 1 insertions, 240 deletions
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index d7315f9626b..f4cd1fb8af4 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -17,7 +17,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - #include "Common.h" #include "QuestDef.h" #include "GameObject.h" @@ -39,14 +38,11 @@ #include "Util.h" #include "OutdoorPvPMgr.h" #include "BattleGroundAV.h" - GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue) { m_objectType |= TYPEMASK_GAMEOBJECT; m_objectTypeId = TYPEID_GAMEOBJECT; - m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION | UPDATEFLAG_ROTATION); - m_valuesCount = GAMEOBJECT_END; m_respawnTime = 0; m_respawnDelayTime = 25; @@ -57,17 +53,14 @@ GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue) m_cooldownTime = 0; m_goInfo = NULL; m_goData = NULL; - m_DBTableGuid = 0; m_rotation = 0; } - GameObject::~GameObject() { //if(m_uint32Values) // field array can be not exist if GameOBject not loaded // CleanupsBeforeDelete(); } - void GameObject::CleanupsBeforeDelete() { if(m_uint32Values) // field array can be not exist if GameOBject not loaded @@ -81,7 +74,6 @@ void GameObject::CleanupsBeforeDelete() owner = ObjectAccessor::GetObjectInWorld(owner_guid, (Player*)NULL); else*/ owner = ObjectAccessor::GetUnit(*this,owner_guid); - if(owner) owner->RemoveGameObject(this,false); else @@ -91,14 +83,12 @@ void GameObject::CleanupsBeforeDelete() ownerType = "player"; else if(IS_PET_GUID(owner_guid)) 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, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(owner_guid), ownerType); } } } } - void GameObject::AddToWorld() { ///- Register the gameobject for guid lookup @@ -106,12 +96,10 @@ void GameObject::AddToWorld() { if(m_zoneScript) m_zoneScript->OnGameObjectCreate(this, true); - ObjectAccessor::Instance().AddObject(this); WorldObject::AddToWorld(); } } - void GameObject::RemoveFromWorld() { ///- Remove the gameobject from the accessor @@ -119,7 +107,6 @@ void GameObject::RemoveFromWorld() { if(m_zoneScript) m_zoneScript->OnGameObjectCreate(this, false); - // Possible crash at access to deleted GO in Unit::m_gameobj if(uint64 owner_guid = GetOwnerGUID()) { @@ -132,73 +119,53 @@ void GameObject::RemoveFromWorld() ObjectAccessor::Instance().RemoveObject(this); } } - bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit) { ASSERT(map); SetMap(map); - Relocate(x,y,z,ang); if(!IsPositionValid()) { sLog.outError("Gameobject (GUID: %u Entry: %u ) not created. Suggested coordinates isn't valid (X: %f Y: %f)",guidlow,name_id,x,y); return false; } - SetPhaseMask(phaseMask,false); - GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(name_id); if (!goinfo) { sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f) ang: %f rotation0: %f rotation1: %f rotation2: %f rotation3: %f",guidlow, name_id, map->GetId(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3); return false; } - Object::_Create(guidlow, goinfo->id, HIGHGUID_GAMEOBJECT); - m_goInfo = goinfo; - if (goinfo->type >= MAX_GAMEOBJECT_TYPE) { sLog.outErrorDb("Gameobject (GUID: %u Entry: %u) not created: it have not exist GO type '%u' in `gameobject_template`. It's will crash client if created.",guidlow,name_id,goinfo->type); return false; } - SetFloatValue(GAMEOBJECT_PARENTROTATION+0, rotation0); SetFloatValue(GAMEOBJECT_PARENTROTATION+1, rotation1); - UpdateRotationFields(rotation2,rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_PARENTROTATION+2/3 - SetFloatValue(OBJECT_FIELD_SCALE_X, goinfo->size); - SetUInt32Value(GAMEOBJECT_FACTION, goinfo->faction); SetUInt32Value(GAMEOBJECT_FLAGS, goinfo->flags); - SetEntry(goinfo->id); - SetUInt32Value(GAMEOBJECT_DISPLAYID, goinfo->displayId); - // GAMEOBJECT_BYTES_1, index at 0, 1, 2 and 3 SetGoState(go_state); SetGoType(GameobjectTypes(goinfo->type)); - SetGoArtKit(0); // unknown what this is SetGoAnimProgress(animprogress); - SetByteValue(GAMEOBJECT_BYTES_1, 2, artKit); - switch(goinfo->type) { case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING: m_goValue->building.health = goinfo->building.intactNumHits + goinfo->building.damagedNumHits; break; } - SetZoneScript(); - return true; } - void GameObject::Update(uint32 /*p_time*/) { if (IS_MO_TRANSPORT(GetGUID())) @@ -206,7 +173,6 @@ void GameObject::Update(uint32 /*p_time*/) //((Transport*)this)->Update(p_time); return; } - switch (m_lootState) { case GO_NOT_READY: @@ -233,16 +199,13 @@ void GameObject::Update(uint32 /*p_time*/) { SetGoState(GO_STATE_ACTIVE); SetUInt32Value(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); - UpdateData udata; WorldPacket packet; BuildValuesUpdateBlockForPlayer(&udata,((Player*)caster)); udata.BuildPacket(&packet); ((Player*)caster)->GetSession()->SendPacket(&packet); - SendCustomAnim(); } - m_lootState = GO_READY; // can be successfully open with some chance } return; @@ -262,7 +225,6 @@ void GameObject::Update(uint32 /*p_time*/) m_respawnTime = 0; m_SkillupList.clear(); m_usetimes = 0; - switch (GetGoType()) { case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now @@ -271,7 +233,6 @@ void GameObject::Update(uint32 /*p_time*/) if(caster && caster->GetTypeId()==TYPEID_PLAYER) { caster->FinishSpell(CURRENT_CHANNELED_SPELL); - WorldPacket data(SMSG_FISH_NOT_HOOKED,0); ((Player*)caster)->GetSession()->SendPacket(&data); } @@ -302,7 +263,6 @@ void GameObject::Update(uint32 /*p_time*/) } } } - if(isSpawned()) { // traps can have time and can not have @@ -311,11 +271,9 @@ void GameObject::Update(uint32 /*p_time*/) { if(m_cooldownTime >= time(NULL)) return; - // traps Unit* owner = GetOwner(); Unit* ok = NULL; // pointer to appropriate target if found any - bool IsBattleGroundTrap = false; //FIXME: this is activation radius (in different casting radius that must be selected from spell data) //TODO: move activated state code (cast itself) to GO_ACTIVATED, in this place only check activating and set state @@ -328,15 +286,12 @@ void GameObject::Update(uint32 /*p_time*/) { if(m_respawnTime > 0) break; - radius = goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3 IsBattleGroundTrap = true; - if(!radius) return; } } - // Note: this hack with search required until GO casting not implemented // search unfriendly creature if(owner) // hunter trap @@ -356,22 +311,17 @@ void GameObject::Update(uint32 /*p_time*/) VisitNearbyWorldObject(radius, searcher); ok = player; } - if (ok) { // some traps do not have spell but should be triggered if(goInfo->trap.spellId) CastSpell(ok, goInfo->trap.spellId); - m_cooldownTime = time(NULL) + 4; // 4 seconds - // count charges //if(goInfo->trap.charges > 0) // AddUse(); - if(owner) SetLootState(GO_JUST_DEACTIVATED); - if(IsBattleGroundTrap && ok->GetTypeId() == TYPEID_PLAYER) { //BattleGround gameobjects case @@ -390,7 +340,6 @@ void GameObject::Update(uint32 /*p_time*/) } } } - break; } case GO_ACTIVATED: @@ -412,7 +361,6 @@ void GameObject::Update(uint32 /*p_time*/) if (GetGoType() == GAMEOBJECT_TYPE_GOOBER) { uint32 spellId = GetGOInfo()->goober.spellId; - if(spellId) { std::set<uint32>::const_iterator it = m_unique_users.begin(); @@ -424,13 +372,11 @@ void GameObject::Update(uint32 /*p_time*/) //if (owner) owner->CastSpell(owner, spellId, false, 0, 0, GetGUID()); if (owner) owner->CastSpell(owner, spellId, false); } - m_unique_users.clear(); m_usetimes = 0; } //any return here in case battleground traps } - if(GetOwnerGUID()) { if(Unit* owner = GetOwner(false)) @@ -441,7 +387,6 @@ void GameObject::Update(uint32 /*p_time*/) } return; } - //burning flags in some battlegrounds, if you find better condition, just add it if (GetGOInfo()->IsDespawnAtAction() || GetGoAnimProgress() > 0) { @@ -449,76 +394,59 @@ void GameObject::Update(uint32 /*p_time*/) //reset flags SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); } - loot.clear(); SetLootState(GO_READY); - if(!m_respawnDelayTime) return; - if(!m_spawnedByDefault) { m_respawnTime = 0; ObjectAccessor::UpdateObjectVisibility(this); return; } - m_respawnTime = time(NULL) + m_respawnDelayTime; - // if option not set then object will be saved at grid unload if(sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY)) SaveRespawnTime(); - ObjectAccessor::UpdateObjectVisibility(this); - break; } } } - void GameObject::Refresh() { // not refresh despawned not casted GO (despawned casted GO destroyed in all cases anyway) if(m_respawnTime > 0 && m_spawnedByDefault) return; - if(isSpawned()) GetMap()->Add(this); } - void GameObject::AddUniqueUse(Player* player) { AddUse(); m_unique_users.insert(player->GetGUIDLow()); } - void GameObject::Delete() { SetLootState(GO_NOT_READY); if (GetOwnerGUID()) if (Unit * owner = GetOwner(false)) owner->RemoveGameObject(this, false); - assert (!GetOwnerGUID()); SendObjectDeSpawnAnim(GetGUID()); - SetGoState(GO_STATE_READY); SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); - uint16 poolid = poolhandler.IsPartOfAPool(GetGUIDLow(), TYPEID_GAMEOBJECT); if (poolid) poolhandler.UpdatePool(poolid, GetGUIDLow(), TYPEID_GAMEOBJECT); else AddObjectToRemoveList(); } - void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner) { fishloot->clear(); - uint32 zone, subzone; GetZoneAndAreaId(zone,subzone); - // if subzone loot exist use it if(LootTemplates_Fishing.HaveLootFor(subzone)) fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner,true); @@ -526,7 +454,6 @@ void GameObject::getFishLoot(Loot *fishloot, Player* loot_owner) else fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner,true); } - void GameObject::SaveToDB() { // this should only be used when the gameobject has already been loaded @@ -537,22 +464,17 @@ void GameObject::SaveToDB() sLog.outError("GameObject::SaveToDB failed, cannot get gameobject data!"); return; } - SaveToDB(GetMapId(), data->spawnMask, data->phaseMask); } - void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) { const GameObjectInfo *goI = GetGOInfo(); - if (!goI) return; - if (!m_DBTableGuid) m_DBTableGuid = GetGUIDLow(); // update in loaded data (changing data only in this place) GameObjectData& data = objmgr.NewGOData(m_DBTableGuid); - // data->guid = guid don't must be update at save data.id = GetEntry(); data.mapid = mapid; @@ -570,7 +492,6 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) data.go_state = GetGoState(); data.spawnMask = spawnMask; data.artKit = GetGoArtKit(); - // updated in DB std::ostringstream ss; ss << "INSERT INTO gameobject VALUES ( " @@ -590,23 +511,19 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) << m_respawnDelayTime << ", " << uint32(GetGoAnimProgress()) << ", " << uint32(GetGoState()) << ")"; - WorldDatabase.BeginTransaction(); WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog( ss.str( ).c_str( ) ); WorldDatabase.CommitTransaction(); } - bool GameObject::LoadFromDB(uint32 guid, Map *map) { GameObjectData const* data = objmgr.GetGOData(guid); - if( !data ) { sLog.outErrorDb("Gameobject (GUID: %u) not found in table `gameobject`, can't load. ",guid); return false; } - uint32 entry = data->id; //uint32 map_id = data->mapid; // already used before call uint32 phaseMask = data->phaseMask; @@ -614,26 +531,20 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) float y = data->posY; float z = data->posZ; float ang = data->orientation; - float rotation0 = data->rotation0; float rotation1 = data->rotation1; float rotation2 = data->rotation2; float rotation3 = data->rotation3; - uint32 animprogress = data->animprogress; GOState go_state = data->go_state; uint32 artKit = data->artKit; - m_DBTableGuid = guid; if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); - if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit) ) return false; - if(data->spawntimesecs >= 0) { m_spawnedByDefault = true; - if(!GetGOInfo()->GetDespawnPossibility() && !GetGOInfo()->IsDespawnAtAction()) { SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NODESPAWN); @@ -644,7 +555,6 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) { m_respawnDelayTime = data->spawntimesecs; m_respawnTime = objmgr.GetGORespawnTime(m_DBTableGuid, map->GetInstanceId()); - // ready to respawn if(m_respawnTime && m_respawnTime <= time(NULL)) { @@ -659,12 +569,9 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map) m_respawnDelayTime = -data->spawntimesecs; m_respawnTime = 0; } - m_goData = data; - return true; } - void GameObject::DeleteFromDB() { objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); @@ -672,12 +579,10 @@ void GameObject::DeleteFromDB() WorldDatabase.PExecuteLog("DELETE FROM gameobject WHERE guid = '%u'", m_DBTableGuid); WorldDatabase.PExecuteLog("DELETE FROM game_event_gameobject WHERE guid = '%u'", m_DBTableGuid); } - GameObject* GameObject::GetGameObject(WorldObject& object, uint64 guid) { return object.GetMap()->GetGameObject(guid); } - /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ @@ -691,7 +596,6 @@ bool GameObject::hasQuest(uint32 quest_id) const } return false; } - bool GameObject::hasInvolvedQuest(uint32 quest_id) const { QuestRelations const& qr = objmgr.mGOQuestInvolvedRelations; @@ -702,7 +606,6 @@ bool GameObject::hasInvolvedQuest(uint32 quest_id) const } return false; } - bool GameObject::IsTransport() const { // If something is marked as a transport, don't transmit an out of range packet for it. @@ -710,37 +613,31 @@ bool GameObject::IsTransport() const if(!gInfo) return false; return gInfo->type == GAMEOBJECT_TYPE_TRANSPORT || gInfo->type == GAMEOBJECT_TYPE_MO_TRANSPORT; } - Unit* GameObject::GetOwner(bool inWorld) const { if (inWorld) return ObjectAccessor::GetUnit(*this, GetOwnerGUID()); return ObjectAccessor::GetUnitInOrOutOfWorld(*this, GetOwnerGUID()); } - void GameObject::SaveRespawnTime() { if(m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault) objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime); } - bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const { // Not in world if(!IsInWorld() || !u->IsInWorld()) return false; - // Transport always visible at this step implementation if(IsTransport() && IsInMap(u)) return true; - // quick check visibility false cases for non-GM-mode if(!u->isGameMaster()) { // despawned and then not visible for non-GM in GM-mode if(!isSpawned()) return false; - // special invisibility cases if(GetGOInfo()->type == GAMEOBJECT_TYPE_TRAP && GetGOInfo()->trap.stealthed) { @@ -749,12 +646,10 @@ bool GameObject::isVisibleForInState(Player const* u, bool inVisibleList) const return false; } } - // check distance return IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false); } - bool GameObject::canDetectTrap(Player const* u, float distance) const { if(u->hasUnitState(UNIT_STAT_STUNNED)) @@ -765,17 +660,14 @@ bool GameObject::canDetectTrap(Player const* u, float distance) const return false; if(u->HasAuraType(SPELL_AURA_DETECT_STEALTH)) return true; - //Visible distance is modified by -Level Diff (every level diff = 0.25f in visible distance) float visibleDistance = (int32(u->getLevel()) - int32(GetOwner()->getLevel()))* 0.25f; //GetModifier for trap (miscvalue 1) //35y for aura 2836 //WARNING: these values are guessed, may be not blizzlike visibleDistance += u->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DETECT, 1)* 0.5f; - return distance < visibleDistance; } - void GameObject::Respawn() { if(m_spawnedByDefault && m_respawnTime > 0) @@ -784,12 +676,10 @@ void GameObject::Respawn() objmgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),0); } } - bool GameObject::ActivateToQuest( Player *pTarget)const { if(!objmgr.IsGameObjectForQuests(GetEntry())) return false; - switch(GetGoType()) { // scan GO chest with loot including quest items @@ -816,20 +706,16 @@ bool GameObject::ActivateToQuest( Player *pTarget)const default: break; } - return false; } - void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) { GameObjectInfo const* trapInfo = sGOStorage.LookupEntry<GameObjectInfo>(trapEntry); if(!trapInfo || trapInfo->type!=GAMEOBJECT_TYPE_TRAP) return; - SpellEntry const* trapSpell = sSpellStore.LookupEntry(trapInfo->trap.spellId); if(!trapSpell) // checked at load already return; - float range; SpellRangeEntry const * srentry = sSpellRangeStore.LookupEntry(trapSpell->rangeIndex); //get owner to check hostility of GameObject @@ -844,7 +730,6 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) //if no owner assume that object is hostile to target range = GetSpellMaxRangeForHostile(srentry); } - // search nearest linked GO GameObject* trapGO = NULL; { @@ -852,63 +737,48 @@ void GameObject::TriggeringLinkedGameObject( uint32 trapEntry, Unit* target) CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; - MaNGOS::NearestGameObjectEntryInObjectRangeCheck go_check(*target,trapEntry,range); MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> checker(this, trapGO,go_check); - TypeContainerVisitor<Trinity::GameObjectLastSearcher<Trinity::NearestGameObjectEntryInObjectRangeCheck>, GridTypeMapContainer > object_checker(checker); CellLock<GridReadGuard> cell_lock(cell, p); cell_lock->Visit(cell_lock, object_checker, *GetMap(), *target, range); } - // found correct GO // FIXME: when GO casting will be implemented trap must cast spell to target if(trapGO) target->CastSpell(target,trapSpell,true, 0, 0, GetGUID()); } - GameObject* GameObject::LookupFishingHoleAround(float range) { GameObject* ok = NULL; - CellPair p(Trinity::ComputeCellPair(GetPositionX(),GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; MaNGOS::NearestGameObjectFishingHole u_check(*this, range); MaNGOS::GameObjectSearcher<MaNGOS::NearestGameObjectFishingHole> checker(this, ok, u_check); - CellLock<GridReadGuard> cell_lock(cell, p); - TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::NearestGameObjectFishingHole>, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *GetMap(), *this, range); - return ok; } - void GameObject::ResetDoorOrButton() { if (m_lootState == GO_READY || m_lootState == GO_JUST_DEACTIVATED) return; - SwitchDoorOrButton(false); SetLootState(GO_JUST_DEACTIVATED); m_cooldownTime = 0; } - void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */) { if(m_lootState != GO_READY) return; - if(!time_to_restore) time_to_restore = GetGOInfo()->GetAutoCloseTime(); - SwitchDoorOrButton(true,alternative); SetLootState(GO_ACTIVATED); - m_cooldownTime = time(NULL) + time_to_restore; } - void GameObject::SetGoArtKit(uint8 kit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, kit); @@ -916,7 +786,6 @@ void GameObject::SetGoArtKit(uint8 kit) if(data) data->artKit = kit; } - void GameObject::SetGoArtKit(uint8 artkit, GameObject *go, uint32 lowguid) { const GameObjectData *data = NULL; @@ -927,49 +796,40 @@ void GameObject::SetGoArtKit(uint8 artkit, GameObject *go, uint32 lowguid) } else if(lowguid) data = objmgr.GetGOData(lowguid); - if(data) const_cast<GameObjectData*>(data)->artKit = artkit; } - void GameObject::SwitchDoorOrButton(bool activate, bool alternative /* = false */) { if(activate) SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); else RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_IN_USE); - if(GetGoState() == GO_STATE_READY) //if closed -> open SetGoState(alternative ? GO_STATE_ACTIVE_ALTERNATIVE : GO_STATE_ACTIVE); else //if open -> close SetGoState(GO_STATE_READY); } - void GameObject::Use(Unit* user) { // by default spell caster is user Unit* spellCaster = user; uint32 spellId = 0; bool triggered = false; - switch(GetGoType()) { case GAMEOBJECT_TYPE_DOOR: //0 case GAMEOBJECT_TYPE_BUTTON: //1 //doors/buttons never really despawn, only reset to default state/flags UseDoorOrButton(); - // activate script GetMap()->ScriptsStart(sGameObjectScripts, GetDBTableGUIDLow(), spellCaster, this); return; - case GAMEOBJECT_TYPE_QUESTGIVER: //2 { if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - player->PrepareQuestMenu( GetGUID() ); player->SendPreparedQuest( GetGUID() ); return; @@ -980,22 +840,16 @@ void GameObject::Use(Unit* user) GameObjectInfo const* info = GetGOInfo(); if(!info) return; - if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - // a chair may have n slots. we have to calculate their positions and teleport the player to the nearest one - // check if the db is sane if(info->chair.slots > 0) { float lowestDist = DEFAULT_VISIBILITY_DISTANCE; - float x_lowest = GetPositionX(); float y_lowest = GetPositionY(); - // the object orientation + 1/2 pi // every slot will be on that straight line float orthogonalOrientation = GetOrientation()+M_PI*0.5f; @@ -1004,20 +858,16 @@ void GameObject::Use(Unit* user) { // the distance between this slot and the center of the go - imagine a 1D space float relativeDistance = (info->size*i)-(info->size*(info->chair.slots-1)/2.0f); - float x_i = GetPositionX() + relativeDistance * cos(orthogonalOrientation); float y_i = GetPositionY() + relativeDistance * sin(orthogonalOrientation); - // calculate the distance between the player and this slot float thisDistance = player->GetDistance2d(x_i, y_i); - /* debug code. It will spawn a npc on each slot to visualize them. Creature* helper = player->SummonCreature(14496, x_i, y_i, GetPositionZ(), GetOrientation(), TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10000); std::ostringstream output; output << i << ": thisDist: " << thisDistance; helper->MonsterSay(output.str().c_str(), LANG_UNIVERSAL, 0); */ - if(thisDistance <= lowestDist) { lowestDist = thisDistance; @@ -1039,11 +889,9 @@ void GameObject::Use(Unit* user) case GAMEOBJECT_TYPE_GOOBER: //10 { GameObjectInfo const* info = GetGOInfo(); - if(user->GetTypeId()==TYPEID_PLAYER) { Player* player = (Player*)user; - // show page if(info->goober.pageId) { @@ -1051,17 +899,13 @@ void GameObject::Use(Unit* user) data << GetGUID(); player->GetSession()->SendPacket(&data); } - // possible quest objective for active quests player->CastedCreatureOrGO(info->id, GetGUID(), 0); - if (info->goober.eventId) GetMap()->ScriptsStart(sEventScripts, info->goober.eventId, player, this); } - // cast this spell later if provided spellId = info->goober.spellId; - break; } case GAMEOBJECT_TYPE_CAMERA: //13 @@ -1069,18 +913,13 @@ void GameObject::Use(Unit* user) GameObjectInfo const* info = GetGOInfo(); if(!info) return; - if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - if (info->camera.cinematicId) player->SendCinematicStart(info->camera.cinematicId); - if (info->camera.eventID) GetMap()->ScriptsStart(sEventScripts, info->camera.eventID, player, this); - return; } //fishing bobber @@ -1088,12 +927,9 @@ void GameObject::Use(Unit* user) { if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - if(player->GetGUID() != GetOwnerGUID()) return; - switch(getLootState()) { case GO_READY: // ready for loot @@ -1101,24 +937,18 @@ void GameObject::Use(Unit* user) // 1) skill must be >= base_zone_skill // 2) if skill == base_zone_skill => 5% chance // 3) chance is linear dependence from (base_zone_skill-skill) - uint32 zone, subzone; GetZoneAndAreaId(zone,subzone); - int32 zone_skill = objmgr.GetFishingBaseSkillLevel( subzone ); if(!zone_skill) zone_skill = objmgr.GetFishingBaseSkillLevel( zone ); - //provide error, no fishable zone or area should be 0 if(!zone_skill) sLog.outErrorDb("Fishable areaId %u are not properly defined in `skill_fishing_base_level`.",subzone); - int32 skill = player->GetSkillValue(SKILL_FISHING); int32 chance = skill - zone_skill + 5; int32 roll = irand(1,100); - DEBUG_LOG("Fishing check (skill: %i zone min skill: %i chance %i roll: %i",skill,zone_skill,chance,roll); - if(chance >= roll) { player->UpdateFishingSkill(); @@ -1129,7 +959,6 @@ void GameObject::Use(Unit* user) // prevent removing GO at spell cancel player->RemoveGameObject(this,false); SetOwnerGUID(player->GetGUID()); - //TODO: find reasonable value for fishing hole search GameObject* ok = LookupFishingHoleAround(20.0f + CONTACT_DISTANCE); if (ok) @@ -1149,47 +978,34 @@ void GameObject::Use(Unit* user) default: { SetLootState(GO_JUST_DEACTIVATED); - WorldPacket data(SMSG_FISH_NOT_HOOKED, 0); player->GetSession()->SendPacket(&data); break; } } - player->FinishSpell(CURRENT_CHANNELED_SPELL); return; } - case GAMEOBJECT_TYPE_SUMMONING_RITUAL: //18 { if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - Unit* caster = GetOwner(); - GameObjectInfo const* info = GetGOInfo(); - if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; - // accept only use by player from same group for caster except caster itself if(((Player*)caster)==player || !((Player*)caster)->IsInSameRaidWith(player)) return; - AddUniqueUse(player); - // full amount unique participants including original summoner if(GetUniqueUseCount() < info->summoningRitual.reqParticipants) return; - // in case summoning ritual caster is GO creator spellCaster = caster; - if(!caster->GetCurrentSpell(CURRENT_CHANNELED_SPELL)) return; - spellId = info->summoningRitual.spellId; if(spellId==62330) // GO store not existed spell, replace by expected { @@ -1198,54 +1014,41 @@ void GameObject::Use(Unit* user) spellId = 61993; triggered = true; } - // finish spell player->FinishSpell(CURRENT_CHANNELED_SPELL); - // can be deleted now SetLootState(GO_JUST_DEACTIVATED); - // go to end function to spell casting break; } case GAMEOBJECT_TYPE_SPELLCASTER: //22 { SetUInt32Value(GAMEOBJECT_FLAGS,2); - GameObjectInfo const* info = GetGOInfo(); if(!info) return; - if(info->spellcaster.partyOnly) { Unit* caster = GetOwner(); if( !caster || caster->GetTypeId()!=TYPEID_PLAYER ) return; - if(user->GetTypeId()!=TYPEID_PLAYER || !((Player*)user)->IsInSameRaidWith((Player*)caster)) return; } - spellId = info->spellcaster.spellId; - AddUse(); break; } case GAMEOBJECT_TYPE_MEETINGSTONE: //23 { GameObjectInfo const* info = GetGOInfo(); - if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetSelection()); - // accept only use by player from same group for caster except caster itself if(!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameGroupWith(player)) return; - //required lvl checks! uint8 level = player->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) @@ -1253,22 +1056,17 @@ void GameObject::Use(Unit* user) level = targetPlayer->getLevel(); if (level < info->meetingstone.minLevel || level > info->meetingstone.maxLevel) return; - if(info->id==194097) spellId = 61994; // Ritual of Summoning else spellId = 59782; // Summoning Stone Effect - break; } - case GAMEOBJECT_TYPE_FLAGSTAND: // 24 { if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - if( player->CanUseBattleGroundObject() ) { // in battleground check @@ -1291,9 +1089,7 @@ void GameObject::Use(Unit* user) { if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - if( player->CanUseBattleGroundObject() ) { // in battleground check @@ -1337,18 +1133,13 @@ void GameObject::Use(Unit* user) GameObjectInfo const* info = GetGOInfo(); if(!info) return; - if(user->GetTypeId()!=TYPEID_PLAYER) return; - Player* player = (Player*)user; - // fallback, will always work player->TeleportTo(GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(),TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET); - WorldPacket data(SMSG_ENABLE_BARBER_SHOP, 0); player->GetSession()->SendPacket(&data); - player->SetStandState(UNIT_STAND_STATE_SIT_LOW_CHAIR+info->barberChair.chairheight); return; } @@ -1356,10 +1147,8 @@ void GameObject::Use(Unit* user) sLog.outDebug("Unknown Object Type %u", GetGoType()); break; } - if(!spellId) return; - SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId ); if(!spellInfo) { @@ -1369,23 +1158,18 @@ void GameObject::Use(Unit* user) sLog.outDebug("WORLD: %u non-dbc spell was handled by OutdoorPvP", spellId); return; } - Spell *spell = new Spell(spellCaster, spellInfo, triggered); //Spell *spell = new Spell(spellCaster, spellInfo, triggered,GetGUID()); - // spell target is user of GO SpellCastTargets targets; targets.setUnitTarget( user ); - spell->prepare(&targets); } - void GameObject::CastSpell(Unit* target, uint32 spellId) { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId); if(!spellInfo) return; - bool self = false; for(uint8 i = 0; i < 3; ++i) { @@ -1395,18 +1179,15 @@ void GameObject::CastSpell(Unit* target, uint32 spellId) break; } } - if(self) { if(target) target->CastSpell(target, spellInfo, true); return; } - //summon world trigger Creature *trigger = SummonTrigger(GetPositionX(), GetPositionY(), GetPositionZ(), 0, 1); if(!trigger) return; - trigger->SetVisibility(VISIBILITY_OFF); //should this be true? if(Unit *owner = GetOwner()) { @@ -1416,14 +1197,13 @@ void GameObject::CastSpell(Unit* target, uint32 spellId) else { trigger->setFaction(14); - // Set owner guid for target if no owner avalible - needed by trigger auras + // Set owner guid for target if no owner avalible - needed by trigger auras // - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell()) trigger->CastSpell(target, spellInfo, true, 0, 0, target ? target->GetGUID() : 0); } //trigger->setDeathState(JUST_DIED); //trigger->RemoveCorpse(); } - void GameObject::SendCustomAnim() { WorldPacket data(SMSG_GAMEOBJECT_CUSTOM_ANIM,8+4); @@ -1431,13 +1211,11 @@ void GameObject::SendCustomAnim() data << (uint32)0; SendMessageToSet(&data, true); } - bool GameObject::IsInRange(float x, float y, float z, float radius) const { GameObjectDisplayInfoEntry const * info = sGameObjectDisplayInfoStore.LookupEntry(GetUInt32Value(GAMEOBJECT_DISPLAYID)); if(!info) return IsWithinDist3d(x, y, z, radius); - float sinA = sin(GetOrientation()); float cosA = cos(GetOrientation()); float dx = x - GetPositionX(); @@ -1452,23 +1230,19 @@ bool GameObject::IsInRange(float x, float y, float z, float radius) const && dy < info->maxY + radius && dy > info->minY - radius && dz < info->maxZ + radius && dz > info->minZ - radius; } - void GameObject::TakenDamage(uint32 damage) { if(!m_goValue->building.health) return; - if(m_goValue->building.health > damage) m_goValue->building.health -= damage; else m_goValue->building.health = 0; - if(HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED)) // from damaged to destroyed { if(!m_goValue->building.health) { RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED); SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->building.destroyedDisplayId); EventInform(m_goInfo->building.destroyedEvent); @@ -1482,14 +1256,12 @@ void GameObject::TakenDamage(uint32 damage) m_goValue->building.health = 0; else if(!m_goValue->building.health) m_goValue->building.health = 1; - SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED); SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->building.damagedDisplayId); EventInform(m_goInfo->building.damagedEvent); } } } - void GameObject::Rebuild() { RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED + GO_FLAG_DESTROYED); @@ -1497,13 +1269,11 @@ void GameObject::Rebuild() m_goValue->building.health = m_goInfo->building.intactNumHits + m_goInfo->building.damagedNumHits; EventInform(m_goInfo->building.rebuildingEvent); } - void GameObject::EventInform(uint32 eventId) { if(eventId && m_zoneScript) m_zoneScript->ProcessEvent(this, eventId); } - // overwrite WorldObject function for proper name localization const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const { @@ -1516,36 +1286,27 @@ const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const return cl->Name[loc_idx].c_str(); } } - return GetName(); } - void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/) { static double const atan_pow = atan(pow(2.0f, -20.0f)); - double f_rot1 = sin(GetOrientation() / 2.0f); double f_rot2 = cos(GetOrientation() / 2.0f); - int64 i_rot1 = int64(f_rot1 / atan_pow *(f_rot2 >= 0 ? 1.0f : -1.0f)); int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF; - //float f_rot2 = sin(0.0f / 2.0f); //int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f)); //rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000; - //float f_rot3 = sin(0.0f / 2.0f); //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f)); //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000; - m_rotation = rotation; - if(rotation2==0.0f && rotation3==0.0f) { rotation2 = f_rot1; rotation3 = f_rot2; } - SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2); SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3); } |