diff --git a/src/ClassicUO.Client/ClassicUO.Client.csproj b/src/ClassicUO.Client/ClassicUO.Client.csproj index 58bb7751e..1a16d085f 100644 --- a/src/ClassicUO.Client/ClassicUO.Client.csproj +++ b/src/ClassicUO.Client/ClassicUO.Client.csproj @@ -94,6 +94,10 @@ + + + + ..\..\external\cuoapi\cuoapi.dll diff --git a/src/ClassicUO.Client/Dust765/Dust765/CombatCollection.cs b/src/ClassicUO.Client/Dust765/Dust765/CombatCollection.cs index c254f1e78..9ee50986c 100644 --- a/src/ClassicUO.Client/Dust765/Dust765/CombatCollection.cs +++ b/src/ClassicUO.Client/Dust765/Dust765/CombatCollection.cs @@ -280,7 +280,7 @@ public static ushort OwnAuraColorByHP() else if (ww < 1) ww = 0; - World.Player.UpdateHits((byte) ww); + World.Player.UpdateHits((byte)ww); } if (World.Player.HitsPercentage < 20) @@ -292,7 +292,7 @@ public static ushort OwnAuraColorByHP() else if (World.Player.HitsPercentage < 80) color = 0x0035; //yellow (but shows green?) else if (World.Player.HitsPercentage == 100) - color = (ushort) Notoriety.GetHue(World.Player.NotorietyFlag); + color = (ushort)Notoriety.GetHue(World.Player.NotorietyFlag); // "original colors from overhead %, < 30 0x0021, < 50 0x0030, < 80 0x0058" return color; @@ -376,6 +376,7 @@ public static void StartSpelltime() } //GAME\GAMEOBJECTS\VIEWS\ - MULTIVIEW.CS - STATICVIEW.CS - TILEVIEW.CS + //22 - Teleport //24 - Wall of Stone //28 - Fire Field //39 - Poison Field @@ -444,6 +445,7 @@ public static bool MultiFieldPreview(Multi obj) } } } + if (GameActions.LastSpellIndexCursor == 28 || GameActions.LastSpellIndexCursor == 39 || GameActions.LastSpellIndexCursor == 47 || GameActions.LastSpellIndexCursor == 50) { //Calc _fieldEastToWest @@ -515,7 +517,7 @@ public static bool MultiFieldPreview(Multi obj) } } } - if (GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) + if (GameActions.LastSpellIndexCursor == 22 || GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) { if (SelectedObject.Object != null && (SelectedObject.Object.RealScreenPosition.X + 22) == obj.RealScreenPosition.X && (SelectedObject.Object.RealScreenPosition.Y + 22) == obj.RealScreenPosition.Y) { @@ -677,6 +679,7 @@ public static bool StaticFieldPreview(Static obj) } } } + if (GameActions.LastSpellIndexCursor == 28 || GameActions.LastSpellIndexCursor == 39 || GameActions.LastSpellIndexCursor == 47 || GameActions.LastSpellIndexCursor == 50) { //Calc _fieldEastToWest @@ -748,7 +751,7 @@ public static bool StaticFieldPreview(Static obj) } } } - if (GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) + if (GameActions.LastSpellIndexCursor == 22 || GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) { if (SelectedObject.Object != null && (SelectedObject.Object.RealScreenPosition.X + 22) == obj.RealScreenPosition.X && (SelectedObject.Object.RealScreenPosition.Y + 22) == obj.RealScreenPosition.Y) { @@ -850,6 +853,9 @@ public static bool StaticFieldPreview(Static obj) } return false; } + + + public static bool LandFieldPreview(Land obj) { if (GameCursor._spellTime >= 1) @@ -911,6 +917,7 @@ public static bool LandFieldPreview(Land obj) } } } + if (GameActions.LastSpellIndexCursor == 28 || GameActions.LastSpellIndexCursor == 39 || GameActions.LastSpellIndexCursor == 47 || GameActions.LastSpellIndexCursor == 50) { //Calc _fieldEastToWest @@ -982,7 +989,7 @@ public static bool LandFieldPreview(Land obj) } } } - if (GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) + if (GameActions.LastSpellIndexCursor == 22 || GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) { if (SelectedObject.Object != null && (SelectedObject.Object.RealScreenPosition.X + 22) == obj.RealScreenPosition.X && (SelectedObject.Object.RealScreenPosition.Y + 22) == obj.RealScreenPosition.Y) { @@ -1088,6 +1095,7 @@ public static bool MobileFieldPreview(Mobile obj) { if (GameCursor._spellTime >= 1) { + if (GameActions.LastSpellIndexCursor == 24) { //Calc _fieldEastToWest @@ -1145,6 +1153,7 @@ public static bool MobileFieldPreview(Mobile obj) } } } + if (GameActions.LastSpellIndexCursor == 28 || GameActions.LastSpellIndexCursor == 39 || GameActions.LastSpellIndexCursor == 47 || GameActions.LastSpellIndexCursor == 50) { //Calc _fieldEastToWest @@ -1216,7 +1225,7 @@ public static bool MobileFieldPreview(Mobile obj) } } } - if (GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) + if (GameActions.LastSpellIndexCursor == 22 || GameActions.LastSpellIndexCursor == 48 || GameActions.LastSpellIndexCursor == 49 || GameActions.LastSpellIndexCursor == 55) { if (SelectedObject.Object != null && (SelectedObject.Object.RealScreenPosition.X + 22) == obj.RealScreenPosition.X && (SelectedObject.Object.RealScreenPosition.Y + 22) == obj.RealScreenPosition.Y) { @@ -1343,7 +1352,7 @@ public static void SpellCastFromCliloc(string text) if (ProfileManager.CurrentProfile.OnCastingGump) { if (!GameActions.iscasting) - World.Player.OnCasting.Start((uint) GameActions.LastSpellIndexCursor); + World.Player.OnCasting.Start((uint)GameActions.LastSpellIndexCursor); } // ## BEGIN - END ## // ONCASTINGGUMP } @@ -1355,7 +1364,7 @@ public static ushort SpellIconHue(ushort hue) switch (TargetManager.TargetingType) { case TargetType.Neutral: - hue = 0x0000; //BETTER HUE? 0x03B2 + hue = 0x03B2; //BETTER HUE? 0x03B2 return hue; case TargetType.Harmful: @@ -1489,8 +1498,8 @@ public static void HarmOnSwing() public static Point CalcUnderChar5(Mobile mobile) { Point p = mobile.RealScreenPosition; - p.X += (int) mobile.Offset.X + 22 + 5; - p.Y += (int) (mobile.Offset.Y - mobile.Offset.Z) + 22 + 5; + p.X += (int)mobile.Offset.X + 22 + 5; + p.Y += (int)(mobile.Offset.Y - mobile.Offset.Z) + 22 + 5; p = Client.Game.Scene.Camera.WorldToScreen(p); @@ -1500,8 +1509,8 @@ public static Point CalcUnderChar5(Mobile mobile) public static Point CalcUnderChar(Mobile mobile) { Point p = mobile.RealScreenPosition; - p.X += (int) mobile.Offset.X + 22; - p.Y += (int) (mobile.Offset.Y - mobile.Offset.Z) + 22; + p.X += (int)mobile.Offset.X + 22; + p.Y += (int)(mobile.Offset.Y - mobile.Offset.Z) + 22; p = Client.Game.Scene.Camera.WorldToScreen(p); @@ -1510,8 +1519,8 @@ public static Point CalcUnderChar(Mobile mobile) public static Point CalcOverChar(Mobile mobile) { Point p = mobile.RealScreenPosition; - p.X += (int) mobile.Offset.X + 22; - p.Y += (int) (mobile.Offset.Y - mobile.Offset.Z) + 22; + p.X += (int)mobile.Offset.X + 22; + p.Y += (int)(mobile.Offset.Y - mobile.Offset.Z) + 22; AnimationsLoader.Instance.GetAnimationDimensions ( @@ -1532,8 +1541,8 @@ out int height Point p1 = p; - p1.X = (int) (mobile.RealScreenPosition.X + mobile.Offset.X + 22); - p1.Y = (int) (mobile.RealScreenPosition.Y + (mobile.Offset.Y - mobile.Offset.Z) - (height + centerY + 8 + 22) + (mobile.IsGargoyle && mobile.IsFlying ? -22 : !mobile.IsMounted ? 22 : 0)); + p1.X = (int)(mobile.RealScreenPosition.X + mobile.Offset.X + 22); + p1.Y = (int)(mobile.RealScreenPosition.Y + (mobile.Offset.Y - mobile.Offset.Z) - (height + centerY + 8 + 22) + (mobile.IsGargoyle && mobile.IsFlying ? -22 : !mobile.IsMounted ? 22 : 0)); if (mobile.ObjectHandlesStatus == ObjectHandlesStatus.DISPLAYING) { diff --git a/src/ClassicUO.Client/Game/GameActions.cs b/src/ClassicUO.Client/Game/GameActions.cs index 2027f869c..1a6c65855 100644 --- a/src/ClassicUO.Client/Game/GameActions.cs +++ b/src/ClassicUO.Client/Game/GameActions.cs @@ -32,6 +32,7 @@ using System; using ClassicUO.Configuration; +using ClassicUO.Dust765.Dust765; using ClassicUO.Game.Data; using ClassicUO.Game.GameObjects; using ClassicUO.Game.Managers; @@ -720,6 +721,7 @@ public static void CastSpellFromBook(int index, uint bookSerial) // ## BEGIN - END ## // VISUAL HELPERS LastSpellIndexCursor = index; GameCursor._spellTime = 0; + // ## BEGIN - END ## // VISUAL HELPERS // ## BEGIN - END ## // ONCASTINGGUMP if (ProfileManager.CurrentProfile.OnCastingGump) @@ -741,6 +743,8 @@ public static void CastSpell(int index) // ## BEGIN - END ## // VISUAL HELPERS LastSpellIndexCursor = index; GameCursor._spellTime = 0; + CombatCollection.StartSpelltime(); + // ## BEGIN - END ## // VISUAL HELPERS // ## BEGIN - END ## // ONCASTINGGUMP if (ProfileManager.CurrentProfile.OnCastingGump) @@ -751,6 +755,7 @@ public static void CastSpell(int index) // ## BEGIN - END ## // ONCASTINGGUMP LastSpellIndex = index; + Socket.Send_CastSpell(index); } } diff --git a/src/ClassicUO.Client/Game/GameObjects/Views/LandView.cs b/src/ClassicUO.Client/Game/GameObjects/Views/LandView.cs index 10a4658c3..74774f580 100644 --- a/src/ClassicUO.Client/Game/GameObjects/Views/LandView.cs +++ b/src/ClassicUO.Client/Game/GameObjects/Views/LandView.cs @@ -91,7 +91,7 @@ public override bool Draw(UltimaBatcher2D batcher, int posX, int posY, float dep } if (ProfileManager.CurrentProfile.HighlightTileAtRangeSpell) { - if (GameCursor._spellTime >= 1 && Distance == ProfileManager.CurrentProfile.HighlightTileAtRangeRangeSpell) + if (GameActions.LastSpellIndexCursor > 0 && Distance == ProfileManager.CurrentProfile.HighlightTileAtRangeRangeSpell) { hueVec.X = ProfileManager.CurrentProfile.HighlightTileRangeHueSpell; hueVec.Y = 1; diff --git a/src/ClassicUO.Client/Game/GameObjects/Views/MultiView.cs b/src/ClassicUO.Client/Game/GameObjects/Views/MultiView.cs index 0f64b2bd9..74c2da8f9 100644 --- a/src/ClassicUO.Client/Game/GameObjects/Views/MultiView.cs +++ b/src/ClassicUO.Client/Game/GameObjects/Views/MultiView.cs @@ -123,7 +123,7 @@ public override bool Draw(UltimaBatcher2D batcher, int posX, int posY, float dep } if (ProfileManager.CurrentProfile.HighlightTileAtRangeSpell) { - if (GameCursor._spellTime >= 1 && Distance == ProfileManager.CurrentProfile.HighlightTileAtRangeRangeSpell) + if (GameActions.LastSpellIndexCursor > 0 && Distance == ProfileManager.CurrentProfile.HighlightTileAtRangeRangeSpell) { hueVec.X = ProfileManager.CurrentProfile.HighlightTileRangeHueSpell; hueVec.Y = 1; diff --git a/src/ClassicUO.Client/Game/GameObjects/Views/StaticView.cs b/src/ClassicUO.Client/Game/GameObjects/Views/StaticView.cs index e1a49f165..892e5233a 100644 --- a/src/ClassicUO.Client/Game/GameObjects/Views/StaticView.cs +++ b/src/ClassicUO.Client/Game/GameObjects/Views/StaticView.cs @@ -102,7 +102,7 @@ public override bool Draw(UltimaBatcher2D batcher, int posX, int posY, float dep } if (ProfileManager.CurrentProfile.HighlightTileAtRangeSpell) { - if (GameCursor._spellTime >= 1 && Distance == ProfileManager.CurrentProfile.HighlightTileAtRangeRangeSpell) + if (GameActions.LastSpellIndexCursor > 0 && Distance == ProfileManager.CurrentProfile.HighlightTileAtRangeRangeSpell) { hueVec.X = ProfileManager.CurrentProfile.HighlightTileRangeHueSpell; hueVec.Y = 1; diff --git a/src/ClassicUO.Client/Game/Managers/PartyManager.cs b/src/ClassicUO.Client/Game/Managers/PartyManager.cs index 028e231e2..ebed383e0 100644 --- a/src/ClassicUO.Client/Game/Managers/PartyManager.cs +++ b/src/ClassicUO.Client/Game/Managers/PartyManager.cs @@ -31,6 +31,7 @@ #endregion using System; +using Microsoft.Extensions.Caching.Memory; using ClassicUO.Configuration; using ClassicUO.Game.Data; using ClassicUO.Game.GameObjects; @@ -38,6 +39,7 @@ using ClassicUO.IO; using ClassicUO.Network; using ClassicUO.Resources; +using System.Collections.Generic; namespace ClassicUO.Game.Managers { @@ -55,6 +57,8 @@ internal class PartyManager public long PartyHealTimer { get; set; } public uint PartyHealTarget { get; set; } + + public void ParsePacket(ref StackDataReader p) { byte code = p.ReadUInt8(); @@ -246,6 +250,7 @@ public void Clear() internal class PartyMember : IEquatable { private string _name; + public Dictionary nameCache = new Dictionary(); public PartyMember(uint serial) { @@ -262,10 +267,19 @@ public string Name if (mobile != null) { _name = mobile.Name; + nameCache[mobile.Serial] = _name; if (string.IsNullOrEmpty(_name)) { - _name = ResGeneral.NotSeeing; + if (nameCache.TryGetValue(Serial, out string cachedName)) + { + _name = string.IsNullOrEmpty(_name) ? cachedName : _name; + } + else + { + _name = ResGeneral.NotSeeing; + } + } } diff --git a/src/ClassicUO.Client/Game/Managers/WorldMapEntityManager.cs b/src/ClassicUO.Client/Game/Managers/WorldMapEntityManager.cs index 81e86ce84..2d0653bf3 100644 --- a/src/ClassicUO.Client/Game/Managers/WorldMapEntityManager.cs +++ b/src/ClassicUO.Client/Game/Managers/WorldMapEntityManager.cs @@ -30,6 +30,8 @@ #endregion +using System; +using Microsoft.Extensions.Caching.Memory; using System.Collections.Generic; using ClassicUO.Configuration; using ClassicUO.Game.Data; @@ -38,38 +40,73 @@ using ClassicUO.Network; using ClassicUO.Network.Encryption; using ClassicUO.Utility.Logging; +using static System.Net.Mime.MediaTypeNames; namespace ClassicUO.Game.Managers { internal class WMapEntity { + public bool IsGuild; + public uint LastUpdate; + public string Name; + public uint Serial; + public int X, Y, HP, Map; + public static readonly Dictionary nameCache = new Dictionary(); + public WMapEntity(uint serial) { - Serial = serial; + GetName(serial); + } - //var mob = World.Mobiles.Get(serial); + // ## BEGIN - START ## // DUST765 - Fix to use cache for name in Map Gump + public string GetName(uint serial) + { - //if (mob != null) - // GetName(); - } + Mobile mob = World.Mobiles.Get(serial); + Entity e = World.Get(serial); - public bool IsGuild; - public uint LastUpdate; - public string Name; - public readonly uint Serial; - public int X, Y, HP, Map; - //public string GetName() - //{ - // Entity e = World.Get(Serial); + if (mob != null && !mob.IsDestroyed) + { + WMapEntity wme = World.WMapManager.GetEntity(mob); + + if (wme != null) + { + if (string.IsNullOrEmpty(wme.Name)) + { + + wme.Name = mob.Name; + Name = wme.Name; + nameCache[serial] = Name; + GameActions.Print("Mob is not null Is wme != null " + wme.Serial + " Name: " + mob.Name + " nameCache: " + nameCache[serial]); + } + } + } + if (e != null) + { + Name = e.Name; + serial = e.Serial; + nameCache[serial] = Name; + GameActions.Print("Entity is not null Is wme != null " + e.Name + " Name: " + mob.Name + " nameCache: " + nameCache[serial]); + } + + + if (nameCache.TryGetValue(serial, out string cachedName)) + { + var teste = string.IsNullOrEmpty(Name) ? cachedName : Name; + GameActions.Print("Entity is not null Is wme != null " + teste); + return string.IsNullOrEmpty(Name) ? cachedName : Name; + } + else + { + return string.IsNullOrEmpty(Name) ? "" : Name; + } + + - // if (e != null && !e.IsDestroyed && !string.IsNullOrEmpty(e.Name) && Name != e.Name) - // { - // Name = e.Name; - // } - // return string.IsNullOrEmpty(Name) ? "" : Name; - //} + // ## BEGIN - END ## // DUST765 - Fix to use cache for name in Map Gump + } } internal class WorldMapEntityManager @@ -77,7 +114,8 @@ internal class WorldMapEntityManager private bool _ackReceived; private uint _lastUpdate, _lastPacketSend, _lastPacketRecv; private readonly List _toRemove = new List(); - // ## BEGIN - END ## // TAZUO + public static readonly Dictionary nameCache = new Dictionary(); + // ## BEGIN - START ## // TAZUO public WMapEntity _corpse; // ## BEGIN - END ## // TAZUO @@ -87,7 +125,7 @@ public bool Enabled { return ((World.ClientFeatures.Flags & CharacterListFlags.CLF_NEW_MOVEMENT_SYSTEM) == 0 || _ackReceived) && EncryptionHelper.Type == 0 && - ProfileManager.CurrentProfile != null && ProfileManager.CurrentProfile.WorldMapShowParty && + ProfileManager.CurrentProfile != null && ProfileManager.CurrentProfile.WorldMapShowParty && UIManager.GetGump() != null; // horrible, but works } } @@ -156,12 +194,17 @@ public void AddOrUpdate if (!Entities.TryGetValue(serial, out WMapEntity entity) || entity == null) { + var nameFilter = name != "" ? name : entity.GetName(serial); entity = new WMapEntity(serial) { - X = x, Y = y, HP = hp, Map = map, + + X = x, + Y = y, + HP = hp, + Map = map, LastUpdate = Time.Ticks + 1000, IsGuild = isguild, - Name = name + Name = nameFilter }; Entities[serial] = entity; @@ -177,7 +220,9 @@ public void AddOrUpdate if (string.IsNullOrEmpty(entity.Name) && !string.IsNullOrEmpty(name)) { - entity.Name = name; + + entity.Name = entity.IsGuild ? name : entity.GetName(serial); + } } } @@ -270,6 +315,29 @@ public void RequestServerPartyGuildInfo(bool force = false) } } } + else + { + foreach (Mobile mob in World.Mobiles.Values) + { + if (mob == World.Player) + { + continue; + } + + Mobile mobs = World.Mobiles.Get(mob.Serial); + if (mobs.NotorietyFlag == NotorietyFlag.Ally) + { + if (mobs == null || mobs.Distance > 2000000) + { + NetClient.Socket.Send_QueryGuildPosition(); + + break; + } + } + + } + + } } } diff --git a/src/ClassicUO.Client/Game/Scenes/GameScene.cs b/src/ClassicUO.Client/Game/Scenes/GameScene.cs index 81a21ab58..be9ec33ea 100644 --- a/src/ClassicUO.Client/Game/Scenes/GameScene.cs +++ b/src/ClassicUO.Client/Game/Scenes/GameScene.cs @@ -450,7 +450,6 @@ public override void Unload() // special case for wmap. this allow us to save settings UIManager.GetGump()?.SaveSettings(); - ProfileManager.CurrentProfile?.Save(ProfileManager.ProfilePath); Macros.Save(); diff --git a/src/ClassicUO.Client/Game/UI/Controls/PaperDollInteractable.cs b/src/ClassicUO.Client/Game/UI/Controls/PaperDollInteractable.cs index 797c262f1..027d2c0d4 100644 --- a/src/ClassicUO.Client/Game/UI/Controls/PaperDollInteractable.cs +++ b/src/ClassicUO.Client/Game/UI/Controls/PaperDollInteractable.cs @@ -354,7 +354,7 @@ public void RequestUpdate() _updateUI = true; } - private static ushort GetAnimID(ushort graphic, ushort animID, bool isfemale) + public static ushort GetAnimID(ushort graphic, ushort animID, bool isfemale) { int offset = isfemale ? Constants.FEMALE_GUMP_OFFSET : Constants.MALE_GUMP_OFFSET; @@ -395,7 +395,7 @@ private static ushort GetAnimID(ushort graphic, ushort animID, bool isfemale) return (ushort) (animID + offset); } - private class GumpPicEquipment : GumpPic + public class GumpPicEquipment : GumpPic { private readonly Layer _layer; diff --git a/src/ClassicUO.Client/Game/UI/Gumps/RaceChangeGump.cs b/src/ClassicUO.Client/Game/UI/Gumps/RaceChangeGump.cs new file mode 100644 index 000000000..afa2cd1bb --- /dev/null +++ b/src/ClassicUO.Client/Game/UI/Gumps/RaceChangeGump.cs @@ -0,0 +1,813 @@ +using ClassicUO.Assets; +using ClassicUO.Configuration; +using ClassicUO.Game.Data; +using ClassicUO.Game.GameObjects; +using ClassicUO.Game.Managers; +using ClassicUO.Game.UI.Controls; +using ClassicUO.Input; +using ClassicUO.Network; +using System; +using System.Collections.Generic; + +namespace ClassicUO.Game.UI.Gumps +{ + internal class RaceChangeGump : Gump + { + private bool isFemale { get; } = false; + private RaceType selectedRace { get; } = RaceType.HUMAN; + private PlayerMobile fakeMobile; + private CustomPaperDollGump paperDollInteractable; + private readonly Dictionary> CurrentColorOption = new Dictionary>(); + private readonly Dictionary CurrentOption = new Dictionary() + { + { + Layer.Hair, 1 + }, + { + Layer.Beard, 0 + } + }; + private Item hair, beard; + + #region + private ushort raceTextGraphic + { + get + { + switch (selectedRace) + { + case RaceType.HUMAN: + return 0x702; + case RaceType.ELF: + return 0x705; + case RaceType.GARGOYLE: + return 0x7D4; + } + return 0; + } + } + private int raceTextWidth + { + get + { + switch (selectedRace) + { + case RaceType.HUMAN: + return 79; + case RaceType.ELF: + return 79; + case RaceType.GARGOYLE: + return 99; + } + return 0; + } + } + private ushort genderTextGraphic + { + get + { + return (ushort)(isFemale ? 0x70D : 0x710); + } + } + #endregion + + public RaceChangeGump(bool isFemale, byte race) : base(0, 0) + { + if (race <= 0 || race > (int)RaceType.GARGOYLE) + { + //Invalid race byte + Dispose(); + return; + } + + selectedRace = (RaceType)race; + this.isFemale = isFemale; + + X = 50; + Y = 50; + CanMove = false; + CanCloseWithRightClick = true; + AcceptMouseInput = true; + + BuildGump(); + + WantUpdateSize = true; + } + + private void BuildGump() + { + #region Background elements + Add + ( + new ResizePic(0x0E10) + { + X = 0, + Y = 0, + Width = 595, + Height = 400 + }, + 1 + ); //Main background + + Add + ( + new ResizePic(0x0E10) + { + X = 25, + Y = 45, + Width = 151, + Height = 310 + }, + 1 + ); //Left side, hair style etc + + Add + ( + new ResizePic(0x0E10) + { + X = 419, + Y = 45, + Width = 151, + Height = 310 + }, + 1 + ); //Right side tone/colors + #endregion + + Add(new GumpPic(176 - raceTextWidth, 360, raceTextGraphic, 0)); //non-functional "Button" that says Human, Elf, or Gargoyle + + Add(new GumpPic(419, 360, genderTextGraphic, 0)); //non-functional "Button" that says Male or Female + + Button confirmButton; + Add(confirmButton = new Button(0, 0x15A4, 0x15A6, 0x15A5) { X = 560, Y = 360 }); //Button to confirm, in classic client it is an arrow pointing right. + confirmButton.MouseUp += ConfirmButton_MouseUp; + + //Add hair styles + BuildHairStyles(40, 60); + + //Add color pickers + BuildColorOptions(434, 60); + + //Create fake character + CreateCharacter(); + UpdateEquipments(); + + //Add the main paperdoll graphic + Add(new GumpPic(185, 25, 0x708, 0)); + Add + ( + paperDollInteractable = new CustomPaperDollGump(210, 75, fakeMobile, hair, beard) + { + AcceptMouseInput = false + } + ); + + paperDollInteractable.RequestUpdate(); + + Add(new GumpPic(211, 15, 0x769, 0)); //Character Race Changer text + } + + /// + /// Build hair options for race change gump. + /// + /// The starting point for these ui elements + /// The starting point for these ui elements + private void BuildHairStyles(int x, int y) + { + #region TextSetup + bool isAsianLang = string.Compare(Settings.GlobalSettings.Language, "CHT", StringComparison.InvariantCultureIgnoreCase) == 0 || + string.Compare(Settings.GlobalSettings.Language, "KOR", StringComparison.InvariantCultureIgnoreCase) == 0 || + string.Compare(Settings.GlobalSettings.Language, "JPN", StringComparison.InvariantCultureIgnoreCase) == 0; + + bool unicode = isAsianLang; + byte font = (byte)(isAsianLang ? 3 : 9); + ushort hue = (ushort)(isAsianLang ? 0xFFFF : 0); + #endregion + + CharacterCreationValues.ComboContent content = CharacterCreationValues.GetHairComboContent(isFemale, selectedRace); + + CurrentOption[Layer.Beard] = 0; + CurrentOption[Layer.Hair] = 1; + + #region Hair style + Add + ( + new Label(ClilocLoader.Instance.GetString(selectedRace == RaceType.GARGOYLE ? 1112309 : 3000121), unicode, hue, font: font) + { + X = x + 1, + Y = y + } + ); + y += 15; + + Combobox hair; + Add + (hair = + new Combobox + ( + x, + y, + 120, + content.Labels, + CurrentOption[Layer.Hair] + ) + ); + hair.OnOptionSelected += (s, e) => + { + CurrentOption[Layer.Hair] = e; + UpdateEquipments(); + paperDollInteractable.RequestUpdate(this.hair, beard); + }; + y += 30; + #endregion + + #region Facial Hair + if (!isFemale && selectedRace != RaceType.ELF) + { + content = CharacterCreationValues.GetFacialHairComboContent(selectedRace); + + Add + ( + new Label(ClilocLoader.Instance.GetString(selectedRace == RaceType.GARGOYLE ? 1112511 : 3000122), unicode, hue, font: font) + { + X = x + 1, + Y = y + } + ); + y += 15; + + Combobox facialHair; + Add + (facialHair = + new Combobox + ( + x, + y, + 120, + content.Labels, + CurrentOption[Layer.Beard] + ) + ); + facialHair.OnOptionSelected += (s, e) => + { + CurrentOption[Layer.Beard] = e; + UpdateEquipments(); + paperDollInteractable.RequestUpdate(this.hair, beard); + }; + } + #endregion + } + + /// + /// Build color options for race change gump + /// + /// The starting point for these ui elements + /// The starting point for these ui elements + private void BuildColorOptions(int x, int y) + { + ushort[] pallet = CharacterCreationValues.GetSkinPallet(selectedRace); + + AddCustomColorPicker + ( + x, + y, + pallet, + Layer.Invalid, + 3000183, + 8, + pallet.Length >> 3 + ); + y += 42; + + // Hair + pallet = CharacterCreationValues.GetHairPallet(selectedRace); + + AddCustomColorPicker + ( + x, + y, + pallet, + Layer.Hair, + selectedRace == RaceType.GARGOYLE ? 1112322 : 3000184, + 8, + pallet.Length >> 3 + ); + y += 42; + + if (!isFemale && selectedRace != RaceType.ELF) + { + // Facial + pallet = CharacterCreationValues.GetHairPallet(selectedRace); + + AddCustomColorPicker + ( + x, + y, + pallet, + Layer.Beard, + selectedRace == RaceType.GARGOYLE ? 1112512 : 3000446, + 8, + pallet.Length >> 3 + ); + } + } + + /// + /// Must be called *after* color options have been set up. + /// + private void CreateCharacter() + { + #region Create a fake character to use for the gump + if (fakeMobile == null || fakeMobile.IsDestroyed) + { + fakeMobile = new PlayerMobile(1); + World.Mobiles.Add(fakeMobile); + } + + LinkedObject first = fakeMobile.Items; + + while (first != null) + { + LinkedObject next = first.Next; + + World.RemoveItem((Item)first, true); + + first = next; + } + + fakeMobile.Clear(); + fakeMobile.Race = selectedRace; + fakeMobile.IsFemale = isFemale; + + if (isFemale) + { + fakeMobile.Flags |= Flags.Female; + } + else + { + fakeMobile.Flags &= ~Flags.Female; + } + #endregion + + if (selectedRace == RaceType.ELF) + { + fakeMobile.Graphic = (ushort)(isFemale ? 0x025E : 0x025D); + } + else + { + fakeMobile.Graphic = (ushort)(isFemale ? 0x0191 : 0x0190); + } + } + + private void AddCustomColorPicker + ( + int x, + int y, + ushort[] pallet, + Layer layer, + int clilocLabel, + int rows, + int columns + ) + { + CustomColorPicker colorPicker; + + Add + ( + colorPicker = new CustomColorPicker + ( + layer, + clilocLabel, + pallet, + rows, + columns + ) + { + X = x, + Y = y + }, + 1 + ); + + if (!CurrentColorOption.ContainsKey(layer)) + { + CurrentColorOption[layer] = new Tuple(0, colorPicker.HueSelected); + } + else + { + colorPicker.SetSelectedIndex(CurrentColorOption[layer].Item1); + } + + colorPicker.ColorSelected += ColorPicker_ColorSelected; + } + + private void ColorPicker_ColorSelected(object sender, ColorSelectedEventArgs e) + { + if (e.SelectedIndex == 0xFFFF) + { + return; + } + + CurrentColorOption[e.Layer] = new Tuple(e.SelectedIndex, e.SelectedHue); + + if (e.Layer != Layer.Invalid) + { + Item item = fakeMobile.FindItemByLayer(e.Layer); + + if (item != null) + { + item.Hue = e.SelectedHue; + } + } + else + { + fakeMobile.Hue = e.SelectedHue; + } + + paperDollInteractable.RequestUpdate(hair, beard); + } + + private void ConfirmButton_MouseUp(object sender, Input.MouseEventArgs e) + { + if (e.Button == Input.MouseButtonType.Left) + { + NetClient.Socket.Send_ChangeRaceRequest( + CurrentColorOption[Layer.Invalid].Item2, + (ushort)CharacterCreationValues.GetHairComboContent(isFemale, selectedRace).GetGraphic(CurrentOption[Layer.Hair]), + CurrentColorOption[Layer.Hair].Item2, + (ushort)CharacterCreationValues.GetFacialHairComboContent(selectedRace).GetGraphic(CurrentOption[Layer.Beard]), + CurrentColorOption[Layer.Beard].Item2 + ); + Dispose(); + } + } + + private void UpdateEquipments() + { + Layer layer; + CharacterCreationValues.ComboContent content; + + fakeMobile.Hue = CurrentColorOption[Layer.Invalid].Item2; + + if (!isFemale && selectedRace != RaceType.ELF) + { + layer = Layer.Beard; + content = CharacterCreationValues.GetFacialHairComboContent(selectedRace); + + beard = CreateItem(content.GetGraphic(CurrentOption[layer]), CurrentColorOption[layer].Item2, layer); + } + + layer = Layer.Hair; + content = CharacterCreationValues.GetHairComboContent(isFemale, selectedRace); + + hair = CreateItem(content.GetGraphic(CurrentOption[layer]), CurrentColorOption[layer].Item2, layer); + } + + private Item CreateItem(int id, ushort hue, Layer layer) + { + Item existsItem = fakeMobile.FindItemByLayer(layer); + + if (existsItem != null) + { + World.RemoveItem(existsItem, true); + fakeMobile.Remove(existsItem); + } + + if (id == 0) + { + return null; + } + // This is a workaround to avoid to see naked guy + // We are simulating server objects into World.Items map. + Item item = World.GetOrCreateItem(0x4000_0000 + (uint)layer); // use layer as unique Serial + fakeMobile.Remove(item); + item.Graphic = (ushort)id; + item.Hue = hue; + item.Layer = layer; + item.Container = fakeMobile; + fakeMobile.PushToBack(item); + // + + return item; + } + + #region Classes + private class ColorSelectedEventArgs : EventArgs + { + public ColorSelectedEventArgs(Layer layer, ushort[] pallet, int selectedIndex) + { + Layer = layer; + Pallet = pallet; + SelectedIndex = selectedIndex; + } + + public Layer Layer { get; } + + private ushort[] Pallet { get; } + + public int SelectedIndex { get; } + + public ushort SelectedHue => Pallet != null && SelectedIndex >= 0 && SelectedIndex < Pallet.Length ? Pallet[SelectedIndex] : (ushort)0xFFFF; + } + + private class CustomColorPicker : Control + { + //private readonly ColorBox _box; + private readonly int _cellH; + private readonly int _cellW; + private readonly ColorBox _colorPicker; + private ColorPickerBox _colorPickerBox; + private readonly int _columns, _rows; + private int _lastSelectedIndex; + private readonly Layer _layer; + private readonly ushort[] _pallet; + + public CustomColorPicker(Layer layer, int label, ushort[] pallet, int rows, int columns) + { + Width = 121; + Height = 25; + _cellW = 125 / columns; + _cellH = 280 / rows; + _columns = columns; + _rows = rows; + _layer = layer; + _pallet = pallet; + + bool isAsianLang = string.Compare(Settings.GlobalSettings.Language, "CHT", StringComparison.InvariantCultureIgnoreCase) == 0 || + string.Compare(Settings.GlobalSettings.Language, "KOR", StringComparison.InvariantCultureIgnoreCase) == 0 || + string.Compare(Settings.GlobalSettings.Language, "JPN", StringComparison.InvariantCultureIgnoreCase) == 0; + + bool unicode = isAsianLang; + byte font = (byte)(isAsianLang ? 3 : 9); + ushort hue = (ushort)(isAsianLang ? 0xFFFF : 0); + + Add + ( + new Label(ClilocLoader.Instance.GetString(label), unicode, hue, font: font) + { + X = 0, + Y = 0 + } + ); + + Add + ( + _colorPicker = new ColorBox(121, 23, (ushort)((pallet?[0] ?? 1) + 1)) + { + X = 1, + Y = 15 + } + ); + + _colorPicker.MouseUp += ColorPicker_MouseClick; + } + + public ushort HueSelected => _colorPicker.Hue; + + public event EventHandler ColorSelected; + + public void SetSelectedIndex(int index) + { + if (_colorPickerBox != null) + { + _colorPickerBox.SelectedIndex = index; + + SetCurrentHue(); + } + } + + private void SetCurrentHue() + { + _colorPicker.Hue = _colorPickerBox.SelectedHue; + _lastSelectedIndex = _colorPickerBox.SelectedIndex; + + _colorPickerBox.Dispose(); + } + + private void ColorPickerBoxOnMouseUp(object sender, MouseEventArgs e) + { + int column = e.X / _cellW; + int row = e.Y / _cellH; + int selectedIndex = row * _columns + column; + + if (selectedIndex >= 0 && selectedIndex < _colorPickerBox.Hues.Length) + { + ColorSelected?.Invoke(this, new ColorSelectedEventArgs(_layer, _colorPickerBox.Hues, selectedIndex)); + SetCurrentHue(); + } + } + + private void ColorPicker_MouseClick(object sender, MouseEventArgs e) + { + if (e.Button == MouseButtonType.Left) + { + _colorPickerBox?.Dispose(); + _colorPickerBox = null; + + if (_colorPickerBox == null) + { + _colorPickerBox = new ColorPickerBox + ( + 485, + 109, + _rows, + _columns, + _cellW, + _cellH, + _pallet + ) + { + IsModal = true, + LayerOrder = UILayer.Over, + ModalClickOutsideAreaClosesThisControl = true, + ShowLivePreview = false, + SelectedIndex = _lastSelectedIndex + }; + + UIManager.Add(_colorPickerBox); + + _colorPickerBox.ColorSelectedIndex += ColorPickerBoxOnColorSelectedIndex; + _colorPickerBox.MouseUp += ColorPickerBoxOnMouseUp; + } + } + } + + private void ColorPickerBoxOnColorSelectedIndex(object sender, EventArgs e) + { + ColorSelected?.Invoke(this, new ColorSelectedEventArgs(_layer, _colorPickerBox.Hues, _colorPickerBox.SelectedIndex)); + } + } + + /// + /// Partially custom paperdoll gump required, when in-game the fake character created gets automatically removed and breaks the original paperdoll gump. + /// + private class CustomPaperDollGump : PaperDollInteractable + { + private readonly Mobile playerMobile; + private Item hair; + private Item beard; + private bool requestUpdate = false; + + public CustomPaperDollGump(int x, int y, Mobile playerMobile, Item hair, Item beard) : base(x, y, playerMobile, null) + { + this.playerMobile = playerMobile; + this.hair = hair; + this.beard = beard; + } + + private void UpdateUI() + { + if (IsDisposed) + { + return; + } + + Mobile mobile = playerMobile; + + if (mobile == null) + { + Dispose(); + + return; + } + + Clear(); + + #region Add the base gump - the semi-naked paper doll. + ushort body; + ushort hue = mobile.Hue; + + if (mobile.Graphic == 0x0191 || mobile.Graphic == 0x0193) + { + body = 0x000D; + } + else if (mobile.Graphic == 0x025D) + { + body = 0x000E; + } + else if (mobile.Graphic == 0x025E) + { + body = 0x000F; + } + else if (mobile.Graphic == 0x029A || mobile.Graphic == 0x02B6) + { + body = 0x029A; + } + else if (mobile.Graphic == 0x029B || mobile.Graphic == 0x02B7) + { + body = 0x0299; + } + else if (mobile.Graphic == 0x04E5) + { + body = 0xC835; + } + else if (mobile.Graphic == 0x03DB) + { + body = 0x000C; + hue = 0x03EA; + } + else if (mobile.IsFemale) + { + body = 0x000D; + } + else + { + body = 0x000C; + } + + // body + Add + ( + new GumpPic(0, 0, body, hue) + { + IsPartialHue = true + } + ); + + + if (mobile.Graphic == 0x03DB) + { + Add + ( + new GumpPic(0, 0, 0xC72B, mobile.Hue) + { + AcceptMouseInput = true, + IsPartialHue = true + } + ); + } + #endregion + + // equipment + + if (hair != null) + { + ushort id = GetAnimID(mobile.Graphic, hair.ItemData.AnimID, mobile.IsFemale); + + Add + ( + new GumpPicEquipment + ( + hair.Serial, + 0, + 0, + id, + (ushort)(hair.Hue & 0x3FFF), + Layer.Hair + ) + { + AcceptMouseInput = true, + IsPartialHue = hair.ItemData.IsPartialHue, + CanLift = false + } + ); + } + + if (beard != null) + { + ushort id = GetAnimID(mobile.Graphic, beard.ItemData.AnimID, mobile.IsFemale); + + Add + ( + new GumpPicEquipment + ( + beard.Serial, + 0, + 0, + id, + (ushort)(beard.Hue & 0x3FFF), + Layer.Beard + ) + { + AcceptMouseInput = true, + IsPartialHue = beard.ItemData.IsPartialHue, + CanLift = false + } + ); + } + } + + public void RequestUpdate(Item hair, Item beard) + { + this.hair = hair; + this.beard = beard; + requestUpdate = true; + } + + public new void RequestUpdate() + { + requestUpdate = true; + } + + public override void Update() + { + if (requestUpdate) + { + UpdateUI(); + requestUpdate = false; + } + } + } + #endregion + } +} \ No newline at end of file diff --git a/src/ClassicUO.Client/Game/UI/Gumps/WorldMapGump.cs b/src/ClassicUO.Client/Game/UI/Gumps/WorldMapGump.cs index 3bbad18e1..c81d165dc 100644 --- a/src/ClassicUO.Client/Game/UI/Gumps/WorldMapGump.cs +++ b/src/ClassicUO.Client/Game/UI/Gumps/WorldMapGump.cs @@ -180,7 +180,7 @@ public bool TopMost { _isTopMost = value; - SaveSettings(); + SaveSettings(); } ShowBorder = !_isTopMost; @@ -225,7 +225,7 @@ private void LoadSettings() ResizeWindow(new Point(Width, Height)); - _flipMap = ProfileManager.CurrentProfile.WorldMapFlipMap; + _flipMap = ProfileManager.CurrentProfile.WorldMapFlipMap; _showPartyMembers = ProfileManager.CurrentProfile.WorldMapShowParty; World.WMapManager.SetEnable(_showPartyMembers); @@ -433,7 +433,7 @@ private void BuildOptionDictionary() _options["add_marker_on_player"] = new ContextMenuItemEntry(ResGumps.AddMarkerOnPlayer, () => AddMarkerOnPlayer()); _options["saveclose"] = new ContextMenuItemEntry(ResGumps.SaveClose, Dispose); - _options["show_grid_if_zoomed"] = new ContextMenuItemEntry(ResGumps.GridIfZoomed, () => { _showGridIfZoomed = !_showGridIfZoomed; SaveSettings(); }, true, _showGridIfZoomed); + _options["show_grid_if_zoomed"] = new ContextMenuItemEntry(ResGumps.GridIfZoomed, () => { _showGridIfZoomed = !_showGridIfZoomed; SaveSettings(); }, true, _showGridIfZoomed); } @@ -630,8 +630,8 @@ public override void Update() private Point RotatePoint(int x, int y, float zoom, int dist, float angle = 45f) { - x = (int) (x * zoom); - y = (int) (y * zoom); + x = (int)(x * zoom); + y = (int)(y * zoom); if (angle == 0.0f) { @@ -641,7 +641,7 @@ private Point RotatePoint(int x, int y, float zoom, int dist, float angle = 45f) double cos = Math.Cos(dist * Math.PI / 4.0); double sin = Math.Sin(dist * Math.PI / 4.0); - return new Point((int) Math.Round(cos * x - sin * y), (int) Math.Round(sin * x + cos * y)); + return new Point((int)Math.Round(cos * x - sin * y), (int)Math.Round(sin * x + cos * y)); } private void AdjustPosition @@ -866,7 +866,7 @@ private class CurLoader { public static unsafe Texture2D CreateTextureFromICO_Cur(Stream stream) { - byte[] buffer = System.Buffers.ArrayPool.Shared.Rent((int) stream.Length); + byte[] buffer = System.Buffers.ArrayPool.Shared.Rent((int)stream.Length); try { @@ -1152,8 +1152,8 @@ public static unsafe Texture2D CreateTextureFromICO_Cur(Stream stream) private static unsafe IntPtr INTERNAL_convertSurfaceFormat(IntPtr surface) { IntPtr result = surface; - SDL.SDL_Surface* surPtr = (SDL.SDL_Surface*) surface; - SDL.SDL_PixelFormat* pixelFormatPtr = (SDL.SDL_PixelFormat*) surPtr->format; + SDL.SDL_Surface* surPtr = (SDL.SDL_Surface*)surface; + SDL.SDL_PixelFormat* pixelFormatPtr = (SDL.SDL_PixelFormat*)surPtr->format; // SurfaceFormat.Color is SDL_PIXELFORMAT_ABGR8888 if (pixelFormatPtr->format != SDL.SDL_PIXELFORMAT_ABGR8888) @@ -1170,7 +1170,7 @@ private static unsafe IntPtr INTERNAL_convertSurfaceFormat(IntPtr surface) #region Loading - + private unsafe void LoadMapChunk(Span buffer, Span allZ, int chunkX, int chunkY) { if (World.Map == null) @@ -1315,7 +1315,7 @@ private void LoadMapDetails(Span buffer, Span allZ) } cc = (uint)(r | (g << 8) | (b << 16) | (a << 24)); - } + } } } @@ -1647,7 +1647,7 @@ internal class ZonesFile public List Zones { get; set; } } - private class Zone + private class Zone { public string Label; public Color Color; @@ -2166,9 +2166,9 @@ public override bool Draw(UltimaBatcher2D batcher, int x, int y) int centerX = _center.X + 1; int centerY = _center.Y + 1; - int size = (int) Math.Max(gWidth * 1.75f, gHeight * 1.75f); + int size = (int)Math.Max(gWidth * 1.75f, gHeight * 1.75f); - int size_zoom = (int) (size / Zoom); + int size_zoom = (int)(size / Zoom); int size_zoom_half = size_zoom >> 1; int halfWidth = gWidth >> 1; @@ -2248,7 +2248,7 @@ public override bool Draw(UltimaBatcher2D batcher, int x, int y) // { // batcher.Draw2D(Textures.GetTexture()) // } - //} + // } return base.Draw(batcher, x, y); @@ -2440,7 +2440,7 @@ private void DrawAll(UltimaBatcher2D batcher, Rectangle srcRect, int gX, int gY, { Mobile mob = World.Mobiles.Get(partyMember.Serial); - if (mob != null && mob.Distance <= World.ClientViewRange) + if (mob != null) { WMapEntity wme = World.WMapManager.GetEntity(mob); @@ -2448,7 +2448,7 @@ private void DrawAll(UltimaBatcher2D batcher, Rectangle srcRect, int gX, int gY, { if (string.IsNullOrEmpty(wme.Name) && !string.IsNullOrEmpty(partyMember.Name)) { - wme.Name = partyMember.Name; + wme.Name = wme.GetName(partyMember.Serial); } } @@ -2466,6 +2466,8 @@ private void DrawAll(UltimaBatcher2D batcher, Rectangle srcRect, int gX, int gY, true, _showGroupBar ); + + } else { @@ -2832,24 +2834,24 @@ out rot.Y if (rot.X + size.X / 2 > x + Width - 8) { - rot.X = x + Width - 8 - (int) (size.X / 2); + rot.X = x + Width - 8 - (int)(size.X / 2); } else if (rot.X - size.X / 2 < x) { - rot.X = x + (int) (size.X / 2); + rot.X = x + (int)(size.X / 2); } if (rot.Y + size.Y > y + Height) { - rot.Y = y + Height - (int) size.Y; + rot.Y = y + Height - (int)size.Y; } else if (rot.Y - size.Y < y) { - rot.Y = y + (int) size.Y; + rot.Y = y + (int)size.Y; } - int xx = (int) (rot.X - size.X / 2); - int yy = (int) (rot.Y - size.Y); + int xx = (int)(rot.X - size.X / 2); + int yy = (int)(rot.Y - size.Y); hueVector.X = 0; hueVector.Y = 1; @@ -2974,7 +2976,7 @@ float zoom else { batcher.Draw(marker.MarkerIcon, new Vector2(rot.X - (marker.MarkerIcon.Width >> 1), rot.Y - (marker.MarkerIcon.Height >> 1)), hueVector); - + if (!showMarkerName) { if (Mouse.Position.X >= rot.X - (marker.MarkerIcon.Width >> 1) && @@ -3046,8 +3048,8 @@ private void DrawMarkerString(UltimaBatcher2D batcher, WMapMarker marker, int x, ( xx - 2, yy - 2, - (int) (size.X + 4), - (int) (size.Y + 4) + (int)(size.X + 4), + (int)(size.Y + 4) ), hueVector ); @@ -3102,7 +3104,7 @@ float zoom _flipMap ? 45f : 0f ); - + rot.X += x + width; rot.Y += y + height; @@ -3316,29 +3318,29 @@ out rot.Y if (_showGroupName) { - string name = entity.Name ?? ResGumps.OutOfRange; + string name = entity.Name ?? entity.GetName(entity.Serial); Vector2 size = Fonts.Regular.MeasureString(entity.Name ?? name); if (rot.X + size.X / 2 > x + Width - 8) { - rot.X = x + Width - 8 - (int) (size.X / 2); + rot.X = x + Width - 8 - (int)(size.X / 2); } else if (rot.X - size.X / 2 < x) { - rot.X = x + (int) (size.X / 2); + rot.X = x + (int)(size.X / 2); } if (rot.Y + size.Y > y + Height) { - rot.Y = y + Height - (int) size.Y; + rot.Y = y + Height - (int)size.Y; } else if (rot.Y - size.Y < y) { - rot.Y = y + (int) size.Y; + rot.Y = y + (int)size.Y; } - int xx = (int) (rot.X - size.X / 2); - int yy = (int) (rot.Y - size.Y); + int xx = (int)(rot.X - size.X / 2); + int yy = (int)(rot.Y - size.Y); hueVector.X = 0; hueVector.Y = 1; @@ -3451,7 +3453,7 @@ protected override void OnMouseUp(int x, int y, MouseButtonType button) { HandlePositionTarget(); } - + if (button == MouseButtonType.Left && !Keyboard.Alt) { _isScrolling = false; @@ -3723,11 +3725,11 @@ private static void ConvertCoords(string coords, ref int xAxis, ref int yAxis) if (yCoord.Substring(yCoord.Length - 1).Equals("N")) { - yAxis = (int) (1624 - (yMinute / 60) * (4096.0 / 360) - yDegree * (4096.0 / 360)); + yAxis = (int)(1624 - (yMinute / 60) * (4096.0 / 360) - yDegree * (4096.0 / 360)); } else { - yAxis = (int) (1624 + (yMinute / 60) * (4096.0 / 360) + yDegree * (4096.0 / 360)); + yAxis = (int)(1624 + (yMinute / 60) * (4096.0 / 360) + yDegree * (4096.0 / 360)); } // Calc X next @@ -3737,11 +3739,11 @@ private static void ConvertCoords(string coords, ref int xAxis, ref int yAxis) if (xCoord.Substring(xCoord.Length - 1).Equals("W")) { - xAxis = (int) (1323 - (xMinute / 60) * (5120.0 / 360) - xDegree * (5120.0 / 360)); + xAxis = (int)(1323 - (xMinute / 60) * (5120.0 / 360) - xDegree * (5120.0 / 360)); } else { - xAxis = (int) (1323 + (xMinute / 60) * (5120.0 / 360) + xDegree * (5120.0 / 360)); + xAxis = (int)(1323 + (xMinute / 60) * (5120.0 / 360) + xDegree * (5120.0 / 360)); } // Normalize values outside of map range. diff --git a/src/ClassicUO.Client/Game/World.cs b/src/ClassicUO.Client/Game/World.cs index c0d88696d..010c4efad 100644 --- a/src/ClassicUO.Client/Game/World.cs +++ b/src/ClassicUO.Client/Game/World.cs @@ -48,6 +48,7 @@ using ClassicUO.Game.Scenes; using ClassicUO.Utility.Logging; using ClassicUO.Assets; +using static ClassicUO.Game.Managers.WMapEntity; namespace ClassicUO.Game { diff --git a/src/ClassicUO.Client/Network/PacketHandlers.cs b/src/ClassicUO.Client/Network/PacketHandlers.cs index da51ac3d5..29ac52719 100644 --- a/src/ClassicUO.Client/Network/PacketHandlers.cs +++ b/src/ClassicUO.Client/Network/PacketHandlers.cs @@ -1798,7 +1798,7 @@ private static void DeathScreen(ref StackDataReader p) Map = World.Map.Index, LastUpdate = Time.Ticks + (1000 * 60 * 5), IsGuild = false, - Name = $"Your Corpse" + Name = $"YOUR CORPOSE" }; // ## BEGIN - END ## // TAZUO } @@ -3401,6 +3401,7 @@ private static void UpdateName(ref StackDataReader p) if (wme != null && !string.IsNullOrEmpty(name)) { + wme.Name = name; } @@ -4787,9 +4788,10 @@ private static void ExtendedCommand(ref StackDataReader p) bool isfemale = p.ReadBool(); byte race = p.ReadUInt8(); - // TODO: gump race request + - GameActions.Print("[DEBUG]: change-race gump is not implemented yet.", 34); + UIManager.GetGump()?.Dispose(); + UIManager.Add(new RaceChangeGump(isfemale, race)); break;