Core/Misc: First set of required db changes for 9.0
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -334,6 +334,7 @@ public:
|
||||
|
||||
x = data.Points.front().X;
|
||||
y = data.Points.front().Y;
|
||||
z = data.Points.front().Z;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user