-
Notifications
You must be signed in to change notification settings - Fork 89
/
GameObject.h
839 lines (766 loc) · 37.7 KB
/
GameObject.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
/*
* This file is part of the CMaNGOS Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MANGOSSERVER_GAMEOBJECT_H
#define MANGOSSERVER_GAMEOBJECT_H
#include "Common.h"
#include "SharedDefines.h"
#include "Object.h"
#include "LootMgr.h"
#include "Database/DatabaseEnv.h"
// 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
#if defined( __GNUC__ )
#pragma pack(1)
#else
#pragma pack(push,1)
#endif
// from `gameobject_template`
struct GameObjectInfo
{
uint32 id;
uint32 type;
uint32 displayId;
char* name;
char* IconName;
char* castBarCaption;
char* unk1;
uint32 faction;
uint32 flags;
float size;
uint32 questItems[6];
union // different GO types have different data field
{
//0 GAMEOBJECT_TYPE_DOOR
struct
{
uint32 startOpen; //0 used client side to determine GO_ACTIVATED means open/closed
uint32 lockId; //1 -> Lock.dbc
uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / IN_MILLISECONDS (previous was 0x10000)
uint32 noDamageImmune; //3 break opening whenever you recieve damage?
uint32 openTextID; //4 can be used to replace castBarCaption?
uint32 closeTextID; //5
uint32 ignoredByPathing; //6
} door;
//1 GAMEOBJECT_TYPE_BUTTON
struct
{
uint32 startOpen; //0
uint32 lockId; //1 -> Lock.dbc
uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / IN_MILLISECONDS (previous was 0x10000)
uint32 linkedTrapId; //3
uint32 noDamageImmune; //4 isBattlegroundObject
uint32 large; //5
uint32 openTextID; //6 can be used to replace castBarCaption?
uint32 closeTextID; //7
uint32 losOK; //8
} button;
//2 GAMEOBJECT_TYPE_QUESTGIVER
struct
{
uint32 lockId; //0 -> Lock.dbc
uint32 questList; //1
uint32 pageMaterial; //2
uint32 gossipID; //3
uint32 customAnim; //4
uint32 noDamageImmune; //5
uint32 openTextID; //6 can be used to replace castBarCaption?
uint32 losOK; //7
uint32 allowMounted; //8
uint32 large; //9
} questgiver;
//3 GAMEOBJECT_TYPE_CHEST
struct
{
uint32 lockId; //0 -> Lock.dbc
uint32 lootId; //1
uint32 chestRestockTime; //2
uint32 consumable; //3
uint32 minSuccessOpens; //4
uint32 maxSuccessOpens; //5
uint32 eventId; //6 lootedEvent
uint32 linkedTrapId; //7
uint32 questId; //8 not used currently but store quest required for GO activation for player
uint32 level; //9
uint32 losOK; //10
uint32 leaveLoot; //11
uint32 notInCombat; //12
uint32 logLoot; //13
uint32 openTextID; //14 can be used to replace castBarCaption?
uint32 groupLootRules; //15
uint32 floatingTooltip; //16
} chest;
//4 GAMEOBJECT_TYPE_BINDER - empty
//5 GAMEOBJECT_TYPE_GENERIC
struct
{
uint32 floatingTooltip; //0
uint32 highlight; //1
uint32 serverOnly; //2
uint32 large; //3
uint32 floatOnWater; //4
uint32 questID; //5
} _generic;
//6 GAMEOBJECT_TYPE_TRAP
struct
{
uint32 lockId; //0 -> Lock.dbc
uint32 level; //1
uint32 radius; //2 radius for trap activation
uint32 spellId; //3
uint32 charges; //4 need respawn (if > 0)
uint32 cooldown; //5 time in secs
uint32 autoCloseTime; //6 secs till autoclose = autoCloseTime / IN_MILLISECONDS (previous was 0x10000)
uint32 startDelay; //7
uint32 serverOnly; //8
uint32 stealthed; //9
uint32 large; //10
uint32 stealthAffected; //11
uint32 openTextID; //12 can be used to replace castBarCaption?
uint32 closeTextID; //13
uint32 ignoreTotems; //14
} trap;
//7 GAMEOBJECT_TYPE_CHAIR
struct
{
uint32 slots; //0
uint32 height; //1
uint32 onlyCreatorUse; //2
uint32 triggeredEvent; //3
} chair;
//8 GAMEOBJECT_TYPE_SPELL_FOCUS
struct
{
uint32 focusId; //0
uint32 dist; //1
uint32 linkedTrapId; //2
uint32 serverOnly; //3
uint32 questID; //4
uint32 large; //5
uint32 floatingTooltip; //6
} spellFocus;
//9 GAMEOBJECT_TYPE_TEXT
struct
{
uint32 pageID; //0
uint32 language; //1
uint32 pageMaterial; //2
uint32 allowMounted; //3
} text;
//10 GAMEOBJECT_TYPE_GOOBER
struct
{
uint32 lockId; //0 -> Lock.dbc
uint32 questId; //1
uint32 eventId; //2
uint32 autoCloseTime; //3 secs till autoclose = autoCloseTime / IN_MILLISECONDS (previous was 0x10000)
uint32 customAnim; //4
uint32 consumable; //5
uint32 cooldown; //6
uint32 pageId; //7
uint32 language; //8
uint32 pageMaterial; //9
uint32 spellId; //10
uint32 noDamageImmune; //11
uint32 linkedTrapId; //12
uint32 large; //13
uint32 openTextID; //14 can be used to replace castBarCaption?
uint32 closeTextID; //15
uint32 losOK; //16 isBattlegroundObject
uint32 allowMounted; //17
uint32 floatingTooltip; //18
uint32 gossipID; //19
uint32 WorldStateSetsState; //20
} goober;
//11 GAMEOBJECT_TYPE_TRANSPORT
struct
{
uint32 startFrame; //0
uint32 startOpen; //1
uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / IN_MILLISECONDS (previous was 0x10000)
uint32 pause1EventID; //3
uint32 pause2EventID; //4
uint32 baseMap; //5
uint32 nextFrame1; //6
uint32 unk7; //7
uint32 nextFrame2; //8
uint32 unk9; //9
uint32 nextFrame3; //10
uint32 unk11; //11
uint32 unk12; //12
uint32 unk13; //13
uint32 unk14; //14
uint32 unk15; //15
uint32 unk16; //16
uint32 unk17; //17
uint32 unk18; //18
uint32 unk19; //19
uint32 unk20; //20
uint32 unk21; //21
uint32 unk22; //22 ring of valor elevators
uint32 unk23; //23 ring of valor elevators
} transport;
//12 GAMEOBJECT_TYPE_AREADAMAGE
struct
{
uint32 lockId; //0
uint32 radius; //1
uint32 damageMin; //2
uint32 damageMax; //3
uint32 damageSchool; //4
uint32 autoCloseTime; //5 secs till autoclose = autoCloseTime / IN_MILLISECONDS (previous was 0x10000)
uint32 openTextID; //6
uint32 closeTextID; //7
} areadamage;
//13 GAMEOBJECT_TYPE_CAMERA
struct
{
uint32 lockId; //0 -> Lock.dbc
uint32 cinematicId; //1
uint32 eventID; //2
uint32 openTextID; //3 can be used to replace castBarCaption?
} camera;
//14 GAMEOBJECT_TYPE_MAPOBJECT - empty
//15 GAMEOBJECT_TYPE_MO_TRANSPORT
struct
{
uint32 taxiPathId; //0
uint32 moveSpeed; //1
uint32 accelRate; //2
uint32 startEventID; //3
uint32 stopEventID; //4
uint32 transportPhysics; //5
uint32 mapID; //6
uint32 worldState1; //7
} moTransport;
//16 GAMEOBJECT_TYPE_DUELFLAG - empty
//17 GAMEOBJECT_TYPE_FISHINGNODE - empty
//18 GAMEOBJECT_TYPE_SUMMONING_RITUAL
struct
{
uint32 reqParticipants; //0
uint32 spellId; //1
uint32 animSpell; //2
uint32 ritualPersistent; //3
uint32 casterTargetSpell; //4
uint32 casterTargetSpellTargets; //5
uint32 castersGrouped; //6
uint32 ritualNoTargetCheck; //7
} summoningRitual;
//19 GAMEOBJECT_TYPE_MAILBOX - empty
//20 GAMEOBJECT_TYPE_DONOTUSE - empty
//21 GAMEOBJECT_TYPE_GUARDPOST
struct
{
uint32 creatureID; //0
uint32 charges; //1
} guardpost;
//22 GAMEOBJECT_TYPE_SPELLCASTER
struct
{
uint32 spellId; //0
uint32 charges; //1
uint32 partyOnly; //2
uint32 allowMounted; //3
uint32 large; //4
} spellcaster;
//23 GAMEOBJECT_TYPE_MEETINGSTONE
struct
{
uint32 minLevel; //0
uint32 maxLevel; //1
uint32 areaID; //2
} meetingstone;
//24 GAMEOBJECT_TYPE_FLAGSTAND
struct
{
uint32 lockId; //0
uint32 pickupSpell; //1
uint32 radius; //2
uint32 returnAura; //3
uint32 returnSpell; //4
uint32 noDamageImmune; //5
uint32 openTextID; //6
uint32 losOK; //7
} flagstand;
//25 GAMEOBJECT_TYPE_FISHINGHOLE
struct
{
uint32 radius; //0 how close bobber must land for sending loot
uint32 lootId; //1
uint32 minSuccessOpens; //2
uint32 maxSuccessOpens; //3
uint32 lockId; //4 -> Lock.dbc; possibly 1628 for all?
} fishinghole;
//26 GAMEOBJECT_TYPE_FLAGDROP
struct
{
uint32 lockId; //0
uint32 eventID; //1
uint32 pickupSpell; //2
uint32 noDamageImmune; //3
uint32 openTextID; //4
} flagdrop;
//27 GAMEOBJECT_TYPE_MINI_GAME
struct
{
uint32 gameType; //0
} miniGame;
//29 GAMEOBJECT_TYPE_CAPTURE_POINT
struct
{
uint32 radius; //0
uint32 spell; //1
uint32 worldState1; //2
uint32 worldState2; //3
uint32 winEventID1; //4
uint32 winEventID2; //5
uint32 contestedEventID1; //6
uint32 contestedEventID2; //7
uint32 progressEventID1; //8
uint32 progressEventID2; //9
uint32 neutralEventID1; //10
uint32 neutralEventID2; //11
uint32 neutralPercent; //12
uint32 worldState3; //13
uint32 minSuperiority; //14
uint32 maxSuperiority; //15
uint32 minTime; //16
uint32 maxTime; //17
uint32 large; //18
uint32 highlight; //19
uint32 startingValue; //20
uint32 unidirectional; //21
} capturePoint;
//30 GAMEOBJECT_TYPE_AURA_GENERATOR
struct
{
uint32 startOpen; //0
uint32 radius; //1
uint32 auraID1; //2
uint32 conditionID1; //3
uint32 auraID2; //4
uint32 conditionID2; //5
uint32 serverOnly; //6
} auraGenerator;
//31 GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY
struct
{
uint32 mapID; //0
uint32 difficulty; //1
} dungeonDifficulty;
//32 GAMEOBJECT_TYPE_BARBER_CHAIR
struct
{
uint32 chairheight; //0
uint32 heightOffset; //1
} barberChair;
//33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING // Much guesswork
struct
{
uint32 intactNumHits; //0
uint32 creditProxyCreature; //1
uint32 empty1; //2
uint32 intactEvent; //3
uint32 damagedDisplayId; //4
uint32 damagedNumHits; //5
uint32 unk1; //6
uint32 unk2; //7
uint32 unk3; //8
uint32 damagedEvent; //9
uint32 destroyedDisplayId; //10
uint32 unk4; //11
uint32 unk5; //12
uint32 unk6; //13
uint32 destroyedEvent; //14
uint32 empty10; //15
uint32 debuildingTimeSecs; //16 // unk, only few with value 300)
uint32 empty11; //17
uint32 destructibleData; //18 m_ID of DestructibleModelData.DBC
uint32 empty12; //19
uint32 unk7; //20
uint32 empty13; //21
uint32 rebuildingEvent; //22
uint32 unk8; //23
} destructibleBuilding;
//34 GAMEOBJECT_TYPE_GUILDBANK - empty
//35 GAMEOBJECT_TYPE_TRAPDOOR
struct
{
uint32 whenToPause; // 0
uint32 startOpen; // 1
uint32 autoClose; // 2
} trapDoor;
// not use for specific field access (only for output with loop by all filed), also this determinate max union size
struct
{
uint32 data[32];
} raw;
};
uint32 unk2;
uint32 MinMoneyLoot;
uint32 MaxMoneyLoot;
uint32 ScriptId;
// helpers
bool IsDespawnAtAction() const
{
switch (type)
{
case GAMEOBJECT_TYPE_CHEST: return chest.consumable;
case GAMEOBJECT_TYPE_GOOBER: return goober.consumable;
default: return false;
}
}
uint32 GetLockId() const
{
switch (type)
{
case GAMEOBJECT_TYPE_DOOR: return door.lockId;
case GAMEOBJECT_TYPE_BUTTON: return button.lockId;
case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.lockId;
case GAMEOBJECT_TYPE_CHEST: return chest.lockId;
case GAMEOBJECT_TYPE_TRAP: return trap.lockId;
case GAMEOBJECT_TYPE_GOOBER: return goober.lockId;
case GAMEOBJECT_TYPE_AREADAMAGE: return areadamage.lockId;
case GAMEOBJECT_TYPE_CAMERA: return camera.lockId;
case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.lockId;
case GAMEOBJECT_TYPE_FISHINGHOLE: return fishinghole.lockId;
case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.lockId;
default: return 0;
}
}
bool GetDespawnPossibility() const // despawn at targeting of cast?
{
switch (type)
{
case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune;
case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune;
case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune;
case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune;
case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune;
case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune;
default: return true;
}
}
uint32 GetCharges() const // despawn at uses amount
{
switch (type)
{
case GAMEOBJECT_TYPE_TRAP: return trap.charges;
case GAMEOBJECT_TYPE_GUARDPOST: return guardpost.charges;
case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.charges;
default: return 0;
}
}
uint32 GetCooldown() const // not triggering at detection target or use until coolodwn expire
{
switch (type)
{
case GAMEOBJECT_TYPE_TRAP: return trap.cooldown;
case GAMEOBJECT_TYPE_GOOBER: return goober.cooldown;
default: return 0;
}
}
uint32 GetLinkedGameObjectEntry() const
{
switch (type)
{
case GAMEOBJECT_TYPE_BUTTON: return button.linkedTrapId;
case GAMEOBJECT_TYPE_CHEST: return chest.linkedTrapId;
case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.linkedTrapId;
case GAMEOBJECT_TYPE_GOOBER: return goober.linkedTrapId;
default: return 0;
}
}
uint32 GetAutoCloseTime() const
{
uint32 autoCloseTime = 0;
switch (type)
{
case GAMEOBJECT_TYPE_DOOR: autoCloseTime = door.autoCloseTime; break;
case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = button.autoCloseTime; break;
case GAMEOBJECT_TYPE_TRAP: autoCloseTime = trap.autoCloseTime; break;
case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = goober.autoCloseTime; break;
case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = transport.autoCloseTime; break;
case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = areadamage.autoCloseTime; break;
default: break;
}
return autoCloseTime / IN_MILLISECONDS; // prior to 3.0.3, conversion was / 0x10000;
}
uint32 GetLootId() const
{
switch (type)
{
case GAMEOBJECT_TYPE_CHEST: return chest.lootId;
case GAMEOBJECT_TYPE_FISHINGHOLE: return fishinghole.lootId;
default: return 0;
}
}
uint32 GetGossipMenuId() const
{
switch (type)
{
case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.gossipID;
case GAMEOBJECT_TYPE_GOOBER: return goober.gossipID;
default: return 0;
}
}
};
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
#else
#pragma pack(pop)
#endif
struct GameObjectLocale
{
std::vector<std::string> Name;
std::vector<std::string> CastBarCaption;
};
// client side GO show states
enum GOState
{
GO_STATE_ACTIVE = 0x00, // show in world as used and not reset (closed door open)
GO_STATE_READY = 0x01, // show in world as ready (closed door close)
GO_STATE_ACTIVE_ALTERNATIVE = 0x02, // show in world as used in alt way and not reset (closed door open by cannon fire)
GO_STATE_TRANSPORT_SPEC = 0x18, // additional mask that have all transport gameobjects
};
#define MAX_GO_STATE 3
struct QuaternionData
{
float x, y, z, w;
QuaternionData() : x(0.f), y(0.f), z(0.f), w(0.f) {}
QuaternionData(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) {}
bool isUnit() const { return fabs(x * x + y * y + z * z + w * w - 1.f) < 1e-5;}
};
// from `gameobject`
struct GameObjectData
{
uint32 id; // entry in gamobject_template
uint16 mapid;
uint32 phaseMask;
float posX;
float posY;
float posZ;
float orientation;
QuaternionData rotation;
int32 spawntimesecs;
uint32 animprogress;
GOState go_state;
uint8 spawnMask;
};
// from `gameobject_addon`
struct GameObjectDataAddon
{
uint32 guid;
QuaternionData path_rotation;
};
// For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ...
// For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted>
// For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ...
// For door(open): [GO_NOT_READY]->GO_READY (open) ->GO_ACTIVATED (close)->GO_JUST_DEACTIVATED->GO_READY(open) -> ...
enum LootState
{
GO_NOT_READY = 0,
GO_READY, // can be ready but despawned, and then not possible activate until spawn
GO_ACTIVATED,
GO_JUST_DEACTIVATED
};
enum CapturePointState
{
CAPTURE_STATE_NEUTRAL = 0,
CAPTURE_STATE_PROGRESS_ALLIANCE,
CAPTURE_STATE_PROGRESS_HORDE,
CAPTURE_STATE_CONTEST_ALLIANCE,
CAPTURE_STATE_CONTEST_HORDE,
CAPTURE_STATE_WIN_ALLIANCE,
CAPTURE_STATE_WIN_HORDE
};
enum CapturePointSlider
{
CAPTURE_SLIDER_ALLIANCE = 100, // full alliance
CAPTURE_SLIDER_HORDE = 0, // full horde
CAPTURE_SLIDER_MIDDLE = 50 // middle
};
class Unit;
class GameObjectModel;
struct GameObjectDisplayInfoEntry;
// 5 sec for bobber catch
#define FISHING_BOBBER_READY_TIME 5
#define GO_ANIMPROGRESS_DEFAULT 0xFF
class MANGOS_DLL_SPEC GameObject : public WorldObject
{
public:
explicit GameObject();
~GameObject();
void AddToWorld() override;
void RemoveFromWorld() override;
bool Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMask, float x, float y, float z, float ang,
QuaternionData rotation = QuaternionData(), uint8 animprogress = GO_ANIMPROGRESS_DEFAULT, GOState go_state = GO_STATE_READY);
void Update(uint32 update_diff, uint32 p_time) override;
GameObjectInfo const* GetGOInfo() const;
bool IsTransport() const;
bool HasStaticDBSpawnData() const; // listed in `gameobject` table and have fixed in DB guid
// z_rot, y_rot, x_rot - rotation angles around z, y and x axes
void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot);
void SetWorldRotation(float qx, float qy, float qz, float qw);
void SetTransportPathRotation(QuaternionData rotation); // transforms(rotates) transport's path
int64 GetPackedWorldRotation() const { return m_packedRotation; }
// overwrite WorldObject function for proper name localization
const char* GetNameForLocaleIdx(int32 locale_idx) const override;
void SaveToDB();
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map* map);
void DeleteFromDB();
void SetOwnerGuid(ObjectGuid ownerGuid)
{
m_spawnedByDefault = false; // all object with owner is despawned after delay
SetGuidValue(OBJECT_FIELD_CREATED_BY, ownerGuid);
}
ObjectGuid const& GetOwnerGuid() const { return GetGuidValue(OBJECT_FIELD_CREATED_BY); }
Unit* GetOwner() const;
void SetSpellId(uint32 id)
{
m_spawnedByDefault = false; // all summoned object is despawned after delay
m_spellId = id;
}
uint32 GetSpellId() const { return m_spellId;}
time_t GetRespawnTime() const { return m_respawnTime; }
time_t GetRespawnTimeEx() const
{
time_t now = time(NULL);
if (m_respawnTime > now)
return m_respawnTime;
else
return now;
}
void SetRespawnTime(time_t respawn)
{
m_respawnTime = respawn > 0 ? time(NULL) + respawn : 0;
m_respawnDelayTime = respawn > 0 ? uint32(respawn) : 0;
}
void Respawn();
bool isSpawned() const
{
return m_respawnDelayTime == 0 ||
(m_respawnTime > 0 && !m_spawnedByDefault) ||
(m_respawnTime == 0 && m_spawnedByDefault);
}
bool isSpawnedByDefault() const { return m_spawnedByDefault; }
uint32 GetRespawnDelay() const { return m_respawnDelayTime; }
void Refresh();
void Delete();
// Functions spawn/remove gameobject with DB guid in all loaded map copies (if point grid loaded in map)
static void AddToRemoveListInMaps(uint32 db_guid, GameObjectData const* data);
static void SpawnInMaps(uint32 db_guid, GameObjectData const* data);
GameobjectTypes GetGoType() const { return GameobjectTypes(GetByteValue(GAMEOBJECT_BYTES_1, 1)); }
void SetGoType(GameobjectTypes type) { SetByteValue(GAMEOBJECT_BYTES_1, 1, type); }
GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); }
void SetGoState(GOState state);
uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
void SetGoArtKit(uint8 artkit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, artkit); }
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }
uint32 GetDisplayId() const { return GetUInt32Value(GAMEOBJECT_DISPLAYID); }
void SetDisplayId(uint32 modelId);
void SetPhaseMask(uint32 newPhaseMask, bool update);
float GetObjectBoundingRadius() const override; // overwrite WorldObject version
void Use(Unit* user);
LootState getLootState() const { return m_lootState; }
void SetLootState(LootState s);
void AddToSkillupList(Player* player);
bool IsInSkillupList(Player* player) const;
void ClearSkillupList() { m_SkillupSet.clear(); }
void ClearAllUsesData()
{
ClearSkillupList();
m_useTimes = 0;
m_firstUser.Clear();
m_UniqueUsers.clear();
}
void AddUniqueUse(Player* player);
void AddUse() { ++m_useTimes; }
uint32 GetUseCount() const { return m_useTimes; }
uint32 GetUniqueUseCount() const { return m_UniqueUsers.size(); }
void SaveRespawnTime() override;
// Loot System
Loot loot;
void StartGroupLoot(Group* group, uint32 timer) override;
ObjectGuid GetLootRecipientGuid() const { return m_lootRecipientGuid; }
uint32 GetLootGroupRecipientId() const { return m_lootGroupRecipientId; }
Player* GetLootRecipient() const; // use group cases as prefered
Group* GetGroupLootRecipient() const;
bool HasLootRecipient() const { return m_lootGroupRecipientId || !m_lootRecipientGuid.IsEmpty(); }
bool IsGroupLootRecipient() const { return m_lootGroupRecipientId; }
void SetLootRecipient(Unit* pUnit);
Player* GetOriginalLootRecipient() const; // ignore group changes/etc, not for looting
bool HasQuest(uint32 quest_id) const override;
bool HasInvolvedQuest(uint32 quest_id) const override;
bool ActivateToQuest(Player* pTarget) const;
void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false);
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
bool IsHostileTo(Unit const* unit) const override;
bool IsFriendlyTo(Unit const* unit) const override;
void SummonLinkedTrapIfAny();
void TriggerLinkedGameObject(Unit* target);
// Destructible GO handling
void DealGameObjectDamage(uint32 damage, uint32 spell, Unit* caster);
void RebuildGameObject(uint32 spell, Unit* caster);
void ForceGameObjectHealth(int32 diff, Unit* caster);
uint32 GetHealth() const { return m_useTimes; }
uint32 GetMaxHealth() const { return m_goInfo->destructibleBuilding.intactNumHits + m_goInfo->destructibleBuilding.damagedNumHits; }
bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const override;
bool IsCollisionEnabled() const; // Check if a go should collide. Like if a door is closed
GameObject* LookupFishingHoleAround(float range);
void SetCapturePointSlider(float value);
float GetCapturePointSlider() const { return m_captureSlider; }
GridReference<GameObject>& GetGridRef() { return m_gridRef; }
GameObjectModel* m_model;
protected:
uint32 m_spellId;
time_t m_respawnTime; // (secs) time of next respawn (or despawn if GO have owner()),
uint32 m_respawnDelayTime; // (secs) if 0 then current GO state no dependent from timer
LootState m_lootState;
bool m_spawnedByDefault;
time_t m_cooldownTime; // used as internal reaction delay time store (not state change reaction).
// For traps/goober this: spell casting cooldown, for doors/buttons: reset time.
uint32 m_captureTimer; // (msecs) timer used for capture points
float m_captureSlider; // capture point slider value in range of [0..100]
CapturePointState m_captureState;
GuidSet m_SkillupSet; // players that already have skill-up at GO use
uint32 m_useTimes; // amount uses/charges triggered - also used for health for DESTRUCTIBLE_BUILDING
// collected only for GAMEOBJECT_TYPE_SUMMONING_RITUAL
ObjectGuid m_firstUser; // first GO user, in most used cases owner, but in some cases no, for example non-summoned multi-use GAMEOBJECT_TYPE_SUMMONING_RITUAL
GuidSet m_UniqueUsers; // all players who use item, some items activated after specific amount unique uses
GameObjectInfo const* m_goInfo;
GameObjectDisplayInfoEntry const* m_displayInfo;
int64 m_packedRotation;
QuaternionData m_worldRotation;
// Loot System
uint32 m_groupLootTimer; // (msecs)timer used for group loot
uint32 m_groupLootId; // used to find group which is looting
void StopGroupLoot() override;
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
private:
void SwitchDoorOrButton(bool activate, bool alternative = false);
void TickCapturePoint();
void UpdateModel(); // updates model in case displayId were changed
void UpdateCollisionState() const; // updates state in Map's dynamic collision tree
GridReference<GameObject> m_gridRef;
};
#endif