aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Battlegrounds/BattlegroundScript.cpp
blob: a3bee1d6b382e85b3516cbdd622f714674d0dafa (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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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 "BattlegroundScript.h"
#include "BattlegroundMgr.h"
#include "Creature.h"
#include "GameEventSender.h"
#include "GameObject.h"
#include "Log.h"
#include "Map.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "ScriptMgr.h"
#include "WorldStateMgr.h"

BattlegroundScript::BattlegroundScript(BattlegroundMap* map) : battlegroundMap(map), battleground(map->GetBG())
{
#ifdef TRINITY_API_USE_DYNAMIC_LINKING
    BattlegroundScriptTemplate const* scriptTemplate = sBattlegroundMgr->FindBattlegroundScriptTemplate(battlegroundMap->GetId(), battlegroundMap->GetBG()->GetTypeID());
    if (!scriptTemplate)
        return;

    auto const scriptname = sObjectMgr->GetScriptName(scriptTemplate->ScriptId);
    ASSERT(!scriptname.empty());
    // Acquire a strong reference from the script module
    // to keep it loaded until this object is destroyed.
    module_reference = sScriptMgr->AcquireModuleReferenceOfScriptName(scriptname);
#endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING
}

Team BattlegroundScript::GetPrematureWinner()
{
    Team winner = TEAM_OTHER;
    if (battleground->GetPlayersCountByTeam(ALLIANCE) >= battleground->GetMinPlayersPerTeam())
        winner = ALLIANCE;
    else if (battleground->GetPlayersCountByTeam(HORDE) >= battleground->GetMinPlayersPerTeam())
        winner = HORDE;

    return winner;
}

void BattlegroundScript::TriggerGameEvent(uint32 gameEventId, WorldObject* source, WorldObject* target)
{
    ProcessEvent(target, gameEventId, source);
    GameEvents::TriggerForMap(gameEventId, battlegroundMap, source, target);
    for (auto const& [playerGuid, _] : battleground->GetPlayers())
        if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
            GameEvents::TriggerForPlayer(gameEventId, player);
}

void BattlegroundScript::UpdateWorldState(int32 worldStateId, int32 value, bool hidden) const
{
    sWorldStateMgr->SetValue(worldStateId, value, hidden, battlegroundMap);
}

ArenaScript::ArenaScript(BattlegroundMap* map) : BattlegroundScript(map)
{

}

GameObject* ArenaScript::CreateObject(uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, GOState goState) const
{
    QuaternionData rot(rotation0, rotation1, rotation2, rotation3);
    // Temporally add safety check for bad spawns and send log (object rotations need to be rechecked in sniff)
    if (!rotation0 && !rotation1 && !rotation2 && !rotation3)
    {
        TC_LOG_DEBUG("bg.battleground", "Battleground::AddObject: gameoobject [entry: {}] for BG (map: {}) has zeroed rotation fields, "
            "orientation used temporally, but please fix the spawn", entry, battlegroundMap->GetId());

        rot = QuaternionData::fromEulerAnglesZYX(o, 0.f, 0.f);
    }

    // Must be created this way, adding to godatamap would add it to the base map of the instance
    // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
    // So we must create it specific for this instance
    GameObject* go = GameObject::CreateGameObject(entry, battlegroundMap, Position(x, y, z, o), rot, 255, goState);
    if (!go)
    {
        TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: {}) for BG (map: {}, instance id: {})!",
            entry, battlegroundMap->GetId(), battleground->GetInstanceID());
        return nullptr;
    }

    if (!battlegroundMap->AddToMap(go))
    {
        delete go;
        return nullptr;
    }

    return go;
}

Creature* ArenaScript::CreateCreature(uint32 entry, float x, float y, float z, float o) const
{
    if (!sObjectMgr->GetCreatureTemplate(entry))
    {
        TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: creature template (entry: {}) does not exist for BG (map: {}, instance id: {})!",
            entry, battlegroundMap->GetId(), battleground->GetInstanceID());
        return nullptr;
    }

    Position pos = { x, y, z, o };

    Creature* creature = Creature::CreateCreature(entry, battlegroundMap, pos);
    if (!creature)
    {
        TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: {}) for BG (map: {}, instance id: {})!",
            entry, battlegroundMap->GetId(), battleground->GetInstanceID());
        return nullptr;
    }

    creature->SetHomePosition(pos);

    if (!battlegroundMap->AddToMap(creature))
    {
        delete creature;
        return nullptr;
    }

    return creature;
}