Core/Misc: First set of required db changes for 9.0

This commit is contained in:
Shauren
2020-12-08 18:16:46 +01:00
parent 56c097c129
commit 4ca29f3cb0
12 changed files with 494 additions and 264 deletions
@@ -0,0 +1,80 @@
ALTER TABLE `creature_template` DROP `FadeRegionRadius`;
ALTER TABLE `playerchoice_response`
ADD `ResponseIdentifier` smallint(5) unsigned NOT NULL AFTER `ResponseId`,
ADD `UiTextureKitID` int(11) NOT NULL DEFAULT '0' AFTER `GroupID`;
--
-- Table structure for table `playerchoice_response_reward_item_choice`
--
DROP TABLE IF EXISTS `playerchoice_response_reward_item_choice`;
CREATE TABLE `playerchoice_response_reward_item_choice` (
`ChoiceId` int(11) NOT NULL,
`ResponseId` int(11) NOT NULL,
`Index` int(10) unsigned NOT NULL,
`ItemId` int(10) unsigned NOT NULL DEFAULT '0',
`BonusListIDs` text,
`Quantity` int(11) NOT NULL DEFAULT '0',
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ChoiceId`,`ResponseId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `playerchoice_response_maw_power`
--
DROP TABLE IF EXISTS `playerchoice_response_maw_power`;
CREATE TABLE `playerchoice_response_maw_power` (
`ChoiceId` int(11) NOT NULL,
`ResponseId` int(11) NOT NULL,
`TypeArtFileID` int(11) DEFAULT '0',
`Rarity` int(11) DEFAULT '0',
`RarityColor` int(10) unsigned DEFAULT '0',
`SpellID` int(11) DEFAULT '0',
`MaxStacks` int(11) DEFAULT '0',
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`ChoiceId`,`ResponseId`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `quest_poi` ADD `NavigationPlayerConditionID` int(11) NOT NULL DEFAULT '0' AFTER `PlayerConditionID`;
ALTER TABLE `quest_poi_points` ADD `Z` int(11) NOT NULL DEFAULT '0' AFTER `Y`;
--
-- Table structure for table `quest_reward_choice_items`
--
DROP TABLE IF EXISTS `quest_reward_choice_items`;
CREATE TABLE `quest_reward_choice_items` (
`QuestID` int(10) unsigned NOT NULL,
`Type1` tinyint(3) unsigned DEFAULT '0',
`Type2` tinyint(3) unsigned DEFAULT '0',
`Type3` tinyint(3) unsigned DEFAULT '0',
`Type4` tinyint(3) unsigned DEFAULT '0',
`Type5` tinyint(3) unsigned DEFAULT '0',
`Type6` tinyint(3) unsigned DEFAULT '0',
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`QuestID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
--
-- Table structure for table `quest_reward_display_spell`
--
DROP TABLE IF EXISTS `quest_reward_display_spell`;
CREATE TABLE `quest_reward_display_spell` (
`QuestID` int(10) unsigned NOT NULL,
`Idx` int(10) unsigned NOT NULL,
`SpellID` int(10) unsigned DEFAULT '0',
`PlayerConditionID` int(10) unsigned DEFAULT '0',
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`QuestID`,`Idx`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
ALTER TABLE `quest_template`
ADD `ContentTuningID` int(10) unsigned NOT NULL DEFAULT '0' AFTER `QuestPackageID`,
DROP `QuestLevel`,
DROP `ScalingFactionGroup`,
DROP `MaxScalingLevel`,
DROP `MinLevel`;
ALTER TABLE `scenario_poi` ADD `NavigationPlayerConditionID` int(11) NOT NULL DEFAULT '0' AFTER `PlayerConditionID`;
ALTER TABLE `scenario_poi_points` ADD `Z` int(11) NOT NULL DEFAULT '0' AFTER `Y`;
@@ -77,7 +77,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
PrepareStatement(WORLD_SEL_WAYPOINT_SCRIPT_ID_BY_GUID, "SELECT id FROM waypoint_scripts WHERE guid = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_DEL_CREATURE, "DELETE FROM creature WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(WORLD_SEL_COMMANDS, "SELECT name, permission, help FROM command", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, FadeRegionRadius, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ? OR 1 = ?", CONNECTION_SYNCH);
PrepareStatement(WORLD_SEL_CREATURE_TEMPLATE, "SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, name, femaleName, subname, TitleAlt, IconName, gossip_menu_id, minlevel, maxlevel, HealthScalingExpansion, RequiredExpansion, VignetteID, faction, npcflag, speed_walk, speed_run, scale, `rank`, dmgschool, BaseAttackTime, RangeAttackTime, BaseVariance, RangeVariance, unit_class, unit_flags, unit_flags2, unit_flags3, dynamicflags, family, trainer_class, type, type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName FROM creature_template WHERE entry = ? OR 1 = ?", 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_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", 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)) <= ? ORDER BY order_", CONNECTION_SYNCH);
@@ -208,7 +208,6 @@ WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc) const
stats.HealthScalingExpansion = HealthScalingExpansion;
stats.VignetteID = VignetteID;
stats.Class = unit_class;
stats.FadeRegionRadius = FadeRegionRadius;
stats.WidgetSetID = WidgetSetID;
stats.WidgetSetUnitConditionID = WidgetSetUnitConditionID;
@@ -395,7 +395,6 @@ struct TC_GAME_API CreatureTemplate
float ModExperience;
bool RacialLeader;
uint32 movementId;
float FadeRegionRadius;
int32 WidgetSetID;
int32 WidgetSetUnitConditionID;
bool RegenHealth;
+210 -113
View File
@@ -430,9 +430,9 @@ void ObjectMgr::LoadCreatureTemplates()
// "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, VehicleId, mingold, maxgold, AIName, MovementType, "
// 60 61 62 63 64 65 66 67 68
// "InhabitType, HoverHeight, HealthModifier, HealthModifierExtra, ManaModifier, ManaModifierExtra, ArmorModifier, DamageModifier, ExperienceModifier, "
// 69 70 71 72 73 74 75 76
// "RacialLeader, movementId, FadeRegionRadius, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, "
// 77
// 69 70 71 72 73 74 75
// "RacialLeader, movementId, WidgetSetID, WidgetSetUnitConditionID, RegenHealth, mechanic_immune_mask, flags_extra, "
// 76
// "ScriptName FROM creature_template WHERE entry = ? OR 1 = ?");
WorldDatabasePreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEMPLATE);
@@ -536,13 +536,12 @@ void ObjectMgr::LoadCreatureTemplate(Field* fields)
creatureTemplate.ModExperience = fields[68].GetFloat();
creatureTemplate.RacialLeader = fields[69].GetBool();
creatureTemplate.movementId = fields[70].GetUInt32();
creatureTemplate.FadeRegionRadius = fields[71].GetFloat();
creatureTemplate.WidgetSetID = fields[72].GetInt32();
creatureTemplate.WidgetSetUnitConditionID = fields[73].GetInt32();
creatureTemplate.RegenHealth = fields[74].GetBool();
creatureTemplate.MechanicImmuneMask = fields[75].GetUInt32();
creatureTemplate.flags_extra = fields[76].GetUInt32();
creatureTemplate.ScriptID = GetScriptId(fields[77].GetString());
creatureTemplate.WidgetSetID = fields[71].GetInt32();
creatureTemplate.WidgetSetUnitConditionID = fields[72].GetInt32();
creatureTemplate.RegenHealth = fields[73].GetBool();
creatureTemplate.MechanicImmuneMask = fields[74].GetUInt32();
creatureTemplate.flags_extra = fields[75].GetUInt32();
creatureTemplate.ScriptID = GetScriptId(fields[76].GetString());
}
void ObjectMgr::LoadCreatureTemplateModels()
@@ -4083,6 +4082,7 @@ void ObjectMgr::BuildPlayerLevelInfo(uint8 race, uint8 _class, uint8 level, Play
info->stats[STAT_STAMINA] += (lvl > 32 ? 2: (lvl > 4 ? 1: 0));
info->stats[STAT_AGILITY] += (lvl > 38 ? 2: (lvl > 8 && (lvl%2) ? 1: 0));
info->stats[STAT_INTELLECT] += (lvl > 38 ? 3: (lvl > 4 ? 1: 0));
break;
}
}
}
@@ -4100,35 +4100,35 @@ void ObjectMgr::LoadQuests()
_exclusiveQuestGroups.clear();
QueryResult result = WorldDatabase.Query("SELECT "
//0 1 2 3 4 5 6 7 8 9 10 11 12
"ID, QuestType, QuestLevel, ScalingFactionGroup, MaxScalingLevel, QuestPackageID, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, "
//13 14 15 16 17 18 19 20 21 22 23
"RewardMoney, RewardMoneyDifficulty, RewardMoneyMultiplier, RewardBonusMoney, RewardDisplaySpell1, RewardDisplaySpell2, RewardDisplaySpell3, RewardSpell, RewardHonor, RewardKillHonor, StartItem, "
//24 25 26 27 28 29
//0 1 2 3 4 5 6 7 8 9
"ID, QuestType, QuestPackageID, ContentTuningID, QuestSortID, QuestInfoID, SuggestedGroupNum, RewardNextQuest, RewardXPDifficulty, RewardXPMultiplier, "
//10 11 12 13 14 15 16 17
"RewardMoney, RewardMoneyDifficulty, RewardMoneyMultiplier, RewardBonusMoney, RewardSpell, RewardHonor, RewardKillHonor, StartItem, "
//18 19 20 21 22 23
"RewardArtifactXPDifficulty, RewardArtifactXPMultiplier, RewardArtifactCategoryID, Flags, FlagsEx, FlagsEx2, "
//30 31 32 33 34 35 36 37
//24 25 26 27 28 29 30 31
"RewardItem1, RewardAmount1, ItemDrop1, ItemDropQuantity1, RewardItem2, RewardAmount2, ItemDrop2, ItemDropQuantity2, "
//38 39 40 41 42 43 44 45
//32 33 34 35 36 37 38 39
"RewardItem3, RewardAmount3, ItemDrop3, ItemDropQuantity3, RewardItem4, RewardAmount4, ItemDrop4, ItemDropQuantity4, "
//46 47 48 49 50 51
//40 41 42 43 44 45
"RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemDisplayID1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemDisplayID2, "
//52 53 54 55 56 57
//46 47 48 49 50 51
"RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemDisplayID3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemDisplayID4, "
//58 59 60 61 62 63
//52 53 54 55 56 57
"RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemDisplayID5, RewardChoiceItemID6, RewardChoiceItemQuantity6, RewardChoiceItemDisplayID6, "
//64 65 66 67 68 69 70 71 72 73 74
//58 59 60 61 62 63 64 65 66 67 68
"POIContinent, POIx, POIy, POIPriority, RewardTitle, RewardArenaPoints, RewardSkillLineID, RewardNumSkillUps, PortraitGiver, PortraitGiverMount, PortraitTurnIn, "
//75 76 77 78 79 80 81 82
//69 70 71 72 73 74 75 76
"RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionCapIn1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionCapIn2, "
//83 84 85 86 87 88 89 90
//77 78 79 80 81 82 83 84
"RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionCapIn3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionCapIn4, "
//91 92 93 94 95
//85 86 87 88 89
"RewardFactionID5, RewardFactionValue5, RewardFactionOverride5, RewardFactionCapIn5, RewardFactionFlags, "
//96 97 98 99 100 101 102 103
//90 91 92 93 94 95 96 97
"RewardCurrencyID1, RewardCurrencyQty1, RewardCurrencyID2, RewardCurrencyQty2, RewardCurrencyID3, RewardCurrencyQty3, RewardCurrencyID4, RewardCurrencyQty4, "
//104 105 106 107 108 109 110 111 112
//98 99 100 101 102 103 104 105 106
"AcceptedSoundKitID, CompleteSoundKitID, AreaGroupID, TimeAllowed, AllowableRaces, TreasurePickerID, Expansion, ManagedWorldStateID, QuestSessionBonus, "
//113 114 115 116 117 118 119 120 121
//107 108 109 110 111 112 113 114 115
"LogTitle, LogDescription, QuestDescription, AreaDescription, PortraitGiverText, PortraitGiverName, PortraitTurnInText, PortraitTurnInName, QuestCompletionLog"
" FROM quest_template");
if (!result)
@@ -4159,8 +4159,15 @@ void ObjectMgr::LoadQuests()
QuestLoaderFunction LoaderFunction;
};
static std::vector<QuestLoaderHelper> const QuestLoaderHelpers =
// QuestID needs to be fields[0]
QuestLoaderHelper const QuestLoaderHelpers[] =
{
// 0 1 2 3 4 5 6
{ "QuestID, Type1, Type2, Type3, Type4, Type5, Type6", "quest_reward_choice_items", "", "reward choice items", &Quest::LoadRewardChoiceItems },
// 0 1 2
{ "QuestID, SpellID, PlayerConditionID", "quest_reward_display_spell", "ORDER BY QuestID ASC, Idx ASC", "reward display spells", &Quest::LoadRewardDisplaySpell },
// 0 1 2 3 4 5 6 7 8
{ "ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4", "quest_details", "", "details", &Quest::LoadQuestDetails },
@@ -4180,14 +4187,13 @@ void ObjectMgr::LoadQuests()
// 0 1
{ "QuestId, RewardMailSenderEntry", "quest_mail_sender", "", "mail sender entries", &Quest::LoadQuestMailSender },
// QuestID needs to be fields[0]
// 0 1 2 3 4 5 6 7 8 9
{ "QuestID, ID, Type, StorageIndex, ObjectID, Amount, Flags, Flags2, ProgressBarWeight, Description", "quest_objectives", "ORDER BY `Order` ASC, StorageIndex ASC", "quest objectives", &Quest::LoadQuestObjective }
};
for (QuestLoaderHelper const& loader : QuestLoaderHelpers)
{
QueryResult result = WorldDatabase.PQuery("SELECT %s FROM %s", loader.QueryFields, loader.TableName, loader.QueryExtra);
QueryResult result = WorldDatabase.PQuery("SELECT %s FROM %s %s", loader.QueryFields, loader.TableName, loader.QueryExtra);
if (!result)
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest %s. DB table `%s` is empty.", loader.TableDesc, loader.TableName);
@@ -4315,10 +4321,10 @@ void ObjectMgr::LoadQuests()
}
}
if (qinfo->_minLevel == -1 || qinfo->_minLevel > DEFAULT_MAX_LEVEL)
if (qinfo->_contentTuningID && !sContentTuningStore.LookupEntry(qinfo->_contentTuningID))
{
TC_LOG_ERROR("sql.sql", "Quest %u should be disabled because `MinLevel` = %i", qinfo->GetQuestId(), int32(qinfo->_minLevel));
// no changes needed, sending -1 in SMSG_QUEST_QUERY_RESPONSE is valid
TC_LOG_ERROR("sql.sql", "Quest %u has `ContentTuningID` = %u but content tuning with this id does not exist.",
qinfo->GetQuestId(), qinfo->_contentTuningID);
}
// client quest log visual (area case)
@@ -4603,27 +4609,43 @@ void ObjectMgr::LoadQuests()
for (uint8 j = 0; j < QUEST_REWARD_CHOICES_COUNT; ++j)
{
uint32 id = qinfo->RewardChoiceItemId[j];
if (id)
if (uint32 id = qinfo->RewardChoiceItemId[j])
{
if (!sObjectMgr->GetItemTemplate(id))
switch (qinfo->RewardChoiceItemType[j])
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.",
qinfo->GetQuestId(), j+1, id, id);
qinfo->RewardChoiceItemId[j] = 0; // no changes, quest will not reward this
case LootItemType::Item:
if (!sObjectMgr->GetItemTemplate(id))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = %u but item with entry %u does not exist, quest will not reward this item.",
qinfo->GetQuestId(), j + 1, id, id);
qinfo->RewardChoiceItemId[j] = 0; // no changes, quest will not reward this
}
break;
case LootItemType::Currency:
if (!sCurrencyTypesStore.HasRecord(id))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = %u but currency with id %u does not exist, quest will not reward this currency.",
qinfo->GetQuestId(), j + 1, id, id);
qinfo->RewardChoiceItemId[j] = 0; // no changes, quest will not reward this
}
break;
default:
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemType%d` = %u but it is not a valid item type, reward removed.",
qinfo->GetQuestId(), j + 1, uint32(qinfo->RewardChoiceItemType[j]));
qinfo->RewardChoiceItemId[j] = 0;
break;
}
if (!qinfo->RewardChoiceItemCount[j])
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = %u but `RewardChoiceItemCount%d` = 0, quest can't be done.",
qinfo->GetQuestId(), j+1, id, j+1);
// no changes, quest can't be done
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = %u but `RewardChoiceItemCount%d` = 0.",
qinfo->GetQuestId(), j + 1, id, j + 1);
}
}
else if (qinfo->RewardChoiceItemCount[j]>0)
else if (qinfo->RewardChoiceItemCount[j] > 0)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardChoiceItemId%d` = 0 but `RewardChoiceItemCount%d` = %u.",
qinfo->GetQuestId(), j+1, j+1, qinfo->RewardChoiceItemCount[j]);
qinfo->GetQuestId(), j + 1, j + 1, qinfo->RewardChoiceItemCount[j]);
// no changes, quest ignore this data
}
}
@@ -4678,28 +4700,6 @@ void ObjectMgr::LoadQuests()
}
}
for (uint32 i = 0; i < QUEST_REWARD_DISPLAY_SPELL_COUNT; ++i)
{
if (qinfo->RewardDisplaySpell[i])
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell[i], DIFFICULTY_NONE);
if (!spellInfo)
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell%u` = %u but spell %u does not exist, spell removed as display reward.",
qinfo->GetQuestId(), i, qinfo->RewardDisplaySpell[i], qinfo->RewardDisplaySpell[i]);
qinfo->RewardDisplaySpell[i] = 0; // no spell reward will display for this quest
}
else if (!SpellMgr::IsSpellValid(spellInfo))
{
TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell%u` = %u but spell %u is broken, quest will not have a spell reward.",
qinfo->GetQuestId(), i, qinfo->RewardDisplaySpell[i], qinfo->RewardDisplaySpell[i]);
qinfo->RewardDisplaySpell[i] = 0; // no spell reward will display for this quest
}
}
}
if (qinfo->_rewardSpell > 0)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->_rewardSpell, DIFFICULTY_NONE);
@@ -7892,41 +7892,33 @@ void ObjectMgr::LoadQuestPOI()
uint32 count = 0;
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
QueryResult result = WorldDatabase.Query("SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, UiMapID, Priority, Flags, WorldEffectID, PlayerConditionID, SpawnTrackingID, AlwaysAllowMergingBlobs FROM quest_poi order by QuestID, Idx1");
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
QueryResult result = WorldDatabase.Query("SELECT QuestID, BlobIndex, Idx1, ObjectiveIndex, QuestObjectiveID, QuestObjectID, MapID, UiMapID, Priority, Flags, WorldEffectID, PlayerConditionID, NavigationPlayerConditionID, SpawnTrackingID, AlwaysAllowMergingBlobs FROM quest_poi order by QuestID, Idx1");
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 quest POI definitions. DB table `quest_poi` is empty.");
return;
}
// 0 1 2 3
QueryResult points = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2");
// 0 1 2 3 4
QueryResult pointsResult = WorldDatabase.Query("SELECT QuestID, Idx1, X, Y, Z FROM quest_poi_points ORDER BY QuestID DESC, Idx1, Idx2");
std::vector<std::vector<std::vector<QuestPOIBlobPoint>>> POIs;
std::unordered_map<int32, std::map<int32, std::vector<QuestPOIBlobPoint>>> allPoints;
if (points)
if (pointsResult)
{
// The first result should have the highest questId
Field* fields = points->Fetch();
uint32 questIdMax = fields[0].GetInt32();
POIs.resize(questIdMax + 1);
do
{
fields = points->Fetch();
Field* fields = pointsResult->Fetch();
int32 QuestID = fields[0].GetInt32();
int32 Idx1 = fields[1].GetInt32();
int32 X = fields[2].GetInt32();
int32 Y = fields[3].GetInt32();
int32 x = fields[2].GetInt32();
int32 y = fields[3].GetInt32();
int32 z = fields[4].GetInt32();
if (int32(POIs[QuestID].size()) <= Idx1 + 1)
POIs[QuestID].resize(Idx1 + 10);
QuestPOIBlobPoint point(X, Y);
POIs[QuestID][Idx1].push_back(point);
} while (points->NextRow());
allPoints[QuestID][Idx1].emplace_back(x, y, z);
} while (pointsResult->NextRow());
}
do
@@ -7945,23 +7937,28 @@ void ObjectMgr::LoadQuestPOI()
int32 flags = fields[9].GetInt32();
int32 worldEffectID = fields[10].GetInt32();
int32 playerConditionID = fields[11].GetInt32();
int32 spawnTrackingID = fields[12].GetInt32();
bool alwaysAllowMergingBlobs = fields[13].GetBool();
int32 navigationPlayerConditionID = fields[12].GetInt32();
int32 spawnTrackingID = fields[13].GetInt32();
bool alwaysAllowMergingBlobs = fields[14].GetBool();
if (!sObjectMgr->GetQuestTemplate(questID))
TC_LOG_ERROR("sql.sql", "`quest_poi` quest id (%u) Idx1 (%u) does not exist in `quest_template`", questID, idx1);
if (questID < int32(POIs.size()) && idx1 < int32(POIs[questID].size()))
if (std::map<int32, std::vector<QuestPOIBlobPoint>>* blobs = Trinity::Containers::MapGetValuePtr(allPoints, questID))
{
QuestPOIData& poiData = _questPOIStore[questID];
poiData.QuestID = questID;
poiData.Blobs.emplace_back(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapID, priority, flags,
worldEffectID, playerConditionID, spawnTrackingID, std::move(POIs[questID][idx1]), alwaysAllowMergingBlobs);
if (std::vector<QuestPOIBlobPoint>* points = Trinity::Containers::MapGetValuePtr(*blobs, idx1))
{
QuestPOIData& poiData = _questPOIStore[questID];
poiData.QuestID = questID;
poiData.Blobs.emplace_back(blobIndex, objectiveIndex, questObjectiveID, questObjectID, mapID, uiMapID, priority, flags,
worldEffectID, playerConditionID, navigationPlayerConditionID, spawnTrackingID, std::move(*points), alwaysAllowMergingBlobs);
++count;
continue;
}
}
else
TC_LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest %i POI id %i", questID, blobIndex);
++count;
TC_LOG_ERROR("sql.sql", "Table quest_poi references unknown quest points for quest %i POI id %i", questID, blobIndex);
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u quest POI definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
@@ -10384,6 +10381,8 @@ void ObjectMgr::LoadPlayerChoices()
uint32 itemRewardCount = 0;
uint32 currencyRewardCount = 0;
uint32 factionRewardCount = 0;
uint32 itemChoiceRewardCount = 0;
uint32 mawPowersCount = 0;
do
{
@@ -10401,7 +10400,11 @@ void ObjectMgr::LoadPlayerChoices()
} while (choices->NextRow());
if (QueryResult responses = WorldDatabase.Query("SELECT ChoiceId, ResponseId, ChoiceArtFileId, Flags, WidgetSetID, UiTextureAtlasElementID, SoundKitID, GroupID, Answer, Header, SubHeader, ButtonTemplate, Description, Confirmation, RewardQuestID FROM playerchoice_response ORDER BY `Index` ASC"))
// 0 1 2 3 4 5
if (QueryResult responses = WorldDatabase.Query("SELECT ChoiceId, ResponseId, ResponseIdentifier, ChoiceArtFileId, Flags, WidgetSetID, "
// 6 7 8 9 10 11 12 13 14 15 16
"UiTextureAtlasElementID, SoundKitID, GroupID, UiTextureKitID, Answer, Header, SubHeader, ButtonTemplate, Description, Confirmation, RewardQuestID "
"FROM playerchoice_response ORDER BY `Index` ASC"))
{
do
{
@@ -10421,20 +10424,22 @@ void ObjectMgr::LoadPlayerChoices()
PlayerChoiceResponse& response = choice->Responses.back();
response.ResponseId = responseId;
response.ChoiceArtFileId = fields[2].GetInt32();
response.Flags = fields[3].GetInt32();
response.WidgetSetID = fields[4].GetUInt32();
response.UiTextureAtlasElementID = fields[5].GetUInt32();
response.SoundKitID = fields[6].GetUInt32();
response.GroupID = fields[7].GetUInt8();
response.Answer = fields[8].GetString();
response.Header = fields[9].GetString();
response.SubHeader = fields[10].GetString();
response.ButtonTooltip = fields[11].GetString();
response.Description = fields[12].GetString();
response.Confirmation = fields[13].GetString();
if (!fields[14].IsNull())
response.RewardQuestID = fields[14].GetUInt32();
response.ResponseId = fields[2].GetUInt16();
response.ChoiceArtFileId = fields[3].GetInt32();
response.Flags = fields[4].GetInt32();
response.WidgetSetID = fields[5].GetUInt32();
response.UiTextureAtlasElementID = fields[6].GetUInt32();
response.SoundKitID = fields[7].GetUInt32();
response.GroupID = fields[8].GetUInt8();
response.UiTextureKitID = fields[9].GetInt32();
response.Answer = fields[10].GetString();
response.Header = fields[11].GetString();
response.SubHeader = fields[12].GetString();
response.ButtonTooltip = fields[13].GetString();
response.Description = fields[14].GetString();
response.Confirmation = fields[15].GetString();
if (!fields[16].IsNull())
response.RewardQuestID = fields[16].GetUInt32();
++responseCount;
@@ -10548,6 +10553,7 @@ void ObjectMgr::LoadPlayerChoices()
}
responseItr->Reward->Items.emplace_back(itemId, std::move(bonusListIds), quantity);
++itemRewardCount;
} while (rewards->NextRow());
}
@@ -10593,6 +10599,7 @@ void ObjectMgr::LoadPlayerChoices()
}
responseItr->Reward->Currency.emplace_back(currencyId, quantity);
++currencyRewardCount;
} while (rewards->NextRow());
}
@@ -10638,12 +10645,102 @@ void ObjectMgr::LoadPlayerChoices()
}
responseItr->Reward->Faction.emplace_back(factionId, quantity);
++factionRewardCount;
} while (rewards->NextRow());
}
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " player choices, %u responses, %u rewards, %u item rewards, %u currency rewards and %u faction rewards in %u ms.",
_playerChoices.size(), responseCount, rewardCount, itemRewardCount, currencyRewardCount, factionRewardCount, GetMSTimeDiffToNow(oldMSTime));
if (QueryResult rewards = WorldDatabase.Query("SELECT ChoiceId, ResponseId, ItemId, BonusListIDs, Quantity FROM playerchoice_response_reward_item_choice ORDER BY `Index` ASC"))
{
do
{
Field* fields = rewards->Fetch();
int32 choiceId = fields[0].GetInt32();
int32 responseId = fields[1].GetInt32();
uint32 itemId = fields[2].GetUInt32();
Tokenizer bonusListIDsTok(fields[3].GetString(), ' ');
std::vector<int32> bonusListIds;
for (char const* token : bonusListIDsTok)
bonusListIds.push_back(int32(atol(token)));
int32 quantity = fields[4].GetInt32();
PlayerChoice* choice = Trinity::Containers::MapGetValuePtr(_playerChoices, choiceId);
if (!choice)
{
TC_LOG_ERROR("sql.sql", "Table `playerchoice_response_reward_item_choice` references non-existing ChoiceId: %d (ResponseId: %d), skipped", choiceId, responseId);
continue;
}
auto responseItr = std::find_if(choice->Responses.begin(), choice->Responses.end(),
[responseId](PlayerChoiceResponse const& playerChoiceResponse) { return playerChoiceResponse.ResponseId == responseId; });
if (responseItr == choice->Responses.end())
{
TC_LOG_ERROR("sql.sql", "Table `playerchoice_response_reward_item_choice` references non-existing ResponseId: %d for ChoiceId %d, skipped", responseId, choiceId);
continue;
}
if (!responseItr->Reward)
{
TC_LOG_ERROR("sql.sql", "Table `playerchoice_response_reward_item_choice` references non-existing player choice reward for ChoiceId %d, ResponseId: %d, skipped",
choiceId, responseId);
continue;
}
if (!GetItemTemplate(itemId))
{
TC_LOG_ERROR("sql.sql", "Table `playerchoice_response_reward_item_choice` references non-existing item %u for ChoiceId %d, ResponseId: %d, skipped",
itemId, choiceId, responseId);
continue;
}
responseItr->Reward->ItemChoices.emplace_back(itemId, std::move(bonusListIds), quantity);
++itemChoiceRewardCount;
} while (rewards->NextRow());
}
if (QueryResult mawPowersResult = WorldDatabase.Query("SELECT ChoiceId, ResponseId, TypeArtFileID, Rarity, RarityColor, SpellID, MaxStacks FROM playerchoice_response_maw_power"))
{
do
{
Field* fields = mawPowersResult->Fetch();
int32 choiceId = fields[0].GetInt32();
int32 responseId = fields[1].GetInt32();
PlayerChoice* choice = Trinity::Containers::MapGetValuePtr(_playerChoices, choiceId);
if (!choice)
{
TC_LOG_ERROR("sql.sql", "Table `playerchoice_response_maw_power` references non-existing ChoiceId: %d (ResponseId: %d), skipped", choiceId, responseId);
continue;
}
auto responseItr = std::find_if(choice->Responses.begin(), choice->Responses.end(),
[responseId](PlayerChoiceResponse const& playerChoiceResponse)
{
return playerChoiceResponse.ResponseId == responseId;
});
if (responseItr == choice->Responses.end())
{
TC_LOG_ERROR("sql.sql", "Table `playerchoice_response_maw_power` references non-existing ResponseId: %d for ChoiceId %d, skipped", responseId, choiceId);
continue;
}
responseItr->MawPower.emplace();
PlayerChoiceResponseMawPower& mawPower = responseItr->MawPower.get();
mawPower.TypeArtFileID = fields[2].GetInt32();
mawPower.Rarity = fields[3].GetInt32();
mawPower.RarityColor = fields[4].GetUInt32();
mawPower.SpellID = fields[5].GetInt32();
mawPower.MaxStacks = fields[6].GetInt32();
++mawPowersCount;
} while (mawPowersResult->NextRow());
}
TC_LOG_INFO("server.loading", ">> Loaded " SZFMTD " player choices, %u responses, %u rewards, %u item rewards, %u currency rewards, %u faction rewards, %u item choice rewards and %u maw powers in %u ms.",
_playerChoices.size(), responseCount, rewardCount, itemRewardCount, currencyRewardCount, factionRewardCount, itemChoiceRewardCount, mawPowersCount, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadPlayerChoicesLocale()
+21 -8
View File
@@ -722,7 +722,7 @@ struct QuestPOIBlobPoint
int32 Z;
QuestPOIBlobPoint() : X(0), Y(0), Z(0) { }
QuestPOIBlobPoint(int32 x, int32 y) : X(x), Y(y), Z(0) { }
QuestPOIBlobPoint(int32 x, int32 y, int32 z) : X(x), Y(y), Z(z) { }
};
struct QuestPOIBlobData
@@ -745,10 +745,10 @@ struct QuestPOIBlobData
QuestPOIBlobData() : BlobIndex(0), ObjectiveIndex(0), QuestObjectiveID(0), QuestObjectID(0), MapID(0), UiMapID(0), Priority(0), Flags(0), WorldEffectID(0),
PlayerConditionID(0), NavigationPlayerConditionID(0), SpawnTrackingID(0), AlwaysAllowMergingBlobs(false) { }
QuestPOIBlobData(int32 blobIndex, int32 objectiveIndex, int32 questObjectiveID, int32 questObjectID, int32 mapID, int32 uiMapID, int32 priority,
int32 flags, int32 worldEffectID, int32 playerConditionID, int32 spawnTrackingID, std::vector<QuestPOIBlobPoint> points,
int32 flags, int32 worldEffectID, int32 playerConditionID, int32 navigationPlayerConditionID, int32 spawnTrackingID, std::vector<QuestPOIBlobPoint> points,
bool alwaysAllowMergingBlobs) : BlobIndex(blobIndex), ObjectiveIndex(objectiveIndex), QuestObjectiveID(questObjectiveID),
QuestObjectID(questObjectID), MapID(mapID), UiMapID(uiMapID), Priority(priority), Flags(flags), WorldEffectID(worldEffectID),
PlayerConditionID(playerConditionID), NavigationPlayerConditionID(0), SpawnTrackingID(spawnTrackingID), Points(std::move(points)),
PlayerConditionID(playerConditionID), NavigationPlayerConditionID(navigationPlayerConditionID), SpawnTrackingID(spawnTrackingID), Points(std::move(points)),
AlwaysAllowMergingBlobs(alwaysAllowMergingBlobs) { }
};
@@ -828,17 +828,29 @@ struct PlayerChoiceResponseReward
std::vector<PlayerChoiceResponseRewardItem> Items;
std::vector<PlayerChoiceResponseRewardEntry> Currency;
std::vector<PlayerChoiceResponseRewardEntry> Faction;
std::vector<PlayerChoiceResponseRewardItem> ItemChoices;
};
struct PlayerChoiceResponseMawPower
{
int32 TypeArtFileID = 0;
int32 Rarity = 0;
uint32 RarityColor = 0;
int32 SpellID = 0;
int32 MaxStacks = 0;
};
struct PlayerChoiceResponse
{
int32 ResponseId;
int32 ChoiceArtFileId;
int32 Flags;
uint32 WidgetSetID;
int32 ResponseId = 0;
uint16 ResponseIdentifier = 0;
int32 ChoiceArtFileId = 0;
int32 Flags = 0;
uint32 WidgetSetID = 0;
uint32 UiTextureAtlasElementID = 0;
uint32 SoundKitID = 0;
uint8 GroupID;
uint8 GroupID = 0;
int32 UiTextureKitID = 0;
std::string Answer;
std::string Header;
std::string SubHeader;
@@ -847,6 +859,7 @@ struct PlayerChoiceResponse
std::string Confirmation;
Optional<PlayerChoiceResponseReward> Reward;
Optional<uint32> RewardQuestID;
Optional<PlayerChoiceResponseMawPower> MawPower;
};
struct PlayerChoice
+109 -83
View File
@@ -16,6 +16,7 @@
*/
#include "QuestDef.h"
#include "ConditionMgr.h"
#include "DB2Stores.h"
#include "Field.h"
#include "GameTables.h"
@@ -23,47 +24,42 @@
#include "ObjectMgr.h"
#include "Player.h"
#include "QuestPackets.h"
#include "SpellMgr.h"
#include "World.h"
Quest::Quest(Field* questRecord)
{
_id = questRecord[0].GetUInt32();
_type = questRecord[1].GetUInt8();
_level = questRecord[2].GetInt32();
_scalingFactionGroup = questRecord[3].GetInt32();
_maxScalingLevel = questRecord[4].GetInt32();
_packageID = questRecord[5].GetUInt32();
_minLevel = questRecord[6].GetInt32();
_questSortID = questRecord[7].GetInt16();
_questInfoID = questRecord[8].GetUInt16();
_suggestedPlayers = questRecord[9].GetUInt8();
_nextQuestInChain = questRecord[10].GetUInt32();
_rewardXPDifficulty = questRecord[11].GetUInt32();
_rewardXPMultiplier = questRecord[12].GetFloat();
_rewardMoney = questRecord[13].GetUInt32();
_rewardMoneyDifficulty = questRecord[14].GetUInt32();
_rewardMoneyMultiplier = questRecord[15].GetFloat();
_rewardBonusMoney = questRecord[16].GetUInt32();
for (uint32 i = 0; i < QUEST_REWARD_DISPLAY_SPELL_COUNT; ++i)
RewardDisplaySpell[i] = questRecord[17 + i].GetUInt32();
_rewardSpell = questRecord[20].GetUInt32();
_rewardHonor = questRecord[21].GetUInt32();
_rewardKillHonor = questRecord[22].GetUInt32();
_sourceItemId = questRecord[23].GetUInt32();
_rewardArtifactXPDifficulty = questRecord[24].GetUInt32();
_rewardArtifactXPMultiplier = questRecord[25].GetFloat();
_rewardArtifactCategoryID = questRecord[26].GetUInt32();
_flags = questRecord[27].GetUInt32();
_flagsEx = questRecord[28].GetUInt32();
_flagsEx2 = questRecord[29].GetUInt32();
_packageID = questRecord[2].GetUInt32();
_contentTuningID = questRecord[3].GetInt32();
_questSortID = questRecord[4].GetInt16();
_questInfoID = questRecord[5].GetUInt16();
_suggestedPlayers = questRecord[6].GetUInt8();
_nextQuestInChain = questRecord[7].GetUInt32();
_rewardXPDifficulty = questRecord[8].GetUInt32();
_rewardXPMultiplier = questRecord[9].GetFloat();
_rewardMoney = questRecord[10].GetUInt32();
_rewardMoneyDifficulty = questRecord[11].GetUInt32();
_rewardMoneyMultiplier = questRecord[12].GetFloat();
_rewardBonusMoney = questRecord[13].GetUInt32();
_rewardSpell = questRecord[14].GetUInt32();
_rewardHonor = questRecord[15].GetUInt32();
_rewardKillHonor = questRecord[16].GetUInt32();
_sourceItemId = questRecord[17].GetUInt32();
_rewardArtifactXPDifficulty = questRecord[18].GetUInt32();
_rewardArtifactXPMultiplier = questRecord[19].GetFloat();
_rewardArtifactCategoryID = questRecord[20].GetUInt32();
_flags = questRecord[21].GetUInt32();
_flagsEx = questRecord[22].GetUInt32();
_flagsEx2 = questRecord[23].GetUInt32();
for (uint32 i = 0; i < QUEST_ITEM_DROP_COUNT; ++i)
{
RewardItemId[i] = questRecord[30 + i * 4].GetUInt32();
RewardItemCount[i] = questRecord[31 + i * 4].GetUInt32();
ItemDrop[i] = questRecord[32 + i * 4].GetUInt32();
ItemDropQuantity[i] = questRecord[33 + i * 4].GetUInt32();
RewardItemId[i] = questRecord[24 + i * 4].GetUInt32();
RewardItemCount[i] = questRecord[25 + i * 4].GetUInt32();
ItemDrop[i] = questRecord[26 + i * 4].GetUInt32();
ItemDropQuantity[i] = questRecord[27 + i * 4].GetUInt32();
if (RewardItemId[i])
++_rewItemsCount;
@@ -71,66 +67,92 @@ Quest::Quest(Field* questRecord)
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
RewardChoiceItemId[i] = questRecord[46 + i * 3].GetUInt32();
RewardChoiceItemCount[i] = questRecord[47 + i * 3].GetUInt32();
RewardChoiceItemDisplayId[i] = questRecord[48 + i * 3].GetUInt32();
RewardChoiceItemId[i] = questRecord[40 + i * 3].GetUInt32();
RewardChoiceItemCount[i] = questRecord[41 + i * 3].GetUInt32();
RewardChoiceItemDisplayId[i] = questRecord[42 + i * 3].GetUInt32();
if (RewardChoiceItemId[i])
++_rewChoiceItemsCount;
}
_poiContinent = questRecord[64].GetUInt32();
_poix = questRecord[65].GetFloat();
_poiy = questRecord[66].GetFloat();
_poiPriority = questRecord[67].GetUInt32();
_poiContinent = questRecord[58].GetUInt32();
_poix = questRecord[59].GetFloat();
_poiy = questRecord[60].GetFloat();
_poiPriority = questRecord[61].GetUInt32();
_rewardTitleId = questRecord[68].GetUInt32();
_rewardArenaPoints = questRecord[69].GetUInt32();
_rewardSkillId = questRecord[70].GetUInt32();
_rewardSkillPoints = questRecord[71].GetUInt32();
_rewardTitleId = questRecord[62].GetUInt32();
_rewardArenaPoints = questRecord[63].GetUInt32();
_rewardSkillId = questRecord[64].GetUInt32();
_rewardSkillPoints = questRecord[65].GetUInt32();
_questGiverPortrait = questRecord[72].GetUInt32();
_questGiverPortraitMount = questRecord[73].GetUInt32();
_questTurnInPortrait = questRecord[74].GetUInt32();
_questGiverPortrait = questRecord[66].GetUInt32();
_questGiverPortraitMount = questRecord[67].GetUInt32();
_questTurnInPortrait = questRecord[68].GetUInt32();
for (uint32 i = 0; i < QUEST_REWARD_REPUTATIONS_COUNT; ++i)
{
RewardFactionId[i] = questRecord[75 + i * 4].GetUInt32();
RewardFactionValue[i] = questRecord[76 + i * 4].GetInt32();
RewardFactionOverride[i] = questRecord[77 + i * 4].GetInt32();
RewardFactionCapIn[i] = questRecord[78 + i * 4].GetUInt32();
RewardFactionId[i] = questRecord[69 + i * 4].GetUInt32();
RewardFactionValue[i] = questRecord[70 + i * 4].GetInt32();
RewardFactionOverride[i] = questRecord[71 + i * 4].GetInt32();
RewardFactionCapIn[i] = questRecord[72 + i * 4].GetUInt32();
}
_rewardReputationMask = questRecord[95].GetUInt32();
_rewardReputationMask = questRecord[89].GetUInt32();
for (uint32 i = 0; i < QUEST_REWARD_CURRENCY_COUNT; ++i)
{
RewardCurrencyId[i] = questRecord[96 + i * 2].GetUInt32();
RewardCurrencyCount[i] = questRecord[97 + i * 2].GetUInt32();
RewardCurrencyId[i] = questRecord[90 + i * 2].GetUInt32();
RewardCurrencyCount[i] = questRecord[91 + i * 2].GetUInt32();
if (RewardCurrencyId[i])
++_rewCurrencyCount;
}
_soundAccept = questRecord[104].GetUInt32();
_soundTurnIn = questRecord[105].GetUInt32();
_areaGroupID = questRecord[106].GetUInt32();
_limitTime = questRecord[107].GetUInt32();
_allowableRaces.RawValue = questRecord[108].GetUInt64();
_treasurePickerID = questRecord[109].GetInt32();
_expansion = questRecord[110].GetInt32();
_managedWorldStateID = questRecord[111].GetInt32();
_questSessionBonus = questRecord[112].GetInt32();
_soundAccept = questRecord[98].GetUInt32();
_soundTurnIn = questRecord[99].GetUInt32();
_areaGroupID = questRecord[100].GetUInt32();
_limitTime = questRecord[101].GetUInt32();
_allowableRaces.RawValue = questRecord[102].GetUInt64();
_treasurePickerID = questRecord[103].GetInt32();
_expansion = questRecord[104].GetInt32();
_managedWorldStateID = questRecord[105].GetInt32();
_questSessionBonus = questRecord[106].GetInt32();
_logTitle = questRecord[113].GetString();
_logDescription = questRecord[114].GetString();
_questDescription = questRecord[115].GetString();
_areaDescription = questRecord[116].GetString();
_portraitGiverText = questRecord[117].GetString();
_portraitGiverName = questRecord[118].GetString();
_portraitTurnInText = questRecord[119].GetString();
_portraitTurnInName = questRecord[120].GetString();
_questCompletionLog = questRecord[121].GetString();
_logTitle = questRecord[107].GetString();
_logDescription = questRecord[108].GetString();
_questDescription = questRecord[109].GetString();
_areaDescription = questRecord[111].GetString();
_portraitGiverText = questRecord[111].GetString();
_portraitGiverName = questRecord[112].GetString();
_portraitTurnInText = questRecord[113].GetString();
_portraitTurnInName = questRecord[114].GetString();
_questCompletionLog = questRecord[115].GetString();
}
void Quest::LoadRewardDisplaySpell(Field* fields)
{
uint32 spellId = fields[1].GetUInt32();
uint32 playerConditionId = fields[2].GetUInt32();
if (!sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))
{
TC_LOG_ERROR("sql.sql", "Table `quest_reward_display_spell` has non-existing Spell (%u) set for quest %u. Skipped.", spellId, fields[0].GetUInt32());
return;
}
if (playerConditionId && !sPlayerConditionStore.LookupEntry(playerConditionId))
{
TC_LOG_ERROR("sql.sql", "Table `quest_reward_display_spell` has non-existing PlayerCondition (%u) set for quest %u. Set to 0.", spellId, fields[0].GetUInt32());
playerConditionId = 0;
}
RewardDisplaySpell.emplace_back(spellId, playerConditionId);
}
void Quest::LoadRewardChoiceItems(Field* fields)
{
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
RewardChoiceItemType[i] = LootItemType(fields[1 + i].GetUInt8());
}
void Quest::LoadQuestDetails(Field* fields)
@@ -262,7 +284,7 @@ uint32 Quest::XPValue(Player const* player) const
if (questLevel != player->getLevel())
multiplier = sXpGameTable.GetRow(std::min<int32>(player->getLevel(), questLevel))->Divisor / sXpGameTable.GetRow(player->getLevel())->Divisor;
int32 diffFactor = 2 * (questLevel + (_level == -1 ? 0 : 5) - player->getLevel()) + 10;
int32 diffFactor = 2 * (questLevel + (GetQuestLevel() == -1 ? 0 : 5) - player->getLevel()) + 10;
if (diffFactor < 1)
diffFactor = 1;
else if (diffFactor > 10)
@@ -301,8 +323,17 @@ void Quest::BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player
rewards.ArtifactCategoryID = GetArtifactCategoryId();
rewards.Title = GetRewTitle();
rewards.FactionFlags = GetRewardReputationMask();
for (uint32 i = 0; i < QUEST_REWARD_DISPLAY_SPELL_COUNT; ++i)
rewards.SpellCompletionDisplayID[i] = RewardDisplaySpell[i];
auto displaySpellItr = rewards.SpellCompletionDisplayID.begin();
for (QuestRewardDisplaySpell displaySpell : RewardDisplaySpell)
{
if (PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(displaySpell.PlayerConditionId))
if (!ConditionMgr::IsPlayerMeetingCondition(player, playerCondition))
continue;
*displaySpellItr = displaySpell.SpellId;
if (++displaySpellItr == rewards.SpellCompletionDisplayID.end())
break;
}
rewards.SpellCompletionID = GetRewSpell();
rewards.SkillLineID = GetRewardSkillId();
@@ -311,6 +342,7 @@ void Quest::BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player
for (uint32 i = 0; i < QUEST_REWARD_CHOICES_COUNT; ++i)
{
rewards.ChoiceItems[i].LootItemType = RewardChoiceItemType[i];
rewards.ChoiceItems[i].Item.ItemID = RewardChoiceItemId[i];
rewards.ChoiceItems[i].Quantity = RewardChoiceItemCount[i];
}
@@ -452,16 +484,10 @@ WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
}
}
if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS))
AddQuestLevelToTitle(response.Info.LogTitle, GetQuestLevel());
response.Info.QuestID = GetQuestId();
response.Info.QuestType = GetQuestType();
response.Info.QuestLevel = GetQuestLevel();
response.Info.QuestScalingFactionGroup = GetQuestScalingFactionGroup();
response.Info.QuestMaxScalingLevel = GetQuestMaxScalingLevel();
response.Info.ContentTuningID = GetContentTuningId();
response.Info.QuestPackageID = GetQuestPackageID();
response.Info.QuestMinLevel = GetMinLevel();
response.Info.QuestSortID = GetZoneOrSort();
response.Info.QuestInfoID = GetQuestInfoID();
response.Info.SuggestedGroupNum = GetSuggestedPlayers();
@@ -475,8 +501,8 @@ WorldPacket Quest::BuildQueryData(LocaleConstant loc) const
response.Info.RewardMoneyDifficulty = GetRewMoneyDifficulty();
response.Info.RewardMoneyMultiplier = GetMoneyMultiplier();
response.Info.RewardBonusMoney = GetRewMoneyMaxLevel();
for (uint8 i = 0; i < QUEST_REWARD_DISPLAY_SPELL_COUNT; ++i)
response.Info.RewardDisplaySpell[i] = RewardDisplaySpell[i];
for (QuestRewardDisplaySpell displaySpell : RewardDisplaySpell)
response.Info.RewardDisplaySpell.push_back({ int32(displaySpell.SpellId), int32(displaySpell.PlayerConditionId) });
response.Info.RewardSpell = GetRewSpell();
+43 -31
View File
@@ -27,6 +27,7 @@
#include <vector>
class Player;
enum class LootItemType : uint8;
namespace WorldPackets
{
@@ -337,6 +338,15 @@ struct QuestObjective
typedef std::vector<QuestObjective> QuestObjectives;
struct QuestRewardDisplaySpell
{
QuestRewardDisplaySpell() : SpellId(0), PlayerConditionId(0) { }
QuestRewardDisplaySpell(uint32 spellId, uint32 playerConditionId) : SpellId(spellId), PlayerConditionId(playerConditionId) { }
uint32 SpellId;
uint32 PlayerConditionId;
};
// This Quest class provides a convenient way to access a few pretotaled (cached) quest details,
// all base quest information, and any utility functions such as generating the amount of
// xp to give
@@ -347,7 +357,9 @@ class TC_GAME_API Quest
friend class PlayerMenu;
public:
// Loading data. All queries are in ObjectMgr::LoadQuests()
Quest(Field* questRecord);
explicit Quest(Field* questRecord);
void LoadRewardDisplaySpell(Field* fields);
void LoadRewardChoiceItems(Field* fields);
void LoadQuestDetails(Field* fields);
void LoadQuestRequestItems(Field* fields);
void LoadQuestOfferReward(Field* fields);
@@ -366,17 +378,19 @@ class TC_GAME_API Quest
bool HasSpecialFlag(uint32 flag) const { return (_specialFlags & flag) != 0; }
void SetSpecialFlag(uint32 flag) { _specialFlags |= flag; }
// DEPRECATED
int32 GetMinLevel() const { return 0; }
int32 GetQuestLevel() const { return 0; }
int32 GetQuestScalingFactionGroup() const { return 0; }
int32 GetQuestMaxScalingLevel() const { return 0; }
// table data accessors:
uint32 GetQuestId() const { return _id; }
uint32 GetQuestType() const { return _type; }
uint32 GetQuestPackageID() const { return _packageID; }
uint32 GetContentTuningId() const { return _contentTuningID; }
int32 GetZoneOrSort() const { return _questSortID; }
int32 GetMinLevel() const { return _minLevel; }
uint32 GetMaxLevel() const { return _maxLevel; }
int32 GetQuestLevel() const { return _level; }
int32 GetQuestScalingFactionGroup() const { return _scalingFactionGroup; }
int32 GetQuestMaxScalingLevel() const { return _maxScalingLevel; }
int32 GetContentTuningId() const { return 0; }
uint32 GetQuestInfoID() const { return _questInfoID; }
uint32 GetAllowableClasses() const { return _allowableClasses; }
Trinity::RaceMask<uint64> GetAllowableRaces() const { return _allowableRaces; }
@@ -465,25 +479,26 @@ class TC_GAME_API Quest
bool CanIncreaseRewardedQuestCounters() const;
// multiple values
uint32 RewardDisplaySpell[QUEST_REWARD_DISPLAY_SPELL_COUNT] = { };
uint32 RewardItemId[QUEST_REWARD_ITEM_COUNT] = { };
uint32 RewardItemCount[QUEST_REWARD_ITEM_COUNT] = { };
uint32 ItemDrop[QUEST_ITEM_DROP_COUNT] = { };
uint32 ItemDropQuantity[QUEST_ITEM_DROP_COUNT] = { };
uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT] = { };
uint32 RewardChoiceItemCount[QUEST_REWARD_CHOICES_COUNT] = { };
uint32 RewardChoiceItemDisplayId[QUEST_REWARD_CHOICES_COUNT] = { };
uint32 RewardFactionId[QUEST_REWARD_REPUTATIONS_COUNT] = { };
int32 RewardFactionValue[QUEST_REWARD_REPUTATIONS_COUNT] = { };
int32 RewardFactionOverride[QUEST_REWARD_REPUTATIONS_COUNT] = { };
uint32 RewardFactionCapIn[QUEST_REWARD_REPUTATIONS_COUNT] = { };
uint32 RewardCurrencyId[QUEST_REWARD_CURRENCY_COUNT] = { };
uint32 RewardCurrencyCount[QUEST_REWARD_CURRENCY_COUNT] = { };
QuestObjectives Objectives = { };
uint32 DetailsEmote[QUEST_EMOTE_COUNT] = { };
uint32 DetailsEmoteDelay[QUEST_EMOTE_COUNT] = { };
uint32 OfferRewardEmote[QUEST_EMOTE_COUNT] = { };
uint32 OfferRewardEmoteDelay[QUEST_EMOTE_COUNT] = { };
std::vector<QuestRewardDisplaySpell> RewardDisplaySpell;
std::array<uint32, QUEST_REWARD_ITEM_COUNT> RewardItemId = { };
std::array<uint32, QUEST_REWARD_ITEM_COUNT> RewardItemCount = { };
std::array<uint32, QUEST_ITEM_DROP_COUNT> ItemDrop = { };
std::array<uint32, QUEST_ITEM_DROP_COUNT> ItemDropQuantity = { };
std::array<LootItemType, QUEST_REWARD_CHOICES_COUNT> RewardChoiceItemType = { };
std::array<uint32, QUEST_REWARD_CHOICES_COUNT> RewardChoiceItemId = { };
std::array<uint32, QUEST_REWARD_CHOICES_COUNT> RewardChoiceItemCount = { };
std::array<uint32, QUEST_REWARD_CHOICES_COUNT> RewardChoiceItemDisplayId = { };
std::array<uint32, QUEST_REWARD_REPUTATIONS_COUNT> RewardFactionId = { };
std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> RewardFactionValue = { };
std::array<int32, QUEST_REWARD_REPUTATIONS_COUNT> RewardFactionOverride = { };
std::array<uint32, QUEST_REWARD_REPUTATIONS_COUNT> RewardFactionCapIn = { };
std::array<uint32, QUEST_REWARD_CURRENCY_COUNT> RewardCurrencyId = { };
std::array<uint32, QUEST_REWARD_CURRENCY_COUNT> RewardCurrencyCount = { };
QuestObjectives Objectives;
std::array<uint32, QUEST_EMOTE_COUNT> DetailsEmote = { };
std::array<uint32, QUEST_EMOTE_COUNT> DetailsEmoteDelay = { };
std::array<uint32, QUEST_EMOTE_COUNT> OfferRewardEmote = { };
std::array<uint32, QUEST_EMOTE_COUNT> OfferRewardEmoteDelay = { };
uint32 GetRewChoiceItemsCount() const { return _rewChoiceItemsCount; }
uint32 GetRewItemsCount() const { return _rewItemsCount; }
@@ -498,7 +513,7 @@ class TC_GAME_API Quest
void BuildQuestRewards(WorldPackets::Quest::QuestRewards& rewards, Player* player) const;
std::vector<uint32> DependentPreviousQuests;
WorldPacket QueryData[TOTAL_LOCALES];
std::array<WorldPacket, TOTAL_LOCALES> QueryData;
private:
uint32 _rewChoiceItemsCount = 0;
@@ -509,11 +524,8 @@ class TC_GAME_API Quest
// wdb data (quest query response)
uint32 _id = 0;
uint32 _type = 0;
int32 _level = 0;
int32 _scalingFactionGroup = 0;
int32 _maxScalingLevel = 0;
uint32 _packageID = 0;
int32 _minLevel = 0;
uint32 _contentTuningID = 0;
int32 _questSortID = 0;
uint32 _questInfoID = 0;
uint32 _suggestedPlayers = 0;
@@ -600,7 +612,7 @@ struct QuestStatusData
{
QuestStatus Status = QUEST_STATUS_NONE;
uint32 Timer = 0;
std::vector<int32> ObjectiveData = { };
std::vector<int32> ObjectiveData;
};
#endif
+2 -1
View File
@@ -18,6 +18,7 @@
#include "Scenario.h"
#include "InstanceSaveMgr.h"
#include "Log.h"
#include "LootMgr.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Player.h"
@@ -57,7 +58,7 @@ void Scenario::CompleteStep(ScenarioStepEntry const* step)
if (Quest const* quest = sObjectMgr->GetQuestTemplate(step->RewardQuestID))
for (ObjectGuid guid : _players)
if (Player* player = ObjectAccessor::FindPlayer(guid))
player->RewardQuest(quest, 0, nullptr, false);
player->RewardQuest(quest, LootItemType::Item, 0, nullptr, false);
if (step->IsBonusObjective())
return;
+24 -22
View File
@@ -16,6 +16,7 @@
*/
#include "ScenarioMgr.h"
#include "Containers.h"
#include "DatabaseEnv.h"
#include "DB2Stores.h"
#include "InstanceScenario.h"
@@ -147,41 +148,35 @@ void ScenarioMgr::LoadScenarioPOI()
uint32 count = 0;
// 0 1 2 3 4 5 6 7 8
QueryResult result = WorldDatabase.Query("SELECT CriteriaTreeID, BlobIndex, Idx1, MapID, UiMapID, Priority, Flags, WorldEffectID, PlayerConditionID FROM scenario_poi ORDER BY CriteriaTreeID, Idx1");
// 0 1 2 3 4 5 6 7 8 9
QueryResult result = WorldDatabase.Query("SELECT CriteriaTreeID, BlobIndex, Idx1, MapID, UiMapID, Priority, Flags, WorldEffectID, PlayerConditionID, NavigationPlayerConditionID FROM scenario_poi ORDER BY CriteriaTreeID, Idx1");
if (!result)
{
TC_LOG_ERROR("server.loading", ">> Loaded 0 scenario POI definitions. DB table `scenario_poi` is empty.");
return;
}
// 0 1 2 3
QueryResult points = WorldDatabase.Query("SELECT CriteriaTreeID, Idx1, X, Y FROM scenario_poi_points ORDER BY CriteriaTreeID DESC, Idx1, Idx2");
// 0 1 2 3 4
QueryResult pointsResult = WorldDatabase.Query("SELECT CriteriaTreeID, Idx1, X, Y, Z FROM scenario_poi_points ORDER BY CriteriaTreeID DESC, Idx1, Idx2");
std::vector<std::vector<std::vector<ScenarioPOIPoint>>> POIs;
std::unordered_map<int32, std::map<int32, std::vector<ScenarioPOIPoint>>> allPoints;
if (points)
if (pointsResult)
{
// The first result should have the highest criteriaTreeId
Field* fields = points->Fetch();
uint32 criteriaTreeIdMax = fields[0].GetInt32();
POIs.resize(criteriaTreeIdMax + 1);
Field* fields = pointsResult->Fetch();
do
{
fields = points->Fetch();
fields = pointsResult->Fetch();
int32 CriteriaTreeID = fields[0].GetInt32();
int32 Idx1 = fields[1].GetInt32();
int32 X = fields[2].GetInt32();
int32 Y = fields[3].GetInt32();
int32 Z = fields[4].GetInt32();
if (int32(POIs[CriteriaTreeID].size()) <= Idx1 + 1)
POIs[CriteriaTreeID].resize(Idx1 + 10);
ScenarioPOIPoint point(X, Y);
POIs[CriteriaTreeID][Idx1].push_back(point);
} while (points->NextRow());
allPoints[CriteriaTreeID][Idx1].emplace_back(X, Y, Z);
} while (pointsResult->NextRow());
}
do
@@ -197,16 +192,23 @@ void ScenarioMgr::LoadScenarioPOI()
int32 flags = fields[6].GetInt32();
int32 worldEffectID = fields[7].GetInt32();
int32 playerConditionID = fields[8].GetInt32();
int32 navigationPlayerConditionID = fields[9].GetInt32();
if (!sCriteriaMgr->GetCriteriaTree(criteriaTreeID))
TC_LOG_ERROR("sql.sql", "`scenario_poi` CriteriaTreeID (%u) Idx1 (%u) does not correspond to a valid criteria tree", criteriaTreeID, idx1);
if (criteriaTreeID < int32(POIs.size()) && idx1 < int32(POIs[criteriaTreeID].size()))
_scenarioPOIStore[criteriaTreeID].emplace_back(blobIndex, mapID, uiMapID, priority, flags, worldEffectID, playerConditionID, POIs[criteriaTreeID][idx1]);
else
TC_LOG_ERROR("server.loading", "Table scenario_poi references unknown scenario poi points for criteria tree id %i POI id %i", criteriaTreeID, blobIndex);
if (std::map<int32, std::vector<ScenarioPOIPoint>>* blobs = Trinity::Containers::MapGetValuePtr(allPoints, criteriaTreeID))
{
if (std::vector<ScenarioPOIPoint>* points = Trinity::Containers::MapGetValuePtr(*blobs, idx1))
{
_scenarioPOIStore[criteriaTreeID].emplace_back(blobIndex, mapID, uiMapID, priority, flags, worldEffectID, playerConditionID, navigationPlayerConditionID, std::move(*points));
++count;
continue;
}
}
TC_LOG_ERROR("server.loading", "Table scenario_poi references unknown scenario poi points for criteria tree id %i POI id %i", criteriaTreeID, blobIndex);
++count;
} while (result->NextRow());
TC_LOG_INFO("server.loading", ">> Loaded %u scenario POI definitions in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
+3 -3
View File
@@ -68,7 +68,7 @@ struct ScenarioPOIPoint
int32 Z;
ScenarioPOIPoint() : X(0), Y(0), Z(0) { }
ScenarioPOIPoint(int32 x, int32 y) : X(x), Y(y), Z(0) { }
ScenarioPOIPoint(int32 x, int32 y, int32 z) : X(x), Y(y), Z(z) { }
};
struct ScenarioPOI
@@ -86,9 +86,9 @@ struct ScenarioPOI
ScenarioPOI() : BlobIndex(0), MapID(0), UiMapID(0), Priority(0), Flags(0), WorldEffectID(0), PlayerConditionID(0), NavigationPlayerConditionID(0) { }
ScenarioPOI(int32 blobIndex, int32 mapID, int32 uiMapID, int32 priority, int32 flags, int32 worldEffectID,
int32 playerConditionID, std::vector<ScenarioPOIPoint> points) :
int32 playerConditionID, int32 navigationPlayerConditionID, std::vector<ScenarioPOIPoint> points) :
BlobIndex(blobIndex), MapID(mapID), UiMapID(uiMapID), Priority(priority), Flags(flags), WorldEffectID(worldEffectID),
PlayerConditionID(playerConditionID), NavigationPlayerConditionID(0), Points(std::move(points)) { }
PlayerConditionID(playerConditionID), NavigationPlayerConditionID(navigationPlayerConditionID), Points(std::move(points)) { }
ScenarioPOI(ScenarioPOI&& scenarioPOI) = default;
};
+1
View File
@@ -334,6 +334,7 @@ public:
x = data.Points.front().X;
y = data.Points.front().Y;
z = data.Points.front().Z;
}
else
{