#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.

This commit is contained in:
WarrentyExpired 2026-08-06 11:06:05 -04:00
parent b51c58f514
commit 3045c83799
3512 changed files with 627673 additions and 0 deletions

View file

@ -0,0 +1,283 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Targeting;
using Server.Network;
namespace Server.Items
{
public enum BagOfSendingHue
{
Yellow,
Blue,
Red
}
public class BagOfSending : Item, TranslocationItem
{
public static BagOfSendingHue RandomHue()
{
switch ( Utility.Random( 3 ) )
{
case 0: return BagOfSendingHue.Yellow;
case 1: return BagOfSendingHue.Blue;
default: return BagOfSendingHue.Red;
}
}
private int m_Charges;
private int m_Recharges;
private BagOfSendingHue m_BagOfSendingHue;
[CommandProperty( AccessLevel.GameMaster )]
public int Charges
{
get{ return m_Charges; }
set
{
if ( value > this.MaxCharges )
m_Charges = this.MaxCharges;
else if ( value < 0 )
m_Charges = 0;
else
m_Charges = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int Recharges
{
get{ return m_Recharges; }
set
{
if ( value > this.MaxRecharges )
m_Recharges = this.MaxRecharges;
else if ( value < 0 )
m_Recharges = 0;
else
m_Recharges = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxCharges{ get{ return 30; } }
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRecharges{ get{ return 255; } }
public string TranslocationItemName{ get{ return "bag of sending"; } }
public override int LabelNumber{ get{ return 1054104; } } // a bag of sending
[CommandProperty( AccessLevel.GameMaster )]
public BagOfSendingHue BagOfSendingHue
{
get{ return m_BagOfSendingHue; }
set
{
m_BagOfSendingHue = value;
switch ( value )
{
case BagOfSendingHue.Yellow: this.Hue = 0x8A5; break;
case BagOfSendingHue.Blue: this.Hue = 0x8AD; break;
case BagOfSendingHue.Red: this.Hue = 0x89B; break;
}
}
}
[Constructable]
public BagOfSending() : this( RandomHue() )
{
}
[Constructable]
public BagOfSending( BagOfSendingHue hue ) : base( 0xE76 )
{
Weight = 2.0;
this.BagOfSendingHue = hue;
m_Charges = Utility.RandomMinMax( 3, 9 );
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1060741, m_Charges.ToString() ); // charges: ~1_val~
}
public override void OnSingleClick( Mobile from )
{
base.OnSingleClick( from );
LabelTo( from, 1060741, m_Charges.ToString() ); // charges: ~1_val~
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive )
list.Add( new UseBagEntry( this, Charges > 0 && IsChildOf( from.Backpack ) ) );
}
private class UseBagEntry : ContextMenuEntry
{
private BagOfSending m_Bag;
public UseBagEntry( BagOfSending bag, bool enabled ) : base( 6189 )
{
m_Bag = bag;
if ( !enabled )
Flags |= CMEFlags.Disabled;
}
public override void OnClick()
{
if ( m_Bag.Deleted )
return;
Mobile from = Owner.From;
if ( from.CheckAlive() )
m_Bag.OnDoubleClick( from );
}
}
public override void OnDoubleClick( Mobile from )
{
if( from.Region.IsPartOf( typeof( Regions.Jail ) ) )
{
from.SendMessage( "You may not do that in jail." );
}
else if( !this.IsChildOf( from.Backpack ) )
{
MessageHelper.SendLocalizedMessageTo(this, from, 1062334, 0x59); // The bag of sending must be in your backpack.
}
else if( this.Charges == 0 )
{
MessageHelper.SendLocalizedMessageTo( this, from, 1042544, 0x59 ); // This item is out of charges.
}
else
{
from.Target = new SendTarget( this );
}
}
private class SendTarget : Target
{
private BagOfSending m_Bag;
public SendTarget( BagOfSending bag ) : base( -1, false, TargetFlags.None )
{
m_Bag = bag;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Bag.Deleted )
return;
if( from.Region.IsPartOf( typeof( Regions.Jail ) ) )
{
from.SendMessage( "You may not do that in jail." );
}
else if( !m_Bag.IsChildOf( from.Backpack ) )
{
MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1062334, 0x59); // The bag of sending must be in your backpack. 1054107 is gone from client, using generic response
}
else if ( m_Bag.Charges == 0 )
{
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1042544, 0x59 ); // This item is out of charges.
}
else if ( targeted is Item )
{
Item item = (Item)targeted;
int reqCharges = (int)Math.Max( 1, Math.Ceiling( item.TotalWeight / 10.0 ) );
if ( !item.IsChildOf( from.Backpack ) )
{
MessageHelper.SendLocalizedMessageTo(m_Bag, from, 1054152, 0x59); // You may only send items from your backpack to your bank box.
}
else if ( item is BagOfSending || item is Container )
{
from.Send( new AsciiMessage( m_Bag.Serial, m_Bag.ItemID, MessageType.Regular, 0x3B2, 3, "", "You cannot send a container through the bag of sending." ) );
}
else if ( item.LootType == LootType.Cursed )
{
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054108, 0x59 ); // The bag of sending rejects the cursed item.
}
else if ( !item.VerifyMove( from ) || item is Server.Engines.Quests.QuestItem || item.Nontransferable )
{
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054109, 0x59 ); // The bag of sending rejects that item.
}
else if ( Spells.SpellHelper.IsDoomGauntlet( from.Map, from.Location ) )
{
from.SendLocalizedMessage( 1062089 ); // You cannot use that here.
}
else if ( !from.BankBox.TryDropItem( from, item, false ) )
{
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054110, 0x59 ); // Your bank box is full.
}
else if ( Core.ML && reqCharges > m_Bag.Charges )
{
from.SendLocalizedMessage( 1079932 ); //You don't have enough charges to send that much weight
}
else
{
m_Bag.Charges -= (Core.ML ? reqCharges : 1);
MessageHelper.SendLocalizedMessageTo( m_Bag, from, 1054150, 0x59 ); // The item was placed in your bank box.
}
}
}
}
public BagOfSending( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 1 ); // version
writer.WriteEncodedInt( (int) m_Recharges );
writer.WriteEncodedInt( (int) m_Charges );
writer.WriteEncodedInt( (int) m_BagOfSendingHue );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_Recharges = reader.ReadEncodedInt();
goto case 0;
}
case 0:
{
m_Charges = Math.Min( reader.ReadEncodedInt(), MaxCharges );
m_BagOfSendingHue = (BagOfSendingHue) reader.ReadEncodedInt();
break;
}
}
}
}
}

