aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Scenarios/InstanceScenario.cpp
blob: 09eaf707dcf4b144b48e43c8c137db74d84d3b17 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program. If not, see <http://www.gnu.org/licenses/>.
 */

#include "InstanceScenario.h"
#include "Containers.h"
#include "DB2Stores.h"
#include "GameTime.h"
#include "InstanceScript.h"
#include "Map.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "ScenarioMgr.h"
#include "StringFormat.h"

InstanceScenario::InstanceScenario(InstanceMap* map, ScenarioData const* scenarioData) : Scenario(map, scenarioData)
{
    ASSERT(_map);
    LoadInstanceData();

    Map::PlayerList const& players = map->GetPlayers();
    for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
        if (Player* player = itr->GetSource()->ToPlayer())
            SendScenarioState(player);
}

void InstanceScenario::LoadInstanceData()
{
    InstanceScript const* instanceScript = _map->ToInstanceMap()->GetInstanceScript();
    if (!instanceScript)
        return;

    std::vector<CriteriaTree const*> criteriaTrees;

    CriteriaList const& killCreatureCriteria = sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(CriteriaType::KillCreature, _data->Entry->ID);
    if (!killCreatureCriteria.empty())
    {
        if (std::vector<InstanceSpawnGroupInfo> const* spawnGroups = sObjectMgr->GetInstanceSpawnGroupsForMap(_map->GetId()))
        {
            std::unordered_map<uint32, uint64> despawnedCreatureCountsById;
            for (InstanceSpawnGroupInfo const& spawnGroup : *spawnGroups)
            {
                if (instanceScript->GetBossState(spawnGroup.BossStateId) != DONE)
                    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];
            }

            for (Criteria const* criteria : killCreatureCriteria)
            {
                // 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);
                }
            }
        }
    }

    for (Criteria const* criteria : sCriteriaMgr->GetScenarioCriteriaByTypeAndScenario(CriteriaType::DefeatDungeonEncounter, _data->Entry->ID))
    {
        if (!instanceScript->IsEncounterCompleted(criteria->Entry->Asset.DungeonEncounterID))
            continue;

        SetCriteriaProgress(criteria, 1, nullptr, PROGRESS_SET);

        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;

        if (IsCompletedCriteriaTree(tree))
            SetStepState(step, SCENARIO_STEP_DONE);
    }
}

std::string InstanceScenario::GetOwnerInfo() const
{
    return Trinity::StringFormat("Instance ID {}", _map->GetInstanceId());
}

void InstanceScenario::SendPacket(WorldPacket const* data) const
{
    _map->SendToPlayers(data);
}