- 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:
eos 2012-05-27 02:21:32 +00:00
parent 99b0ad9de5
commit ece7ad37ac
12 changed files with 316 additions and 131 deletions

View file

@ -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 );
}
}

View 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;
}
}
}

View file

@ -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];