View file

@ -0,0 +1,471 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Targeting;
using Server.ContextMenus;
using Server.Network;
using Server.Regions;
using Server.Spells;
using Server.Spells.Ninjitsu;
namespace Server.Items
{
public class BallOfSummoning : Item, TranslocationItem
{
private int m_Charges;
private int m_Recharges;
private BaseCreature m_Pet;
private string m_PetName;
[CommandProperty( AccessLevel.GameMaster )]
public int Charges
{
get{ return m_Charges; }
set
{
if ( value > this.MaxCharges )
m_Charges = this.MaxCharges;
else if ( value < 0 )
m_Charges = 0;
else
m_Charges = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int Recharges
{
get{ return m_Recharges; }
set
{
if ( value > this.MaxRecharges )
m_Recharges = this.MaxRecharges;
else if ( value < 0 )
m_Recharges = 0;
else
m_Recharges = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxCharges{ get{ return 20; } }
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRecharges{ get{ return 255; } }
public string TranslocationItemName{ get{ return "crystal ball of pet summoning"; } }
[CommandProperty( AccessLevel.GameMaster )]
public BaseCreature Pet
{
get
{
if ( m_Pet != null && m_Pet.Deleted )
{
m_Pet = null;
InternalUpdatePetName();
}
return m_Pet;
}
set
{
m_Pet = value;
InternalUpdatePetName();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string PetName{ get{ return m_PetName; } }
[Constructable]
public BallOfSummoning() : base( 0xE2E )
{
Weight = 10.0;
Light = LightType.Circle150;
m_Charges = Utility.RandomMinMax( 3, 9 );
m_PetName = "";
}
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( 1054131, m_Charges.ToString() + ( m_PetName.Length == 0 ? "\t " : "\t" + m_PetName ) ); // a crystal ball of pet summoning: [charges: ~1_charges~] : [linked pet: ~2_petName~]
}
public override void OnSingleClick( Mobile from )
{
LabelTo( from, 1054131, m_Charges.ToString() + ( m_PetName.Length == 0 ? "\t " : "\t" + m_PetName ) ); // a crystal ball of pet summoning: [charges: ~1_charges~] : [linked pet: ~2_petName~]
}
private delegate void BallCallback( Mobile from );
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive && this.RootParent == from )
{
if ( Pet == null )
{
list.Add( new BallEntry( new BallCallback( LinkPet ), 6180 ) );
}
else
{
list.Add(new BallEntry(new BallCallback( CastSummonPet ), 6181 ));
list.Add( new BallEntry( new BallCallback( UpdatePetName ), 6183 ) );
list.Add( new BallEntry( new BallCallback( UnlinkPet ), 6182 ) );
}
}
}
private class BallEntry : ContextMenuEntry
{
private BallCallback m_Callback;
public BallEntry( BallCallback callback, int number ) : base( number, 2 )
{
m_Callback = callback;
}
public override void OnClick()
{
Mobile from = Owner.From;
if ( from.CheckAlive() )
m_Callback( from );
}
}
public override void OnDoubleClick( Mobile from )
{
if ( this.RootParent != from ) // TODO: Previous implementation allowed use on ground, without house protection checks. What is the correct behavior?
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1042001 ); // That must be in your pack for you to use it.
return;
}
AnimalFormContext animalContext = AnimalForm.GetContext( from );
if( Core.ML && animalContext != null )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1080073 ); // You cannot use a Crystal Ball of Pet Summoning while in animal form.
return;
}
if ( Pet == null )
{
LinkPet( from );
}
else
{
CastSummonPet( from );
}
}
public void LinkPet( Mobile from )
{
BaseCreature pet = this.Pet;
if ( Deleted || pet != null || this.RootParent != from )
return;
from.SendLocalizedMessage( 1054114 ); // Target your pet that you wish to link to this Crystal Ball of Pet Summoning.
from.Target = new PetLinkTarget( this );
}
private class PetLinkTarget : Target
{
private BallOfSummoning m_Ball;
public PetLinkTarget( BallOfSummoning ball ) : base( -1, false, TargetFlags.None )
{
m_Ball = ball;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Ball.Deleted || m_Ball.Pet != null )
return;
if ( m_Ball.RootParent != from )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1042001 ); // That must be in your pack for you to use it.
}
else if ( targeted is BaseCreature )
{
BaseCreature creature = (BaseCreature)targeted;
if ( !creature.Controlled || creature.ControlMaster != from )
{
MessageHelper.SendLocalizedMessageTo( m_Ball, from, 1054117, 0x59 ); // You may only link your own pets to a Crystal Ball of Pet Summoning.
}
else if ( !creature.IsBonded )
{
MessageHelper.SendLocalizedMessageTo( m_Ball, from, 1054118, 0x59 ); // You must bond with your pet before it can be linked to a Crystal Ball of Pet Summoning.
}
else
{
MessageHelper.SendLocalizedMessageTo( m_Ball, from, 1054119, 0x59 ); // Your pet is now linked to this Crystal Ball of Pet Summoning.
m_Ball.Pet = creature;
}
}
else if ( targeted == m_Ball )
{
MessageHelper.SendLocalizedMessageTo( m_Ball, from, 1054115, 0x59 ); // The Crystal Ball of Pet Summoning cannot summon itself.
}
else
{
MessageHelper.SendLocalizedMessageTo( m_Ball, from, 1054116, 0x59 ); // Only pets can be linked to this Crystal Ball of Pet Summoning.
}
}
}
public void CastSummonPet( Mobile from )
{
BaseCreature pet = this.Pet;
if ( Deleted || pet == null || this.RootParent != from )
return;
if ( Charges == 0 )
{
SendLocalizedMessageTo( from, 1054122 ); // The Crystal Ball darkens. It must be charged before it can be used again.
}
else if ( pet is BaseMount && ((BaseMount)pet).Rider == from )
{
MessageHelper.SendLocalizedMessageTo( this, from, 1054124, 0x36 ); // The Crystal Ball fills with a yellow mist. Why would you summon your pet while riding it?
}
else if ( pet.Map == Map.Internal && ( !pet.IsStabled || (from.Followers + pet.ControlSlots) > from.FollowersMax ) )
{
MessageHelper.SendLocalizedMessageTo( this, from, 1054125, 0x5 ); // The Crystal Ball fills with a blue mist. Your pet is not responding to the summons.
}
else if ( ( !pet.Controlled || pet.ControlMaster != from ) && !from.Stabled.Contains( pet ) )
{
MessageHelper.SendLocalizedMessageTo( this, from, 1054126, 0x8FD ); // The Crystal Ball fills with a grey mist. You are not the owner of the pet you are attempting to summon.
}
else if ( !pet.IsBonded )
{
MessageHelper.SendLocalizedMessageTo( this, from, 1054127, 0x22 ); // The Crystal Ball fills with a red mist. You appear to have let your bond to your pet deteriorate.
}
else if ( from.Map == Map.Ilshenar || from.Region.IsPartOf( typeof( DungeonRegion ) ) || from.Region.IsPartOf( typeof( Jail ) ) || from.Region.IsPartOf( typeof( Server.Engines.ConPVP.SafeZone ) ) )
{
from.Send( new AsciiMessage( this.Serial, this.ItemID, MessageType.Regular, 0x22, 3, "", "You cannot summon your pet to this location." ) );
}
else if ( Core.ML && from is PlayerMobile && DateTime.UtcNow < ((PlayerMobile)from).LastPetBallTime.AddSeconds( 15.0 ) )
{
MessageHelper.SendLocalizedMessageTo( this, from, 1080072, 0x22 ); // You must wait a few seconds before you can summon your pet.
}
else
{
if( Core.ML )
new PetSummoningSpell( this, from ).Cast();
else
SummonPet( from );
}
}
public void SummonPet( Mobile from )
{
BaseCreature pet = this.Pet;
if ( pet == null )
return;
Charges--;
if ( pet.IsStabled )
{
pet.SetControlMaster( from );
if ( pet.Summoned )
pet.SummonMaster = from;
pet.ControlTarget = from;
pet.ControlOrder = OrderType.Follow;
pet.IsStabled = false;
pet.StabledBy = null;
from.Stabled.Remove( pet );
if ( from is PlayerMobile )
((PlayerMobile)from).AutoStabled.Remove( pet );
}
pet.MoveToWorld( from.Location, from.Map );
MessageHelper.SendLocalizedMessageTo( this, from, 1054128, 0x43 ); // The Crystal Ball fills with a green mist. Your pet has been summoned.
if ( from is PlayerMobile )
{
((PlayerMobile)from).LastPetBallTime = DateTime.UtcNow;
}
}
public void UnlinkPet( Mobile from )
{
if ( !Deleted && Pet != null && this.RootParent == from )
{
Pet = null;
SendLocalizedMessageTo( from, 1054120 ); // This crystal ball is no longer linked to a pet.
}
}
public void UpdatePetName( Mobile from )
{
InternalUpdatePetName();
}
private void InternalUpdatePetName()
{
BaseCreature pet = this.Pet;
if ( pet == null )
m_PetName = "";
else
m_PetName = pet.Name;
InvalidateProperties();
}
public BallOfSummoning( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 1 ); // version
writer.WriteEncodedInt( (int) m_Recharges );
writer.WriteEncodedInt( (int) m_Charges );
writer.Write( (Mobile) this.Pet );
writer.Write( (string) m_PetName );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_Recharges = reader.ReadEncodedInt();
goto case 0;
}
case 0:
{
m_Charges = Math.Min( reader.ReadEncodedInt(), MaxCharges );
this.Pet = (BaseCreature) reader.ReadMobile();
m_PetName = reader.ReadString();
break;
}
}
}
private class PetSummoningSpell : Spell
{
private static SpellInfo m_Info = new SpellInfo( "Ball Of Summoning", "", 230 );
private BallOfSummoning m_Ball;
private Mobile m_Caster;
public PetSummoningSpell( BallOfSummoning ball, Mobile caster )
: base( caster, null, m_Info )
{
m_Caster = caster;
m_Ball = ball;
}
public override bool ClearHandsOnCast { get { return false; } }
public override bool RevealOnCast { get { return true; } }
public override TimeSpan GetCastRecovery()
{
return TimeSpan.Zero;
}
public override double CastDelayFastScalar { get { return 0; } }
public override TimeSpan CastDelayBase
{
get
{
return TimeSpan.FromSeconds( 2.0 );
}
}
public override int GetMana()
{
return 0;
}
public override bool ConsumeReagents()
{
return true;
}
public override bool CheckFizzle()
{
return true;
}
private bool m_Stop;
public void Stop()
{
m_Stop = true;
Disturb( DisturbType.Hurt, false, false );
}
public override bool CheckDisturb( DisturbType type, bool checkFirst, bool resistable )
{
if( type == DisturbType.EquipRequest || type == DisturbType.UseRequest/* || type == DisturbType.Hurt*/ )
return false;
return true;
}
public override void DoHurtFizzle()
{
if( !m_Stop )
base.DoHurtFizzle();
}
public override void DoFizzle()
{
if( !m_Stop )
base.DoFizzle();
}
public override void OnDisturb( DisturbType type, bool message )
{
if( message && !m_Stop )
Caster.SendLocalizedMessage( 1080074 ); // You have been disrupted while attempting to summon your pet!
}
public override void OnCast()
{
m_Ball.SummonPet( m_Caster );
FinishSequence();
}
}
}
}

