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
|
---
tableofcontents: 1
---
# C++ Code Standards
## Intro
### Why are coding standards important?
It makes it easier for everyone to maintain and read the written code as well as it gives us more control over it.
It can also act as a safe guard to prevent errors in the code.
### Why is it important for everyone to follow the standards?
We only accept code that is written to the standards, this means that a PR you want to contribute with can be merged faster if you follow the standards from the beginning.
## Coding Standards
### Tabs and Indents
We never use tabs, instead we use spaces.
One tab is equal to 4 spaces and that is what should be used throughout the whole project.
Visual Studio:
Tools -> Options -> Text Editor -> C/C++ -> Tabs -> Smart, 4, 4, Insert spaces.
Notepad++:
Settings -> Preferences -> Language -> Tab size: 4, Replace by space: checked
### Comments
Always comment code where it is not typical repeated code and where the code is not self-explanatory.
Comments should either be placed dierectly above the code, or directly beside it.
```cpp
// A Comment
if (a == b)
if (a == b)
{
a = b; // A Comment
```
### Whitespace
Trailing whitespace is a not allowed.
You should also not have unneeded spaces within a bracket.
Wrong:
```cpp
if( var )
if ( var )
```
Correct:
```cpp
if (var)
```
### Brackets
When we work with if or else statements, etc, we always use brackets.
```cpp
if (var)
{
me->DoA();
me->DoB();
}
else
{
me->DoC();
}
```
### Random numbers vs. Constants
Constants makes the code easier to read and understand, they also provide a safe guard and prevents numbers from being hard-coded.
Wrong:
```cpp
if (player->GetQuestStatus(10090) == 1)
{
me->RemoveFlag(58, 2);
}
```
Correct:
```cpp
if (player->GetQuestStatus(QUEST_BEAT_UP) == QUEST_STATUS_INCOMPLETE)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
}
```
### Enumerations vs. define
It is strongly advised to avoid using #define for constants. use either a const variable or an enum if multiple variables can be grouped togehter.
Enums must have a name. Separate constant on different enums depending on their type.
```cpp
enum Spells
{
SPELL_1 = 1111
SPELL_2 = 2222
SPELL_3 = 3333
};
constexpr uint32 SPELL_4 = 4444;
```
### Enum vs. Enum Class
Enum classes are prefered to be used as they can cause fewer suprises that could lead to bugs as the enum will not implicitly convert to other types like integer or other enums.
```cpp
enum class Spell : uint32
{
One = 1111,
Two = 2222,
Three = 3333
}
```
### Standard prefixes for constants
All constants that we store have a standardized prefix.
| PREFIX | Comment |
| :----- | :------- |
| SPELL_ | Spell ID |
| NPC_ | [creature_template.entry](creature_template#entry) |
| ITEM_ | [item_template.entry](item_template#entry) |
| GO_ | [gameobject_template.entry](gameobject_template#entry) |
| QUEST_ | [quest_template.id](quest_template#id) |
| SAY_ | [creature_text.GroupID](creature_text#groupid) |
| EMOTE_ | [creature_text.GroupID](creature_text#groupid) Different prefix from SAY_ to show that this is an emote. |
| MODEL_ | Creature model, DisplayID |
| XX_G | Heroic mode prefix (goes after the other prefix) XX is max man amount from mode. (OBSOLETE AS OF PATCH 3.2 WITH SpellDifficulty.dbc) |
| RAID_XX | Raid mode prefix (goes before the other prefix) XX is max man amount from mode. (OBSOLETE AS OF PATCH 3.2 WITH SpellDifficulty.dbc) |
| EVENT_ | Event/Encounter identifier for instances |
| DATA_ | Identifiers in instance used for GUIDs/data not being event/encounter |
| ACHIEV_ | Achievement ID |
Correct:
```
SPELL_ENRAGE
SPELL_ENRAGE_H
EVENT_ILLIDAN
DATA_ILLIDAN
ACHIEVE_MAKE_IT_COUNT
```
### Naming of variables and functions
Never use HUNGARIAN NOTATION in variable names!
for public/protected members or global variables:
```cpp
uint64 SomeGuid;
uint32 ShadowBoltTimer;
uint8 ShadowBoltCount;
bool IsEnraged;
float HeightData;
```
for private members:
```cpp
uint64 _someGuid;
uint32 _mapEntry;
uint8 _count;
bool _isDead;
float _heightData;
```
Methods are always UpperCamelCase and their parameters in lowerCamelCase
```cpp
void DoSomething(uint32 someNumber)
{
uint32 someOtherNumber = 5;
}
```
Always use 'f' after float values when declaring them to avoid compile warnings.
```cpp
float posX = 234.3456f;
```
### WorldObjects
We define WorldObjects in this way:
```cpp
GameObject* go;
Creature* creature;
Item* item;
Player* player;
Unit* unit;
```
We never use multiple declaration with pointers
```cpp
Something* obj1, *obj2;
```
The proper way to do this is
```cpp
Something* obj1;
Something* obj2;
```
References are defined in a similar way (& must be stuck to the type)
```cpp
Creature& creature;
```
Never define "me" in a creature or object script!
'me' is the pointer to the scripted creature or object.
### Defining const variables
const keyword should always go after type name
```cpp
Player const* player; // player object is constant
Unit* const unit; // pointer to the unit is constant
SpellEntry const* const spell; // both spell and pointer to spell are constant
```
### Static variables
static keyword always should be put as first
```cpp
static uint32 someVar = 5;
static float const otherVar = 1.0f;
```
|