aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/characters_database.sql28
-rw-r--r--sql/updates/characters/master/2022_10_03_02_characters.sql1
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp5
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h4
-rw-r--r--src/server/game/Instances/InstanceScript.cpp7
-rw-r--r--src/server/game/Instances/InstanceScript.h2
-rw-r--r--src/server/game/Scenarios/InstanceScenario.cpp161
-rw-r--r--src/server/game/Scenarios/InstanceScenario.h9
-rw-r--r--src/server/game/Scenarios/ScenarioMgr.cpp2
-rw-r--r--src/server/game/Scenarios/ScenarioMgr.h4
10 files changed, 62 insertions, 161 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index 8fed83db228..f730f61f659 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -2587,31 +2587,6 @@ LOCK TABLES `instance` WRITE;
UNLOCK TABLES;
--
--- Table structure for table `instance_scenario_progress`
---
-
-DROP TABLE IF EXISTS `instance_scenario_progress`;
-/*!40101 SET @saved_cs_client = @@character_set_client */;
-/*!50503 SET character_set_client = utf8mb4 */;
-CREATE TABLE `instance_scenario_progress` (
- `id` int unsigned NOT NULL,
- `criteria` int unsigned NOT NULL,
- `counter` bigint unsigned NOT NULL,
- `date` bigint NOT NULL DEFAULT '0',
- PRIMARY KEY (`id`,`criteria`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-/*!40101 SET character_set_client = @saved_cs_client */;
-
---
--- Dumping data for table `instance_scenario_progress`
---
-
-LOCK TABLES `instance_scenario_progress` WRITE;
-/*!40000 ALTER TABLE `instance_scenario_progress` DISABLE KEYS */;
-/*!40000 ALTER TABLE `instance_scenario_progress` ENABLE KEYS */;
-UNLOCK TABLES;
-
---
-- Table structure for table `item_instance`
--
@@ -3629,7 +3604,8 @@ INSERT INTO `updates` VALUES
('2022_08_21_00_characters.sql','1D75688392FBDA18CD8494F32CF682DCB49642EC','ARCHIVED','2022-08-21 00:02:03',0),
('2022_09_18_00_characters.sql','A7DF0C1F0E074F3E63A6CDD0AF873A1F3DC33B29','RELEASED','2022-09-18 21:48:42',0),
('2022_10_03_00_characters.sql','7B062787230D9158A622EB4AFE7FA6D18AB47BB3','RELEASED','2022-10-03 22:32:58',0),
-('2022_10_03_01_characters.sql','7CF58BD9CC366301CC992017028568C8774C4BC2','RELEASED','2022-10-03 22:36:38',0);
+('2022_10_03_01_characters.sql','7CF58BD9CC366301CC992017028568C8774C4BC2','RELEASED','2022-10-03 22:36:38',0),
+('2022_10_03_02_characters.sql','33135AB3132943F15F4849A16EC5EFEA402F24F6','RELEASED','2022-10-03 22:38:27',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/characters/master/2022_10_03_02_characters.sql b/sql/updates/characters/master/2022_10_03_02_characters.sql
new file mode 100644
index 00000000000..0bc7b663012
--- /dev/null
+++ b/sql/updates/characters/master/2022_10_03_02_characters.sql
@@ -0,0 +1 @@
+DROP TABLE IF EXISTS `instance_scenario_progress`;
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 766f1bc620b..723e85311b5 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -748,11 +748,6 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_BLACKMARKET_AUCTIONS, "UPDATE blackmarket_auctions SET currentBid = ?, time = ?, numBids = ?, bidder = ? WHERE marketId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_BLACKMARKET_AUCTIONS, "INSERT INTO blackmarket_auctions (marketId, currentBid, time, numBids, bidder) VALUES (?, ?, ?, ? ,?)", CONNECTION_ASYNC);
- // Scenario
- PrepareStatement(CHAR_SEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE, "SELECT criteria, counter, date FROM instance_scenario_progress WHERE id = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_DEL_SCENARIO_INSTANCE_CRITERIA, "DELETE FROM instance_scenario_progress WHERE id = ? AND criteria = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_INS_SCENARIO_INSTANCE_CRITERIA, "INSERT INTO instance_scenario_progress (id, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
-
// Spell Location
PrepareStatement(CHAR_SEL_CHARACTER_AURA_STORED_LOCATIONS, "SELECT Spell, MapId, PositionX, PositionY, PositionZ, Orientation FROM character_aura_stored_location WHERE Guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_CHARACTER_AURA_STORED_LOCATIONS_BY_GUID, "DELETE FROM character_aura_stored_location WHERE Guid = ?", CONNECTION_ASYNC);
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index 588c0dccf60..26ec666a5d7 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -619,10 +619,6 @@ enum CharacterDatabaseStatements : uint32
CHAR_UPD_BLACKMARKET_AUCTIONS,
CHAR_INS_BLACKMARKET_AUCTIONS,
- CHAR_SEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE,
- CHAR_DEL_SCENARIO_INSTANCE_CRITERIA,
- CHAR_INS_SCENARIO_INSTANCE_CRITERIA,
-
CHAR_SEL_CHARACTER_AURA_STORED_LOCATIONS,
CHAR_DEL_CHARACTER_AURA_STORED_LOCATIONS_BY_GUID,
CHAR_DEL_CHARACTER_AURA_STORED_LOCATION,
diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp
index 9c1956c4dfb..3d3a8cf3384 100644
--- a/src/server/game/Instances/InstanceScript.cpp
+++ b/src/server/game/Instances/InstanceScript.cpp
@@ -80,12 +80,6 @@ InstanceScript::~InstanceScript()
{
}
-void InstanceScript::SaveToDB()
-{
- if (InstanceScenario* scenario = instance->GetInstanceScenario())
- scenario->SaveToDB();
-}
-
bool InstanceScript::IsEncounterInProgress() const
{
for (std::vector<BossInfo>::const_iterator itr = bosses.begin(); itr != bosses.end(); ++itr)
@@ -438,7 +432,6 @@ bool InstanceScript::SetBossState(uint32 id, EncounterState state)
}
bossInfo->state = state;
- SaveToDB();
if (dungeonEncounter)
instance->UpdateInstanceLock({ dungeonEncounter, id, state });
}
diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h
index a296877d123..121e243033c 100644
--- a/src/server/game/Instances/InstanceScript.h
+++ b/src/server/game/Instances/InstanceScript.h
@@ -360,8 +360,6 @@ class TC_GAME_API InstanceScript : public ZoneScript
void LoadDungeonEncounterData(uint32 bossId, std::array<uint32, MAX_DUNGEON_ENCOUNTERS_PER_BOSS> const& dungeonEncounterIds);
void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* source);
- void SaveToDB();
-
std::string headers;
std::vector<BossInfo> bosses;
std::vector<PersistentInstanceScriptValueBase*> _persistentScriptValues;
diff --git a/src/server/game/Scenarios/InstanceScenario.cpp b/src/server/game/Scenarios/InstanceScenario.cpp
index 30336a6b8f9..31f7414be0f 100644
--- a/src/server/game/Scenarios/InstanceScenario.cpp
+++ b/src/server/game/Scenarios/InstanceScenario.cpp
@@ -16,20 +16,20 @@
*/
#include "InstanceScenario.h"
-#include "DatabaseEnv.h"
+#include "Containers.h"
#include "DB2Stores.h"
#include "GameTime.h"
-#include "Log.h"
+#include "InstanceScript.h"
#include "Map.h"
+#include "ObjectMgr.h"
#include "Player.h"
+#include "ScenarioMgr.h"
+#include "StringFormat.h"
-// TODO
-// Do not save to db except for scenario type 3 (SCENARIO_TYPE_USE_DUNGEON_DISPLAY)
-
-InstanceScenario::InstanceScenario(Map const* map, ScenarioData const* scenarioData) : Scenario(scenarioData), _map(map)
+InstanceScenario::InstanceScenario(InstanceMap const* map, ScenarioData const* scenarioData) : Scenario(scenarioData), _map(map)
{
ASSERT(_map);
- LoadInstanceData(_map->GetInstanceId());
+ LoadInstanceData();
Map::PlayerList const& players = map->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
@@ -37,124 +37,67 @@ InstanceScenario::InstanceScenario(Map const* map, ScenarioData const* scenarioD
SendScenarioState(player);
}
-void InstanceScenario::SaveToDB()
+void InstanceScenario::LoadInstanceData()
{
- if (_criteriaProgress.empty())
- return;
-
- DifficultyEntry const* difficultyEntry = sDifficultyStore.LookupEntry(_map->GetDifficultyID());
- if (!difficultyEntry || difficultyEntry->Flags & DIFFICULTY_FLAG_CHALLENGE_MODE) // Map should have some sort of "CanSave" boolean that returns whether or not the map is savable. (Challenge modes cannot be saved for example)
+ InstanceScript const* instanceScript = _map->GetInstanceScript();
+ if (!instanceScript)
return;
- uint32 id = _map->GetInstanceId();
- if (!id)
- {
- TC_LOG_DEBUG("scenario", "Scenario::SaveToDB: Can not save scenario progress without an instance save. Map::GetInstanceId() did not return an instance save.");
- return;
- }
+ std::vector<CriteriaTree const*> criteriaTrees;
- CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
- for (auto iter = _criteriaProgress.begin(); iter != _criteriaProgress.end(); ++iter)
+ CriteriaList const& killCreatureCriteria = sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(CriteriaType::KillCreature, _data->Entry->ID);
+ if (!killCreatureCriteria.empty())
{
- if (!iter->second.Changed)
- continue;
-
- Criteria const* criteria = sCriteriaMgr->GetCriteria(iter->first);
- switch (CriteriaType(criteria->Entry->Type))
+ if (std::vector<InstanceSpawnGroupInfo> const* spawnGroups = sObjectMgr->GetInstanceSpawnGroupsForMap(_map->GetId()))
{
- // Blizzard only appears to store creature kills and dungeon encounters
- case CriteriaType::KillCreature:
- case CriteriaType::DefeatDungeonEncounter:
- break;
- default:
- continue;
- }
-
- if (iter->second.Counter)
- {
- CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_SCENARIO_INSTANCE_CRITERIA);
- stmt->setUInt32(0, id);
- stmt->setUInt32(1, iter->first);
- trans->Append(stmt);
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_SCENARIO_INSTANCE_CRITERIA);
- stmt->setUInt32(0, id);
- stmt->setUInt32(1, iter->first);
- stmt->setUInt64(2, iter->second.Counter);
- stmt->setInt64(3, iter->second.Date);
- trans->Append(stmt);
- }
-
- iter->second.Changed = false;
- }
-
- CharacterDatabase.CommitTransaction(trans);
-}
-
-void InstanceScenario::LoadInstanceData(uint32 instanceId)
-{
- CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE);
- stmt->setUInt32(0, instanceId);
-
- PreparedQueryResult result = CharacterDatabase.Query(stmt);
- if (result)
- {
- CharacterDatabaseTransaction trans = CharacterDatabase.BeginTransaction();
- time_t now = GameTime::GetGameTime();
-
- std::vector<CriteriaTree const*> criteriaTrees;
- do
- {
- Field* fields = result->Fetch();
- uint32 id = fields[0].GetUInt32();
- uint64 counter = fields[1].GetUInt64();
- time_t date = fields[2].GetInt64();
-
- Criteria const* criteria = sCriteriaMgr->GetCriteria(id);
- if (!criteria)
+ std::unordered_map<uint32, uint64> despawnedCreatureCountsById;
+ for (InstanceSpawnGroupInfo const& spawnGroup : *spawnGroups)
{
- // Removing non-existing criteria data for all instances
- TC_LOG_ERROR("criteria.instancescenarios", "Removing scenario criteria %u data from the table `instance_scenario_progress`.", id);
-
- stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_SCENARIO_INSTANCE_CRITERIA);
- stmt->setUInt32(0, instanceId);
- stmt->setUInt32(1, uint32(id));
- trans->Append(stmt);
- continue;
- }
+ if (instanceScript->GetBossState(spawnGroup.BossStateId) != DONE)
+ continue;
- if (criteria->Entry->StartTimer && time_t(date + criteria->Entry->StartTimer) < now)
- continue;
+ bool isDespawned = !((1 << DONE) & spawnGroup.BossStates) || (spawnGroup.Flags & InstanceSpawnGroupInfo::FLAG_BLOCK_SPAWN);
+ if (isDespawned)
+ for (auto const& [spawnGroupId, spawn] : sObjectMgr->GetSpawnMetadataForGroup(spawnGroup.SpawnGroupId))
+ if (SpawnData const* spawnData = spawn->ToSpawnData())
+ ++despawnedCreatureCountsById[spawnData->id];
+ }
- switch (CriteriaType(criteria->Entry->Type))
+ for (Criteria const* criteria : killCreatureCriteria)
{
- // Blizzard appears to only stores creatures killed progress for unknown reasons. Either technical shortcoming or intentional
- case CriteriaType::KillCreature:
- case CriteriaType::DefeatDungeonEncounter:
- break;
- default:
- continue;
+ // count creatures in despawned spawn groups
+ if (uint64* progress = Trinity::Containers::MapGetValuePtr(despawnedCreatureCountsById, criteria->Entry->Asset.CreatureID))
+ {
+ SetCriteriaProgress(criteria, *progress, nullptr, PROGRESS_SET);
+
+ if (CriteriaTreeList const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(criteria->ID))
+ for (CriteriaTree const* tree : *trees)
+ criteriaTrees.push_back(tree);
+ }
}
+ }
+ }
- SetCriteriaProgress(criteria, counter, nullptr, PROGRESS_SET);
+ for (Criteria const* criteria : sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(CriteriaType::DefeatDungeonEncounter, _data->Entry->ID))
+ {
+ if (!instanceScript->IsEncounterCompleted(criteria->Entry->Asset.DungeonEncounterID))
+ continue;
- if (CriteriaTreeList const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(criteria->ID))
- for (CriteriaTree const* tree : *trees)
- criteriaTrees.push_back(tree);
- }
- while (result->NextRow());
+ SetCriteriaProgress(criteria, 1, nullptr, PROGRESS_SET);
- CharacterDatabase.CommitTransaction(trans);
+ if (CriteriaTreeList const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(criteria->ID))
+ for (CriteriaTree const* tree : *trees)
+ criteriaTrees.push_back(tree);
+ }
- for (CriteriaTree const* tree : criteriaTrees)
- {
- ScenarioStepEntry const* step = tree->ScenarioStep;
- if (!step)
- continue;
+ for (CriteriaTree const* tree : criteriaTrees)
+ {
+ ScenarioStepEntry const* step = tree->ScenarioStep;
+ if (!step)
+ continue;
- if (IsCompletedCriteriaTree(tree))
- SetStepState(step, SCENARIO_STEP_DONE);
- }
+ if (IsCompletedCriteriaTree(tree))
+ SetStepState(step, SCENARIO_STEP_DONE);
}
}
diff --git a/src/server/game/Scenarios/InstanceScenario.h b/src/server/game/Scenarios/InstanceScenario.h
index e3c84c28ba5..8bd9385ea61 100644
--- a/src/server/game/Scenarios/InstanceScenario.h
+++ b/src/server/game/Scenarios/InstanceScenario.h
@@ -20,21 +20,20 @@
#include "Scenario.h"
-class Map;
+class InstanceMap;
class TC_GAME_API InstanceScenario : public Scenario
{
public:
- InstanceScenario(Map const* map, ScenarioData const* scenarioData);
+ InstanceScenario(InstanceMap const* map, ScenarioData const* scenarioData);
- void SaveToDB();
- void LoadInstanceData(uint32 instanceId);
+ void LoadInstanceData();
protected:
std::string GetOwnerInfo() const override;
void SendPacket(WorldPacket const* data) const override;
- Map const* _map;
+ InstanceMap const* _map;
};
#endif // InstanceScenario_h__
diff --git a/src/server/game/Scenarios/ScenarioMgr.cpp b/src/server/game/Scenarios/ScenarioMgr.cpp
index 36152089b2a..0d081403b92 100644
--- a/src/server/game/Scenarios/ScenarioMgr.cpp
+++ b/src/server/game/Scenarios/ScenarioMgr.cpp
@@ -30,7 +30,7 @@ ScenarioMgr* ScenarioMgr::Instance()
return &instance;
}
-InstanceScenario* ScenarioMgr::CreateInstanceScenario(Map const* map, TeamId team) const
+InstanceScenario* ScenarioMgr::CreateInstanceScenario(InstanceMap const* map, TeamId team) const
{
auto dbDataItr = _scenarioDBData.find(std::make_pair(map->GetId(), map->GetDifficultyID()));
// No scenario registered for this map and difficulty in the database
diff --git a/src/server/game/Scenarios/ScenarioMgr.h b/src/server/game/Scenarios/ScenarioMgr.h
index 4445879d42c..46359461f07 100644
--- a/src/server/game/Scenarios/ScenarioMgr.h
+++ b/src/server/game/Scenarios/ScenarioMgr.h
@@ -25,8 +25,8 @@
#include <unordered_map>
#include <vector>
+class InstanceMap;
class InstanceScenario;
-class Map;
struct ScenarioEntry;
struct ScenarioStepEntry;
@@ -105,7 +105,7 @@ private:
public:
static ScenarioMgr* Instance();
- InstanceScenario* CreateInstanceScenario(Map const* map, TeamId team) const;
+ InstanceScenario* CreateInstanceScenario(InstanceMap const* map, TeamId team) const;
void LoadDBData();
void LoadDB2Data();