2 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #ifndef MANGOSSERVER_GAMEOBJECT_H
20 #define MANGOSSERVER_GAMEOBJECT_H
23 #include "SharedDefines.h"
26 #include "Database/DatabaseEnv.h"
28 // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform
29 #if defined( __GNUC__ )
35 // from `gameobject_template`
46 union // different GO types have different data field
48 //0 GAMEOBJECT_TYPE_DOOR
51 uint32 startOpen
; //0 used client side to determine GO_ACTIVATED means open/closed
52 uint32 lockId
; //1 -> Lock.dbc
53 uint32 autoCloseTime
; //2 secs till autoclose = autoCloseTime / 0x10000
54 uint32 noDamageImmune
; //3 break opening whenever you recieve damage?
55 uint32 openTextID
; //4 can be used to replace castBarCaption?
56 uint32 closeTextID
; //5
58 //1 GAMEOBJECT_TYPE_BUTTON
62 uint32 lockId
; //1 -> Lock.dbc
63 uint32 autoCloseTime
; //2 secs till autoclose = autoCloseTime / 0x10000
64 uint32 linkedTrap
; //3
65 uint32 noDamageImmune
; //4 isBattlegroundObject
67 uint32 openTextID
; //6 can be used to replace castBarCaption?
68 uint32 closeTextID
; //7
71 //2 GAMEOBJECT_TYPE_QUESTGIVER
74 uint32 lockId
; //0 -> Lock.dbc
76 uint32 pageMaterial
; //2
78 uint32 customAnim
; //4
79 uint32 noDamageImmune
; //5
80 uint32 openTextID
; //6 can be used to replace castBarCaption?
82 uint32 allowMounted
; //8
85 //3 GAMEOBJECT_TYPE_CHEST
88 uint32 lockId
; //0 -> Lock.dbc
90 uint32 chestRestockTime
; //2
91 uint32 consumable
; //3
92 uint32 minSuccessOpens
; //4
93 uint32 maxSuccessOpens
; //5
94 uint32 eventId
; //6 lootedEvent
95 uint32 linkedTrapId
; //7
96 uint32 questId
; //8 not used currently but store quest required for GO activation for player
99 uint32 leaveLoot
; //11
100 uint32 notInCombat
; //12
102 uint32 openTextID
; //14 can be used to replace castBarCaption?
103 uint32 groupLootRules
; //15
105 //5 GAMEOBJECT_TYPE_GENERIC
108 uint32 floatingTooltip
; //0
109 uint32 highlight
; //1
110 uint32 serverOnly
; //2
112 uint32 floatOnWater
; //4
115 //6 GAMEOBJECT_TYPE_TRAP
118 uint32 lockId
; //0 -> Lock.dbc
120 uint32 radius
; //2 radius for trap activation
122 uint32 charges
; //4 need respawn (if > 0)
123 uint32 cooldown
; //5 time in secs
124 uint32 autoCloseTime
; //6
125 uint32 startDelay
; //7
126 uint32 serverOnly
; //8
127 uint32 stealthed
; //9
129 uint32 stealthAffected
; //11
130 uint32 openTextID
; //12 can be used to replace castBarCaption?
131 uint32 closeTextID
; //13
133 //7 GAMEOBJECT_TYPE_CHAIR
138 uint32 onlyCreatorUse
; //2
140 //8 GAMEOBJECT_TYPE_SPELL_FOCUS
145 uint32 linkedTrapId
; //2
146 uint32 serverOnly
; //3
150 //9 GAMEOBJECT_TYPE_TEXT
155 uint32 pageMaterial
; //2
156 uint32 allowMounted
; //3
158 //10 GAMEOBJECT_TYPE_GOOBER
161 uint32 lockId
; //0 -> Lock.dbc
164 uint32 autoCloseTime
; //3
165 uint32 customAnim
; //4
166 uint32 consumable
; //5
170 uint32 pageMaterial
; //9
172 uint32 noDamageImmune
; //11
173 uint32 linkedTrapId
; //12
175 uint32 openTextID
; //14 can be used to replace castBarCaption?
176 uint32 closeTextID
; //15
177 uint32 losOK
; //16 isBattlegroundObject
178 uint32 allowMounted
; //17
180 //11 GAMEOBJECT_TYPE_TRANSPORT
184 uint32 startOpen
; //1
185 uint32 autoCloseTime
; //2 secs till autoclose = autoCloseTime / 0x10000
187 //12 GAMEOBJECT_TYPE_AREADAMAGE
192 uint32 damageMin
; //2
193 uint32 damageMax
; //3
194 uint32 damageSchool
; //4
195 uint32 autoCloseTime
; //5 secs till autoclose = autoCloseTime / 0x10000
196 uint32 openTextID
; //6
197 uint32 closeTextID
; //7
199 //13 GAMEOBJECT_TYPE_CAMERA
202 uint32 lockId
; //0 -> Lock.dbc
203 uint32 cinematicId
; //1
205 uint32 openTextID
; //3 can be used to replace castBarCaption?
207 //15 GAMEOBJECT_TYPE_MO_TRANSPORT
210 uint32 taxiPathId
; //0
211 uint32 moveSpeed
; //1
212 uint32 accelRate
; //2
213 uint32 startEventID
; //3
214 uint32 stopEventID
; //4
215 uint32 transportPhysics
; //5
218 //17 GAMEOBJECT_TYPE_FISHINGNODE
224 //18 GAMEOBJECT_TYPE_SUMMONING_RITUAL
227 uint32 reqParticipants
; //0
229 uint32 animSpell
; //2
230 uint32 ritualPersistent
; //3
231 uint32 casterTargetSpell
; //4
232 uint32 casterTargetSpellTargets
; //5
233 uint32 castersGrouped
; //6
234 uint32 ritualNoTargetCheck
; //7
236 //20 GAMEOBJECT_TYPE_AUCTIONHOUSE
239 uint32 actionHouseID
; //0
241 //21 GAMEOBJECT_TYPE_GUARDPOST
244 uint32 creatureID
; //0
247 //22 GAMEOBJECT_TYPE_SPELLCASTER
252 uint32 partyOnly
; //2
254 //23 GAMEOBJECT_TYPE_MEETINGSTONE
261 //24 GAMEOBJECT_TYPE_FLAGSTAND
265 uint32 pickupSpell
; //1
267 uint32 returnAura
; //3
268 uint32 returnSpell
; //4
269 uint32 noDamageImmune
; //5
270 uint32 openTextID
; //6
273 //25 GAMEOBJECT_TYPE_FISHINGHOLE // not implemented yet
276 uint32 radius
; //0 how close bobber must land for sending loot
278 uint32 minSuccessOpens
; //2
279 uint32 maxSuccessOpens
; //3
280 uint32 lockId
; //4 -> Lock.dbc; possibly 1628 for all?
282 //26 GAMEOBJECT_TYPE_FLAGDROP
287 uint32 pickupSpell
; //2
288 uint32 noDamageImmune
; //3
289 uint32 openTextID
; //4
291 //27 GAMEOBJECT_TYPE_MINI_GAME
296 //29 GAMEOBJECT_TYPE_CAPTURE_POINT
301 uint32 worldState1
; //2
302 uint32 worldstate2
; //3
303 uint32 winEventID1
; //4
304 uint32 winEventID2
; //5
305 uint32 contestedEventID1
; //6
306 uint32 contestedEventID2
; //7
307 uint32 progressEventID1
; //8
308 uint32 progressEventID2
; //9
309 uint32 neutralEventID1
; //10
310 uint32 neutralEventID2
; //11
311 uint32 neutralPercent
; //12
312 uint32 worldstate3
; //13
313 uint32 minSuperiority
; //14
314 uint32 maxSuperiority
; //15
318 uint32 highlight
; //19
320 //30 GAMEOBJECT_TYPE_AURA_GENERATOR
323 uint32 startOpen
; //0
326 uint32 conditionID1
; //3
328 uint32 conditionID2
; //5
329 uint32 serverOnly
; //6
331 //31 GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY
335 uint32 difficulty
; //1
337 //32 GAMEOBJECT_TYPE_BARBER_CHAIR
340 uint32 chairheight
; //0
341 uint32 heightOffset
; //1
343 //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
346 uint32 dmgPctState1
; //0
347 uint32 dmgPctState2
; //1
348 uint32 state1Name
; //2
349 uint32 state2Name
; //3
350 } destructibleBuilding
;
351 //34 GAMEOBJECT_TYPE_TRAPDOOR
354 uint32 whenToPause
; // 0
355 uint32 startOpen
; // 1
356 uint32 autoClose
; // 2
359 // not use for specific field access (only for output with loop by all filed), also this determinate max union size
360 struct // GAMEOBJECT_TYPE_SPELLCASTER
368 struct GameObjectLocale
370 std::vector
<std::string
> Name
;
371 std::vector
<std::string
> CastBarCaption
;
375 struct GameObjectData
377 uint32 id
; // entry in gamobject_template
393 // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
394 #if defined( __GNUC__ )
400 // For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ...
401 // For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted>
402 // For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ...
403 // For door(open): [GO_NOT_READY]->GO_READY (open) ->GO_ACTIVATED (close)->GO_JUST_DEACTIVATED->GO_READY(open) -> ...
407 GO_READY
, // can be ready but despawned, and then not possible activate until spawn
414 // 5 sec for bobber catch
415 #define FISHING_BOBBER_READY_TIME 5
417 class MANGOS_DLL_SPEC GameObject
: public WorldObject
420 explicit GameObject();
424 void RemoveFromWorld();
426 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
, uint32 go_state
);
427 void Update(uint32 p_time
);
428 static GameObject
* GetGameObject(WorldObject
& object
, uint64 guid
);
429 GameObjectInfo
const* GetGOInfo() const;
431 bool IsTransport() const;
433 void SetOwnerGUID(uint64 owner
)
435 m_spawnedByDefault
= false; // all object with owner is despawned after delay
436 SetUInt64Value(OBJECT_FIELD_CREATED_BY
, owner
);
438 uint64
GetOwnerGUID() const { return GetUInt64Value(OBJECT_FIELD_CREATED_BY
); }
439 Unit
* GetOwner() const;
441 uint32
GetDBTableGUIDLow() const { return m_DBTableGuid
; }
443 void Say(const char* text
, uint32 language
, uint64 TargetGuid
) { MonsterSay(text
,language
,TargetGuid
); }
444 void Yell(const char* text
, uint32 language
, uint64 TargetGuid
) { MonsterYell(text
,language
,TargetGuid
); }
445 void TextEmote(const char* text
, uint64 TargetGuid
) { MonsterTextEmote(text
,TargetGuid
); }
446 void Whisper(const char* text
,uint64 receiver
) { MonsterWhisper(text
,receiver
); }
447 void Say(int32 textId
, uint32 language
, uint64 TargetGuid
) { MonsterSay(textId
,language
,TargetGuid
); }
448 void Yell(int32 textId
, uint32 language
, uint64 TargetGuid
) { MonsterYell(textId
,language
,TargetGuid
); }
449 void TextEmote(int32 textId
, uint64 TargetGuid
) { MonsterTextEmote(textId
,TargetGuid
); }
450 void Whisper(int32 textId
, uint64 receiver
) { MonsterWhisper(textId
,receiver
); }
452 // overwrite WorldObject function for proper name localization
453 const char* GetNameForLocaleIdx(int32 locale_idx
) const;
456 void SaveToDB(uint32 mapid
, uint8 spawnMask
);
457 bool LoadFromDB(uint32 guid
, Map
*map
);
459 void SetLootState(LootState s
) { m_lootState
= s
; }
460 static uint32
GetLootId(GameObjectInfo
const* info
);
461 uint32
GetLootId() const { return GetLootId(GetGOInfo()); }
462 uint32
GetLockId() const
466 case GAMEOBJECT_TYPE_DOOR
: return GetGOInfo()->door
.lockId
;
467 case GAMEOBJECT_TYPE_BUTTON
: return GetGOInfo()->button
.lockId
;
468 case GAMEOBJECT_TYPE_QUESTGIVER
: return GetGOInfo()->questgiver
.lockId
;
469 case GAMEOBJECT_TYPE_CHEST
: return GetGOInfo()->chest
.lockId
;
470 case GAMEOBJECT_TYPE_TRAP
: return GetGOInfo()->trap
.lockId
;
471 case GAMEOBJECT_TYPE_GOOBER
: return GetGOInfo()->goober
.lockId
;
472 case GAMEOBJECT_TYPE_AREADAMAGE
: return GetGOInfo()->areadamage
.lockId
;
473 case GAMEOBJECT_TYPE_CAMERA
: return GetGOInfo()->camera
.lockId
;
474 case GAMEOBJECT_TYPE_FLAGSTAND
: return GetGOInfo()->flagstand
.lockId
;
475 case GAMEOBJECT_TYPE_FISHINGHOLE
:return GetGOInfo()->fishinghole
.lockId
;
476 case GAMEOBJECT_TYPE_FLAGDROP
: return GetGOInfo()->flagdrop
.lockId
;
481 time_t GetRespawnTime() const { return m_respawnTime
; }
482 time_t GetRespawnTimeEx() const
484 time_t now
= time(NULL
);
485 if(m_respawnTime
> now
)
486 return m_respawnTime
;
491 void SetRespawnTime(int32 respawn
)
493 m_respawnTime
= respawn
> 0 ? time(NULL
) + respawn
: 0;
494 m_respawnDelayTime
= respawn
> 0 ? respawn
: 0;
497 bool isSpawned() const
499 return m_respawnDelayTime
== 0 ||
500 (m_respawnTime
> 0 && !m_spawnedByDefault
) ||
501 (m_respawnTime
== 0 && m_spawnedByDefault
);
503 bool isSpawnedByDefault() const { return m_spawnedByDefault
; }
504 uint32
GetRespawnDelay() const { return m_respawnDelayTime
; }
507 void SetSpellId(uint32 id
) { m_spellId
= id
;}
508 uint32
GetSpellId() const { return m_spellId
;}
509 void getFishLoot(Loot
*loot
);
510 GameobjectTypes
GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1
, 1)); }
511 void SetGoType(GameobjectTypes type
) { SetByteValue(GAMEOBJECT_BYTES_1
, 1, type
); }
512 uint8
GetGoState() const { return GetByteValue(GAMEOBJECT_BYTES_1
, 0); }
513 void SetGoState(uint8 state
) { SetByteValue(GAMEOBJECT_BYTES_1
, 0, state
); }
514 uint8
GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1
, 2); }
515 void SetGoArtKit(uint8 artkit
) { SetByteValue(GAMEOBJECT_BYTES_1
, 2, artkit
); }
516 uint8
GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1
, 3); }
517 void SetGoAnimProgress(uint8 animprogress
) { SetByteValue(GAMEOBJECT_BYTES_1
, 3, animprogress
); }
519 void Use(Unit
* user
);
521 LootState
getLootState() const { return m_lootState
; }
523 void AddToSkillupList(uint32 PlayerGuidLow
) { m_SkillupList
.push_back(PlayerGuidLow
); }
524 bool IsInSkillupList(uint32 PlayerGuidLow
) const
526 for (std::list
<uint32
>::const_iterator i
= m_SkillupList
.begin(); i
!= m_SkillupList
.end(); ++i
)
527 if (*i
== PlayerGuidLow
) return true;
530 void ClearSkillupList() { m_SkillupList
.clear(); }
532 void AddUniqueUse(Player
* player
);
533 void AddUse() { ++m_usetimes
; }
535 uint32
GetUseCount() const { return m_usetimes
; }
536 uint32
GetUniqueUseCount() const { return m_unique_users
.size(); }
538 void SaveRespawnTime();
542 bool hasQuest(uint32 quest_id
) const;
543 bool hasInvolvedQuest(uint32 quest_id
) const;
544 bool ActivateToQuest(Player
*pTarget
) const;
545 void UseDoorOrButton(uint32 time_to_restore
= 0); // 0 = use `gameobject`.`spawntimesecs`
547 uint32
GetLinkedGameObjectEntry() const
551 case GAMEOBJECT_TYPE_CHEST
: return GetGOInfo()->chest
.linkedTrapId
;
552 case GAMEOBJECT_TYPE_SPELL_FOCUS
: return GetGOInfo()->spellFocus
.linkedTrapId
;
553 case GAMEOBJECT_TYPE_GOOBER
: return GetGOInfo()->goober
.linkedTrapId
;
558 uint32
GetAutoCloseTime() const
560 uint32 autoCloseTime
= 0;
563 case GAMEOBJECT_TYPE_DOOR
: autoCloseTime
= GetGOInfo()->door
.autoCloseTime
; break;
564 case GAMEOBJECT_TYPE_BUTTON
: autoCloseTime
= GetGOInfo()->button
.autoCloseTime
; break;
565 case GAMEOBJECT_TYPE_TRAP
: autoCloseTime
= GetGOInfo()->trap
.autoCloseTime
; break;
566 case GAMEOBJECT_TYPE_GOOBER
: autoCloseTime
= GetGOInfo()->goober
.autoCloseTime
; break;
567 case GAMEOBJECT_TYPE_TRANSPORT
: autoCloseTime
= GetGOInfo()->transport
.autoCloseTime
; break;
568 case GAMEOBJECT_TYPE_AREADAMAGE
: autoCloseTime
= GetGOInfo()->areadamage
.autoCloseTime
; break;
571 return autoCloseTime
/ 0x10000;
574 void TriggeringLinkedGameObject( uint32 trapEntry
, Unit
* target
);
576 bool isVisibleForInState(Player
const* u
, bool inVisibleList
) const;
578 GameObject
* LookupFishingHoleAround(float range
);
580 GridReference
<GameObject
> &GetGridRef() { return m_gridRef
; }
582 uint32 m_charges
; // Spell charges for GAMEOBJECT_TYPE_SPELLCASTER (22)
584 time_t m_respawnTime
; // (secs) time of next respawn (or despawn if GO have owner()),
585 uint32 m_respawnDelayTime
; // (secs) if 0 then current GO state no dependent from timer
586 LootState m_lootState
;
587 bool m_spawnedByDefault
;
588 time_t m_cooldownTime
; // used as internal reaction delay time store (not state change reaction).
589 // For traps this: spell casting cooldown, for doors/buttons: reset time.
590 std::list
<uint32
> m_SkillupList
;
592 std::set
<uint32
> m_unique_users
;
595 uint32 m_DBTableGuid
; ///< For new or temporary gameobjects is 0 for saved it is lowguid
596 GameObjectInfo
const* m_goInfo
;
598 void SwitchDoorOrButton(bool activate
);
600 GridReference
<GameObject
> m_gridRef
;