From 858e86d45b0c1e026bc65b812b5590de7486a772 Mon Sep 17 00:00:00 2001 From: "eos@runuo.com" Date: Sun, 2 Jun 2013 13:12:09 +0000 Subject: [PATCH] - Added High Seas expansion to the expansions list. - Changed the default expansion to HS. - Changed meer monsters to all be FightMode.Evil. - Added refuse trades option (client 7.0.30.0+). - Added item insurance menu. - Updated context menus to support new clilocs. - Added item properties to gumps. - Reverting items not decaying on spawners, needs to be configurable. - Added AUO features to FeatureProtection. - Tweaked third party authentication to not trigger the character password gump in the client. --- Scripts/Misc/CurrentExpansion.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerEternal.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerMage.cs | 2 +- .../Mobiles/Monsters/LBR/Meers/MeerWarrior.cs | 2 +- Scripts/Mobiles/PlayerMobile.cs | 366 ++++++++++++++++-- Scripts/Multis/Boats/BaseBoat.cs | 3 +- Server/ContextMenus/ContextMenuEntry.cs | 6 +- Server/ExpansionInfo.cs | 12 +- Server/Gumps/Gump.cs | 5 + Server/Gumps/GumpItemProperty.cs | 60 +++ Server/Item.cs | 3 +- Server/Main.cs | 5 + Server/Mobile.cs | 9 +- Server/Network/Packets.cs | 87 ++++- Server/Utility.cs | 5 + 15 files changed, 512 insertions(+), 57 deletions(-) create mode 100644 Server/Gumps/GumpItemProperty.cs diff --git a/Scripts/Misc/CurrentExpansion.cs b/Scripts/Misc/CurrentExpansion.cs index a208e8602..82ae8ce56 100644 --- a/Scripts/Misc/CurrentExpansion.cs +++ b/Scripts/Misc/CurrentExpansion.cs @@ -5,7 +5,7 @@ namespace Server { public class CurrentExpansion { - private static readonly Expansion Expansion = Expansion.SA; + private static readonly Expansion Expansion = Expansion.HS; public static void Configure() { diff --git a/Scripts/Mobiles/Monsters/LBR/Meers/MeerEternal.cs b/Scripts/Mobiles/Monsters/LBR/Meers/MeerEternal.cs index 36affbec0..e55ded024 100644 --- a/Scripts/Mobiles/Monsters/LBR/Meers/MeerEternal.cs +++ b/Scripts/Mobiles/Monsters/LBR/Meers/MeerEternal.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles public class MeerEternal : BaseCreature { [Constructable] - public MeerEternal() : base( AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.2, 0.4 ) + public MeerEternal() : base( AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4 ) { Name = "a meer eternal"; Body = 772; diff --git a/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs b/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs index e0c4df685..abbbfac8d 100644 --- a/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs +++ b/Scripts/Mobiles/Monsters/LBR/Meers/MeerMage.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles public class MeerMage : BaseCreature { [Constructable] - public MeerMage() : base( AIType.AI_Mage, FightMode.Aggressor, 10, 1, 0.2, 0.4 ) + public MeerMage() : base( AIType.AI_Mage, FightMode.Evil, 10, 1, 0.2, 0.4 ) { Name = "a meer mage"; Body = 770; diff --git a/Scripts/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs b/Scripts/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs index 8f2d6bba1..b8de7bd4a 100644 --- a/Scripts/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs +++ b/Scripts/Mobiles/Monsters/LBR/Meers/MeerWarrior.cs @@ -11,7 +11,7 @@ namespace Server.Mobiles public class MeerWarrior : BaseCreature { [Constructable] - public MeerWarrior() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 ) + public MeerWarrior() : base( AIType.AI_Melee, FightMode.Evil, 10, 1, 0.2, 0.4 ) { Name = "a meer warrior"; Body = 771; diff --git a/Scripts/Mobiles/PlayerMobile.cs b/Scripts/Mobiles/PlayerMobile.cs index d441cff5b..73068d877 100644 --- a/Scripts/Mobiles/PlayerMobile.cs +++ b/Scripts/Mobiles/PlayerMobile.cs @@ -46,7 +46,8 @@ namespace Server.Mobiles Young = 0x00000400, AcceptGuildInvites = 0x00000800, DisplayChampionTitle = 0x00001000, - HasStatReward = 0x00002000 + HasStatReward = 0x00002000, + RefuseTrades = 0x00004000 } public enum NpcGuild @@ -395,6 +396,13 @@ namespace Server.Mobiles get{ return GetFlag( PlayerFlag.HasStatReward ); } set{ SetFlag( PlayerFlag.HasStatReward, value ); } } + + [CommandProperty( AccessLevel.GameMaster )] + public bool RefuseTrades + { + get{ return GetFlag( PlayerFlag.RefuseTrades ); } + set{ SetFlag( PlayerFlag.RefuseTrades, value ); } + } #endregion #region Auto Arrow Recovery @@ -1580,12 +1588,18 @@ namespace Server.Mobiles { if ( InsuranceEnabled ) { + if ( Core.SA ) + list.Add( new CallbackEntry( 1114299, new ContextCallback( OpenItemInsuranceMenu ) ) ); // Open Item Insurance Menu + list.Add( new CallbackEntry( 6201, new ContextCallback( ToggleItemInsurance ) ) ); // Toggle Item Insurance - if ( AutoRenewInsurance ) - list.Add( new CallbackEntry( 6202, new ContextCallback( CancelRenewInventoryInsurance ) ) ); // Cancel Renewing Inventory Insurance - else - list.Add( new CallbackEntry( 6200, new ContextCallback( AutoRenewInventoryInsurance ) ) ); // Auto Renew Inventory Insurance + if ( !Core.SA ) + { + if ( AutoRenewInsurance ) + list.Add( new CallbackEntry( 6202, new ContextCallback( CancelRenewInventoryInsurance ) ) ); // Cancel Renewing Inventory Insurance + else + list.Add( new CallbackEntry( 6200, new ContextCallback( AutoRenewInventoryInsurance ) ) ); // Auto Renew Inventory Insurance + } } if ( MLQuestSystem.Enabled ) @@ -1608,6 +1622,9 @@ namespace Server.Mobiles if( Alive ) list.Add( new CallbackEntry( 6210, new ContextCallback( ToggleChampionTitleDisplay ) ) ); + + if ( Core.HS ) + list.Add( new CallbackEntry( RefuseTrades ? 1154112 : 1154113, new ContextCallback( ToggleTrades ) ) ); // Allow Trades / Refuse Trades } if ( from != this ) { @@ -1654,6 +1671,11 @@ namespace Server.Mobiles #region Insurance + private static int GetInsuranceCost( Item item ) + { + return 600; // TODO + } + private void ToggleItemInsurance() { if ( !CheckAlive() ) @@ -1665,10 +1687,7 @@ namespace Server.Mobiles private bool CanInsure( Item item ) { - if ( (( item is Container) && !(item is BaseQuiver)) || item is BagOfSending || item is KeyRing ) - return false; - - if ( (item is Spellbook && item.LootType == LootType.Blessed)|| item is Runebook || item is PotionKeg || item is Sigil ) + if ( ( item is Container && !( item is BaseQuiver ) ) || item is BagOfSending || item is KeyRing || item is PotionKeg || item is Sigil ) return false; if ( item.Stackable ) @@ -1680,6 +1699,12 @@ namespace Server.Mobiles if ( item.ItemID == 0x204E ) // death shroud return false; + if ( item.LootType == LootType.Blessed || item.LootType == LootType.Newbied || item.BlessedFor == this ) + { + //SendLocalizedMessage( 1060870, "", 0x23 ); // That item is blessed and does not need to be insured + return false; + } + return true; } @@ -1688,11 +1713,16 @@ namespace Server.Mobiles if ( !CheckAlive() ) return; - Item item = obj as Item; + ToggleItemInsurance_Callback( from, obj as Item, true ); + } + private void ToggleItemInsurance_Callback( Mobile from, Item item, bool target ) + { if ( item == null || !item.IsChildOf( this ) ) { - BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); + if ( target ) + BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); + SendLocalizedMessage( 1060871, "", 0x23 ); // You can only insure items that you have equipped or that are in your backpack } else if ( item.Insured ) @@ -1701,27 +1731,28 @@ namespace Server.Mobiles SendLocalizedMessage( 1060874, "", 0x35 ); // You cancel the insurance on the item - BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); - SendLocalizedMessage( 1060868, "", 0x23 ); // Target the item you wish to toggle insurance status on to cancel + if ( target ) + { + BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); + SendLocalizedMessage( 1060868, "", 0x23 ); // Target the item you wish to toggle insurance status on to cancel + } } else if ( !CanInsure( item ) ) { - BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); - SendLocalizedMessage( 1060869, "", 0x23 ); // You cannot insure that - } - else if ( item.LootType == LootType.Blessed || item.LootType == LootType.Newbied || item.BlessedFor == from ) - { - BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); - SendLocalizedMessage( 1060870, "", 0x23 ); // That item is blessed and does not need to be insured + if ( target ) + BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); + SendLocalizedMessage( 1060869, "", 0x23 ); // You cannot insure that } else { if ( !item.PayedInsurance ) { - if ( Banker.Withdraw( from, 600 ) ) + int cost = GetInsuranceCost( item ); + + if ( Banker.Withdraw( from, cost ) ) { - SendLocalizedMessage( 1060398, "600" ); // ~1_AMOUNT~ gold has been withdrawn from your bank box. + SendLocalizedMessage( 1060398, cost.ToString() ); // ~1_AMOUNT~ gold has been withdrawn from your bank box. item.PayedInsurance = true; } else @@ -1735,8 +1766,11 @@ namespace Server.Mobiles SendLocalizedMessage( 1060873, "", 0x23 ); // You have insured the item - BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); - SendLocalizedMessage( 1060868, "", 0x23 ); // Target the item you wish to toggle insurance status on to cancel + if ( target ) + { + BeginTarget( -1, false, TargetFlags.None, new TargetCallback( ToggleItemInsurance_Callback ) ); + SendLocalizedMessage( 1060868, "", 0x23 ); // Target the item you wish to toggle insurance status on to cancel + } } } @@ -1757,7 +1791,7 @@ namespace Server.Mobiles if( Core.SE ) { if( !HasGump( typeof( CancelRenewInventoryInsuranceGump ) ) ) - SendGump( new CancelRenewInventoryInsuranceGump( this ) ); + SendGump( new CancelRenewInventoryInsuranceGump( this, null ) ); } else { @@ -1769,10 +1803,12 @@ namespace Server.Mobiles private class CancelRenewInventoryInsuranceGump : Gump { private PlayerMobile m_Player; + private ItemInsuranceMenuGump m_InsuranceGump; - public CancelRenewInventoryInsuranceGump( PlayerMobile player ) : base( 250, 200 ) + public CancelRenewInventoryInsuranceGump( PlayerMobile player, ItemInsuranceMenuGump insuranceGump ) : base( 250, 200 ) { m_Player = player; + m_InsuranceGump = insuranceGump; AddBackground( 0, 0, 240, 142, 0x13BE ); AddImageTiled( 6, 6, 228, 100, 0xA40 ); @@ -1802,6 +1838,265 @@ namespace Server.Mobiles { m_Player.SendLocalizedMessage( 1042021 ); // Cancelled. } + + if ( m_InsuranceGump != null ) + m_Player.SendGump( m_InsuranceGump.NewInstance() ); + } + } + + private void OpenItemInsuranceMenu() + { + if ( !CheckAlive() ) + return; + + List items = new List(); + + foreach ( Item item in Items ) + { + if ( DisplayInItemInsuranceGump( item ) ) + items.Add( item ); + } + + Container pack = Backpack; + + if ( pack != null ) + items.AddRange( pack.FindItemsByType( true, DisplayInItemInsuranceGump ) ); + + // TODO: Investigate item sorting + + CloseGump( typeof( ItemInsuranceMenuGump ) ); + + if ( items.Count == 0 ) + SendLocalizedMessage( 1114915, "", 0x35 ); // None of your current items meet the requirements for insurance. + else + SendGump( new ItemInsuranceMenuGump( this, items.ToArray() ) ); + } + + private bool DisplayInItemInsuranceGump( Item item ) + { + return ( item.Insured || CanInsure( item ) ); + } + + private class ItemInsuranceMenuGump : Gump + { + private PlayerMobile m_From; + private Item[] m_Items; + private bool[] m_Insure; + private int m_Page; + + public ItemInsuranceMenuGump( PlayerMobile from, Item[] items ) + : this( from, items, null, 0 ) + { + } + + public ItemInsuranceMenuGump( PlayerMobile from, Item[] items, bool[] insure, int page ) + : base( 25, 50 ) + { + m_From = from; + m_Items = items; + + if ( insure == null ) + { + insure = new bool[items.Length]; + + for ( int i = 0; i < items.Length; ++i ) + insure[i] = items[i].Insured; + } + + m_Insure = insure; + m_Page = page; + + AddPage( 0 ); + + AddBackground( 0, 0, 520, 510, 0x13BE ); + AddImageTiled( 10, 10, 500, 30, 0xA40 ); + AddImageTiled( 10, 50, 500, 355, 0xA40 ); + AddImageTiled( 10, 415, 500, 80, 0xA40 ); + AddAlphaRegion( 10, 10, 500, 485 ); + + AddButton( 15, 470, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 50, 472, 80, 20, 1011012, 0x7FFF, false, false ); // CANCEL + + if ( from.AutoRenewInsurance ) + AddButton( 360, 10, 9723, 9724, 1, GumpButtonType.Reply, 0 ); + else + AddButton( 360, 10, 9720, 9722, 1, GumpButtonType.Reply, 0 ); + + AddHtmlLocalized( 395, 14, 105, 20, 1114122, 0x7FFF, false, false ); // AUTO REINSURE + + AddButton( 395, 470, 0xFA5, 0xFA6, 2, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 430, 472, 50, 20, 1006044, 0x7FFF, false, false ); // OK + + AddHtmlLocalized( 10, 14, 150, 20, 1114121, 0x7FFF, false, false ); //
ITEM INSURANCE MENU
+ + AddHtmlLocalized( 45, 54, 70, 20, 1062214, 0x7FFF, false, false ); // Item + AddHtmlLocalized( 250, 54, 70, 20, 1061038, 0x7FFF, false, false ); // Cost + AddHtmlLocalized( 400, 54, 70, 20, 1114311, 0x7FFF, false, false ); // Insured + + int balance = Banker.GetBalance( from ); + int cost = 0; + + for ( int i = 0; i < items.Length; ++i ) + { + if ( insure[i] ) + cost += GetInsuranceCost( items[i] ); + } + + AddHtmlLocalized( 15, 420, 300, 20, 1114310, 0x7FFF, false, false ); // GOLD AVAILABLE: + AddLabel( 215, 420, 0x481, balance.ToString() ); + AddHtmlLocalized( 15, 435, 300, 20, 1114123, 0x7FFF, false, false ); // TOTAL COST OF INSURANCE: + AddLabel( 215, 435, 0x481, cost.ToString() ); + + if ( cost != 0 ) + { + AddHtmlLocalized( 15, 450, 300, 20, 1114125, 0x7FFF, false, false ); // NUMBER OF DEATHS PAYABLE: + AddLabel( 215, 450, 0x481, ( balance / cost ).ToString() ); + } + + for ( int i = page * 4, y = 72; i < ( page + 1 ) * 4 && i < items.Length; ++i, y += 75 ) + { + Item item = items[i]; + Rectangle2D b = ItemBounds.Table[item.ItemID]; + + AddImageTiledButton( 40, y, 0x918, 0x918, 0, GumpButtonType.Page, 0, item.ItemID, item.Hue, 40 - b.Width / 2 - b.X, 30 - b.Height / 2 - b.Y ); + AddItemProperty( item.Serial ); + + if ( insure[i] ) + { + AddButton( 400, y, 9723, 9724, 100 + i, GumpButtonType.Reply, 0 ); + AddLabel( 250, y, 0x481, GetInsuranceCost( item ).ToString() ); + } + else + { + AddButton( 400, y, 9720, 9722, 100 + i, GumpButtonType.Reply, 0 ); + AddLabel( 250, y, 0x66C, GetInsuranceCost( item ).ToString() ); + } + } + + if ( page >= 1 ) + { + AddButton( 15, 380, 0xFAE, 0xFAF, 3, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 50, 380, 450, 20, 1044044, 0x7FFF, false, false ); // PREV PAGE + } + + if ( ( page + 1 ) * 4 < items.Length ) + { + AddButton( 400, 380, 0xFA5, 0xFA7, 4, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 435, 380, 70, 20, 1044045, 0x7FFF, false, false ); // NEXT PAGE + } + } + + public ItemInsuranceMenuGump NewInstance() + { + return new ItemInsuranceMenuGump( m_From, m_Items, m_Insure, m_Page ); + } + + public override void OnResponse( NetState sender, RelayInfo info ) + { + if ( info.ButtonID == 0 || !m_From.CheckAlive() ) + return; + + switch ( info.ButtonID ) + { + case 1: // Auto Reinsure + { + if ( m_From.AutoRenewInsurance ) + { + if ( !m_From.HasGump( typeof( CancelRenewInventoryInsuranceGump ) ) ) + m_From.SendGump( new CancelRenewInventoryInsuranceGump( m_From, this ) ); + } + else + { + m_From.AutoRenewInventoryInsurance(); + m_From.SendGump( new ItemInsuranceMenuGump( m_From, m_Items, m_Insure, m_Page ) ); + } + + break; + } + case 2: // OK + { + m_From.SendGump( new ItemInsuranceMenuConfirmGump( m_From, m_Items, m_Insure, m_Page ) ); + + break; + } + case 3: // Prev + { + if ( m_Page >= 1 ) + m_From.SendGump( new ItemInsuranceMenuGump( m_From, m_Items, m_Insure, m_Page - 1 ) ); + + break; + } + case 4: // Next + { + if ( ( m_Page + 1 ) * 4 < m_Items.Length ) + m_From.SendGump( new ItemInsuranceMenuGump( m_From, m_Items, m_Insure, m_Page + 1 ) ); + + break; + } + default: + { + int idx = info.ButtonID - 100; + + if ( idx >= 0 && idx < m_Items.Length ) + m_Insure[idx] = !m_Insure[idx]; + + m_From.SendGump( new ItemInsuranceMenuGump( m_From, m_Items, m_Insure, m_Page ) ); + + break; + } + } + } + } + + private class ItemInsuranceMenuConfirmGump : Gump + { + private PlayerMobile m_From; + private Item[] m_Items; + private bool[] m_Insure; + private int m_Page; + + public ItemInsuranceMenuConfirmGump( PlayerMobile from, Item[] items, bool[] insure, int page ) + : base( 250, 200 ) + { + m_From = from; + m_Items = items; + m_Insure = insure; + m_Page = page; + + AddBackground( 0, 0, 240, 142, 0x13BE ); + AddImageTiled( 6, 6, 228, 100, 0xA40 ); + AddImageTiled( 6, 116, 228, 20, 0xA40 ); + AddAlphaRegion( 6, 6, 228, 142 ); + + AddHtmlLocalized( 8, 8, 228, 100, 1114300, 0x7FFF, false, false ); // Do you wish to insure all newly selected items? + + AddButton( 6, 116, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 40, 118, 450, 20, 1060051, 0x7FFF, false, false ); // CANCEL + + AddButton( 114, 116, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 ); + AddHtmlLocalized( 148, 118, 450, 20, 1073996, 0x7FFF, false, false ); // ACCEPT + } + + public override void OnResponse( NetState sender, RelayInfo info ) + { + if ( !m_From.CheckAlive() ) + return; + + if ( info.ButtonID == 1 ) + { + for ( int i = 0; i < m_Items.Length; ++i ) + { + Item item = m_Items[i]; + + if ( item.Insured != m_Insure[i] ) + m_From.ToggleItemInsurance_Callback( m_From, item, false ); + } + } + else + { + m_From.SendLocalizedMessage( 1042021 ); // Cancelled. + m_From.SendGump( new ItemInsuranceMenuGump( m_From, m_Items, m_Insure, m_Page ) ); + } } } @@ -1863,6 +2158,11 @@ namespace Server.Mobiles #endregion + private void ToggleTrades() + { + RefuseTrades = !RefuseTrades; + } + private void GetVendor() { BaseHouse house = BaseHouse.FindHouseAt( this ); @@ -2021,6 +2321,8 @@ namespace Server.Mobiles msgNum = 1062781; // You are already trading with someone else! else if ( to.HasTrade ) msgNum = 1062779; // That person is already involved in a trade + else if ( to is PlayerMobile && ((PlayerMobile)to).RefuseTrades ) + msgNum = 1154111; // ~1_NAME~ is refusing all trades. } if ( msgNum == 0 ) @@ -2042,7 +2344,12 @@ namespace Server.Mobiles if ( msgNum != 0 ) { if ( message ) - this.SendLocalizedMessage( msgNum ); + { + if ( msgNum == 1154111 ) + SendLocalizedMessage( msgNum, to.Name ); + else + SendLocalizedMessage( msgNum ); + } return false; } @@ -2350,7 +2657,10 @@ namespace Server.Mobiles if ( AutoRenewInsurance ) { - int cost = ( m_InsuranceAward == null ? 600 : 300 ); + int cost = GetInsuranceCost( item ); + + if ( m_InsuranceAward != null ) + cost /= 2; if ( Banker.Withdraw( this, cost ) ) { diff --git a/Scripts/Multis/Boats/BaseBoat.cs b/Scripts/Multis/Boats/BaseBoat.cs index c0a2691cf..1fe6ae7d2 100644 --- a/Scripts/Multis/Boats/BaseBoat.cs +++ b/Scripts/Multis/Boats/BaseBoat.cs @@ -436,8 +436,7 @@ namespace Server.Multis * 'walking' in piloting mode has a 1s interval, speed 0x2 */ - // Legacy clients will continue to see the old-style movement, but speeds are adjusted - private static bool NewBoatMovement = true; + private static bool NewBoatMovement { get { return Core.HS; } } private static TimeSpan SlowInterval = TimeSpan.FromSeconds( NewBoatMovement ? 0.50 : 0.75 ); private static TimeSpan FastInterval = TimeSpan.FromSeconds( NewBoatMovement ? 0.25 : 0.75 ); diff --git a/Server/ContextMenus/ContextMenuEntry.cs b/Server/ContextMenus/ContextMenuEntry.cs index 570cadd57..fbad8aed2 100644 --- a/Server/ContextMenus/ContextMenuEntry.cs +++ b/Server/ContextMenus/ContextMenuEntry.cs @@ -123,7 +123,11 @@ namespace Server.ContextMenus /// public ContextMenuEntry( int number, int range ) { - m_Number = number; + if ( number <= 0x7FFF ) // Legacy code support + m_Number = 3000000 + number; + else + m_Number = number; + m_Range = range; m_Enabled = true; m_Color = 0xFFFF; diff --git a/Server/ExpansionInfo.cs b/Server/ExpansionInfo.cs index f8ce73c10..44b0a10ad 100644 --- a/Server/ExpansionInfo.cs +++ b/Server/ExpansionInfo.cs @@ -32,7 +32,8 @@ namespace Server AOS, SE, ML, - SA + SA, + HS } [Flags] @@ -83,7 +84,8 @@ namespace Server ExpansionAOS = ExpansionLBR | AOS | Unk7, ExpansionSE = ExpansionAOS | SE, ExpansionML = ExpansionSE | ML | Unk2, - ExpansionSA = ExpansionML | SA | Gothic | Rustic + ExpansionSA = ExpansionML | SA | Gothic | Rustic, + ExpansionHS = ExpansionSA } [Flags] @@ -113,7 +115,8 @@ namespace Server ExpansionAOS = ContextMenus | AOS, ExpansionSE = ExpansionAOS | SE, ExpansionML = ExpansionSE | ML, - ExpansionSA = ExpansionML + ExpansionSA = ExpansionML, + ExpansionHS = ExpansionSA } public class ExpansionInfo @@ -129,7 +132,8 @@ namespace Server new ExpansionInfo( 5, "Age of Shadows", ClientFlags.Malas, FeatureFlags.ExpansionAOS, CharacterListFlags.ExpansionAOS, 0x0000 ), new ExpansionInfo( 6, "Samurai Empire", ClientFlags.Tokuno, FeatureFlags.ExpansionSE, CharacterListFlags.ExpansionSE, 0x00C0 ), // 0x20 | 0x80 new ExpansionInfo( 7, "Mondain's Legacy", new ClientVersion( "5.0.0a" ), FeatureFlags.ExpansionML, CharacterListFlags.ExpansionML, 0x02C0 ), // 0x20 | 0x80 | 0x200 - new ExpansionInfo( 8, "Stygian Abyss", ClientFlags.TerMur, FeatureFlags.ExpansionSA, CharacterListFlags.ExpansionSA, 0xD02C0 ) // 0x20 | 0x80 | 0x200 | 0x10000 | 0x40000 | 0x80000 + new ExpansionInfo( 8, "Stygian Abyss", ClientFlags.TerMur, FeatureFlags.ExpansionSA, CharacterListFlags.ExpansionSA, 0xD02C0 ), // 0x20 | 0x80 | 0x200 | 0x10000 | 0x40000 | 0x80000 + new ExpansionInfo( 9, "High Seas", new ClientVersion( "7.0.9.0" ), FeatureFlags.ExpansionHS, CharacterListFlags.ExpansionHS, 0xD02C0 ) // 0x20 | 0x80 | 0x200 | 0x10000 | 0x40000 | 0x80000 }; private string m_Name; diff --git a/Server/Gumps/Gump.cs b/Server/Gumps/Gump.cs index 0e0710ea7..568f4bd14 100644 --- a/Server/Gumps/Gump.cs +++ b/Server/Gumps/Gump.cs @@ -310,6 +310,11 @@ namespace Server.Gumps Add( new GumpTextEntryLimited( x, y, width, height, hue, entryID, initialText, size ) ); } + public void AddItemProperty( int serial ) + { + Add( new GumpItemProperty( serial ) ); + } + public void Add( GumpEntry g ) { if ( g.Parent != this ) diff --git a/Server/Gumps/GumpItemProperty.cs b/Server/Gumps/GumpItemProperty.cs new file mode 100644 index 000000000..100305720 --- /dev/null +++ b/Server/Gumps/GumpItemProperty.cs @@ -0,0 +1,60 @@ +/*************************************************************************** + * GumpItemProperty.cs + * ------------------- + * begin : May 26, 2013 + * copyright : (C) The RunUO Software Team + * email : info@runuo.com + * + * $Id$ + * + ***************************************************************************/ + +/*************************************************************************** + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + ***************************************************************************/ + +using System; +using Server.Network; + +namespace Server.Gumps +{ + public class GumpItemProperty : GumpEntry + { + private int m_Serial; + + public GumpItemProperty( int serial ) + { + m_Serial = serial; + } + + public int Serial + { + get + { + return m_Serial; + } + set + { + Delta( ref m_Serial, value ); + } + } + + public override string Compile() + { + return String.Format( "{{ itemproperty {0} }}", m_Serial ); + } + + private static byte[] m_LayoutName = Gump.StringToBuffer( "itemproperty" ); + + public override void AppendTo( IGumpWriter disp ) + { + disp.AppendLayout( m_LayoutName ); + disp.AppendLayout( m_Serial ); + } + } +} diff --git a/Server/Item.cs b/Server/Item.cs index a17513573..bed97b0b0 100644 --- a/Server/Item.cs +++ b/Server/Item.cs @@ -1508,7 +1508,8 @@ namespace Server { get { - return (Movable && Visible && Spawner == null); + // TODO: Make item decay an option on the spawner + return (Movable && Visible/* && Spawner == null*/); } } diff --git a/Server/Main.cs b/Server/Main.cs index 9692a9623..5acb85e9c 100644 --- a/Server/Main.cs +++ b/Server/Main.cs @@ -202,6 +202,11 @@ namespace Server get { return m_Expansion >= Expansion.SA; } } + public static bool HS + { + get { return m_Expansion >= Expansion.HS; } + } + #endregion public static string ExePath diff --git a/Server/Mobile.cs b/Server/Mobile.cs index a7d07ae39..c5218d495 100644 --- a/Server/Mobile.cs +++ b/Server/Mobile.cs @@ -2784,8 +2784,13 @@ namespace Server { m_ContextMenu = value; - if( m_ContextMenu != null ) - Send( new DisplayContextMenu( m_ContextMenu ) ); + if ( m_ContextMenu != null && m_NetState != null ) + { + if ( m_NetState.NewHaven ) + Send( new DisplayContextMenu( m_ContextMenu ) ); + else + Send( new DisplayContextMenuOld( m_ContextMenu ) ); + } } } diff --git a/Server/Network/Packets.cs b/Server/Network/Packets.cs index 2e7c1d837..b093752c8 100644 --- a/Server/Network/Packets.cs +++ b/Server/Network/Packets.cs @@ -902,6 +902,8 @@ namespace Server.Network { None = 0x00, Disabled = 0x01, + Arrow = 0x02, + Highlighted = 0x04, Colored = 0x20 } @@ -915,6 +917,55 @@ namespace Server.Network this.EnsureCapacity( 12 + (length * 8) ); + m_Stream.Write( (short) 0x14 ); + m_Stream.Write( (short) 0x02 ); + + IEntity target = menu.Target as IEntity; + + m_Stream.Write( (int) ( target == null ? Serial.MinusOne : target.Serial ) ); + + m_Stream.Write( (byte) length ); + + Point3D p; + + if ( target is Mobile ) + p = target.Location; + else if ( target is Item ) + p = ((Item)target).GetWorldLocation(); + else + p = Point3D.Zero; + + for ( int i = 0; i < length; ++i ) + { + ContextMenuEntry e = entries[i]; + + m_Stream.Write( (int) e.Number ); + m_Stream.Write( (short) i ); + + int range = e.Range; + + if ( range == -1 ) + range = 18; + + CMEFlags flags = (e.Enabled && menu.From.InRange( p, range )) ? CMEFlags.None : CMEFlags.Disabled; + + flags |= e.Flags; + + m_Stream.Write( (short) flags ); + } + } + } + + public sealed class DisplayContextMenuOld : Packet + { + public DisplayContextMenuOld( ContextMenu menu ) : base( 0xBF ) + { + ContextMenuEntry[] entries = menu.Entries; + + int length = (byte) entries.Length; + + this.EnsureCapacity( 12 + (length * 8) ); + m_Stream.Write( (short) 0x14 ); m_Stream.Write( (short) 0x01 ); @@ -938,7 +989,7 @@ namespace Server.Network ContextMenuEntry e = entries[i]; m_Stream.Write( (short) i ); - m_Stream.Write( (ushort) e.Number ); + m_Stream.Write( (ushort) ( e.Number - 3000000 ) ); int range = e.Range; @@ -3805,9 +3856,9 @@ namespace Server.Network public enum ThirdPartyFeature : ulong { FilterWeather = 1 << 0, - FilterLight = 1 << 1, + FilterLight = 1 << 1, - SmartTarget = 1 << 2, + SmartTarget = 1 << 2, RangedTarget = 1 << 3, AutoOpenDoors = 1 << 4, @@ -3821,14 +3872,24 @@ namespace Server.Network UseOnceAgent = 1 << 9, RestockAgent = 1 << 10, - SellAgent = 1 << 11, - BuyAgent = 1 << 12, + SellAgent = 1 << 11, + BuyAgent = 1 << 12, PotionHotkeys = 1 << 13, RandomTargets = 1 << 14, ClosestTargets = 1 << 15, // All closest target hotkeys OverheadHealth = 1 << 16, // Health and Mana/Stam messages shown over player's heads + + AutolootAgent = 1 << 17, + BoneCutterAgent = 1 << 18, + AdvancedMacros = 1 << 19, + AutoRemount = 1 << 20, + AutoBandage = 1 << 21, + BuffChecks = 1 << 22, // Buff bar checks for macros + FilterSeason = 1 << 23, + + All = ulong.MaxValue } public static class FeatureProtection @@ -3930,15 +3991,13 @@ namespace Server.Network m_Stream.UnderlyingStream.Flush(); byte[] hashCode = m_MD5Provider.ComputeHash( m_Stream.UnderlyingStream.GetBuffer(), 0, (int) m_Stream.UnderlyingStream.Length ); - - Random rnd = new Random(); - byte[] buffer = new byte[29]; + byte[] buffer = new byte[28]; for ( int i = 0; i < count; ++i ) { - rnd.NextBytes( buffer ); + Utility.RandomBytes( buffer ); - m_Stream.Seek( 34 + ( i * 60 ), SeekOrigin.Begin ); + m_Stream.Seek( 35 + ( i * 60 ), SeekOrigin.Begin ); m_Stream.Write( buffer, 0, buffer.Length ); } @@ -4025,15 +4084,13 @@ namespace Server.Network m_Stream.UnderlyingStream.Flush(); byte[] hashCode = m_MD5Provider.ComputeHash( m_Stream.UnderlyingStream.GetBuffer(), 0, (int) m_Stream.UnderlyingStream.Length ); - - Random rnd = new Random(); - byte[] buffer = new byte[29]; + byte[] buffer = new byte[28]; for ( int i = 0; i < count; ++i ) { - rnd.NextBytes( buffer ); + Utility.RandomBytes( buffer ); - m_Stream.Seek( 34 + ( i * 60 ), SeekOrigin.Begin ); + m_Stream.Seek( 35 + ( i * 60 ), SeekOrigin.Begin ); m_Stream.Write( buffer, 0, buffer.Length ); } diff --git a/Server/Utility.cs b/Server/Utility.cs index 116da164f..1cd229e1f 100644 --- a/Server/Utility.cs +++ b/Server/Utility.cs @@ -831,6 +831,11 @@ namespace Server return m_Random.Next( count ); } + public static void RandomBytes( byte[] buffer ) + { + m_Random.NextBytes( buffer ); + } + #region Random Hues ///