Les PNJ poses avec .npc add disparaissaient au redemarrage

Creature::SaveToDB et GameObject::SaveToDB passaient directement
data.spawnDifficulties a StringJoin, qui serialise avec un flux. Or
`enum Difficulty` a pour type sous-jacent uint8 : le flux ecrivait donc le
*caractere* brut au lieu du nombre. Une difficulte 0, celle du monde ouvert,
donnait un octet NUL.

Au chargement suivant la colonne etait illisible et ObjectMgr rejetait le
spawn -- "not spawned in any difficulty, skipped". Tout PNJ pose en jeu
tenait donc jusqu au redemarrage, puis disparaissait. 46 lignes etaient
concernees en base, dont les 42 Portails d Invocation de Mercenaire.

Conversion en uint32 avant la jointure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
SylvaniaCore deploy
2026-08-16 08:23:16 +02:00
parent 65dacb0de7
commit 3bdd7fd4e8
2 changed files with 24 additions and 2 deletions
+12 -1
View File
@@ -1255,7 +1255,18 @@ void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiffic
stmt->setUInt64(index++, m_spawnId);
stmt->setUInt32(index++, GetEntry());
stmt->setUInt16(index++, uint16(mapid));
stmt->setString(index++, StringJoin(data.spawnDifficulties, ","));
// `enum Difficulty` a pour type sous-jacent uint8 : le passer tel quel a
// StringJoin faisait ecrire par le flux le *caractere* brut au lieu du
// nombre. Une difficulte 0 (monde ouvert) donnait donc un octet NUL, la
// colonne devenait illisible et le spawn etait rejete au chargement
// suivant ("not spawned in any difficulty, skipped") : tout PNJ pose en
// jeu disparaissait au redemarrage.
std::vector<uint32> difficultyIds;
difficultyIds.reserve(data.spawnDifficulties.size());
for (Difficulty spawnDifficulty : data.spawnDifficulties)
difficultyIds.push_back(uint32(spawnDifficulty));
stmt->setString(index++, StringJoin(difficultyIds, ","));
stmt->setUInt32(index++, data.phaseId);
stmt->setUInt32(index++, data.phaseGroup);
stmt->setUInt32(index++, displayId);
@@ -981,7 +981,18 @@ void GameObject::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiff
stmt->setUInt64(index++, m_spawnId);
stmt->setUInt32(index++, GetEntry());
stmt->setUInt16(index++, uint16(mapid));
stmt->setString(index++, StringJoin(data.spawnDifficulties, ","));
// `enum Difficulty` a pour type sous-jacent uint8 : le passer tel quel a
// StringJoin faisait ecrire par le flux le *caractere* brut au lieu du
// nombre. Une difficulte 0 (monde ouvert) donnait donc un octet NUL, la
// colonne devenait illisible et le spawn etait rejete au chargement
// suivant ("not spawned in any difficulty, skipped") : tout PNJ pose en
// jeu disparaissait au redemarrage.
std::vector<uint32> difficultyIds;
difficultyIds.reserve(data.spawnDifficulties.size());
for (Difficulty spawnDifficulty : data.spawnDifficulties)
difficultyIds.push_back(uint32(spawnDifficulty));
stmt->setString(index++, StringJoin(difficultyIds, ","));
stmt->setUInt32(index++, data.phaseId);
stmt->setUInt32(index++, data.phaseGroup);
stmt->setFloat(index++, GetPositionX());