From 3bdd7fd4e8b3d2eaf0e9143755ccf71a3cf11611 Mon Sep 17 00:00:00 2001 From: SylvaniaCore deploy Date: Sun, 16 Aug 2026 08:23:16 +0200 Subject: [PATCH] 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 --- src/server/game/Entities/Creature/Creature.cpp | 13 ++++++++++++- src/server/game/Entities/GameObject/GameObject.cpp | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index fa2a752..4bbc29d 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1255,7 +1255,18 @@ void Creature::SaveToDB(uint32 mapid, std::vector 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 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); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index ffe9adf..6a8b6d7 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -981,7 +981,18 @@ void GameObject::SaveToDB(uint32 mapid, std::vector 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 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());