Core/Reputation: Implemented "friendship reputation"
Port From (https://github.com/TrinityCore/TrinityCore/commit/80a6347b7a0e8dfbe5e690504ed373f75c4f4c76)
This commit is contained in:
@@ -2165,6 +2165,15 @@ namespace Framework.Constants
|
|||||||
Disabled = 0x1
|
Disabled = 0x1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum FriendshipReputationFlags : int
|
||||||
|
{
|
||||||
|
NoFXOnReactionChange = 0x01,
|
||||||
|
NoLogTextOnRepGain = 0x02,
|
||||||
|
NoLogTextOnReactionChange = 0x04,
|
||||||
|
ShowRepGainandReactionChangeForHiddenFaction = 0x08,
|
||||||
|
NoRepGainModifiers = 0x10
|
||||||
|
}
|
||||||
|
|
||||||
public enum GlobalCurve
|
public enum GlobalCurve
|
||||||
{
|
{
|
||||||
CritDiminishing = 0,
|
CritDiminishing = 0,
|
||||||
|
|||||||
@@ -405,6 +405,15 @@ namespace Framework.Database
|
|||||||
PrepareStatement(HotfixStatements.SEL_FACTION_TEMPLATE, "SELECT ID, Faction, Flags, FactionGroup, FriendGroup, EnemyGroup, Enemies1, Enemies2, Enemies3, " +
|
PrepareStatement(HotfixStatements.SEL_FACTION_TEMPLATE, "SELECT ID, Faction, Flags, FactionGroup, FriendGroup, EnemyGroup, Enemies1, Enemies2, Enemies3, " +
|
||||||
"Enemies4, Friend1, Friend2, Friend3, Friend4 FROM faction_template");
|
"Enemies4, Friend1, Friend2, Friend3, Friend4 FROM faction_template");
|
||||||
|
|
||||||
|
// FriendshipRepReaction.db2
|
||||||
|
PrepareStatement(HotfixStatements.SEL_FRIENDSHIP_REP_REACTION, "SELECT ID, Reaction, FriendshipRepID, ReactionThreshold FROM friendship_rep_reaction");
|
||||||
|
PrepareStatement(HotfixStatements.SEL_FRIENDSHIP_REP_REACTION_LOCALE, "SELECT ID, Reaction_lang FROM friendship_rep_reaction_locale WHERE locale = ?");
|
||||||
|
|
||||||
|
// FriendshipReputation.db2
|
||||||
|
PrepareStatement(HotfixStatements.SEL_FRIENDSHIP_REPUTATION, "SELECT Description, StandingModified, StandingChanged, ID, FactionID, TextureFileID, Flags FROM friendship_reputation");
|
||||||
|
PrepareStatement(HotfixStatements.SEL_FRIENDSHIP_REPUTATION_LOCALE, "SELECT ID, Description_lang, StandingModified_lang, StandingChanged_lang FROM friendship_reputation_locale WHERE locale = ?");
|
||||||
|
|
||||||
|
|
||||||
// GameobjectDisplayInfo.db2
|
// GameobjectDisplayInfo.db2
|
||||||
PrepareStatement(HotfixStatements.SEL_GAMEOBJECT_DISPLAY_INFO, "SELECT ID, GeoBoxMinX, GeoBoxMinY, GeoBoxMinZ, GeoBoxMaxX, GeoBoxMaxY, GeoBoxMaxZ, " +
|
PrepareStatement(HotfixStatements.SEL_GAMEOBJECT_DISPLAY_INFO, "SELECT ID, GeoBoxMinX, GeoBoxMinY, GeoBoxMinZ, GeoBoxMaxX, GeoBoxMaxY, GeoBoxMaxZ, " +
|
||||||
"FileDataID, ObjectEffectPackageID, OverrideLootEffectScale, OverrideNameScale FROM gameobject_display_info");
|
"FileDataID, ObjectEffectPackageID, OverrideLootEffectScale, OverrideNameScale FROM gameobject_display_info");
|
||||||
@@ -1376,6 +1385,12 @@ namespace Framework.Database
|
|||||||
|
|
||||||
SEL_FACTION_TEMPLATE,
|
SEL_FACTION_TEMPLATE,
|
||||||
|
|
||||||
|
SEL_FRIENDSHIP_REP_REACTION,
|
||||||
|
SEL_FRIENDSHIP_REP_REACTION_LOCALE,
|
||||||
|
|
||||||
|
SEL_FRIENDSHIP_REPUTATION,
|
||||||
|
SEL_FRIENDSHIP_REPUTATION_LOCALE,
|
||||||
|
|
||||||
SEL_GAMEOBJECT_DISPLAY_INFO,
|
SEL_GAMEOBJECT_DISPLAY_INFO,
|
||||||
|
|
||||||
SEL_GAMEOBJECTS,
|
SEL_GAMEOBJECTS,
|
||||||
|
|||||||
@@ -393,42 +393,7 @@ namespace Game.Chat
|
|||||||
if (factionId == 0 || !int.TryParse(rankTxt, out int amount))
|
if (factionId == 0 || !int.TryParse(rankTxt, out int amount))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ((amount == 0) && !(amount < 0) && !rankTxt.IsNumber())
|
var factionEntry = CliDB.FactionStorage.LookupByKey(factionId);
|
||||||
{
|
|
||||||
string rankStr = rankTxt.ToLower();
|
|
||||||
|
|
||||||
int r = 0;
|
|
||||||
amount = -42000;
|
|
||||||
for (; r < (int)ReputationRank.Max; ++r)
|
|
||||||
{
|
|
||||||
string rank = handler.GetCypherString(ReputationMgr.ReputationRankStrIndex[r]);
|
|
||||||
if (string.IsNullOrEmpty(rank))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (rank.Equals(rankStr))
|
|
||||||
{
|
|
||||||
string deltaTxt = args.NextString();
|
|
||||||
if (!string.IsNullOrEmpty(deltaTxt))
|
|
||||||
{
|
|
||||||
if (!int.TryParse(deltaTxt, out int delta) || delta < 0 || (delta > ReputationMgr.PointsInRank[r] - 1))
|
|
||||||
{
|
|
||||||
handler.SendSysMessage(CypherStrings.CommandFactionDelta, (ReputationMgr.PointsInRank[r] - 1));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
amount += delta;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
amount += ReputationMgr.PointsInRank[r];
|
|
||||||
}
|
|
||||||
if (r >= (int)ReputationRank.Max)
|
|
||||||
{
|
|
||||||
handler.SendSysMessage(CypherStrings.CommandFactionInvparam, rankTxt);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FactionRecord factionEntry = CliDB.FactionStorage.LookupByKey(factionId);
|
|
||||||
if (factionEntry == null)
|
if (factionEntry == null)
|
||||||
{
|
{
|
||||||
handler.SendSysMessage(CypherStrings.CommandFactionUnknown, factionId);
|
handler.SendSysMessage(CypherStrings.CommandFactionUnknown, factionId);
|
||||||
@@ -441,6 +406,50 @@ namespace Game.Chat
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try to find rank by name
|
||||||
|
if ((amount == 0) && !(amount < 0) && !rankTxt.IsNumber())
|
||||||
|
{
|
||||||
|
string rankStr = rankTxt.ToLower();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
|
for (; i != ReputationMgr.ReputationRankThresholds.Length - 1; ++i, ++r)
|
||||||
|
{
|
||||||
|
string rank = handler.GetCypherString(ReputationMgr.ReputationRankStrIndex[r]);
|
||||||
|
if (string.IsNullOrEmpty(rank))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (rank.Equals(rankStr))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == ReputationMgr.ReputationRankThresholds.Length - 1)
|
||||||
|
{
|
||||||
|
handler.SendSysMessage(CypherStrings.CommandFactionInvparam, rankTxt);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
amount = ReputationMgr.ReputationRankThresholds[i];
|
||||||
|
|
||||||
|
string deltaTxt = args.NextString();
|
||||||
|
if (!string.IsNullOrEmpty(deltaTxt))
|
||||||
|
{
|
||||||
|
int toNextRank = 0;
|
||||||
|
var nextThresholdIndex = i;
|
||||||
|
++nextThresholdIndex;
|
||||||
|
if (nextThresholdIndex != ReputationMgr.ReputationRankThresholds.Length - 1)
|
||||||
|
toNextRank = nextThresholdIndex - i;
|
||||||
|
|
||||||
|
if (!int.TryParse(deltaTxt, out int delta) || delta < 0 || delta >= toNextRank)
|
||||||
|
{
|
||||||
|
handler.SendSysMessage(CypherStrings.CommandFactionDelta, Math.Max(0, toNextRank - 1));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
amount += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
target.GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false);
|
target.GetReputationMgr().SetOneFactionReputation(factionEntry, amount, false);
|
||||||
target.GetReputationMgr().SendState(target.GetReputationMgr().GetState(factionEntry));
|
target.GetReputationMgr().SendState(target.GetReputationMgr().GetState(factionEntry));
|
||||||
handler.SendSysMessage(CypherStrings.CommandModifyRep, factionEntry.Name[handler.GetSessionDbcLocale()], factionId, handler.GetNameLink(target), target.GetReputationMgr().GetReputation(factionEntry));
|
handler.SendSysMessage(CypherStrings.CommandModifyRep, factionEntry.Name[handler.GetSessionDbcLocale()], factionId, handler.GetNameLink(target), target.GetReputationMgr().GetReputation(factionEntry));
|
||||||
|
|||||||
@@ -139,6 +139,8 @@ namespace Game.DataStorage
|
|||||||
ExpectedStatModStorage = ReadDB2<ExpectedStatModRecord>("ExpectedStatMod.db2", HotfixStatements.SEL_EXPECTED_STAT_MOD);
|
ExpectedStatModStorage = ReadDB2<ExpectedStatModRecord>("ExpectedStatMod.db2", HotfixStatements.SEL_EXPECTED_STAT_MOD);
|
||||||
FactionStorage = ReadDB2<FactionRecord>("Faction.db2", HotfixStatements.SEL_FACTION, HotfixStatements.SEL_FACTION_LOCALE);
|
FactionStorage = ReadDB2<FactionRecord>("Faction.db2", HotfixStatements.SEL_FACTION, HotfixStatements.SEL_FACTION_LOCALE);
|
||||||
FactionTemplateStorage = ReadDB2<FactionTemplateRecord>("FactionTemplate.db2", HotfixStatements.SEL_FACTION_TEMPLATE);
|
FactionTemplateStorage = ReadDB2<FactionTemplateRecord>("FactionTemplate.db2", HotfixStatements.SEL_FACTION_TEMPLATE);
|
||||||
|
FriendshipRepReactionStorage = ReadDB2<FriendshipRepReactionRecord>("FriendshipRepReaction.db2", HotfixStatements.SEL_FRIENDSHIP_REP_REACTION, HotfixStatements.SEL_FRIENDSHIP_REP_REACTION_LOCALE);
|
||||||
|
FriendshipReputationStorage = ReadDB2<FriendshipReputationRecord>("FriendshipReputation.db2", HotfixStatements.SEL_FRIENDSHIP_REPUTATION, HotfixStatements.SEL_FRIENDSHIP_REPUTATION_LOCALE);
|
||||||
GameObjectDisplayInfoStorage = ReadDB2<GameObjectDisplayInfoRecord>("GameObjectDisplayInfo.db2", HotfixStatements.SEL_GAMEOBJECT_DISPLAY_INFO);
|
GameObjectDisplayInfoStorage = ReadDB2<GameObjectDisplayInfoRecord>("GameObjectDisplayInfo.db2", HotfixStatements.SEL_GAMEOBJECT_DISPLAY_INFO);
|
||||||
GameObjectsStorage = ReadDB2<GameObjectsRecord>("GameObjects.db2", HotfixStatements.SEL_GAMEOBJECTS, HotfixStatements.SEL_GAMEOBJECTS_LOCALE);
|
GameObjectsStorage = ReadDB2<GameObjectsRecord>("GameObjects.db2", HotfixStatements.SEL_GAMEOBJECTS, HotfixStatements.SEL_GAMEOBJECTS_LOCALE);
|
||||||
GarrAbilityStorage = ReadDB2<GarrAbilityRecord>("GarrAbility.db2", HotfixStatements.SEL_GARR_ABILITY, HotfixStatements.SEL_GARR_ABILITY_LOCALE);
|
GarrAbilityStorage = ReadDB2<GarrAbilityRecord>("GarrAbility.db2", HotfixStatements.SEL_GARR_ABILITY, HotfixStatements.SEL_GARR_ABILITY_LOCALE);
|
||||||
@@ -503,6 +505,8 @@ namespace Game.DataStorage
|
|||||||
public static DB6Storage<ExpectedStatModRecord> ExpectedStatModStorage;
|
public static DB6Storage<ExpectedStatModRecord> ExpectedStatModStorage;
|
||||||
public static DB6Storage<FactionRecord> FactionStorage;
|
public static DB6Storage<FactionRecord> FactionStorage;
|
||||||
public static DB6Storage<FactionTemplateRecord> FactionTemplateStorage;
|
public static DB6Storage<FactionTemplateRecord> FactionTemplateStorage;
|
||||||
|
public static DB6Storage<FriendshipRepReactionRecord> FriendshipRepReactionStorage;
|
||||||
|
public static DB6Storage<FriendshipReputationRecord> FriendshipReputationStorage;
|
||||||
public static DB6Storage<GameObjectsRecord> GameObjectsStorage;
|
public static DB6Storage<GameObjectsRecord> GameObjectsStorage;
|
||||||
public static DB6Storage<GameObjectDisplayInfoRecord> GameObjectDisplayInfoStorage;
|
public static DB6Storage<GameObjectDisplayInfoRecord> GameObjectDisplayInfoStorage;
|
||||||
public static DB6Storage<GarrAbilityRecord> GarrAbilityStorage;
|
public static DB6Storage<GarrAbilityRecord> GarrAbilityStorage;
|
||||||
|
|||||||
@@ -263,6 +263,12 @@ namespace Game.DataStorage
|
|||||||
if (faction.ParentFactionID != 0)
|
if (faction.ParentFactionID != 0)
|
||||||
_factionTeams.Add(faction.ParentFactionID, faction.Id);
|
_factionTeams.Add(faction.ParentFactionID, faction.Id);
|
||||||
|
|
||||||
|
foreach (FriendshipRepReactionRecord friendshipRepReaction in CliDB.FriendshipRepReactionStorage.Values)
|
||||||
|
_friendshipRepReactions.Add(friendshipRepReaction.FriendshipRepID, friendshipRepReaction);
|
||||||
|
|
||||||
|
foreach (var key in _friendshipRepReactions.Keys)
|
||||||
|
_friendshipRepReactions[key].Sort(new FriendshipRepReactionRecordComparer());
|
||||||
|
|
||||||
foreach (GameObjectDisplayInfoRecord gameObjectDisplayInfo in CliDB.GameObjectDisplayInfoStorage.Values)
|
foreach (GameObjectDisplayInfoRecord gameObjectDisplayInfo in CliDB.GameObjectDisplayInfoStorage.Values)
|
||||||
{
|
{
|
||||||
if (gameObjectDisplayInfo.GeoBoxMax.X < gameObjectDisplayInfo.GeoBoxMin.X)
|
if (gameObjectDisplayInfo.GeoBoxMax.X < gameObjectDisplayInfo.GeoBoxMin.X)
|
||||||
@@ -1306,6 +1312,11 @@ namespace Game.DataStorage
|
|||||||
return _factionTeams.LookupByKey(faction);
|
return _factionTeams.LookupByKey(faction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<FriendshipRepReactionRecord> GetFriendshipRepReactions(uint friendshipRepID)
|
||||||
|
{
|
||||||
|
return _friendshipRepReactions.LookupByKey(friendshipRepID);
|
||||||
|
}
|
||||||
|
|
||||||
public uint GetGlobalCurveId(GlobalCurve globalCurveType)
|
public uint GetGlobalCurveId(GlobalCurve globalCurveType)
|
||||||
{
|
{
|
||||||
foreach (var globalCurveEntry in CliDB.GlobalCurveStorage.Values)
|
foreach (var globalCurveEntry in CliDB.GlobalCurveStorage.Values)
|
||||||
@@ -2241,6 +2252,7 @@ namespace Game.DataStorage
|
|||||||
Dictionary<Tuple<uint, int>, ExpectedStatRecord> _expectedStatsByLevel = new();
|
Dictionary<Tuple<uint, int>, ExpectedStatRecord> _expectedStatsByLevel = new();
|
||||||
MultiMap<uint, ExpectedStatModRecord> _expectedStatModsByContentTuning = new();
|
MultiMap<uint, ExpectedStatModRecord> _expectedStatModsByContentTuning = new();
|
||||||
MultiMap<uint, uint> _factionTeams = new();
|
MultiMap<uint, uint> _factionTeams = new();
|
||||||
|
MultiMap<uint, FriendshipRepReactionRecord> _friendshipRepReactions = new();
|
||||||
Dictionary<uint, HeirloomRecord> _heirlooms = new();
|
Dictionary<uint, HeirloomRecord> _heirlooms = new();
|
||||||
MultiMap<uint, uint> _glyphBindableSpells = new();
|
MultiMap<uint, uint> _glyphBindableSpells = new();
|
||||||
MultiMap<uint, uint> _glyphRequiredSpecs = new();
|
MultiMap<uint, uint> _glyphRequiredSpecs = new();
|
||||||
@@ -2494,6 +2506,14 @@ namespace Game.DataStorage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FriendshipRepReactionRecordComparer : IComparer<FriendshipRepReactionRecord>
|
||||||
|
{
|
||||||
|
public int Compare(FriendshipRepReactionRecord left, FriendshipRepReactionRecord right)
|
||||||
|
{
|
||||||
|
return left.ReactionThreshold.CompareTo(right.ReactionThreshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MountTypeXCapabilityRecordComparer : IComparer<MountTypeXCapabilityRecord>
|
class MountTypeXCapabilityRecordComparer : IComparer<MountTypeXCapabilityRecord>
|
||||||
{
|
{
|
||||||
public int Compare(MountTypeXCapabilityRecord left, MountTypeXCapabilityRecord right)
|
public int Compare(MountTypeXCapabilityRecord left, MountTypeXCapabilityRecord right)
|
||||||
|
|||||||
@@ -99,4 +99,23 @@ namespace Game.DataStorage
|
|||||||
}
|
}
|
||||||
public bool IsContestedGuardFaction() { return (Flags & (ushort)FactionTemplateFlags.ContestedGuard) != 0; }
|
public bool IsContestedGuardFaction() { return (Flags & (ushort)FactionTemplateFlags.ContestedGuard) != 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public sealed class FriendshipRepReactionRecord
|
||||||
|
{
|
||||||
|
public uint Id;
|
||||||
|
public LocalizedString Reaction;
|
||||||
|
public uint FriendshipRepID;
|
||||||
|
public ushort ReactionThreshold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FriendshipReputationRecord
|
||||||
|
{
|
||||||
|
public LocalizedString Description;
|
||||||
|
public LocalizedString StandingModified;
|
||||||
|
public LocalizedString StandingChanged;
|
||||||
|
public uint Id;
|
||||||
|
public int FactionID;
|
||||||
|
public int TextureFileID;
|
||||||
|
public FriendshipReputationFlags Flags;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1413,6 +1413,16 @@ namespace Game.Entities
|
|||||||
//Repitation
|
//Repitation
|
||||||
public int CalculateReputationGain(ReputationSource source, uint creatureOrQuestLevel, int rep, int faction, bool noQuestBonus = false)
|
public int CalculateReputationGain(ReputationSource source, uint creatureOrQuestLevel, int rep, int faction, bool noQuestBonus = false)
|
||||||
{
|
{
|
||||||
|
bool noBonuses = false;
|
||||||
|
var factionEntry = CliDB.FactionStorage.LookupByKey(faction);
|
||||||
|
if (factionEntry != null)
|
||||||
|
{
|
||||||
|
var friendshipReputation = CliDB.FriendshipReputationStorage.LookupByKey(factionEntry.FriendshipRepID);
|
||||||
|
if (friendshipReputation != null)
|
||||||
|
if (friendshipReputation.Flags.HasAnyFlag(FriendshipReputationFlags.NoRepGainModifiers))
|
||||||
|
noBonuses = true;
|
||||||
|
}
|
||||||
|
|
||||||
float percent = 100.0f;
|
float percent = 100.0f;
|
||||||
|
|
||||||
float repMod = noQuestBonus ? 0.0f : GetTotalAuraModifier(AuraType.ModReputationGain);
|
float repMod = noQuestBonus ? 0.0f : GetTotalAuraModifier(AuraType.ModReputationGain);
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ using Game.Entities;
|
|||||||
using Game.Networking.Packets;
|
using Game.Networking.Packets;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Game
|
namespace Game
|
||||||
{
|
{
|
||||||
@@ -37,18 +38,32 @@ namespace Game
|
|||||||
_sendFactionIncreased = false;
|
_sendFactionIncreased = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReputationRank ReputationToRank(int standing)
|
ReputationRank ReputationToRankHelper<T>(IList<T> thresholds, int standing, Func<T, int> thresholdExtractor)
|
||||||
{
|
{
|
||||||
int limit = Reputation_Cap + 1;
|
int i = 0;
|
||||||
for (var rank = ReputationRank.Max - 1; rank >= ReputationRank.Min; --rank)
|
int rank = -1;
|
||||||
|
while (i != thresholds.Count - 1 && standing >= thresholdExtractor(thresholds[i]))
|
||||||
{
|
{
|
||||||
limit -= PointsInRank[(int)rank];
|
++rank;
|
||||||
if (standing >= limit)
|
++i;
|
||||||
return rank;
|
|
||||||
}
|
}
|
||||||
return ReputationRank.Min;
|
|
||||||
|
return (ReputationRank)rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReputationRank ReputationToRank(FactionRecord factionEntry, int standing)
|
||||||
|
{
|
||||||
|
ReputationRank rank = ReputationRank.Min;
|
||||||
|
|
||||||
|
var friendshipReactions = Global.DB2Mgr.GetFriendshipRepReactions(factionEntry.FriendshipRepID);
|
||||||
|
if (!friendshipReactions.Empty())
|
||||||
|
rank = ReputationToRankHelper(friendshipReactions, standing, (FriendshipRepReactionRecord frr) => { return frr.ReactionThreshold; });
|
||||||
|
else
|
||||||
|
rank = ReputationToRankHelper(ReputationRankThresholds, standing, (int threshold) => { return threshold; });
|
||||||
|
|
||||||
|
return rank;
|
||||||
|
}
|
||||||
|
|
||||||
public FactionState GetState(FactionRecord factionEntry)
|
public FactionState GetState(FactionRecord factionEntry)
|
||||||
{
|
{
|
||||||
return factionEntry.CanHaveReputation() ? GetState(factionEntry.ReputationIndex) : null;
|
return factionEntry.CanHaveReputation() ? GetState(factionEntry.ReputationIndex) : null;
|
||||||
@@ -88,24 +103,35 @@ namespace Game
|
|||||||
|
|
||||||
public int GetBaseReputation(FactionRecord factionEntry)
|
public int GetBaseReputation(FactionRecord factionEntry)
|
||||||
{
|
{
|
||||||
if (factionEntry == null)
|
int dataIndex = GetFactionDataIndexForRaceAndClass(factionEntry);
|
||||||
|
if (dataIndex < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
long raceMask = SharedConst.GetMaskForRace(_player.GetRace());
|
return factionEntry.ReputationBase[dataIndex];
|
||||||
uint classMask = _player.GetClassMask();
|
|
||||||
for (var i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if ((Convert.ToBoolean(factionEntry.ReputationRaceMask[i] & raceMask) ||
|
|
||||||
(factionEntry.ReputationRaceMask[i] == 0 && factionEntry.ReputationClassMask[i] != 0)) &&
|
|
||||||
(Convert.ToBoolean(factionEntry.ReputationClassMask[i] & classMask) ||
|
|
||||||
factionEntry.ReputationClassMask[i] == 0))
|
|
||||||
return factionEntry.ReputationBase[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// in faction.dbc exist factions with (RepListId >=0, listed in character reputation list) with all BaseRepRaceMask[i] == 0
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetMinReputation(FactionRecord factionEntry)
|
||||||
|
{
|
||||||
|
var friendshipReactions = Global.DB2Mgr.GetFriendshipRepReactions(factionEntry.FriendshipRepID);
|
||||||
|
if (!friendshipReactions.Empty())
|
||||||
|
return friendshipReactions[0].ReactionThreshold;
|
||||||
|
|
||||||
|
return ReputationRankThresholds[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetMaxReputation(FactionRecord factionEntry)
|
||||||
|
{
|
||||||
|
var friendshipReactions = Global.DB2Mgr.GetFriendshipRepReactions(factionEntry.FriendshipRepID);
|
||||||
|
if (!friendshipReactions.Empty())
|
||||||
|
return friendshipReactions.LastOrDefault().ReactionThreshold;
|
||||||
|
|
||||||
|
int dataIndex = GetFactionDataIndexForRaceAndClass(factionEntry);
|
||||||
|
if (dataIndex >= 0 && factionEntry.ReputationMax[dataIndex] != 0)
|
||||||
|
return factionEntry.ReputationMax[dataIndex];
|
||||||
|
|
||||||
|
return ReputationRankThresholds.LastOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
public int GetReputation(FactionRecord factionEntry)
|
public int GetReputation(FactionRecord factionEntry)
|
||||||
{
|
{
|
||||||
// Faction without recorded reputation. Just ignore.
|
// Faction without recorded reputation. Just ignore.
|
||||||
@@ -122,13 +148,13 @@ namespace Game
|
|||||||
public ReputationRank GetRank(FactionRecord factionEntry)
|
public ReputationRank GetRank(FactionRecord factionEntry)
|
||||||
{
|
{
|
||||||
int reputation = GetReputation(factionEntry);
|
int reputation = GetReputation(factionEntry);
|
||||||
return ReputationToRank(reputation);
|
return ReputationToRank(factionEntry, reputation);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReputationRank GetBaseRank(FactionRecord factionEntry)
|
ReputationRank GetBaseRank(FactionRecord factionEntry)
|
||||||
{
|
{
|
||||||
int reputation = GetBaseReputation(factionEntry);
|
int reputation = GetBaseReputation(factionEntry);
|
||||||
return ReputationToRank(reputation);
|
return ReputationToRank(factionEntry, reputation);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReputationRank GetForcedRankIfAny(FactionTemplateRecord factionTemplateEntry)
|
public ReputationRank GetForcedRankIfAny(FactionTemplateRecord factionTemplateEntry)
|
||||||
@@ -146,21 +172,11 @@ namespace Game
|
|||||||
|
|
||||||
uint GetDefaultStateFlags(FactionRecord factionEntry)
|
uint GetDefaultStateFlags(FactionRecord factionEntry)
|
||||||
{
|
{
|
||||||
if (factionEntry == null)
|
int dataIndex = GetFactionDataIndexForRaceAndClass(factionEntry);
|
||||||
|
if (dataIndex < 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
long raceMask = SharedConst.GetMaskForRace(_player.GetRace());
|
return factionEntry.ReputationFlags[dataIndex];
|
||||||
uint classMask = _player.GetClassMask();
|
|
||||||
for (int i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if ((Convert.ToBoolean(factionEntry.ReputationRaceMask[i] & raceMask) ||
|
|
||||||
(factionEntry.ReputationRaceMask[i] == 0 &&
|
|
||||||
factionEntry.ReputationClassMask[i] != 0)) &&
|
|
||||||
(Convert.ToBoolean(factionEntry.ReputationClassMask[i] & classMask) ||
|
|
||||||
factionEntry.ReputationClassMask[i] == 0))
|
|
||||||
return factionEntry.ReputationFlags[i];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendForceReactions()
|
public void SendForceReactions()
|
||||||
@@ -252,7 +268,8 @@ namespace Game
|
|||||||
if (Convert.ToBoolean(newFaction.Flags & FactionFlags.Visible))
|
if (Convert.ToBoolean(newFaction.Flags & FactionFlags.Visible))
|
||||||
++_visibleFactionCount;
|
++_visibleFactionCount;
|
||||||
|
|
||||||
UpdateRankCounters(ReputationRank.Hostile, GetBaseRank(factionEntry));
|
if (factionEntry.FriendshipRepID == 0)
|
||||||
|
UpdateRankCounters(ReputationRank.Hostile, GetBaseRank(factionEntry));
|
||||||
|
|
||||||
_factions[newFaction.ReputationListID] = newFaction;
|
_factions[newFaction.ReputationListID] = newFaction;
|
||||||
}
|
}
|
||||||
@@ -363,13 +380,13 @@ namespace Game
|
|||||||
standing += factionState.Standing + BaseRep;
|
standing += factionState.Standing + BaseRep;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (standing > Reputation_Cap)
|
if (standing > GetMaxReputation(factionEntry))
|
||||||
standing = Reputation_Cap;
|
standing = GetMaxReputation(factionEntry);
|
||||||
else if (standing < Reputation_Bottom)
|
else if (standing < GetMinReputation(factionEntry))
|
||||||
standing = Reputation_Bottom;
|
standing = GetMinReputation(factionEntry);
|
||||||
|
|
||||||
ReputationRank old_rank = ReputationToRank(factionState.Standing + BaseRep);
|
ReputationRank old_rank = ReputationToRank(factionEntry, factionState.Standing + BaseRep);
|
||||||
ReputationRank new_rank = ReputationToRank(standing);
|
ReputationRank new_rank = ReputationToRank(factionEntry, standing);
|
||||||
|
|
||||||
int newStanding = standing - BaseRep;
|
int newStanding = standing - BaseRep;
|
||||||
|
|
||||||
@@ -387,8 +404,8 @@ namespace Game
|
|||||||
if (new_rank > old_rank)
|
if (new_rank > old_rank)
|
||||||
_sendFactionIncreased = true;
|
_sendFactionIncreased = true;
|
||||||
|
|
||||||
UpdateRankCounters(old_rank, new_rank);
|
if (factionEntry.FriendshipRepID == 0)
|
||||||
|
UpdateRankCounters(old_rank, new_rank);
|
||||||
|
|
||||||
_player.UpdateCriteria(CriteriaTypes.KnownFactions, factionEntry.Id);
|
_player.UpdateCriteria(CriteriaTypes.KnownFactions, factionEntry.Id);
|
||||||
_player.UpdateCriteria(CriteriaTypes.GainReputation, factionEntry.Id);
|
_player.UpdateCriteria(CriteriaTypes.GainReputation, factionEntry.Id);
|
||||||
@@ -524,10 +541,13 @@ namespace Game
|
|||||||
faction.Standing = result.Read<int>(1);
|
faction.Standing = result.Read<int>(1);
|
||||||
|
|
||||||
// update counters
|
// update counters
|
||||||
int BaseRep = GetBaseReputation(factionEntry);
|
if (factionEntry.FriendshipRepID == 0)
|
||||||
ReputationRank old_rank = ReputationToRank(BaseRep);
|
{
|
||||||
ReputationRank new_rank = ReputationToRank(BaseRep + faction.Standing);
|
int BaseRep = GetBaseReputation(factionEntry);
|
||||||
UpdateRankCounters(old_rank, new_rank);
|
ReputationRank old_rank = ReputationToRank(factionEntry, BaseRep);
|
||||||
|
ReputationRank new_rank = ReputationToRank(factionEntry, BaseRep + faction.Standing);
|
||||||
|
UpdateRankCounters(old_rank, new_rank);
|
||||||
|
}
|
||||||
|
|
||||||
FactionFlags dbFactionFlags = (FactionFlags)result.Read<uint>(2);
|
FactionFlags dbFactionFlags = (FactionFlags)result.Read<uint>(2);
|
||||||
|
|
||||||
@@ -601,6 +621,24 @@ namespace Game
|
|||||||
++_honoredFactionCount;
|
++_honoredFactionCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GetFactionDataIndexForRaceAndClass(FactionRecord factionEntry)
|
||||||
|
{
|
||||||
|
if (factionEntry == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
long raceMask = SharedConst.GetMaskForRace(_player.GetRace());
|
||||||
|
short classMask = (short)_player.GetClassMask();
|
||||||
|
for (int i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
|
if ((factionEntry.ReputationRaceMask[i].HasAnyFlag(raceMask) || (factionEntry.ReputationRaceMask[i] == 0 && factionEntry.ReputationClassMask[i] != 0))
|
||||||
|
&& (factionEntry.ReputationClassMask[i].HasAnyFlag(classMask) || factionEntry.ReputationClassMask[i] == 0))
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
public byte GetVisibleFactionCount() { return _visibleFactionCount; }
|
public byte GetVisibleFactionCount() { return _visibleFactionCount; }
|
||||||
|
|
||||||
public byte GetHonoredFactionCount() { return _honoredFactionCount; }
|
public byte GetHonoredFactionCount() { return _honoredFactionCount; }
|
||||||
@@ -633,13 +671,13 @@ namespace Game
|
|||||||
if (factionEntry == null)
|
if (factionEntry == null)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ulong raceMask = (ulong)SharedConst.GetMaskForRace(race);
|
long raceMask = SharedConst.GetMaskForRace(race);
|
||||||
uint classMask = (1u << ((int)playerClass - 1));
|
uint classMask = (1u << ((int)playerClass - 1));
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
if ((factionEntry.ReputationClassMask[i] == 0 || factionEntry.ReputationClassMask[i].HasAnyFlag((short)classMask))
|
if ((factionEntry.ReputationClassMask[i] == 0 || factionEntry.ReputationClassMask[i].HasAnyFlag((short)classMask))
|
||||||
&& (factionEntry.ReputationRaceMask[i] == 0 || factionEntry.ReputationRaceMask[i].HasAnyFlag((uint)raceMask)))
|
&& (factionEntry.ReputationRaceMask[i] == 0 || factionEntry.ReputationRaceMask[i].HasAnyFlag(raceMask)))
|
||||||
return factionEntry.ReputationBase[i];
|
return factionEntry.ReputationBase[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,19 +693,38 @@ namespace Game
|
|||||||
bool _sendFactionIncreased; //! Play visual effect on next SMSG_SET_FACTION_STANDING sent
|
bool _sendFactionIncreased; //! Play visual effect on next SMSG_SET_FACTION_STANDING sent
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public static int[] PointsInRank = { 36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000 };
|
public static int[] ReputationRankThresholds =
|
||||||
|
{
|
||||||
|
-42000,
|
||||||
|
// Hated
|
||||||
|
-6000,
|
||||||
|
// Hostile
|
||||||
|
-3000,
|
||||||
|
// Unfriendly
|
||||||
|
0,
|
||||||
|
// Neutral
|
||||||
|
3000,
|
||||||
|
// Friendly
|
||||||
|
9000,
|
||||||
|
// Honored
|
||||||
|
21000,
|
||||||
|
// Revered
|
||||||
|
42000
|
||||||
|
// Exalted
|
||||||
|
};
|
||||||
|
|
||||||
public static CypherStrings[] ReputationRankStrIndex =
|
public static CypherStrings[] ReputationRankStrIndex =
|
||||||
{
|
{
|
||||||
CypherStrings.RepHated, CypherStrings.RepHostile, CypherStrings.RepUnfriendly, CypherStrings.RepNeutral,
|
CypherStrings.RepHated, CypherStrings.RepHostile, CypherStrings.RepUnfriendly, CypherStrings.RepNeutral,
|
||||||
CypherStrings.RepFriendly, CypherStrings.RepHonored, CypherStrings.RepRevered, CypherStrings.RepExalted
|
CypherStrings.RepFriendly, CypherStrings.RepHonored, CypherStrings.RepRevered, CypherStrings.RepExalted
|
||||||
};
|
};
|
||||||
const int Reputation_Cap = 42999;
|
|
||||||
|
const int Reputation_Cap = 42000;
|
||||||
const int Reputation_Bottom = -42000;
|
const int Reputation_Bottom = -42000;
|
||||||
SortedDictionary<uint, FactionState> _factions = new();
|
SortedDictionary<uint, FactionState> _factions = new();
|
||||||
Dictionary<uint, ReputationRank> _forcedReactions = new();
|
Dictionary<uint, ReputationRank> _forcedReactions = new();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FactionState
|
public class FactionState
|
||||||
{
|
{
|
||||||
public uint Id;
|
public uint Id;
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
--
|
||||||
|
-- Table structure for table `friendship_rep_reaction`
|
||||||
|
--
|
||||||
|
DROP TABLE IF EXISTS `friendship_rep_reaction`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `friendship_rep_reaction` (
|
||||||
|
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`Reaction` text,
|
||||||
|
`FriendshipRepID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`ReactionThreshold` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`ID`,`VerifiedBuild`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `friendship_rep_reaction_locale`
|
||||||
|
--
|
||||||
|
DROP TABLE IF EXISTS `friendship_rep_reaction_locale`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `friendship_rep_reaction_locale` (
|
||||||
|
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`locale` varchar(4) NOT NULL,
|
||||||
|
`Reaction_lang` text,
|
||||||
|
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`ID`,`locale`,`VerifiedBuild`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
|
/*!50500 PARTITION BY LIST COLUMNS(locale)
|
||||||
|
(PARTITION deDE VALUES IN ('deDE') ENGINE = InnoDB,
|
||||||
|
PARTITION esES VALUES IN ('esES') ENGINE = InnoDB,
|
||||||
|
PARTITION esMX VALUES IN ('esMX') ENGINE = InnoDB,
|
||||||
|
PARTITION frFR VALUES IN ('frFR') ENGINE = InnoDB,
|
||||||
|
PARTITION itIT VALUES IN ('itIT') ENGINE = InnoDB,
|
||||||
|
PARTITION koKR VALUES IN ('koKR') ENGINE = InnoDB,
|
||||||
|
PARTITION ptBR VALUES IN ('ptBR') ENGINE = InnoDB,
|
||||||
|
PARTITION ruRU VALUES IN ('ruRU') ENGINE = InnoDB,
|
||||||
|
PARTITION zhCN VALUES IN ('zhCN') ENGINE = InnoDB,
|
||||||
|
PARTITION zhTW VALUES IN ('zhTW') ENGINE = InnoDB) */;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `friendship_reputation`
|
||||||
|
--
|
||||||
|
DROP TABLE IF EXISTS `friendship_reputation`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `friendship_reputation` (
|
||||||
|
`Description` text,
|
||||||
|
`StandingModified` text,
|
||||||
|
`StandingChanged` text,
|
||||||
|
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`FactionID` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`TextureFileID` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`Flags` int(11) NOT NULL DEFAULT '0',
|
||||||
|
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`ID`,`VerifiedBuild`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `friendship_reputation_locale`
|
||||||
|
--
|
||||||
|
DROP TABLE IF EXISTS `friendship_reputation_locale`;
|
||||||
|
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||||
|
/*!50503 SET character_set_client = utf8mb4 */;
|
||||||
|
CREATE TABLE `friendship_reputation_locale` (
|
||||||
|
`ID` int(10) unsigned NOT NULL DEFAULT '0',
|
||||||
|
`locale` varchar(4) NOT NULL,
|
||||||
|
`Description_lang` text,
|
||||||
|
`StandingModified_lang` text,
|
||||||
|
`StandingChanged_lang` text,
|
||||||
|
`VerifiedBuild` int(11) NOT NULL DEFAULT '0',
|
||||||
|
PRIMARY KEY (`ID`,`locale`,`VerifiedBuild`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||||
|
/*!50500 PARTITION BY LIST COLUMNS(locale)
|
||||||
|
(PARTITION deDE VALUES IN ('deDE') ENGINE = InnoDB,
|
||||||
|
PARTITION esES VALUES IN ('esES') ENGINE = InnoDB,
|
||||||
|
PARTITION esMX VALUES IN ('esMX') ENGINE = InnoDB,
|
||||||
|
PARTITION frFR VALUES IN ('frFR') ENGINE = InnoDB,
|
||||||
|
PARTITION itIT VALUES IN ('itIT') ENGINE = InnoDB,
|
||||||
|
PARTITION koKR VALUES IN ('koKR') ENGINE = InnoDB,
|
||||||
|
PARTITION ptBR VALUES IN ('ptBR') ENGINE = InnoDB,
|
||||||
|
PARTITION ruRU VALUES IN ('ruRU') ENGINE = InnoDB,
|
||||||
|
PARTITION zhCN VALUES IN ('zhCN') ENGINE = InnoDB,
|
||||||
|
PARTITION zhTW VALUES IN ('zhTW') ENGINE = InnoDB) */;
|
||||||
|
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||||
Reference in New Issue
Block a user