summaryrefslogtreecommitdiff
path: root/src/server/game/Reputation/ReputationMgr.h
blob: 79d855ec05cb431441a67db90da40d557e22d62b (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/*
 * This file is part of the AzerothCore 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/>.
 */

#ifndef __ACORE_REPUTATION_MGR_H
#define __ACORE_REPUTATION_MGR_H

#include "DatabaseEnvFwd.h"
#include "DBCStructure.h"
#include "Language.h"
#include "SharedDefines.h"
#include <map>

constexpr std::array<uint32, MAX_REPUTATION_RANK> ReputationRankStrIndex =
{
    LANG_REP_HATED,
    LANG_REP_HOSTILE,
    LANG_REP_UNFRIENDLY,
    LANG_REP_NEUTRAL,
    LANG_REP_FRIENDLY,
    LANG_REP_HONORED,
    LANG_REP_REVERED,
    LANG_REP_EXALTED
};

typedef uint32 RepListID;
struct FactionState
{
    uint32 ID;
    RepListID ReputationListID;
    int32  Standing;
    uint8 Flags;
    bool needSend;
    bool needSave;
    bool roundedUp;
};

typedef std::map<RepListID, FactionState> FactionStateList;
typedef std::map<uint32, ReputationRank> ForcedReactions;

class Player;

class ReputationMgr
{
public:                                                 // constructors and global modifiers
    explicit ReputationMgr(Player* owner) : _player(owner),
        _visibleFactionCount(0), _honoredFactionCount(0), _reveredFactionCount(0), _exaltedFactionCount(0), _sendFactionIncreased(false) {}
    ~ReputationMgr() {}

    void SaveToDB(CharacterDatabaseTransaction trans);
    void LoadFromDB(PreparedQueryResult result);
public:                                                 // statics
    static const int32 PointsInRank[MAX_REPUTATION_RANK];
    static const int32 Reputation_Cap;
    static const int32 Reputation_Bottom;

    static ReputationRank ReputationToRank(int32 standing);
    static int32 ReputationRankToStanding(ReputationRank rank);

public:                                                 // accessors
    uint8 GetVisibleFactionCount() const { return _visibleFactionCount; }
    uint8 GetHonoredFactionCount() const { return _honoredFactionCount; }
    uint8 GetReveredFactionCount() const { return _reveredFactionCount; }
    uint8 GetExaltedFactionCount() const { return _exaltedFactionCount; }

    FactionStateList const& GetStateList() const { return _factions; }

    FactionState const* GetState(FactionEntry const* factionEntry) const
    {
        return factionEntry->CanHaveReputation() ? GetState(factionEntry->reputationListID) : nullptr;
    }

    FactionState const* GetState(RepListID id) const
    {
        FactionStateList::const_iterator repItr = _factions.find (id);
        return repItr != _factions.end() ? &repItr->second : nullptr;
    }

    bool IsAtWar(uint32 faction_id) const;
    bool IsAtWar(FactionEntry const* factionEntry) const;

    int32 GetReputation(uint32 faction_id) const;
    int32 GetReputation(FactionEntry const* factionEntry) const;
    int32 GetBaseReputation(FactionEntry const* factionEntry) const;

    ReputationRank GetRank(FactionEntry const* factionEntry) const;
    ReputationRank GetBaseRank(FactionEntry const* factionEntry) const;
    uint32 GetReputationRankStrIndex(FactionEntry const* factionEntry) const
    {
        return ReputationRankStrIndex[GetRank(factionEntry)];
    };

    ReputationRank const* GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const
    {
        ForcedReactions::const_iterator forceItr = _forcedReactions.find(factionTemplateEntry->faction);
        return forceItr != _forcedReactions.end() ? &forceItr->second : nullptr;
    }

public:                                                 // modifiers
    bool SetReputation(FactionEntry const* factionEntry, float standing)
    {
        return SetReputation(factionEntry, standing, false);
    }
    bool ModifyReputation(FactionEntry const* factionEntry, float standing, bool noSpillOver = false, Optional<ReputationRank> repMaxCap = {})
    {
        return SetReputation(factionEntry, standing, true, noSpillOver, repMaxCap);
    }

    void SetVisible(FactionTemplateEntry const* factionTemplateEntry);
    void SetVisible(FactionEntry const* factionEntry);
    void SetAtWar(RepListID repListID, bool on);
    void SetInactive(RepListID repListID, bool on);

    void ApplyForceReaction(uint32 faction_id, ReputationRank rank, bool apply);

    //! Public for chat command needs
    bool SetOneFactionReputation(FactionEntry const* factionEntry, float standing, bool incremental, Optional<ReputationRank> repMaxCap = { });

public:                                                 // senders
    void SendInitialReputations();
    void SendForceReactions();
    void SendState(FactionState const* faction);
    void SendStates();

private:                                                // internal helper functions
    void Initialize();
    uint32 GetDefaultStateFlags(FactionEntry const* factionEntry) const;
    bool SetReputation(FactionEntry const* factionEntry, float standing, bool incremental, bool noSpillOver = false, Optional<ReputationRank> repMaxCap = { });
    void SetVisible(FactionState* faction);
    void SetAtWar(FactionState* faction, bool atWar) const;
    void SetInactive(FactionState* faction, bool inactive) const;
    void SendVisible(FactionState const* faction) const;
    void UpdateRankCounters(ReputationRank old_rank, ReputationRank new_rank);
private:
    Player* _player;
    FactionStateList _factions;
    ForcedReactions _forcedReactions;
    uint8 _visibleFactionCount : 8;
    uint8 _honoredFactionCount : 8;
    uint8 _reveredFactionCount : 8;
    uint8 _exaltedFactionCount : 8;
    bool _sendFactionIncreased; //! Play visual effect on next SMSG_SET_FACTION_STANDING sent
};

#endif