Project SkyFire Core
SkyFire 5.4.8 server core API documentation
Loading...
Searching...
No Matches
GameObject.cpp
Go to the documentation of this file.
1/*
2* This file is part of Project SkyFire https://www.projectskyfire.org.
3* See LICENSE.md file for Copyright information
4*/
5
6#include "Battleground.h"
7#include "CellImpl.h"
9#include "DynamicTree.h"
10#include "GameObjectAI.h"
11#include "GameObjectModel.h"
13#include "GridNotifiersImpl.h"
14#include "Group.h"
15#include "GroupMgr.h"
16#include "ObjectMgr.h"
17#include "OutdoorPvPMgr.h"
18#include "Player.h"
19#include "PoolMgr.h"
20#include "ScriptMgr.h"
21#include "SpellMgr.h"
22#include "Transport.h"
23#include "UpdateFieldFlags.h"
24#include "World.h"
25#include <G3D/Quat.h>
26
28m_model(NULL), m_goValue(), m_AI(NULL)
29{
32
34
36 m_respawnTime = 0;
39 m_spawnedByDefault = true;
40 m_usetimes = 0;
41 m_spellId = 0;
43 m_goInfo = NULL;
44 m_ritualOwner = NULL;
45 m_goData = NULL;
46
47 m_DBTableGuid = 0;
48 m_rotation = 0;
49
54
55 ResetLootMode(); // restore default loot mode
56 m_stationaryPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f);
57}
58
60{
61 delete m_AI;
62 delete m_model;
63 //if (m_uint32Values) // field array can be not exist if GameOBject not loaded
64 // CleanupsBeforeDelete();
65}
66
68{
69 if (m_AI)
70 delete m_AI;
71
73
74 if (!m_AI)
75 return false;
76
77 m_AI->InitializeAI();
78 return true;
79}
80
81std::string GameObject::GetAIName() const
82{
83 if (GameObjectTemplate const* got = sObjectMgr->GetGameObjectTemplate(GetEntry()))
84 return got->AIName;
85
86 return "";
87}
88
89void GameObject::CleanupsBeforeDelete(bool /*finalCleanup*/)
90{
91 if (IsInWorld())
93
94 if (m_uint32Values) // field array can be not exist if GameOBject not loaded
96
97 if (GetTransport() && !ToTransport())
98 {
100 SetTransport(NULL);
101 m_movementInfo.transport.Reset();
102 }
103}
104
106{
107 uint64 ownerGUID = GetOwnerGUID();
108 if (!ownerGUID)
109 return;
110
111 if (Unit* owner = ObjectAccessor::GetUnit(*this, ownerGUID))
112 {
113 owner->RemoveGameObject(this, false);
115 return;
116 }
117
118 const char* ownerType = "creature";
119 if (IS_PLAYER_GUID(ownerGUID))
120 ownerType = "player";
121 else if (IS_PET_GUID(ownerGUID))
122 ownerType = "pet";
123
124 SF_LOG_FATAL("misc", "Removed GameObject (GUID: %u Entry: %u SpellId: %u LinkedGO: %u) that just lost any reference to the owner (GUID: %u Type: '%s') GO list",
125 GetGUIDLow(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), GUID_LOPART(ownerGUID), ownerType);
126 SetOwnerGUID(0);
127}
128
130{
132 if (!IsInWorld())
133 {
134 if (m_zoneScript)
135 m_zoneScript->OnGameObjectCreate(this);
136
137 sObjectAccessor->AddObject(this);
138
139 // The state can be changed after GameObject::Create but before GameObject::AddToWorld
141 if (m_model)
143
144 EnableCollision(toggledState);
146 }
147}
148
150{
152 if (IsInWorld())
153 {
154 if (m_zoneScript)
155 m_zoneScript->OnGameObjectRemove(this);
156
158 if (m_model)
159 if (GetMap()->ContainsGameObjectModel(*m_model))
162 sObjectAccessor->RemoveObject(this);
163 }
164}
165
166bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit)
167{
168 ASSERT(map);
169 SetMap(map);
170
171 Relocate(x, y, z, ang);
172 m_stationaryPosition.Relocate(x, y, z, ang);
173 if (!IsPositionValid())
174 {
175 SF_LOG_ERROR("misc", "Gameobject (GUID: %u Entry: %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)", guidlow, name_id, x, y);
176 return false;
177 }
178
180 if (m_zoneScript)
181 {
182 name_id = m_zoneScript->GetGameObjectEntry(guidlow, name_id);
183 if (!name_id)
184 return false;
185 }
186
187 GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(name_id);
188 if (!goinfo)
189 {
190 SF_LOG_ERROR("sql.sql", "Gameobject (GUID: %u Entry: %u) not created: non-existing entry in `gameobject_template`. Map: %u (X: %f Y: %f Z: %f)", guidlow, name_id, map->GetId(), x, y, z);
191 return false;
192 }
193
194 HighGuid guidHigh = HIGHGUID_GAMEOBJECT;
195 if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT)
196 {
198 guidHigh = HIGHGUID_TRANSPORT;
199 }
200
201 Object::_Create(guidlow, goinfo->entry, guidHigh);
202
203 m_goInfo = goinfo;
204
205 if (goinfo->type >= MAX_GAMEOBJECT_TYPE)
206 {
207 SF_LOG_ERROR("sql.sql", "Gameobject (GUID: %u Entry: %u) not created: non-existing GO type '%u' in `gameobject_template`. It will crash client if created.", guidlow, name_id, goinfo->type);
208 return false;
209 }
210
213
214 UpdateRotationFields(rotation2, rotation3); // GAMEOBJECT_FACING, GAMEOBJECT_ROTATION, GAMEOBJECT_FIELD_PARENT_ROTATION+2/3
215
216 SetObjectScale(goinfo->size);
217
220
221 SetEntry(goinfo->entry);
222
223 // set name for logs usage, doesn't affect anything ingame
224 SetName(goinfo->name);
225
226 SetDisplayId(goinfo->displayId);
227
229 // GAMEOBJECT_FIELD_STATE_SPELL_VISUAL_ID, index at 0, 1, 2 and 3
231 SetGoState(go_state);
232 SetGoArtKit(artKit);
233
234 SetGoHealth(0xFF);
235
236 switch (goinfo->type)
237 {
239 SetGoAnimProgress(animprogress);
240 m_goValue.FishingHole.MaxOpens = std::rand() % GetGOInfo()->fishinghole.maxSuccessOpens + GetGOInfo()->fishinghole.minSuccessOpens;
241 break;
243 m_goValue.Building.Health = goinfo->building.intactNumHits + goinfo->building.damagedNumHits;
244 m_goValue.Building.MaxHealth = m_goValue.Building.Health;
246 SetUInt32Value(GAMEOBJECT_FIELD_PARENT_ROTATION, m_goInfo->building.destructibleData);
247 break;
249 {
252 goinfo->transport.startOpen != 0, !m_transportPauseTimes.empty()));
255 SetGoAnimProgress(animprogress);
256 break;
257 }
260 break;
262 if (GetGOInfo()->trap.stealthed)
263 {
264 m_stealth.AddFlag(STEALTH_TRAP);
265 m_stealth.AddValue(STEALTH_TRAP, 70);
266 }
267
268 if (GetGOInfo()->trap.invisible)
269 {
271 m_invisibility.AddValue(INVISIBILITY_TRAP, 300);
272 }
273 break;
274 default:
275 SetGoAnimProgress(animprogress);
276 break;
277 }
280
281 // Initialize loot duplicate count depending on raid difficulty
282 if (map->Is25ManRaid())
283 loot.maxDuplicates = 3;
284
285 return true;
286}
287
289{
290 if (AI())
291 AI()->UpdateAI(diff);
292 else if (!AIM_Initialize())
293 SF_LOG_ERROR("misc", "Could not initialize GameObjectAI");
294
297
298 switch (m_lootState)
299 {
301 {
302 switch (GetGoType())
303 {
305 {
306 // Arming Time for GAMEOBJECT_TYPE_TRAP (6)
307 GameObjectTemplate const* goInfo = GetGOInfo();
308 // Bombs
309 if (goInfo->trap.type == 2)
310 m_cooldownTime = time(NULL) + 10; // Hardcoded tooltip value
311 else if (Unit* owner = GetOwner())
312 {
313 if (owner->IsInCombat())
314 m_cooldownTime = time(NULL) + goInfo->trap.startDelay;
315 }
317 break;
318 }
319 /* TODO: Fix movement in unloaded grid - currently GO will just disappear
320 case GAMEOBJECT_TYPE_TRANSPORT:
321 {
322 if (!m_goValue.Transport.AnimationInfo)
323 break;
324
325 if (GetGoState() == GO_STATE_READY)
326 {
327 m_goValue.Transport.PathProgress += diff;
328 uint32 timer = m_goValue.Transport.PathProgress % m_goValue.Transport.AnimationInfo->TotalTime;
329 TransportAnimationEntry const* node = m_goValue.Transport.AnimationInfo->GetAnimNode(timer);
330 if (node && m_goValue.Transport.CurrentSeg != node->TimeSeg)
331 {
332 m_goValue.Transport.CurrentSeg = node->TimeSeg;
333
334 G3D::Quat rotation = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer);
335 G3D::Vector3 pos = rotation.toRotationMatrix()
336 * G3D::Matrix3::fromEulerAnglesZYX(GetOrientation(), 0.0f, 0.0f)
337 * G3D::Vector3(node->X, node->Y, node->Z);
338
339 pos += G3D::Vector3(GetStationaryX(), GetStationaryY(), GetStationaryZ());
340
341 G3D::Vector3 src(GetPositionX(), GetPositionY(), GetPositionZ());
342
343 sLog->outInfo("misc", "Src: %s Dest: %s", src.toString().c_str(), pos.toString().c_str());
344
345 GetMap()->GameObjectRelocation(this, pos.x, pos.y, pos.z, GetOrientation());
346 }
347 }
348 break;
349 }
350 */
352 {
353 // fishing code (bobber ready)
354 if (time(NULL) > m_respawnTime - FISHING_BOBBER_READY_TIME)
355 {
356 // splash bobber (bobber ready now)
357 Unit* caster = GetOwner();
358 if (caster && caster->GetTypeId() == TypeID::TYPEID_PLAYER)
359 {
362
363 UpdateData udata(caster->GetMapId());
364 WorldPacket packet;
365 BuildValuesUpdateBlockForPlayer(&udata, caster->ToPlayer());
366 udata.BuildPacket(&packet);
367 caster->ToPlayer()->SendDirectMessage(&packet);
368
370 }
371
372 m_lootState = LootState::GO_READY; // can be successfully open with some chance
373 }
374 return;
375 }
376 default:
377 m_lootState = LootState::GO_READY; // for other GOis same switched without delay to GO_READY
378 break;
379 }
380 // NO BREAK for switch (m_lootState)
381 }
383 {
384 if (m_respawnTime > 0) // timer on
385 {
386 time_t now = time(NULL);
387 if (m_respawnTime <= now) // timer expired
388 {
390 time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid);
391 if (linkedRespawntime) // Can't respawn, the master is dead
392 {
393 uint64 targetGuid = sObjectMgr->GetLinkedRespawnGuid(dbtableHighGuid);
394 if (targetGuid == dbtableHighGuid) // if linking self, never respawn (check delayed to next day)
396 else
397 m_respawnTime = (now > linkedRespawntime ? now : linkedRespawntime) + std::rand() % MINUTE + 5; // else copy time from master and add a little
398 SaveRespawnTime(); // also save to DB immediately
399 return;
400 }
401
402 m_respawnTime = 0;
403 m_SkillupList.clear();
404 m_usetimes = 0;
405
406 switch (GetGoType())
407 {
408 case GAMEOBJECT_TYPE_FISHINGNODE: // can't fish now
409 {
410 Unit* caster = GetOwner();
411 if (caster && caster->GetTypeId() == TypeID::TYPEID_PLAYER)
412 {
413 caster->ToPlayer()->RemoveGameObject(this, false);
414
416 caster->ToPlayer()->SendDirectMessage(&data);
417 }
418 // can be delete
420 return;
421 }
424 //we need to open doors if they are closed (add there another condition if this code breaks some usage, but it need to be here for battlegrounds)
427 break;
429 // Initialize a new max fish count on respawn
430 m_goValue.FishingHole.MaxOpens = std::rand() % GetGOInfo()->fishinghole.maxSuccessOpens + GetGOInfo()->fishinghole.minSuccessOpens;
431 break;
432 default:
433 break;
434 }
435
436 if (!m_spawnedByDefault) // despawn timer
437 {
438 // can be despawned or destroyed
440 return;
441 }
442 // respawn timer
443 uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0;
444 if (poolid)
445 sPoolMgr->UpdatePool<GameObject>(poolid, GetDBTableGUIDLow());
446 else
447 GetMap()->AddToMap(this);
448 }
449 }
450
451 if (isSpawned())
452 {
453 // traps can have time and can not have
454 GameObjectTemplate const* goInfo = GetGOInfo();
455 if (goInfo->type == GAMEOBJECT_TYPE_TRAP)
456 {
457 if (m_cooldownTime >= time(NULL))
458 return;
459
460 // Type 2 - Bomb (will go away after casting it's spell)
461 if (goInfo->trap.type == 2)
462 {
463 if (goInfo->trap.spellId)
464 CastSpell(NULL, goInfo->trap.spellId); // FIXME: null target won't work for target type 1
466 break;
467 }
468 // Type 0 and 1 - trap (type 0 will not get removed after casting a spell)
469 Unit* owner = GetOwner();
470 Unit* ok = NULL; // pointer to appropriate target if found any
471
472 bool IsBattlegroundTrap = false;
473 //FIXME: this is activation radius (in different casting radius that must be selected from spell data)
475 float radius = (float)(goInfo->trap.radius) / 3 * 2;
476 if (!radius)
477 {
478 if (goInfo->trap.cooldown != 3) // cast in other case (at some triggering/linked go/etc explicit call)
479 return;
480 else
481 {
482 if (m_respawnTime > 0)
483 break;
484
485 radius = (float)goInfo->trap.cooldown; // battlegrounds gameobjects has data2 == 0 && data5 == 3
486 IsBattlegroundTrap = true;
487
488 if (!radius)
489 return;
490 }
491 }
492
493 // Note: this hack with search required until GO casting not implemented
494 // search unfriendly creature
495 if (owner && goInfo->trap.autoCloseTime != -1) // hunter trap; -1 = environmental (campfire)
496 {
497 Skyfire::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
499 VisitNearbyGridObject(radius, searcher);
500 if (!ok) VisitNearbyWorldObject(radius, searcher);
501 }
502 else // environmental trap
503 {
504 // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support
505 // affect only players
506 Player* player = NULL;
507 Skyfire::AnyPlayerInObjectRangeCheck checker(this, radius);
509 VisitNearbyWorldObject(radius, searcher);
510 ok = player;
511 }
512
513 if (ok)
514 {
515 // some traps do not have spell but should be triggered
516 if (goInfo->trap.spellId)
517 CastSpell(ok, goInfo->trap.spellId);
518
519 m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); // template or 4 seconds
520
521 if (goInfo->trap.type == 1)
523
524 if (IsBattlegroundTrap && ok->GetTypeId() == TypeID::TYPEID_PLAYER)
525 {
526 //Battleground gameobjects case
527 if (ok->ToPlayer()->InBattleground())
528 if (Battleground* bg = ok->ToPlayer()->GetBattleground())
529 bg->HandleTriggerBuff(GetGUID());
530 }
531 }
532 }
533 else if (uint32 max_charges = goInfo->GetCharges())
534 {
535 if (m_usetimes >= max_charges)
536 {
537 m_usetimes = 0;
538 SetLootState(LootState::GO_JUST_DEACTIVATED); // can be despawned or destroyed
539 }
540 }
541 }
542
543 break;
544 }
546 {
547 switch (GetGoType())
548 {
551 if (GetGOInfo()->GetAutoCloseTime() && (m_cooldownTime < time(NULL)))
553 break;
555 if (m_cooldownTime < time(NULL))
556 {
558
560 m_cooldownTime = 0;
561 }
562 break;
565 {
566 if (m_groupLootTimer <= diff)
567 {
568 Group* group = sGroupMgr->GetGroupByGUID(lootingGroupLowGUID);
569 if (group)
570 group->EndRoll(&loot);
573 }
574 else m_groupLootTimer -= diff;
575 }
576 default:
577 break;
578 }
579 break;
580 }
582 {
583 //if Gameobject should cast spell, then this, but some GOs (type = 10) should be destroyed
585 {
586 uint32 spellId = GetGOInfo()->goober.spellId;
587
588 if (spellId)
589 {
590 for (std::set<uint64>::const_iterator it = m_unique_users.begin(); it != m_unique_users.end(); ++it)
591 // m_unique_users can contain only player GUIDs
592 if (Player* owner = ObjectAccessor::GetPlayer(*this, *it))
593 owner->CastSpell(owner, spellId, false);
594
595 m_unique_users.clear();
596 m_usetimes = 0;
597 }
598
600
601 //any return here in case battleground traps
602 if (GetGOInfo()->flags & GO_FLAG_NODESPAWN)
603 return;
604 }
605
606 loot.clear();
607
610 if (GetSpellId() || GetOwnerGUID())
611 {
613 Delete();
614 return;
615 }
616
618
619 //burning flags in some battlegrounds, if you find better condition, just add it
620 if (GetGOInfo()->IsDespawnAtAction() || GetGoAnimProgress() > 0)
621 {
623 //reset flags
625 }
626
628 return;
629
631 {
632 m_respawnTime = 0;
634 return;
635 }
636
637 m_respawnTime = time(NULL) + m_respawnDelayTime;
638
639 // if option not set then object will be saved at grid unload
642
644
645 break;
646 }
647 }
648 sScriptMgr->OnGameObjectUpdate(this, diff);
649}
650
652{
653 // not refresh despawned not casted GO (despawned casted GO destroyed in all cases anyway)
655 return;
656
657 if (isSpawned())
658 GetMap()->AddToMap(this);
659}
660
662{
663 AddUse();
664 m_unique_users.insert(player->GetGUID());
665}
666
683
684void GameObject::getFishLoot(Loot* fishloot, Player* loot_owner)
685{
686 fishloot->clear();
687
688 uint32 zone, subzone;
689 GetZoneAndAreaId(zone, subzone);
690
691 // if subzone loot exist use it
692 if (!fishloot->FillLoot(subzone, LootTemplates_Fishing, loot_owner, true, true))
693 // else use zone loot (must exist in like case)
694 fishloot->FillLoot(zone, LootTemplates_Fishing, loot_owner, true);
695}
696
698{
699 // this should only be used when the gameobject has already been loaded
700 // preferably after adding to map, because mapid may not be valid otherwise
701 GameObjectData const* data = sObjectMgr->GetGOData(m_DBTableGuid);
702 if (!data)
703 {
704 SF_LOG_ERROR("misc", "GameObject::SaveToDB failed, cannot get gameobject data!");
705 return;
706 }
707
708 SaveToDB(GetMapId(), data->spawnMask);
709}
710
711void GameObject::SaveToDB(uint32 mapid, uint32 spawnMask)
712{
713 const GameObjectTemplate* goI = GetGOInfo();
714
715 if (!goI)
716 return;
717
718 if (!m_DBTableGuid)
720 // update in loaded data (changing data only in this place)
721 GameObjectData& data = sObjectMgr->NewGOData(m_DBTableGuid);
722
723 // data->guid = guid must not be updated at save
724 data.id = GetEntry();
725 data.mapid = mapid;
726 data.posX = GetPositionX();
727 data.posY = GetPositionY();
728 data.posZ = GetPositionZ();
736 data.go_state = GetGoState();
737 data.spawnMask = spawnMask;
738 data.artKit = GetGoArtKit();
739
740 // Update in DB
741 SQLTransaction trans = WorldDatabase.BeginTransaction();
742
743 uint8 index = 0;
744
745 PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
746 stmt->setUInt32(0, m_DBTableGuid);
747 trans->Append(stmt);
748
749 stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_GAMEOBJECT);
750 stmt->setUInt32(index++, m_DBTableGuid);
751 stmt->setUInt32(index++, GetEntry());
752 stmt->setUInt16(index++, uint16(mapid));
753 stmt->setUInt32(index++, spawnMask);
754 stmt->setFloat(index++, GetPositionX());
755 stmt->setFloat(index++, GetPositionY());
756 stmt->setFloat(index++, GetPositionZ());
757 stmt->setFloat(index++, GetOrientation());
762 stmt->setInt32(index++, int32(m_respawnDelayTime));
763 stmt->setUInt8(index++, GetGoAnimProgress());
764 stmt->setUInt8(index++, uint8(GetGoState()));
765 trans->Append(stmt);
766
767 WorldDatabase.CommitTransaction(trans);
768}
769
770bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap)
771{
772 GameObjectData const* data = sObjectMgr->GetGOData(guid);
773
774 if (!data)
775 {
776 SF_LOG_ERROR("sql.sql", "Gameobject (GUID: %u) not found in table `gameobject`, can't load. ", guid);
777 return false;
778 }
779
780 uint32 entry = data->id;
781 //uint32 map_id = data->mapid; // already used before call
782 float x = data->posX;
783 float y = data->posY;
784 float z = data->posZ;
785 float ang = data->orientation;
786
787 float rotation0 = data->rotation0;
788 float rotation1 = data->rotation1;
789 float rotation2 = data->rotation2;
790 float rotation3 = data->rotation3;
791
792 uint32 animprogress = data->animprogress;
793 GOState go_state = data->go_state;
794 uint32 artKit = data->artKit;
795
796 m_DBTableGuid = guid;
797 if (map->GetInstanceId() != 0) guid = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);
798
799 if (!Create(guid, entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit))
800 return false;
801
802 // unset flag 0x04 for questgiver objects if they have it. no idea why they have it.
805
806 if (data->phaseid)
807 SetPhased(data->phaseid, false, true);
808
809 if (data->phaseGroup)
810 {
811 for (auto ph : GetPhasesForGroup(data->phaseGroup))
812 SetPhased(ph, false, true);
813 }
814
815 if (data->spawntimesecs >= 0)
816 {
817 m_spawnedByDefault = true;
818
819 if (!GetGOInfo()->GetDespawnPossibility() && !GetGOInfo()->IsDespawnAtAction())
820 {
823 m_respawnTime = 0;
824 }
825 else
826 {
829
830 // ready to respawn
831 if (m_respawnTime && m_respawnTime <= time(NULL))
832 {
833 m_respawnTime = 0;
835 }
836 }
837 }
838 else
839 {
840 m_spawnedByDefault = false;
842 m_respawnTime = 0;
843 }
844
845 m_goData = data;
846
847 if (addToMap && !GetMap()->AddToMap(this))
848 return false;
849
850 return true;
851}
852
854{
856 sObjectMgr->DeleteGOData(m_DBTableGuid);
857
858 PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT);
859
860 stmt->setUInt32(0, m_DBTableGuid);
861
862 WorldDatabase.Execute(stmt);
863
864 stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_EVENT_GAMEOBJECT);
865
866 stmt->setUInt32(0, m_DBTableGuid);
867
868 WorldDatabase.Execute(stmt);
869}
870
872{
873 return object.GetMap()->GetGameObject(guid);
874}
875
876/*********************************************************/
877/*** QUEST SYSTEM ***/
878/*********************************************************/
879bool GameObject::hasQuest(uint32 quest_id) const
880{
881 QuestRelationBounds qr = sObjectMgr->GetGOQuestRelationBounds(GetEntry());
882 for (QuestRelations::const_iterator itr = qr.first; itr != qr.second; ++itr)
883 {
884 if (itr->second == quest_id)
885 return true;
886 }
887 return false;
888}
889
891{
892 QuestRelationBounds qir = sObjectMgr->GetGOQuestInvolvedRelationBounds(GetEntry());
893 for (QuestRelations::const_iterator itr = qir.first; itr != qir.second; ++itr)
894 {
895 if (itr->second == quest_id)
896 return true;
897 }
898 return false;
899}
900
902{
903 // If something is marked as a transport, don't transmit an out of range packet for it.
904 GameObjectTemplate const* gInfo = GetGOInfo();
905 if (!gInfo)
906 return false;
907
909}
910
911// is Dynamic transport = non-stop Transport
913{
914 // If something is marked as a transport, don't transmit an out of range packet for it.
915 GameObjectTemplate const* gInfo = GetGOInfo();
916 if (!gInfo)
917 return false;
918
919 return gInfo->type == GAMEOBJECT_TYPE_MO_TRANSPORT || (gInfo->type == GAMEOBJECT_TYPE_TRANSPORT && !gInfo->transport.pause);
920}
921
923{
924 if (GetGoType() == GAMEOBJECT_TYPE_TRANSPORT && m_goValue.Transport.AnimationInfo)
925 return m_goValue.Transport.AnimationInfo->TotalTime;
926
928}
929
931{
932 m_goValue.Transport.HoldingAtProgress = false;
934 GetGoType(), GetTransportPeriod(), pathProgress);
936}
937
938std::vector<uint32> const* GameObject::GetPauseTimes() const
939{
941 return &m_transportPauseTimes;
942
943 return NULL;
944}
945
947{
948 m_goValue.Transport.AnimationInfo = sTransportMgr->GetTransportAnimInfo(GetGOInfo()->entry);
949 m_goValue.Transport.CurrentSeg = 0;
950 m_goValue.Transport.PathProgress = 0;
951 m_goValue.Transport.WaitingAtPathStart = false;
952 m_goValue.Transport.HoldingAtProgress = false;
953 m_goValue.Transport.HoldProgress = 0;
954 m_goValue.Transport.StateChangeEndTime = 0;
955
956 m_transportPauseTimes.clear();
957
958 uint32 const period = GetTransportPeriod();
959 if (GetGOInfo()->transport.pause && period)
961
962 if (!m_transportPauseTimes.empty() && GetGOInfo()->transport.startOpen)
963 m_goValue.Transport.PathProgress = m_transportPauseTimes.front();
964 else
966 !m_transportPauseTimes.empty(), period, getMSTime());
967
968 uint32 const now = getMSTime();
969 m_goValue.Transport.WaitingAtPathStart = !m_transportPauseTimes.empty() && !GetGOInfo()->transport.startOpen;
970 m_goValue.Transport.StateChangeTime = now;
971 m_goValue.Transport.StateChangeEndTime = now;
972 m_goValue.Transport.StateChangeProgress = m_goValue.Transport.PathProgress;
975}
976
978{
979 uint32 const period = GetTransportPeriod();
980 if (!period)
981 return;
982
983 uint32 newProgress = m_goValue.Transport.PathProgress;
984 bool updateStoppedFlag = false;
985 bool stopped = false;
986 if (m_goValue.Transport.HoldingAtProgress)
987 {
988 newProgress = m_goValue.Transport.HoldProgress;
989 updateStoppedFlag = true;
990 stopped = true;
991 }
992 else if (m_transportPauseTimes.empty())
994 else
995 {
996 uint32 const targetProgress = GetLegacyTransportTargetProgress(GetGoState());
997 uint32 const stopTime = m_goValue.Transport.StateChangeEndTime;
998 uint32 const now = getMSTime();
999
1000 if (stopTime > now)
1001 {
1002 uint32 const travelTime = stopTime - m_goValue.Transport.StateChangeTime;
1003 uint32 const elapsedTime = now - m_goValue.Transport.StateChangeTime;
1005 m_goValue.Transport.StateChangeProgress, targetProgress, period, elapsedTime, travelTime,
1007 }
1008 else
1009 {
1010 newProgress = targetProgress;
1011 stopped = true;
1012 }
1013
1014 updateStoppedFlag = true;
1015 }
1016
1017 if (updateStoppedFlag)
1019
1020 if (newProgress == m_goValue.Transport.PathProgress)
1021 return;
1022
1023 m_goValue.Transport.PathProgress = newProgress;
1024 // Legacy transport movement is client-side from DBC path data; only notify progress changes here.
1026}
1027
1029{
1031 return;
1032
1034 return;
1035
1036 uint32 const period = GetTransportPeriod();
1037 if (!period)
1038 return;
1039
1041
1042 m_goValue.Transport.HoldingAtProgress = false;
1043 if (newState == GOState::GO_STATE_TRANSPORT_STOPPED && m_goValue.Transport.WaitingAtPathStart)
1044 m_goValue.Transport.WaitingAtPathStart = false;
1045
1046 uint32 const targetProgress = GetLegacyTransportTargetProgress(newState);
1047 uint32 const now = getMSTime();
1049 m_goValue.Transport.PathProgress, targetProgress);
1050
1051 m_goValue.Transport.StateChangeTime = now;
1052 m_goValue.Transport.StateChangeProgress = m_goValue.Transport.PathProgress;
1053 m_goValue.Transport.StateChangeEndTime = now + travelTime;
1054 SetUInt32Value(GAMEOBJECT_FIELD_LEVEL, m_goValue.Transport.StateChangeEndTime);
1055
1056 if (int32(oldState) < int32(GOState::GO_STATE_TRANSPORT_ACTIVE) || oldState == newState)
1057 {
1058 if (m_goValue.Transport.PathProgress > targetProgress)
1060 else
1062 }
1063 else
1064 {
1065 int32 const stopFrameCount = int32(m_transportPauseTimes.size());
1066 int32 newToOldStateDelta = int32(newState) - int32(oldState);
1067 if (newToOldStateDelta < 0)
1068 newToOldStateDelta += stopFrameCount + 1;
1069
1070 int32 oldToNewStateDelta = int32(oldState) - int32(newState);
1071 if (oldToNewStateDelta < 0)
1072 oldToNewStateDelta += stopFrameCount + 1;
1073
1074 bool const isAtStartOfPath = m_goValue.Transport.StateChangeProgress == 0;
1075 if (oldToNewStateDelta < newToOldStateDelta && !isAtStartOfPath)
1077 else
1079 }
1080
1081 SetLegacyTransportStopped(travelTime == 0);
1082
1083 if (oldState != newState)
1085}
1086
1088{
1090 return;
1091
1092 uint32 const now = getMSTime();
1093 m_goValue.Transport.HoldingAtProgress = false;
1094 m_goValue.Transport.WaitingAtPathStart = false;
1095 m_goValue.Transport.StateChangeTime = now;
1096 m_goValue.Transport.StateChangeProgress = m_goValue.Transport.PathProgress;
1097 m_goValue.Transport.StateChangeEndTime = now + travelTime;
1098 SetUInt32Value(GAMEOBJECT_FIELD_LEVEL, m_goValue.Transport.StateChangeEndTime);
1099 SetLegacyTransportStopped(travelTime == 0);
1101}
1102
1104{
1106 return;
1107
1108 uint32 const now = getMSTime();
1109 uint32 const targetProgress = m_transportPauseTimes.front();
1110
1111 m_goValue.Transport.HoldingAtProgress = false;
1112 m_goValue.Transport.WaitingAtPathStart = false;
1113 m_goValue.Transport.StateChangeTime = now;
1114 m_goValue.Transport.StateChangeProgress = m_goValue.Transport.PathProgress;
1115 m_goValue.Transport.StateChangeEndTime = now + travelTime;
1116 SetUInt32Value(GAMEOBJECT_FIELD_LEVEL, m_goValue.Transport.StateChangeEndTime);
1118
1119 if (m_goValue.Transport.PathProgress > targetProgress)
1121 else
1123
1124 SetLegacyTransportStopped(travelTime == 0);
1126}
1127
1129{
1131 return;
1132
1133 uint32 initialProgress = 0;
1134 bool waitingAtPathStart = !GetGOInfo()->transport.startOpen;
1135 if (GetGOInfo()->transport.startOpen)
1136 initialProgress = m_transportPauseTimes.front();
1137
1138 uint32 const now = getMSTime();
1139 m_goValue.Transport.PathProgress = initialProgress;
1140 m_goValue.Transport.StateChangeTime = now;
1141 m_goValue.Transport.StateChangeProgress = initialProgress;
1142 m_goValue.Transport.StateChangeEndTime = now;
1143 m_goValue.Transport.HoldProgress = initialProgress;
1144 m_goValue.Transport.HoldingAtProgress = true;
1145 m_goValue.Transport.WaitingAtPathStart = waitingAtPathStart;
1151}
1152
1154{
1156 return;
1157
1159
1160 uint32 const now = getMSTime();
1161 m_goValue.Transport.StateChangeTime = now;
1162 m_goValue.Transport.StateChangeProgress = m_goValue.Transport.PathProgress;
1163 m_goValue.Transport.StateChangeEndTime = now;
1164 m_goValue.Transport.HoldProgress = m_goValue.Transport.PathProgress;
1165 m_goValue.Transport.HoldingAtProgress = true;
1166 m_goValue.Transport.WaitingAtPathStart = false;
1171}
1172
1174{
1175 uint32 const dynamicFlags = GetUInt32Value(OBJECT_FIELD_DYNAMIC_FLAGS);
1176 uint32 const updatedFlags = Skyfire::GameObjects::SetLegacyTransportStoppedFlag(dynamicFlags, stopped);
1177
1178 if (dynamicFlags != updatedFlags)
1180}
1181
1192
1194{
1196 {
1197 if (m_goValue.Transport.WaitingAtPathStart)
1198 return 0;
1199
1200 return m_transportPauseTimes.front();
1201 }
1202
1203 return 0;
1204}
1205
1207{
1208 GameObjectTemplate const* gInfo = GetGOInfo();
1209 if (!gInfo)
1210 return false;
1211
1213}
1214
1216{
1217 return ObjectAccessor::GetUnit(*this, GetOwnerGUID());
1218}
1219
1225
1227{
1229 return true;
1230
1232 return true;
1233
1234 if (!seer)
1235 return false;
1236
1237 // Always seen by owner and friendly units
1238 if (uint64 guid = GetOwnerGUID())
1239 {
1240 if (seer->GetGUID() == guid)
1241 return true;
1242
1243 Unit* owner = GetOwner();
1244 if (owner && seer->isType(TYPEMASK_UNIT) && owner->IsFriendlyTo(((Unit*)seer)))
1245 return true;
1246 }
1247
1248 return false;
1249}
1250
1252{
1254 return true;
1255
1256 // Despawned
1257 if (!isSpawned())
1258 return true;
1259
1260 return false;
1261}
1262
1264{
1266 {
1267 m_respawnTime = time(NULL);
1269 }
1270}
1271
1273{
1274 if (target->HasQuestForGO(GetEntry()))
1275 return true;
1276
1277 if (!sObjectMgr->IsGameObjectForQuests(GetEntry()))
1278 return false;
1279
1280 switch (GetGoType())
1281 {
1282 // scan GO chest with loot including quest items
1284 {
1285 if (LootTemplates_Gameobject.HaveQuestLootForPlayer(GetGOInfo()->GetLootId(), target))
1286 {
1287 if (Battleground const* bg = target->GetBattleground())
1288 return bg->CanActivateGO(GetEntry(), target->GetTeam());
1289 return true;
1290 }
1291 break;
1292 }
1294 {
1295 if (GetGOInfo()->_generic.questID == -1 || target->GetQuestStatus(GetGOInfo()->_generic.questID) == QUEST_STATUS_INCOMPLETE)
1296 return true;
1297 break;
1298 }
1300 {
1301 if (GetGOInfo()->goober.questId == -1 || target->GetQuestStatus(GetGOInfo()->goober.questId) == QUEST_STATUS_INCOMPLETE)
1302 return true;
1303 break;
1304 }
1305 default:
1306 break;
1307 }
1308
1309 return false;
1310}
1311
1313{
1314 GameObjectTemplate const* trapInfo = sObjectMgr->GetGameObjectTemplate(trapEntry);
1315 if (!trapInfo || trapInfo->type != GAMEOBJECT_TYPE_TRAP)
1316 return;
1317
1318 SpellInfo const* trapSpell = sSpellMgr->GetSpellInfo(trapInfo->trap.spellId);
1319 if (!trapSpell) // checked at load already
1320 return;
1321
1322 float range = float(target->GetSpellMaxRangeForTarget(GetOwner(), trapSpell));
1323
1324 // search nearest linked GO
1325 GameObject* trapGO = NULL;
1326 {
1327 // using original GO distance
1329 Cell cell(p);
1330
1331 Skyfire::NearestGameObjectEntryInObjectRangeCheck go_check(*target, trapEntry, range);
1333
1335 cell.Visit(p, object_checker, *GetMap(), *target, range);
1336 }
1337
1338 // found correct GO
1339 if (trapGO)
1340 trapGO->CastSpell(target, trapInfo->trap.spellId);
1341}
1342
1344{
1345 GameObject* ok = NULL;
1346
1348 Cell cell(p);
1349 Skyfire::NearestGameObjectFishingHole u_check(*this, range);
1351
1353 cell.Visit(p, grid_object_checker, *GetMap(), *this, range);
1354
1355 return ok;
1356}
1357
1367
1368void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = false */, Unit* user /*=NULL*/)
1369{
1371 return;
1372
1373 if (!time_to_restore)
1374 time_to_restore = GetGOInfo()->GetAutoCloseTime();
1375
1376 SwitchDoorOrButton(true, alternative);
1378
1379 m_cooldownTime = time(NULL) + time_to_restore;
1380}
1381
1383{
1385 GameObjectData* data = const_cast<GameObjectData*>(sObjectMgr->GetGOData(m_DBTableGuid));
1386 if (data)
1387 data->artKit = kit;
1388}
1389
1391{
1392 const GameObjectData* data = NULL;
1393 if (go)
1394 {
1395 go->SetGoArtKit(artkit);
1396 data = go->GetGOData();
1397 }
1398 else if (lowguid)
1399 data = sObjectMgr->GetGOData(lowguid);
1400
1401 if (data)
1402 const_cast<GameObjectData*>(data)->artKit = artkit;
1403}
1404
1405void GameObject::SwitchDoorOrButton(bool activate, bool alternative /* = false */)
1406{
1407 if (activate)
1409 else
1411
1412 if (GetGoState() == GOState::GO_STATE_READY) //if closed -> open
1414 else //if open -> close
1416}
1417
1419{
1420 // we cannot use go with not selectable flags
1422 return;
1423
1424 // by default spell caster is user
1425 Unit* spellCaster = user;
1426 uint32 spellId = 0;
1427 bool triggered = false;
1428
1429 if (Player* playerUser = user->ToPlayer())
1430 {
1431 if (playerUser->OnArchaeologyFindUsed(this))
1432 return;
1433
1434 if (sScriptMgr->OnGossipHello(playerUser, this))
1435 return;
1436
1437 if (AI()->GossipHello(playerUser))
1438 return;
1439 }
1440
1441 // If cooldown data present in template
1442 if (uint32 cooldown = GetGOInfo()->GetCooldown())
1443 {
1444 if (m_cooldownTime > sWorld->GetGameTime())
1445 return;
1446
1447 m_cooldownTime = sWorld->GetGameTime() + cooldown;
1448 }
1449
1450 switch (GetGoType())
1451 {
1452 case GAMEOBJECT_TYPE_DOOR: //0
1453 case GAMEOBJECT_TYPE_BUTTON: //1
1454 //doors/buttons never really despawn, only reset to default state/flags
1455 UseDoorOrButton(0, false, user);
1456 return;
1458 {
1459 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1460 return;
1461
1462 Player* player = user->ToPlayer();
1463
1464 player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID, true);
1465 player->SendPreparedGossip(this);
1466 return;
1467 }
1468 case GAMEOBJECT_TYPE_CHEST: //3
1469 {
1470 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1471 return;
1472
1473 // Archaeology finds are handled at the start of Use(); remaining chests open as loot.
1475 return;
1476 }
1477 case GAMEOBJECT_TYPE_TRAP: //6
1478 {
1479 GameObjectTemplate const* goInfo = GetGOInfo();
1480 if (goInfo->trap.spellId)
1481 CastSpell(user, goInfo->trap.spellId);
1482
1483 m_cooldownTime = time(NULL) + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)); // template or 4 seconds
1484
1485 if (goInfo->trap.type == 1) // Deactivate after trigger
1487
1488 return;
1489 }
1490 //Sitting: Wooden bench, chairs enzz
1491 case GAMEOBJECT_TYPE_CHAIR: //7
1492 {
1493 GameObjectTemplate const* info = GetGOInfo();
1494 if (!info)
1495 return;
1496
1497 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1498 return;
1499
1500 if (ChairListSlots.empty()) // this is called once at first chair use to make list of available slots
1501 {
1502 if (info->chair.slots > 0) // sometimes chairs in DB have error in fields and we dont know number of slots
1503 for (uint32 i = 0; i < info->chair.slots; ++i)
1504 ChairListSlots[i] = 0; // Last user of current slot set to 0 (none sit here yet)
1505 else
1506 ChairListSlots[0] = 0; // error in DB, make one default slot
1507 }
1508
1509 Player* player = user->ToPlayer();
1510
1511 // a chair may have n slots. we have to calculate their positions and teleport the player to the nearest one
1512
1513 float lowestDist = DEFAULT_VISIBILITY_DISTANCE;
1514
1515 uint32 nearest_slot = 0;
1516 float x_lowest = GetPositionX();
1517 float y_lowest = GetPositionY();
1518
1519 // the object orientation + 1/2 pi
1520 // every slot will be on that straight line
1521 float orthogonalOrientation = GetOrientation() + M_PI * 0.5f;
1522 // find nearest slot
1523 bool found_free_slot = false;
1524 for (ChairSlotAndUser::iterator itr = ChairListSlots.begin(); itr != ChairListSlots.end(); ++itr)
1525 {
1526 // the distance between this slot and the center of the go - imagine a 1D space
1527 float relativeDistance = (info->size * itr->first) - (info->size * (info->chair.slots - 1) / 2.0f);
1528
1529 float x_i = GetPositionX() + relativeDistance * std::cos(orthogonalOrientation);
1530 float y_i = GetPositionY() + relativeDistance * std::sin(orthogonalOrientation);
1531
1532 if (itr->second)
1533 {
1534 if (Player* ChairUser = ObjectAccessor::FindPlayer(itr->second))
1535 {
1536 if (ChairUser->IsSitState() && ChairUser->getStandState() != UNIT_STAND_STATE_SIT && ChairUser->GetExactDist2d(x_i, y_i) < 0.1f)
1537 continue; // This seat is already occupied by ChairUser. NOTE: Not sure if the ChairUser->getStandState() != UNIT_STAND_STATE_SIT check is required.
1538 else
1539 itr->second = 0; // This seat is unoccupied.
1540 }
1541 else
1542 itr->second = 0; // The seat may of had an occupant, but they're offline.
1543 }
1544
1545 found_free_slot = true;
1546
1547 // calculate the distance between the player and this slot
1548 float thisDistance = player->GetDistance2d(x_i, y_i);
1549
1550 if (thisDistance <= lowestDist)
1551 {
1552 nearest_slot = itr->first;
1553 lowestDist = thisDistance;
1554 x_lowest = x_i;
1555 y_lowest = y_i;
1556 }
1557 }
1558
1559 if (found_free_slot)
1560 {
1561 ChairSlotAndUser::iterator itr = ChairListSlots.find(nearest_slot);
1562 if (itr != ChairListSlots.end())
1563 {
1564 itr->second = player->GetGUID(); //this slot in now used by player
1567 return;
1568 }
1569 }
1570
1571 return;
1572 }
1573 //big gun, its a spell/aura
1574 case GAMEOBJECT_TYPE_GOOBER: //10
1575 {
1576 GameObjectTemplate const* info = GetGOInfo();
1577
1578 if (user->GetTypeId() == TypeID::TYPEID_PLAYER)
1579 {
1580 Player* player = user->ToPlayer();
1581
1582 if (info->goober.pageId) // show page...
1583 {
1585 }
1586 else if (info->goober.gossipID)
1587 {
1588 player->PrepareGossipMenu(this, info->goober.gossipID);
1589 player->SendPreparedGossip(this);
1590 }
1591
1592 if (info->goober.eventId)
1593 {
1594 SF_LOG_DEBUG("maps.script", "Goober ScriptStart id %u for GO entry %u (GUID %u).", info->goober.eventId, GetEntry(), GetDBTableGUIDLow());
1595 GetMap()->ScriptsStart(sEventScripts, info->goober.eventId, player, this);
1596 EventInform(info->goober.eventId);
1597 }
1598
1599 // possible quest objective for active quests
1600 if (info->goober.questId && sObjectMgr->GetQuestTemplate(info->goober.questId))
1601 {
1602 //Quest require to be active for GO using
1604 break;
1605 }
1606
1607 if (Battleground* bg = player->GetBattleground())
1608 bg->EventPlayerUsedGO(player, this);
1609
1610 player->KillCreditGO(info->entry, GetGUID());
1611 }
1612
1613 if (uint32 trapEntry = info->goober.linkedTrapId)
1614 TriggeringLinkedGameObject(trapEntry, user);
1615
1618
1619 // this appear to be ok, however others exist in addition to this that should have custom (ex: 190510, 188692, 187389)
1620 if (info->goober.customAnim)
1622 else
1624
1625 m_cooldownTime = time(NULL) + info->GetAutoCloseTime();
1626
1627 // cast this spell later if provided
1628 spellId = info->goober.spellId;
1629 spellCaster = NULL;
1630
1631 break;
1632 }
1633 case GAMEOBJECT_TYPE_CAMERA: //13
1634 {
1635 GameObjectTemplate const* info = GetGOInfo();
1636 if (!info)
1637 return;
1638
1639 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1640 return;
1641
1642 Player* player = user->ToPlayer();
1643
1644 if (info->camera.cinematicId)
1645 player->SendCinematicStart(info->camera.cinematicId);
1646
1647 if (info->camera.eventID)
1648 GetMap()->ScriptsStart(sEventScripts, info->camera.eventID, player, this);
1649
1650 return;
1651 }
1652 //fishing bobber
1654 {
1655 Player* player = user->ToPlayer();
1656 if (!player)
1657 return;
1658
1659 if (player->GetGUID() != GetOwnerGUID())
1660 return;
1661
1662 switch (getLootState())
1663 {
1664 case LootState::GO_READY: // ready for loot
1665 {
1666 uint32 zone, subzone;
1667 GetZoneAndAreaId(zone, subzone);
1668
1669 int32 zone_skill = sObjectMgr->GetFishingBaseSkillLevel(subzone);
1670 if (!zone_skill)
1671 zone_skill = sObjectMgr->GetFishingBaseSkillLevel(zone);
1672
1673 //provide error, no fishable zone or area should be 0
1674 if (!zone_skill)
1675 SF_LOG_ERROR("sql.sql", "Fishable areaId %u are not properly defined in `skill_fishing_base_level`.", subzone);
1676
1677 int32 skill = player->GetSkillValue(SKILL_FISHING);
1678
1679 int32 chance;
1680 if (skill < zone_skill)
1681 {
1682 chance = int32(pow((double)skill / zone_skill, 2) * 100);
1683 if (chance < 1)
1684 chance = 1;
1685 }
1686 else
1687 chance = 100;
1688
1689 int32 roll = std::rand() % 100 + 1;
1690
1691 SF_LOG_DEBUG("misc", "Fishing check (skill: %i zone min skill: %i chance %i roll: %i", skill, zone_skill, chance, roll);
1692
1693 // but you will likely cause junk in areas that require a high fishing skill (not yet implemented)
1694 if (chance >= roll)
1695 {
1696 player->UpdateFishingSkill();
1697
1699 // prevent removing GO at spell cancel
1701 SetOwnerGUID(player->GetGUID());
1702
1705 if (ok)
1706 {
1707 ok->Use(player);
1709 }
1710 else
1712 }
1714 else
1715 m_respawnTime = time(NULL);
1716
1717 break;
1718 }
1719 case LootState::GO_JUST_DEACTIVATED: // nothing to do, will be deleted at next update
1720 break;
1721 default:
1722 {
1724
1726 player->SendDirectMessage(&data);
1727 break;
1728 }
1729 }
1730
1732 return;
1733 }
1734
1736 {
1737 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1738 return;
1739
1740 Player* player = user->ToPlayer();
1741
1742 Unit* owner = GetOwner();
1743
1744 GameObjectTemplate const* info = GetGOInfo();
1745
1746 // ritual owner is set for GO's without owner (not summoned)
1747 if (!m_ritualOwner && !owner)
1748 m_ritualOwner = player;
1749
1750 if (owner)
1751 {
1752 if (owner->GetTypeId() != TypeID::TYPEID_PLAYER)
1753 return;
1754
1755 // accept only use by player from same group as owner, excluding owner itself (unique use already added in spell effect)
1756 if (player == owner->ToPlayer() || (info->summoningRitual.castersGrouped && !player->IsInSameRaidWith(owner->ToPlayer())))
1757 return;
1758
1759 // expect owner to already be channeling, so if not...
1761 return;
1762
1763 // in case summoning ritual caster is GO creator
1764 spellCaster = owner;
1765 }
1766 else
1767 {
1768 if (player != m_ritualOwner && (info->summoningRitual.castersGrouped && !player->IsInSameRaidWith(m_ritualOwner)))
1769 return;
1770
1771 spellCaster = player;
1772 }
1773
1774 AddUniqueUse(player);
1775
1776 if (info->summoningRitual.animSpell)
1777 {
1778 player->CastSpell(player, info->summoningRitual.animSpell, true);
1779
1780 // for this case, summoningRitual.spellId is always triggered
1781 triggered = true;
1782 }
1783
1784 // full amount unique participants including original summoner
1786 {
1787 if (m_ritualOwner)
1788 spellCaster = m_ritualOwner;
1789
1790 spellId = info->summoningRitual.spellId;
1791
1792 if (spellId == 62330) // GO store nonexistent spell, replace by expected
1793 {
1794 // spell have reagent and mana cost but it not expected use its
1795 // it triggered spell in fact casted at currently channeled GO
1796 spellId = 61993;
1797 triggered = true;
1798 }
1799
1800 // Cast casterTargetSpell at a random GO user
1801 // on the current DB there is only one gameobject that uses this (Ritual of Doom)
1802 // and its required target number is 1 (outter for loop will run once)
1803 if (info->summoningRitual.casterTargetSpell && info->summoningRitual.casterTargetSpell != 1) // No idea why this field is a bool in some cases
1804 for (uint32 i = 0; i < info->summoningRitual.casterTargetSpellTargets; i++)
1805 // m_unique_users can contain only player GUIDs
1807 spellCaster->CastSpell(target, info->summoningRitual.casterTargetSpell, true);
1808
1809 // finish owners spell
1810 if (owner)
1812
1813 // can be deleted now, if
1816 else
1817 {
1818 // reset ritual for this GO
1819 m_ritualOwner = NULL;
1820 m_unique_users.clear();
1821 m_usetimes = 0;
1822 }
1823 }
1824 else
1825 return;
1826
1827 // go to end function to spell casting
1828 break;
1829 }
1831 {
1832 GameObjectTemplate const* info = GetGOInfo();
1833 if (!info)
1834 return;
1835
1836 if (info->spellcaster.partyOnly)
1837 {
1838 Unit* caster = GetOwner();
1839 if (!caster || caster->GetTypeId() != TypeID::TYPEID_PLAYER)
1840 return;
1841
1842 if (user->GetTypeId() != TypeID::TYPEID_PLAYER || !user->ToPlayer()->IsInSameRaidWith(caster->ToPlayer()))
1843 return;
1844 }
1845
1847 spellId = info->spellcaster.spellId;
1848
1849 AddUse();
1850 break;
1851 }
1853 {
1854 GameObjectTemplate const* info = GetGOInfo();
1855
1856 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1857 return;
1858
1859 Player* player = user->ToPlayer();
1860
1861 Player* targetPlayer = ObjectAccessor::FindPlayer(player->GetTarget());
1862
1863 // accept only use by player from same raid as caster, except caster itself
1864 if (!targetPlayer || targetPlayer == player || !targetPlayer->IsInSameRaidWith(player))
1865 return;
1866
1867 //required lvl checks!
1868 uint8 level = player->getLevel();
1869 if (level < info->meetingstone.minLevel)
1870 return;
1871 level = targetPlayer->getLevel();
1872 if (level < info->meetingstone.minLevel)
1873 return;
1874
1875 if (info->entry == 194097)
1876 spellId = 61994; // Ritual of Summoning
1877 else
1878 spellId = 59782; // Summoning Stone Effect
1879
1880 break;
1881 }
1882
1883 case GAMEOBJECT_TYPE_FLAGSTAND: // 24
1884 {
1885 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1886 return;
1887
1888 Player* player = user->ToPlayer();
1889
1890 if (player->CanUseBattlegroundObject(this))
1891 {
1892 // in battleground check
1893 Battleground* bg = player->GetBattleground();
1894 if (!bg)
1895 return;
1896
1897 if (player->GetVehicle())
1898 return;
1899
1902 // BG flag click
1903 // AB:
1904 // 15001
1905 // 15002
1906 // 15003
1907 // 15004
1908 // 15005
1909 bg->EventPlayerClickedOnFlag(player, this);
1910 return; //we don;t need to delete flag ... it is despawned!
1911 }
1912 break;
1913 }
1914
1915 case GAMEOBJECT_TYPE_FISHINGHOLE: // 25
1916 {
1917 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1918 return;
1919
1920 Player* player = user->ToPlayer();
1921
1924 return;
1925 }
1926
1927 case GAMEOBJECT_TYPE_FLAGDROP: // 26
1928 {
1929 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1930 return;
1931
1932 Player* player = user->ToPlayer();
1933
1934 if (player->CanUseBattlegroundObject(this))
1935 {
1936 // in battleground check
1937 Battleground* bg = player->GetBattleground();
1938 if (!bg)
1939 return;
1940
1941 if (player->GetVehicle())
1942 return;
1943
1946 // BG flag dropped
1947 // WS:
1948 // 179785 - Silverwing Flag
1949 // 179786 - Warsong Flag
1950 // EotS:
1951 // 184142 - Netherstorm Flag
1952 GameObjectTemplate const* info = GetGOInfo();
1953 if (info)
1954 {
1955 switch (info->entry)
1956 {
1957 case 179785: // Silverwing Flag
1958 case 179786: // Warsong Flag
1960 bg->EventPlayerClickedOnFlag(player, this);
1961 else
1963 bg->EventPlayerClickedOnFlag(player, this);
1964 break;
1965 case 184142: // Netherstorm Flag
1967 bg->EventPlayerClickedOnFlag(player, this);
1968 break;
1969 }
1970 }
1971 //this cause to call return, all flags must be deleted here!!
1972 spellId = 0;
1973 Delete();
1974 }
1975 break;
1976 }
1978 {
1979 GameObjectTemplate const* info = GetGOInfo();
1980 if (!info)
1981 return;
1982
1983 if (user->GetTypeId() != TypeID::TYPEID_PLAYER)
1984 return;
1985
1986 Player* player = user->ToPlayer();
1987
1988 // fallback, will always work
1990
1992 player->SendDirectMessage(&data);
1993
1995 return;
1996 }
1997 default:
1999 SF_LOG_ERROR("misc", "GameObject::Use(): unit (type: %u, guid: %u, name: %s) tries to use object (guid: %u, entry: %u, name: %s) of unknown type (%u)",
2000 uint8(user->GetTypeId()), user->GetGUIDLow(), user->GetName().c_str(), GetGUIDLow(), GetEntry(), GetGOInfo()->name.c_str(), GetGoType());
2001 break;
2002 }
2003
2004 if (!spellId)
2005 return;
2006
2007 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
2008 if (!spellInfo)
2009 {
2010 if (user->GetTypeId() != TypeID::TYPEID_PLAYER || !sOutdoorPvPMgr->HandleCustomSpell(user->ToPlayer(), spellId, this))
2011 SF_LOG_ERROR("misc", "WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u)", spellId, GetEntry(), GetGoType());
2012 else
2013 SF_LOG_DEBUG("outdoorpvp", "WORLD: %u non-dbc spell was handled by OutdoorPvP", spellId);
2014 return;
2015 }
2016
2017 if (spellCaster)
2018 spellCaster->CastSpell(user, spellInfo, triggered);
2019 else
2020 CastSpell(user, spellId);
2021}
2022
2023void GameObject::CastSpell(Unit* target, uint32 spellId)
2024{
2025 SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
2026 if (!spellInfo)
2027 return;
2028
2029 bool self = false;
2030 for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
2031 {
2032 if (spellInfo->Effects[i].TargetA.GetTarget() == TARGET_UNIT_CASTER)
2033 {
2034 self = true;
2035 break;
2036 }
2037 }
2038
2039 if (self)
2040 {
2041 if (target)
2042 target->CastSpell(target, spellInfo, true);
2043 return;
2044 }
2045
2046 //summon world trigger
2047 Creature* trigger = SummonTrigger(GetPositionX(), GetPositionY(), GetPositionZ(), 0, spellInfo->CalcCastTime() + 100);
2048 if (!trigger)
2049 return;
2050
2051 if (Unit* owner = GetOwner())
2052 {
2053 trigger->setFaction(owner->getFaction());
2054 // needed for GO casts for proper target validation checks
2055 trigger->SetOwnerGUID(owner->GetGUID());
2056 trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, owner->GetGUID());
2057 }
2058 else
2059 {
2060 trigger->setFaction(14);
2061 // Set owner guid for target if no owner available - needed by trigger auras
2062 // - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
2063 trigger->CastSpell(target ? target : trigger, spellInfo, true, 0, 0, target ? target->GetGUID() : 0);
2064 }
2065}
2066
2068{
2069 ObjectGuid Guid = GetGUID();
2071
2072 data.WriteBit(Guid[4]);
2073 data.WriteBit(Guid[7]);
2074 data.WriteBit(Guid[1]);
2075 data.WriteBit(Guid[0]);
2076 data.WriteBit(Guid[5]);
2077 data.WriteBit(Guid[3]);
2078 data.WriteBit(Guid[2]);
2079 data.WriteBit(0); //unk
2080 data.WriteBit(Guid[6]);
2081 data.FlushBits();
2082
2083 data << uint32(anim);
2084 data.WriteByteSeq(Guid[5]);
2085 data.WriteByteSeq(Guid[6]);
2086 data.WriteByteSeq(Guid[7]);
2087 data.WriteByteSeq(Guid[3]);
2088 data.WriteByteSeq(Guid[4]);
2089 data.WriteByteSeq(Guid[0]);
2090 data.WriteByteSeq(Guid[2]);
2091 data.WriteByteSeq(Guid[1]);
2092
2093 SendMessageToSet(&data, true);
2094}
2095
2096bool GameObject::IsInRange(float x, float y, float z, float radius) const
2097{
2098 GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(m_goInfo->displayId);
2099 if (!info)
2100 return IsWithinDist3d(x, y, z, radius);
2101
2102 float sinA = std::sin(GetOrientation());
2103 float cosA = std::cos(GetOrientation());
2104 float dx = x - GetPositionX();
2105 float dy = y - GetPositionY();
2106 float dz = z - GetPositionZ();
2107 float dist = sqrt(dx * dx + dy * dy);
2110 if (G3D::fuzzyEq(dist, 0.0f))
2111 return true;
2112
2113 float sinB = dx / dist;
2114 float cosB = dy / dist;
2115 dx = dist * (cosA * cosB + sinA * sinB);
2116 dy = dist * (cosA * sinB - sinA * cosB);
2117 return dx < info->maxX + radius && dx > info->minX - radius
2118 && dy < info->maxY + radius && dy > info->minY - radius
2119 && dz < info->maxZ + radius && dz > info->minZ - radius;
2120}
2121
2123{
2124 if (!eventId)
2125 return;
2126
2127 if (AI())
2128 AI()->EventInform(eventId);
2129
2130 if (m_zoneScript)
2131 m_zoneScript->ProcessEvent(this, eventId);
2132}
2133
2134// overwrite WorldObject function for proper name localization
2135std::string const& GameObject::GetNameForLocaleIdx(LocaleConstant loc_idx) const
2136{
2137 if (loc_idx != DEFAULT_LOCALE)
2138 {
2139 uint8 uloc_idx = uint8(loc_idx);
2140 if (GameObjectLocale const* cl = sObjectMgr->GetGameObjectLocale(GetEntry()))
2141 if (cl->Name.size() > uloc_idx && !cl->Name[uloc_idx].empty())
2142 return cl->Name[uloc_idx];
2143 }
2144
2145 return GetName();
2146}
2147
2149{
2150 static double const atan_pow = atan(pow(2.0f, -20.0f));
2151
2152 double f_rot1 = std::sin(GetOrientation() / 2.0f);
2153 double f_rot2 = std::cos(GetOrientation() / 2.0f);
2154
2155 int64 i_rot1 = int64(f_rot1 / atan_pow * (f_rot2 >= 0 ? 1.0f : -1.0f));
2156 int64 rotation = (i_rot1 << 43 >> 43) & 0x00000000001FFFFF;
2157
2158 //float f_rot2 = std::sin(0.0f / 2.0f);
2159 //int64 i_rot2 = f_rot2 / atan(pow(2.0f, -20.0f));
2160 //rotation |= (((i_rot2 << 22) >> 32) >> 11) & 0x000003FFFFE00000;
2161
2162 //float f_rot3 = std::sin(0.0f / 2.0f);
2163 //int64 i_rot3 = f_rot3 / atan(pow(2.0f, -21.0f));
2164 //rotation |= (i_rot3 >> 42) & 0x7FFFFC0000000000;
2165
2166 m_rotation = rotation;
2167}
2168
2169void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3 /*=0.0f*/)
2170{
2172
2173 if (rotation2 == 0.0f && rotation3 == 0.0f)
2174 {
2175 double f_rot1 = std::sin(GetOrientation() / 2.0f);
2176 double f_rot2 = std::cos(GetOrientation() / 2.0f);
2177
2178 rotation2 = (float)f_rot1;
2179 rotation3 = (float)f_rot2;
2180 }
2181
2184}
2185
2186void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= NULL*/, uint32 spellId /*= 0*/)
2187{
2188 if (!m_goValue.Building.MaxHealth || !change)
2189 return;
2190
2191 // prevent double destructions of the same object
2192 if (change < 0 && !m_goValue.Building.Health)
2193 return;
2194
2195 if (int32(m_goValue.Building.Health) + change <= 0)
2196 m_goValue.Building.Health = 0;
2197 else if (int32(m_goValue.Building.Health) + change >= int32(m_goValue.Building.MaxHealth))
2198 m_goValue.Building.Health = m_goValue.Building.MaxHealth;
2199 else
2200 m_goValue.Building.Health += change;
2201
2202 // Set the health bar, value = 255 * healthPct;
2203 SetGoAnimProgress(m_goValue.Building.Health * 255 / m_goValue.Building.MaxHealth);
2204
2205 Player* player = attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself();
2206
2207 // dealing damage, send packet
2208 if (player)
2209 {
2210 ObjectGuid playerGUID = player->GetGUID();
2211 ObjectGuid vehicleGUID = attackerOrHealer->GetGUID();
2212 ObjectGuid objectGUID = GetGUID();
2213
2214 WorldPacket data(SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, 8 + 8 + 8 + 4 + 4);
2215 data.WriteGuidMask(vehicleGUID, 2);
2216 data.WriteGuidMask(objectGUID, 2);
2217 data.WriteGuidMask(playerGUID, 7);
2218 data.WriteGuidMask(objectGUID, 4);
2219 data.WriteGuidMask(playerGUID, 3, 5);
2220 data.WriteGuidMask(objectGUID, 0);
2221 data.WriteGuidMask(playerGUID, 2, 6);
2222 data.WriteGuidMask(vehicleGUID, 4);
2223 data.WriteGuidMask(objectGUID, 5);
2224 data.WriteGuidMask(playerGUID, 0, 1);
2225 data.WriteGuidMask(objectGUID, 1);
2226 data.WriteGuidMask(vehicleGUID, 0, 3, 6);
2227 data.WriteGuidMask(objectGUID, 7);
2228 data.WriteGuidMask(vehicleGUID, 7, 5);
2229 data.WriteGuidMask(objectGUID, 6);
2230 data.WriteGuidMask(playerGUID, 4);
2231 data.WriteGuidMask(vehicleGUID, 1);
2232 data.WriteGuidMask(objectGUID, 3);
2233
2234 data.WriteGuidBytes(vehicleGUID, 2);
2235 data << uint32(spellId);
2236 data.WriteGuidBytes(playerGUID, 5, 6);
2237 data.WriteGuidBytes(objectGUID, 7);
2238 data.WriteGuidBytes(playerGUID, 1);
2239 data.WriteGuidBytes(objectGUID, 1);
2240 data.WriteGuidBytes(playerGUID, 2);
2241 data.WriteGuidBytes(vehicleGUID, 7, 5);
2242 data.WriteGuidBytes(objectGUID, 0, 2, 6);
2243 data.WriteGuidBytes(vehicleGUID, 1, 6);
2244 data << int32(-change); // change < 0 triggers SPELL_BUILDING_HEAL combat log event
2245 // change >= 0 triggers SPELL_BUILDING_DAMAGE event
2246 data.WriteGuidBytes(objectGUID, 5);
2247 data.WriteGuidBytes(playerGUID, 0);
2248 data.WriteGuidBytes(vehicleGUID, 0);
2249 data.WriteGuidBytes(playerGUID, 7, 4);
2250 data.WriteGuidBytes(objectGUID, 3);
2251 data.WriteGuidBytes(vehicleGUID, 3);
2252 data.WriteGuidBytes(objectGUID, 4);
2253 data.WriteGuidBytes(vehicleGUID, 4);
2254 data.WriteGuidBytes(playerGUID, 3);
2255
2256 player->SendDirectMessage(&data);
2257 }
2258
2260
2261 if (!m_goValue.Building.Health)
2262 newState = GO_DESTRUCTIBLE_DESTROYED;
2263 else if (m_goValue.Building.Health <= GetGOInfo()->building.damagedNumHits)
2264 newState = GO_DESTRUCTIBLE_DAMAGED;
2265 else if (m_goValue.Building.Health == m_goValue.Building.MaxHealth)
2266 newState = GO_DESTRUCTIBLE_INTACT;
2267
2268 if (newState == GetDestructibleState())
2269 return;
2270
2271 SetDestructibleState(newState, player, false);
2272}
2273
2274void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker /*= NULL*/, bool setHealth /*= false*/)
2275{
2276 // the user calling this must know he is already operating on destructible gameobject
2278
2279 switch (state)
2280 {
2283 SetDisplayId(m_goInfo->displayId);
2284 if (setHealth)
2285 {
2286 m_goValue.Building.Health = m_goValue.Building.MaxHealth;
2287 SetGoAnimProgress(255);
2288 }
2289 EnableCollision(true);
2290 break;
2292 {
2293 EventInform(m_goInfo->building.damagedEvent);
2294 sScriptMgr->OnGameObjectDamaged(this, eventInvoker);
2295 if (eventInvoker)
2296 if (Battleground* bg = eventInvoker->GetBattleground())
2297 bg->EventPlayerDamagedGO(eventInvoker, this, m_goInfo->building.damagedEvent);
2298
2301
2302 uint32 modelId = m_goInfo->building.damagedDisplayId;
2303 if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
2304 if (modelData->DamagedDisplayId)
2305 modelId = modelData->DamagedDisplayId;
2306 SetDisplayId(modelId);
2307
2308 if (setHealth)
2309 {
2310 m_goValue.Building.Health = m_goInfo->building.damagedNumHits;
2311 uint32 maxHealth = m_goValue.Building.MaxHealth;
2312 // in this case current health is 0 anyway so just prevent crashing here
2313 if (!maxHealth)
2314 maxHealth = 1;
2315 SetGoAnimProgress(m_goValue.Building.Health * 255 / maxHealth);
2316 }
2317 break;
2318 }
2320 {
2321 sScriptMgr->OnGameObjectDestroyed(this, eventInvoker);
2322 EventInform(m_goInfo->building.destroyedEvent);
2323 if (eventInvoker)
2324 {
2325 if (Battleground* bg = eventInvoker->GetBattleground())
2326 {
2327 bg->EventPlayerDamagedGO(eventInvoker, this, m_goInfo->building.destroyedEvent);
2328 bg->DestroyGate(eventInvoker, this);
2329 }
2330 }
2331
2334
2335 uint32 modelId = m_goInfo->building.destroyedDisplayId;
2336 if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
2337 if (modelData->DestroyedDisplayId)
2338 modelId = modelData->DestroyedDisplayId;
2339 SetDisplayId(modelId);
2340
2341 if (setHealth)
2342 {
2343 m_goValue.Building.Health = 0;
2345 }
2346 EnableCollision(false);
2347 break;
2348 }
2350 {
2351 EventInform(m_goInfo->building.rebuildingEvent);
2353
2354 uint32 modelId = m_goInfo->displayId;
2355 if (DestructibleModelDataEntry const* modelData = sDestructibleModelDataStore.LookupEntry(m_goInfo->building.destructibleData))
2356 if (modelData->RebuildingDisplayId)
2357 modelId = modelData->RebuildingDisplayId;
2358 SetDisplayId(modelId);
2359
2360 // restores to full health
2361 if (setHealth)
2362 {
2363 m_goValue.Building.Health = m_goValue.Building.MaxHealth;
2364 SetGoAnimProgress(255);
2365 }
2366 EnableCollision(true);
2367 break;
2368 }
2369 }
2370}
2371
2373{
2374 m_lootState = state;
2375 AI()->OnStateChanged(uint32(state), unit);
2376 sScriptMgr->OnGameObjectLootStateChanged(this, uint32(state), unit);
2377 if (m_model)
2378 {
2379 bool collision = false;
2380 // Use the current go state
2382 collision = !collision;
2383
2384 EnableCollision(collision);
2385 }
2386}
2387
2389{
2390 GOState const oldState = GetGoState();
2392 HandleLegacyTransportStateChange(oldState, state);
2393 sScriptMgr->OnGameObjectStateChanged(this, uint32(state));
2394 if (m_model && !IsTransport())
2395 {
2396 if (!IsInWorld())
2397 return;
2398
2399 // startOpen determines whether we are going to add or remove the LoS on activation
2400 bool collision = false;
2401 if (state == GOState::GO_STATE_READY)
2402 collision = !collision;
2403
2404 EnableCollision(collision);
2405 }
2406}
2407
2409{
2411 UpdateModel();
2412}
2413
2414void GameObject::SetPhaseMask(uint32 newPhaseMask, bool update)
2415{
2416 WorldObject::SetPhaseMask(newPhaseMask, update);
2417 if (m_model && m_model->isEnabled())
2418 EnableCollision(true);
2419}
2420bool GameObject::SetPhased(uint32 id, bool update, bool apply)
2421{
2422 bool res = WorldObject::SetPhased(id, update, apply);
2423 if (m_model && m_model->isEnabled())
2424 EnableCollision(true);
2425 return res;
2426}
2428{
2429 if (!m_model)
2430 return;
2431
2432 /*if (enable && !GetMap()->ContainsGameObjectModel(*m_model))
2433 GetMap()->InsertGameObjectModel(*m_model);*/
2434
2435 m_model->enable(enable ? GetPhaseMask() : 0);
2436}
2437
2439{
2440 if (!IsInWorld())
2441 return;
2442 if (m_model)
2443 if (GetMap()->ContainsGameObjectModel(*m_model))
2445 delete m_model;
2446 m_model = CreateModel();
2447 if (m_model)
2449}
2450
2452{
2453 if (!m_lootRecipient)
2454 return NULL;
2456}
2457
2459{
2461 return NULL;
2462 return sGroupMgr->GetGroupByGUID(m_lootRecipientGroup);
2463}
2464
2466{
2467 // set the player whose group should receive the right
2468 // to loot the creature after it dies
2469 // should be set to NULL after the loot disappears
2470
2471 if (!unit)
2472 {
2473 m_lootRecipient = 0;
2475 return;
2476 }
2477
2478 if (unit->GetTypeId() != TypeID::TYPEID_PLAYER && !unit->IsVehicle())
2479 return;
2480
2482 if (!player) // normal creature, no player involved
2483 return;
2484
2485 m_lootRecipient = player->GetGUID();
2486 if (Group* group = player->GetGroup())
2487 m_lootRecipientGroup = group->GetLowGUID();
2488}
2489
2490bool GameObject::IsLootAllowedFor(Player const* player) const
2491{
2493 return true;
2494
2495 if (player->GetGUID() == m_lootRecipient)
2496 return true;
2497
2498 Group const* playerGroup = player->GetGroup();
2499 if (!playerGroup || playerGroup != GetLootRecipientGroup()) // if we dont have a group we arent the recipient
2500 return false; // if go doesnt have group bound it means it was solo killed by someone else
2501
2502 return true;
2503}
2504
2505void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const
2506{
2507 if (!target)
2508 return;
2509
2511 bool targetIsGM = target->IsGameMaster();
2512
2513 ByteBuffer fieldBuffer;
2514
2515 UpdateMask updateMask;
2516 updateMask.SetCount(m_valuesCount);
2517
2520 if (GetOwnerGUID() == target->GetGUID())
2521 visibleFlag |= UF_FLAG_OWNER;
2522
2523 for (uint16 index = 0; index < m_valuesCount; ++index)
2524 {
2525 bool const forceTransportDynamicFlags =
2526 updateType != UPDATETYPE_VALUES &&
2527 index == OBJECT_FIELD_DYNAMIC_FLAGS &&
2528 IsTransport() &&
2529 GetTransportPeriod() != 0;
2530
2531 if ((m_fieldNotifyFlags & flags[index] ||
2532 ((updateType == UPDATETYPE_VALUES ? _changesMask.GetBit(index) : m_uint32Values[index]) && (flags[index] & visibleFlag)) ||
2533 forceTransportDynamicFlags ||
2534 (index == GAMEOBJECT_FIELD_FLAGS && forcedFlags)))
2535 {
2536 updateMask.SetBit(index);
2537
2538 if (index == OBJECT_FIELD_DYNAMIC_FLAGS)
2539 {
2540 uint16 dynFlags = 0;
2541 int16 pathProgress = -1;
2542 switch (GetGoType())
2543 {
2546 if (ActivateToQuest(target))
2548 else if (targetIsGM)
2549 dynFlags |= GO_DYNFLAG_LO_ACTIVATE;
2550 break;
2552 if (ActivateToQuest(target))
2553 dynFlags |= GO_DYNFLAG_LO_SPARKLE;
2554 break;
2557 {
2558 dynFlags = uint16(GetUInt32Value(OBJECT_FIELD_DYNAMIC_FLAGS) & 0xFFFF);
2559
2560 uint32 const transportPeriod = GetTransportPeriod();
2561 if (Skyfire::GameObjects::UsesControlledTransportProgress(GetGoType(), transportPeriod) && transportPeriod)
2562 {
2564 GetGoType(), transportPeriod, m_goValue.Transport.PathProgress);
2565 pathProgress = int16(float(transportProgress) / float(transportPeriod) * 65535.0f);
2566 }
2567 break;
2568 }
2569 default:
2570 break;
2571 }
2572
2573 fieldBuffer << uint16(dynFlags);
2574 fieldBuffer << int16(pathProgress);
2575 }
2576 else if (index == GAMEOBJECT_FIELD_FLAGS)
2577 {
2580 if (GetGOInfo()->chest.groupLootRules && !IsLootAllowedFor(target))
2582
2583 fieldBuffer << flags;
2584 }
2585 else
2586 fieldBuffer << m_uint32Values[index]; // other cases
2587 }
2588 }
2589
2590 *data << uint8(updateMask.GetBlockCount());
2591 updateMask.AppendToPacket(data);
2592 data->append(fieldBuffer);
2593 *data << uint8(0);
2594}
2595
2596void GameObject::GetRespawnPosition(float& x, float& y, float& z, float* ori /* = NULL*/) const
2597{
2598 if (m_DBTableGuid)
2599 {
2600 if (GameObjectData const* data = sObjectMgr->GetGOData(GetDBTableGUIDLow()))
2601 {
2602 x = data->posX;
2603 y = data->posY;
2604 z = data->posZ;
2605 if (ori)
2606 *ori = data->orientation;
2607 return;
2608 }
2609 }
2610
2611 x = GetPositionX();
2612 y = GetPositionY();
2613 z = GetPositionZ();
2614 if (ori)
2615 *ori = GetOrientation();
2616}
2617
2619{
2620 if (!m_model)
2621 return;
2622
2623 if (GetMap()->ContainsGameObjectModel(*m_model))
2624 {
2626 m_model->Relocate();
2628 }
2629}
2631{
2632 switch (state)
2633 {
2635 return 0;
2636 break;
2638 return 1;
2639 break;
2641 return 2;
2642 break;
2644 return 24;
2645 break;
2647 return 25;
2648 break;
2649 default:
2650 return 0;
2651 break;
2652 }
2653}
2654
2656{
2657public:
2658 explicit GameObjectModelOwnerImpl(GameObject const* owner) : _owner(owner) { }
2659
2660 bool isSpawned() const OVERRIDE { return _owner->isSpawned(); }
2661 uint32 GetDisplayId() const OVERRIDE { return _owner->GetDisplayId(); }
2662 uint32 GetPhaseMask() const OVERRIDE { return _owner->GetPhaseMask(); }
2663 G3D::Vector3 GetPosition() const OVERRIDE { return G3D::Vector3(_owner->GetPositionX(), _owner->GetPositionY(), _owner->GetPositionZ()); }
2664 float GetOrientation() const OVERRIDE { return _owner->GetOrientation(); }
2665 float GetScale() const OVERRIDE { return _owner->GetObjectScale(); }
2666 void DebugVisualizeCorner(G3D::Vector3 const& corner) const OVERRIDE { _owner->SummonCreature(1, corner.x, corner.y, corner.z, 0, TempSummonType::TEMPSUMMON_MANUAL_DESPAWN); }
2667
2668private:
2670};
2671
2673{
2674 return GameObjectModel::Create(std::make_unique<GameObjectModelOwnerImpl>(this), sWorld->GetDataPath());
2675}
LocaleConstant
Definition Common.h:138
#define DEFAULT_LOCALE
Definition Common.h:154
@ MINUTE
Definition Common.h:119
@ DAY
Definition Common.h:121
#define M_PI
Definition Common.h:192
@ ACHIEVEMENT_CRITERIA_TYPE_FISH_IN_GAMEOBJECT
Definition DBCEnums.h:234
DBCStorage< DestructibleModelDataEntry > sDestructibleModelDataStore(DestructibleModelDatafmt)
DBCStorage< GameObjectDisplayInfoEntry > sGameObjectDisplayInfoStore(GameObjectDisplayInfofmt)
std::set< uint32 > const & GetPhasesForGroup(uint32 group)
#define MAX_SPELL_EFFECTS
std::int32_t int32
Definition Define.h:73
std::uint8_t uint8
Definition Define.h:79
std::uint32_t uint32
Definition Define.h:77
#define OVERRIDE
Definition Define.h:60
std::uint64_t uint64
Definition Define.h:76
std::int64_t int64
Definition Define.h:72
std::uint16_t uint16
Definition Define.h:78
std::int16_t int16
Definition Define.h:74
#define ASSERT
Definition Errors.h:29
LootState
Definition GameObject.h:615
@ GO_JUST_DEACTIVATED
Definition GameObject.h:619
#define FISHING_BOBBER_READY_TIME
Definition GameObject.h:626
GOState
Definition GameObject.h:575
@ GO_STATE_TRANSPORT_ACTIVE
Definition GameObject.h:580
@ GO_STATE_ACTIVE
Definition GameObject.h:576
@ GO_STATE_READY
Definition GameObject.h:577
@ GO_STATE_TRANSPORT_STOPPED
Definition GameObject.h:581
@ GO_STATE_ACTIVE_ALTERNATIVE
Definition GameObject.h:578
TypeMapContainer< AllGridObjectTypes > GridTypeMapContainer
Definition GridDefines.h:71
CoordPair< TOTAL_NUMBER_OF_CELLS_PER_MAP > CellCoord
#define sGroupMgr
Definition GroupMgr.h:44
#define SF_LOG_DEBUG(filterType__,...)
Definition Log.h:134
#define SF_LOG_FATAL(filterType__,...)
Definition Log.h:146
#define SF_LOG_ERROR(filterType__,...)
Definition Log.h:143
LootStore LootTemplates_Gameobject("gameobject_loot_template", "gameobject entry", true)
LootStore LootTemplates_Fishing("fishing_loot_template", "area id", true)
@ LOOT_FISHINGHOLE
Definition LootMgr.h:76
@ LOOT_FISHING
Definition LootMgr.h:69
@ LOOT_CORPSE
Definition LootMgr.h:67
@ TYPEID_PLAYER
Definition Object.h:55
@ TYPEID_GAMEOBJECT
Definition Object.h:56
#define DEFAULT_VISIBILITY_DISTANCE
Definition Object.h:25
@ TEMPSUMMON_MANUAL_DESPAWN
Definition Object.h:75
#define CONTACT_DISTANCE
Definition Object.h:20
@ TYPEMASK_UNIT
Definition Object.h:40
@ TYPEMASK_GAMEOBJECT
Definition Object.h:42
#define sObjectAccessor
uint32 GUID_LOPART(uint64 x)
bool IS_PET_GUID(uint64 guid)
HighGuid
@ HIGHGUID_GAMEOBJECT
@ HIGHGUID_TRANSPORT
uint64 MAKE_NEW_GUID(uint32 l, uint32 e, uint32 h)
bool IS_PLAYER_GUID(uint64 guid)
ScriptMapMap sEventScripts
Definition ObjectMgr.cpp:51
std::pair< QuestRelations::const_iterator, QuestRelations::const_iterator > QuestRelationBounds
Definition ObjectMgr.h:457
#define sObjectMgr
Definition ObjectMgr.h:1617
#define sOutdoorPvPMgr
@ TELE_TO_NOT_LEAVE_COMBAT
Definition Player.h:831
@ TELE_TO_NOT_UNSUMMON_PET
Definition Player.h:832
@ TELE_TO_NOT_LEAVE_TRANSPORT
Definition Player.h:830
#define sPoolMgr
Definition PoolMgr.h:154
@ QUEST_STATUS_INCOMPLETE
Definition QuestDef.h:89
#define sScriptMgr
Definition ScriptMgr.h:764
GameobjectTypes
@ GAMEOBJECT_TYPE_CAMERA
@ GAMEOBJECT_TYPE_BUTTON
@ GAMEOBJECT_TYPE_MO_TRANSPORT
@ GAMEOBJECT_TYPE_TRANSPORT
@ GAMEOBJECT_TYPE_SUMMONING_RITUAL
@ GAMEOBJECT_TYPE_MEETINGSTONE
@ GAMEOBJECT_TYPE_TRAP
@ GAMEOBJECT_TYPE_GENERIC
@ GAMEOBJECT_TYPE_CHEST
@ GAMEOBJECT_TYPE_FISHINGHOLE
@ GAMEOBJECT_TYPE_FLAGDROP
@ GAMEOBJECT_TYPE_QUESTGIVER
@ GAMEOBJECT_TYPE_SPELLCASTER
@ GAMEOBJECT_TYPE_FLAGSTAND
@ GAMEOBJECT_TYPE_CHAIR
@ GAMEOBJECT_TYPE_GOOBER
@ GAMEOBJECT_TYPE_FISHINGNODE
@ GAMEOBJECT_TYPE_BARBER_CHAIR
@ GAMEOBJECT_TYPE_DOOR
@ GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
@ GO_DYNFLAG_LO_ACTIVATE
@ GO_DYNFLAG_LO_INVERTED_MOVEMENT
@ GO_DYNFLAG_LO_SPARKLE
@ STEALTH_TRAP
@ TARGET_UNIT_CASTER
@ INVISIBILITY_TRAP
#define MAX_GAMEOBJECT_TYPE
GameObjectDestructibleState
@ GO_DESTRUCTIBLE_DESTROYED
@ GO_DESTRUCTIBLE_REBUILDING
@ GO_DESTRUCTIBLE_INTACT
@ GO_DESTRUCTIBLE_DAMAGED
@ GO_FLAG_INTERACT_COND
@ GO_FLAG_NODESPAWN
@ GO_FLAG_NOT_SELECTABLE
@ GO_FLAG_IN_USE
@ GO_FLAG_DESTROYED
@ GO_FLAG_LOCKED
@ GO_FLAG_DAMAGED
@ SKILL_FISHING
@ SPELL_AURA_MOD_INVISIBILITY
@ SPELL_AURA_MOUNTED
@ SPELL_AURA_MOD_STEALTH
#define sSpellMgr
Definition SpellMgr.h:744
uint32 getMSTime()
Definition Timer.h:12
Skyfire::AutoPtr< Transaction, Skyfire::Mutex > SQLTransaction
Definition Transaction.h:42
#define sTransportMgr
@ UNIT_STAND_STATE_SIT_LOW_CHAIR
Definition Unit.h:166
@ UNIT_STAND_STATE_SIT
Definition Unit.h:163
@ CURRENT_CHANNELED_SPELL
Definition Unit.h:1110
@ UPDATETYPE_VALUES
Definition UpdateData.h:16
@ UPDATEFLAG_ROTATION
Definition UpdateData.h:34
@ UPDATEFLAG_TRANSPORT
Definition UpdateData.h:26
@ UPDATEFLAG_STATIONARY_POSITION
Definition UpdateData.h:31
uint32 GameObjectUpdateFieldFlags[GAMEOBJECT_END]
@ UF_FLAG_VIEWER_DEPENDENT
@ UF_FLAG_PUBLIC
@ UF_FLAG_OWNER
@ OBJECT_FIELD_DYNAMIC_FLAGS
@ GAMEOBJECT_FIELD_LEVEL
@ GAMEOBJECT_FIELD_PARENT_ROTATION
@ GAMEOBJECT_FIELD_PERCENT_HEALTH
@ GAMEOBJECT_FIELD_FACTION_TEMPLATE
@ GAMEOBJECT_FIELD_DISPLAY_ID
@ GAMEOBJECT_END
@ GAMEOBJECT_FIELD_STATE_SPELL_VISUAL_ID
@ GAMEOBJECT_FIELD_FLAGS
@ WORLD_DEL_EVENT_GAMEOBJECT
@ WORLD_DEL_GAMEOBJECT
@ WORLD_INS_GAMEOBJECT
BattlegroundTypeId GetTypeID(bool GetRandom=false) const
virtual void EventPlayerClickedOnFlag(Player *, GameObject *)
void WriteGuidBytes(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:264
bool WriteBit(uint32 bit)
Definition ByteBuffer.h:164
void WriteGuidMask(const ObjectGuid &guid, Offsets... offsets)
Definition ByteBuffer.h:248
void append(T value)
Definition ByteBuffer.h:147
void WriteByteSeq(uint8 b)
Definition ByteBuffer.h:227
void FlushBits()
Definition ByteBuffer.h:154
virtual void UpdateAI(uint32)
virtual void OnStateChanged(uint32, Unit *)
virtual void EventInform(uint32)
std::vector< uint32 > m_transportPauseTimes
Definition GameObject.h:874
void SetGoState(GOState state)
Unit * GetOwner() const
Player * m_ritualOwner
Definition GameObject.h:863
void UpdateLegacyTransportPathProgress()
GameObjectValue m_goValue
Definition GameObject.h:873
std::string const & GetNameForLocaleIdx(LocaleConstant locale_idx) const OVERRIDE
GameObjectTemplate const * GetGOInfo() const
Definition GameObject.h:643
uint32 GetDBTableGUIDLow() const
Definition GameObject.h:651
GOState GetGoState() const
Definition GameObject.h:717
time_t m_respawnTime
Definition GameObject.h:855
void DeleteFromDB()
time_t m_cooldownTime
Definition GameObject.h:859
void AddUse()
Definition GameObject.h:765
void RemoveFromWorld() OVERRIDE
void SetGoArtKit(uint8 artkit)
GameObjectData const * m_goData
Definition GameObject.h:872
LootState getLootState() const
Definition GameObject.h:742
uint32 GetSpellId() const
Definition GameObject.h:687
bool IsAlwaysVisibleFor(WorldObject const *seer) const OVERRIDE
void SetOwnerGUID(uint64 owner)
Definition GameObject.h:665
uint8 GetGoAnimProgress() const
Definition GameObject.h:732
uint64 GetOwnerGUID() const
Definition GameObject.h:679
Position m_stationaryPosition
Definition GameObject.h:877
bool IsInvisibleDueToDespawn() const OVERRIDE
void UseDoorOrButton(uint32 time_to_restore=0, bool alternative=false, Unit *user=NULL)
void Delete()
bool hasInvolvedQuest(uint32 quest_id) const OVERRIDE
void UpdateWorldRotationField()
Group * GetLootRecipientGroup() const
uint32 GetUniqueUseCount() const
Definition GameObject.h:768
void UpdateRotationFields(float rotation2=0.0f, float rotation3=0.0f)
void EnableCollision(bool enable)
uint8 GetGoArtKit() const
Definition GameObject.h:730
void SetGoAnimProgress(uint8 animprogress)
Definition GameObject.h:733
uint32 m_DBTableGuid
For new or temporary gameobjects is 0 for saved it is lowguid.
Definition GameObject.h:870
bool isSpawned() const
Definition GameObject.h:705
void InitializeLegacyTransport()
ChairSlotAndUser ChairListSlots
Definition GameObject.h:868
uint32 GetTransportPeriod() const
void MarkLegacyTransportPathProgressChanged()
GameObjectData const * GetGOData() const
Definition GameObject.h:644
Player * GetLootRecipient() const
GameObjectModel * CreateModel()
uint32 m_spellId
Definition GameObject.h:854
bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit=0)
bool HasLootRecipient() const
Definition GameObject.h:778
void CleanupsBeforeDelete(bool finalCleanup=true) OVERRIDE
uint32 m_respawnDelayTime
Definition GameObject.h:856
GameObjectAI * AI() const
Definition GameObject.h:824
void ResetLootMode()
Definition GameObject.h:751
void SetLegacyTransportTravelTime(uint32 travelTime)
void SetLegacyTransportStopped(bool stopped)
bool IsInRange(float x, float y, float z, float radius) const
static GameObject * GetGameObject(WorldObject &object, uint64 guid)
void SetRespawnTime(int32 respawn)
Definition GameObject.h:699
void TriggeringLinkedGameObject(uint32 trapEntry, Unit *target)
GameobjectTypes GetGoType() const
Definition GameObject.h:719
uint64 m_rotation
Definition GameObject.h:876
void SetGoType(GameobjectTypes type)
Definition GameObject.h:720
void StartLegacyTransportToFirstStop(uint32 travelTime)
bool LoadGameObjectFromDB(uint32 guid, Map *map, bool addToMap=true)
bool ActivateToQuest(Player *target) const
void SetTransportPathProgress(uint32 pathProgress)
void AddToWorld() OVERRIDE
void StopLegacyTransportAtInitialStop()
void SetPhaseMask(uint32 newPhaseMask, bool update) OVERRIDE
bool AIM_Initialize()
void RemoveFromOwner()
void HandleLegacyTransportStateChange(GOState oldState, GOState newState)
void SaveRespawnTime() OVERRIDE
void SendCustomAnim(uint32 anim)
void Refresh()
void SetLootRecipient(Unit *unit)
GameObjectAI * m_AI
Definition GameObject.h:892
GameObjectModel * m_model
Definition GameObject.h:830
void ResetDoorOrButton()
void EventInform(uint32 eventId)
void UpdateModelPosition()
bool SetPhased(uint32 id, bool update, bool apply) OVERRIDE
void Update(uint32 p_time) OVERRIDE
GameObject * LookupFishingHoleAround(float range)
void BuildValuesUpdate(uint8 updatetype, ByteBuffer *data, Player *target) const OVERRIDE
void SetDisplayId(uint32 displayid)
GameObjectTemplate const * m_goInfo
Definition GameObject.h:871
uint32 GetGOStateValue(GOState state)
std::string GetAIName() const
void SetLootState(LootState s, Unit *unit=NULL)
uint32 m_groupLootTimer
Definition GameObject.h:779
void StopLegacyTransportAtCurrentProgress()
void SetDestructibleState(GameObjectDestructibleState state, Player *eventInvoker=NULL, bool setHealth=false)
void UpdateModel()
void Use(Unit *user)
bool IsDynTransport() const
void SwitchDoorOrButton(bool activate, bool alternative=false)
uint32 m_lootRecipientGroup
Definition GameObject.h:880
bool IsDestructibleBuilding() const
std::list< uint32 > m_SkillupList
Definition GameObject.h:861
void CastSpell(Unit *target, uint32 spell)
void SaveToDB()
void ModifyHealth(int32 change, Unit *attackerOrHealer=NULL, uint32 spellId=0)
std::set< uint64 > m_unique_users
Definition GameObject.h:864
void getFishLoot(Loot *loot, Player *loot_owner)
Transport * ToTransport()
Definition GameObject.h:833
uint64 m_lootRecipient
Definition GameObject.h:879
uint32 lootingGroupLowGUID
Definition GameObject.h:780
bool m_spawnedByDefault
Definition GameObject.h:858
void SetGoHealth(uint8 health)
Definition GameObject.h:729
void GetRespawnPosition(float &x, float &y, float &z, float *ori=NULL) const
uint32 GetLegacyTransportTargetProgress(GOState state) const
GameObjectDestructibleState GetDestructibleState() const
Definition GameObject.h:811
bool IsLootAllowedFor(Player const *player) const
LootState m_lootState
Definition GameObject.h:857
void AddUniqueUse(Player *player)
bool hasQuest(uint32 quest_id) const OVERRIDE
uint32 m_usetimes
Definition GameObject.h:865
std::vector< uint32 > const * GetPauseTimes() const
bool IsTransport() const
static GameObjectModel * Create(std::unique_ptr< GameObjectModelOwnerBase > modelOwner, std::string const &dataPath)
bool isSpawned() const OVERRIDE
uint32 GetDisplayId() const OVERRIDE
G3D::Vector3 GetPosition() const OVERRIDE
float GetScale() const OVERRIDE
float GetOrientation() const OVERRIDE
void DebugVisualizeCorner(G3D::Vector3 const &corner) const OVERRIDE
GameObject const * _owner
uint32 GetPhaseMask() const OVERRIDE
GameObjectModelOwnerImpl(GameObject const *owner)
Definition Group.h:147
void EndRoll(Loot *loot)
Definition Group.cpp:1378
void ScriptsStart(std::map< uint32, std::multimap< uint32, ScriptInfo > > const &scripts, uint32 id, Object *source, Object *target)
Put scripts in the execution queue.
void RemoveGameObjectModel(const GameObjectModel &model)
Definition Map.h:446
time_t GetGORespawnTime(uint32 dbGuid) const
Definition Map.h:465
bool AddToMap(T *)
Definition Map.cpp:504
void SaveGORespawnTime(uint32 dbGuid, time_t respawnTime)
Definition Map.cpp:3242
bool Is25ManRaid() const
Definition Map.cpp:3063
void RemoveGORespawnTime(uint32 dbGuid)
Definition Map.cpp:3261
GameObject * GetGameObject(uint64 guid)
Definition Map.cpp:3184
uint32 GetInstanceId() const
Definition Map.h:357
uint32 GetId(void) const
Definition Map.h:300
time_t GetLinkedRespawnTime(uint64 guid) const
Definition Map.cpp:3326
void InsertGameObjectModel(const GameObjectModel &model)
Definition Map.h:447
MapObject()
Definition Object.h:593
friend class Map
Definition Object.h:589
static Player * GetPlayer(WorldObject const &, uint64 guid)
static Unit * GetUnit(WorldObject const &, uint64 guid)
static Player * FindPlayer(uint64)
void UpdateUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1071
void SetByteValue(uint16 index, uint8 offset, uint8 value)
Definition Object.cpp:1158
uint16 m_objectType
Definition Object.h:242
ObjectGuid GetObjectGUID() const
Definition Object.h:123
uint64 GetGUID() const
Definition Object.h:119
uint32 GetUInt32Value(uint16 index) const
Definition Object.cpp:325
Player * ToPlayer()
Definition Object.h:204
bool IsInWorld() const
Definition Object.h:114
uint32 GetGUIDLow() const
Definition Object.h:120
UpdateMask _changesMask
Definition Object.h:254
TypeID GetTypeId() const
Definition Object.h:131
uint32 * m_uint32Values
Definition Object.h:250
void _Create(uint32 guidlow, uint32 entry, HighGuid guidhigh)
Definition Object.cpp:129
bool isType(uint16 mask) const
Definition Object.h:132
uint16 m_valuesCount
Definition Object.h:256
void SetFlag(uint16 index, uint32 newFlag)
Definition Object.cpp:1261
void RemoveFlag(uint16 index, uint32 oldFlag)
Definition Object.cpp:1280
float GetFloatValue(uint16 index) const
Definition Object.cpp:337
uint16 m_fieldNotifyFlags
Definition Object.h:258
uint32 GetEntry() const
Definition Object.h:125
void BuildValuesUpdateBlockForPlayer(UpdateData *data, Player *target) const
Definition Object.cpp:270
void SetFloatValue(uint16 index, float value)
Definition Object.cpp:1141
virtual void AddToWorld()
Definition Object.cpp:148
bool HasFlag(uint16 index, uint32 flag) const
Definition Object.cpp:1309
void SetEntry(uint32 entry)
Definition Object.h:126
virtual void SetObjectScale(float scale)
Definition Object.h:129
void SetUInt32Value(uint16 index, uint32 value)
Definition Object.cpp:1038
uint16 m_updateFlag
Definition Object.h:245
TypeID m_objectTypeId
Definition Object.h:244
bool m_objectUpdated
Definition Object.h:260
uint32 GetTeam() const
Definition Player.h:2527
void SendCinematicStart(uint32 CinematicSequenceId)
Definition Player.cpp:6960
bool CanUseBattlegroundObject(GameObject *gameobject)
Definition Player.cpp:20321
bool IsInSameRaidWith(Player const *p) const
Definition Player.cpp:3030
bool UpdateFishingSkill()
Definition Player.cpp:6221
uint16 GetSkillValue(uint32 skill) const
Definition Player.cpp:6563
void SendDirectMessage(WorldPacket *data)
Definition Player.cpp:6904
bool InBattleground() const
Definition Player.h:2692
void SendPreparedGossip(WorldObject *source)
Definition Player.cpp:11815
void KillCreditGO(uint32 entry, uint64 guid=0)
WorldSession * GetSession() const
Definition Player.h:2417
bool HasQuestForGO(int32 goId) const
Definition Player.cpp:19375
Battleground * GetBattleground() const
Definition Player.cpp:19212
Group * GetGroup()
Definition Player.h:2972
bool IsGameMaster() const
Definition Player.h:1369
void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint64 miscValue1=0, uint64 miscValue2=0, uint64 miscValue3=0, Unit *unit=NULL)
Definition Player.cpp:21033
bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options=0)
Definition Player.cpp:2090
QuestStatus GetQuestStatus(uint32 quest_id) const
void PrepareGossipMenu(WorldObject *source, uint32 menuId=0, bool showQuests=false)
Definition Player.cpp:11668
void SendLoot(uint64 guid, LootType loot_type, bool isAoE=false)
Definition Player.cpp:9346
void setFloat(const uint8 index, const float value)
void setUInt16(const uint8 index, const uint16 value)
void setUInt32(const uint8 index, const uint32 value)
void setUInt8(const uint8 index, const uint8 value)
void setInt32(const uint8 index, const int32 value)
SpellImplicitTargetInfo TargetA
Definition SpellInfo.h:102
SpellEffectInfo Effects[MAX_SPELL_EFFECTS]
Definition SpellInfo.h:255
uint32 CalcCastTime(uint8 level=0, Spell *spell=NULL) const
void RemovePassenger(WorldObject *passenger)
Definition Unit.h:1367
bool IsVehicle() const
Definition Unit.h:1523
Vehicle * GetVehicle() const
Definition Unit.h:2743
void RemoveGameObject(GameObject *gameObj, bool del)
Definition Unit.cpp:1689
void setFaction(uint32 faction)
Definition Unit.h:1699
void CastSpell(SpellCastTargets const &targets, SpellInfo const *spellInfo, CustomSpellValues const *value, TriggerCastFlags triggerFlags=TRIGGERED_NONE, Item *castItem=NULL, AuraEffect const *triggeredByAura=NULL, uint64 originalCaster=0)
Player * GetCharmerOrOwnerPlayerOrPlayerItself() const
Definition Unit.cpp:2355
uint64 GetTarget() const
Definition Unit.h:2830
float GetSpellMaxRangeForTarget(Unit const *target, SpellInfo const *spellInfo) const
Definition Unit.cpp:4877
void SetOwnerGUID(uint64 owner)
Definition Unit.cpp:2314
void RemoveAurasByType(AuraType auraType, uint64 casterGUID=0, Aura *except=NULL, bool negative=true, bool positive=true)
void FinishSpell(CurrentSpellTypes spellType, bool ok=true)
Definition Unit.cpp:1390
bool IsFriendlyTo(Unit const *unit) const
Definition Unit.cpp:2283
uint8 getLevel() const
Definition Unit.h:1528
void SetStandState(uint8 state)
Definition Unit.cpp:5902
Spell * GetCurrentSpell(CurrentSpellTypes spellType) const
Definition Unit.h:2363
bool BuildPacket(WorldPacket *packet)
uint32 GetBlockCount() const
Definition UpdateMask.h:51
void SetCount(uint32 valuesCount)
Definition UpdateMask.h:54
void SetBit(uint32 index)
Definition UpdateMask.h:34
void AppendToPacket(ByteBuffer *data)
Definition UpdateMask.h:38
uint32 GetMapId() const
Definition Object.h:546
virtual void SetPhaseMask(uint32 newPhaseMask, bool update)
Definition Object.cpp:3219
uint32 GetPhaseMask() const
Definition Object.h:643
bool IsWithinDist3d(float x, float y, float z, float dist) const
Definition Object.cpp:1710
Map * GetMap() const
Definition Object.h:740
virtual void RemoveFromWorld()
Definition Object.cpp:1587
Creature * SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI *(*GetAI)(Creature *)=NULL)
Definition Object.cpp:2762
virtual bool IsInvisibleDueToDespawn() const
Definition Object.h:831
FlaggedValuesArray32< int32, uint32, InvisibilityType, TOTAL_INVISIBILITY_TYPES > m_invisibility
Definition Object.h:729
void SendObjectDeSpawnAnim(uint64 guid)
Definition Object.cpp:2503
void SetTransport(Transport *t)
Definition Object.h:805
virtual bool SetPhased(uint32 id, bool update, bool apply)
Definition Object.cpp:3353
uint32 LastUsedScriptID
Definition Object.h:794
void SetName(std::string const &newname)
Definition Object.h:665
void SetZoneScript()
Definition Object.cpp:2687
float GetDistance2d(WorldObject const *obj) const
Definition Object.cpp:1684
ZoneScript * m_zoneScript
Definition Object.h:818
std::string const & GetName() const
Definition Object.h:664
virtual void SetMap(Map *map)
Definition Object.cpp:2514
virtual bool IsAlwaysVisibleFor(WorldObject const *) const
Definition Object.h:830
void AddObjectToRemoveList()
Definition Object.cpp:2550
void VisitNearbyGridObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:783
WorldObject(bool isWorldObject)
Definition Object.cpp:1514
Transport * GetTransport() const
Definition Object.h:797
void VisitNearbyWorldObject(float const &radius, NOTIFIER &notifier) const
Definition Object.h:784
FlaggedValuesArray32< int32, uint32, StealthType, TOTAL_STEALTH_TYPES > m_stealth
Definition Object.h:726
MovementInfo m_movementInfo
Definition Object.h:807
virtual void SendMessageToSet(WorldPacket *data, bool self)
Definition Object.cpp:2485
void GetZoneAndAreaId(uint32 &zoneid, uint32 &areaid) const
Definition Object.cpp:1607
virtual void UpdateObjectVisibility(bool forced=true)
Definition Object.cpp:3480
void SendPageText(ObjectGuid GameObjectGUID)
WorldDatabaseWorkerPool WorldDatabase
Accessor to the world database.
Definition Main.cpp:40
@ SMSG_GAMEOBJECT_CUSTOM_ANIM
Definition Opcodes.h:659
@ SMSG_FISH_ESCAPED
Definition Opcodes.h:656
@ SMSG_ENABLE_BARBER_SHOP
Definition Opcodes.h:648
@ SMSG_DESTRUCTIBLE_BUILDING_DAMAGE
Definition Opcodes.h:636
@ SMSG_FISH_NOT_HOOKED
Definition Opcodes.h:657
#define sWorld
Definition World.h:910
@ CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY
Definition World.h:111
GameObjectAI * SelectGameObjectAI(GameObject *go)
C::value_type const & SelectRandomContainerElement(C const &container)
Definition Containers.h:48
uint32 GetLegacyTransportTransitionTime(uint32 sourceProgress, uint32 targetProgress)
uint32 GetTransportDynamicPathProgress(uint32 gameObjectType, uint32 transportPeriod, uint32 pathProgress)
uint32 InterpolateLegacyTransportPathProgress(uint32 sourceProgress, uint32 targetProgress, uint32 transportPeriod, uint32 elapsedTime, uint32 travelTime, bool invertedMovement=false)
uint32 ClampLegacyTransportPathProgress(uint32 pathProgress, uint32 transportPeriod)
uint32 GetInitialLegacyTransportPathProgress(bool hasStopFrames, uint32 transportPeriod, uint32 now)
uint32 SetLegacyTransportStoppedFlag(uint32 dynamicFlags, bool stopped)
uint32 GetInitialLegacyTransportState(bool, bool hasStopFrames)
bool UsesControlledTransportProgress(uint32 gameObjectType, uint32 transportPeriod)
uint32 WrapTransportPathProgress(uint32 pathProgress, uint32 transportPeriod)
CellCoord ComputeCellCoord(float x, float y)
Definition Cell.h:37
void Visit(CellCoord const &, TypeContainerVisitor< T, CONTAINER > &visitor, Map &, WorldObject const &, float) const
Definition CellImpl.h:109
uint32 phaseGroup
Definition GameObject.h:593
int32 spawntimesecs
Definition GameObject.h:602
uint32 animprogress
Definition GameObject.h:603
GOState go_state
Definition GameObject.h:604
float maxX
float maxY
float minY
float minX
float minZ
float maxZ
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@114312050106372302366137106154036240136321221160 barberChair
uint32 GetAutoCloseTime() const
Definition GameObject.h:470
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@152130076372303155010023156377005036224346144151 camera
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@154136051106040324176270267211357174344063050360 chest
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@133216107201365043142154201341232071301300107152 transport
uint32 GetCharges() const
Definition GameObject.h:448
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@334327144355150311317234223372371064337023010042 trap
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@105243172300324111262263021120111346345123061033 summoningRitual
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@316034272062200025205312222263007157266267301257 chair
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@243266127071011160240350104214013054067132104252 fishinghole
std::string name
Definition GameObject.h:28
uint32 casterTargetSpellTargets
Definition GameObject.h:233
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@315077355127077256043020131262337362171234125061 spellcaster
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@240010171105306235035040051230330371375266145364 building
struct GameObjectTemplate::@046065176235271051340241126110345143267101032070::@336060043160212225074214221232260020127013174055 goober
void clear()
Definition LootMgr.h:308
bool FillLoot(uint32 lootId, LootStore const &store, Player *lootOwner, bool personal, bool noEmptyError=false, uint16 lootMode=LOOT_MODE_DEFAULT)
Definition LootMgr.cpp:418
float GetPositionZ() const
Definition Object.h:330
float GetOrientation() const
Definition Object.h:331
bool IsPositionValid() const
Definition Object.cpp:2049
float GetPositionX() const
Definition Object.h:328
float GetPositionY() const
Definition Object.h:329
void Relocate(float x, float y)
Definition Object.h:302