diff --git a/Scripts/Items/Special/House Raffle/HouseRaffleDeed.cs b/Scripts/Items/Special/House Raffle/HouseRaffleDeed.cs index 4b3d9d241..f5421c479 100644 --- a/Scripts/Items/Special/House Raffle/HouseRaffleDeed.cs +++ b/Scripts/Items/Special/House Raffle/HouseRaffleDeed.cs @@ -1,15 +1,24 @@ using System; using Server; +using Server.Gumps; using Server.Misc; namespace Server.Items { public class HouseRaffleDeed : Item { + private HouseRaffleStone m_Stone; private Point3D m_PlotLocation; private Map m_Facet; private Mobile m_AwardedTo; + [CommandProperty( AccessLevel.GameMaster, AccessLevel.Seer )] + public HouseRaffleStone Stone + { + get { return m_Stone; } + set { m_Stone = value; InvalidateProperties(); } + } + [CommandProperty( AccessLevel.GameMaster, AccessLevel.Seer )] public Point3D PlotLocation { @@ -31,6 +40,12 @@ namespace Server.Items set { m_AwardedTo = value; InvalidateProperties(); } } + [CommandProperty( AccessLevel.GameMaster, AccessLevel.Seer )] + public bool IsExpired + { + get { return ( m_Stone == null || m_Stone.Deleted || m_Stone.IsExpired ); } + } + public override string DefaultName { get { return "a writ of lease"; } @@ -43,14 +58,20 @@ namespace Server.Items [Constructable] public HouseRaffleDeed() - : this ( Point3D.Zero, null, null ) + : this ( null, null ) { } - public HouseRaffleDeed( Point3D loc, Map facet, Mobile m ) : base( 0x2830 ) + public HouseRaffleDeed( HouseRaffleStone stone, Mobile m ) : base( 0x2830 ) { - m_PlotLocation = loc; - m_Facet = facet; + m_Stone = stone; + + if ( stone != null ) + { + m_PlotLocation = stone.GetPlotCenter(); + m_Facet = stone.PlotFacet; + } + m_AwardedTo = m; LootType = LootType.Blessed; @@ -75,17 +96,38 @@ namespace Server.Items { list.Add( 1060658, "location\t{0}", HouseRaffleStone.FormatLocation( m_PlotLocation, m_Facet, false ) ); // ~1_val~: ~2_val~ list.Add( 1060659, "facet\t{0}", m_Facet ); // ~1_val~: ~2_val~ + list.Add( 1150486 ); // [Marked Item] } + if ( IsExpired ) + list.Add( 1150487 ); // [Expired] + //list.Add( 1060660, "shard\t{0}", ServerList.ServerName ); // ~1_val~: ~2_val~ } + public override void OnDoubleClick( Mobile from ) + { + if ( !ValidLocation() ) + return; + + if ( IsChildOf( from.Backpack ) ) + { + from.CloseGump( typeof( WritOfLeaseGump ) ); + from.SendGump( new WritOfLeaseGump( this ) ); + } + else + { + from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. + } + } + public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int) 1 ); // version + writer.Write( m_Stone ); writer.Write( m_PlotLocation ); writer.Write( m_Facet ); writer.Write( m_AwardedTo ); @@ -99,6 +141,12 @@ namespace Server.Items switch ( version ) { + case 1: + { + m_Stone = reader.ReadItem(); + + goto case 0; + } case 0: { m_PlotLocation = reader.ReadPoint3D(); @@ -109,5 +157,78 @@ namespace Server.Items } } } + + private class WritOfLeaseGump : Gump + { + public WritOfLeaseGump( HouseRaffleDeed deed ) : base( 150, 50 ) + { + AddPage( 0 ); + + AddImage( 0, 0, 9380 ); + AddImage( 114, 0, 9381 ); + AddImage( 171, 0, 9382 ); + AddImage( 0, 140, 9383 ); + AddImage( 114, 140, 9384 ); + AddImage( 171, 140, 9385 ); + AddImage( 0, 182, 9383 ); + AddImage( 114, 182, 9384 ); + AddImage( 171, 182, 9385 ); + AddImage( 0, 224, 9383 ); + AddImage( 114, 224, 9384 ); + AddImage( 171, 224, 9385 ); + AddImage( 0, 266, 9386 ); + AddImage( 114, 266, 9387 ); + AddImage( 171, 266, 9388 ); + + AddHtmlLocalized( 30, 48, 229, 20, 1150484, 200, false, false ); // WRIT OF LEASE + AddHtml( 28, 75, 231, 280, FormatDescription( deed ), false, true ); + } + + private static string FormatDescription( HouseRaffleDeed deed ) + { + if ( deed == null ) + return String.Empty; + + if ( deed.IsExpired ) + { + return String.Format( + "" + + "This deed once entitled the bearer to build a house on the plot of land " + + "located at {0} on the {1} facet.

" + + + "The deed has expired, and now the indicated plot of land " + + "is subject to normal house construction rules.

" + + + "This deed functions as a recall rune marked for the location of the plot it represents." + + "
", + HouseRaffleStone.FormatLocation( deed.PlotLocation, deed.PlotFacet, false ), + deed.PlotFacet + ); + } + else + { + int daysLeft = (int)Math.Ceiling( ( deed.Stone.Started + deed.Stone.Duration + HouseRaffleStone.ExpirationTime - DateTime.Now ).TotalDays ); + + return String.Format( + "" + + "This deed entitles the bearer to build a house on the plot of land " + + "located at {0} on the {1} facet.

" + + + "The deed will expire after {2} more day{3} have passed, and at that time the right to place " + + "a house reverts to normal house construction rules.

" + + + "This deed functions as a recall rune marked for the location of the plot it represents.

" + + + "To place a house on the deeded plot, you must simply have this deed in your backpack " + + "or bank box when using a House Placement Tool there." + + "
", + HouseRaffleStone.FormatLocation( deed.PlotLocation, deed.PlotFacet, false ), + deed.PlotFacet, + daysLeft, + ( daysLeft == 1 ) ? "" : "s" + ); + } + } + } } } diff --git a/Scripts/Items/Special/House Raffle/HouseRaffleRegion.cs b/Scripts/Items/Special/House Raffle/HouseRaffleRegion.cs index 974d34ea7..d6c915e8f 100644 --- a/Scripts/Items/Special/House Raffle/HouseRaffleRegion.cs +++ b/Scripts/Items/Special/House Raffle/HouseRaffleRegion.cs @@ -20,20 +20,36 @@ namespace Server.Regions public override bool AllowHousing( Mobile from, Point3D p ) { - if ( m_Stone == null || m_Stone.Deed == null ) + if ( m_Stone == null ) + return false; + + if ( m_Stone.IsExpired ) + return true; + + if ( m_Stone.Deed == null ) return false; Container pack = from.Backpack; - if ( pack != null ) - { - List deeds = pack.FindItemsByType(); + if ( pack != null && ContainsDeed( pack ) ) + return true; - for ( int i = 0; i < deeds.Count; i++ ) - { - if ( deeds[i] == m_Stone.Deed ) - return true; - } + BankBox bank = from.FindBankNoCreate(); + + if ( bank != null && ContainsDeed( bank ) ) + return true; + + return false; + } + + private bool ContainsDeed( Container cont ) + { + List deeds = cont.FindItemsByType(); + + for ( int i = 0; i < deeds.Count; ++i ) + { + if ( deeds[i] == m_Stone.Deed ) + return true; } return false; diff --git a/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs b/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs index 71648f44f..82737c5d3 100644 --- a/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs +++ b/Scripts/Items/Special/House Raffle/HouseRaffleStone.cs @@ -83,7 +83,7 @@ namespace Server.Items private const int DefaultTicketPrice = 5000; private const int MessageHue = 1153; - private static readonly TimeSpan ExpirationTime = TimeSpan.FromDays( 30.0 ); + public static readonly TimeSpan ExpirationTime = TimeSpan.FromDays( 30.0 ); private HouseRaffleRegion m_Region; private Rectangle2D m_Bounds; @@ -355,7 +355,7 @@ namespace Server.Items return result.ToString(); } - private Point3D GetPlotCenter() + public Point3D GetPlotCenter() { int x = m_Bounds.X + m_Bounds.Width / 2; int y = m_Bounds.Y + m_Bounds.Height / 2; @@ -394,10 +394,20 @@ namespace Server.Items } else if ( m_Winner != null ) { - list.Add( 1060658, "won by\t{0}", m_Winner.Name ); // ~1_val~: ~2_val~ + list.Add( 1060658, "winner\t{0}", m_Winner.Name ); // ~1_val~: ~2_val~ } } + public override void OnSingleClick( Mobile from ) + { + base.OnSingleClick( from ); + + if ( m_Active ) + LabelTo( from, 1060658, String.Format( "Ends\t{0}", m_Started + m_Duration ) ); // ~1_val~: ~2_val~ + else if ( m_Winner != null ) + LabelTo( from, 1060658, String.Format( "Winner\t{0}", m_Winner.Name ) ); // ~1_val~: ~2_val~ + } + public override void GetContextMenuEntries( Mobile from, List list ) { base.GetContextMenuEntries( from, list ); @@ -484,7 +494,7 @@ namespace Server.Items if ( m_Winner != null ) { - m_Deed = new HouseRaffleDeed( GetPlotCenter(), m_Facet, m_Winner ); + m_Deed = new HouseRaffleDeed( this, m_Winner ); m_Winner.SendMessage( MessageHue, "Congratulations, {0}! You have won the raffle for the plot located at {1}.", m_Entries[winner].From.Name, FormatLocation() ); diff --git a/Scripts/Mobiles/Animals/Misc/PackHorse.cs b/Scripts/Mobiles/Animals/Misc/PackHorse.cs index 1a72ff53e..739c989d2 100644 --- a/Scripts/Mobiles/Animals/Misc/PackHorse.cs +++ b/Scripts/Mobiles/Animals/Misc/PackHorse.cs @@ -176,7 +176,7 @@ namespace Server.Mobiles if ( from == animal || from.AccessLevel >= AccessLevel.GameMaster ) return true; - if ( from.Alive && animal.Controlled && !animal.IsDeadPet && (from == animal.ControlMaster || from == animal.SummonMaster) ) + if ( from.Alive && animal.Controlled && !animal.IsDeadPet && ( from == animal.ControlMaster || from == animal.SummonMaster || animal.IsPetFriend( from ) ) ) return true; return false; diff --git a/Scripts/Multis/Deeds.cs b/Scripts/Multis/Deeds.cs index 1b17cae4a..1300debc3 100644 --- a/Scripts/Multis/Deeds.cs +++ b/Scripts/Multis/Deeds.cs @@ -4,6 +4,7 @@ using System.Collections; using Server.Multis; using Server.Targeting; using Server.Items; +using Server.Regions; namespace Server.Multis.Deeds { @@ -33,6 +34,8 @@ namespace Server.Multis.Deeds m_Deed.OnPlacement( from, p ); else if ( reg.IsPartOf( typeof( TreasureRegion ) ) ) from.SendLocalizedMessage( 1043287 ); // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. + else if ( reg.IsPartOf( typeof( HouseRaffleRegion ) ) ) + from.SendLocalizedMessage( 1150493 ); // You must have a deed for this plot of land in order to build here. else from.SendLocalizedMessage( 501265 ); // Housing can not be created in this area. } @@ -205,6 +208,11 @@ namespace Server.Multis.Deeds from.SendLocalizedMessage( 501270 ); //Lord British has decreed a 'no build' period, thus you cannot build this house at this time. break; } + case HousePlacementResult.BadRegionRaffle: + { + from.SendLocalizedMessage( 1150493 ); // You must have a deed for this plot of land in order to build here. + break; + } } } } diff --git a/Scripts/Multis/HousePlacement.cs b/Scripts/Multis/HousePlacement.cs index 0b62c9ce3..74c4f343b 100644 --- a/Scripts/Multis/HousePlacement.cs +++ b/Scripts/Multis/HousePlacement.cs @@ -21,6 +21,7 @@ namespace Server.Multis BadRegionHidden, BadRegionTemp, InvalidCastleKeep, + BadRegionRaffle } public class HousePlacement @@ -114,6 +115,9 @@ namespace Server.Multis if ( reg.IsPartOf( typeof( TreasureRegion ) ) ) return HousePlacementResult.BadRegionHidden; + if ( reg.IsPartOf( typeof( HouseRaffleRegion ) ) ) + return HousePlacementResult.BadRegionRaffle; + return HousePlacementResult.BadRegion; } diff --git a/Scripts/Multis/HousePlacementTool.cs b/Scripts/Multis/HousePlacementTool.cs index 5e8440ed6..dcf25c21b 100644 --- a/Scripts/Multis/HousePlacementTool.cs +++ b/Scripts/Multis/HousePlacementTool.cs @@ -4,6 +4,7 @@ using Server; using Server.Gumps; using Server.Multis; using Server.Mobiles; +using Server.Regions; using Server.Targeting; namespace Server.Items @@ -249,6 +250,8 @@ namespace Server.Items m_Placed = m_Entry.OnPlacement( from, p ); else if ( reg.IsPartOf( typeof( TreasureRegion ) ) ) from.SendLocalizedMessage( 1043287 ); // The house could not be created here. Either something is blocking the house, or the house would not be on valid terrain. + else if ( reg.IsPartOf( typeof( HouseRaffleRegion ) ) ) + from.SendLocalizedMessage( 1150493 ); // You must have a deed for this plot of land in order to build here. else from.SendLocalizedMessage( 501265 ); // Housing can not be created in this area. } @@ -428,6 +431,11 @@ namespace Server.Items from.SendLocalizedMessage( 501270 ); // Lord British has decreed a 'no build' period, thus you cannot build this house at this time. break; } + case HousePlacementResult.BadRegionRaffle: + { + from.SendLocalizedMessage( 1150493 ); // You must have a deed for this plot of land in order to build here. + break; + } case HousePlacementResult.InvalidCastleKeep: { from.SendLocalizedMessage( 1061122 ); // Castles and keeps cannot be created here. @@ -526,6 +534,11 @@ namespace Server.Items from.SendLocalizedMessage( 501270 ); //Lord British has decreed a 'no build' period, thus you cannot build this house at this time. break; } + case HousePlacementResult.BadRegionRaffle: + { + from.SendLocalizedMessage( 1150493 ); // You must have a deed for this plot of land in order to build here. + break; + } case HousePlacementResult.InvalidCastleKeep: { from.SendLocalizedMessage( 1061122 ); // Castles and keeps cannot be created here. diff --git a/Scripts/Skills/AnimalLore.cs b/Scripts/Skills/AnimalLore.cs index f915e6438..dd9ee510b 100644 --- a/Scripts/Skills/AnimalLore.cs +++ b/Scripts/Skills/AnimalLore.cs @@ -42,11 +42,11 @@ namespace Server.SkillHandlers { if ( c.Body.IsAnimal || c.Body.IsMonster || c.Body.IsSea ) { - if ( (!c.Controlled || !c.Tamable) && from.Skills[SkillName.AnimalLore].Value < 100.0 ) + if ( !c.Controlled && from.Skills[SkillName.AnimalLore].Value < 100.0 ) { from.SendLocalizedMessage( 1049674 ); // At your skill level, you can only lore tamed creatures. } - else if ( !c.Tamable && from.Skills[SkillName.AnimalLore].Value < 110.0 ) + else if ( !c.Controlled && !c.Tamable && from.Skills[SkillName.AnimalLore].Value < 110.0 ) { from.SendLocalizedMessage( 1049675 ); // At your skill level, you can only lore tamed or tameable creatures. }