diff --git a/Client/MirObjects/MonsterObject.cs b/Client/MirObjects/MonsterObject.cs index dcdba2329..17883da3a 100644 --- a/Client/MirObjects/MonsterObject.cs +++ b/Client/MirObjects/MonsterObject.cs @@ -100,9 +100,7 @@ public void Load(S.ObjectMonster info, bool update = false) if (MasterObjectId == 0 && Rarity != MonsterType.Normal) { - //Moving the rarity tag processing from the server to the client allows for more complex tag displays in the future, such as adding special markers on monster health bars. - //Add localization for rarity text - Name = $"{Rarity.ToLocalizedString()}_{Name}"; + Name = $"{info.CustomRarityName}_{Name}"; } Buffs = info.Buffs; diff --git a/Server/MirEnvir/Map.cs b/Server/MirEnvir/Map.cs index 9e4f2dcfb..5e00ef590 100644 --- a/Server/MirEnvir/Map.cs +++ b/Server/MirEnvir/Map.cs @@ -2559,7 +2559,10 @@ public bool Spawn() MonsterObject ob = MonsterObject.GetMonster(Monster); if (ob == null) return true; - MonsterType type = Settings.MonsterRarityEnabled + bool allowRarity = Settings.MonsterRarityEnabled && + (Monster == null || !Monster.IsBoss); + + MonsterType type = allowRarity ? MonsterRarityData.Roll(RandomProvider.GetThreadRandom()) : MonsterType.Normal; diff --git a/Server/MirObjects/MonsterObject.cs b/Server/MirObjects/MonsterObject.cs index c1d557e20..bee8566a1 100644 --- a/Server/MirObjects/MonsterObject.cs +++ b/Server/MirObjects/MonsterObject.cs @@ -684,6 +684,10 @@ protected internal MonsterObject(MonsterInfo info) public void SetMonsterType(MonsterType type) { + // Summoned monsters (pets) should always be Normal rarity + if (Master != null && type != MonsterType.Normal) + return; + MonsterType = type; } public bool Spawn(Map temp, Point location) @@ -760,19 +764,28 @@ protected virtual void ApplyMonsterTypeBonuses() MonsterRarityProfile profile = GetRarityProfile(); - ScaleStat(Stat.HP, profile.HpMultiplier); + if (profile.EnableHpIncrease) + { + ScaleStat(Stat.HP, profile.HpMultiplier); + } - ScaleStat(Stat.MinAC, profile.DefenseMultiplier); - ScaleStat(Stat.MaxAC, profile.DefenseMultiplier); - ScaleStat(Stat.MinMAC, profile.DefenseMultiplier); - ScaleStat(Stat.MaxMAC, profile.DefenseMultiplier); + if (profile.EnableDefenseIncrease) + { + ScaleStat(Stat.MinAC, profile.DefenseMultiplier); + ScaleStat(Stat.MaxAC, profile.DefenseMultiplier); + ScaleStat(Stat.MinMAC, profile.DefenseMultiplier); + ScaleStat(Stat.MaxMAC, profile.DefenseMultiplier); + } - ScaleStat(Stat.MinDC, profile.DamageMultiplier); - ScaleStat(Stat.MaxDC, profile.DamageMultiplier); - ScaleStat(Stat.MinMC, profile.DamageMultiplier); - ScaleStat(Stat.MaxMC, profile.DamageMultiplier); - ScaleStat(Stat.MinSC, profile.DamageMultiplier); - ScaleStat(Stat.MaxSC, profile.DamageMultiplier); + if (profile.EnableDamageIncrease) + { + ScaleStat(Stat.MinDC, profile.DamageMultiplier); + ScaleStat(Stat.MaxDC, profile.DamageMultiplier); + ScaleStat(Stat.MinMC, profile.DamageMultiplier); + ScaleStat(Stat.MaxMC, profile.DamageMultiplier); + ScaleStat(Stat.MinSC, profile.DamageMultiplier); + ScaleStat(Stat.MaxSC, profile.DamageMultiplier); + } } protected void ScaleStat(Stat stat, double multiplier) @@ -2875,7 +2888,8 @@ public override Packet GetInfo() BindingShotCenter = BindingShotCenter, Buffs = Buffs.Where(d => d.Info.Visible).Select(e => e.Type).ToList(), MasterObjectId = Master?.ObjectID ?? 0, - Rarity= MonsterType + Rarity = MonsterType, + CustomRarityName = GetRarityProfile().CustomName ?? string.Empty }; } diff --git a/Server/Settings.cs b/Server/Settings.cs index 09e37e765..a9c3d7482 100644 --- a/Server/Settings.cs +++ b/Server/Settings.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Drawing; using System.Security.Cryptography; using Server.MirDatabase; using Server.MirObjects; @@ -119,7 +120,7 @@ private static MessageQueue MessageQueue public static bool MonsterRecallEnabled = true; public static int MonsterRecallRange = 12; public static int MonsterRecallCooldown = 5000; - public static bool MonsterRarityEnabled = true; + public static bool MonsterRarityEnabled = false; public static double MonsterRarityUncommonChancePercent = 3.0, MonsterRarityRareChancePercent = 0.75, MonsterRarityEliteChancePercent = 0.1; @@ -146,6 +147,21 @@ private static MessageQueue MessageQueue MonsterRarityEliteGoldMultiplier = 2.50; public static int MonsterRarityEliteItemDropBonusPercent = 75, MonsterRarityEliteGoldDropBonusPercent = 75; + public static Color MonsterRarityUncommonNameColour = Color.LightGreen; + public static Color MonsterRarityRareNameColour = Color.DeepSkyBlue; + public static Color MonsterRarityEliteNameColour = Color.Gold; + public static string MonsterRarityUncommonCustomName = "Uncommon"; + public static string MonsterRarityRareCustomName = "Rare"; + public static string MonsterRarityEliteCustomName = "Elite"; + public static bool MonsterRarityUncommonEnableHpIncrease = true; + public static bool MonsterRarityUncommonEnableDefenseIncrease = true; + public static bool MonsterRarityUncommonEnableDamageIncrease = true; + public static bool MonsterRarityRareEnableHpIncrease = true; + public static bool MonsterRarityRareEnableDefenseIncrease = true; + public static bool MonsterRarityRareEnableDamageIncrease = true; + public static bool MonsterRarityEliteEnableHpIncrease = true; + public static bool MonsterRarityEliteEnableDefenseIncrease = true; + public static bool MonsterRarityEliteEnableDamageIncrease = true; public static bool PetSave = false; @@ -1731,6 +1747,7 @@ public static void LoadMonsterRarity() MonsterRarityRareGoldMultiplier = rarityReader.ReadDouble("Rare", "GoldMultiplier", MonsterRarityRareGoldMultiplier); MonsterRarityRareItemDropBonusPercent = rarityReader.ReadInt32("Rare", "ItemDropBonusPercent", MonsterRarityRareItemDropBonusPercent); MonsterRarityRareGoldDropBonusPercent = rarityReader.ReadInt32("Rare", "GoldDropBonusPercent", MonsterRarityRareGoldDropBonusPercent); + MonsterRarityRareNameColour = ReadRarityColour(rarityReader, "Rare", "NameColour", MonsterRarityRareNameColour); MonsterRarityEliteHpMultiplier = rarityReader.ReadDouble("Elite", "HpMultiplier", MonsterRarityEliteHpMultiplier); MonsterRarityEliteDefenseMultiplier = rarityReader.ReadDouble("Elite", "DefenseMultiplier", MonsterRarityEliteDefenseMultiplier); @@ -1739,6 +1756,29 @@ public static void LoadMonsterRarity() MonsterRarityEliteGoldMultiplier = rarityReader.ReadDouble("Elite", "GoldMultiplier", MonsterRarityEliteGoldMultiplier); MonsterRarityEliteItemDropBonusPercent = rarityReader.ReadInt32("Elite", "ItemDropBonusPercent", MonsterRarityEliteItemDropBonusPercent); MonsterRarityEliteGoldDropBonusPercent = rarityReader.ReadInt32("Elite", "GoldDropBonusPercent", MonsterRarityEliteGoldDropBonusPercent); + MonsterRarityEliteNameColour = ReadRarityColour(rarityReader, "Elite", "NameColour", MonsterRarityEliteNameColour); + MonsterRarityUncommonNameColour = ReadRarityColour(rarityReader, "Uncommon", "NameColour", MonsterRarityUncommonNameColour); + + string uncommonName = rarityReader.ReadString("Uncommon", "CustomName", MonsterRarityUncommonCustomName); + MonsterRarityUncommonCustomName = string.IsNullOrWhiteSpace(uncommonName) ? "Uncommon" : uncommonName; + + string rareName = rarityReader.ReadString("Rare", "CustomName", MonsterRarityRareCustomName); + MonsterRarityRareCustomName = string.IsNullOrWhiteSpace(rareName) ? "Rare" : rareName; + + string eliteName = rarityReader.ReadString("Elite", "CustomName", MonsterRarityEliteCustomName); + MonsterRarityEliteCustomName = string.IsNullOrWhiteSpace(eliteName) ? "Elite" : eliteName; + + MonsterRarityUncommonEnableHpIncrease = rarityReader.ReadBoolean("Uncommon", "EnableHpIncrease", MonsterRarityUncommonEnableHpIncrease); + MonsterRarityUncommonEnableDefenseIncrease = rarityReader.ReadBoolean("Uncommon", "EnableDefenseIncrease", MonsterRarityUncommonEnableDefenseIncrease); + MonsterRarityUncommonEnableDamageIncrease = rarityReader.ReadBoolean("Uncommon", "EnableDamageIncrease", MonsterRarityUncommonEnableDamageIncrease); + + MonsterRarityRareEnableHpIncrease = rarityReader.ReadBoolean("Rare", "EnableHpIncrease", MonsterRarityRareEnableHpIncrease); + MonsterRarityRareEnableDefenseIncrease = rarityReader.ReadBoolean("Rare", "EnableDefenseIncrease", MonsterRarityRareEnableDefenseIncrease); + MonsterRarityRareEnableDamageIncrease = rarityReader.ReadBoolean("Rare", "EnableDamageIncrease", MonsterRarityRareEnableDamageIncrease); + + MonsterRarityEliteEnableHpIncrease = rarityReader.ReadBoolean("Elite", "EnableHpIncrease", MonsterRarityEliteEnableHpIncrease); + MonsterRarityEliteEnableDefenseIncrease = rarityReader.ReadBoolean("Elite", "EnableDefenseIncrease", MonsterRarityEliteEnableDefenseIncrease); + MonsterRarityEliteEnableDamageIncrease = rarityReader.ReadBoolean("Elite", "EnableDamageIncrease", MonsterRarityEliteEnableDamageIncrease); MonsterRarityData.SetEnabled(MonsterRarityEnabled); MonsterRarityData.Configure(MonsterRarityUncommonChancePercent, MonsterRarityRareChancePercent, MonsterRarityEliteChancePercent); @@ -1754,7 +1794,11 @@ public static void LoadMonsterRarity() GoldMultiplier = MonsterRarityUncommonGoldMultiplier, ItemDropBonusPercent = MonsterRarityUncommonItemDropBonusPercent, GoldDropBonusPercent = MonsterRarityUncommonGoldDropBonusPercent, - NameColour = MonsterRarityData.GetProfile(MonsterType.Uncommon).NameColour + NameColour = MonsterRarityUncommonNameColour, + CustomName = MonsterRarityUncommonCustomName, + EnableHpIncrease = MonsterRarityUncommonEnableHpIncrease, + EnableDefenseIncrease = MonsterRarityUncommonEnableDefenseIncrease, + EnableDamageIncrease = MonsterRarityUncommonEnableDamageIncrease }, [MonsterType.Rare] = new MonsterRarityProfile { @@ -1765,7 +1809,11 @@ public static void LoadMonsterRarity() GoldMultiplier = MonsterRarityRareGoldMultiplier, ItemDropBonusPercent = MonsterRarityRareItemDropBonusPercent, GoldDropBonusPercent = MonsterRarityRareGoldDropBonusPercent, - NameColour = MonsterRarityData.GetProfile(MonsterType.Rare).NameColour + NameColour = MonsterRarityRareNameColour, + CustomName = MonsterRarityRareCustomName, + EnableHpIncrease = MonsterRarityRareEnableHpIncrease, + EnableDefenseIncrease = MonsterRarityRareEnableDefenseIncrease, + EnableDamageIncrease = MonsterRarityRareEnableDamageIncrease }, [MonsterType.Elite] = new MonsterRarityProfile { @@ -1776,7 +1824,11 @@ public static void LoadMonsterRarity() GoldMultiplier = MonsterRarityEliteGoldMultiplier, ItemDropBonusPercent = MonsterRarityEliteItemDropBonusPercent, GoldDropBonusPercent = MonsterRarityEliteGoldDropBonusPercent, - NameColour = MonsterRarityData.GetProfile(MonsterType.Elite).NameColour + NameColour = MonsterRarityEliteNameColour, + CustomName = MonsterRarityEliteCustomName, + EnableHpIncrease = MonsterRarityEliteEnableHpIncrease, + EnableDefenseIncrease = MonsterRarityEliteEnableDefenseIncrease, + EnableDamageIncrease = MonsterRarityEliteEnableDamageIncrease } }; @@ -1793,5 +1845,40 @@ private static double ReadRarityChancePercent(InIReader reader, string percentKe return percent; } + public static void SaveMonsterRarity() + { + var rarityReader = new InIReader(Path.Combine(ConfigPath, "MonsterRarity.ini")); + + rarityReader.Write("General", "Enabled", MonsterRarityEnabled); + + rarityReader.Write("Uncommon", "NameColour", MonsterRarityUncommonNameColour.Name); + rarityReader.Write("Rare", "NameColour", MonsterRarityRareNameColour.Name); + rarityReader.Write("Elite", "NameColour", MonsterRarityEliteNameColour.Name); + + rarityReader.Write("Uncommon", "CustomName", MonsterRarityUncommonCustomName); + rarityReader.Write("Rare", "CustomName", MonsterRarityRareCustomName); + rarityReader.Write("Elite", "CustomName", MonsterRarityEliteCustomName); + + rarityReader.Write("Uncommon", "EnableHpIncrease", MonsterRarityUncommonEnableHpIncrease); + rarityReader.Write("Uncommon", "EnableDefenseIncrease", MonsterRarityUncommonEnableDefenseIncrease); + rarityReader.Write("Uncommon", "EnableDamageIncrease", MonsterRarityUncommonEnableDamageIncrease); + + rarityReader.Write("Rare", "EnableHpIncrease", MonsterRarityRareEnableHpIncrease); + rarityReader.Write("Rare", "EnableDefenseIncrease", MonsterRarityRareEnableDefenseIncrease); + rarityReader.Write("Rare", "EnableDamageIncrease", MonsterRarityRareEnableDamageIncrease); + + rarityReader.Write("Elite", "EnableHpIncrease", MonsterRarityEliteEnableHpIncrease); + rarityReader.Write("Elite", "EnableDefenseIncrease", MonsterRarityEliteEnableDefenseIncrease); + rarityReader.Write("Elite", "EnableDamageIncrease", MonsterRarityEliteEnableDamageIncrease); + + rarityReader.Save(); + } + + private static Color ReadRarityColour(InIReader reader, string section, string key, Color defaultColour) + { + string value = reader.ReadString(section, key, defaultColour.Name); + Color parsed = Color.FromName(value); + return parsed.IsEmpty ? defaultColour : parsed; + } } } diff --git a/Shared/Data/MonsterRarityData.cs b/Shared/Data/MonsterRarityData.cs index 9c7554df4..2ccbf9073 100644 --- a/Shared/Data/MonsterRarityData.cs +++ b/Shared/Data/MonsterRarityData.cs @@ -12,6 +12,10 @@ public struct MonsterRarityProfile public int ItemDropBonusPercent; public int GoldDropBonusPercent; public Color NameColour; + public string CustomName; + public bool EnableHpIncrease; + public bool EnableDefenseIncrease; + public bool EnableDamageIncrease; } public static class MonsterRarityData @@ -28,7 +32,11 @@ public static class MonsterRarityData GoldMultiplier = 1.00, ItemDropBonusPercent = 0, GoldDropBonusPercent = 0, - NameColour = Color.White + NameColour = Color.White, + CustomName = null, + EnableHpIncrease = false, + EnableDefenseIncrease = false, + EnableDamageIncrease = false }, [MonsterType.Uncommon] = new MonsterRarityProfile { @@ -39,7 +47,11 @@ public static class MonsterRarityData GoldMultiplier = 1.25, ItemDropBonusPercent = 15, GoldDropBonusPercent = 15, - NameColour = Color.LightGreen + NameColour = Color.LightGreen, + CustomName = null, + EnableHpIncrease = true, + EnableDefenseIncrease = true, + EnableDamageIncrease = true }, [MonsterType.Rare] = new MonsterRarityProfile { @@ -50,7 +62,11 @@ public static class MonsterRarityData GoldMultiplier = 1.75, ItemDropBonusPercent = 35, GoldDropBonusPercent = 35, - NameColour = Color.DeepSkyBlue + NameColour = Color.DeepSkyBlue, + CustomName = null, + EnableHpIncrease = true, + EnableDefenseIncrease = true, + EnableDamageIncrease = true }, [MonsterType.Elite] = new MonsterRarityProfile { @@ -61,7 +77,11 @@ public static class MonsterRarityData GoldMultiplier = 2.50, ItemDropBonusPercent = 75, GoldDropBonusPercent = 75, - NameColour = Color.Gold + NameColour = Color.Gold, + CustomName = null, + EnableHpIncrease = true, + EnableDefenseIncrease = true, + EnableDamageIncrease = true } }; @@ -99,6 +119,12 @@ public static MonsterRarityProfile GetProfile(MonsterType type) return Profiles.TryGetValue(type, out var profile) ? profile : Profiles[MonsterType.Normal]; } + public static string GetDisplayName(MonsterType type) + { + var profile = GetProfile(type); + return !string.IsNullOrEmpty(profile.CustomName) ? profile.CustomName : type.ToLocalizedString(); + } + public static MonsterType Roll(Random random) { if (!Enabled) diff --git a/Shared/ServerPackets.cs b/Shared/ServerPackets.cs index e6a4f4ff9..dfe6a4fda 100644 --- a/Shared/ServerPackets.cs +++ b/Shared/ServerPackets.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Drawing; namespace ServerPackets @@ -2232,6 +2232,7 @@ public override short Index public bool BindingShotCenter; public uint MasterObjectId; public MonsterType Rarity; + public string CustomRarityName = string.Empty; public List Buffs = new List(); @@ -2256,6 +2257,7 @@ protected override void ReadPacket(BinaryReader reader) ExtraByte = reader.ReadByte(); MasterObjectId= reader.ReadUInt32(); Rarity= (MonsterType)reader.ReadByte(); + CustomRarityName = reader.ReadString(); int count = reader.ReadInt32(); for (int i = 0; i < count; i++) @@ -2286,6 +2288,7 @@ protected override void WritePacket(BinaryWriter writer) writer.Write((byte)ExtraByte); writer.Write(MasterObjectId); writer.Write((byte)Rarity); + writer.Write(CustomRarityName); writer.Write(Buffs.Count); for (int i = 0; i < Buffs.Count; i++)