From 897f9006a48bd7cda045f0b4942f9ec081b50e29 Mon Sep 17 00:00:00 2001 From: WarrentyExpired Date: Wed, 22 Jul 2026 12:21:14 -0400 Subject: [PATCH] #W# Virtue Tome and Shrines fast travel system done. --- .../Britannia/ShrineControllers.cfg | 23 ++ Scripts/Items/VirtueShrineController.cs | 239 ++++++++++++++++++ Scripts/Items/VirtueSigil.cs | 56 ++++ Scripts/Items/VirtueTome.cs | 77 +++++- 4 files changed, 382 insertions(+), 13 deletions(-) create mode 100644 Data/Decoration/Britannia/ShrineControllers.cfg create mode 100644 Scripts/Items/VirtueShrineController.cs create mode 100644 Scripts/Items/VirtueSigil.cs diff --git a/Data/Decoration/Britannia/ShrineControllers.cfg b/Data/Decoration/Britannia/ShrineControllers.cfg new file mode 100644 index 0000000..6be5207 --- /dev/null +++ b/Data/Decoration/Britannia/ShrineControllers.cfg @@ -0,0 +1,23 @@ +CompassionController 0x1BC3 Compassion +2488 1481 5 + +HonestyController 0x1BC3 Honesty +4137 1087 5 + +HonorController 0x1BC3 Honor +1876 2823 6 + +HumilityController 0x1BC3 Humility +4126 2999 5 + +JusticeController 0x1BC3 Justice +1655 546 0 + +SacrificeController 0x1BC3 Sacrifice +3743 928 2 + +SpiritualityController 0x1BC3 Spirituality +1008 1849 10 + +ValorController 0x1BC3 Valor +1246 3410 7 diff --git a/Scripts/Items/VirtueShrineController.cs b/Scripts/Items/VirtueShrineController.cs new file mode 100644 index 0000000..af16f37 --- /dev/null +++ b/Scripts/Items/VirtueShrineController.cs @@ -0,0 +1,239 @@ +using System; +using Server; +using Server.Items; +using Server.Mobiles; +using Server.Network; + +namespace Server.Items +{ + public class ShrineController : Item + { + private VirtueName m_Shrine; + + [CommandProperty( AccessLevel.GameMaster )] + public VirtueName Shrine + { + get { return m_Shrine; } + set { m_Shrine = value; InvalidateProperties(); } + } + + [Constructable] + public ShrineController() : this( VirtueName.Compassion ) + { + } + + [Constructable] + public ShrineController( VirtueName shrine ) : base( 0x1BC3 ) + { + m_Shrine = shrine; + Name = shrine.ToString() + " Shrine Controller"; + Movable = false; + Visible = false; + } + + public ShrineController( Serial serial ) : base( serial ) + { + } + + public override bool HandlesOnSpeech { get { return true; } } + + public override void OnSpeech( SpeechEventArgs e ) + { + if ( e.Handled || !e.Mobile.InRange( this.GetWorldLocation(), 5 ) ) + return; + + string speech = e.Speech.ToLower().Trim(); + string mantra = GetMantra( m_Shrine ); + + if ( speech == mantra ) + { + PlayerMobile pm = e.Mobile as PlayerMobile; + if ( pm != null ) + { + foreach ( Item item in pm.Backpack.Items ) + { + if ( item is VirtueSigil && ((VirtueSigil)item).Shrine == m_Shrine ) + { + pm.SendMessage( 33, "You already possess the sigil for this shrine." ); + return; + } + } + + pm.SendMessage( 63, "The shrine recognizes your devotion and grants you a sigil!" ); + + pm.PlaySound( 0x244 ); + Effects.SendLocationParticles( EffectItem.Create( pm.Location, pm.Map, EffectItem.DefaultDuration ), 0x376A, 10, 10, 2023 ); + + pm.AddToBackpack( new VirtueSigil( m_Shrine ) ); + e.Handled = true; + } + } + } + + private string GetMantra( VirtueName virtue ) + { + switch ( virtue ) + { + case VirtueName.Compassion: return "mu"; + case VirtueName.Honesty: return "ahm"; + case VirtueName.Honor: return "summ"; + case VirtueName.Humility: return "lum"; + case VirtueName.Justice: return "beh"; + case VirtueName.Sacrifice: return "cah"; + case VirtueName.Spirituality: return "om"; + case VirtueName.Valor: return "ra"; + default: return "om"; + } + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); // version + writer.Write( (int) m_Shrine ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + m_Shrine = (VirtueName)reader.ReadInt(); + } + } + + public class CompassionController : ShrineController + { + [Constructable] public CompassionController() : base( VirtueName.Compassion ) { } + public CompassionController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class HonestyController : ShrineController + { + [Constructable] public HonestyController() : base( VirtueName.Honesty ) { } + public HonestyController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class HonorController : ShrineController + { + [Constructable] public HonorController() : base( VirtueName.Honor ) { } + public HonorController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class HumilityController : ShrineController + { + [Constructable] public HumilityController() : base( VirtueName.Humility ) { } + public HumilityController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class JusticeController : ShrineController + { + [Constructable] public JusticeController() : base( VirtueName.Justice ) { } + public JusticeController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class SacrificeController : ShrineController + { + [Constructable] public SacrificeController() : base( VirtueName.Sacrifice ) { } + public SacrificeController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class SpiritualityController : ShrineController + { + [Constructable] public SpiritualityController() : base( VirtueName.Spirituality ) { } + public SpiritualityController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } + + public class ValorController : ShrineController + { + [Constructable] public ValorController() : base( VirtueName.Valor ) { } + public ValorController( Serial serial ) : base( serial ) { } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); + } + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + } + } +} diff --git a/Scripts/Items/VirtueSigil.cs b/Scripts/Items/VirtueSigil.cs new file mode 100644 index 0000000..bac1835 --- /dev/null +++ b/Scripts/Items/VirtueSigil.cs @@ -0,0 +1,56 @@ +using System; +using Server; + +namespace Server.Items +{ + public enum VirtueName + { + Compassion = 0, + Honesty, + Honor, + Humility, + Justice, + Sacrifice, + Spirituality, + Valor + } + + public class VirtueSigil : Item + { + private VirtueName m_Shrine; + + [CommandProperty( AccessLevel.GameMaster )] + public VirtueName Shrine + { + get { return m_Shrine; } + set { m_Shrine = value; InvalidateProperties(); } + } + + [Constructable] + public VirtueSigil( VirtueName shrine ) : base( 0x1F14 ) + { + m_Shrine = shrine; + Name = "A Sigil of " + shrine.ToString(); + Hue = 1174; + Weight = 1.0; + } + + public VirtueSigil( Serial serial ) : base( serial ) + { + } + + public override void Serialize( GenericWriter writer ) + { + base.Serialize( writer ); + writer.Write( (int) 0 ); // version + writer.Write( (int) m_Shrine ); + } + + public override void Deserialize( GenericReader reader ) + { + base.Deserialize( reader ); + int version = reader.ReadInt(); + m_Shrine = (VirtueName)reader.ReadInt(); + } + } +} diff --git a/Scripts/Items/VirtueTome.cs b/Scripts/Items/VirtueTome.cs index 9cc64e2..ed13ff6 100644 --- a/Scripts/Items/VirtueTome.cs +++ b/Scripts/Items/VirtueTome.cs @@ -8,24 +8,54 @@ namespace Server.Items { public class VirtueTome : Item { + public bool[] Unlocked = new bool[8]; + [Constructable] - public VirtueTome() : base( 0x2259 ) // Standard spellbook graphic + public VirtueTome() : base( 0x22C3 ) { Name = "A Tome of Virtues"; - Hue = 1174; // A nice bright gold/yellow hue + Hue = 1174; Weight = 1.0; - LootType = LootType.Blessed; // So they don't lose their travel hub on death + LootType = LootType.Blessed; } public VirtueTome( Serial serial ) : base( serial ) { } + public override bool OnDragDrop( Mobile from, Item dropped ) + { + if ( dropped is VirtueSigil ) + { + VirtueSigil sigil = (VirtueSigil)dropped; + int index = (int)sigil.Shrine; + + if ( index >= 0 && index < 8 ) + { + if ( Unlocked[index] ) + { + from.SendMessage( 33, "This tome already holds the knowledge of that shrine." ); + } + else + { + Unlocked[index] = true; + from.SendMessage( 63, "The knowledge of the shrine has been bound to your tome!" ); + + from.PlaySound( 0x244 ); + dropped.Delete(); + } + return true; + } + } + + return base.OnDragDrop( from, dropped ); + } + public override void OnDoubleClick( Mobile from ) { if ( !IsChildOf( from.Backpack ) ) { - from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it. + from.SendLocalizedMessage( 1042001 ); return; } @@ -39,13 +69,26 @@ namespace Server.Items public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); - writer.Write( (int) 0 ); // version + writer.Write( (int) 1 ); + + for ( int i = 0; i < 8; i++ ) + { + writer.Write( Unlocked[i] ); + } } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); + + if ( version >= 1 ) + { + for ( int i = 0; i < 8; i++ ) + { + Unlocked[i] = reader.ReadBool(); + } + } } } @@ -53,16 +96,15 @@ namespace Server.Items { private PlayerMobile m_From; private VirtueTome m_Tome; - private int m_TravelCost = 15; // <--- SET YOUR VIRTUE POINT COST HERE + private int m_TravelCost = 15; - // Standard Britannia Shrine Locations private Point3D[] m_Shrines = new Point3D[] { new Point3D( 2487, 1485, 0 ), // Compassion new Point3D( 4137, 1092, 0 ), // Honesty new Point3D( 1879, 2823, 1 ), // Honor new Point3D( 4130, 2999, 0 ), // Humility - new Point3D( 1658, 547, 0 ), // Justice + new Point3D( 1658, 547, 0 ), // Justice new Point3D( 3743, 931, 2 ), // Sacrifice new Point3D( 1010, 1849, 5 ), // Spirituality new Point3D( 1250, 3410, 1 ) // Valor @@ -80,14 +122,22 @@ namespace Server.Items AddHtml( 10, 40, 280, 20, String.Format( "Available Virtue Points: {0}", from.VirtuePoints ), false, false ); AddHtml( 10, 60, 280, 20, String.Format( "Travel Cost: {0} Points", m_TravelCost ), false, false ); - // Shrine Buttons int y = 90; string[] shrineNames = { "Compassion", "Honesty", "Honor", "Humility", "Justice", "Sacrifice", "Spirituality", "Valor" }; for ( int i = 0; i < shrineNames.Length; i++ ) { - AddButton( 20, y, 4005, 4007, i + 1, GumpButtonType.Reply, 0 ); - AddLabel( 55, y, 0, shrineNames[i] ); + // Check if the shrine is unlocked + if ( m_Tome.Unlocked[i] ) + { + AddButton( 20, y, 4005, 4007, i + 1, GumpButtonType.Reply, 0 ); + AddLabel( 55, y, 0, shrineNames[i] ); + } + else + { + // If locked, hide the button and grey out the text + AddLabel( 55, y, 922, shrineNames[i] + " (Locked)" ); + } y += 30; } } @@ -100,15 +150,16 @@ namespace Server.Items { int index = button - 1; + if ( !m_Tome.Unlocked[index] ) + return; + if ( m_From.VirtuePoints >= m_TravelCost ) { m_From.VirtuePoints -= m_TravelCost; m_From.SendMessage( 63, "You channel your virtues to step through the ether." ); - // Teleport the player m_From.MoveToWorld( m_Shrines[index], Map.Britannia ); - // Play a cool spell effect and sound Effects.SendLocationParticles( EffectItem.Create( m_From.Location, m_From.Map, EffectItem.DefaultDuration ), 0x3728, 10, 10, 2023 ); m_From.PlaySound( 0x1FE ); }