View file

@ -0,0 +1,474 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Network;
using Server.Prompts;
using Server.Targeting;
using Server.Spells;
using Server.Mobiles;
namespace Server.Items
{
public class BraceletOfBinding : BaseBracelet, TranslocationItem
{
private int m_Charges;
private int m_Recharges;
private string m_Inscription;
private BraceletOfBinding m_Bound;
private TransportTimer m_Timer;
[CommandProperty( AccessLevel.GameMaster )]
public int Charges
{
get{ return m_Charges; }
set
{
if ( value > this.MaxCharges )
m_Charges = this.MaxCharges;
else if ( value < 0 )
m_Charges = 0;
else
m_Charges = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int Recharges
{
get{ return m_Recharges; }
set
{
if ( value > this.MaxRecharges )
m_Recharges = this.MaxRecharges;
else if ( value < 0 )
m_Recharges = 0;
else
m_Recharges = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxCharges{ get{ return 20; } }
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRecharges{ get{ return 255; } }
public string TranslocationItemName{ get{ return "bracelet of binding"; } }
[CommandProperty( AccessLevel.GameMaster )]
public string Inscription
{
get{ return m_Inscription; }
set
{
m_Inscription = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public BraceletOfBinding Bound
{
get
{
if ( m_Bound != null && m_Bound.Deleted )
m_Bound = null;
return m_Bound;
}
set{ m_Bound = value; }
}
[Constructable]
public BraceletOfBinding() : base( 0x1086 )
{
Hue = 0x489;
Weight = 1.0;
m_Inscription = "";
}
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( 1054000, m_Charges.ToString() + ( m_Inscription.Length == 0 ? "\t " : " :\t" + m_Inscription ) ); // a bracelet of binding : ~1_val~ ~2_val~
}
public override void OnSingleClick( Mobile from )
{
LabelTo( from, 1054000, m_Charges.ToString() + ( m_Inscription.Length == 0 ? "\t " : " :\t" + m_Inscription ) ); // a bracelet of binding : ~1_val~ ~2_val~
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive && this.IsChildOf( from ) )
{
BraceletOfBinding bound = this.Bound;
list.Add( new BraceletEntry( new BraceletCallback( Activate ), 6170, bound != null ) );
list.Add( new BraceletEntry( new BraceletCallback( Search ), 6171, bound != null ) );
list.Add( new BraceletEntry( new BraceletCallback( Bind ), bound == null ? 6173 : 6174, true ) );
list.Add( new BraceletEntry( new BraceletCallback( Inscribe ), 6175, true ) );
}
}
private delegate void BraceletCallback( Mobile from );
private class BraceletEntry : ContextMenuEntry
{
private BraceletCallback m_Callback;
public BraceletEntry( BraceletCallback callback, int number, bool enabled ) : base( number )
{
m_Callback = callback;
if ( !enabled )
Flags |= CMEFlags.Disabled;
}
public override void OnClick()
{
Mobile from = Owner.From;
if ( from.CheckAlive() )
m_Callback( from );
}
}
public override void OnDoubleClick( Mobile from )
{
BraceletOfBinding bound = this.Bound;
if ( Bound == null )
{
Bind( from );
}
else
{
Activate( from );
}
}
public void Activate( Mobile from )
{
BraceletOfBinding bound = this.Bound;
if ( Deleted || bound == null )
return;
if ( !this.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else if ( m_Timer != null )
{
from.SendLocalizedMessage( 1054013 ); // The bracelet is already attempting contact. You decide to wait a moment.
}
else
{
from.PlaySound( 0xF9 );
from.LocalOverheadMessage( MessageType.Regular, 0x5D, true, "* You concentrate on the bracelet to summon its power *" );
from.Frozen = true;
m_Timer = new TransportTimer( this, from );
m_Timer.Start();
}
}
private class TransportTimer : Timer
{
private BraceletOfBinding m_Bracelet;
private Mobile m_From;
public TransportTimer( BraceletOfBinding bracelet, Mobile from ) : base( TimeSpan.FromSeconds( 2.0 ) )
{
m_Bracelet = bracelet;
m_From = from;
}
protected override void OnTick()
{
m_Bracelet.m_Timer = null;
m_From.Frozen = false;
if ( m_Bracelet.Deleted || m_From.Deleted )
return;
if ( m_Bracelet.CheckUse( m_From, false ) )
{
Mobile boundRoot = m_Bracelet.Bound.RootParent as Mobile;
if ( boundRoot != null )
{
m_Bracelet.Charges--;
BaseCreature.TeleportPets( m_From, boundRoot.Location, boundRoot.Map, true );
m_From.PlaySound( 0x1FC );
m_From.MoveToWorld( boundRoot.Location, boundRoot.Map );
m_From.PlaySound( 0x1FC );
}
}
}
}
public void Search( Mobile from )
{
BraceletOfBinding bound = this.Bound;
if ( Deleted || bound == null )
return;
if ( !this.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else
{
CheckUse( from, true );
}
}
private bool CheckUse( Mobile from, bool successMessage )
{
BraceletOfBinding bound = this.Bound;
if ( bound == null )
return false;
Mobile boundRoot = bound.RootParent as Mobile;
if ( Charges == 0 )
{
from.SendLocalizedMessage( 1054005 ); // The bracelet glows black. It must be charged before it can be used again.
return false;
}
else if ( from.FindItemOnLayer( Layer.Bracelet ) != this )
{
from.SendLocalizedMessage( 1054004 ); // You must equip the bracelet in order to use its power.
return false;
}
else if ( boundRoot == null || boundRoot.NetState == null || boundRoot.FindItemOnLayer( Layer.Bracelet ) != bound )
{
from.SendLocalizedMessage( 1054006 ); // The bracelet emits a red glow. The bracelet's twin is not available for transport.
return false;
}
else if ( !Core.AOS && from.Map != boundRoot.Map )
{
from.SendLocalizedMessage( 1054014 ); // The bracelet glows black. The bracelet's target is on another facet.
return false;
}
else if ( Factions.Sigil.ExistsOn( from ) )
{
from.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
return false;
}
else if ( !SpellHelper.CheckTravel( from, TravelCheckType.RecallFrom ) )
{
return false;
}
else if ( !SpellHelper.CheckTravel( from, boundRoot.Map, boundRoot.Location, TravelCheckType.RecallTo ) )
{
return false;
}
else if ( boundRoot.Map == Map.Felucca && from is PlayerMobile && ((PlayerMobile)from).Young )
{
from.SendLocalizedMessage( 1049543 ); // You decide against traveling to Felucca while you are still young.
return false;
}
else if ( from.Kills >= 5 && boundRoot.Map != Map.Felucca )
{
from.SendLocalizedMessage( 1019004 ); // You are not allowed to travel there.
return false;
}
else if ( from.Criminal )
{
from.SendLocalizedMessage( 1005561, "", 0x22 ); // Thou'rt a criminal and cannot escape so easily.
return false;
}
else if ( SpellHelper.CheckCombat( from ) )
{
from.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
return false;
}
else if ( Server.Misc.WeightOverloading.IsOverloaded( from ) )
{
from.SendLocalizedMessage( 502359, "", 0x22 ); // Thou art too encumbered to move.
return false;
}
else if ( from.Region.IsPartOf( typeof( Server.Regions.Jail ) ) )
{
from.SendLocalizedMessage( 1114345, "", 0x35 ); // You'll need a better jailbreak plan than that!
return false;
}
else if ( boundRoot.Region.IsPartOf( typeof( Server.Regions.Jail ) ) )
{
from.SendLocalizedMessage( 1019004 ); // You are not allowed to travel there.
return false;
}
else
{
if ( successMessage )
from.SendLocalizedMessage( 1054015 ); // The bracelet's twin is available for transport.
return true;
}
}
public void Bind( Mobile from )
{
if ( Deleted )
return;
if ( !this.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else
{
from.SendLocalizedMessage( 1054001 ); // Target the bracelet of binding you wish to bind this bracelet to.
from.Target = new BindTarget( this );
}
}
private class BindTarget : Target
{
private BraceletOfBinding m_Bracelet;
public BindTarget( BraceletOfBinding bracelet ) : base( -1, false, TargetFlags.None )
{
m_Bracelet = bracelet;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Bracelet.Deleted )
return;
if ( !m_Bracelet.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else if ( targeted is BraceletOfBinding )
{
BraceletOfBinding bindBracelet = (BraceletOfBinding)targeted;
if ( bindBracelet == m_Bracelet )
{
from.SendLocalizedMessage( 1054012 ); // You cannot bind a bracelet of binding to itself!
}
else if ( !bindBracelet.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else
{
from.SendLocalizedMessage( 1054003 ); // You bind the bracelet to its counterpart. The bracelets glow with power.
from.PlaySound( 0x1FA );
m_Bracelet.Bound = bindBracelet;
}
}
else
{
from.SendLocalizedMessage( 1054002 ); // You can only bind this bracelet to another bracelet of binding!
}
}
}
public void Inscribe( Mobile from )
{
if ( Deleted )
return;
if ( !this.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else
{
from.SendLocalizedMessage( 1054009 ); // Enter the text to inscribe upon the bracelet :
from.Prompt = new InscribePrompt( this );
}
}
private class InscribePrompt : Prompt
{
private BraceletOfBinding m_Bracelet;
public InscribePrompt( BraceletOfBinding bracelet )
{
m_Bracelet = bracelet;
}
public override void OnResponse( Mobile from, string text )
{
if ( m_Bracelet.Deleted )
return;
if ( !m_Bracelet.IsChildOf( from ) )
{
from.SendLocalizedMessage( 1042664 ); // You must have the object in your backpack to use it.
}
else
{
from.SendLocalizedMessage( 1054011 ); // You mark the bracelet with your inscription.
m_Bracelet.Inscription = text;
}
}
public override void OnCancel( Mobile from )
{
from.SendLocalizedMessage( 1054010 ); // You decide not to inscribe the bracelet at this time.
}
}
public BraceletOfBinding( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 1 ); // version
writer.WriteEncodedInt( (int) m_Recharges );
writer.WriteEncodedInt( (int) m_Charges );
writer.Write( (string) m_Inscription );
writer.Write( (Item) this.Bound );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_Recharges = reader.ReadEncodedInt();
goto case 0;
}
case 0:
{
m_Charges = Math.Min( reader.ReadEncodedInt(), MaxCharges );
m_Inscription = reader.ReadString();
this.Bound = (BraceletOfBinding) reader.ReadItem();
break;
}
}
}
}
}

View file

@ -0,0 +1,23 @@
using System;
using Server.Network;
namespace Server
{
public class MessageHelper
{
public static void SendLocalizedMessageTo( Item from, Mobile to, int number, int hue )
{
SendLocalizedMessageTo( from, to, number, "", hue );
}
public static void SendLocalizedMessageTo( Item from, Mobile to, int number, string args, int hue )
{
to.Send( new MessageLocalized( from.Serial, from.ItemID, MessageType.Regular, hue, 3, number, "", args ) );
}
public static void SendMessageTo( Item from, Mobile to, string text, int hue )
{
to.Send( new UnicodeMessage( from.Serial, from.ItemID, MessageType.Regular, hue, 3, "ENU", "", text ) );
}
}
}

View file

@ -0,0 +1,123 @@
using System;
using Server;
using Server.Network;
using Server.Targeting;
namespace Server.Items
{
public interface TranslocationItem
{
int Charges{ get; set; }
int Recharges{ get; set; }
int MaxCharges{ get; }
int MaxRecharges{ get; }
string TranslocationItemName{ get; }
}
public class PowderOfTranslocation : Item
{
[Constructable]
public PowderOfTranslocation() : this( 1 )
{
}
[Constructable]
public PowderOfTranslocation( int amount ) : base( 0x26B8 )
{
Stackable = true;
Weight = 0.1;
Amount = amount;
}
public override void OnDoubleClick( Mobile from )
{
if ( from.InRange( this.GetWorldLocation(), 2 ) )
{
from.Target = new InternalTarget( this );
}
else
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
}
}
private class InternalTarget : Target
{
private PowderOfTranslocation m_Powder;
public InternalTarget( PowderOfTranslocation powder ) : base( -1, false, TargetFlags.None )
{
m_Powder = powder;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Powder.Deleted )
return;
if ( !from.InRange( m_Powder.GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
}
else if ( targeted is TranslocationItem )
{
TranslocationItem transItem = (TranslocationItem)targeted;
if ( transItem.Charges >= transItem.MaxCharges )
{
MessageHelper.SendLocalizedMessageTo( m_Powder, from, 1054137, 0x59 ); // This item cannot absorb any more powder of translocation.
}
else if ( transItem.Recharges >= transItem.MaxRecharges )
{
MessageHelper.SendLocalizedMessageTo( m_Powder, from, 1054138, 0x59 ); // This item has been oversaturated with powder of translocation and can no longer be recharged.
}
else
{
if ( transItem.Charges + m_Powder.Amount > transItem.MaxCharges )
{
int delta = transItem.MaxCharges - transItem.Charges;
m_Powder.Amount -= delta;
transItem.Charges = transItem.MaxCharges;
transItem.Recharges += delta;
}
else
{
transItem.Charges += m_Powder.Amount;
transItem.Recharges += m_Powder.Amount;
m_Powder.Delete();
}
if ( transItem is Item )
{
// The ~1_translocationItem~ glows with green energy and absorbs magical power from the powder.
MessageHelper.SendLocalizedMessageTo( (Item)transItem, from, 1054139, transItem.TranslocationItemName, 0x43 );
}
}
}
else
{
MessageHelper.SendLocalizedMessageTo( m_Powder, from, 1054140, 0x59 ); // Powder of translocation has no effect on this item.
}
}
}
public PowderOfTranslocation( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,42 @@
using System;
using Server;
namespace Server.Items
{
public class ZoogiFungus : Item, ICommodity
{
int ICommodity.DescriptionNumber { get { return LabelNumber; } }
bool ICommodity.IsDeedable { get { return (Core.ML); } }
[Constructable]
public ZoogiFungus() : this( 1 )
{
}
[Constructable]
public ZoogiFungus( int amount ) : base( 0x26B7 )
{
Stackable = true;
Weight = 0.1;
Amount = amount;
}
public ZoogiFungus( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}