2.7 KiB
2.7 KiB
C++ guidelines
Run the linter before claiming a change is done: python apps/codestyle/codestyle-cpp.py
Code style
Hard rules (also enforced by CI with -Werror, plus cppcheck):
- Allman braces. No braces around single-line statements.
if (x)— neverif(x)orif ( x ). auto const&(notconst auto&);Type const*(notconst Type*).- Use
{}format specifiers (fmt-style), not%u/%s. - Use the typed helpers, not raw flag access:
IsPlayer(),IsCreature(),IsItem(), … instead ofGetTypeId() == TYPEID_*.GetNpcFlags(),HasNpcFlag(),SetNpcFlag(),RemoveNpcFlag(),ReplaceAllNpcFlags()instead of*Flag(UNIT_NPC_FLAGS, …).IsRefundable(),IsBOPTradable(),IsWrapped()instead ofHasFlag(ITEM_FIELD_FLAGS, …).HasFlag(ItemFlag)/HasFlag2(ItemFlag2)/HasFlagCu(ItemFlagsCustom)instead of bitwiseFlags & ITEM_FLAG….ObjectGuid::ToString().c_str()instead ofObjectGuid::GetCounter().
Project conventions
- Logging:
LOG_INFO("category.sub", "msg with {}", arg)(alsoLOG_WARN/ERROR/DEBUG/TRACE). Categories are hierarchical, dot-separated (server.loading,entities.player,sql.dev). Noprintf-style, nosLog->, noTC_LOG_*. Macro insrc/common/Logging/Log.h. - Random: use helpers in
src/common/Utilities/Random.h—urand,irand,frand,rand32,rand_chance,roll_chance_f,roll_chance_i. Notstd::randor<random>. - Strings:
Acore::StringFormat(fmt, args...)({}placeholders) —src/common/Utilities/StringFormat.h. - Config:
sConfigMgr->GetOption<T>("Name", default)— read once at startup/reload and cache the value; never call it in hot paths or per-call gating checks. - Namespace: project-wide
Acore::(noTrinity::remnants — rename when porting from upstream forks). - Long-lived references: don't store a raw
Player*/Creature*/Unit*past the current call/tick — the object can be removed (logout, despawn, instance unload) and the pointer dangles. Store theObjectGuidand resolve at use time viaObjectAccessor::FindPlayer(guid),Map::GetCreature(guid), etc. - DB queries: use
PreparedStatement(viaWorldDatabase/CharacterDatabase/LoginDatabaseand the prepared-statement enums), not raw query strings. Non-blocking reads go async:_queryProcessor.AddCallback(db.AsyncQuery(stmt).WithPreparedCallback(...))(orWithCallback). Multi-statement writes wrap inSQLTransaction+Execute/AppendPreparedStatement. - Timed actions in AI: use
EventMap(event id → delay; simple) orTaskScheduler(lambdas, repeats, cancellation), both members ofCreatureAI— don't roll your own tick counters. See any boss script undersrc/server/scripts/.