From dfac47a5629367caf5e3db3106f2160b1f3d7ce3 Mon Sep 17 00:00:00 2001 From: Malcrom Date: Fri, 14 Jan 2022 19:21:50 -0400 Subject: [PATCH] feat(Core/Creature): Allow 3 ids per spawn point. TESTING (#10169) * feat(Core/Creature): Allow 3 ids per spawn point. * Move GetRandomId to a function * Update id to id1 * Fixed some errors crashing core and text * Set ids to lowercase for GetRandomId function * Update src/server/database/Database/Implementation/WorldDatabase.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Co-authored-by: acidmanifesto Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> --- .../rev_1642127807584111320.sql | 12 +++ .../Database/Implementation/WorldDatabase.cpp | 6 +- src/server/game/Conditions/ConditionMgr.cpp | 2 +- .../game/Entities/Creature/Creature.cpp | 40 ++++++++-- src/server/game/Entities/Creature/Creature.h | 2 +- .../game/Entities/Creature/CreatureData.h | 4 +- src/server/game/Events/GameEventMgr.cpp | 19 ++--- src/server/game/Globals/ObjectMgr.cpp | 79 ++++++++++--------- .../game/Handlers/AuctionHouseHandler.cpp | 2 +- src/server/game/Maps/ZoneScript.h | 2 +- src/server/game/OutdoorPvP/OutdoorPvP.cpp | 2 +- src/server/scripts/Commands/cs_go.cpp | 2 +- src/server/scripts/Commands/cs_npc.cpp | 16 ++-- src/server/scripts/Commands/cs_tele.cpp | 7 +- .../PitOfSaron/instance_pit_of_saron.cpp | 2 +- .../IcecrownCitadel/icecrown_citadel.cpp | 4 +- .../instance_icecrown_citadel.cpp | 2 +- 17 files changed, 123 insertions(+), 80 deletions(-) create mode 100644 data/sql/updates/pending_db_world/rev_1642127807584111320.sql diff --git a/data/sql/updates/pending_db_world/rev_1642127807584111320.sql b/data/sql/updates/pending_db_world/rev_1642127807584111320.sql new file mode 100644 index 000000000..b326dfae1 --- /dev/null +++ b/data/sql/updates/pending_db_world/rev_1642127807584111320.sql @@ -0,0 +1,12 @@ +INSERT INTO `version_db_world` (`sql_rev`) VALUES ('1642127807584111320'); + +ALTER TABLE `creature` + CHANGE COLUMN `creature_id1` `id1` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Creature Identifier' AFTER `guid`, + CHANGE COLUMN `creature_id2` `id2` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Creature Identifier' AFTER `id1`, + ADD COLUMN `id3` MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 COMMENT 'Creature Identifier' AFTER `id2`, + DROP COLUMN `chance_id1`; + +UPDATE `acore_string` SET `content_default`="Player selected NPC\nDB GUID: %u, current GUID: %u.\nCurrent Entry: %u of (%u, %u, %u).\nDisplayID: %u (Native: %u).\nFaction: %u.\nnpcFlags: %u." WHERE `entry`=539; +UPDATE `acore_string` SET `locale_frFR`='PNJ sélectionné par le joueur\nGUID en base: %u, GUID actuel: %u.\nEntry actuel: %u de (%u, %u, %u).\nDisplayID: %u (Natif: %u).\nFaction: %u.\nnpcFlags: %u.' WHERE `entry`=539; +UPDATE `acore_string` SET `locale_deDE`='Vom Spieler gewählter NPC\nDB GUID: %u, aktuelle GUID: %u.\nAktueller Entry: %u von (%u, %u, %u).\nDisplayID: %u (Ursprünglich: %u).\nFraktion: %u.\nnpcFlags: %u.' WHERE `entry`=539; +UPDATE `acore_string` SET `locale_zhCN`='当前选择NPC属性\nDB GUID: %u,目前 GUID: %u.\n阵营: %u 的 (%u, %u, %u).\n外观ID: %u (Native: %u).\n编号: %u.\nNPC标识: %u.' WHERE `entry`=539; diff --git a/src/server/database/Database/Implementation/WorldDatabase.cpp b/src/server/database/Database/Implementation/WorldDatabase.cpp index 1bf8be12f..623533a2a 100644 --- a/src/server/database/Database/Implementation/WorldDatabase.cpp +++ b/src/server/database/Database/Implementation/WorldDatabase.cpp @@ -80,10 +80,10 @@ void WorldDatabaseConnection::DoPrepareStatements() PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, faction, npcflag, speed_walk, speed_run, speed_swim, speed_flight, detection_range, scale, `rank`, dmgschool, DamageModifier, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, dynamicflags, family, trainer_type, trainer_spell, trainer_class, trainer_race, type, type_flags, lootid, pickpocketloot, skinloot, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, ctm.Ground, ctm.Swim, ctm.Flight, ctm.Rooted, ctm.Chase, ctm.Random, ctm.InteractionPauseTimer, HoverHeight, HealthModifier, ManaModifier, ArmorModifier, ExperienceModifier, RacialLeader, movementId, RegenHealth, mechanic_immune_mask, spell_school_immune_mask, flags_extra, ScriptName FROM creature_template ct LEFT JOIN creature_template_movement ctm ON ct.entry = ctm.CreatureId WHERE entry = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_BY_ID, "SELECT guid, delay, command, datalong, datalong2, dataint, x, y, z, o FROM waypoint_scripts WHERE id = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_ITEM_TEMPLATE_BY_NAME, "SELECT entry FROM item_template WHERE name = ?", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE creature_id1 = ?", CONNECTION_SYNCH); + PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id1 = ? OR id2 = ? OR id3 = ?", CONNECTION_SYNCH); PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? AND (phaseMask & ?) <> 0 ORDER BY order_", CONNECTION_SYNCH); - PrepareStatement(WORLD_SEL_CREATURE_NEAREST, "SELECT guid, creature_id1,creature_id2, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? AND (phaseMask & ?) <> 0 ORDER BY order_", CONNECTION_SYNCH); - PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, creature_id1, creature_id2, chance_id1, map, spawnMask, phaseMask, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); + PrepareStatement(WORLD_SEL_CREATURE_NEAREST, "SELECT guid, id1, id2, id3, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? AND (phaseMask & ?) <> 0 ORDER BY order_", CONNECTION_SYNCH); + PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id1, id2, id3, map, spawnMask, phaseMask, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); PrepareStatement(WORLD_DEL_GAME_EVENT_CREATURE, "DELETE FROM game_event_creature WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP, "DELETE FROM game_event_model_equip WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(WORLD_INS_GAMEOBJECT, "INSERT INTO gameobject (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 52879c9e2..c1b09135c 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1984,7 +1984,7 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { if (CreatureData const* creatureData = sObjectMgr->GetCreatureData(cond->ConditionValue3)) { - if (cond->ConditionValue2 && creatureData->id != cond->ConditionValue2) + if (cond->ConditionValue2 && creatureData->id1 != cond->ConditionValue2) { LOG_ERROR("sql.sql", "ObjectEntryGuid condition has guid %u set but does not match creature entry (%u), skipped", cond->ConditionValue3, cond->ConditionValue2); return false; diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 00ab06200..272a93d72 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -1310,7 +1310,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) dynamicflags = 0; } - data.id = GetEntry(); + data.id1 = GetEntry(); data.mapid = mapid; data.phaseMask = phaseMask; data.displayid = displayId; @@ -1357,7 +1357,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) stmt->setUInt32(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt32(index++, 0); - stmt->setFloat(index++, 100.0f); + stmt->setUInt32(index++, 0); stmt->setUInt16(index++, uint16(mapid)); stmt->setUInt8(index++, spawnMask); stmt->setUInt32(index++, GetPhaseMask()); @@ -1613,9 +1613,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad m_spawnId = spawnId; // Add to world - uint32 entry = data->id; - if(data->id2) - entry = (roll_chance_f(data->chance_id1)) ? data->id : data->id2; + uint32 entry = GetRandomId(data->id1, data->id2, data->id3); if (!Create(map->GenerateLowGuid(), map, data->phaseMask, entry, 0, data->posX, data->posY, data->posZ, data->orientation, data)) return false; @@ -1913,7 +1911,7 @@ void Creature::Respawn(bool force) // Respawn check if spawn has 2 entries if (data->id2) { - uint32 entry = (roll_chance_f(data->chance_id1)) ? data->id : data->id2; + uint32 entry = GetRandomId(data->id1, data->id2, data->id3); UpdateEntry(entry, data, true); // Select Random Entry m_defaultMovementType = MovementGeneratorType(data->movementType); // Reload Movement Type LoadEquipment(data->equipmentId); // Reload Equipment @@ -3458,3 +3456,33 @@ bool Creature::CanPeriodicallyCallForAssistance() const return true; } + +uint32 Creature::GetRandomId(uint32 id1, uint32 id2, uint32 id3) +{ + uint32 id = id1; + uint8 ids = 0; + + if (id2) + { + ++ids; + if (id3) ++ids; + } + + if (ids) + { + uint8 idNumber = urand(0, ids); + switch (idNumber) + { + case 0: + id = id1; + break; + case 1: + id = id2; + break; + case 2: + id = id3; + break; + } + } + return id; +} diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 035f81e15..e5b56a48d 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -167,7 +167,7 @@ public: [[nodiscard]] bool HasSpell(uint32 spellID) const override; void UpdateMovementFlags(); - + uint32 GetRandomId(uint32 id1, uint32 id2, uint32 id3); bool UpdateEntry(uint32 entry, const CreatureData* data = nullptr, bool changelevel = true ); bool UpdateStats(Stats stat) override; bool UpdateAllStats() override; diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index 15b2584eb..b1159c9bc 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -359,9 +359,9 @@ typedef std::unordered_map EquipmentInfo struct CreatureData { CreatureData() { } - uint32 id{0}; // entry in creature_template + uint32 id1{0}; // entry in creature_template uint32 id2{0}; // entry in creature_template - float chance_id1{0}; // Chance for first id to spawn + uint32 id3{0}; // entry in creature_template uint16 mapid{0}; uint32 phaseMask{0}; uint32 displayid{0}; diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index bd22efb39..60cfd0925 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -230,7 +230,7 @@ void GameEventMgr::LoadFromDB() { { uint32 oldMSTime = getMSTime(); - // 1 2 3 4 5 6 7 8 9 10 + // 1 2 3 4 5 6 7 8 9 10 QueryResult result = WorldDatabase.Query("SELECT eventEntry, UNIX_TIMESTAMP(start_time), UNIX_TIMESTAMP(end_time), occurence, length, holiday, holidayStage, description, world_event, announce FROM game_event"); if (!result) { @@ -490,8 +490,8 @@ void GameEventMgr::LoadFromDB() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 - QueryResult result = WorldDatabase.Query("SELECT creature.guid, creature.creature_id1, creature.creature_id2, game_event_model_equip.eventEntry, game_event_model_equip.modelid, game_event_model_equip.equipment_id " + // 0 1 2 3 4 5 6 + QueryResult result = WorldDatabase.Query("SELECT creature.guid, creature.id1, creature.id2, creature.id3, game_event_model_equip.eventEntry, game_event_model_equip.modelid, game_event_model_equip.equipment_id " "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid"); if (!result) @@ -508,8 +508,9 @@ void GameEventMgr::LoadFromDB() ObjectGuid::LowType guid = fields[0].GetUInt32(); uint32 entry = fields[1].GetUInt32(); - //uint32 entry2 = fields[2].GetUInt32(); - uint16 event_id = fields[3].GetUInt8(); + uint32 entry2 = fields[2].GetUInt32(); + uint32 entry3 = fields[3].GetUInt32(); + uint16 event_id = fields[4].GetUInt8(); if (event_id >= mGameEventModelEquip.size()) { @@ -519,15 +520,15 @@ void GameEventMgr::LoadFromDB() ModelEquipList& equiplist = mGameEventModelEquip[event_id]; ModelEquip newModelEquipSet; - newModelEquipSet.modelid = fields[4].GetUInt32(); - newModelEquipSet.equipment_id = fields[5].GetUInt8(); + newModelEquipSet.modelid = fields[5].GetUInt32(); + newModelEquipSet.equipment_id = fields[6].GetUInt8(); newModelEquipSet.equipement_id_prev = 0; newModelEquipSet.modelid_prev = 0; if (newModelEquipSet.equipment_id > 0) { int8 equipId = static_cast(newModelEquipSet.equipment_id); - if (!sObjectMgr->GetEquipmentInfo(entry, equipId)) + if ((!sObjectMgr->GetEquipmentInfo(entry, equipId)) || (entry2 && !sObjectMgr->GetEquipmentInfo(entry2, equipId)) || (entry3 && !sObjectMgr->GetEquipmentInfo(entry3, equipId))) { LOG_ERROR("sql.sql", "Table `game_event_model_equip` have creature (Guid: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", guid, newModelEquipSet.equipment_id); @@ -888,7 +889,7 @@ void GameEventMgr::LoadFromDB() newEntry.entry = 0; if (CreatureData const* data = sObjectMgr->GetCreatureData(guid)) - newEntry.entry = data->id; + newEntry.entry = data->id1; // check validity with event's npcflag if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, nullptr, nullptr, event_npc_flag)) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index c486ecdad..2bb7f8569 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -1486,7 +1486,7 @@ void ObjectMgr::LoadCreatureMovementOverrides() "COALESCE(cmo.InteractionPauseTimer, ctm.InteractionPauseTimer) " "FROM creature_movement_override AS cmo " "LEFT JOIN creature AS c ON c.guid = cmo.SpawnId " - "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.creature_id1"); + "LEFT JOIN creature_template_movement AS ctm ON ctm.CreatureId = c.id1"); if (!result) { LOG_INFO("server.loading", ">> Loaded 0 creature movement overrides. DB table `creature_movement_override` is empty!"); @@ -1722,8 +1722,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - guid = ObjectGuid::Create(slave->id, guidLow); - linkedGuid = ObjectGuid::Create(master->id, linkedGuidLow); + guid = ObjectGuid::Create(slave->id1, guidLow); + linkedGuid = ObjectGuid::Create(master->id1, linkedGuidLow); break; } case CREATURE_TO_GO: @@ -1759,7 +1759,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - guid = ObjectGuid::Create(slave->id, guidLow); + guid = ObjectGuid::Create(slave->id1, guidLow); linkedGuid = ObjectGuid::Create(master->id, linkedGuidLow); break; } @@ -1834,7 +1834,7 @@ void ObjectMgr::LoadLinkedRespawn() } guid = ObjectGuid::Create(slave->id, guidLow); - linkedGuid = ObjectGuid::Create(master->id, linkedGuidLow); + linkedGuid = ObjectGuid::Create(master->id1, linkedGuidLow); break; } } @@ -1853,7 +1853,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid return false; CreatureData const* master = GetCreatureData(guidLow); - ObjectGuid guid = ObjectGuid::Create(master->id, guidLow); + ObjectGuid guid = ObjectGuid::Create(master->id1, guidLow); if (!linkedGuidLow) // we're removing the linking { @@ -1884,7 +1884,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(ObjectGuid::LowType guidLow, ObjectGuid return false; } - ObjectGuid linkedGuid = ObjectGuid::Create(slave->id, linkedGuidLow); + ObjectGuid linkedGuid = ObjectGuid::Create(slave->id1, linkedGuidLow); _linkedRespawnStore[guid] = linkedGuid; WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_REP_CREATURE_LINKED_RESPAWN); @@ -1898,7 +1898,7 @@ void ObjectMgr::LoadTempSummons() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 9 + // 0 1 2 3 4 5 6 7 8 9 QueryResult result = WorldDatabase.Query("SELECT summonerId, summonerType, groupId, entry, position_x, position_y, position_z, orientation, summonType, summonTime FROM creature_summon_groups"); if (!result) @@ -1984,8 +1984,8 @@ void ObjectMgr::LoadCreatures() { uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 6 7 8 9 10 11 - QueryResult result = WorldDatabase.Query("SELECT creature.guid, creature_id1, creature_id2, chance_id1, map, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, " + // 0 1 2 3 4 5 6 7 8 9 10 11 + QueryResult result = WorldDatabase.Query("SELECT creature.guid, id1, id2, id3, map, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, wander_distance, " // 12 13 14 15 16 17 18 19 20 21 22 "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, " // 23 @@ -2016,36 +2016,37 @@ void ObjectMgr::LoadCreatures() Field* fields = result->Fetch(); ObjectGuid::LowType spawnId = fields[0].GetUInt32(); - uint32 id = fields[1].GetUInt32(); + uint32 id1 = fields[1].GetUInt32(); uint32 id2 = fields[2].GetUInt32(); - uint32 chance = fields[3].GetUInt32(); + uint32 id3 = fields[3].GetUInt32(); - CreatureTemplate const* cInfo = GetCreatureTemplate(id); + CreatureTemplate const* cInfo = GetCreatureTemplate(id1); if (!cInfo) { - LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: %u) with non existing creature entry %u in creature_id1 field, skipped.", spawnId, id); + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: %u) with non existing creature entry %u in id1 field, skipped.", spawnId, id1); continue; } CreatureTemplate const* cInfo2 = GetCreatureTemplate(id2); if (!cInfo2 && id2) { - LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: %u) with non existing creature entry %u in creature_id2 field, skipped.", spawnId, id2); + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: %u) with non existing creature entry %u in id2 field, skipped.", spawnId, id2); continue; } - if (!chance || chance > 100) + CreatureTemplate const* cInfo3 = GetCreatureTemplate(id3); + if (!cInfo3 && id3) { - LOG_ERROR("sql.sql", "Table `creature` chance_id1 (Value: %u) must be greater than 0 and less than or equal to 100, skipped.", chance); + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: %u) with non existing creature entry %u in id3 field, skipped.", spawnId, id3); continue; } - if (chance == 100 && id2) + if (!id2 && id3) { - LOG_ERROR("sql.sql", "Table `creature` has spawnid = %u chance = 100 even though creature_id2 has an entry. changed to 50.", spawnId); - chance = 50; + LOG_ERROR("sql.sql", "Table `creature` has creature (SpawnId: %u) with creature entry %u in id3 field but no entry in id2 field, skipped.", spawnId, id3); + continue; } CreatureData& data = _creatureDataStore[spawnId]; - data.id = id; + data.id1 = id1; data.id2 = id2; - data.chance_id1 = chance; + data.id3 = id3; data.mapid = fields[4].GetUInt16(); data.equipmentId = fields[5].GetInt8(); data.posX = fields[6].GetFloat(); @@ -2089,10 +2090,10 @@ void ObjectMgr::LoadCreatures() bool ok = true; for (uint32 diff = 0; diff < MAX_DIFFICULTY - 1 && ok; ++diff) { - if (_difficultyEntries[diff].find(data.id) != _difficultyEntries[diff].end()) + if ((_difficultyEntries[diff].find(data.id1) != _difficultyEntries[diff].end()) || (_difficultyEntries[diff].find(data.id2) != _difficultyEntries[diff].end()) || (_difficultyEntries[diff].find(data.id3) != _difficultyEntries[diff].end())) { - LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u) that listed as difficulty %u template (entry: %u) in `creature_template`, skipped.", - spawnId, diff + 1, data.id); + LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u) that listed as difficulty %u template (Entries: %u, %u, %u) in `creature_template`, skipped.", + spawnId, diff + 1, data.id1, data.id2, data.id3); ok = false; } } @@ -2102,32 +2103,30 @@ void ObjectMgr::LoadCreatures() // -1 random, 0 no equipment, if (data.equipmentId != 0) { - if (!GetEquipmentInfo(data.id, data.equipmentId)) + if ((!GetEquipmentInfo(data.id1, data.equipmentId)) || (data.id2 && !GetEquipmentInfo(data.id2, data.equipmentId)) || (data.id3 && !GetEquipmentInfo(data.id3, data.equipmentId))) { - LOG_ERROR("sql.sql", "Table `creature` have creature (Entry: %u) with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", - data.id, data.equipmentId); + LOG_ERROR("sql.sql", "Table `creature` have creature (Entries: %u, %u, %u) one or more with equipment_id %u not found in table `creature_equip_template`, set to no equipment.", + data.id1, data.id2, data.id3, data.equipmentId); data.equipmentId = 0; } } - - if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) + if ((cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) || (data.id2 && cInfo2->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) || (data.id3 && cInfo3->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND)) { if (!mapEntry->IsDungeon()) - LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.", - spawnId, data.id); + LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entries: %u, %u, %u) with a `creature_template`.`flags_extra` in one or more entries including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature are not in instance.", + spawnId, data.id1, data.id2, data.id3); } - if (data.wander_distance < 0.0f) { - LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entry: %u) with `wander_distance`< 0, set to 0.", spawnId, data.id); + LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entries: %u, %u, %u) with `wander_distance`< 0, set to 0.", spawnId, data.id1, data.id2, data.id3); data.wander_distance = 0.0f; } else if (data.movementType == RANDOM_MOTION_TYPE) { if (data.wander_distance == 0.0f) { - LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entry: %u) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).", - spawnId, data.id); + LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entries: %u, %u, %u) with `MovementType`=1 (random movement) but with `wander_distance`=0, replace by idle movement type (0).", + spawnId, data.id1, data.id2, data.id3); data.movementType = IDLE_MOTION_TYPE; } } @@ -2135,14 +2134,14 @@ void ObjectMgr::LoadCreatures() { if (data.wander_distance != 0.0f) { - LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entry: %u) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", spawnId, data.id); + LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entries: %u, %u, %u) with `MovementType`=0 (idle) have `wander_distance`<>0, set to 0.", spawnId, data.id1, data.id2, data.id3); data.wander_distance = 0.0f; } } if (data.phaseMask == 0) { - LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, data.id); + LOG_ERROR("sql.sql", "Table `creature` have creature (SpawnId: %u Entries: %u, %u, %u) with `phaseMask`=0 (not visible for anyone), set to 1.", spawnId, data.id1, data.id2, data.id3); data.phaseMask = 1; } @@ -2265,7 +2264,9 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 mapId, float x, float y, float ObjectGuid::LowType spawnId = GenerateCreatureSpawnId(); CreatureData& data = NewOrExistCreatureData(spawnId); data.spawnMask = spawnId; - data.id = entry; + data.id1 = entry; + data.id2 = 0; + data.id3 = 0; data.mapid = mapId; data.displayid = 0; data.equipmentId = 0; diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 632144b8c..dd0641810 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -277,7 +277,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) return; } - CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id); + CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id1); if (!auctioneerInfo) { LOG_ERROR("network.opcode", "Non existing auctioneer (%s)", auctioneer.ToString().c_str()); diff --git a/src/server/game/Maps/ZoneScript.h b/src/server/game/Maps/ZoneScript.h index faed37767..7a52ba113 100644 --- a/src/server/game/Maps/ZoneScript.h +++ b/src/server/game/Maps/ZoneScript.h @@ -29,7 +29,7 @@ public: ZoneScript() {} virtual ~ZoneScript() {} - virtual uint32 GetCreatureEntry(ObjectGuid::LowType /*guidlow*/, CreatureData const* data) { return data->id; } + virtual uint32 GetCreatureEntry(ObjectGuid::LowType /*guidlow*/, CreatureData const* data) { return data->id1; } virtual uint32 GetGameObjectEntry(ObjectGuid::LowType /*guidlow*/, uint32 entry) { return entry; } virtual void OnCreatureCreate(Creature*) { } diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index df0cdc4a9..a887b1597 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -84,7 +84,7 @@ void OPvPCapturePoint::AddCre(uint32 type, ObjectGuid::LowType guid, uint32 entr const CreatureData* data = sObjectMgr->GetCreatureData(guid); if (!data) return; - entry = data->id; + entry = data->id1; } m_Creatures[type] = guid; m_CreatureTypes[m_Creatures[type]] = type; diff --git a/src/server/scripts/Commands/cs_go.cpp b/src/server/scripts/Commands/cs_go.cpp index 90204f153..c82376570 100644 --- a/src/server/scripts/Commands/cs_go.cpp +++ b/src/server/scripts/Commands/cs_go.cpp @@ -94,7 +94,7 @@ public: CreatureData const* spawnpoint = nullptr; for (auto const& pair : sObjectMgr->GetAllCreatureData()) { - if (pair.second.id != *cId) + if (pair.second.id1 != *cId) continue; if (!spawnpoint) diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 0490e269e..b8a767f82 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -223,7 +223,7 @@ public: { ObjectGuid::LowType guid = sObjectMgr->GenerateCreatureSpawnId(); CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid); - data.id = id; + data.id1 = id; data.phaseMask = chr->GetPhaseMaskForSpawn(); data.posX = chr->GetTransOffsetX(); data.posY = chr->GetTransOffsetY(); @@ -595,14 +595,14 @@ public: uint32 displayid = target->GetDisplayId(); uint32 nativeid = target->GetNativeDisplayId(); uint32 entry = target->GetEntry(); - uint32 creature_id1 = 0; - uint32 creature_id2 = 0; - float chance_id1 = 0.0f; + uint32 id1 = 0; + uint32 id2 = 0; + uint32 id3 = 0; if (CreatureData const* cData = target->GetCreatureData()) { - creature_id1 = cData->id; - creature_id2 = cData->id2; - chance_id1 = cData->chance_id1; + id1 = cData->id1; + id2 = cData->id2; + id3 = cData->id3; } int64 curRespawnDelay = target->GetRespawnTimeEx() - time(nullptr); @@ -611,7 +611,7 @@ public: std::string curRespawnDelayStr = secsToTimeString(uint64(curRespawnDelay), true); std::string defRespawnDelayStr = secsToTimeString(target->GetRespawnDelay(), true); - handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetSpawnId(), target->GetGUID().GetCounter(), entry, creature_id1, creature_id2, chance_id1, displayid, nativeid, faction, npcflags); + handler->PSendSysMessage(LANG_NPCINFO_CHAR, target->GetSpawnId(), target->GetGUID().GetCounter(), entry, id1, id2, id3, displayid, nativeid, faction, npcflags); handler->PSendSysMessage(LANG_NPCINFO_LEVEL, target->getLevel()); handler->PSendSysMessage(LANG_NPCINFO_EQUIPMENT, target->GetCurrentEquipmentId(), target->GetOriginalEquipmentId()); handler->PSendSysMessage(LANG_NPCINFO_HEALTH, target->GetCreateHealth(), target->GetMaxHealth(), target->GetHealth()); diff --git a/src/server/scripts/Commands/cs_tele.cpp b/src/server/scripts/Commands/cs_tele.cpp index c73860e97..22ce06da4 100644 --- a/src/server/scripts/Commands/cs_tele.cpp +++ b/src/server/scripts/Commands/cs_tele.cpp @@ -328,7 +328,7 @@ public: CreatureData const* spawnpoint = nullptr; for (auto const& pair : sObjectMgr->GetAllCreatureData()) { - if (pair.second.id != *creatureId) + if (pair.second.id1 != *creatureId) continue; if (!spawnpoint) @@ -362,7 +362,7 @@ public: return false; } - CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(spawnpoint->id)); + CreatureTemplate const* creatureTemplate = ASSERT_NOTNULL(sObjectMgr->GetCreatureTemplate(spawnpoint->id1)); return DoNameTeleport(handler, player, spawnpoint->mapid, { spawnpoint->posX, spawnpoint->posY, spawnpoint->posZ }, creatureTemplate->Name); } @@ -372,7 +372,8 @@ public: std::string normalizedName(name); WorldDatabase.EscapeString(normalizedName); - QueryResult result = WorldDatabase.PQuery("SELECT c.position_x, c.position_y, c.position_z, c.orientation, c.map, ct.name FROM creature c INNER JOIN creature_template ct ON c.creature_id1 = ct.entry WHERE ct.name LIKE '%s'", normalizedName.c_str()); + // May need work //PussyWizardEliteMalcrom + QueryResult result = WorldDatabase.PQuery("SELECT c.position_x, c.position_y, c.position_z, c.orientation, c.map, ct.name FROM creature c INNER JOIN creature_template ct ON c.id1 = ct.entry WHERE ct.name LIKE '%s'", normalizedName.c_str()); if (!result) { handler->SendSysMessage(LANG_COMMAND_GOCREATNOTFOUND); diff --git a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp index cc5022ce3..9a26bcfe9 100644 --- a/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/PitOfSaron/instance_pit_of_saron.cpp @@ -88,7 +88,7 @@ public: teamIdInInstance = player->GetTeamId(); } - uint32 entry = data->id; + uint32 entry = data->id1; switch (entry) { case NPC_RESCUED_ALLIANCE_SLAVE: diff --git a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp index 8ab8cef8f..5ebe9dc2a 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/icecrown_citadel.cpp @@ -1025,7 +1025,7 @@ public: if (Creature* crusader = ObjectAccessor::GetCreature(*me, instance->GetGuidData(DATA_CAPTAIN_ARNATH + i))) if (crusader->IsAlive()) { - if (crusader->GetEntry() == crusader->GetCreatureData()->id) + if (crusader->GetEntry() == crusader->GetCreatureData()->id1) { crusader->m_Events.AddEvent(new CaptainSurviveTalk(*crusader), crusader->m_Events.CalculateTime(delay)); delay += 6000; @@ -1207,7 +1207,7 @@ public: void Reset() override { me->SetCorpseDelay(DAY); // leave corpse for a long time so svalna can resurrect - IsUndead = (me->GetCreatureData() && me->GetCreatureData()->id != me->GetEntry()); + IsUndead = (me->GetCreatureData() && me->GetCreatureData()->id1 != me->GetEntry()); } void JustDied(Unit* /*killer*/) override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp index 9d1742b64..3c532ceaa 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/instance_icecrown_citadel.cpp @@ -490,7 +490,7 @@ public: TeamIdInInstance = player->GetTeamId(); } - uint32 entry = data->id; + uint32 entry = data->id1; switch (entry) { case NPC_HORDE_GUNSHIP_CANNON: