- Corrected the Sanctuary dungeon region bounds in Trammel.
- Added the [Message command to send players a page reply style message. - Added a more robust version of the [DesignInsert command, supporting the [Area modifier and conditionals, and only allowing insertion of Static items unless otherwise specified (using [DesignInsert true). Items can also be inserted into multiple house plots at the same time. - Added the ObjectTypes check to the [Serial command implementor, fixing potential server crashes on invalid casts. - Grammar fixes for page gump replies. - Removed the runebook use delay for Core.SA. - Ridgeback, SavageRidgeback and ScaledSwampDragon now override bonding requirements. - Added a PlayerMobile type check to BaseVendor.OnDragDrop to prevent invalid casts. - Players can now return filled bulk orders without having any points in the bulk order crafting skill. - Added ArcaneFocus constructor overloads to make it addable in game.
This commit is contained in:
parent
99b0ad9de5
commit
ece7ad37ac
12 changed files with 316 additions and 131 deletions
|
|
@ -5,6 +5,7 @@ using System.Net;
|
|||
using System.Net.Sockets;
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
using Server.Engines.Help;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
|
@ -44,7 +45,8 @@ namespace Server.Commands.Generic
|
|||
Register( new DismountCommand() );
|
||||
Register( new AddCommand() );
|
||||
Register( new AddToPackCommand() );
|
||||
Register( new TellCommand() );
|
||||
Register( new TellCommand( true ) );
|
||||
Register( new TellCommand( false ) );
|
||||
Register( new PrivSoundCommand() );
|
||||
Register( new IncreaseCommand() );
|
||||
Register( new OpenBrowserCommand() );
|
||||
|
|
@ -350,14 +352,28 @@ namespace Server.Commands.Generic
|
|||
|
||||
public class TellCommand : BaseCommand
|
||||
{
|
||||
public TellCommand()
|
||||
private bool m_InGump;
|
||||
|
||||
public TellCommand( bool inGump )
|
||||
{
|
||||
m_InGump = inGump;
|
||||
|
||||
AccessLevel = AccessLevel.Counselor;
|
||||
Supports = CommandSupport.AllMobiles;
|
||||
Commands = new string[]{ "Tell" };
|
||||
ObjectTypes = ObjectTypes.Mobiles;
|
||||
Usage = "Tell \"text\"";
|
||||
Description = "Sends a system message to a targeted player.";
|
||||
|
||||
if ( inGump )
|
||||
{
|
||||
Commands = new string[]{ "Message", "Msg" };
|
||||
Usage = "Message \"text\"";
|
||||
Description = "Sends a message to a targeted player.";
|
||||
}
|
||||
else
|
||||
{
|
||||
Commands = new string[]{ "Tell" };
|
||||
Usage = "Tell \"text\"";
|
||||
Description = "Sends a system message to a targeted player.";
|
||||
}
|
||||
}
|
||||
|
||||
public override void Execute( CommandEventArgs e, object obj )
|
||||
|
|
@ -365,9 +381,12 @@ namespace Server.Commands.Generic
|
|||
Mobile mob = (Mobile)obj;
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
CommandLogging.WriteLine( from, "{0} {1} telling {2} \"{3}\"", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( mob ), e.ArgString );
|
||||
CommandLogging.WriteLine( from, "{0} {1} {2} {3} \"{4}\"", from.AccessLevel, CommandLogging.Format( from ), m_InGump ? "messaging" : "telling", CommandLogging.Format( mob ), e.ArgString );
|
||||
|
||||
mob.SendMessage( e.ArgString );
|
||||
if ( m_InGump )
|
||||
mob.SendGump( new MessageSentGump( mob, from.Name, e.ArgString ) );
|
||||
else
|
||||
mob.SendMessage( e.ArgString );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
205
Scripts/Commands/Generic/Commands/DesignInsert.cs
Normal file
205
Scripts/Commands/Generic/Commands/DesignInsert.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Multis;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Commands.Generic
|
||||
{
|
||||
public class DesignInsertCommand : BaseCommand
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
TargetCommands.Register( new DesignInsertCommand() );
|
||||
}
|
||||
|
||||
public DesignInsertCommand()
|
||||
{
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Supports = CommandSupport.Single | CommandSupport.Area;
|
||||
Commands = new string[] { "DesignInsert" };
|
||||
ObjectTypes = ObjectTypes.Items;
|
||||
Usage = "DesignInsert [allItems=false]";
|
||||
Description = "Inserts multiple targeted items into a customizable house's design.";
|
||||
}
|
||||
|
||||
#region Single targeting mode
|
||||
public override void Execute( CommandEventArgs e, object obj )
|
||||
{
|
||||
Target t = new DesignInsertTarget( new List<HouseFoundation>(), ( e.Length < 1 || !e.GetBoolean( 0 ) ) );
|
||||
t.Invoke( e.Mobile, obj );
|
||||
}
|
||||
|
||||
private class DesignInsertTarget : Target
|
||||
{
|
||||
private List<HouseFoundation> m_Foundations;
|
||||
private bool m_StaticsOnly;
|
||||
|
||||
public DesignInsertTarget( List<HouseFoundation> foundations, bool staticsOnly )
|
||||
: base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_Foundations = foundations;
|
||||
m_StaticsOnly = staticsOnly;
|
||||
}
|
||||
|
||||
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
|
||||
{
|
||||
if ( m_Foundations.Count != 0 )
|
||||
{
|
||||
from.SendMessage( "Your changes have been committed. Updating..." );
|
||||
|
||||
foreach ( HouseFoundation house in m_Foundations )
|
||||
house.Delta( ItemDelta.Update );
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object obj )
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert( obj as Item, m_StaticsOnly, out house );
|
||||
|
||||
switch ( result )
|
||||
{
|
||||
case DesignInsertResult.Valid:
|
||||
{
|
||||
if ( m_Foundations.Count == 0 )
|
||||
from.SendMessage( "The item has been inserted into the house design. Press ESC when you are finished." );
|
||||
else
|
||||
from.SendMessage( "The item has been inserted into the house design." );
|
||||
|
||||
if ( !m_Foundations.Contains( house ) )
|
||||
m_Foundations.Add( house );
|
||||
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.InvalidItem:
|
||||
{
|
||||
from.SendMessage( "That cannot be inserted. Try again." );
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.NotInHouse:
|
||||
case DesignInsertResult.OutsideHouseBounds:
|
||||
{
|
||||
from.SendMessage( "That item is not inside a customizable house. Try again." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
from.Target = new DesignInsertTarget( m_Foundations, m_StaticsOnly );
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Area targeting mode
|
||||
public override void ExecuteList( CommandEventArgs e, ArrayList list )
|
||||
{
|
||||
e.Mobile.SendGump( new WarningGump( 1060637, 30720, String.Format( "You are about to insert {0} objects. This cannot be undone without a full server revert.<br><br>Continue?", list.Count ), 0xFFC000, 420, 280, new WarningGumpCallback( OnConfirmCallback ), new object[] { e, list, ( e.Length < 1 || !e.GetBoolean( 0 ) ) } ) );
|
||||
AddResponse( "Awaiting confirmation..." );
|
||||
}
|
||||
|
||||
private void OnConfirmCallback( Mobile from, bool okay, object state )
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
CommandEventArgs e = (CommandEventArgs)states[0];
|
||||
ArrayList list = (ArrayList)states[1];
|
||||
bool staticsOnly = (bool)states[2];
|
||||
|
||||
bool flushToLog = false;
|
||||
|
||||
if ( okay )
|
||||
{
|
||||
List<HouseFoundation> foundations = new List<HouseFoundation>();
|
||||
flushToLog = ( list.Count > 20 );
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
HouseFoundation house;
|
||||
DesignInsertResult result = ProcessInsert( list[i] as Item, staticsOnly, out house );
|
||||
|
||||
switch ( result )
|
||||
{
|
||||
case DesignInsertResult.Valid:
|
||||
{
|
||||
AddResponse( "The item has been inserted into the house design." );
|
||||
|
||||
if ( !foundations.Contains( house ) )
|
||||
foundations.Add( house );
|
||||
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.InvalidItem:
|
||||
{
|
||||
LogFailure( "That cannot be inserted." );
|
||||
break;
|
||||
}
|
||||
case DesignInsertResult.NotInHouse:
|
||||
case DesignInsertResult.OutsideHouseBounds:
|
||||
{
|
||||
LogFailure( "That item is not inside a customizable house." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( HouseFoundation house in foundations )
|
||||
house.Delta( ItemDelta.Update );
|
||||
}
|
||||
else
|
||||
{
|
||||
AddResponse( "Command aborted." );
|
||||
}
|
||||
|
||||
Flush( from, flushToLog );
|
||||
}
|
||||
#endregion
|
||||
|
||||
public enum DesignInsertResult
|
||||
{
|
||||
Valid,
|
||||
InvalidItem,
|
||||
NotInHouse,
|
||||
OutsideHouseBounds
|
||||
}
|
||||
|
||||
public static DesignInsertResult ProcessInsert( Item item, bool staticsOnly, out HouseFoundation house )
|
||||
{
|
||||
house = null;
|
||||
|
||||
if ( item == null || item is BaseMulti || item is HouseSign || ( staticsOnly && !( item is Static ) ) )
|
||||
return DesignInsertResult.InvalidItem;
|
||||
|
||||
house = BaseHouse.FindHouseAt( item ) as HouseFoundation;
|
||||
|
||||
if ( house == null )
|
||||
return DesignInsertResult.NotInHouse;
|
||||
|
||||
int x = item.X - house.X;
|
||||
int y = item.Y - house.Y;
|
||||
int z = item.Z - house.Z;
|
||||
|
||||
if ( !TryInsertIntoState( house.CurrentState, item.ItemID, x, y, z ) )
|
||||
return DesignInsertResult.OutsideHouseBounds;
|
||||
|
||||
TryInsertIntoState( house.DesignState, item.ItemID, x, y, z );
|
||||
item.Delete();
|
||||
|
||||
return DesignInsertResult.Valid;
|
||||
}
|
||||
|
||||
private static bool TryInsertIntoState( DesignState state, int itemID, int x, int y, int z )
|
||||
{
|
||||
MultiComponentList mcl = state.Components;
|
||||
|
||||
if ( x < mcl.Min.X || y < mcl.Min.Y || x > mcl.Max.X || y > mcl.Max.Y )
|
||||
return false;
|
||||
|
||||
mcl.Add( itemID, x, y, z );
|
||||
state.OnRevised();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -48,6 +48,40 @@ namespace Server.Commands.Generic
|
|||
}
|
||||
else
|
||||
{
|
||||
switch ( command.ObjectTypes )
|
||||
{
|
||||
case ObjectTypes.Both:
|
||||
{
|
||||
if ( !(obj is Item) && !(obj is Mobile) )
|
||||
{
|
||||
e.Mobile.SendMessage( "This command does not work on that." );
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Items:
|
||||
{
|
||||
if ( !(obj is Item) )
|
||||
{
|
||||
e.Mobile.SendMessage( "This command only works on items." );
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ObjectTypes.Mobiles:
|
||||
{
|
||||
if ( !(obj is Mobile) )
|
||||
{
|
||||
e.Mobile.SendMessage( "This command only works on mobiles." );
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string[] oldArgs = e.Arguments;
|
||||
string[] args = new string[oldArgs.Length - 2];
|
||||
|
||||
|
|
|
|||
|
|
@ -637,7 +637,7 @@ namespace Server.Engines.Help
|
|||
m_Entry.AddResponse( state.Mobile, "[Go Sender]" );
|
||||
m.MoveToWorld( m_Entry.Sender.Location, m_Entry.Sender.Map );
|
||||
|
||||
m.SendMessage( "You have been teleported to that pages sender." );
|
||||
m.SendMessage( "You have been teleported to that page's sender." );
|
||||
|
||||
Resend( state );
|
||||
}
|
||||
|
|
@ -664,7 +664,7 @@ namespace Server.Engines.Help
|
|||
m_Entry.AddResponse( state.Mobile, "[Go Handler]" );
|
||||
m.MoveToWorld( h.Location, h.Map );
|
||||
|
||||
m.SendMessage( "You have been teleported to that pages handler." );
|
||||
m.SendMessage( "You have been teleported to that page's handler." );
|
||||
Resend( state );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ namespace Server.Items
|
|||
return;
|
||||
}
|
||||
|
||||
if ( DateTime.Now < NextUse )
|
||||
if ( DateTime.Now < m_NextUse )
|
||||
{
|
||||
from.SendLocalizedMessage( 502406 ); // This book needs time to recharge.
|
||||
return;
|
||||
|
|
@ -352,7 +352,8 @@ namespace Server.Items
|
|||
|
||||
public virtual void OnTravel()
|
||||
{
|
||||
NextUse = DateTime.Now + UseDelay;
|
||||
if ( !Core.SA )
|
||||
m_NextUse = DateTime.Now + UseDelay;
|
||||
}
|
||||
|
||||
public override void OnAfterDuped( Item newItem )
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ namespace Server.Mobiles
|
|||
MinTameSkill = 83.1;
|
||||
}
|
||||
|
||||
public override bool OverrideBondingReqs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override double GetControlChance( Mobile m, bool useBaseSkill )
|
||||
{
|
||||
return 1.0;
|
||||
|
|
|
|||
|
|
@ -45,6 +45,11 @@ namespace Server.Mobiles
|
|||
MinTameSkill = 83.1;
|
||||
}
|
||||
|
||||
public override bool OverrideBondingReqs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override double GetControlChance( Mobile m, bool useBaseSkill )
|
||||
{
|
||||
return 1.0;
|
||||
|
|
|
|||
|
|
@ -44,6 +44,11 @@ namespace Server.Mobiles
|
|||
MinTameSkill = 93.9;
|
||||
}
|
||||
|
||||
public override bool OverrideBondingReqs()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override double GetControlChance( Mobile m, bool useBaseSkill )
|
||||
{
|
||||
return 1.0;
|
||||
|
|
|
|||
|
|
@ -752,16 +752,14 @@ namespace Server.Mobiles
|
|||
|
||||
if ( dropped is SmallBOD || dropped is LargeBOD )
|
||||
{
|
||||
if( Core.ML )
|
||||
{
|
||||
if( ((PlayerMobile)from).NextBODTurnInTime > DateTime.Now )
|
||||
{
|
||||
SayTo( from, 1079976 ); //
|
||||
return false;
|
||||
}
|
||||
}
|
||||
PlayerMobile pm = from as PlayerMobile;
|
||||
|
||||
if ( !IsValidBulkOrder( dropped ) || !SupportsBulkOrders( from ) )
|
||||
if ( Core.ML && pm != null && pm.NextBODTurnInTime > DateTime.Now )
|
||||
{
|
||||
SayTo( from, 1079976 ); // You'll have to wait a few seconds while I inspect the last order.
|
||||
return false;
|
||||
}
|
||||
else if ( !IsValidBulkOrder( dropped ) )
|
||||
{
|
||||
SayTo( from, 1045130 ); // That order is for some other shopkeeper.
|
||||
return false;
|
||||
|
|
@ -796,10 +794,8 @@ namespace Server.Mobiles
|
|||
|
||||
OnSuccessfulBulkOrderReceive( from );
|
||||
|
||||
if( Core.ML )
|
||||
{
|
||||
((PlayerMobile)from).NextBODTurnInTime = DateTime.Now + TimeSpan.FromSeconds( 10.0 );
|
||||
}
|
||||
if ( Core.ML && pm != null )
|
||||
pm.NextBODTurnInTime = DateTime.Now + TimeSpan.FromSeconds( 10.0 );
|
||||
|
||||
dropped.Delete();
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -792,8 +792,6 @@ namespace Server.Multis
|
|||
|
||||
PacketHandlers.RegisterEncoded( 0x1A, true, new OnEncodedPacketReceive( Designer_Revert ) );
|
||||
|
||||
CommandSystem.Register( "DesignInsert", AccessLevel.GameMaster, new CommandEventHandler( DesignInsert_OnCommand ) );
|
||||
|
||||
EventSink.Speech += new SpeechEventHandler( EventSink_Speech );
|
||||
}
|
||||
|
||||
|
|
@ -1413,101 +1411,6 @@ namespace Server.Multis
|
|||
}
|
||||
}
|
||||
|
||||
[Usage( "DesignInsert" )]
|
||||
[Description( "Inserts multiple targeted items into a customizable houses design." )]
|
||||
public static void DesignInsert_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
e.Mobile.Target = new DesignInsertTarget( null );
|
||||
e.Mobile.SendMessage( "Target an item to insert it into the house design." );
|
||||
}
|
||||
|
||||
private class DesignInsertTarget : Target
|
||||
{
|
||||
private HouseFoundation m_Foundation;
|
||||
|
||||
public DesignInsertTarget( HouseFoundation foundation )
|
||||
: base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_Foundation = foundation;
|
||||
}
|
||||
|
||||
protected override void OnTargetCancel( Mobile from, TargetCancelType cancelType )
|
||||
{
|
||||
if( m_Foundation != null )
|
||||
{
|
||||
from.SendMessage( "Your changes have been committed. Updating..." );
|
||||
|
||||
m_Foundation.Delta( ItemDelta.Update );
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object obj )
|
||||
{
|
||||
Item item = obj as Item;
|
||||
|
||||
if( item == null )
|
||||
{
|
||||
from.Target = new DesignInsertTarget( m_Foundation );
|
||||
from.SendMessage( "That is not an item. Try again." );
|
||||
}
|
||||
else
|
||||
{
|
||||
HouseFoundation house = BaseHouse.FindHouseAt( item ) as HouseFoundation;
|
||||
|
||||
if( house == null )
|
||||
{
|
||||
from.Target = new DesignInsertTarget( m_Foundation );
|
||||
from.SendMessage( "That item is not inside a customizable house. Try again." );
|
||||
}
|
||||
else if( m_Foundation != null && house != m_Foundation )
|
||||
{
|
||||
from.Target = new DesignInsertTarget( m_Foundation );
|
||||
from.SendMessage( "That item is not inside the current house; all targeted items must reside in the same house. You may cancel this target and repeat the command." );
|
||||
}
|
||||
else
|
||||
{
|
||||
DesignState state = house.CurrentState;
|
||||
MultiComponentList mcl = state.Components;
|
||||
|
||||
int x = item.X - house.X;
|
||||
int y = item.Y - house.Y;
|
||||
int z = item.Z - house.Z;
|
||||
|
||||
if( x >= mcl.Min.X && y >= mcl.Min.Y && x <= mcl.Max.X && y <= mcl.Max.Y )
|
||||
{
|
||||
mcl.Add( item.ItemID, x, y, z );
|
||||
item.Delete();
|
||||
|
||||
state.OnRevised();
|
||||
|
||||
state = house.DesignState;
|
||||
mcl = state.Components;
|
||||
|
||||
if( x >= mcl.Min.X && y >= mcl.Min.Y && x <= mcl.Max.X && y <= mcl.Max.Y )
|
||||
{
|
||||
mcl.Add( item.ItemID, x, y, z );
|
||||
state.OnRevised();
|
||||
}
|
||||
|
||||
from.Target = new DesignInsertTarget( house );
|
||||
|
||||
if( m_Foundation == null )
|
||||
from.SendMessage( "The item has been inserted into the house design. Press ESC when you are finished." );
|
||||
else
|
||||
from.SendMessage( "The item has been inserted into the house design." );
|
||||
|
||||
m_Foundation = house;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.Target = new DesignInsertTarget( m_Foundation );
|
||||
from.SendMessage( "That item is not inside a customizable house. Try again." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void TraceValidity( NetState state, int itemID )
|
||||
{
|
||||
try
|
||||
|
|
@ -1572,7 +1475,7 @@ namespace Server.Multis
|
|||
/* Client closed his house design window
|
||||
* - Remove design context
|
||||
* - Notify the client that customization has ended
|
||||
* - Refresh client with current visable design state
|
||||
* - Refresh client with current visible design state
|
||||
* - If a signpost is needed, add it
|
||||
* - Eject all from house
|
||||
* - Restore relocated entities
|
||||
|
|
|
|||
|
|
@ -16,6 +16,18 @@ namespace Server.Items
|
|||
set { m_StrengthBonus = value; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ArcaneFocus()
|
||||
: this( TimeSpan.FromHours( 1 ), 1 )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ArcaneFocus( int lifeSpan, int strengthBonus )
|
||||
: this( TimeSpan.FromSeconds( lifeSpan ), strengthBonus )
|
||||
{
|
||||
}
|
||||
|
||||
public ArcaneFocus( TimeSpan lifeSpan, int strengthBonus ) : base( 0x3155, lifeSpan )
|
||||
{
|
||||
LootType = LootType.Blessed;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue