#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.
This commit is contained in:
parent
b51c58f514
commit
3045c83799
3512 changed files with 627673 additions and 0 deletions
1226
Scripts/Misc/AOS.cs
Normal file
1226
Scripts/Misc/AOS.cs
Normal file
File diff suppressed because it is too large
Load diff
40
Scripts/Misc/AccountPrompt.cs
Normal file
40
Scripts/Misc/AccountPrompt.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class AccountPrompt
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( Accounts.Count == 0 && !Core.Service )
|
||||
{
|
||||
Console.WriteLine( "This server has no accounts." );
|
||||
Console.Write( "Do you want to create the owner account now? (y/n)" );
|
||||
|
||||
if( Console.ReadKey( true ).Key == ConsoleKey.Y )
|
||||
{
|
||||
Console.WriteLine();
|
||||
|
||||
Console.Write( "Username: " );
|
||||
string username = Console.ReadLine();
|
||||
|
||||
Console.Write( "Password: " );
|
||||
string password = Console.ReadLine();
|
||||
|
||||
Account a = new Account( username, password );
|
||||
a.AccessLevel = AccessLevel.Owner;
|
||||
|
||||
Console.WriteLine( "Account created." );
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine();
|
||||
|
||||
Console.WriteLine( "Account not created." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Scripts/Misc/Animations.cs
Normal file
30
Scripts/Misc/Animations.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Animations
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.AnimateRequest += new AnimateRequestEventHandler( EventSink_AnimateRequest );
|
||||
}
|
||||
|
||||
private static void EventSink_AnimateRequest( AnimateRequestEventArgs e )
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
int action;
|
||||
|
||||
switch ( e.Action )
|
||||
{
|
||||
case "bow": action = 32; break;
|
||||
case "salute": action = 33; break;
|
||||
default: return;
|
||||
}
|
||||
|
||||
if ( from.Alive && !from.Mounted && from.Body.IsHuman )
|
||||
from.Animate( action, 5, 1, true, false, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
195
Scripts/Misc/Assistants.cs
Normal file
195
Scripts/Misc/Assistants.cs
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public static partial class Assistants
|
||||
{
|
||||
private static class Settings
|
||||
{
|
||||
public const bool Enabled = false;
|
||||
public const bool KickOnFailure = true; // It will also kick clients running without assistants
|
||||
|
||||
public static readonly TimeSpan HandshakeTimeout = TimeSpan.FromSeconds(30.0);
|
||||
public static readonly TimeSpan DisconnectDelay = TimeSpan.FromSeconds(15.0);
|
||||
|
||||
public const string WarningMessage = "The server was unable to negotiate features with your assistant. "
|
||||
+ "You must download and run an updated version of <A HREF=\"http://uosteam.com\">UOSteam</A>"
|
||||
+ " or <A HREF=\"https://bitbucket.org/msturgill/razor-releases/downloads\">Razor</A>."
|
||||
+ "<BR><BR>Make sure you've checked the option <B>Negotiate features with server</B>, "
|
||||
+ "once you have this box checked you may log in and play normally."
|
||||
+ "<BR><BR>You will be disconnected shortly.";
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
//DisallowFeature( Features.FilterWeather );
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum Features : ulong
|
||||
{
|
||||
None = 0,
|
||||
|
||||
FilterWeather = 1 << 0, // Weather Filter
|
||||
FilterLight = 1 << 1, // Light Filter
|
||||
SmartTarget = 1 << 2, // Smart Last Target
|
||||
RangedTarget = 1 << 3, // Range Check Last Target
|
||||
AutoOpenDoors = 1 << 4, // Automatically Open Doors
|
||||
DequipOnCast = 1 << 5, // Unequip Weapon on spell cast
|
||||
AutoPotionEquip = 1 << 6, // Un/re-equip weapon on potion use
|
||||
PoisonedChecks = 1 << 7, // Block heal If poisoned/Macro If Poisoned condition/Heal or Cure self
|
||||
LoopedMacros = 1 << 8, // Disallow looping or recursive macros
|
||||
UseOnceAgent = 1 << 9, // The use once agent
|
||||
RestockAgent = 1 << 10, // The restock agent
|
||||
SellAgent = 1 << 11, // The sell agent
|
||||
BuyAgent = 1 << 12, // The buy agent
|
||||
PotionHotkeys = 1 << 13, // All potion hotkeys
|
||||
RandomTargets = 1 << 14, // All random target hotkeys (not target next, last target, target self)
|
||||
ClosestTargets = 1 << 15, // All closest target hotkeys
|
||||
OverheadHealth = 1 << 16, // Health and Mana/Stam messages shown over player's heads
|
||||
AutolootAgent = 1 << 17, // The autoloot agent
|
||||
BoneCutterAgent = 1 << 18, // The bone cutter agent
|
||||
AdvancedMacros = 1 << 19, // Advanced macro engine
|
||||
AutoRemount = 1 << 20, // Auto remount after dismount
|
||||
AutoBandage = 1 << 21, // Auto bandage friends, self, last and mount option
|
||||
EnemyTargetShare = 1 << 22, // Enemy target share on guild, party or alliance chat
|
||||
FilterSeason = 1 << 23, // Season Filter
|
||||
SpellTargetShare = 1 << 24, // Spell target share on guild, party or alliance chat
|
||||
|
||||
All = ulong.MaxValue
|
||||
}
|
||||
|
||||
private static Features m_DisallowedFeatures = Features.None;
|
||||
|
||||
public static void DisallowFeature(Features feature)
|
||||
{
|
||||
SetDisallowed(feature, true);
|
||||
}
|
||||
|
||||
public static void AllowFeature(Features feature)
|
||||
{
|
||||
SetDisallowed(feature, false);
|
||||
}
|
||||
|
||||
public static void SetDisallowed(Features feature, bool value)
|
||||
{
|
||||
if (value)
|
||||
m_DisallowedFeatures |= feature;
|
||||
else
|
||||
m_DisallowedFeatures &= ~feature;
|
||||
}
|
||||
|
||||
public static Features DisallowedFeatures { get { return m_DisallowedFeatures; } }
|
||||
}
|
||||
|
||||
private static class Negotiator
|
||||
{
|
||||
private static Dictionary<Mobile, Timer> m_Dictionary = new Dictionary<Mobile, Timer>();
|
||||
|
||||
private static TimerStateCallback OnHandshakeTimeout_Callback = new TimerStateCallback(OnHandshakeTimeout);
|
||||
private static TimerStateCallback OnForceDisconnect_Callback = new TimerStateCallback(OnForceDisconnect);
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (Settings.Enabled)
|
||||
{
|
||||
EventSink.Login += new LoginEventHandler(EventSink_Login);
|
||||
ProtocolExtensions.Register(0xFF, true, new OnPacketReceive(OnHandshakeResponse));
|
||||
}
|
||||
}
|
||||
|
||||
private static void EventSink_Login(LoginEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
if (m != null && m.NetState != null && m.NetState.Running)
|
||||
{
|
||||
Timer t;
|
||||
m.Send(new BeginHandshake());
|
||||
|
||||
if (Settings.KickOnFailure)
|
||||
m.Send(new BeginHandshake());
|
||||
|
||||
if (m_Dictionary.TryGetValue(m, out t) && t != null)
|
||||
t.Stop();
|
||||
|
||||
m_Dictionary[m] = t = Timer.DelayCall(Settings.HandshakeTimeout, OnHandshakeTimeout_Callback, m);
|
||||
t.Start();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnHandshakeResponse(NetState state, PacketReader pvSrc)
|
||||
{
|
||||
pvSrc.Trace(state);
|
||||
|
||||
if (state == null || state.Mobile == null || !state.Running)
|
||||
return;
|
||||
|
||||
Timer t;
|
||||
Mobile m = state.Mobile;
|
||||
|
||||
if (m_Dictionary.TryGetValue(m, out t))
|
||||
{
|
||||
if (t != null)
|
||||
t.Stop();
|
||||
|
||||
m_Dictionary.Remove(m);
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnHandshakeTimeout(object state)
|
||||
{
|
||||
Timer t = null;
|
||||
Mobile m = state as Mobile;
|
||||
|
||||
if (m == null)
|
||||
return;
|
||||
|
||||
m_Dictionary.Remove(m);
|
||||
|
||||
if (!Settings.KickOnFailure)
|
||||
{
|
||||
Console.WriteLine("Player '{0}' failed to negotiate features.", m);
|
||||
}
|
||||
else if (m.NetState != null && m.NetState.Running)
|
||||
{
|
||||
m.SendGump(new Gumps.WarningGump(1060635, 30720, Settings.WarningMessage, 0xFFC000, 420, 250, null, null));
|
||||
|
||||
if (m.AccessLevel <= AccessLevel.Player)
|
||||
{
|
||||
m_Dictionary[m] = t = Timer.DelayCall(Settings.DisconnectDelay, OnForceDisconnect_Callback, m);
|
||||
t.Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnForceDisconnect(object state)
|
||||
{
|
||||
if (state is Mobile)
|
||||
{
|
||||
Mobile m = (Mobile)state;
|
||||
|
||||
if (m.NetState != null && m.NetState.Running)
|
||||
m.NetState.Dispose();
|
||||
|
||||
m_Dictionary.Remove(m);
|
||||
|
||||
Console.WriteLine("Player {0} kicked (Failed assistant handshake)", m);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class BeginHandshake : ProtocolExtension
|
||||
{
|
||||
public BeginHandshake()
|
||||
: base(0xFE, 8)
|
||||
{
|
||||
m_Stream.Write((uint)((ulong)Settings.DisallowedFeatures >> 32));
|
||||
m_Stream.Write((uint)((ulong)Settings.DisallowedFeatures & 0xFFFFFFFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
62
Scripts/Misc/AttackMessage.cs
Normal file
62
Scripts/Misc/AttackMessage.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class AttackMessage
|
||||
{
|
||||
private const string AggressorFormat = "You are attacking {0}!";
|
||||
private const string AggressedFormat = "{0} is attacking you!";
|
||||
private const int Hue = 0x22;
|
||||
|
||||
private static TimeSpan Delay = TimeSpan.FromMinutes( 1.0 );
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.AggressiveAction += new AggressiveActionEventHandler( EventSink_AggressiveAction );
|
||||
}
|
||||
|
||||
public static void EventSink_AggressiveAction( AggressiveActionEventArgs e )
|
||||
{
|
||||
Mobile aggressor = e.Aggressor;
|
||||
Mobile aggressed = e.Aggressed;
|
||||
|
||||
if ( !aggressor.Player || !aggressed.Player )
|
||||
return;
|
||||
|
||||
if ( !CheckAggressions( aggressor, aggressed ) )
|
||||
{
|
||||
aggressor.LocalOverheadMessage( MessageType.Regular, Hue, true, String.Format( AggressorFormat, aggressed.Name ) );
|
||||
aggressed.LocalOverheadMessage( MessageType.Regular, Hue, true, String.Format( AggressedFormat, aggressor.Name ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckAggressions( Mobile m1, Mobile m2 )
|
||||
{
|
||||
List<AggressorInfo> list = m1.Aggressors;
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
AggressorInfo info = list[i];
|
||||
|
||||
if ( info.Attacker == m2 && DateTime.UtcNow < (info.LastCombatTime + Delay) )
|
||||
return true;
|
||||
}
|
||||
|
||||
list = m2.Aggressors;
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
AggressorInfo info = list[i];
|
||||
|
||||
if ( info.Attacker == m1 && DateTime.UtcNow < (info.LastCombatTime + Delay) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Scripts/Misc/AutoRestart.cs
Normal file
88
Scripts/Misc/AutoRestart.cs
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class AutoRestart : Timer
|
||||
{
|
||||
public static bool Enabled = false; // is the script enabled?
|
||||
|
||||
private static TimeSpan RestartTime = TimeSpan.FromHours( 2.0 ); // time of day at which to restart
|
||||
private static TimeSpan RestartDelay = TimeSpan.Zero; // how long the server should remain active before restart (period of 'server wars')
|
||||
|
||||
private static TimeSpan WarningDelay = TimeSpan.FromMinutes( 1.0 ); // at what interval should the shutdown message be displayed?
|
||||
|
||||
private static bool m_Restarting;
|
||||
private static DateTime m_RestartTime;
|
||||
|
||||
public static bool Restarting
|
||||
{
|
||||
get{ return m_Restarting; }
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "Restart", AccessLevel.Administrator, new CommandEventHandler( Restart_OnCommand ) );
|
||||
new AutoRestart().Start();
|
||||
}
|
||||
|
||||
public static void Restart_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
if ( m_Restarting )
|
||||
{
|
||||
e.Mobile.SendMessage( "The server is already restarting." );
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage( "You have initiated server shutdown." );
|
||||
Enabled = true;
|
||||
m_RestartTime = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
public AutoRestart() : base( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 1.0 ) )
|
||||
{
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
|
||||
m_RestartTime = DateTime.UtcNow.Date + RestartTime;
|
||||
|
||||
if ( m_RestartTime < DateTime.UtcNow )
|
||||
m_RestartTime += TimeSpan.FromDays( 1.0 );
|
||||
}
|
||||
|
||||
private void Warning_Callback()
|
||||
{
|
||||
World.Broadcast( 0x22, true, "The server is going down shortly." );
|
||||
}
|
||||
|
||||
private void Restart_Callback()
|
||||
{
|
||||
Core.Kill( true );
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( m_Restarting || !Enabled )
|
||||
return;
|
||||
|
||||
if ( DateTime.UtcNow < m_RestartTime )
|
||||
return;
|
||||
|
||||
if ( WarningDelay > TimeSpan.Zero )
|
||||
{
|
||||
Warning_Callback();
|
||||
Timer.DelayCall( WarningDelay, WarningDelay, new TimerCallback( Warning_Callback ) );
|
||||
}
|
||||
|
||||
AutoSave.Save();
|
||||
|
||||
m_Restarting = true;
|
||||
|
||||
Timer.DelayCall( RestartDelay, new TimerCallback( Restart_Callback ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
188
Scripts/Misc/AutoSave.cs
Normal file
188
Scripts/Misc/AutoSave.cs
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class AutoSave : Timer
|
||||
{
|
||||
private static TimeSpan m_Delay = TimeSpan.FromMinutes( ValidSettings.ServerSaveMinutes() );
|
||||
//private static TimeSpan m_Warning = TimeSpan.Zero;
|
||||
private static TimeSpan m_Warning = TimeSpan.FromSeconds( Settings.S_ServerSaveWarningSeconds );
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
new AutoSave().Start();
|
||||
CommandSystem.Register( "SetSaves", AccessLevel.Administrator, new CommandEventHandler( SetSaves_OnCommand ) );
|
||||
}
|
||||
|
||||
private static bool m_SavesEnabled = true;
|
||||
|
||||
public static bool SavesEnabled
|
||||
{
|
||||
get{ return m_SavesEnabled; }
|
||||
set{ m_SavesEnabled = value; }
|
||||
}
|
||||
|
||||
[Usage( "SetSaves <true | false>" )]
|
||||
[Description( "Enables or disables automatic shard saving." )]
|
||||
public static void SetSaves_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
if ( e.Length == 1 )
|
||||
{
|
||||
m_SavesEnabled = e.GetBoolean( 0 );
|
||||
e.Mobile.SendMessage( "Saves have been {0}.", m_SavesEnabled ? "enabled" : "disabled" );
|
||||
}
|
||||
else
|
||||
{
|
||||
e.Mobile.SendMessage( "Format: SetSaves <true | false>" );
|
||||
}
|
||||
}
|
||||
|
||||
public AutoSave() : base( m_Delay - m_Warning, m_Delay )
|
||||
{
|
||||
Priority = TimerPriority.OneMinute;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( !m_SavesEnabled || AutoRestart.Restarting )
|
||||
return;
|
||||
|
||||
if ( m_Warning == TimeSpan.Zero )
|
||||
{
|
||||
Save( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
int s = (int)m_Warning.TotalSeconds;
|
||||
int m = s / 60;
|
||||
s %= 60;
|
||||
|
||||
if ( m > 0 && s > 0 )
|
||||
World.Broadcast( 0x35, true, "The world will save in {0} minute{1} and {2} second{3}.", m, m != 1 ? "s" : "", s, s != 1 ? "s" : "" );
|
||||
else if ( m > 0 )
|
||||
World.Broadcast( 0x35, true, "The world will save in {0} minute{1}.", m, m != 1 ? "s" : "" );
|
||||
else
|
||||
World.Broadcast( 0x35, true, "The world will save in {0} second{1}.", s, s != 1 ? "s" : "" );
|
||||
|
||||
Timer.DelayCall( m_Warning, new TimerCallback( Save ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save()
|
||||
{
|
||||
AutoSave.Save( false );
|
||||
}
|
||||
|
||||
public static void Save( bool permitBackgroundWrite )
|
||||
{
|
||||
if ( AutoRestart.Restarting )
|
||||
return;
|
||||
|
||||
World.WaitForWriteCompletion();
|
||||
|
||||
try{ Backup(); }
|
||||
catch ( Exception e ) { Console.WriteLine("WARNING: Automatic backup FAILED: {0}", e); }
|
||||
|
||||
World.Save( true, permitBackgroundWrite );
|
||||
}
|
||||
|
||||
private static string[] m_Backups = new string[]
|
||||
{
|
||||
"Third Backup",
|
||||
"Second Backup",
|
||||
"Most Recent"
|
||||
};
|
||||
|
||||
private static void Backup()
|
||||
{
|
||||
if ( m_Backups.Length == 0 )
|
||||
return;
|
||||
|
||||
string root = Path.Combine( Core.BaseDirectory, "Backups/Automatic" );
|
||||
|
||||
if ( !Directory.Exists( root ) )
|
||||
Directory.CreateDirectory( root );
|
||||
|
||||
string[] existing = Directory.GetDirectories( root );
|
||||
|
||||
for ( int i = 0; i < m_Backups.Length; ++i )
|
||||
{
|
||||
DirectoryInfo dir = Match( existing, m_Backups[i] );
|
||||
|
||||
if ( dir == null )
|
||||
continue;
|
||||
|
||||
if ( i > 0 )
|
||||
{
|
||||
string timeStamp = FindTimeStamp( dir.Name );
|
||||
|
||||
if ( timeStamp != null )
|
||||
{
|
||||
try{ dir.MoveTo( FormatDirectory( root, m_Backups[i - 1], timeStamp ) ); }
|
||||
catch{}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
try{ dir.Delete( true ); }
|
||||
catch{}
|
||||
}
|
||||
}
|
||||
|
||||
string saves = Path.Combine( Core.BaseDirectory, "Saves" );
|
||||
|
||||
if ( Directory.Exists( saves ) )
|
||||
Directory.Move( saves, FormatDirectory( root, m_Backups[m_Backups.Length - 1], GetTimeStamp() ) );
|
||||
}
|
||||
|
||||
private static DirectoryInfo Match( string[] paths, string match )
|
||||
{
|
||||
for ( int i = 0; i < paths.Length; ++i )
|
||||
{
|
||||
DirectoryInfo info = new DirectoryInfo( paths[i] );
|
||||
|
||||
if ( info.Name.StartsWith( match ) )
|
||||
return info;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string FormatDirectory( string root, string name, string timeStamp )
|
||||
{
|
||||
return Path.Combine( root, String.Format( "{0} ({1})", name, timeStamp ) );
|
||||
}
|
||||
|
||||
private static string FindTimeStamp( string input )
|
||||
{
|
||||
int start = input.IndexOf( '(' );
|
||||
|
||||
if ( start >= 0 )
|
||||
{
|
||||
int end = input.IndexOf( ')', ++start );
|
||||
|
||||
if ( end >= start )
|
||||
return input.Substring( start, end-start );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string GetTimeStamp()
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
|
||||
return String.Format( "{0}-{1}-{2} {3}-{4:D2}-{5:D2}",
|
||||
now.Day,
|
||||
now.Month,
|
||||
now.Year,
|
||||
now.Hour,
|
||||
now.Minute,
|
||||
now.Second
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
47
Scripts/Misc/Broadcasts.cs
Normal file
47
Scripts/Misc/Broadcasts.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Broadcasts
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Crashed += new CrashedEventHandler( EventSink_Crashed );
|
||||
EventSink.Shutdown += new ShutdownEventHandler( EventSink_Shutdown );
|
||||
EventSink.Disconnected += new DisconnectedEventHandler(World_Leave);
|
||||
}
|
||||
|
||||
public static void EventSink_Crashed( CrashedEventArgs e )
|
||||
{
|
||||
try
|
||||
{
|
||||
World.Broadcast( 0x35, true, "The server has crashed." );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void EventSink_Shutdown( ShutdownEventArgs e )
|
||||
{
|
||||
try
|
||||
{
|
||||
World.Broadcast( 0x35, true, "The server has shut down." );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void World_Leave(DisconnectedEventArgs args)
|
||||
{
|
||||
if ( Settings.S_SaveOnCharacterLogout )
|
||||
{
|
||||
World.Save( true, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
308
Scripts/Misc/BuffIcons.cs
Normal file
308
Scripts/Misc/BuffIcons.cs
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class BuffInfo
|
||||
{
|
||||
public static bool Enabled { get { return Core.ML; } }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if( Enabled )
|
||||
{
|
||||
EventSink.ClientVersionReceived += new ClientVersionReceivedHandler( delegate( ClientVersionReceivedArgs args )
|
||||
{
|
||||
PlayerMobile pm = args.State.Mobile as PlayerMobile;
|
||||
|
||||
if( pm != null )
|
||||
Timer.DelayCall( TimeSpan.Zero, pm.ResendBuffs );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
#region Properties
|
||||
private BuffIcon m_ID;
|
||||
public BuffIcon ID { get { return m_ID; } }
|
||||
|
||||
private int m_TitleCliloc;
|
||||
public int TitleCliloc { get { return m_TitleCliloc; } }
|
||||
|
||||
private int m_SecondaryCliloc;
|
||||
public int SecondaryCliloc { get { return m_SecondaryCliloc; } }
|
||||
|
||||
private TimeSpan m_TimeLength;
|
||||
public TimeSpan TimeLength { get { return m_TimeLength; } }
|
||||
|
||||
private DateTime m_TimeStart;
|
||||
public DateTime TimeStart { get { return m_TimeStart; } }
|
||||
|
||||
private Timer m_Timer;
|
||||
public Timer Timer { get { return m_Timer; } }
|
||||
|
||||
private bool m_RetainThroughDeath;
|
||||
public bool RetainThroughDeath { get { return m_RetainThroughDeath; } }
|
||||
|
||||
private TextDefinition m_Args;
|
||||
public TextDefinition Args { get { return m_Args; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1 )
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc )
|
||||
{
|
||||
m_ID = iconID;
|
||||
m_TitleCliloc = titleCliloc;
|
||||
m_SecondaryCliloc = secondaryCliloc;
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1, length, m )
|
||||
{
|
||||
}
|
||||
|
||||
//Only the timed one needs to Mobile to know when to automagically remove it.
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m )
|
||||
: this( iconID, titleCliloc, secondaryCliloc )
|
||||
{
|
||||
m_TimeLength = length;
|
||||
m_TimeStart = DateTime.UtcNow;
|
||||
|
||||
m_Timer = Timer.DelayCall( length, new TimerCallback(
|
||||
delegate
|
||||
{
|
||||
PlayerMobile pm = m as PlayerMobile;
|
||||
|
||||
if( pm == null )
|
||||
return;
|
||||
|
||||
pm.RemoveBuff( this );
|
||||
} ) );
|
||||
}
|
||||
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, TextDefinition args )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1, args )
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args )
|
||||
: this( iconID, titleCliloc, secondaryCliloc )
|
||||
{
|
||||
m_Args = args;
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, bool retainThroughDeath )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1, retainThroughDeath )
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, bool retainThroughDeath )
|
||||
: this( iconID, titleCliloc, secondaryCliloc )
|
||||
{
|
||||
m_RetainThroughDeath = retainThroughDeath;
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, TextDefinition args, bool retainThroughDeath )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1, args, retainThroughDeath )
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, bool retainThroughDeath )
|
||||
: this( iconID, titleCliloc, secondaryCliloc, args )
|
||||
{
|
||||
m_RetainThroughDeath = retainThroughDeath;
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m, TextDefinition args )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1, length, m, args )
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, TextDefinition args )
|
||||
: this( iconID, titleCliloc, secondaryCliloc, length, m )
|
||||
{
|
||||
m_Args = args;
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, TimeSpan length, Mobile m, TextDefinition args, bool retainThroughDeath )
|
||||
: this( iconID, titleCliloc, titleCliloc + 1, length, m, args, retainThroughDeath )
|
||||
{
|
||||
}
|
||||
|
||||
public BuffInfo( BuffIcon iconID, int titleCliloc, int secondaryCliloc, TimeSpan length, Mobile m, TextDefinition args, bool retainThroughDeath )
|
||||
: this( iconID, titleCliloc, secondaryCliloc, length, m )
|
||||
{
|
||||
m_Args = args;
|
||||
m_RetainThroughDeath = retainThroughDeath;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Convenience Methods
|
||||
public static void AddBuff( Mobile m, BuffInfo b )
|
||||
{
|
||||
PlayerMobile pm = m as PlayerMobile;
|
||||
|
||||
if( pm != null )
|
||||
pm.AddBuff( b );
|
||||
}
|
||||
|
||||
public static void RemoveBuff( Mobile m, BuffInfo b )
|
||||
{
|
||||
PlayerMobile pm = m as PlayerMobile;
|
||||
|
||||
if( pm != null )
|
||||
pm.RemoveBuff( b );
|
||||
}
|
||||
|
||||
public static void RemoveBuff( Mobile m, BuffIcon b )
|
||||
{
|
||||
PlayerMobile pm = m as PlayerMobile;
|
||||
|
||||
if( pm != null )
|
||||
pm.RemoveBuff( b );
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public enum BuffIcon : short
|
||||
{
|
||||
DismountPrevention=0x3E9,
|
||||
NoRearm=0x3EA,
|
||||
//Currently, no 0x3EB or 0x3EC
|
||||
NightSight=0x3ED, //*
|
||||
DeathStrike,
|
||||
EvilOmen,
|
||||
UnknownStandingSwirl, //Which is healing throttle & Stamina throttle?
|
||||
UnknownKneelingSword,
|
||||
DivineFury, //*
|
||||
EnemyOfOne, //*
|
||||
HidingAndOrStealth, //*
|
||||
ActiveMeditation, //*
|
||||
BloodOathCaster, //*
|
||||
BloodOathCurse, //*
|
||||
CorpseSkin, //*
|
||||
Mindrot, //*
|
||||
PainSpike, //*
|
||||
Strangle,
|
||||
GiftOfRenewal, //*
|
||||
AttuneWeapon, //*
|
||||
Thunderstorm, //*
|
||||
EssenceOfWind, //*
|
||||
EtherealVoyage, //*
|
||||
GiftOfLife, //*
|
||||
ArcaneEmpowerment, //*
|
||||
MortalStrike,
|
||||
ReactiveArmor, //*
|
||||
Protection, //*
|
||||
ArchProtection,
|
||||
MagicReflection, //*
|
||||
Incognito, //*
|
||||
Disguised,
|
||||
AnimalForm,
|
||||
Polymorph,
|
||||
Invisibility, //*
|
||||
Paralyze, //*
|
||||
Poison,
|
||||
Bleed,
|
||||
Clumsy, //*
|
||||
FeebleMind, //*
|
||||
Weaken, //*
|
||||
Curse, //*
|
||||
MassCurse,
|
||||
Agility, //*
|
||||
Cunning, //*
|
||||
Strength, //*
|
||||
Bless, //*
|
||||
Sleep,
|
||||
StoneForm,
|
||||
SpellPlague,
|
||||
SpellTrigger,
|
||||
NetherBolt,
|
||||
Fly
|
||||
}
|
||||
|
||||
public sealed class AddBuffPacket : Packet
|
||||
{
|
||||
public AddBuffPacket( Mobile m, BuffInfo info )
|
||||
: this( m, info.ID, info.TitleCliloc, info.SecondaryCliloc, info.Args, (info.TimeStart != DateTime.MinValue) ? ((info.TimeStart + info.TimeLength) - DateTime.UtcNow) : TimeSpan.Zero )
|
||||
{
|
||||
}
|
||||
|
||||
public AddBuffPacket( Mobile mob, BuffIcon iconID, int titleCliloc, int secondaryCliloc, TextDefinition args, TimeSpan length )
|
||||
: base( 0xDF )
|
||||
{
|
||||
bool hasArgs = (args != null);
|
||||
|
||||
this.EnsureCapacity( (hasArgs ? (48 + args.ToString().Length * 2): 44) );
|
||||
m_Stream.Write( (int)mob.Serial );
|
||||
|
||||
|
||||
m_Stream.Write( (short)iconID ); //ID
|
||||
m_Stream.Write( (short)0x1 ); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
m_Stream.Fill( 4 );
|
||||
|
||||
m_Stream.Write( (short)iconID ); //ID
|
||||
m_Stream.Write( (short)0x01 ); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
m_Stream.Fill( 4 );
|
||||
|
||||
if( length < TimeSpan.Zero )
|
||||
length = TimeSpan.Zero;
|
||||
|
||||
m_Stream.Write( (short)length.TotalSeconds ); //Time in seconds
|
||||
|
||||
m_Stream.Fill( 3 );
|
||||
m_Stream.Write( (int)titleCliloc );
|
||||
m_Stream.Write( (int)secondaryCliloc );
|
||||
|
||||
if( !hasArgs )
|
||||
{
|
||||
//m_Stream.Fill( 2 );
|
||||
m_Stream.Fill( 10 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Stream.Fill( 4 );
|
||||
m_Stream.Write( (short)0x1 ); //Unknown -> Possibly something saying 'hey, I have more data!'?
|
||||
m_Stream.Fill( 2 );
|
||||
|
||||
//m_Stream.WriteLittleUniNull( "\t#1018280" );
|
||||
m_Stream.WriteLittleUniNull( String.Format( "\t{0}", args.ToString() ) );
|
||||
|
||||
m_Stream.Write( (short)0x1 ); //Even more Unknown -> Possibly something saying 'hey, I have more data!'?
|
||||
m_Stream.Fill( 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class RemoveBuffPacket : Packet
|
||||
{
|
||||
public RemoveBuffPacket( Mobile mob, BuffInfo info )
|
||||
: this( mob, info.ID )
|
||||
{
|
||||
}
|
||||
|
||||
public RemoveBuffPacket( Mobile mob, BuffIcon iconID )
|
||||
: base( 0xDF )
|
||||
{
|
||||
this.EnsureCapacity( 13 );
|
||||
m_Stream.Write( (int)mob.Serial );
|
||||
|
||||
m_Stream.Write( (short)iconID ); //ID
|
||||
m_Stream.Write( (short)0x0 ); //Type 0 for removal. 1 for add 2 for Data
|
||||
|
||||
m_Stream.Fill( 4 );
|
||||
}
|
||||
}
|
||||
}
|
||||
1711
Scripts/Misc/CharacterCreation.cs
Normal file
1711
Scripts/Misc/CharacterCreation.cs
Normal file
File diff suppressed because it is too large
Load diff
170
Scripts/Misc/Cleanup.cs
Normal file
170
Scripts/Misc/Cleanup.cs
Normal file
|
|
@ -0,0 +1,170 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Cleanup
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
Timer.DelayCall( TimeSpan.FromSeconds( 2.5 ), new TimerCallback( Run ) );
|
||||
}
|
||||
|
||||
public static void Run()
|
||||
{
|
||||
List<Item> items = new List<Item>();
|
||||
List<Item> validItems = new List<Item>();
|
||||
List<Mobile> hairCleanup = new List<Mobile>();
|
||||
|
||||
int boxes = 0;
|
||||
|
||||
foreach ( Item item in World.Items.Values )
|
||||
{
|
||||
if ( item.Map == null )
|
||||
{
|
||||
items.Add( item );
|
||||
continue;
|
||||
}
|
||||
else if ( item is CommodityDeed )
|
||||
{
|
||||
CommodityDeed deed = (CommodityDeed)item;
|
||||
|
||||
if ( deed.Commodity != null )
|
||||
validItems.Add( deed.Commodity );
|
||||
|
||||
continue;
|
||||
}
|
||||
else if ( item is BaseHouse )
|
||||
{
|
||||
BaseHouse house = (BaseHouse)item;
|
||||
|
||||
foreach ( RelocatedEntity relEntity in house.RelocatedEntities )
|
||||
{
|
||||
if ( relEntity.Entity is Item )
|
||||
validItems.Add( (Item)relEntity.Entity );
|
||||
}
|
||||
|
||||
foreach ( VendorInventory inventory in house.VendorInventories )
|
||||
{
|
||||
foreach ( Item subItem in inventory.Items )
|
||||
validItems.Add( subItem );
|
||||
}
|
||||
}
|
||||
else if ( item is BankBox )
|
||||
{
|
||||
BankBox box = (BankBox)item;
|
||||
Mobile owner = box.Owner;
|
||||
|
||||
if ( owner == null )
|
||||
{
|
||||
items.Add( box );
|
||||
++boxes;
|
||||
}
|
||||
else if ( box.Items.Count == 0 )
|
||||
{
|
||||
items.Add( box );
|
||||
++boxes;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
else if ( (item.Layer == Layer.Hair || item.Layer == Layer.FacialHair) )
|
||||
{
|
||||
object rootParent = item.RootParent;
|
||||
|
||||
if ( rootParent is Mobile )
|
||||
{
|
||||
Mobile rootMobile = (Mobile)rootParent;
|
||||
if ( item.Parent != rootMobile && rootMobile.AccessLevel == AccessLevel.Player )
|
||||
{
|
||||
items.Add( item );
|
||||
continue;
|
||||
}
|
||||
else if( item.Parent == rootMobile )
|
||||
{
|
||||
hairCleanup.Add( rootMobile );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( item.Parent != null || item.Map != Map.Internal || item.HeldBy != null )
|
||||
continue;
|
||||
|
||||
if ( item.Location != Point3D.Zero )
|
||||
continue;
|
||||
|
||||
if ( !IsBuggable( item ) )
|
||||
continue;
|
||||
|
||||
items.Add( item );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < validItems.Count; ++i )
|
||||
items.Remove( validItems[i] );
|
||||
|
||||
if ( items.Count > 0 )
|
||||
{
|
||||
if ( boxes > 0 )
|
||||
Console.WriteLine( "Cleanup: Detected {0} inaccessible items, including {1} bank boxes, removing..", items.Count, boxes );
|
||||
else
|
||||
Console.WriteLine( "Cleanup: Detected {0} inaccessible items, removing..", items.Count );
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
items[i].Delete();
|
||||
}
|
||||
|
||||
if ( hairCleanup.Count > 0 )
|
||||
{
|
||||
Console.WriteLine( "Cleanup: Detected {0} hair and facial hair items being worn, converting to their virtual counterparts..", hairCleanup.Count );
|
||||
|
||||
for ( int i = 0; i < hairCleanup.Count; i++ )
|
||||
hairCleanup[i].ConvertHair();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsBuggable( Item item )
|
||||
{
|
||||
if ( item is Fists )
|
||||
return false;
|
||||
|
||||
if ( item is ICommodity || item is Multis.BaseBoat
|
||||
|| item is Fish || item is BigFish
|
||||
|| item is BasePotion || item is Food || item is CookableFood
|
||||
|| item is SpecialFishingNet || item is BaseMagicFish
|
||||
|| item is Shoes || item is Sandals
|
||||
|| item is Boots || item is ThighBoots
|
||||
|| item is TreasureMap || item is MessageInABottle
|
||||
|| item is BaseArmor || item is BaseWeapon
|
||||
|| item is BaseClothing
|
||||
|| ( item is BaseJewel && Core.AOS )
|
||||
|| ( item is BasePotion && Core.ML )
|
||||
#region Champion artifacts
|
||||
|| item is SkullPole
|
||||
|| item is EvilIdolSkull
|
||||
|| item is MonsterStatuette
|
||||
|| item is Pier
|
||||
|| item is ArtifactLargeVase
|
||||
|| item is ArtifactVase
|
||||
|| item is MinotaurStatueDeed
|
||||
|| item is SwampTile
|
||||
|| item is WallBlood
|
||||
|| item is TatteredAncientMummyWrapping
|
||||
|| item is LavaTile
|
||||
|| item is DemonSkull
|
||||
|| item is Web
|
||||
|| item is WaterTile
|
||||
|| item is WindSpirit
|
||||
|| item is DirtPatch
|
||||
|| item is Futon )
|
||||
#endregion
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
221
Scripts/Misc/ClientVerification.cs
Normal file
221
Scripts/Misc/ClientVerification.cs
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
using System;
|
||||
using Server;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using Server.Network;
|
||||
using Server.Gumps;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class ClientVerification
|
||||
{
|
||||
private enum OldClientResponse
|
||||
{
|
||||
Ignore,
|
||||
Warn,
|
||||
Annoy,
|
||||
LenientKick,
|
||||
Kick
|
||||
}
|
||||
|
||||
private static bool m_DetectClientRequirement = true;
|
||||
private static OldClientResponse m_OldClientResponse = OldClientResponse.LenientKick;
|
||||
|
||||
private static ClientVersion m_Required;
|
||||
private static bool m_AllowRegular = true, m_AllowUOTD = true, m_AllowGod = true;
|
||||
|
||||
private static TimeSpan m_AgeLeniency = TimeSpan.FromDays( 10 );
|
||||
private static TimeSpan m_GameTimeLeniency = TimeSpan.FromHours( 25 );
|
||||
|
||||
private static TimeSpan m_KickDelay = TimeSpan.FromSeconds( 20.0 );
|
||||
|
||||
public static ClientVersion Required
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Required;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Required = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool AllowRegular
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AllowRegular;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_AllowRegular = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool AllowUOTD
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AllowUOTD;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_AllowUOTD = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool AllowGod
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_AllowGod;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_AllowGod = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static TimeSpan KickDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_KickDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_KickDelay = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.ClientVersionReceived += new ClientVersionReceivedHandler( EventSink_ClientVersionReceived );
|
||||
|
||||
//ClientVersion.Required = null;
|
||||
//Required = new ClientVersion( "6.0.0.0" );
|
||||
|
||||
if( m_DetectClientRequirement )
|
||||
{
|
||||
string path = Core.FindDataFile( "client.exe" );
|
||||
|
||||
if( File.Exists( path ) )
|
||||
{
|
||||
FileVersionInfo info = FileVersionInfo.GetVersionInfo( path );
|
||||
|
||||
if ( info.FileMajorPart != 0 || info.FileMinorPart != 0 || info.FileBuildPart != 0 || info.FilePrivatePart != 0 )
|
||||
{
|
||||
Required = new ClientVersion( info.FileMajorPart, info.FileMinorPart, info.FileBuildPart, info.FilePrivatePart );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( Required != null )
|
||||
{
|
||||
Utility.PushColor( ConsoleColor.White );
|
||||
Console.WriteLine( "Restricting client version to {0}. Action to be taken: {1}", Required, m_OldClientResponse );
|
||||
Utility.PopColor();
|
||||
}
|
||||
}
|
||||
|
||||
private static void EventSink_ClientVersionReceived( ClientVersionReceivedArgs e )
|
||||
{
|
||||
string kickMessage = null;
|
||||
NetState state = e.State;
|
||||
ClientVersion version = e.Version;
|
||||
|
||||
if ( state.Mobile == null || state.Mobile.AccessLevel > AccessLevel.Player )
|
||||
return;
|
||||
|
||||
if( Required != null && version < Required && ( m_OldClientResponse == OldClientResponse.Kick ||( m_OldClientResponse == OldClientResponse.LenientKick && (DateTime.UtcNow - state.Mobile.CreationTime) > m_AgeLeniency && state.Mobile is PlayerMobile && ((PlayerMobile)state.Mobile).GameTime > m_GameTimeLeniency )))
|
||||
{
|
||||
kickMessage = String.Format( "This server requires your client version be at least {0}.", Required );
|
||||
}
|
||||
else if( !AllowGod || !AllowRegular || !AllowUOTD )
|
||||
{
|
||||
if( !AllowGod && version.Type == ClientType.God )
|
||||
kickMessage = "This server does not allow god clients to connect.";
|
||||
else if( !AllowRegular && version.Type == ClientType.Regular )
|
||||
kickMessage = "This server does not allow regular clients to connect.";
|
||||
else if( !AllowUOTD && state.IsUOTDClient )
|
||||
kickMessage = "This server does not allow UO:TD clients to connect.";
|
||||
|
||||
if( !AllowGod && !AllowRegular && !AllowUOTD )
|
||||
{
|
||||
kickMessage = "This server does not allow any clients to connect.";
|
||||
}
|
||||
else if( AllowGod && !AllowRegular && !AllowUOTD && version.Type != ClientType.God )
|
||||
{
|
||||
kickMessage = "This server requires you to use the god client.";
|
||||
}
|
||||
else if( kickMessage != null )
|
||||
{
|
||||
if( AllowRegular && AllowUOTD )
|
||||
kickMessage += " You can use regular or UO:TD clients.";
|
||||
else if( AllowRegular )
|
||||
kickMessage += " You can use regular clients.";
|
||||
else if( AllowUOTD )
|
||||
kickMessage += " You can use UO:TD clients.";
|
||||
}
|
||||
}
|
||||
|
||||
if( kickMessage != null )
|
||||
{
|
||||
state.Mobile.SendMessage( 0x22, kickMessage );
|
||||
state.Mobile.SendMessage( 0x22, "You will be disconnected in {0} seconds.", KickDelay.TotalSeconds );
|
||||
|
||||
Timer.DelayCall( KickDelay, delegate
|
||||
{
|
||||
if( state.Socket != null )
|
||||
{
|
||||
Console.WriteLine( "Client: {0}: Disconnecting, bad version", state );
|
||||
state.Dispose();
|
||||
}
|
||||
} );
|
||||
}
|
||||
else if( Required != null && version < Required )
|
||||
{
|
||||
switch( m_OldClientResponse )
|
||||
{
|
||||
case OldClientResponse.Warn:
|
||||
{
|
||||
state.Mobile.SendMessage( 0x22, "Your client is out of date. Please update your client.", Required );
|
||||
state.Mobile.SendMessage( 0x22, "This server recommends that your client version be at least {0}.", Required );
|
||||
break;
|
||||
}
|
||||
case OldClientResponse.LenientKick:
|
||||
case OldClientResponse.Annoy:
|
||||
{
|
||||
SendAnnoyGump( state.Mobile );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void SendAnnoyGump( Mobile m )
|
||||
{
|
||||
if( m.NetState != null && m.NetState.Version < Required )
|
||||
{
|
||||
Gump g = new WarningGump( 1060637, 30720, String.Format( "Your client is out of date. Please update your client.<br>This server recommends that your client version be at least {0}.<br> <br>You are currently using version {1}.<br> <br>To patch, run UOPatch.exe inside your Ultima Online folder.", Required, m.NetState.Version ), 0xFFC000, 480, 360,
|
||||
delegate( Mobile mob, bool selection, object o )
|
||||
{
|
||||
m.SendMessage( "You will be reminded of this again." );
|
||||
|
||||
if ( m_OldClientResponse == OldClientResponse.LenientKick )
|
||||
m.SendMessage( "Old clients will be kicked after {0} days of character age and {1} hours of play time", m_AgeLeniency, m_GameTimeLeniency );
|
||||
|
||||
Timer.DelayCall( TimeSpan.FromMinutes( Utility.Random( 5, 15 ) ), delegate { SendAnnoyGump( m ); } );
|
||||
}, null, false );
|
||||
|
||||
g.Dragable = false;
|
||||
g.Closable = false;
|
||||
g.Resizable = false;
|
||||
|
||||
m.SendGump( g );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
263
Scripts/Misc/CrashGuard.cs
Normal file
263
Scripts/Misc/CrashGuard.cs
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net.Mail;
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class CrashGuard
|
||||
{
|
||||
private static bool Enabled = true;
|
||||
private static bool SaveBackup = true;
|
||||
private static bool RestartServer = true;
|
||||
private static bool GenerateReport = true;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( Enabled ) // If enabled, register our crash event handler
|
||||
EventSink.Crashed += new CrashedEventHandler( CrashGuard_OnCrash );
|
||||
}
|
||||
|
||||
public static void CrashGuard_OnCrash( CrashedEventArgs e )
|
||||
{
|
||||
if ( GenerateReport )
|
||||
GenerateCrashReport( e );
|
||||
|
||||
World.WaitForWriteCompletion();
|
||||
|
||||
if ( SaveBackup )
|
||||
Backup();
|
||||
|
||||
|
||||
/*if ( Core.Service )
|
||||
e.Close = true;
|
||||
else */ if ( RestartServer )
|
||||
Restart( e );
|
||||
}
|
||||
|
||||
private static void SendEmail( string filePath )
|
||||
{
|
||||
Console.Write( "Crash: Sending email..." );
|
||||
|
||||
MailMessage message = new MailMessage( Email.FromAddress, Email.CrashAddresses );
|
||||
|
||||
message.Subject = "Automated RunUO Crash Report";
|
||||
|
||||
message.Body = "Automated RunUO Crash Report. See attachment for details.";
|
||||
|
||||
message.Attachments.Add( new Attachment( filePath ) );
|
||||
|
||||
if ( Email.Send( message ) )
|
||||
Console.WriteLine( "done" );
|
||||
else
|
||||
Console.WriteLine( "failed" );
|
||||
}
|
||||
|
||||
private static string GetRoot()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Path.GetDirectoryName( Environment.GetCommandLineArgs()[0] );
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static string Combine( string path1, string path2 )
|
||||
{
|
||||
if ( path1.Length == 0 )
|
||||
return path2;
|
||||
|
||||
return Path.Combine( path1, path2 );
|
||||
}
|
||||
|
||||
private static void Restart( CrashedEventArgs e )
|
||||
{
|
||||
string root = GetRoot();
|
||||
|
||||
Console.Write( "Crash: Restarting..." );
|
||||
|
||||
try
|
||||
{
|
||||
Process.Start( Core.ExePath, Core.Arguments );
|
||||
Console.WriteLine( "done" );
|
||||
|
||||
e.Close = true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine( "failed" );
|
||||
}
|
||||
}
|
||||
|
||||
private static void CreateDirectory( string path )
|
||||
{
|
||||
if ( !Directory.Exists( path ) )
|
||||
Directory.CreateDirectory( path );
|
||||
}
|
||||
|
||||
private static void CreateDirectory( string path1, string path2 )
|
||||
{
|
||||
CreateDirectory( Combine( path1, path2 ) );
|
||||
}
|
||||
|
||||
private static void CopyFile( string rootOrigin, string rootBackup, string path )
|
||||
{
|
||||
string originPath = Combine( rootOrigin, path );
|
||||
string backupPath = Combine( rootBackup, path );
|
||||
|
||||
try
|
||||
{
|
||||
if ( File.Exists( originPath ) )
|
||||
File.Copy( originPath, backupPath );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void Backup()
|
||||
{
|
||||
Console.Write( "Crash: Backing up..." );
|
||||
|
||||
try
|
||||
{
|
||||
string timeStamp = GetTimeStamp();
|
||||
|
||||
string root = GetRoot();
|
||||
string rootBackup = Combine( root, String.Format( "Backups/Crashed/{0}/", timeStamp ) );
|
||||
string rootOrigin = Combine( root, String.Format( "Saves/" ) );
|
||||
|
||||
// Create new directories
|
||||
CreateDirectory( rootBackup );
|
||||
CreateDirectory( rootBackup, "Accounts/" );
|
||||
CreateDirectory( rootBackup, "Items/" );
|
||||
CreateDirectory( rootBackup, "Mobiles/" );
|
||||
CreateDirectory( rootBackup, "Guilds/" );
|
||||
CreateDirectory( rootBackup, "Regions/" );
|
||||
|
||||
// Copy files
|
||||
CopyFile( rootOrigin, rootBackup, "Accounts/Accounts.xml" );
|
||||
|
||||
CopyFile( rootOrigin, rootBackup, "Items/Items.bin" );
|
||||
CopyFile( rootOrigin, rootBackup, "Items/Items.idx" );
|
||||
CopyFile( rootOrigin, rootBackup, "Items/Items.tdb" );
|
||||
|
||||
CopyFile( rootOrigin, rootBackup, "Mobiles/Mobiles.bin" );
|
||||
CopyFile( rootOrigin, rootBackup, "Mobiles/Mobiles.idx" );
|
||||
CopyFile( rootOrigin, rootBackup, "Mobiles/Mobiles.tdb" );
|
||||
|
||||
CopyFile( rootOrigin, rootBackup, "Guilds/Guilds.bin" );
|
||||
CopyFile( rootOrigin, rootBackup, "Guilds/Guilds.idx" );
|
||||
|
||||
CopyFile( rootOrigin, rootBackup, "Regions/Regions.bin" );
|
||||
CopyFile( rootOrigin, rootBackup, "Regions/Regions.idx" );
|
||||
|
||||
Console.WriteLine( "done" );
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine( "failed" );
|
||||
}
|
||||
}
|
||||
|
||||
private static void GenerateCrashReport( CrashedEventArgs e )
|
||||
{
|
||||
Console.Write( "Crash: Generating report..." );
|
||||
|
||||
try
|
||||
{
|
||||
string timeStamp = GetTimeStamp();
|
||||
string fileName = String.Format( "Crash {0}.log", timeStamp );
|
||||
|
||||
string root = GetRoot();
|
||||
string filePath = Combine( root, fileName );
|
||||
|
||||
using ( StreamWriter op = new StreamWriter( filePath ) )
|
||||
{
|
||||
Version ver = Core.Assembly.GetName().Version;
|
||||
|
||||
op.WriteLine( "Server Crash Report" );
|
||||
op.WriteLine( "===================" );
|
||||
op.WriteLine();
|
||||
op.WriteLine( "RunUO Version {0}.{1}, Build {2}.{3}", ver.Major, ver.Minor, ver.Build, ver.Revision );
|
||||
op.WriteLine( "Operating System: {0}", Environment.OSVersion );
|
||||
op.WriteLine( ".NET Framework: {0}", Environment.Version );
|
||||
op.WriteLine( "Time: {0}", DateTime.UtcNow );
|
||||
|
||||
try { op.WriteLine( "Mobiles: {0}", World.Mobiles.Count ); }
|
||||
catch {}
|
||||
|
||||
try { op.WriteLine( "Items: {0}", World.Items.Count ); }
|
||||
catch {}
|
||||
|
||||
op.WriteLine( "Exception:" );
|
||||
op.WriteLine( e.Exception );
|
||||
op.WriteLine();
|
||||
|
||||
op.WriteLine( "Clients:" );
|
||||
|
||||
try
|
||||
{
|
||||
List<NetState> states = NetState.Instances;
|
||||
|
||||
op.WriteLine( "- Count: {0}", states.Count );
|
||||
|
||||
for ( int i = 0; i < states.Count; ++i )
|
||||
{
|
||||
NetState state = states[i];
|
||||
|
||||
op.Write( "+ {0}:", state );
|
||||
|
||||
Account a = state.Account as Account;
|
||||
|
||||
if ( a != null )
|
||||
op.Write( " (account = {0})", a.Username );
|
||||
|
||||
Mobile m = state.Mobile;
|
||||
|
||||
if ( m != null )
|
||||
op.Write( " (mobile = 0x{0:X} '{1}')", m.Serial.Value, m.Name );
|
||||
|
||||
op.WriteLine();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
op.WriteLine( "- Failed" );
|
||||
}
|
||||
}
|
||||
|
||||
Console.WriteLine( "done" );
|
||||
|
||||
if ( Email.FromAddress != null && Email.CrashAddresses != null )
|
||||
SendEmail( filePath );
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine( "failed" );
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetTimeStamp()
|
||||
{
|
||||
DateTime now = DateTime.UtcNow;
|
||||
|
||||
return String.Format( "{0}-{1}-{2}-{3}-{4}-{5}",
|
||||
now.Day,
|
||||
now.Month,
|
||||
now.Year,
|
||||
now.Hour,
|
||||
now.Minute,
|
||||
now.Second
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
Scripts/Misc/CurrentExpansion.cs
Normal file
41
Scripts/Misc/CurrentExpansion.cs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
using System;
|
||||
|
||||
using Server.Accounting;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class CurrentExpansion
|
||||
{
|
||||
private static readonly Expansion Expansion = Expansion.TOL;
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Core.Expansion = Expansion;
|
||||
|
||||
AccountGold.Enabled = Core.TOL;
|
||||
AccountGold.ConvertOnBank = true;
|
||||
AccountGold.ConvertOnTrade = false;
|
||||
VirtualCheck.UseEditGump = true;
|
||||
|
||||
bool Enabled = Core.AOS;
|
||||
|
||||
Mobile.InsuranceEnabled = Enabled;
|
||||
ObjectPropertyList.Enabled = Enabled;
|
||||
Mobile.VisibleDamageType = Enabled ? VisibleDamageType.Related : VisibleDamageType.None;
|
||||
Mobile.GuildClickMessage = !Enabled;
|
||||
Mobile.AsciiClickMessage = !Enabled;
|
||||
|
||||
if ( Enabled )
|
||||
{
|
||||
AOS.DisableStatInfluences();
|
||||
|
||||
if ( ObjectPropertyList.Enabled )
|
||||
PacketHandlers.SingleClickProps = true; // single click for everything is overriden to check object property list
|
||||
|
||||
Mobile.ActionDelay = 1000;
|
||||
Mobile.AOSStatusHandler = new AOSStatusHandler( AOS.GetStatus );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Misc/DataPath.cs
Normal file
51
Scripts/Misc/DataPath.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using Microsoft.Win32;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class DataPath
|
||||
{
|
||||
private static string CustomPath = "Data/Files";
|
||||
|
||||
/* The following is a list of files which a required for proper execution:
|
||||
Cliloc.enu
|
||||
map0.mul
|
||||
map1.mul
|
||||
map2.mul
|
||||
map3.mul
|
||||
map4.mul
|
||||
map5.mul
|
||||
multi.idx
|
||||
multi.mul
|
||||
staidx0.mul
|
||||
staidx1.mul
|
||||
staidx2.mul
|
||||
staidx3.mul
|
||||
staidx4.mul
|
||||
staidx5.mul
|
||||
statics0.mul
|
||||
statics1.mul
|
||||
statics2.mul
|
||||
statics3.mul
|
||||
statics4.mul
|
||||
statics5.mul
|
||||
tiledata.mul
|
||||
*/
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
if ( CustomPath != null )
|
||||
Core.DataDirectories.Add( CustomPath );
|
||||
|
||||
if ( Core.DataDirectories.Count == 0 && !Core.Service )
|
||||
{
|
||||
Console.WriteLine( "Enter the map files directory:" );
|
||||
Console.Write( "> " );
|
||||
|
||||
Core.DataDirectories.Add( Console.ReadLine() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Scripts/Misc/DispellableAttribute.cs
Normal file
10
Scripts/Misc/DispellableAttribute.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
[AttributeUsage( AttributeTargets.Class )]
|
||||
public class DispellableAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
10
Scripts/Misc/DispellableFieldAttribute.cs
Normal file
10
Scripts/Misc/DispellableFieldAttribute.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
[AttributeUsage( AttributeTargets.Class )]
|
||||
public class DispellableFieldAttribute : Attribute
|
||||
{
|
||||
}
|
||||
}
|
||||
564
Scripts/Misc/DoorGenerator.cs
Normal file
564
Scripts/Misc/DoorGenerator.cs
Normal file
|
|
@ -0,0 +1,564 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class DoorGenerator
|
||||
{
|
||||
private static Rectangle2D[] m_BritRegions = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D( new Point2D( 250, 750 ), new Point2D( 775, 1330 ) ),
|
||||
new Rectangle2D( new Point2D( 525, 2095 ), new Point2D( 925, 2430 ) ),
|
||||
new Rectangle2D( new Point2D( 1025, 2155 ), new Point2D( 1265, 2310 ) ),
|
||||
new Rectangle2D( new Point2D( 1635, 2430 ), new Point2D( 1705, 2508 ) ),
|
||||
new Rectangle2D( new Point2D( 1775, 2605 ), new Point2D( 2165, 2975 ) ),
|
||||
new Rectangle2D( new Point2D( 1055, 3520 ), new Point2D( 1570, 4075 ) ),
|
||||
new Rectangle2D( new Point2D( 2860, 3310 ), new Point2D( 3120, 3630 ) ),
|
||||
new Rectangle2D( new Point2D( 2470, 1855 ), new Point2D( 3950, 3045 ) ),
|
||||
new Rectangle2D( new Point2D( 3425, 990 ), new Point2D( 3900, 1455 ) ),
|
||||
new Rectangle2D( new Point2D( 4175, 735 ), new Point2D( 4840, 1600 ) ),
|
||||
new Rectangle2D( new Point2D( 2375, 330 ), new Point2D( 3100, 1045 ) ),
|
||||
new Rectangle2D( new Point2D( 2100, 1090 ), new Point2D( 2310, 1450 ) ),
|
||||
new Rectangle2D( new Point2D( 1495, 1400 ), new Point2D( 1550, 1475 ) ),
|
||||
new Rectangle2D( new Point2D( 1085, 1520 ), new Point2D( 1415, 1910 ) ),
|
||||
new Rectangle2D( new Point2D( 1410, 1500 ), new Point2D( 1745, 1795 ) ),
|
||||
new Rectangle2D( new Point2D( 5120, 2300 ), new Point2D( 6143, 4095 ) )
|
||||
};
|
||||
|
||||
private static Rectangle2D[] m_IlshRegions = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D( new Point2D( 0, 0 ), new Point2D( 288*8, 200*8 ) )
|
||||
};
|
||||
|
||||
private static Rectangle2D[] m_MalasRegions = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D( new Point2D( 0, 0 ), new Point2D( 320*8, 256*8 ) )
|
||||
};
|
||||
|
||||
private static int[] m_SouthFrames = new int[]
|
||||
{
|
||||
0x0006,
|
||||
0x0008,
|
||||
0x000B,
|
||||
0x001A,
|
||||
0x001B,
|
||||
0x001F,
|
||||
0x0038,
|
||||
0x0057,
|
||||
0x0059,
|
||||
0x005B,
|
||||
0x005D,
|
||||
0x0080,
|
||||
0x0081,
|
||||
0x0082,
|
||||
0x0084,
|
||||
0x0090,
|
||||
0x0091,
|
||||
0x0094,
|
||||
0x0096,
|
||||
0x0099,
|
||||
0x00A6,
|
||||
0x00A7,
|
||||
0x00AA,
|
||||
0x00AE,
|
||||
0x00B0,
|
||||
0x00B3,
|
||||
0x00C7,
|
||||
0x00C9,
|
||||
0x00F8,
|
||||
0x00FA,
|
||||
0x00FD,
|
||||
0x00FE,
|
||||
0x0100,
|
||||
0x0103,
|
||||
0x0104,
|
||||
0x0106,
|
||||
0x0109,
|
||||
0x0127,
|
||||
0x0129,
|
||||
0x012B,
|
||||
0x012D,
|
||||
0x012F,
|
||||
0x0131,
|
||||
0x0132,
|
||||
0x0134,
|
||||
0x0135,
|
||||
0x0137,
|
||||
0x0139,
|
||||
0x013B,
|
||||
0x014C,
|
||||
0x014E,
|
||||
0x014F,
|
||||
0x0151,
|
||||
0x0153,
|
||||
0x0155,
|
||||
0x0157,
|
||||
0x0158,
|
||||
0x015A,
|
||||
0x015D,
|
||||
0x015E,
|
||||
0x015F,
|
||||
0x0162,
|
||||
0x01CF,
|
||||
0x01D1,
|
||||
0x01D4,
|
||||
0x01FF,
|
||||
0x0204,
|
||||
0x0206,
|
||||
0x0208,
|
||||
0x020A
|
||||
};
|
||||
|
||||
private static int[] m_NorthFrames = new int[]
|
||||
{
|
||||
0x0006,
|
||||
0x0008,
|
||||
0x000D,
|
||||
0x001A,
|
||||
0x001B,
|
||||
0x0020,
|
||||
0x003A,
|
||||
0x0057,
|
||||
0x0059,
|
||||
0x005B,
|
||||
0x005D,
|
||||
0x0080,
|
||||
0x0081,
|
||||
0x0082,
|
||||
0x0084,
|
||||
0x0090,
|
||||
0x0091,
|
||||
0x0094,
|
||||
0x0096,
|
||||
0x0099,
|
||||
0x00A6,
|
||||
0x00A7,
|
||||
0x00AC,
|
||||
0x00AE,
|
||||
0x00B0,
|
||||
0x00C7,
|
||||
0x00C9,
|
||||
0x00F8,
|
||||
0x00FA,
|
||||
0x00FD,
|
||||
0x00FE,
|
||||
0x0100,
|
||||
0x0103,
|
||||
0x0104,
|
||||
0x0106,
|
||||
0x0109,
|
||||
0x0127,
|
||||
0x0129,
|
||||
0x012B,
|
||||
0x012D,
|
||||
0x012F,
|
||||
0x0131,
|
||||
0x0132,
|
||||
0x0134,
|
||||
0x0135,
|
||||
0x0137,
|
||||
0x0139,
|
||||
0x013B,
|
||||
0x014C,
|
||||
0x014E,
|
||||
0x014F,
|
||||
0x0151,
|
||||
0x0153,
|
||||
0x0155,
|
||||
0x0157,
|
||||
0x0158,
|
||||
0x015A,
|
||||
0x015D,
|
||||
0x015E,
|
||||
0x015F,
|
||||
0x0162,
|
||||
0x01CF,
|
||||
0x01D1,
|
||||
0x01D4,
|
||||
0x01FF,
|
||||
0x0201,
|
||||
0x0204,
|
||||
0x0208,
|
||||
0x020A
|
||||
};
|
||||
|
||||
private static int[] m_EastFrames = new int[]
|
||||
{
|
||||
0x0007,
|
||||
0x000A,
|
||||
0x001A,
|
||||
0x001C,
|
||||
0x001E,
|
||||
0x0037,
|
||||
0x0058,
|
||||
0x0059,
|
||||
0x005C,
|
||||
0x005E,
|
||||
0x0080,
|
||||
0x0081,
|
||||
0x0082,
|
||||
0x0084,
|
||||
0x0090,
|
||||
0x0092,
|
||||
0x0095,
|
||||
0x0097,
|
||||
0x0098,
|
||||
0x00A6,
|
||||
0x00A8,
|
||||
0x00AB,
|
||||
0x00AE,
|
||||
0x00AF,
|
||||
0x00B2,
|
||||
0x00C7,
|
||||
0x00C8,
|
||||
0x00EA,
|
||||
0x00F8,
|
||||
0x00F9,
|
||||
0x00FC,
|
||||
0x00FE,
|
||||
0x00FF,
|
||||
0x0102,
|
||||
0x0104,
|
||||
0x0105,
|
||||
0x0108,
|
||||
0x0127,
|
||||
0x0128,
|
||||
0x012B,
|
||||
0x012C,
|
||||
0x012E,
|
||||
0x0130,
|
||||
0x0132,
|
||||
0x0133,
|
||||
0x0135,
|
||||
0x0136,
|
||||
0x0138,
|
||||
0x013A,
|
||||
0x014C,
|
||||
0x014D,
|
||||
0x014F,
|
||||
0x0150,
|
||||
0x0152,
|
||||
0x0154,
|
||||
0x0156,
|
||||
0x0158,
|
||||
0x0159,
|
||||
0x015C,
|
||||
0x015E,
|
||||
0x0160,
|
||||
0x0163,
|
||||
0x01CF,
|
||||
0x01D0,
|
||||
0x01D3,
|
||||
0x01FF,
|
||||
0x0203,
|
||||
0x0205,
|
||||
0x0207,
|
||||
0x0209
|
||||
};
|
||||
|
||||
private static int[] m_WestFrames = new int[]
|
||||
{
|
||||
0x0007,
|
||||
0x000C,
|
||||
0x001A,
|
||||
0x001C,
|
||||
0x0021,
|
||||
0x0039,
|
||||
0x0058,
|
||||
0x0059,
|
||||
0x005C,
|
||||
0x005E,
|
||||
0x0080,
|
||||
0x0081,
|
||||
0x0082,
|
||||
0x0084,
|
||||
0x0090,
|
||||
0x0092,
|
||||
0x0095,
|
||||
0x0097,
|
||||
0x0098,
|
||||
0x00A6,
|
||||
0x00A8,
|
||||
0x00AD,
|
||||
0x00AE,
|
||||
0x00AF,
|
||||
0x00B5,
|
||||
0x00C7,
|
||||
0x00C8,
|
||||
0x00EA,
|
||||
0x00F8,
|
||||
0x00F9,
|
||||
0x00FC,
|
||||
0x00FE,
|
||||
0x00FF,
|
||||
0x0102,
|
||||
0x0104,
|
||||
0x0105,
|
||||
0x0108,
|
||||
0x0127,
|
||||
0x0128,
|
||||
0x012C,
|
||||
0x012E,
|
||||
0x0130,
|
||||
0x0132,
|
||||
0x0133,
|
||||
0x0135,
|
||||
0x0136,
|
||||
0x0138,
|
||||
0x013A,
|
||||
0x014C,
|
||||
0x014D,
|
||||
0x014F,
|
||||
0x0150,
|
||||
0x0152,
|
||||
0x0154,
|
||||
0x0156,
|
||||
0x0158,
|
||||
0x0159,
|
||||
0x015C,
|
||||
0x015E,
|
||||
0x0160,
|
||||
0x0163,
|
||||
0x01CF,
|
||||
0x01D0,
|
||||
0x01D3,
|
||||
0x01FF,
|
||||
0x0200,
|
||||
0x0203,
|
||||
0x0207,
|
||||
0x0209
|
||||
};
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "DoorGen", AccessLevel.Administrator, new CommandEventHandler( DoorGen_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "DoorGen" )]
|
||||
[Description( "Generates doors by analyzing the map. Slow." )]
|
||||
public static void DoorGen_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
Generate();
|
||||
}
|
||||
|
||||
private static Map m_Map;
|
||||
private static int m_Count;
|
||||
|
||||
public static void Generate()
|
||||
{
|
||||
World.Broadcast( 0x35, true, "Generating doors, please wait." );
|
||||
|
||||
Network.NetState.FlushAll();
|
||||
Network.NetState.Pause();
|
||||
|
||||
m_Map = Map.Trammel;
|
||||
m_Count = 0;
|
||||
|
||||
for ( int i = 0; i < m_BritRegions.Length; ++i )
|
||||
Generate( m_BritRegions[i] );
|
||||
|
||||
int trammelCount = m_Count;
|
||||
|
||||
m_Map = Map.Felucca;
|
||||
m_Count = 0;
|
||||
|
||||
for ( int i = 0; i < m_BritRegions.Length; ++i )
|
||||
Generate( m_BritRegions[i] );
|
||||
|
||||
int feluccaCount = m_Count;
|
||||
|
||||
m_Map = Map.Ilshenar;
|
||||
m_Count = 0;
|
||||
|
||||
for ( int i = 0; i < m_IlshRegions.Length; ++i )
|
||||
Generate( m_IlshRegions[i] );
|
||||
|
||||
int ilshenarCount = m_Count;
|
||||
|
||||
m_Map = Map.Malas;
|
||||
m_Count = 0;
|
||||
|
||||
for ( int i = 0; i < m_MalasRegions.Length; ++i )
|
||||
Generate( m_MalasRegions[i] );
|
||||
|
||||
int malasCount = m_Count;
|
||||
|
||||
Network.NetState.Resume();
|
||||
|
||||
World.Broadcast( 0x35, true, "Door generation complete. Trammel: {0}; Felucca: {1}; Ilshenar: {2}; Malas: {3};", trammelCount, feluccaCount, ilshenarCount, malasCount );
|
||||
}
|
||||
|
||||
public static bool IsFrame( int id, int[] list )
|
||||
{
|
||||
if ( id > list[list.Length - 1] )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < list.Length; ++i )
|
||||
{
|
||||
int delta = id - list[i];
|
||||
|
||||
if ( delta < 0 )
|
||||
return false;
|
||||
else if ( delta == 0 )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsNorthFrame( int id )
|
||||
{
|
||||
return IsFrame( id, m_NorthFrames );
|
||||
}
|
||||
|
||||
public static bool IsSouthFrame( int id )
|
||||
{
|
||||
return IsFrame( id, m_SouthFrames );
|
||||
}
|
||||
|
||||
public static bool IsWestFrame( int id )
|
||||
{
|
||||
return IsFrame( id, m_WestFrames );
|
||||
}
|
||||
|
||||
public static bool IsEastFrame( int id )
|
||||
{
|
||||
return IsFrame( id, m_EastFrames );
|
||||
}
|
||||
|
||||
public static bool IsEastFrame( int x, int y, int z )
|
||||
{
|
||||
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles( x, y );
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
{
|
||||
StaticTile tile = tiles[i];
|
||||
|
||||
if ( tile.Z == z && IsEastFrame( tile.ID ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsSouthFrame( int x, int y, int z )
|
||||
{
|
||||
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles( x, y );
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
{
|
||||
StaticTile tile = tiles[i];
|
||||
|
||||
if ( tile.Z == z && IsSouthFrame( tile.ID ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static BaseDoor AddDoor( int x, int y, int z, DoorFacing facing )
|
||||
{
|
||||
int doorZ = z;
|
||||
int doorTop = doorZ + 20;
|
||||
|
||||
if ( !m_Map.CanFit( x, y, z, 16, false, false ) )
|
||||
return null;
|
||||
|
||||
if ( y == 1743 && x >= 1343 && x <= 1344 )
|
||||
return null;
|
||||
|
||||
if ( y == 1679 && x >= 1392 && x <= 1393 )
|
||||
return null;
|
||||
|
||||
if ( x == 1320 && y >= 1618 && y <= 1640 )
|
||||
return null;
|
||||
|
||||
if ( x == 1383 && y >= 1642 && y <= 1643 )
|
||||
return null;
|
||||
|
||||
BaseDoor door = new DarkWoodDoor( facing );
|
||||
door.MoveToWorld( new Point3D( x, y, z ), m_Map );
|
||||
|
||||
++m_Count;
|
||||
|
||||
return door;
|
||||
}
|
||||
|
||||
public static void Generate( Rectangle2D region )
|
||||
{
|
||||
for ( int rx = 0; rx < region.Width; ++rx )
|
||||
{
|
||||
for ( int ry = 0; ry < region.Height; ++ry )
|
||||
{
|
||||
int vx = rx + region.X;
|
||||
int vy = ry + region.Y;
|
||||
|
||||
StaticTile[] tiles = m_Map.Tiles.GetStaticTiles( vx, vy );
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
{
|
||||
StaticTile tile = tiles[i];
|
||||
|
||||
int id = tile.ID;
|
||||
int z = tile.Z;
|
||||
|
||||
if ( IsWestFrame( id ) )
|
||||
{
|
||||
if ( IsEastFrame( vx + 2, vy, z ) )
|
||||
{
|
||||
AddDoor( vx + 1, vy, z, DoorFacing.WestCW );
|
||||
}
|
||||
else if ( IsEastFrame( vx + 3, vy, z ) )
|
||||
{
|
||||
BaseDoor first = AddDoor( vx + 1, vy, z, DoorFacing.WestCW );
|
||||
BaseDoor second = AddDoor( vx + 2, vy, z, DoorFacing.EastCCW );
|
||||
|
||||
if ( first != null && second != null )
|
||||
{
|
||||
first.Link = second;
|
||||
second.Link = first;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( first != null )
|
||||
first.Delete();
|
||||
|
||||
if ( second != null )
|
||||
second.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( IsNorthFrame( id ) )
|
||||
{
|
||||
if ( IsSouthFrame( vx, vy + 2, z ) )
|
||||
{
|
||||
AddDoor( vx, vy + 1, z, DoorFacing.SouthCW );
|
||||
}
|
||||
else if ( IsSouthFrame( vx, vy + 3, z ) )
|
||||
{
|
||||
BaseDoor first = AddDoor( vx, vy + 1, z, DoorFacing.NorthCCW );
|
||||
BaseDoor second = AddDoor( vx, vy + 2, z, DoorFacing.SouthCW );
|
||||
|
||||
if ( first != null && second != null )
|
||||
{
|
||||
first.Link = second;
|
||||
second.Link = first;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( first != null )
|
||||
first.Delete();
|
||||
|
||||
if ( second != null )
|
||||
second.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
99
Scripts/Misc/Email.cs
Normal file
99
Scripts/Misc/Email.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using System.Net.Mail;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Email
|
||||
{
|
||||
/* In order to support emailing, fill in EmailServer and FromAddress:
|
||||
* Example:
|
||||
* public static readonly string EmailServer = "mail.domain.com";
|
||||
* public static readonly string FromAddress = "runuo@domain.com";
|
||||
*
|
||||
* If you want to add crash reporting emailing, fill in CrashAddresses:
|
||||
* Example:
|
||||
* public static readonly string CrashAddresses = "first@email.here,second@email.here,third@email.here";
|
||||
*
|
||||
* If you want to add speech log page emailing, fill in SpeechLogPageAddresses:
|
||||
* Example:
|
||||
* public static readonly string SpeechLogPageAddresses = "first@email.here,second@email.here,third@email.here";
|
||||
*/
|
||||
|
||||
public static readonly string EmailServer = null;
|
||||
public static readonly int EmailPort = 25;
|
||||
|
||||
public static readonly string FromAddress = null;
|
||||
public static readonly string EmailUsername = null;
|
||||
public static readonly string EmailPassword = null;
|
||||
|
||||
|
||||
public static readonly string CrashAddresses = null;
|
||||
public static readonly string SpeechLogPageAddresses = null;
|
||||
|
||||
private static Regex _pattern = new Regex( @"^[a-z0-9.+_-]+@([a-z0-9-]+\.)+[a-z]+$", RegexOptions.Compiled | RegexOptions.IgnoreCase );
|
||||
|
||||
public static bool IsValid( string address )
|
||||
{
|
||||
if ( address == null || address.Length > 320 )
|
||||
return false;
|
||||
|
||||
return _pattern.IsMatch( address );
|
||||
}
|
||||
|
||||
private static SmtpClient _Client;
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
if ( EmailServer != null )
|
||||
{
|
||||
_Client = new SmtpClient( EmailServer, EmailPort );
|
||||
if ( EmailUsername != null )
|
||||
{
|
||||
_Client.Credentials = new System.Net.NetworkCredential( EmailUsername, EmailPassword );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Send( MailMessage message )
|
||||
{
|
||||
try
|
||||
{
|
||||
// .NET relies on the MTA to generate Message-ID header. Not all MTAs will add this header.
|
||||
|
||||
DateTime now = DateTime.UtcNow;
|
||||
string messageID = String.Format("<{0}.{1}@{2}>", now.ToString("yyyyMMdd"), now.ToString("HHmmssff"), EmailServer );
|
||||
message.Headers.Add("Message-ID", messageID );
|
||||
|
||||
message.Headers.Add("X-Mailer", "RunUO");
|
||||
|
||||
lock ( _Client ) {
|
||||
_Client.Send( message );
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void AsyncSend( MailMessage message )
|
||||
{
|
||||
ThreadPool.QueueUserWorkItem( new WaitCallback( SendCallback ), message );
|
||||
}
|
||||
|
||||
private static void SendCallback( object state )
|
||||
{
|
||||
MailMessage message = (MailMessage) state;
|
||||
|
||||
if ( Send( message ) )
|
||||
Console.WriteLine( "Sent e-mail '{0}' to '{1}'.", message.Subject, message.To );
|
||||
else
|
||||
Console.WriteLine( "Failure sending e-mail '{0}' to '{1}'.", message.Subject, message.To );
|
||||
}
|
||||
}
|
||||
}
|
||||
727
Scripts/Misc/Emitter.cs
Normal file
727
Scripts/Misc/Emitter.cs
Normal file
|
|
@ -0,0 +1,727 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using Emit = System.Reflection.Emit;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class AssemblyEmitter
|
||||
{
|
||||
private string m_AssemblyName;
|
||||
|
||||
private AppDomain m_AppDomain;
|
||||
private AssemblyBuilder m_AssemblyBuilder;
|
||||
private ModuleBuilder m_ModuleBuilder;
|
||||
|
||||
public AssemblyEmitter( string assemblyName, bool canSave )
|
||||
{
|
||||
m_AssemblyName = assemblyName;
|
||||
|
||||
m_AppDomain = AppDomain.CurrentDomain;
|
||||
|
||||
m_AssemblyBuilder = m_AppDomain.DefineDynamicAssembly(
|
||||
new AssemblyName( assemblyName ),
|
||||
canSave ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run
|
||||
);
|
||||
|
||||
if ( canSave )
|
||||
{
|
||||
m_ModuleBuilder = m_AssemblyBuilder.DefineDynamicModule(
|
||||
assemblyName,
|
||||
String.Format( "{0}.dll", assemblyName.ToLower() ),
|
||||
false
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ModuleBuilder = m_AssemblyBuilder.DefineDynamicModule(
|
||||
assemblyName,
|
||||
false
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public TypeBuilder DefineType( string typeName, TypeAttributes attrs, Type parentType )
|
||||
{
|
||||
return m_ModuleBuilder.DefineType( typeName, attrs, parentType );
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
m_AssemblyBuilder.Save(
|
||||
String.Format( "{0}.dll", m_AssemblyName.ToLower() )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public class MethodEmitter
|
||||
{
|
||||
private TypeBuilder m_TypeBuilder;
|
||||
|
||||
private MethodBuilder m_Builder;
|
||||
private ILGenerator m_Generator;
|
||||
|
||||
private Type[] m_ArgumentTypes;
|
||||
|
||||
public TypeBuilder Type
|
||||
{
|
||||
get { return m_TypeBuilder; }
|
||||
}
|
||||
|
||||
public ILGenerator Generator
|
||||
{
|
||||
get { return m_Generator; }
|
||||
}
|
||||
|
||||
private class CallInfo
|
||||
{
|
||||
public Type type;
|
||||
public MethodInfo method;
|
||||
|
||||
public int index;
|
||||
public ParameterInfo[] parms;
|
||||
|
||||
public CallInfo( Type type, MethodInfo method )
|
||||
{
|
||||
this.type = type;
|
||||
this.method = method;
|
||||
|
||||
this.parms = method.GetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
private Stack<Type> m_Stack;
|
||||
private Stack<CallInfo> m_Calls;
|
||||
|
||||
private Dictionary<Type, Queue<LocalBuilder>> m_Temps;
|
||||
|
||||
public MethodBuilder Method
|
||||
{
|
||||
get { return m_Builder; }
|
||||
}
|
||||
|
||||
public MethodEmitter( TypeBuilder typeBuilder )
|
||||
{
|
||||
m_TypeBuilder = typeBuilder;
|
||||
|
||||
m_Temps = new Dictionary<Type, Queue<LocalBuilder>>();
|
||||
|
||||
m_Stack = new Stack<Type>();
|
||||
m_Calls = new Stack<CallInfo>();
|
||||
}
|
||||
|
||||
public void Define( string name, MethodAttributes attr, Type returnType, Type[] parms )
|
||||
{
|
||||
m_Builder = m_TypeBuilder.DefineMethod( name, attr, returnType, parms );
|
||||
m_Generator = m_Builder.GetILGenerator();
|
||||
|
||||
m_ArgumentTypes = parms;
|
||||
}
|
||||
|
||||
public LocalBuilder CreateLocal( Type localType )
|
||||
{
|
||||
return m_Generator.DeclareLocal( localType );
|
||||
}
|
||||
|
||||
public LocalBuilder AcquireTemp( Type localType )
|
||||
{
|
||||
Queue<LocalBuilder> list;
|
||||
|
||||
if ( !m_Temps.TryGetValue( localType, out list ) )
|
||||
m_Temps[localType] = list = new Queue<LocalBuilder>();
|
||||
|
||||
if ( list.Count > 0 )
|
||||
return list.Dequeue();
|
||||
|
||||
return CreateLocal( localType );
|
||||
}
|
||||
|
||||
public void ReleaseTemp( LocalBuilder local )
|
||||
{
|
||||
Queue<LocalBuilder> list;
|
||||
|
||||
if ( !m_Temps.TryGetValue( local.LocalType, out list ) )
|
||||
m_Temps[local.LocalType] = list = new Queue<LocalBuilder>();
|
||||
|
||||
list.Enqueue( local );
|
||||
}
|
||||
|
||||
public void Branch( Label label )
|
||||
{
|
||||
m_Generator.Emit( OpCodes.Br, label );
|
||||
}
|
||||
|
||||
public void BranchIfFalse( Label label )
|
||||
{
|
||||
Pop( typeof( object ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Brfalse, label );
|
||||
}
|
||||
|
||||
public void BranchIfTrue( Label label )
|
||||
{
|
||||
Pop( typeof( object ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Brtrue, label );
|
||||
}
|
||||
|
||||
public Label CreateLabel()
|
||||
{
|
||||
return m_Generator.DefineLabel();
|
||||
}
|
||||
|
||||
public void MarkLabel( Label label )
|
||||
{
|
||||
m_Generator.MarkLabel( label );
|
||||
}
|
||||
|
||||
public void Pop()
|
||||
{
|
||||
m_Stack.Pop();
|
||||
}
|
||||
|
||||
public void Pop( Type expected )
|
||||
{
|
||||
if ( expected == null )
|
||||
throw new InvalidOperationException( "Expected type cannot be null." );
|
||||
|
||||
Type onStack = m_Stack.Pop();
|
||||
|
||||
if ( expected == typeof( bool ) )
|
||||
expected = typeof( int );
|
||||
|
||||
if ( onStack == typeof( bool ) )
|
||||
onStack = typeof( int );
|
||||
|
||||
if ( !expected.IsAssignableFrom( onStack ) )
|
||||
throw new InvalidOperationException( "Unexpected stack state." );
|
||||
}
|
||||
|
||||
public void Push( Type type )
|
||||
{
|
||||
m_Stack.Push( type );
|
||||
}
|
||||
|
||||
public void Return()
|
||||
{
|
||||
if ( m_Stack.Count != ( m_Builder.ReturnType == typeof( void ) ? 0 : 1 ) )
|
||||
throw new InvalidOperationException( "Stack return mismatch." );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ret );
|
||||
}
|
||||
|
||||
public void LoadNull()
|
||||
{
|
||||
LoadNull( typeof( object ) );
|
||||
}
|
||||
|
||||
public void LoadNull( Type type )
|
||||
{
|
||||
Push( type );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ldnull );
|
||||
}
|
||||
|
||||
public void Load( string value )
|
||||
{
|
||||
Push( typeof( string ) );
|
||||
|
||||
if ( value != null )
|
||||
m_Generator.Emit( OpCodes.Ldstr, value );
|
||||
else
|
||||
m_Generator.Emit( OpCodes.Ldnull );
|
||||
}
|
||||
|
||||
public void Load( Enum value )
|
||||
{
|
||||
int toLoad = ((IConvertible)value).ToInt32( null );
|
||||
Load( toLoad );
|
||||
|
||||
Pop();
|
||||
Push( value.GetType() );
|
||||
}
|
||||
|
||||
public void Load( long value )
|
||||
{
|
||||
Push( typeof( long ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ldc_I8, value );
|
||||
}
|
||||
|
||||
public void Load( float value )
|
||||
{
|
||||
Push( typeof( float ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ldc_R4, value );
|
||||
}
|
||||
|
||||
public void Load( double value )
|
||||
{
|
||||
Push( typeof( double ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ldc_R8, value );
|
||||
}
|
||||
|
||||
public void Load( char value )
|
||||
{
|
||||
Load( (int) value );
|
||||
|
||||
Pop();
|
||||
Push( typeof( char ) );
|
||||
}
|
||||
|
||||
public void Load( bool value )
|
||||
{
|
||||
Push( typeof( bool ) );
|
||||
|
||||
if ( value )
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_1 );
|
||||
else
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_0 );
|
||||
}
|
||||
|
||||
public void Load( int value )
|
||||
{
|
||||
Push( typeof( int ) );
|
||||
|
||||
switch ( value )
|
||||
{
|
||||
case -1:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_M1 );
|
||||
break;
|
||||
|
||||
case 0:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_0 );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_1 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_2 );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_3 );
|
||||
break;
|
||||
|
||||
case 4:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_4 );
|
||||
break;
|
||||
|
||||
case 5:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_5 );
|
||||
break;
|
||||
|
||||
case 6:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_6 );
|
||||
break;
|
||||
|
||||
case 7:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_7 );
|
||||
break;
|
||||
|
||||
case 8:
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_8 );
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( value >= sbyte.MinValue && value <= sbyte.MaxValue )
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_S, (sbyte) value );
|
||||
else
|
||||
m_Generator.Emit( OpCodes.Ldc_I4, value );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadField( FieldInfo field )
|
||||
{
|
||||
Pop( field.DeclaringType );
|
||||
|
||||
Push( field.FieldType );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ldfld, field );
|
||||
}
|
||||
|
||||
public void LoadLocal( LocalBuilder local )
|
||||
{
|
||||
Push( local.LocalType );
|
||||
|
||||
int index = local.LocalIndex;
|
||||
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
m_Generator.Emit( OpCodes.Ldloc_0 );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_Generator.Emit( OpCodes.Ldloc_1 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_Generator.Emit( OpCodes.Ldloc_2 );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_Generator.Emit( OpCodes.Ldloc_3 );
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( index >= byte.MinValue && index <= byte.MinValue )
|
||||
m_Generator.Emit( OpCodes.Ldloc_S, (byte) index );
|
||||
else
|
||||
m_Generator.Emit( OpCodes.Ldloc, (short) index );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void StoreLocal( LocalBuilder local )
|
||||
{
|
||||
Pop( local.LocalType );
|
||||
|
||||
m_Generator.Emit( OpCodes.Stloc, local );
|
||||
}
|
||||
|
||||
public void LoadArgument( int index )
|
||||
{
|
||||
if ( index > 0 )
|
||||
Push( m_ArgumentTypes[index - 1] );
|
||||
else
|
||||
Push( m_TypeBuilder );
|
||||
|
||||
switch ( index )
|
||||
{
|
||||
case 0:
|
||||
m_Generator.Emit( OpCodes.Ldarg_0 );
|
||||
break;
|
||||
|
||||
case 1:
|
||||
m_Generator.Emit( OpCodes.Ldarg_1 );
|
||||
break;
|
||||
|
||||
case 2:
|
||||
m_Generator.Emit( OpCodes.Ldarg_2 );
|
||||
break;
|
||||
|
||||
case 3:
|
||||
m_Generator.Emit( OpCodes.Ldarg_3 );
|
||||
break;
|
||||
|
||||
default:
|
||||
if ( index >= byte.MinValue && index <= byte.MaxValue )
|
||||
m_Generator.Emit( OpCodes.Ldarg_S, (byte) index );
|
||||
else
|
||||
m_Generator.Emit( OpCodes.Ldarg, (short) index );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void CastAs( Type type )
|
||||
{
|
||||
Pop( typeof( object ) );
|
||||
Push( type );
|
||||
|
||||
m_Generator.Emit( OpCodes.Isinst, type );
|
||||
}
|
||||
|
||||
public void Neg()
|
||||
{
|
||||
Pop( typeof( int ) );
|
||||
|
||||
Push( typeof( int ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Neg );
|
||||
}
|
||||
|
||||
public void Compare( OpCode opCode )
|
||||
{
|
||||
Pop();
|
||||
Pop();
|
||||
|
||||
Push( typeof( int ) );
|
||||
|
||||
m_Generator.Emit( opCode );
|
||||
}
|
||||
|
||||
public void LogicalNot()
|
||||
{
|
||||
Pop( typeof( int ) );
|
||||
|
||||
Push( typeof( int ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Ldc_I4_0 );
|
||||
m_Generator.Emit( OpCodes.Ceq );
|
||||
}
|
||||
|
||||
public void Xor()
|
||||
{
|
||||
Pop( typeof( int ) );
|
||||
Pop( typeof( int ) );
|
||||
|
||||
Push( typeof( int ) );
|
||||
|
||||
m_Generator.Emit( OpCodes.Xor );
|
||||
}
|
||||
|
||||
public Type Active
|
||||
{
|
||||
get { return m_Stack.Peek(); }
|
||||
}
|
||||
|
||||
public void Chain( Property prop )
|
||||
{
|
||||
for ( int i = 0; i < prop.Chain.Length; ++i )
|
||||
Call( prop.Chain[i].GetGetMethod() );
|
||||
}
|
||||
|
||||
public void Call( MethodInfo method )
|
||||
{
|
||||
BeginCall( method );
|
||||
|
||||
CallInfo call = m_Calls.Peek();
|
||||
|
||||
if ( call.parms.Length > 0 )
|
||||
throw new InvalidOperationException( "Method requires parameters." );
|
||||
|
||||
FinishCall();
|
||||
}
|
||||
|
||||
public delegate void Callback();
|
||||
|
||||
public bool CompareTo( int sign, Callback argGenerator )
|
||||
{
|
||||
Type active = this.Active;
|
||||
|
||||
MethodInfo compareTo = active.GetMethod( "CompareTo", new Type[] { active } );
|
||||
|
||||
if ( compareTo == null )
|
||||
{
|
||||
/* This gets a little tricky...
|
||||
*
|
||||
* There's a scenario where we might be trying to use CompareTo on an interface
|
||||
* which, while it doesn't explicitly implement CompareTo itself, is said to
|
||||
* extend IComparable indirectly. The implementation is implicitly passed off
|
||||
* to implementers...
|
||||
*
|
||||
* interface ISomeInterface : IComparable
|
||||
* {
|
||||
* void SomeMethod();
|
||||
* }
|
||||
*
|
||||
* class SomeClass : ISomeInterface
|
||||
* {
|
||||
* void SomeMethod() { ... }
|
||||
* int CompareTo( object other ) { ... }
|
||||
* }
|
||||
*
|
||||
* In this case, calling ISomeInterface.GetMethod( "CompareTo" ) will return null.
|
||||
*
|
||||
* Bleh.
|
||||
*/
|
||||
|
||||
Type[] ifaces = active.FindInterfaces( delegate( Type type, object obj )
|
||||
{
|
||||
return ( type.IsGenericType )
|
||||
&& ( type.GetGenericTypeDefinition() == typeof( IComparable<> ) )
|
||||
&& ( type.GetGenericArguments()[0].IsAssignableFrom( active ) );
|
||||
}, null );
|
||||
|
||||
if ( ifaces.Length > 0 )
|
||||
{
|
||||
compareTo = ifaces[0].GetMethod( "CompareTo", new Type[] { active } );
|
||||
}
|
||||
else
|
||||
{
|
||||
ifaces = active.FindInterfaces( delegate( Type type, object obj )
|
||||
{
|
||||
return ( type == typeof( IComparable ) );
|
||||
}, null );
|
||||
|
||||
if ( ifaces.Length > 0 )
|
||||
compareTo = ifaces[0].GetMethod( "CompareTo", new Type[] { active } );
|
||||
}
|
||||
}
|
||||
|
||||
if ( compareTo == null )
|
||||
return false;
|
||||
|
||||
if ( !active.IsValueType )
|
||||
{
|
||||
/* This object is a reference type, so we have to make it behave
|
||||
*
|
||||
* null.CompareTo( null ) = 0
|
||||
* real.CompareTo( null ) = -1
|
||||
* null.CompareTo( real ) = +1
|
||||
*
|
||||
*/
|
||||
|
||||
LocalBuilder aValue = AcquireTemp( active );
|
||||
LocalBuilder bValue = AcquireTemp( active );
|
||||
|
||||
StoreLocal( aValue );
|
||||
|
||||
argGenerator();
|
||||
|
||||
StoreLocal( bValue );
|
||||
|
||||
/* if ( aValue == null )
|
||||
* {
|
||||
* if ( bValue == null )
|
||||
* v = 0;
|
||||
* else
|
||||
* v = +1;
|
||||
* }
|
||||
* else if ( bValue == null )
|
||||
* {
|
||||
* v = -1;
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* v = aValue.CompareTo( bValue );
|
||||
* }
|
||||
*/
|
||||
|
||||
Label store = CreateLabel();
|
||||
|
||||
Label aNotNull = CreateLabel();
|
||||
|
||||
LoadLocal( aValue );
|
||||
BranchIfTrue( aNotNull );
|
||||
// if ( aValue == null )
|
||||
{
|
||||
Label bNotNull = CreateLabel();
|
||||
|
||||
LoadLocal( bValue );
|
||||
BranchIfTrue( bNotNull );
|
||||
// if ( bValue == null )
|
||||
{
|
||||
Load( 0 );
|
||||
Pop( typeof( int ) );
|
||||
Branch( store );
|
||||
}
|
||||
MarkLabel( bNotNull );
|
||||
// else
|
||||
{
|
||||
Load( sign );
|
||||
Pop( typeof( int ) );
|
||||
Branch( store );
|
||||
}
|
||||
}
|
||||
MarkLabel( aNotNull );
|
||||
// else
|
||||
{
|
||||
Label bNotNull = CreateLabel();
|
||||
|
||||
LoadLocal( bValue );
|
||||
BranchIfTrue( bNotNull );
|
||||
// bValue == null
|
||||
{
|
||||
Load( -sign );
|
||||
Pop( typeof( int ) );
|
||||
Branch( store );
|
||||
}
|
||||
MarkLabel( bNotNull );
|
||||
// else
|
||||
{
|
||||
LoadLocal( aValue );
|
||||
BeginCall( compareTo );
|
||||
|
||||
LoadLocal( bValue );
|
||||
ArgumentPushed();
|
||||
|
||||
FinishCall();
|
||||
|
||||
if ( sign == -1 )
|
||||
Neg();
|
||||
}
|
||||
}
|
||||
|
||||
MarkLabel( store );
|
||||
|
||||
ReleaseTemp( aValue );
|
||||
ReleaseTemp( bValue );
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginCall( compareTo );
|
||||
|
||||
argGenerator();
|
||||
|
||||
ArgumentPushed();
|
||||
|
||||
FinishCall();
|
||||
|
||||
if ( sign == -1 )
|
||||
Neg();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void BeginCall( MethodInfo method )
|
||||
{
|
||||
Type type;
|
||||
|
||||
if ( ( method.CallingConvention & CallingConventions.HasThis ) != 0 )
|
||||
type = m_Stack.Peek();
|
||||
else
|
||||
type = method.DeclaringType;
|
||||
|
||||
m_Calls.Push( new CallInfo( type, method ) );
|
||||
|
||||
if ( type.IsValueType )
|
||||
{
|
||||
LocalBuilder temp = AcquireTemp( type );
|
||||
|
||||
m_Generator.Emit( OpCodes.Stloc, temp );
|
||||
m_Generator.Emit( OpCodes.Ldloca, temp );
|
||||
|
||||
ReleaseTemp( temp );
|
||||
}
|
||||
}
|
||||
|
||||
public void FinishCall()
|
||||
{
|
||||
CallInfo call = m_Calls.Pop();
|
||||
|
||||
if ( ( call.type.IsValueType || call.type.IsByRef ) && call.method.DeclaringType != call.type )
|
||||
m_Generator.Emit( OpCodes.Constrained, call.type );
|
||||
|
||||
if ( call.method.DeclaringType.IsValueType || call.method.IsStatic )
|
||||
m_Generator.Emit( OpCodes.Call, call.method );
|
||||
else
|
||||
m_Generator.Emit( OpCodes.Callvirt, call.method );
|
||||
|
||||
for ( int i = call.parms.Length - 1; i >= 0; --i )
|
||||
Pop( call.parms[i].ParameterType );
|
||||
|
||||
if ( ( call.method.CallingConvention & CallingConventions.HasThis ) != 0 )
|
||||
Pop( call.method.DeclaringType );
|
||||
|
||||
if ( call.method.ReturnType != typeof( void ) )
|
||||
Push( call.method.ReturnType );
|
||||
}
|
||||
|
||||
public void ArgumentPushed()
|
||||
{
|
||||
CallInfo call = m_Calls.Peek();
|
||||
|
||||
ParameterInfo parm = call.parms[call.index++];
|
||||
|
||||
Type argumentType = m_Stack.Peek();
|
||||
|
||||
if ( !parm.ParameterType.IsAssignableFrom( argumentType ) )
|
||||
throw new InvalidOperationException( "Parameter type mismatch." );
|
||||
|
||||
if ( argumentType.IsValueType && !parm.ParameterType.IsValueType )
|
||||
m_Generator.Emit( OpCodes.Box, argumentType );
|
||||
}
|
||||
}
|
||||
}
|
||||
32
Scripts/Misc/Fastwalk.cs
Normal file
32
Scripts/Misc/Fastwalk.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
// This fastwalk detection is no longer required
|
||||
// As of B36 PlayerMobile implements movement packet throttling which more reliably controls movement speeds
|
||||
public class Fastwalk
|
||||
{
|
||||
private static int MaxSteps = 4; // Maximum number of queued steps until fastwalk is detected
|
||||
private static bool Enabled = false; // Is fastwalk detection enabled?
|
||||
private static bool UOTDOverride = false; // Should UO:TD clients not be checked for fastwalk?
|
||||
private static AccessLevel AccessOverride = AccessLevel.GameMaster; // Anyone with this or higher access level is not checked for fastwalk
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Mobile.FwdMaxSteps = MaxSteps;
|
||||
Mobile.FwdEnabled = Enabled;
|
||||
Mobile.FwdUOTDOverride = UOTDOverride;
|
||||
Mobile.FwdAccessOverride = AccessOverride;
|
||||
|
||||
if ( Enabled )
|
||||
EventSink.FastWalk += new FastWalkEventHandler( OnFastWalk );
|
||||
}
|
||||
|
||||
public static void OnFastWalk( FastWalkEventArgs e )
|
||||
{
|
||||
e.Blocked = true;//disallow this fastwalk
|
||||
Console.WriteLine( "Client: {0}: Fast movement detected (name={1})", e.NetState, e.NetState.Mobile.Name );
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Scripts/Misc/FoodDecay.cs
Normal file
45
Scripts/Misc/FoodDecay.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class FoodDecayTimer : Timer
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
new FoodDecayTimer().Start();
|
||||
}
|
||||
|
||||
public FoodDecayTimer() : base( TimeSpan.FromMinutes( 5 ), TimeSpan.FromMinutes( 5 ) )
|
||||
{
|
||||
Priority = TimerPriority.OneMinute;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
FoodDecay();
|
||||
}
|
||||
|
||||
public static void FoodDecay()
|
||||
{
|
||||
foreach ( NetState state in NetState.Instances )
|
||||
{
|
||||
HungerDecay( state.Mobile );
|
||||
ThirstDecay( state.Mobile );
|
||||
}
|
||||
}
|
||||
|
||||
public static void HungerDecay( Mobile m )
|
||||
{
|
||||
if ( m != null && m.Hunger >= 1 )
|
||||
m.Hunger -= 1;
|
||||
}
|
||||
|
||||
public static void ThirstDecay( Mobile m )
|
||||
{
|
||||
if ( m != null && m.Thirst >= 1 )
|
||||
m.Thirst -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
224
Scripts/Misc/Geometry.cs
Normal file
224
Scripts/Misc/Geometry.cs
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public delegate void DoEffect_Callback( Point3D p, Map map );
|
||||
|
||||
public static class Geometry
|
||||
{
|
||||
public static void Swap<T>( ref T a, ref T b )
|
||||
{
|
||||
T temp = a;
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
|
||||
public static double RadiansToDegrees( double angle )
|
||||
{
|
||||
return angle * (180.0 / Math.PI);
|
||||
}
|
||||
|
||||
public static double DegreesToRadians( double angle )
|
||||
{
|
||||
return angle * ( Math.PI / 180.0 );
|
||||
}
|
||||
|
||||
public class CirclePoint
|
||||
{
|
||||
private Point2D point;
|
||||
private int angle;
|
||||
private int quadrant;
|
||||
|
||||
public Point2D Point{ get{ return point; } }
|
||||
public int Angle{ get{ return angle; } }
|
||||
public int Quadrant{ get{ return quadrant; } }
|
||||
|
||||
public CirclePoint( Point2D point, int angle, int quadrant )
|
||||
{
|
||||
this.point = point;
|
||||
this.angle = angle;
|
||||
this.quadrant = quadrant;
|
||||
}
|
||||
}
|
||||
|
||||
public static Point2D ArcPoint( Point3D loc, int radius, int angle )
|
||||
{
|
||||
int sideA, sideB;
|
||||
|
||||
if ( angle < 0 )
|
||||
angle = 0;
|
||||
|
||||
if ( angle > 90 )
|
||||
angle = 90;
|
||||
|
||||
sideA = (int) Math.Round( radius * Math.Sin( DegreesToRadians( angle ) ) );
|
||||
sideB = (int) Math.Round( radius * Math.Cos( DegreesToRadians( angle ) ) );
|
||||
|
||||
return new Point2D( loc.X - sideB, loc.Y - sideA );
|
||||
}
|
||||
|
||||
public static void Circle2D( Point3D loc, Map map, int radius, DoEffect_Callback effect )
|
||||
{
|
||||
Circle2D( loc, map, radius, effect, 0, 360 );
|
||||
}
|
||||
|
||||
public static void Circle2D( Point3D loc, Map map, int radius, DoEffect_Callback effect, int angleStart, int angleEnd )
|
||||
{
|
||||
if ( angleStart < 0 || angleStart > 360 )
|
||||
angleStart = 0;
|
||||
|
||||
if ( angleEnd > 360 || angleEnd < 0 )
|
||||
angleEnd = 360;
|
||||
|
||||
if ( angleStart == angleEnd )
|
||||
return;
|
||||
|
||||
bool opposite = angleStart > angleEnd;
|
||||
|
||||
int startQuadrant = angleStart / 90;
|
||||
int endQuadrant = angleEnd / 90;
|
||||
|
||||
Point2D start = ArcPoint( loc, radius, angleStart % 90 );
|
||||
Point2D end = ArcPoint( loc, radius, angleEnd % 90 );
|
||||
|
||||
if ( opposite )
|
||||
{
|
||||
Swap( ref start, ref end );
|
||||
Swap( ref startQuadrant, ref endQuadrant );
|
||||
}
|
||||
|
||||
CirclePoint startPoint = new CirclePoint( start, angleStart, startQuadrant );
|
||||
CirclePoint endPoint = new CirclePoint( end, angleEnd, endQuadrant );
|
||||
|
||||
int error = -radius;
|
||||
int x = radius;
|
||||
int y = 0;
|
||||
|
||||
while (x > y)
|
||||
{
|
||||
plot4points( loc, map, x, y, startPoint, endPoint, effect, opposite );
|
||||
plot4points( loc, map, y, x, startPoint, endPoint, effect, opposite );
|
||||
|
||||
error += ( y * 2 ) + 1;
|
||||
++y;
|
||||
|
||||
if (error >= 0)
|
||||
{
|
||||
--x;
|
||||
error -= x * 2;
|
||||
}
|
||||
}
|
||||
|
||||
plot4points( loc, map, x, y, startPoint, endPoint, effect, opposite );
|
||||
}
|
||||
|
||||
public static void plot4points( Point3D loc, Map map, int x, int y, CirclePoint start, CirclePoint end, DoEffect_Callback effect, bool opposite )
|
||||
{
|
||||
Point2D pointA = new Point2D( loc.X - x, loc.Y - y );
|
||||
Point2D pointB = new Point2D( loc.X - y, loc.Y - x );
|
||||
|
||||
int quadrant = 2;
|
||||
|
||||
if ( x == 0 && start.Quadrant == 3 )
|
||||
quadrant = 3;
|
||||
|
||||
if ( WithinCircleBounds( quadrant == 3 ? pointB : pointA, quadrant, loc, start, end, opposite ) )
|
||||
effect( new Point3D( loc.X + x, loc.Y + y, loc.Z ), map );
|
||||
|
||||
quadrant = 3;
|
||||
|
||||
if ( y == 0 && start.Quadrant == 0 )
|
||||
quadrant = 0;
|
||||
|
||||
if ( x != 0 && WithinCircleBounds( quadrant == 0 ? pointA : pointB, quadrant, loc, start, end, opposite ) )
|
||||
effect( new Point3D( loc.X - x, loc.Y + y, loc.Z ), map );
|
||||
if ( y != 0 && WithinCircleBounds( pointB, 1, loc, start, end, opposite ) )
|
||||
effect( new Point3D( loc.X + x, loc.Y - y, loc.Z ), map );
|
||||
if ( x != 0 && y != 0 && WithinCircleBounds( pointA, 0, loc, start, end, opposite ) )
|
||||
effect( new Point3D( loc.X - x, loc.Y - y, loc.Z ), map );
|
||||
}
|
||||
|
||||
public static bool WithinCircleBounds( Point2D pointLoc, int pointQuadrant, Point3D center, CirclePoint start, CirclePoint end, bool opposite )
|
||||
{
|
||||
if ( start.Angle == 0 && end.Angle == 360 )
|
||||
return true;
|
||||
|
||||
int startX = start.Point.X;
|
||||
int startY = start.Point.Y;
|
||||
int endX = end.Point.X;
|
||||
int endY = end.Point.Y;
|
||||
|
||||
int x = pointLoc.X;
|
||||
int y = pointLoc.Y;
|
||||
|
||||
if ( pointQuadrant < start.Quadrant || pointQuadrant > end.Quadrant )
|
||||
return opposite;
|
||||
|
||||
if ( pointQuadrant > start.Quadrant && pointQuadrant < end.Quadrant )
|
||||
return !opposite;
|
||||
|
||||
bool withinBounds = true;
|
||||
|
||||
if ( start.Quadrant == end.Quadrant )
|
||||
{
|
||||
if ( startX == endX && ( x > startX || y > startY || y < endY ) )
|
||||
withinBounds = false;
|
||||
else if ( startY == endY && ( y < startY || x < startX || x > endX ) )
|
||||
withinBounds = false;
|
||||
else if ( x < startX || x > endX || y > startY || y < endY )
|
||||
withinBounds = false;
|
||||
}
|
||||
else if ( pointQuadrant == start.Quadrant && ( x < startX || y > startY ) )
|
||||
withinBounds = false;
|
||||
else if ( pointQuadrant == end.Quadrant && ( x > endX || y < endY ) )
|
||||
withinBounds = false;
|
||||
|
||||
return opposite ? !withinBounds : withinBounds;
|
||||
}
|
||||
|
||||
public static void Line2D( Point3D start, Point3D end, Map map, DoEffect_Callback effect )
|
||||
{
|
||||
bool steep = Math.Abs( end.Y - start.Y ) > Math.Abs( end.X - start.X );
|
||||
|
||||
int x0 = start.X;
|
||||
int x1 = end.X;
|
||||
int y0 = start.Y;
|
||||
int y1 = end.Y;
|
||||
|
||||
if ( steep )
|
||||
{
|
||||
Swap( ref x0, ref y0 );
|
||||
Swap( ref x1, ref y1 );
|
||||
}
|
||||
|
||||
if ( x0 > x1 )
|
||||
{
|
||||
Swap( ref x0, ref x1 );
|
||||
Swap( ref y0, ref y1 );
|
||||
}
|
||||
|
||||
int deltax = x1 - x0;
|
||||
int deltay = Math.Abs( y1 - y0 );
|
||||
int error = deltax / 2;
|
||||
int ystep = y0 < y1 ? 1 : -1;
|
||||
int y = y0;
|
||||
|
||||
for ( int x = x0; x <= x1; x++ )
|
||||
{
|
||||
if ( steep )
|
||||
effect( new Point3D( y, x, start.Z ), map );
|
||||
else
|
||||
effect( new Point3D( x, y, start.Z ), map );
|
||||
|
||||
error -= deltay;
|
||||
|
||||
if ( error < 0 )
|
||||
{
|
||||
y += ystep;
|
||||
error += deltax;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Scripts/Misc/Gifts/Winter2004/DecorativeTopiary.cs
Normal file
48
Scripts/Misc/Gifts/Winter2004/DecorativeTopiary.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class DecorativeTopiary : Item
|
||||
{
|
||||
[Constructable]
|
||||
public DecorativeTopiary() : base( 0x2378 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public DecorativeTopiary( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
LabelTo( from, 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Scripts/Misc/Gifts/Winter2004/FestiveCactus.cs
Normal file
48
Scripts/Misc/Gifts/Winter2004/FestiveCactus.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FestiveCactus : Item
|
||||
{
|
||||
[Constructable]
|
||||
public FestiveCactus() : base( 0x2376 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public FestiveCactus( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
LabelTo( from, 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Scripts/Misc/Gifts/Winter2004/LightOfTheWinterSolstice.cs
Normal file
104
Scripts/Misc/Gifts/Winter2004/LightOfTheWinterSolstice.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[FlipableAttribute( 0x236E, 0x2371 )]
|
||||
public class LightOfTheWinterSolstice : Item
|
||||
{
|
||||
private static string[] m_StaffNames = new string[]
|
||||
{
|
||||
"Aenima",
|
||||
"Alkiser",
|
||||
"ASayre",
|
||||
"David",
|
||||
"Krrios",
|
||||
"Mark",
|
||||
"Merlin",
|
||||
"Merlix", //LordMerlix
|
||||
"Phantom",
|
||||
"Phenos",
|
||||
"psz",
|
||||
"Ryan",
|
||||
"Quantos",
|
||||
"Outkast", //TheOutkastDev
|
||||
"V", //Admin_V
|
||||
"Zippy"
|
||||
};
|
||||
|
||||
private string m_Dipper;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Dipper{ get{ return m_Dipper; } set{ m_Dipper = value; } }
|
||||
|
||||
[Constructable]
|
||||
public LightOfTheWinterSolstice() : this( m_StaffNames[Utility.Random( m_StaffNames.Length )] )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public LightOfTheWinterSolstice( string dipper ) : base( 0x236E )
|
||||
{
|
||||
m_Dipper = dipper;
|
||||
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
Light = LightType.Circle300;
|
||||
Hue = Utility.RandomDyedHue();
|
||||
}
|
||||
|
||||
public LightOfTheWinterSolstice( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
LabelTo( from, 1070881, m_Dipper ); // Hand Dipped by ~1_name~
|
||||
LabelTo( from, 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070881, m_Dipper ); // Hand Dipped by ~1_name~
|
||||
list.Add( 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
|
||||
writer.Write( (string) m_Dipper );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_Dipper = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_Dipper = m_StaffNames[Utility.Random( m_StaffNames.Length )];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_Dipper != null )
|
||||
m_Dipper = String.Intern( m_Dipper );
|
||||
}
|
||||
}
|
||||
}
|
||||
342
Scripts/Misc/Gifts/Winter2004/Mistletoe.cs
Normal file
342
Scripts/Misc/Gifts/Winter2004/Mistletoe.cs
Normal file
|
|
@ -0,0 +1,342 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MistletoeAddon : Item, IDyable, IAddon
|
||||
{
|
||||
[Constructable]
|
||||
public MistletoeAddon() : this( Utility.RandomDyedHue() )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public MistletoeAddon( int hue ) : base( 0x2375 )
|
||||
{
|
||||
Hue = hue;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public MistletoeAddon( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public bool CouldFit( IPoint3D p, Map map )
|
||||
{
|
||||
if ( !map.CanFit( p.X, p.Y, p.Z, this.ItemData.Height ) )
|
||||
return false;
|
||||
|
||||
if ( this.ItemID == 0x2375 )
|
||||
return BaseAddon.IsWall( p.X, p.Y - 1, p.Z, map ); // North wall
|
||||
else
|
||||
return BaseAddon.IsWall( p.X - 1, p.Y, p.Z, map ); // West wall
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( FixMovingCrate ) );
|
||||
}
|
||||
|
||||
private void FixMovingCrate()
|
||||
{
|
||||
if ( this.Deleted )
|
||||
return;
|
||||
|
||||
if ( this.Movable || this.IsLockedDown )
|
||||
{
|
||||
Item deed = this.Deed;
|
||||
|
||||
if ( this.Parent is Item )
|
||||
{
|
||||
((Item)this.Parent).AddItem( deed );
|
||||
deed.Location = this.Location;
|
||||
}
|
||||
else
|
||||
{
|
||||
deed.MoveToWorld( this.Location, this.Map );
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public Item Deed
|
||||
{
|
||||
get{ return new MistletoeDeed( this.Hue ); }
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( this );
|
||||
|
||||
if ( house != null && house.IsCoOwner( from ) )
|
||||
{
|
||||
if ( from.InRange( this.GetWorldLocation(), 3 ) )
|
||||
{
|
||||
from.CloseGump( typeof( MistletoeAddonGump ) );
|
||||
from.SendGump( new MistletoeAddonGump( from, this ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Dye( Mobile from, DyeTub sender )
|
||||
{
|
||||
if ( Deleted )
|
||||
return false;
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt( this );
|
||||
|
||||
if ( house != null && house.IsCoOwner( from ) )
|
||||
{
|
||||
if ( from.InRange( GetWorldLocation(), 1 ) )
|
||||
{
|
||||
Hue = sender.DyedHue;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 500295 ); // You are too far away to do that.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class MistletoeAddonGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private MistletoeAddon m_Addon;
|
||||
|
||||
public MistletoeAddonGump( Mobile from, MistletoeAddon addon ) : base( 150, 50 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Addon = addon;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddBackground( 0, 0, 220, 170, 0x13BE );
|
||||
AddBackground( 10, 10, 200, 150, 0xBB8 );
|
||||
AddHtmlLocalized( 20, 30, 180, 60, 1062839, false, false ); // Do you wish to re-deed this decoration?
|
||||
AddHtmlLocalized( 55, 100, 160, 25, 1011011, false, false ); // CONTINUE
|
||||
AddButton( 20, 100, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 55, 125, 160, 25, 1011012, false, false ); // CANCEL
|
||||
AddButton( 20, 125, 0xFA5, 0xFA7, 0, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( m_Addon.Deleted )
|
||||
return;
|
||||
|
||||
if ( info.ButtonID == 1 )
|
||||
{
|
||||
if ( m_From.InRange( m_Addon.GetWorldLocation(), 3 ) )
|
||||
{
|
||||
m_From.AddToBackpack( m_Addon.Deed );
|
||||
m_Addon.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendLocalizedMessage( 500295 ); // You are too far away to do that.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Flipable( 0x14F0, 0x14EF )]
|
||||
public class MistletoeDeed : Item
|
||||
{
|
||||
public override int LabelNumber{ get{ return 1070882; } } // Mistletoe Deed
|
||||
|
||||
[Constructable]
|
||||
public MistletoeDeed() : this( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public MistletoeDeed( int hue ) : base( 0x14F0 )
|
||||
{
|
||||
Hue = hue;
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public MistletoeDeed( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
LabelTo( from, 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( IsChildOf( from.Backpack ) )
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( from );
|
||||
|
||||
if ( house != null && house.IsCoOwner( from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062838 ); // Where would you like to place this decoration?
|
||||
from.BeginTarget( -1, true, TargetFlags.None, new TargetStateCallback( Placement_OnTarget ), null );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 502092 ); // You must be in your house to do this.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
|
||||
public void Placement_OnTarget( Mobile from, object targeted, object state )
|
||||
{
|
||||
IPoint3D p = targeted as IPoint3D;
|
||||
|
||||
if ( p == null )
|
||||
return;
|
||||
|
||||
Point3D loc = new Point3D( p );
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt( loc, from.Map, 16 );
|
||||
|
||||
if ( house != null && house.IsCoOwner( from ) )
|
||||
{
|
||||
bool northWall = BaseAddon.IsWall( loc.X, loc.Y - 1, loc.Z, from.Map );
|
||||
bool westWall = BaseAddon.IsWall( loc.X - 1, loc.Y, loc.Z, from.Map );
|
||||
|
||||
if ( northWall && westWall )
|
||||
from.SendGump( new MistletoeDeedGump( from, loc, this ) );
|
||||
else
|
||||
PlaceAddon( from, loc, northWall, westWall );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1042036 ); // That location is not in your house.
|
||||
}
|
||||
}
|
||||
|
||||
private void PlaceAddon( Mobile from, Point3D loc, bool northWall, bool westWall )
|
||||
{
|
||||
if ( Deleted )
|
||||
return;
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt( loc, from.Map, 16 );
|
||||
|
||||
if ( house == null || !house.IsCoOwner( from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042036 ); // That location is not in your house.
|
||||
return;
|
||||
}
|
||||
|
||||
int itemID = 0;
|
||||
|
||||
if ( northWall )
|
||||
itemID = 0x2374;
|
||||
else if ( westWall )
|
||||
itemID = 0x2375;
|
||||
else
|
||||
from.SendLocalizedMessage( 1070883 ); // The mistletoe must be placed next to a wall.
|
||||
|
||||
if ( itemID > 0 )
|
||||
{
|
||||
Item addon = new MistletoeAddon( this.Hue );
|
||||
|
||||
addon.ItemID = itemID;
|
||||
addon.MoveToWorld( loc, from.Map );
|
||||
|
||||
house.Addons.Add( addon );
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
private class MistletoeDeedGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private Point3D m_Loc;
|
||||
private MistletoeDeed m_Deed;
|
||||
|
||||
public MistletoeDeedGump( Mobile from, Point3D loc, MistletoeDeed deed ) : base( 150, 50 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Loc = loc;
|
||||
m_Deed = deed;
|
||||
|
||||
AddBackground( 0, 0, 300, 150, 0xA28 );
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddItem( 90, 30, 0x2375 );
|
||||
AddItem( 180, 30, 0x2374 );
|
||||
AddButton( 50, 35, 0x868, 0x869, 1, GumpButtonType.Reply, 0 );
|
||||
AddButton( 145, 35, 0x868, 0x869, 2, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( m_Deed.Deleted )
|
||||
return;
|
||||
|
||||
switch( info.ButtonID )
|
||||
{
|
||||
case 1:
|
||||
m_Deed.PlaceAddon( m_From, m_Loc, false, true );
|
||||
break;
|
||||
case 2:
|
||||
m_Deed.PlaceAddon( m_From, m_Loc, true, false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
151
Scripts/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs
Normal file
151
Scripts/Misc/Gifts/Winter2004/PileOfGlacialSnow.cs
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PileOfGlacialSnow : Item
|
||||
{
|
||||
[Constructable]
|
||||
public PileOfGlacialSnow() : base( 0x913 )
|
||||
{
|
||||
Hue = 0x480;
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override int LabelNumber{ get{ return 1070874; } } // a Pile of Glacial Snow
|
||||
|
||||
public PileOfGlacialSnow( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if ( version == 0 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
LabelTo( from, 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( !IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042010 ); // You must have the object in your backpack to use it.
|
||||
}
|
||||
else if ( from.Mounted )
|
||||
from.SendLocalizedMessage ( 1010097 ); // You cannot use this while mounted.
|
||||
|
||||
else if ( from.CanBeginAction( typeof( SnowPile ) ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1005575 ); // You carefully pack the snow into a ball...
|
||||
from.Target = new SnowTarget( from, this );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005574 ); // The snow is not ready to be packed yet. Keep trying.
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Mobile m_From;
|
||||
|
||||
public InternalTimer( Mobile from ) : base( TimeSpan.FromSeconds( 5.0 ) )
|
||||
{
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_From.EndAction( typeof( SnowPile ) );
|
||||
}
|
||||
}
|
||||
|
||||
private class SnowTarget : Target
|
||||
{
|
||||
private Mobile m_Thrower;
|
||||
private Item m_Snow;
|
||||
|
||||
public SnowTarget( Mobile thrower, Item snow ) : base ( 10, false, TargetFlags.None )
|
||||
{
|
||||
m_Thrower = thrower;
|
||||
m_Snow = snow;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object target )
|
||||
{
|
||||
if ( target == from )
|
||||
{
|
||||
from.SendLocalizedMessage( 1005576 ); // You can't throw this at yourself.
|
||||
}
|
||||
else if ( target is Mobile )
|
||||
{
|
||||
Mobile targ = (Mobile) target;
|
||||
Container pack = targ.Backpack;
|
||||
|
||||
if ( from.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) || targ.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) )
|
||||
{
|
||||
from.SendMessage( "You may not throw snow here." );
|
||||
}
|
||||
else if ( pack != null && pack.FindItemByType( new Type[]{ typeof( SnowPile ), typeof( PileOfGlacialSnow ) } ) != null )
|
||||
{
|
||||
if ( from.BeginAction( typeof( SnowPile ) ) )
|
||||
{
|
||||
new InternalTimer( from ).Start();
|
||||
|
||||
from.PlaySound( 0x145 );
|
||||
|
||||
from.Animate( 9, 1, 1, true, false, 0 );
|
||||
|
||||
targ.SendLocalizedMessage( 1010572 ); // You have just been hit by a snowball!
|
||||
from.SendLocalizedMessage( 1010573 ); // You throw the snowball and hit the target!
|
||||
|
||||
Effects.SendMovingEffect( from, targ, 0x36E4, 7, 0, false, true, 0x47F, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005574 ); // The snow is not ready to be packed yet. Keep trying.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005577 ); // You can only throw a snowball at something that can throw one back.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005577 ); // You can only throw a snowball at something that can throw one back.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
137
Scripts/Misc/Gifts/Winter2004/SnowPile.cs
Normal file
137
Scripts/Misc/Gifts/Winter2004/SnowPile.cs
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SnowPile : Item
|
||||
{
|
||||
[Constructable]
|
||||
public SnowPile() : base( 0x913 )
|
||||
{
|
||||
Hue = 0x481;
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override int LabelNumber{ get{ return 1005578; } } // a pile of snow
|
||||
|
||||
public SnowPile( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if ( version == 0 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( !IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042010 ); // You must have the object in your backpack to use it.
|
||||
}
|
||||
else if ( from.Mounted )
|
||||
from.SendLocalizedMessage ( 1010097 ); // You cannot use this while mounted.
|
||||
|
||||
else if ( from.CanBeginAction( typeof( SnowPile ) ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1005575 ); // You carefully pack the snow into a ball...
|
||||
from.Target = new SnowTarget( from, this );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005574 ); // The snow is not ready to be packed yet. Keep trying.
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Mobile m_From;
|
||||
|
||||
public InternalTimer( Mobile from ) : base( TimeSpan.FromSeconds( 5.0 ) )
|
||||
{
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_From.EndAction( typeof( SnowPile ) );
|
||||
}
|
||||
}
|
||||
|
||||
private class SnowTarget : Target
|
||||
{
|
||||
private Mobile m_Thrower;
|
||||
private Item m_Snow;
|
||||
|
||||
public SnowTarget( Mobile thrower, Item snow ) : base ( 10, false, TargetFlags.None )
|
||||
{
|
||||
m_Thrower = thrower;
|
||||
m_Snow = snow;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object target )
|
||||
{
|
||||
if ( target == from )
|
||||
{
|
||||
from.SendLocalizedMessage( 1005576 ); // You can't throw this at yourself.
|
||||
}
|
||||
else if ( target is Mobile )
|
||||
{
|
||||
Mobile targ = (Mobile) target;
|
||||
Container pack = targ.Backpack;
|
||||
|
||||
if ( from.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) || targ.Region.IsPartOf( typeof( Engines.ConPVP.SafeZone ) ) )
|
||||
{
|
||||
from.SendMessage( "You may not throw snow here." );
|
||||
}
|
||||
else if ( pack != null && pack.FindItemByType( new Type[]{ typeof( SnowPile ), typeof( PileOfGlacialSnow ) } ) != null )
|
||||
{
|
||||
if ( from.BeginAction( typeof( SnowPile ) ) )
|
||||
{
|
||||
new InternalTimer( from ).Start();
|
||||
|
||||
from.PlaySound( 0x145 );
|
||||
|
||||
from.Animate( 9, 1, 1, true, false, 0 );
|
||||
|
||||
targ.SendLocalizedMessage( 1010572 ); // You have just been hit by a snowball!
|
||||
from.SendLocalizedMessage( 1010573 ); // You throw the snowball and hit the target!
|
||||
|
||||
Effects.SendMovingEffect( from, targ, 0x36E4, 7, 0, false, true, 0x480, 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005574 ); // The snow is not ready to be packed yet. Keep trying.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005577 ); // You can only throw a snowball at something that can throw one back.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005577 ); // You can only throw a snowball at something that can throw one back.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
48
Scripts/Misc/Gifts/Winter2004/SnowyTree.cs
Normal file
48
Scripts/Misc/Gifts/Winter2004/SnowyTree.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SnowyTree : Item
|
||||
{
|
||||
[Constructable]
|
||||
public SnowyTree() : base( 0x2377 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public SnowyTree( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
LabelTo( from, 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1070880 ); // Winter 2004
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Scripts/Misc/Gifts/Winter2004/Winter2004.cs
Normal file
45
Scripts/Misc/Gifts/Winter2004/Winter2004.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class WinterGiftGiver2004 : GiftGiver
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
GiftGiving.Register( new WinterGiftGiver2004() );
|
||||
}
|
||||
|
||||
public override DateTime Start{ get{ return new DateTime( 2004, 12, 24 ); } }
|
||||
public override DateTime Finish{ get{ return new DateTime( 2005, 1, 1 ); } }
|
||||
|
||||
public override void GiveGift( Mobile mob )
|
||||
{
|
||||
GiftBox box = new GiftBox();
|
||||
|
||||
box.DropItem( new MistletoeDeed() );
|
||||
box.DropItem( new PileOfGlacialSnow() );
|
||||
box.DropItem( new LightOfTheWinterSolstice() );
|
||||
|
||||
int random = Utility.Random( 100 );
|
||||
|
||||
if ( random < 60 )
|
||||
box.DropItem( new DecorativeTopiary() );
|
||||
else if ( random < 84 )
|
||||
box.DropItem( new FestiveCactus() );
|
||||
else
|
||||
box.DropItem( new SnowyTree() );
|
||||
|
||||
switch ( GiveGift( mob, box ) )
|
||||
{
|
||||
case GiftResult.Backpack:
|
||||
mob.SendMessage( 0x482, "Happy Holidays from the team! Gift items have been placed in your backpack." );
|
||||
break;
|
||||
case GiftResult.BankBox:
|
||||
mob.SendMessage( 0x482, "Happy Holidays from the team! Gift items have been placed in your bank box." );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1875
Scripts/Misc/Guild.cs
Normal file
1875
Scripts/Misc/Guild.cs
Normal file
File diff suppressed because it is too large
Load diff
189
Scripts/Misc/HardwareInfo.cs
Normal file
189
Scripts/Misc/HardwareInfo.cs
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
using Server.Accounting;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class HardwareInfo
|
||||
{
|
||||
private int m_InstanceID;
|
||||
private int m_OSMajor, m_OSMinor, m_OSRevision;
|
||||
private int m_CpuManufacturer, m_CpuFamily, m_CpuModel, m_CpuClockSpeed, m_CpuQuantity;
|
||||
private int m_PhysicalMemory;
|
||||
private int m_ScreenWidth, m_ScreenHeight, m_ScreenDepth;
|
||||
private int m_DXMajor, m_DXMinor;
|
||||
private int m_VCVendorID, m_VCDeviceID, m_VCMemory;
|
||||
private int m_Distribution, m_ClientsRunning, m_ClientsInstalled, m_PartialInstalled;
|
||||
private string m_VCDescription;
|
||||
private string m_Language;
|
||||
private string m_Unknown;
|
||||
private DateTime m_TimeReceived;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int CpuModel{ get{ return m_CpuModel; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int CpuClockSpeed{ get{ return m_CpuClockSpeed; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int CpuQuantity{ get{ return m_CpuQuantity; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int OSMajor{ get{ return m_OSMajor; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int OSMinor{ get{ return m_OSMinor; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int OSRevision{ get{ return m_OSRevision; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int InstanceID{ get{ return m_InstanceID; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ScreenWidth{ get{ return m_ScreenWidth; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ScreenHeight{ get{ return m_ScreenHeight; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ScreenDepth{ get{ return m_ScreenDepth; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int PhysicalMemory{ get{ return m_PhysicalMemory; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int CpuManufacturer{ get{ return m_CpuManufacturer; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int CpuFamily{ get{ return m_CpuFamily; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int VCVendorID{ get{ return m_VCVendorID; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int VCDeviceID{ get{ return m_VCDeviceID; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int VCMemory{ get{ return m_VCMemory; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int DXMajor{ get{ return m_DXMajor; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int DXMinor{ get{ return m_DXMinor; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string VCDescription{ get{ return m_VCDescription; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Language{ get{ return m_Language; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Distribution{ get{ return m_Distribution; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ClientsRunning{ get{ return m_ClientsRunning; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ClientsInstalled{ get{ return m_ClientsInstalled; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int PartialInstalled{ get{ return m_PartialInstalled; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Unknown{ get{ return m_Unknown; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime TimeReceived { get { return m_TimeReceived; } }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
PacketHandlers.Register( 0xD9, 0x10C, false, new OnPacketReceive( OnReceive ) );
|
||||
|
||||
CommandSystem.Register( "HWInfo", AccessLevel.GameMaster, new CommandEventHandler( HWInfo_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "HWInfo" )]
|
||||
[Description( "Displays information about a targeted player's hardware." )]
|
||||
public static void HWInfo_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
e.Mobile.BeginTarget( -1, false, TargetFlags.None, new TargetCallback( HWInfo_OnTarget ) );
|
||||
e.Mobile.SendMessage( "Target a player to view their hardware information." );
|
||||
}
|
||||
|
||||
public static void HWInfo_OnTarget( Mobile from, object obj )
|
||||
{
|
||||
if ( obj is Mobile && ((Mobile)obj).Player )
|
||||
{
|
||||
Mobile m = (Mobile)obj;
|
||||
Account acct = m.Account as Account;
|
||||
|
||||
if ( acct != null )
|
||||
{
|
||||
HardwareInfo hwInfo = acct.HardwareInfo;
|
||||
|
||||
if ( hwInfo != null )
|
||||
CommandLogging.WriteLine( from, "{0} {1} viewing hardware info of {2}", from.AccessLevel, CommandLogging.Format( from ), CommandLogging.Format( m ) );
|
||||
|
||||
if ( hwInfo != null )
|
||||
from.SendGump( new Gumps.PropertiesGump( from, hwInfo ) );
|
||||
else
|
||||
from.SendMessage( "No hardware information for that account was found." );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "No account has been attached to that player." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.BeginTarget( -1, false, TargetFlags.None, new TargetCallback( HWInfo_OnTarget ) );
|
||||
from.SendMessage( "That is not a player. Try again." );
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnReceive( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
pvSrc.ReadByte(); // 1: <4.0.1a, 2>=4.0.1a
|
||||
|
||||
HardwareInfo info = new HardwareInfo();
|
||||
|
||||
info.m_InstanceID = pvSrc.ReadInt32();
|
||||
info.m_OSMajor = pvSrc.ReadInt32();
|
||||
info.m_OSMinor = pvSrc.ReadInt32();
|
||||
info.m_OSRevision = pvSrc.ReadInt32();
|
||||
info.m_CpuManufacturer = pvSrc.ReadByte();
|
||||
info.m_CpuFamily = pvSrc.ReadInt32();
|
||||
info.m_CpuModel = pvSrc.ReadInt32();
|
||||
info.m_CpuClockSpeed = pvSrc.ReadInt32();
|
||||
info.m_CpuQuantity = pvSrc.ReadByte();
|
||||
info.m_PhysicalMemory = pvSrc.ReadInt32();
|
||||
info.m_ScreenWidth = pvSrc.ReadInt32();
|
||||
info.m_ScreenHeight = pvSrc.ReadInt32();
|
||||
info.m_ScreenDepth = pvSrc.ReadInt32();
|
||||
info.m_DXMajor = pvSrc.ReadInt16();
|
||||
info.m_DXMinor = pvSrc.ReadInt16();
|
||||
info.m_VCDescription = pvSrc.ReadUnicodeStringLESafe( 64 );
|
||||
info.m_VCVendorID = pvSrc.ReadInt32();
|
||||
info.m_VCDeviceID = pvSrc.ReadInt32();
|
||||
info.m_VCMemory = pvSrc.ReadInt32();
|
||||
info.m_Distribution = pvSrc.ReadByte();
|
||||
info.m_ClientsRunning = pvSrc.ReadByte();
|
||||
info.m_ClientsInstalled = pvSrc.ReadByte();
|
||||
info.m_PartialInstalled = pvSrc.ReadByte();
|
||||
info.m_Language = pvSrc.ReadUnicodeStringLESafe( 4 );
|
||||
info.m_Unknown = pvSrc.ReadStringSafe( 64 );
|
||||
|
||||
info.m_TimeReceived = DateTime.UtcNow;
|
||||
|
||||
Account acct = state.Account as Account;
|
||||
|
||||
if ( acct != null )
|
||||
acct.HardwareInfo = info;
|
||||
}
|
||||
}
|
||||
}
|
||||
595
Scripts/Misc/InhumanSpeech.cs
Normal file
595
Scripts/Misc/InhumanSpeech.cs
Normal file
|
|
@ -0,0 +1,595 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
[Flags]
|
||||
public enum IHSFlags
|
||||
{
|
||||
None = 0x00,
|
||||
OnDamaged = 0x01,
|
||||
OnDeath = 0x02,
|
||||
OnMovement = 0x04,
|
||||
OnSpeech = 0x08,
|
||||
All = OnDamaged | OnDeath | OnMovement
|
||||
} // NOTE: To enable monster conversations, add " | OnSpeech" to the "All" line
|
||||
|
||||
public class InhumanSpeech
|
||||
{
|
||||
private static InhumanSpeech m_RatmanSpeech;
|
||||
|
||||
public static InhumanSpeech Ratman
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_RatmanSpeech == null )
|
||||
{
|
||||
m_RatmanSpeech = new InhumanSpeech();
|
||||
|
||||
m_RatmanSpeech.Hue = 149;
|
||||
m_RatmanSpeech.Sound = 438;
|
||||
|
||||
m_RatmanSpeech.Flags = IHSFlags.All;
|
||||
|
||||
m_RatmanSpeech.Keywords = new string[]
|
||||
{
|
||||
"meat", "gold", "kill", "killing", "slay",
|
||||
"sword", "axe", "spell", "magic", "spells",
|
||||
"swords", "axes", "mace", "maces", "monster",
|
||||
"monsters", "food", "run", "escape", "away",
|
||||
"help", "dead", "die", "dying", "lose",
|
||||
"losing", "life", "lives", "death", "ghost",
|
||||
"ghosts", "british", "blackthorn", "guild",
|
||||
"guilds", "dragon", "dragons", "game", "games",
|
||||
"ultima", "silly", "stupid", "dumb", "idiot",
|
||||
"idiots", "cheesy", "cheezy", "crazy", "dork",
|
||||
"jerk", "fool", "foolish", "ugly", "insult", "scum"
|
||||
};
|
||||
|
||||
m_RatmanSpeech.Responses = new string[]
|
||||
{
|
||||
"meat", "kill", "pound", "crush", "yum yum",
|
||||
"crunch", "destroy", "murder", "eat", "munch",
|
||||
"massacre", "food", "monster", "evil", "run",
|
||||
"die", "lose", "dumb", "idiot", "fool", "crazy",
|
||||
"dinner", "lunch", "breakfast", "fight", "battle",
|
||||
"doomed", "rip apart", "tear apart", "smash",
|
||||
"edible?", "shred", "disembowel", "ugly", "smelly",
|
||||
"stupid", "hideous", "smell", "tasty", "invader",
|
||||
"attack", "raid", "plunder", "pillage", "treasure",
|
||||
"loser", "lose", "scum"
|
||||
};
|
||||
|
||||
m_RatmanSpeech.Syllables = new string[]
|
||||
{
|
||||
"skrit",
|
||||
|
||||
"ch", "ch",
|
||||
"it", "ti", "it", "ti",
|
||||
|
||||
"ak", "ek", "ik", "ok", "uk", "yk",
|
||||
"ka", "ke", "ki", "ko", "ku", "ky",
|
||||
"at", "et", "it", "ot", "ut", "yt",
|
||||
|
||||
"cha", "che", "chi", "cho", "chu", "chy",
|
||||
"ach", "ech", "ich", "och", "uch", "ych",
|
||||
"att", "ett", "itt", "ott", "utt", "ytt",
|
||||
"tat", "tet", "tit", "tot", "tut", "tyt",
|
||||
"tta", "tte", "tti", "tto", "ttu", "tty",
|
||||
"tak", "tek", "tik", "tok", "tuk", "tyk",
|
||||
"ack", "eck", "ick", "ock", "uck", "yck",
|
||||
"cka", "cke", "cki", "cko", "cku", "cky",
|
||||
"rak", "rek", "rik", "rok", "ruk", "ryk",
|
||||
|
||||
"tcha", "tche", "tchi", "tcho", "tchu", "tchy",
|
||||
"rach", "rech", "rich", "roch", "ruch", "rych",
|
||||
"rrap", "rrep", "rrip", "rrop", "rrup", "rryp",
|
||||
"ccka", "ccke", "ccki", "ccko", "ccku", "ccky"
|
||||
};
|
||||
}
|
||||
|
||||
return m_RatmanSpeech;
|
||||
}
|
||||
}
|
||||
|
||||
private static InhumanSpeech m_OrcSpeech;
|
||||
|
||||
public static InhumanSpeech Orc
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_OrcSpeech == null )
|
||||
{
|
||||
m_OrcSpeech = new InhumanSpeech();
|
||||
|
||||
m_OrcSpeech.Hue = 34;
|
||||
m_OrcSpeech.Sound = 432;
|
||||
|
||||
m_OrcSpeech.Flags = IHSFlags.All;
|
||||
|
||||
m_OrcSpeech.Keywords = new string[]
|
||||
{
|
||||
"meat", "gold", "kill", "killing", "slay",
|
||||
"sword", "axe", "spell", "magic", "spells",
|
||||
"swords", "axes", "mace", "maces", "monster",
|
||||
"monsters", "food", "run", "escape", "away",
|
||||
"help", "dead", "die", "dying", "lose",
|
||||
"losing", "life", "lives", "death", "ghost",
|
||||
"ghosts", "british", "blackthorn", "guild",
|
||||
"guilds", "dragon", "dragons", "game", "games",
|
||||
"ultima", "silly", "stupid", "dumb", "idiot",
|
||||
"idiots", "cheesy", "cheezy", "crazy", "dork",
|
||||
"jerk", "fool", "foolish", "ugly", "insult", "scum"
|
||||
};
|
||||
|
||||
m_OrcSpeech.Responses = new string[]
|
||||
{
|
||||
"meat", "kill", "pound", "crush", "yum yum",
|
||||
"crunch", "destroy", "murder", "eat", "munch",
|
||||
"massacre", "food", "monster", "evil", "run",
|
||||
"die", "lose", "dumb", "idiot", "fool", "crazy",
|
||||
"dinner", "lunch", "breakfast", "fight", "battle",
|
||||
"doomed", "rip apart", "tear apart", "smash",
|
||||
"edible?", "shred", "disembowel", "ugly", "smelly",
|
||||
"stupid", "hideous", "smell", "tasty", "invader",
|
||||
"attack", "raid", "plunder", "pillage", "treasure",
|
||||
"loser", "lose", "scum"
|
||||
};
|
||||
|
||||
m_OrcSpeech.Syllables = new string[]
|
||||
{
|
||||
"bu", "du", "fu", "ju", "gu",
|
||||
"ulg", "gug", "gub", "gur", "oog",
|
||||
"gub", "log", "ru", "stu", "glu",
|
||||
"ug", "ud", "og", "log", "ro", "flu",
|
||||
"bo", "duf", "fun", "nog", "dun", "bog",
|
||||
"dug", "gh", "ghu", "gho", "nug", "ig",
|
||||
"igh", "ihg", "luh", "duh", "bug", "dug",
|
||||
"dru", "urd", "gurt", "grut", "grunt",
|
||||
"snarf", "urgle", "igg", "glu", "glug",
|
||||
"foo", "bar", "baz", "ghat", "ab", "ad",
|
||||
"gugh", "guk", "ag", "alm", "thu", "log",
|
||||
"bilge", "augh", "gha", "gig", "goth",
|
||||
"zug", "pig", "auh", "gan", "azh", "bag",
|
||||
"hig", "oth", "dagh", "gulg", "ugh", "ba",
|
||||
"bid", "gug", "bug", "rug", "hat", "brui",
|
||||
"gagh", "buad", "buil", "buim", "bum",
|
||||
"hug", "hug", "buo", "ma", "buor", "ghed",
|
||||
"buu", "ca", "guk", "clog", "thurg", "car",
|
||||
"cro", "thu", "da", "cuk", "gil", "cur", "dak",
|
||||
"dar", "deak", "der", "dil", "dit", "at", "ag",
|
||||
"dor", "gar", "dre", "tk", "dri", "gka", "rim",
|
||||
"eag", "egg", "ha", "rod", "eg", "lat", "eichel",
|
||||
"ek", "ep", "ka", "it", "ut", "ewk", "ba", "dagh",
|
||||
"faugh", "foz", "fog", "fid", "fruk", "gag", "fub",
|
||||
"fud", "fur", "bog", "fup", "hagh", "gaa", "kt",
|
||||
"rekk", "lub", "lug", "tug", "gna", "urg", "l",
|
||||
"gno", "gnu", "gol", "gom", "kug", "ukk", "jak",
|
||||
"jek", "rukk", "jja", "akt", "nuk", "hok", "hrol",
|
||||
"olm", "natz", "i", "i", "o", "u", "ikk", "ign",
|
||||
"juk", "kh", "kgh", "ka", "hig", "ke", "ki", "klap",
|
||||
"klu", "knod", "kod", "knu", "thnu", "krug", "nug",
|
||||
"nar", "nag", "neg", "neh", "oag", "ob", "ogh", "oh",
|
||||
"om", "dud", "oo", "pa", "hrak", "qo", "quad", "quil",
|
||||
"ghig", "rur", "sag", "sah", "sg"
|
||||
};
|
||||
}
|
||||
|
||||
return m_OrcSpeech;
|
||||
}
|
||||
}
|
||||
|
||||
private static InhumanSpeech m_LizardmanSpeech;
|
||||
|
||||
public static InhumanSpeech Lizardman
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_LizardmanSpeech == null )
|
||||
{
|
||||
m_LizardmanSpeech = new InhumanSpeech();
|
||||
|
||||
m_LizardmanSpeech.Hue = 58;
|
||||
m_LizardmanSpeech.Sound = 418;
|
||||
|
||||
m_LizardmanSpeech.Flags = IHSFlags.All;
|
||||
|
||||
m_LizardmanSpeech.Keywords = new string[]
|
||||
{
|
||||
"meat", "gold", "kill", "killing", "slay",
|
||||
"sword", "axe", "spell", "magic", "spells",
|
||||
"swords", "axes", "mace", "maces", "monster",
|
||||
"monsters", "food", "run", "escape", "away",
|
||||
"help", "dead", "die", "dying", "lose",
|
||||
"losing", "life", "lives", "death", "ghost",
|
||||
"ghosts", "british", "blackthorn", "guild",
|
||||
"guilds", "dragon", "dragons", "game", "games",
|
||||
"ultima", "silly", "stupid", "dumb", "idiot",
|
||||
"idiots", "cheesy", "cheezy", "crazy", "dork",
|
||||
"jerk", "fool", "foolish", "ugly", "insult", "scum"
|
||||
};
|
||||
|
||||
m_LizardmanSpeech.Responses = new string[]
|
||||
{
|
||||
"meat", "kill", "pound", "crush", "yum yum",
|
||||
"crunch", "destroy", "murder", "eat", "munch",
|
||||
"massacre", "food", "monster", "evil", "run",
|
||||
"die", "lose", "dumb", "idiot", "fool", "crazy",
|
||||
"dinner", "lunch", "breakfast", "fight", "battle",
|
||||
"doomed", "rip apart", "tear apart", "smash",
|
||||
"edible?", "shred", "disembowel", "ugly", "smelly",
|
||||
"stupid", "hideous", "smell", "tasty", "invader",
|
||||
"attack", "raid", "plunder", "pillage", "treasure",
|
||||
"loser", "lose", "scum"
|
||||
};
|
||||
|
||||
m_LizardmanSpeech.Syllables = new string[]
|
||||
{
|
||||
"ss", "sth", "iss", "is", "ith", "kth",
|
||||
"sith", "this", "its", "sit", "tis", "tsi",
|
||||
"ssi", "sil", "lis", "sis", "lil", "thil",
|
||||
"lith", "sthi", "lish", "shi", "shash", "sal",
|
||||
"miss", "ra", "tha", "thes", "ses", "sas", "las",
|
||||
"les", "sath", "sia", "ais", "isa", "asi", "asth",
|
||||
"stha", "sthi", "isth", "asa", "ath", "tha", "als",
|
||||
"sla", "thth", "ci", "ce", "cy", "yss", "ys", "yth",
|
||||
"syth", "thys", "yts", "syt", "tys", "tsy", "ssy",
|
||||
"syl", "lys", "sys", "lyl", "thyl", "lyth", "sthy",
|
||||
"lysh", "shy", "myss", "ysa", "sthy", "ysth"
|
||||
};
|
||||
}
|
||||
|
||||
return m_LizardmanSpeech;
|
||||
}
|
||||
}
|
||||
|
||||
private static InhumanSpeech m_WispSpeech;
|
||||
|
||||
public static InhumanSpeech Wisp
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_WispSpeech == null )
|
||||
{
|
||||
m_WispSpeech = new InhumanSpeech();
|
||||
|
||||
m_WispSpeech.Hue = 89;
|
||||
m_WispSpeech.Sound = 466;
|
||||
|
||||
m_WispSpeech.Flags = IHSFlags.OnMovement;
|
||||
|
||||
m_WispSpeech.Syllables = new string[]
|
||||
{
|
||||
"b", "c", "d", "f", "g", "h", "i",
|
||||
"j", "k", "l", "m", "n", "p", "r",
|
||||
"s", "t", "v", "w", "x", "z", "c",
|
||||
"c", "x", "x", "x", "x", "x", "y",
|
||||
"y", "y", "y", "t", "t", "k", "k",
|
||||
"l", "l", "m", "m", "m", "m", "z"
|
||||
};
|
||||
}
|
||||
|
||||
return m_WispSpeech;
|
||||
}
|
||||
}
|
||||
|
||||
private string[] m_Syllables;
|
||||
private string[] m_Keywords;
|
||||
private string[] m_Responses;
|
||||
|
||||
private Dictionary<string, string> m_KeywordHash;
|
||||
|
||||
private int m_Hue;
|
||||
private int m_Sound;
|
||||
|
||||
private IHSFlags m_Flags;
|
||||
|
||||
public string[] Syllables
|
||||
{
|
||||
get{ return m_Syllables; }
|
||||
set{ m_Syllables = value; }
|
||||
}
|
||||
|
||||
public string[] Keywords
|
||||
{
|
||||
get{ return m_Keywords; }
|
||||
set
|
||||
{
|
||||
m_Keywords = value;
|
||||
m_KeywordHash = new Dictionary<string, string>( m_Keywords.Length, StringComparer.OrdinalIgnoreCase );
|
||||
for ( int i = 0; i < m_Keywords.Length; ++i )
|
||||
m_KeywordHash[m_Keywords[i]] = m_Keywords[i];
|
||||
}
|
||||
}
|
||||
|
||||
public string[] Responses
|
||||
{
|
||||
get{ return m_Responses; }
|
||||
set{ m_Responses = value; }
|
||||
}
|
||||
|
||||
public int Hue
|
||||
{
|
||||
get{ return m_Hue; }
|
||||
set{ m_Hue = value; }
|
||||
}
|
||||
|
||||
public int Sound
|
||||
{
|
||||
get{ return m_Sound; }
|
||||
set{ m_Sound = value; }
|
||||
}
|
||||
|
||||
public IHSFlags Flags
|
||||
{
|
||||
get{ return m_Flags; }
|
||||
set{ m_Flags = value; }
|
||||
}
|
||||
|
||||
public string GetRandomSyllable()
|
||||
{
|
||||
return m_Syllables[Utility.Random( m_Syllables.Length )];
|
||||
}
|
||||
|
||||
public string ConstructWord( int syllableCount )
|
||||
{
|
||||
string[] syllables = new string[syllableCount];
|
||||
|
||||
for ( int i = 0; i < syllableCount; ++i )
|
||||
syllables[i] = GetRandomSyllable();
|
||||
|
||||
return String.Concat( syllables );
|
||||
}
|
||||
|
||||
public string ConstructSentance( int wordCount )
|
||||
{
|
||||
StringBuilder sentance = new StringBuilder();
|
||||
|
||||
bool needUpperCase = true;
|
||||
|
||||
for ( int i = 0; i < wordCount; ++i )
|
||||
{
|
||||
if ( i > 0 ) // not first word )
|
||||
{
|
||||
int random = Utility.RandomMinMax( 1, 15 );
|
||||
|
||||
if ( random < 11 )
|
||||
{
|
||||
sentance.Append( ' ' );
|
||||
}
|
||||
else
|
||||
{
|
||||
needUpperCase = true;
|
||||
|
||||
if ( random > 13 )
|
||||
sentance.Append( "! " );
|
||||
else
|
||||
sentance.Append( ". " );
|
||||
}
|
||||
}
|
||||
|
||||
int syllableCount;
|
||||
|
||||
if ( 30 > Utility.Random( 100 ) )
|
||||
syllableCount = Utility.Random( 1, 5 );
|
||||
else
|
||||
syllableCount = Utility.Random( 1, 3 );
|
||||
|
||||
string word = ConstructWord( syllableCount );
|
||||
|
||||
sentance.Append( word );
|
||||
|
||||
if ( needUpperCase )
|
||||
sentance.Replace( word[0], Char.ToUpper( word[0] ), sentance.Length - word.Length, 1 );
|
||||
|
||||
needUpperCase = false;
|
||||
}
|
||||
|
||||
if ( Utility.RandomMinMax( 1, 5 ) == 1 )
|
||||
sentance.Append( '!' );
|
||||
else
|
||||
sentance.Append( '.' );
|
||||
|
||||
return sentance.ToString();
|
||||
}
|
||||
|
||||
public void SayRandomTranslate( Mobile mob, params string[] sentancesInEnglish )
|
||||
{
|
||||
SaySentance( mob, Utility.RandomMinMax( 2, 3 ) );
|
||||
mob.Say( sentancesInEnglish[Utility.Random( sentancesInEnglish.Length )] );
|
||||
}
|
||||
|
||||
private string GetRandomResponseWord( List<string> keywordsFound )
|
||||
{
|
||||
int random = Utility.Random( keywordsFound.Count + m_Responses.Length );
|
||||
|
||||
if ( random < keywordsFound.Count )
|
||||
return keywordsFound[random];
|
||||
|
||||
return m_Responses[random - keywordsFound.Count];
|
||||
}
|
||||
|
||||
public bool OnSpeech( Mobile mob, Mobile speaker, string text )
|
||||
{
|
||||
if ( (m_Flags & IHSFlags.OnSpeech) == 0 || m_Keywords == null || m_Responses == null || m_KeywordHash == null )
|
||||
return false; // not enabled
|
||||
|
||||
if ( !speaker.Alive )
|
||||
return false;
|
||||
|
||||
if ( !speaker.InRange( mob, 3 ) )
|
||||
return false;
|
||||
|
||||
if ( (speaker.Direction & Direction.Mask) != speaker.GetDirectionTo( mob ) )
|
||||
return false;
|
||||
|
||||
if ( (mob.Direction & Direction.Mask) != mob.GetDirectionTo( speaker ) )
|
||||
return false;
|
||||
|
||||
string[] split = text.Split( ' ' );
|
||||
List<string> keywordsFound = new List<string>();
|
||||
|
||||
for ( int i = 0; i < split.Length; ++i )
|
||||
{
|
||||
string keyword;
|
||||
m_KeywordHash.TryGetValue( split[i], out keyword );
|
||||
|
||||
if ( keyword != null )
|
||||
keywordsFound.Add( keyword );
|
||||
}
|
||||
|
||||
if ( keywordsFound.Count > 0 )
|
||||
{
|
||||
string responseWord;
|
||||
|
||||
if ( Utility.RandomBool() )
|
||||
responseWord = GetRandomResponseWord( keywordsFound );
|
||||
else
|
||||
responseWord = keywordsFound[Utility.Random( keywordsFound.Count )];
|
||||
|
||||
string secondResponseWord = GetRandomResponseWord( keywordsFound );
|
||||
|
||||
StringBuilder response = new StringBuilder();
|
||||
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
{
|
||||
response.Append( "Me " ).Append( responseWord ).Append( '?' );
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
response.Append( responseWord ).Append( " thee!" );
|
||||
response.Replace( responseWord[0], Char.ToUpper( responseWord[0] ), 0, 1 );
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
response.Append( responseWord ).Append( '?' );
|
||||
response.Replace( responseWord[0], Char.ToUpper( responseWord[0] ), 0, 1 );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
response.Append( responseWord ).Append( "! " ).Append( secondResponseWord ).Append( '.' );
|
||||
response.Replace( responseWord[0], Char.ToUpper( responseWord[0] ), 0, 1 );
|
||||
response.Replace( secondResponseWord[0], Char.ToUpper( secondResponseWord[0] ), responseWord.Length + 2, 1 );
|
||||
break;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
response.Append( responseWord ).Append( '.' );
|
||||
response.Replace( responseWord[0], Char.ToUpper( responseWord[0] ), 0, 1 );
|
||||
break;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
response.Append( responseWord ).Append( "? " ).Append( secondResponseWord ).Append( '.' );
|
||||
response.Replace( responseWord[0], Char.ToUpper( responseWord[0] ), 0, 1 );
|
||||
response.Replace( secondResponseWord[0], Char.ToUpper( secondResponseWord[0] ), responseWord.Length + 2, 1 );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int maxWords = (split.Length / 2) + 1;
|
||||
|
||||
if ( maxWords < 2 )
|
||||
maxWords = 2;
|
||||
else if ( maxWords > 6 )
|
||||
maxWords = 6;
|
||||
|
||||
SaySentance( mob, Utility.RandomMinMax( 2, maxWords ) );
|
||||
mob.Say( response.ToString() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnDeath( Mobile mob )
|
||||
{
|
||||
if ( (m_Flags & IHSFlags.OnDeath) == 0 )
|
||||
return; // not enabled
|
||||
|
||||
if ( 90 > Utility.Random( 100 ) )
|
||||
return; // 90% chance to do nothing; 10% chance to talk
|
||||
|
||||
SayRandomTranslate( mob,
|
||||
"Revenge!",
|
||||
"NOOooo!",
|
||||
"I... I...",
|
||||
"Me no die!",
|
||||
"Me die!",
|
||||
"Must... not die...",
|
||||
"Oooh, me hurt...",
|
||||
"Me dying?" );
|
||||
}
|
||||
|
||||
public void OnMovement( Mobile mob, Mobile mover, Point3D oldLocation )
|
||||
{
|
||||
if ( (m_Flags & IHSFlags.OnMovement) == 0 )
|
||||
return; // not enabled
|
||||
|
||||
if ( !mover.Player || (mover.Hidden && mover.AccessLevel > AccessLevel.Player) )
|
||||
return;
|
||||
|
||||
if ( !mob.InRange( mover, 5 ) || mob.InRange( oldLocation, 5 ) )
|
||||
return; // only talk when they enter 5 tile range
|
||||
|
||||
if ( 90 > Utility.Random( 100 ) )
|
||||
return; // 90% chance to do nothing; 10% chance to talk
|
||||
|
||||
SaySentance( mob, 6 );
|
||||
}
|
||||
|
||||
public void OnDamage( Mobile mob, int amount )
|
||||
{
|
||||
if ( (m_Flags & IHSFlags.OnDamaged) == 0 )
|
||||
return; // not enabled
|
||||
|
||||
if ( 90 > Utility.Random( 100 ) )
|
||||
return; // 90% chance to do nothing; 10% chance to talk
|
||||
|
||||
if ( amount < 5 )
|
||||
{
|
||||
SayRandomTranslate( mob,
|
||||
"Ouch!",
|
||||
"Me not hurt bad!",
|
||||
"Thou fight bad.",
|
||||
"Thy blows soft!",
|
||||
"You bad with weapon!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
SayRandomTranslate( mob,
|
||||
"Ouch! Me hurt!",
|
||||
"No, kill me not!",
|
||||
"Me hurt!",
|
||||
"Away with thee!",
|
||||
"Oof! That hurt!",
|
||||
"Aaah! That hurt...",
|
||||
"Good blow!" );
|
||||
}
|
||||
}
|
||||
|
||||
public void OnConstruct( Mobile mob )
|
||||
{
|
||||
mob.SpeechHue = m_Hue;
|
||||
}
|
||||
|
||||
public void SaySentance( Mobile mob, int wordCount )
|
||||
{
|
||||
mob.Say( ConstructSentance( wordCount ) );
|
||||
mob.PlaySound( m_Sound );
|
||||
}
|
||||
|
||||
public InhumanSpeech()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
60
Scripts/Misc/Keywords.cs
Normal file
60
Scripts/Misc/Keywords.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Guilds;
|
||||
using Server.Mobiles;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Keywords
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
// Register our speech handler
|
||||
EventSink.Speech += new SpeechEventHandler( EventSink_Speech );
|
||||
}
|
||||
|
||||
public static void EventSink_Speech( SpeechEventArgs args )
|
||||
{
|
||||
Mobile from = args.Mobile;
|
||||
int[] keywords = args.Keywords;
|
||||
|
||||
for ( int i = 0; i < keywords.Length; ++i )
|
||||
{
|
||||
switch ( keywords[i] )
|
||||
{
|
||||
case 0x002A: // *i resign from my guild*
|
||||
{
|
||||
if ( from.Guild != null )
|
||||
((Guild)from.Guild).RemoveMember( from );
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0032: // *i must consider my sins*
|
||||
{
|
||||
if( !Core.SE )
|
||||
{
|
||||
from.SendMessage( "Short Term Murders : {0}", from.ShortTermMurders );
|
||||
from.SendMessage( "Long Term Murders : {0}", from.Kills );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( 0x3B2, "Short Term Murders: {0} Long Term Murders: {1}", from.ShortTermMurders, from.Kills );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 0x0035: // i renounce my young player status*
|
||||
{
|
||||
if ( from is PlayerMobile && ((PlayerMobile)from).Young && !from.HasGump( typeof( RenounceYoungGump ) ) )
|
||||
{
|
||||
from.SendGump( new RenounceYoungGump() );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
375
Scripts/Misc/LanguageStatistics.cs
Normal file
375
Scripts/Misc/LanguageStatistics.cs
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Server;
|
||||
using Server.Accounting;
|
||||
using Server.Commands;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
/**
|
||||
* This file requires to be saved in a Unicode
|
||||
* compatible format.
|
||||
*
|
||||
* Warning: if you change String.Format methods,
|
||||
* please note that the following character
|
||||
* is suggested before any left-to-right text
|
||||
* in order to prevent undesired formatting
|
||||
* resulting from mixing LR and RL text:
|
||||
*
|
||||
* Use this one if you need to force RL:
|
||||
*
|
||||
* If you do not see the above chars, please
|
||||
* enable showing of unicode control chars
|
||||
**/
|
||||
|
||||
public class LanguageStatistics
|
||||
{
|
||||
struct InternationalCode
|
||||
{
|
||||
string m_Code;
|
||||
string m_Language;
|
||||
string m_Country;
|
||||
string m_Language_LocalName;
|
||||
string m_Country_LocalName;
|
||||
bool m_HasLocalInfo;
|
||||
|
||||
public string Code{ get{ return m_Code; } }
|
||||
public string Language{ get{ return m_Language; } }
|
||||
public string Country{ get{ return m_Country; } }
|
||||
public string Language_LocalName{ get{ return m_Language_LocalName; } }
|
||||
public string Country_LocalName{ get{ return m_Country_LocalName; } }
|
||||
|
||||
public InternationalCode( string code, string language, string country ) : this( code, language, country, null, null )
|
||||
{
|
||||
m_HasLocalInfo = false;
|
||||
}
|
||||
|
||||
public InternationalCode( string code, string language, string country, string language_localname, string country_localname )
|
||||
{
|
||||
m_Code = code;
|
||||
m_Language = language;
|
||||
m_Country = country;
|
||||
m_Language_LocalName = language_localname;
|
||||
m_Country_LocalName = country_localname;
|
||||
m_HasLocalInfo = true;
|
||||
}
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
string s;
|
||||
|
||||
if ( m_HasLocalInfo )
|
||||
{
|
||||
s = String.Format( "{0} - {1}", DefaultLocalNames ? m_Language_LocalName : m_Language, DefaultLocalNames ? m_Country_LocalName : m_Country );
|
||||
|
||||
if ( ShowAlternatives )
|
||||
s += String.Format( " 【{0} - {1}】", DefaultLocalNames ? m_Language : m_Language_LocalName, DefaultLocalNames ? m_Country : m_Country_LocalName );
|
||||
}
|
||||
else
|
||||
{
|
||||
s = String.Format( "{0} - {1}", m_Language, m_Country );
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
private static InternationalCode[] InternationalCodes =
|
||||
{
|
||||
new InternationalCode( "ARA", "Arabic", "Saudi Arabia", "العربية", "السعودية" ),
|
||||
new InternationalCode( "ARI", "Arabic", "Iraq", "العربية", "العراق" ),
|
||||
new InternationalCode( "ARE", "Arabic", "Egypt", "العربية", "مصر" ),
|
||||
new InternationalCode( "ARL", "Arabic", "Libya", "العربية", "ليبيا" ),
|
||||
new InternationalCode( "ARG", "Arabic", "Algeria", "العربية", "الجزائر" ),
|
||||
new InternationalCode( "ARM", "Arabic", "Morocco", "العربية", "المغرب" ),
|
||||
new InternationalCode( "ART", "Arabic", "Tunisia", "العربية", "تونس" ),
|
||||
new InternationalCode( "ARO", "Arabic", "Oman", "العربية", "عمان" ),
|
||||
new InternationalCode( "ARY", "Arabic", "Yemen", "العربية", "اليمن" ),
|
||||
new InternationalCode( "ARS", "Arabic", "Syria", "العربية", "سورية" ),
|
||||
new InternationalCode( "ARJ", "Arabic", "Jordan", "العربية", "الأردن" ),
|
||||
new InternationalCode( "ARB", "Arabic", "Lebanon", "العربية", "لبنان" ),
|
||||
new InternationalCode( "ARK", "Arabic", "Kuwait", "العربية", "الكويت" ),
|
||||
new InternationalCode( "ARU", "Arabic", "U.A.E.", "العربية", "الامارات" ),
|
||||
new InternationalCode( "ARH", "Arabic", "Bahrain", "العربية", "البحرين" ),
|
||||
new InternationalCode( "ARQ", "Arabic", "Qatar", "العربية", "قطر" ),
|
||||
new InternationalCode( "BGR", "Bulgarian", "Bulgaria", "Български", "България" ),
|
||||
new InternationalCode( "CAT", "Catalan", "Spain", "Català", "Espanya" ),
|
||||
new InternationalCode( "CHT", "Chinese", "Taiwan", "台語", "臺灣" ),
|
||||
new InternationalCode( "CHS", "Chinese", "PRC", "中文", "中国" ),
|
||||
new InternationalCode( "ZHH", "Chinese", "Hong Kong", "中文", "香港" ),
|
||||
new InternationalCode( "ZHI", "Chinese", "Singapore", "中文", "新加坡" ),
|
||||
new InternationalCode( "ZHM", "Chinese", "Macau", "中文", "澳門" ),
|
||||
new InternationalCode( "CSY", "Czech", "Czech Republic", "Čeština", "Česká republika" ),
|
||||
new InternationalCode( "DAN", "Danish", "Denmark", "Dansk", "Danmark" ),
|
||||
new InternationalCode( "DEU", "German", "Germany", "Deutsch", "Deutschland" ),
|
||||
new InternationalCode( "DES", "German", "Switzerland", "Deutsch", "der Schweiz" ),
|
||||
new InternationalCode( "DEA", "German", "Austria", "Deutsch", "Österreich" ),
|
||||
new InternationalCode( "DEL", "German", "Luxembourg", "Deutsch", "Luxembourg" ),
|
||||
new InternationalCode( "DEC", "German", "Liechtenstein", "Deutsch", "Liechtenstein" ),
|
||||
new InternationalCode( "ELL", "Greek", "Greece", "Ελληνικά", "Ελλάδα" ),
|
||||
new InternationalCode( "ENU", "English", "United States" ),
|
||||
new InternationalCode( "ENG", "English", "United Kingdom" ),
|
||||
new InternationalCode( "ENA", "English", "Australia" ),
|
||||
new InternationalCode( "ENC", "English", "Canada" ),
|
||||
new InternationalCode( "ENZ", "English", "New Zealand" ),
|
||||
new InternationalCode( "ENI", "English", "Ireland" ),
|
||||
new InternationalCode( "ENS", "English", "South Africa" ),
|
||||
new InternationalCode( "ENJ", "English", "Jamaica" ),
|
||||
new InternationalCode( "ENB", "English", "Caribbean" ),
|
||||
new InternationalCode( "ENL", "English", "Belize" ),
|
||||
new InternationalCode( "ENT", "English", "Trinidad" ),
|
||||
new InternationalCode( "ENW", "English", "Zimbabwe" ),
|
||||
new InternationalCode( "ENP", "English", "Philippines" ),
|
||||
new InternationalCode( "ESP", "Spanish", "Spain (Traditional Sort)", "Español", "España (tipo tradicional)" ),
|
||||
new InternationalCode( "ESM", "Spanish", "Mexico", "Español", "México" ),
|
||||
new InternationalCode( "ESN", "Spanish", "Spain (International Sort)", "Español", "España (tipo internacional)" ),
|
||||
new InternationalCode( "ESG", "Spanish", "Guatemala", "Español", "Guatemala" ),
|
||||
new InternationalCode( "ESC", "Spanish", "Costa Rica", "Español", "Costa Rica" ),
|
||||
new InternationalCode( "ESA", "Spanish", "Panama", "Español", "Panama" ),
|
||||
new InternationalCode( "ESD", "Spanish", "Dominican Republic", "Español", "Republica Dominicana" ),
|
||||
new InternationalCode( "ESV", "Spanish", "Venezuela", "Español", "Venezuela" ),
|
||||
new InternationalCode( "ESO", "Spanish", "Colombia", "Español", "Colombia" ),
|
||||
new InternationalCode( "ESR", "Spanish", "Peru", "Español", "Peru" ),
|
||||
new InternationalCode( "ESS", "Spanish", "Argentina", "Español", "Argentina" ),
|
||||
new InternationalCode( "ESF", "Spanish", "Ecuador", "Español", "Ecuador" ),
|
||||
new InternationalCode( "ESL", "Spanish", "Chile", "Español", "Chile" ),
|
||||
new InternationalCode( "ESY", "Spanish", "Uruguay", "Español", "Uruguay" ),
|
||||
new InternationalCode( "ESZ", "Spanish", "Paraguay", "Español", "Paraguay" ),
|
||||
new InternationalCode( "ESB", "Spanish", "Bolivia", "Español", "Bolivia" ),
|
||||
new InternationalCode( "ESE", "Spanish", "El Salvador", "Español", "El Salvador" ),
|
||||
new InternationalCode( "ESH", "Spanish", "Honduras", "Español", "Honduras" ),
|
||||
new InternationalCode( "ESI", "Spanish", "Nicaragua", "Español", "Nicaragua" ),
|
||||
new InternationalCode( "ESU", "Spanish", "Puerto Rico", "Español", "Puerto Rico" ),
|
||||
new InternationalCode( "FIN", "Finnish", "Finland", "Suomi", "Suomi" ),
|
||||
new InternationalCode( "FRA", "French", "France", "Français", "France" ),
|
||||
new InternationalCode( "FRB", "French", "Belgium", "Français", "Belgique" ),
|
||||
new InternationalCode( "FRC", "French", "Canada", "Français", "Canada" ),
|
||||
new InternationalCode( "FRS", "French", "Switzerland", "Français", "Suisse" ),
|
||||
new InternationalCode( "FRL", "French", "Luxembourg", "Français", "Luxembourg" ),
|
||||
new InternationalCode( "FRM", "French", "Monaco", "Français", "Monaco" ),
|
||||
new InternationalCode( "HEB", "Hebrew", "Israel", "עִבְרִית", "ישׂראל" ),
|
||||
new InternationalCode( "HUN", "Hungarian", "Hungary", "Magyar", "Magyarország" ),
|
||||
new InternationalCode( "ISL", "Icelandic", "Iceland", "Íslenska", "Ísland" ),
|
||||
new InternationalCode( "ITA", "Italian", "Italy", "Italiano", "Italia" ),
|
||||
new InternationalCode( "ITS", "Italian", "Switzerland", "Italiano", "Svizzera" ),
|
||||
new InternationalCode( "JPN", "Japanese", "Japan", "日本語", "日本" ),
|
||||
new InternationalCode( "KOR", "Korean (Extended Wansung)", "Korea", "한국어", "한국" ),
|
||||
new InternationalCode( "NLD", "Dutch", "Netherlands", "Nederlands", "Nederland" ),
|
||||
new InternationalCode( "NLB", "Dutch", "Belgium", "Nederlands", "België" ),
|
||||
new InternationalCode( "NOR", "Norwegian", "Norway (Bokmål)", "Norsk", "Norge (Bokmål)" ),
|
||||
new InternationalCode( "NON", "Norwegian", "Norway (Nynorsk)", "Norsk", "Norge (Nynorsk)" ),
|
||||
new InternationalCode( "PLK", "Polish", "Poland", "Polski", "Polska" ),
|
||||
new InternationalCode( "PTB", "Portuguese", "Brazil", "Português", "Brasil" ),
|
||||
new InternationalCode( "PTG", "Portuguese", "Portugal", "Português", "Brasil" ),
|
||||
new InternationalCode( "ROM", "Romanian", "Romania", "Limba Română", "România" ),
|
||||
new InternationalCode( "RUS", "Russian", "Russia", "Русский", "Россия" ),
|
||||
new InternationalCode( "HRV", "Croatian", "Croatia", "Hrvatski", "Hrvatska" ),
|
||||
new InternationalCode( "SRL", "Serbian", "Serbia (Latin)", "Srpski", "Srbija i Crna Gora" ),
|
||||
new InternationalCode( "SRB", "Serbian", "Serbia (Cyrillic)", "Српски", "Србија и Црна Гора" ),
|
||||
new InternationalCode( "SKY", "Slovak", "Slovakia", "Slovenčina", "Slovensko" ),
|
||||
new InternationalCode( "SQI", "Albanian", "Albania", "Shqip", "Shqipëria" ),
|
||||
new InternationalCode( "SVE", "Swedish", "Sweden", "Svenska", "Sverige" ),
|
||||
new InternationalCode( "SVF", "Swedish", "Finland", "Svenska", "Finland" ),
|
||||
new InternationalCode( "THA", "Thai", "Thailand", "ภาษาไทย", "ประเทศไทย" ),
|
||||
new InternationalCode( "TRK", "Turkish", "Turkey", "Türkçe", "Türkiye" ),
|
||||
new InternationalCode( "URP", "Urdu", "Pakistan", "اردو", "پاکستان" ),
|
||||
new InternationalCode( "IND", "Indonesian", "Indonesia", "Bahasa Indonesia", "Indonesia" ),
|
||||
new InternationalCode( "UKR", "Ukrainian", "Ukraine", "Українська", "Украина" ),
|
||||
new InternationalCode( "BEL", "Belarusian", "Belarus", "Беларускі", "Беларусь" ),
|
||||
new InternationalCode( "SLV", "Slovene", "Slovenia", "Slovenščina", "Slovenija" ),
|
||||
new InternationalCode( "ETI", "Estonian", "Estonia", "Eesti", "Eesti" ),
|
||||
new InternationalCode( "LVI", "Latvian", "Latvia", "Latviešu", "Latvija" ),
|
||||
new InternationalCode( "LTH", "Lithuanian", "Lithuania", "Lietuvių", "Lietuva" ),
|
||||
new InternationalCode( "LTC", "Classic Lithuanian", "Lithuania", "Lietuviškai", "Lietuva" ),
|
||||
new InternationalCode( "FAR", "Farsi", "Iran", "فارسى", "ايران" ),
|
||||
new InternationalCode( "VIT", "Vietnamese", "Viet Nam", "tiếng Việt", "Việt Nam" ),
|
||||
new InternationalCode( "HYE", "Armenian", "Armenia", "Հայերէն", "Հայաստան" ),
|
||||
new InternationalCode( "AZE", "Azeri", "Azerbaijan (Latin)", "Azərbaycanca", "Azərbaycan" ),
|
||||
new InternationalCode( "AZE", "Azeri", "Azerbaijan (Cyrillic)", "Азәрбајҹанҹа", "Азәрбајҹан" ),
|
||||
new InternationalCode( "EUQ", "Basque", "Spain", "Euskera", "Espainia" ),
|
||||
new InternationalCode( "MKI", "Macedonian", "Macedonia", "Македонски", "Македонија" ),
|
||||
new InternationalCode( "AFK", "Afrikaans", "South Africa", "Afrikaans", "Republiek van Suid-Afrika" ),
|
||||
new InternationalCode( "KAT", "Georgian", "Georgia", "ქართული", "საკარტველო" ),
|
||||
new InternationalCode( "FOS", "Faeroese", "Faeroe Islands", "Føroyska", "Føroya" ),
|
||||
new InternationalCode( "HIN", "Hindi", "India", "हिन्दी", "भारत" ),
|
||||
new InternationalCode( "MSL", "Malay", "Malaysia", "Bahasa melayu", "Malaysia" ),
|
||||
new InternationalCode( "MSB", "Malay", "Brunei Darussalam", "Bahasa melayu", "Negara Brunei Darussalam" ),
|
||||
new InternationalCode( "KAZ", "Kazak", "Kazakstan", "Қазақ", "Қазақстан" ),
|
||||
new InternationalCode( "SWK", "Swahili", "Kenya", "Kiswahili", "Kenya" ),
|
||||
new InternationalCode( "UZB", "Uzbek", "Uzbekistan (Latin)", "O'zbek", "O'zbekiston" ),
|
||||
new InternationalCode( "UZB", "Uzbek", "Uzbekistan (Cyrillic)", "Ўзбек", "Ўзбекистон" ),
|
||||
new InternationalCode( "TAT", "Tatar", "Tatarstan", "Татарча", "Татарстан" ),
|
||||
new InternationalCode( "BEN", "Bengali", "India", "বাংলা", "ভারত" ),
|
||||
new InternationalCode( "PAN", "Punjabi", "India", "ਪੰਜਾਬੀ", "ਭਾਰਤ" ),
|
||||
new InternationalCode( "GUJ", "Gujarati", "India", "ગુજરાતી", "ભારત" ),
|
||||
new InternationalCode( "ORI", "Oriya", "India", "ଓଡ଼ିଆ", "ଭାରତ" ),
|
||||
new InternationalCode( "TAM", "Tamil", "India", "தமிழ்", "இந்தியா" ),
|
||||
new InternationalCode( "TEL", "Telugu", "India", "తెలుగు", "భారత" ),
|
||||
new InternationalCode( "KAN", "Kannada", "India", "ಕನ್ನಡ", "ಭಾರತ" ),
|
||||
new InternationalCode( "MAL", "Malayalam", "India", "മലയാളം", "ഭാരത" ),
|
||||
new InternationalCode( "ASM", "Assamese", "India", "অসমিয়া", "Bhārat" ), // missing correct country name
|
||||
new InternationalCode( "MAR", "Marathi", "India", "मराठी", "भारत" ),
|
||||
new InternationalCode( "SAN", "Sanskrit", "India", "संस्कृत", "भारतम्" ),
|
||||
new InternationalCode( "KOK", "Konkani", "India", "कोंकणी", "भारत" )
|
||||
};
|
||||
|
||||
private static string GetFormattedInfo( string code )
|
||||
{
|
||||
if ( code == null || code.Length != 3 )
|
||||
return String.Format( "Unknown code {0}", code );
|
||||
|
||||
for ( int i = 0; i < InternationalCodes.Length; i++ )
|
||||
{
|
||||
if ( code == InternationalCodes[i].Code )
|
||||
{
|
||||
return String.Format( "{0}", InternationalCodes[i].GetName() );
|
||||
}
|
||||
}
|
||||
|
||||
return String.Format( "Unknown code {0}", code );
|
||||
}
|
||||
|
||||
private static bool DefaultLocalNames = false;
|
||||
private static bool ShowAlternatives = true;
|
||||
private static bool CountAccounts = true; // will consider only first character's valid language
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "LanguageStatistics", AccessLevel.Administrator, new CommandEventHandler( LanguageStatistics_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "LanguageStatistics" )]
|
||||
[Description( "Generate a file containing the list of languages for each PlayerMobile." )]
|
||||
public static void LanguageStatistics_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
Dictionary<string, InternationalCodeCounter> ht = new Dictionary<string, InternationalCodeCounter>();
|
||||
|
||||
using ( StreamWriter writer = new StreamWriter( "languages.txt" ) )
|
||||
{
|
||||
if ( CountAccounts )
|
||||
{
|
||||
// count accounts
|
||||
foreach ( Account acc in Accounts.GetAccounts() )
|
||||
{
|
||||
for ( int i = 0; i < acc.Length; i++ )
|
||||
{
|
||||
Mobile mob = acc[i];
|
||||
|
||||
if ( mob == null )
|
||||
continue;
|
||||
|
||||
string lang = mob.Language;
|
||||
|
||||
if ( lang != null )
|
||||
{
|
||||
lang = lang.ToUpper();
|
||||
|
||||
if ( !ht.ContainsKey( lang ) )
|
||||
ht[lang] = new InternationalCodeCounter( lang );
|
||||
else
|
||||
ht[lang].Increase();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// count playermobiles
|
||||
foreach( Mobile mob in World.Mobiles.Values )
|
||||
{
|
||||
if ( mob.Player )
|
||||
{
|
||||
string lang = mob.Language;
|
||||
|
||||
if ( lang != null )
|
||||
{
|
||||
lang = lang.ToUpper();
|
||||
|
||||
if ( !ht.ContainsKey( lang ) )
|
||||
ht[lang] = new InternationalCodeCounter( lang );
|
||||
else
|
||||
ht[lang].Increase();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writer.WriteLine( String.Format( "Language statistics. Numbers show how many {0} use the specified language.", CountAccounts ? "accounts" : "playermobile" ) );
|
||||
writer.WriteLine( "====================================================================================================" );
|
||||
writer.WriteLine();
|
||||
|
||||
// sort the list
|
||||
List<InternationalCodeCounter> list = new List<InternationalCodeCounter>( ht.Values );
|
||||
list.Sort( InternationalCodeComparer.Instance );
|
||||
|
||||
foreach ( InternationalCodeCounter c in list )
|
||||
writer.WriteLine( String.Format( "{0} : {1}", GetFormattedInfo( c.Code ), c.Count ) );
|
||||
|
||||
e.Mobile.SendMessage( "Languages list generated." );
|
||||
}
|
||||
}
|
||||
|
||||
private class InternationalCodeCounter
|
||||
{
|
||||
private string m_Code;
|
||||
private int m_Count;
|
||||
|
||||
public string Code{ get{ return m_Code; } }
|
||||
public int Count{ get{ return m_Count; } }
|
||||
|
||||
public InternationalCodeCounter( string code )
|
||||
{
|
||||
m_Code = code;
|
||||
m_Count = 1;
|
||||
}
|
||||
|
||||
public void Increase()
|
||||
{
|
||||
m_Count++;
|
||||
}
|
||||
}
|
||||
|
||||
private class InternationalCodeComparer : IComparer<InternationalCodeCounter>
|
||||
{
|
||||
public static readonly InternationalCodeComparer Instance = new InternationalCodeComparer();
|
||||
|
||||
public InternationalCodeComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public int Compare( InternationalCodeCounter x, InternationalCodeCounter y )
|
||||
{
|
||||
string a = null, b = null;
|
||||
int ca = 0, cb = 0;
|
||||
|
||||
a = x.Code;
|
||||
ca = x.Count;
|
||||
b = y.Code;
|
||||
cb = y.Count;
|
||||
|
||||
|
||||
if ( ca > cb )
|
||||
return -1;
|
||||
|
||||
if ( ca < cb )
|
||||
return 1;
|
||||
|
||||
if ( a == null && b == null )
|
||||
return 0;
|
||||
|
||||
if ( a == null )
|
||||
return 1;
|
||||
|
||||
if ( b == null )
|
||||
return -1;
|
||||
|
||||
return a.CompareTo( b );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
141
Scripts/Misc/LightCycle.cs
Normal file
141
Scripts/Misc/LightCycle.cs
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class LightCycle
|
||||
{
|
||||
public const int DayLevel = 0;
|
||||
public const int NightLevel = 12;
|
||||
public const int DungeonLevel = 26;
|
||||
public const int JailLevel = 9;
|
||||
|
||||
private static int m_LevelOverride = int.MinValue;
|
||||
|
||||
public static int LevelOverride
|
||||
{
|
||||
get{ return m_LevelOverride; }
|
||||
set
|
||||
{
|
||||
m_LevelOverride = value;
|
||||
|
||||
for ( int i = 0; i < NetState.Instances.Count; ++i )
|
||||
{
|
||||
NetState ns = NetState.Instances[i];
|
||||
Mobile m = ns.Mobile;
|
||||
|
||||
if ( m != null )
|
||||
m.CheckLightLevels( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
new LightCycleTimer().Start();
|
||||
EventSink.Login += new LoginEventHandler( OnLogin );
|
||||
|
||||
CommandSystem.Register( "GlobalLight", AccessLevel.GameMaster, new CommandEventHandler( Light_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "GlobalLight <value>" )]
|
||||
[Description( "Sets the current global light level." )]
|
||||
private static void Light_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
if ( e.Length >= 1 )
|
||||
{
|
||||
LevelOverride = e.GetInt32( 0 );
|
||||
e.Mobile.SendMessage( "Global light level override has been changed to {0}.", m_LevelOverride );
|
||||
}
|
||||
else
|
||||
{
|
||||
LevelOverride = int.MinValue;
|
||||
e.Mobile.SendMessage( "Global light level override has been cleared." );
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnLogin( LoginEventArgs args )
|
||||
{
|
||||
Mobile m = args.Mobile;
|
||||
|
||||
m.CheckLightLevels( true );
|
||||
}
|
||||
|
||||
public static int ComputeLevelFor( Mobile from )
|
||||
{
|
||||
if ( m_LevelOverride > int.MinValue )
|
||||
return m_LevelOverride;
|
||||
|
||||
int hours, minutes;
|
||||
|
||||
Server.Items.Clock.GetTime( from.Map, from.X, from.Y, out hours, out minutes );
|
||||
|
||||
/* OSI times:
|
||||
*
|
||||
* Midnight -> 3:59 AM : Night
|
||||
* 4:00 AM -> 11:59 PM : Day
|
||||
*
|
||||
* RunUO times:
|
||||
*
|
||||
* 10:00 PM -> 11:59 PM : Scale to night
|
||||
* Midnight -> 3:59 AM : Night
|
||||
* 4:00 AM -> 5:59 AM : Scale to day
|
||||
* 6:00 AM -> 9:59 PM : Day
|
||||
*/
|
||||
|
||||
if ( hours < 4 )
|
||||
return NightLevel;
|
||||
|
||||
if ( hours < 6 )
|
||||
return NightLevel + (((((hours - 4) * 60) + minutes) * (DayLevel - NightLevel)) / 120);
|
||||
|
||||
if ( hours < 22 )
|
||||
return DayLevel;
|
||||
|
||||
if ( hours < 24 )
|
||||
return DayLevel + (((((hours - 22) * 60) + minutes) * (NightLevel - DayLevel)) / 120);
|
||||
|
||||
return NightLevel; // should never be
|
||||
}
|
||||
|
||||
private class LightCycleTimer : Timer
|
||||
{
|
||||
public LightCycleTimer() : base( TimeSpan.FromSeconds( 0 ), TimeSpan.FromSeconds( 5.0 ) )
|
||||
{
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
for ( int i = 0; i < NetState.Instances.Count; ++i )
|
||||
{
|
||||
NetState ns = NetState.Instances[i];
|
||||
Mobile m = ns.Mobile;
|
||||
|
||||
if ( m != null )
|
||||
m.CheckLightLevels( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class NightSightTimer : Timer
|
||||
{
|
||||
private Mobile m_Owner;
|
||||
|
||||
public NightSightTimer( Mobile owner ) : base( TimeSpan.FromMinutes( Utility.Random( 15, 25 ) ) )
|
||||
{
|
||||
m_Owner = owner;
|
||||
Priority = TimerPriority.OneMinute;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Owner.EndAction( typeof( LightCycle ) );
|
||||
m_Owner.LightLevel = 0;
|
||||
BuffInfo.RemoveBuff( m_Owner, BuffIcon.NightSight );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
30
Scripts/Misc/LoginStats.cs
Normal file
30
Scripts/Misc/LoginStats.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class LoginStats
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
// Register our event handler
|
||||
EventSink.Login += new LoginEventHandler( EventSink_Login );
|
||||
}
|
||||
|
||||
private static void EventSink_Login( LoginEventArgs args )
|
||||
{
|
||||
int userCount = NetState.Instances.Count;
|
||||
int itemCount = World.Items.Count;
|
||||
int mobileCount = World.Mobiles.Count;
|
||||
|
||||
Mobile m = args.Mobile;
|
||||
|
||||
m.SendMessage( "Welcome, {0}! There {1} currently {2} user{3} online, with {4} item{5} and {6} mobile{7} in the world.",
|
||||
args.Mobile.Name,
|
||||
userCount == 1 ? "is" : "are",
|
||||
userCount, userCount == 1 ? "" : "s",
|
||||
itemCount, itemCount == 1 ? "" : "s",
|
||||
mobileCount, mobileCount == 1 ? "" : "s" );
|
||||
}
|
||||
}
|
||||
}
|
||||
838
Scripts/Misc/Loot.cs
Normal file
838
Scripts/Misc/Loot.cs
Normal file
|
|
@ -0,0 +1,838 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class Loot
|
||||
{
|
||||
#region List definitions
|
||||
|
||||
#region Mondain's Legacy
|
||||
private static Type[] m_MLWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( AssassinSpike ), typeof( DiamondMace ), typeof( ElvenMachete ),
|
||||
typeof( ElvenSpellblade ), typeof( Leafblade ), typeof( OrnateAxe ),
|
||||
typeof( RadiantScimitar ), typeof( RuneBlade ), typeof( WarCleaver ),
|
||||
typeof( WildStaff )
|
||||
};
|
||||
|
||||
public static Type[] MLWeaponTypes{ get{ return m_MLWeaponTypes; } }
|
||||
|
||||
private static Type[] m_MLRangedWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( ElvenCompositeLongbow ), typeof( MagicalShortbow )
|
||||
};
|
||||
|
||||
public static Type[] MLRangedWeaponTypes{ get{ return m_MLRangedWeaponTypes; } }
|
||||
|
||||
private static Type[] m_MLArmorTypes = new Type[]
|
||||
{
|
||||
typeof( Circlet ), typeof( GemmedCirclet ), typeof( LeafTonlet ),
|
||||
typeof( RavenHelm ), typeof( RoyalCirclet ), typeof( VultureHelm ),
|
||||
typeof( WingedHelm ), typeof( LeafArms ), typeof( LeafChest ),
|
||||
typeof( LeafGloves ), typeof( LeafGorget ), typeof( LeafLegs ),
|
||||
typeof( WoodlandArms ), typeof( WoodlandChest ), typeof( WoodlandGloves ),
|
||||
typeof( WoodlandGorget ), typeof( WoodlandLegs ), typeof( HideChest ),
|
||||
typeof( HideGloves ), typeof( HideGorget ), typeof( HidePants ),
|
||||
typeof( HidePauldrons )
|
||||
};
|
||||
|
||||
public static Type[] MLArmorTypes{ get{ return m_MLArmorTypes; } }
|
||||
|
||||
private static Type[] m_MLClothingTypes = new Type[]
|
||||
{
|
||||
typeof( MaleElvenRobe ), typeof( FemaleElvenRobe ), typeof( ElvenPants ),
|
||||
typeof( ElvenShirt ), typeof( ElvenDarkShirt ), typeof( ElvenBoots ),
|
||||
typeof( VultureHelm ), typeof( WoodlandBelt )
|
||||
};
|
||||
|
||||
public static Type[] MLClothingTypes{ get{ return m_MLClothingTypes; } }
|
||||
#endregion
|
||||
|
||||
private static Type[] m_SEWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( Bokuto ), typeof( Daisho ), typeof( Kama ),
|
||||
typeof( Lajatang ), typeof( NoDachi ), typeof( Nunchaku ),
|
||||
typeof( Sai ), typeof( Tekagi ), typeof( Tessen ),
|
||||
typeof( Tetsubo ), typeof( Wakizashi )
|
||||
};
|
||||
|
||||
public static Type[] SEWeaponTypes{ get{ return m_SEWeaponTypes; } }
|
||||
|
||||
private static Type[] m_AosWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( Scythe ), typeof( BoneHarvester ), typeof( Scepter ),
|
||||
typeof( BladedStaff ), typeof( Pike ), typeof( DoubleBladedStaff ),
|
||||
typeof( Lance ), typeof( CrescentBlade )
|
||||
};
|
||||
|
||||
public static Type[] AosWeaponTypes{ get{ return m_AosWeaponTypes; } }
|
||||
|
||||
private static Type[] m_WeaponTypes = new Type[]
|
||||
{
|
||||
typeof( Axe ), typeof( BattleAxe ), typeof( DoubleAxe ),
|
||||
typeof( ExecutionersAxe ), typeof( Hatchet ), typeof( LargeBattleAxe ),
|
||||
typeof( TwoHandedAxe ), typeof( WarAxe ), typeof( Club ),
|
||||
typeof( Mace ), typeof( Maul ), typeof( WarHammer ),
|
||||
typeof( WarMace ), typeof( Bardiche ), typeof( Halberd ),
|
||||
typeof( Spear ), typeof( ShortSpear ), typeof( Pitchfork ),
|
||||
typeof( WarFork ), typeof( BlackStaff ), typeof( GnarledStaff ),
|
||||
typeof( QuarterStaff ), typeof( Broadsword ), typeof( Cutlass ),
|
||||
typeof( Katana ), typeof( Kryss ), typeof( Longsword ),
|
||||
typeof( Scimitar ), typeof( VikingSword ), typeof( Pickaxe ),
|
||||
typeof( HammerPick ), typeof( ButcherKnife ), typeof( Cleaver ),
|
||||
typeof( Dagger ), typeof( SkinningKnife ), typeof( ShepherdsCrook )
|
||||
};
|
||||
|
||||
public static Type[] WeaponTypes{ get{ return m_WeaponTypes; } }
|
||||
|
||||
private static Type[] m_SERangedWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( Yumi )
|
||||
};
|
||||
|
||||
public static Type[] SERangedWeaponTypes{ get{ return m_SERangedWeaponTypes; } }
|
||||
|
||||
private static Type[] m_AosRangedWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( CompositeBow ), typeof( RepeatingCrossbow )
|
||||
};
|
||||
|
||||
public static Type[] AosRangedWeaponTypes{ get{ return m_AosRangedWeaponTypes; } }
|
||||
|
||||
private static Type[] m_RangedWeaponTypes = new Type[]
|
||||
{
|
||||
typeof( Bow ), typeof( Crossbow ), typeof( HeavyCrossbow )
|
||||
};
|
||||
|
||||
public static Type[] RangedWeaponTypes{ get{ return m_RangedWeaponTypes; } }
|
||||
|
||||
private static Type[] m_SEArmorTypes = new Type[]
|
||||
{
|
||||
typeof( ChainHatsuburi ), typeof( LeatherDo ), typeof( LeatherHaidate ),
|
||||
typeof( LeatherHiroSode ), typeof( LeatherJingasa ), typeof( LeatherMempo ),
|
||||
typeof( LeatherNinjaHood ), typeof( LeatherNinjaJacket ), typeof( LeatherNinjaMitts ),
|
||||
typeof( LeatherNinjaPants ), typeof( LeatherSuneate ), typeof( DecorativePlateKabuto ),
|
||||
typeof( HeavyPlateJingasa ), typeof( LightPlateJingasa ), typeof( PlateBattleKabuto ),
|
||||
typeof( PlateDo ), typeof( PlateHaidate ), typeof( PlateHatsuburi ),
|
||||
typeof( PlateHiroSode ), typeof( PlateMempo ), typeof( PlateSuneate ),
|
||||
typeof( SmallPlateJingasa ), typeof( StandardPlateKabuto ), typeof( StuddedDo ),
|
||||
typeof( StuddedHaidate ), typeof( StuddedHiroSode ), typeof( StuddedMempo ),
|
||||
typeof( StuddedSuneate )
|
||||
};
|
||||
|
||||
public static Type[] SEArmorTypes{ get{ return m_SEArmorTypes; } }
|
||||
|
||||
private static Type[] m_ArmorTypes = new Type[]
|
||||
{
|
||||
typeof( BoneArms ), typeof( BoneChest ), typeof( BoneGloves ),
|
||||
typeof( BoneLegs ), typeof( BoneHelm ), typeof( ChainChest ),
|
||||
typeof( ChainLegs ), typeof( ChainCoif ), typeof( Bascinet ),
|
||||
typeof( CloseHelm ), typeof( Helmet ), typeof( NorseHelm ),
|
||||
typeof( OrcHelm ), typeof( FemaleLeatherChest ), typeof( LeatherArms ),
|
||||
typeof( LeatherBustierArms ), typeof( LeatherChest ), typeof( LeatherGloves ),
|
||||
typeof( LeatherGorget ), typeof( LeatherLegs ), typeof( LeatherShorts ),
|
||||
typeof( LeatherSkirt ), typeof( LeatherCap ), typeof( FemalePlateChest ),
|
||||
typeof( PlateArms ), typeof( PlateChest ), typeof( PlateGloves ),
|
||||
typeof( PlateGorget ), typeof( PlateHelm ), typeof( PlateLegs ),
|
||||
typeof( RingmailArms ), typeof( RingmailChest ), typeof( RingmailGloves ),
|
||||
typeof( RingmailLegs ), typeof( FemaleStuddedChest ), typeof( StuddedArms ),
|
||||
typeof( StuddedBustierArms ), typeof( StuddedChest ), typeof( StuddedGloves ),
|
||||
typeof( StuddedGorget ), typeof( StuddedLegs )
|
||||
};
|
||||
|
||||
public static Type[] ArmorTypes{ get{ return m_ArmorTypes; } }
|
||||
|
||||
private static Type[] m_AosShieldTypes = new Type[]
|
||||
{
|
||||
typeof( ChaosShield ), typeof( OrderShield )
|
||||
};
|
||||
|
||||
public static Type[] AosShieldTypes{ get{ return m_AosShieldTypes; } }
|
||||
|
||||
private static Type[] m_ShieldTypes = new Type[]
|
||||
{
|
||||
typeof( BronzeShield ), typeof( Buckler ), typeof( HeaterShield ),
|
||||
typeof( MetalShield ), typeof( MetalKiteShield ), typeof( WoodenKiteShield ),
|
||||
typeof( WoodenShield )
|
||||
};
|
||||
|
||||
public static Type[] ShieldTypes{ get{ return m_ShieldTypes; } }
|
||||
|
||||
private static Type[] m_GemTypes = new Type[]
|
||||
{
|
||||
typeof( Amber ), typeof( Amethyst ), typeof( Citrine ),
|
||||
typeof( Diamond ), typeof( Emerald ), typeof( Ruby ),
|
||||
typeof( Sapphire ), typeof( StarSapphire ), typeof( Tourmaline )
|
||||
};
|
||||
|
||||
public static Type[] GemTypes{ get{ return m_GemTypes; } }
|
||||
|
||||
private static Type[] m_JewelryTypes = new Type[]
|
||||
{
|
||||
typeof( GoldRing ), typeof( GoldBracelet ),
|
||||
typeof( SilverRing ), typeof( SilverBracelet )
|
||||
};
|
||||
|
||||
public static Type[] JewelryTypes{ get{ return m_JewelryTypes; } }
|
||||
|
||||
private static Type[] m_RegTypes = new Type[]
|
||||
{
|
||||
typeof( BlackPearl ), typeof( Bloodmoss ), typeof( Garlic ),
|
||||
typeof( Ginseng ), typeof( MandrakeRoot ), typeof( Nightshade ),
|
||||
typeof( SulfurousAsh ), typeof( SpidersSilk )
|
||||
};
|
||||
|
||||
public static Type[] RegTypes{ get{ return m_RegTypes; } }
|
||||
|
||||
private static Type[] m_NecroRegTypes = new Type[]
|
||||
{
|
||||
typeof( BatWing ), typeof( GraveDust ), typeof( DaemonBlood ),
|
||||
typeof( NoxCrystal ), typeof( PigIron )
|
||||
};
|
||||
|
||||
public static Type[] NecroRegTypes{ get{ return m_NecroRegTypes; } }
|
||||
|
||||
private static Type[] m_PotionTypes = new Type[]
|
||||
{
|
||||
typeof( AgilityPotion ), typeof( StrengthPotion ), typeof( RefreshPotion ),
|
||||
typeof( LesserCurePotion ), typeof( LesserHealPotion ), typeof( LesserPoisonPotion )
|
||||
};
|
||||
|
||||
public static Type[] PotionTypes{ get{ return m_PotionTypes; } }
|
||||
|
||||
private static Type[] m_SEInstrumentTypes = new Type[]
|
||||
{
|
||||
typeof( BambooFlute )
|
||||
};
|
||||
|
||||
public static Type[] SEInstrumentTypes{ get{ return m_SEInstrumentTypes; } }
|
||||
|
||||
private static Type[] m_InstrumentTypes = new Type[]
|
||||
{
|
||||
typeof( Drums ), typeof( Harp ), typeof( LapHarp ),
|
||||
typeof( Lute ), typeof( Tambourine ), typeof( TambourineTassel )
|
||||
};
|
||||
|
||||
public static Type[] InstrumentTypes{ get{ return m_InstrumentTypes; } }
|
||||
|
||||
private static Type[] m_StatueTypes = new Type[]
|
||||
{
|
||||
typeof( StatueSouth ), typeof( StatueSouth2 ), typeof( StatueNorth ),
|
||||
typeof( StatueWest ), typeof( StatueEast ), typeof( StatueEast2 ),
|
||||
typeof( StatueSouthEast ), typeof( BustSouth ), typeof( BustEast )
|
||||
};
|
||||
|
||||
public static Type[] StatueTypes{ get{ return m_StatueTypes; } }
|
||||
|
||||
private static Type[] m_RegularScrollTypes = new Type[]
|
||||
{
|
||||
typeof( ReactiveArmorScroll ), typeof( ClumsyScroll ), typeof( CreateFoodScroll ), typeof( FeeblemindScroll ),
|
||||
typeof( HealScroll ), typeof( MagicArrowScroll ), typeof( NightSightScroll ), typeof( WeakenScroll ),
|
||||
typeof( AgilityScroll ), typeof( CunningScroll ), typeof( CureScroll ), typeof( HarmScroll ),
|
||||
typeof( MagicTrapScroll ), typeof( MagicUnTrapScroll ), typeof( ProtectionScroll ), typeof( StrengthScroll ),
|
||||
typeof( BlessScroll ), typeof( FireballScroll ), typeof( MagicLockScroll ), typeof( PoisonScroll ),
|
||||
typeof( TelekinisisScroll ), typeof( TeleportScroll ), typeof( UnlockScroll ), typeof( WallOfStoneScroll ),
|
||||
typeof( ArchCureScroll ), typeof( ArchProtectionScroll ), typeof( CurseScroll ), typeof( FireFieldScroll ),
|
||||
typeof( GreaterHealScroll ), typeof( LightningScroll ), typeof( ManaDrainScroll ), typeof( RecallScroll ),
|
||||
typeof( BladeSpiritsScroll ), typeof( DispelFieldScroll ), typeof( IncognitoScroll ), typeof( MagicReflectScroll ),
|
||||
typeof( MindBlastScroll ), typeof( ParalyzeScroll ), typeof( PoisonFieldScroll ), typeof( SummonCreatureScroll ),
|
||||
typeof( DispelScroll ), typeof( EnergyBoltScroll ), typeof( ExplosionScroll ), typeof( InvisibilityScroll ),
|
||||
typeof( MarkScroll ), typeof( MassCurseScroll ), typeof( ParalyzeFieldScroll ), typeof( RevealScroll ),
|
||||
typeof( ChainLightningScroll ), typeof( EnergyFieldScroll ), typeof( FlamestrikeScroll ), typeof( GateTravelScroll ),
|
||||
typeof( ManaVampireScroll ), typeof( MassDispelScroll ), typeof( MeteorSwarmScroll ), typeof( PolymorphScroll ),
|
||||
typeof( EarthquakeScroll ), typeof( EnergyVortexScroll ), typeof( ResurrectionScroll ), typeof( SummonAirElementalScroll ),
|
||||
typeof( SummonDaemonScroll ), typeof( SummonEarthElementalScroll ), typeof( SummonFireElementalScroll ), typeof( SummonWaterElementalScroll )
|
||||
};
|
||||
|
||||
private static Type[] m_NecromancyScrollTypes = new Type[]
|
||||
{
|
||||
typeof( AnimateDeadScroll ), typeof( BloodOathScroll ), typeof( CorpseSkinScroll ), typeof( CurseWeaponScroll ),
|
||||
typeof( EvilOmenScroll ), typeof( HorrificBeastScroll ), typeof( LichFormScroll ), typeof( MindRotScroll ),
|
||||
typeof( PainSpikeScroll ), typeof( PoisonStrikeScroll ), typeof( StrangleScroll ), typeof( SummonFamiliarScroll ),
|
||||
typeof( VampiricEmbraceScroll ), typeof( VengefulSpiritScroll ), typeof( WitherScroll ), typeof( WraithFormScroll )
|
||||
};
|
||||
|
||||
private static Type[] m_SENecromancyScrollTypes = new Type[]
|
||||
{
|
||||
typeof( AnimateDeadScroll ), typeof( BloodOathScroll ), typeof( CorpseSkinScroll ), typeof( CurseWeaponScroll ),
|
||||
typeof( EvilOmenScroll ), typeof( HorrificBeastScroll ), typeof( LichFormScroll ), typeof( MindRotScroll ),
|
||||
typeof( PainSpikeScroll ), typeof( PoisonStrikeScroll ), typeof( StrangleScroll ), typeof( SummonFamiliarScroll ),
|
||||
typeof( VampiricEmbraceScroll ), typeof( VengefulSpiritScroll ), typeof( WitherScroll ), typeof( WraithFormScroll ),
|
||||
typeof( ExorcismScroll )
|
||||
};
|
||||
|
||||
private static Type[] m_PaladinScrollTypes = new Type[0];
|
||||
|
||||
#region Mondain's Legacy
|
||||
private static Type[] m_ArcanistScrollTypes = new Type[]
|
||||
{
|
||||
typeof( ArcaneCircleScroll ), typeof( GiftOfRenewalScroll ), typeof( ImmolatingWeaponScroll ), typeof( AttuneWeaponScroll ),
|
||||
typeof( ThunderstormScroll ), typeof( NatureFuryScroll ), /*typeof( SummonFeyScroll ), typeof( SummonFiendScroll ),*/
|
||||
typeof( ReaperFormScroll ), typeof( WildfireScroll ), typeof( EssenceOfWindScroll ), typeof( DryadAllureScroll ),
|
||||
typeof( EtherealVoyageScroll ), typeof( WordOfDeathScroll ), typeof( GiftOfLifeScroll ), typeof( ArcaneEmpowermentScroll )
|
||||
};
|
||||
#endregion
|
||||
|
||||
public static Type[] RegularScrollTypes{ get{ return m_RegularScrollTypes; } }
|
||||
public static Type[] NecromancyScrollTypes{ get{ return m_NecromancyScrollTypes; } }
|
||||
public static Type[] SENecromancyScrollTypes{ get{ return m_SENecromancyScrollTypes; } }
|
||||
public static Type[] PaladinScrollTypes{ get{ return m_PaladinScrollTypes; } }
|
||||
#region Mondain's Legacy
|
||||
public static Type[] ArcanistScrollTypes{ get{ return m_ArcanistScrollTypes; } }
|
||||
#endregion
|
||||
|
||||
private static Type[] m_GrimmochJournalTypes = new Type[]
|
||||
{
|
||||
typeof( GrimmochJournal1 ), typeof( GrimmochJournal2 ), typeof( GrimmochJournal3 ),
|
||||
typeof( GrimmochJournal6 ), typeof( GrimmochJournal7 ), typeof( GrimmochJournal11 ),
|
||||
typeof( GrimmochJournal14 ), typeof( GrimmochJournal17 ), typeof( GrimmochJournal23 )
|
||||
};
|
||||
|
||||
public static Type[] GrimmochJournalTypes{ get{ return m_GrimmochJournalTypes; } }
|
||||
|
||||
private static Type[] m_LysanderNotebookTypes = new Type[]
|
||||
{
|
||||
typeof( LysanderNotebook1 ), typeof( LysanderNotebook2 ), typeof( LysanderNotebook3 ),
|
||||
typeof( LysanderNotebook7 ), typeof( LysanderNotebook8 ), typeof( LysanderNotebook11 )
|
||||
};
|
||||
|
||||
public static Type[] LysanderNotebookTypes{ get{ return m_LysanderNotebookTypes; } }
|
||||
|
||||
private static Type[] m_TavarasJournalTypes = new Type[]
|
||||
{
|
||||
typeof( TavarasJournal1 ), typeof( TavarasJournal2 ), typeof( TavarasJournal3 ),
|
||||
typeof( TavarasJournal6 ), typeof( TavarasJournal7 ), typeof( TavarasJournal8 ),
|
||||
typeof( TavarasJournal9 ), typeof( TavarasJournal11 ), typeof( TavarasJournal14 ),
|
||||
typeof( TavarasJournal16 ), typeof( TavarasJournal16b ), typeof( TavarasJournal17 ),
|
||||
typeof( TavarasJournal19 )
|
||||
};
|
||||
|
||||
public static Type[] TavarasJournalTypes{ get{ return m_TavarasJournalTypes; } }
|
||||
|
||||
|
||||
private static Type[] m_NewWandTypes = new Type[]
|
||||
{
|
||||
typeof( FireballWand ), typeof( LightningWand ), typeof( MagicArrowWand ),
|
||||
typeof( GreaterHealWand ), typeof( HarmWand ), typeof( HealWand )
|
||||
};
|
||||
public static Type[] NewWandTypes{ get{ return m_NewWandTypes; } }
|
||||
|
||||
private static Type[] m_WandTypes = new Type[]
|
||||
{
|
||||
typeof( ClumsyWand ), typeof( FeebleWand ),
|
||||
typeof( ManaDrainWand ), typeof( WeaknessWand )
|
||||
};
|
||||
public static Type[] WandTypes{ get{ return m_WandTypes; } }
|
||||
|
||||
private static Type[] m_OldWandTypes = new Type[]
|
||||
{
|
||||
typeof( IDWand )
|
||||
};
|
||||
public static Type[] OldWandTypes{ get{ return m_OldWandTypes; } }
|
||||
|
||||
private static Type[] m_SEClothingTypes = new Type[]
|
||||
{
|
||||
typeof( ClothNinjaJacket ), typeof( FemaleKimono ), typeof( Hakama ),
|
||||
typeof( HakamaShita ), typeof( JinBaori ), typeof( Kamishimo ),
|
||||
typeof( MaleKimono ), typeof( NinjaTabi ), typeof( Obi ),
|
||||
typeof( SamuraiTabi ), typeof( TattsukeHakama ), typeof( Waraji )
|
||||
};
|
||||
|
||||
public static Type[] SEClothingTypes{ get{ return m_SEClothingTypes; } }
|
||||
|
||||
private static Type[] m_AosClothingTypes = new Type[]
|
||||
{
|
||||
typeof( FurSarong ), typeof( FurCape ), typeof( FlowerGarland ),
|
||||
typeof( GildedDress ), typeof( FurBoots ), typeof( FormalShirt ),
|
||||
};
|
||||
|
||||
public static Type[] AosClothingTypes{ get{ return m_AosClothingTypes; } }
|
||||
|
||||
private static Type[] m_ClothingTypes = new Type[]
|
||||
{
|
||||
typeof( Cloak ),
|
||||
typeof( Bonnet ), typeof( Cap ), typeof( FeatheredHat ),
|
||||
typeof( FloppyHat ), typeof( JesterHat ), typeof( Surcoat ),
|
||||
typeof( SkullCap ), typeof( StrawHat ), typeof( TallStrawHat ),
|
||||
typeof( TricorneHat ), typeof( WideBrimHat ), typeof( WizardsHat ),
|
||||
typeof( BodySash ), typeof( Doublet ), typeof( Boots ),
|
||||
typeof( FullApron ), typeof( JesterSuit ), typeof( Sandals ),
|
||||
typeof( Tunic ), typeof( Shoes ), typeof( Shirt ),
|
||||
typeof( Kilt ), typeof( Skirt ), typeof( FancyShirt ),
|
||||
typeof( FancyDress ), typeof( ThighBoots ), typeof( LongPants ),
|
||||
typeof( PlainDress ), typeof( Robe ), typeof( ShortPants ),
|
||||
typeof( HalfApron )
|
||||
};
|
||||
public static Type[] ClothingTypes{ get{ return m_ClothingTypes; } }
|
||||
|
||||
private static Type[] m_SEHatTypes = new Type[]
|
||||
{
|
||||
typeof( ClothNinjaHood ), typeof( Kasa )
|
||||
};
|
||||
|
||||
public static Type[] SEHatTypes{ get{ return m_SEHatTypes; } }
|
||||
|
||||
private static Type[] m_AosHatTypes = new Type[]
|
||||
{
|
||||
typeof( FlowerGarland ), typeof( BearMask ), typeof( DeerMask ) //Are Bear& Deer mask inside the Pre-AoS loottables too?
|
||||
};
|
||||
|
||||
public static Type[] AosHatTypes{ get{ return m_AosHatTypes; } }
|
||||
|
||||
private static Type[] m_HatTypes = new Type[]
|
||||
{
|
||||
typeof( SkullCap ), typeof( Bandana ), typeof( FloppyHat ),
|
||||
typeof( Cap ), typeof( WideBrimHat ), typeof( StrawHat ),
|
||||
typeof( TallStrawHat ), typeof( WizardsHat ), typeof( Bonnet ),
|
||||
typeof( FeatheredHat ), typeof( TricorneHat ), typeof( JesterHat )
|
||||
};
|
||||
|
||||
public static Type[] HatTypes{ get{ return m_HatTypes; } }
|
||||
|
||||
private static Type[] m_LibraryBookTypes = new Type[]
|
||||
{
|
||||
typeof( GrammarOfOrcish ), typeof( CallToAnarchy ), typeof( ArmsAndWeaponsPrimer ),
|
||||
typeof( SongOfSamlethe ), typeof( TaleOfThreeTribes ), typeof( GuideToGuilds ),
|
||||
typeof( BirdsOfBritannia ), typeof( BritannianFlora ), typeof( ChildrenTalesVol2 ),
|
||||
typeof( TalesOfVesperVol1 ), typeof( DeceitDungeonOfHorror ), typeof( DimensionalTravel ),
|
||||
typeof( EthicalHedonism ), typeof( MyStory ), typeof( DiversityOfOurLand ),
|
||||
typeof( QuestOfVirtues ), typeof( RegardingLlamas ), typeof( TalkingToWisps ),
|
||||
typeof( TamingDragons ), typeof( BoldStranger ), typeof( BurningOfTrinsic ),
|
||||
typeof( TheFight ), typeof( LifeOfATravellingMinstrel ), typeof( MajorTradeAssociation ),
|
||||
typeof( RankingsOfTrades ), typeof( WildGirlOfTheForest ), typeof( TreatiseOnAlchemy ),
|
||||
typeof( VirtueBook )
|
||||
};
|
||||
|
||||
public static Type[] LibraryBookTypes{ get{ return m_LibraryBookTypes; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accessors
|
||||
|
||||
public static BaseWand RandomWand()
|
||||
{
|
||||
if ( Core.ML )
|
||||
return Construct( m_NewWandTypes ) as BaseWand;
|
||||
else if ( Core.AOS )
|
||||
return Construct( m_WandTypes, m_NewWandTypes ) as BaseWand;
|
||||
else
|
||||
return Construct( m_OldWandTypes, m_WandTypes, m_NewWandTypes ) as BaseWand;
|
||||
}
|
||||
|
||||
public static BaseClothing RandomClothing()
|
||||
{
|
||||
return RandomClothing( false, false );
|
||||
}
|
||||
|
||||
public static BaseClothing RandomClothing( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLClothingTypes, m_AosClothingTypes, m_ClothingTypes ) as BaseClothing;
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEClothingTypes, m_AosClothingTypes, m_ClothingTypes ) as BaseClothing;
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosClothingTypes, m_ClothingTypes ) as BaseClothing;
|
||||
|
||||
return Construct( m_ClothingTypes ) as BaseClothing;
|
||||
}
|
||||
|
||||
public static BaseWeapon RandomRangedWeapon()
|
||||
{
|
||||
return RandomRangedWeapon( false, false );
|
||||
}
|
||||
|
||||
public static BaseWeapon RandomRangedWeapon( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLRangedWeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes ) as BaseWeapon;
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SERangedWeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes ) as BaseWeapon;
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosRangedWeaponTypes, m_RangedWeaponTypes ) as BaseWeapon;
|
||||
|
||||
return Construct( m_RangedWeaponTypes ) as BaseWeapon;
|
||||
}
|
||||
|
||||
public static BaseWeapon RandomWeapon()
|
||||
{
|
||||
return RandomWeapon( false, false );
|
||||
}
|
||||
|
||||
public static BaseWeapon RandomWeapon( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLWeaponTypes, m_AosWeaponTypes, m_WeaponTypes ) as BaseWeapon;
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEWeaponTypes, m_AosWeaponTypes, m_WeaponTypes ) as BaseWeapon;
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosWeaponTypes, m_WeaponTypes ) as BaseWeapon;
|
||||
|
||||
return Construct( m_WeaponTypes ) as BaseWeapon;
|
||||
}
|
||||
|
||||
public static Item RandomWeaponOrJewelry()
|
||||
{
|
||||
return RandomWeaponOrJewelry( false, false );
|
||||
}
|
||||
|
||||
public static Item RandomWeaponOrJewelry( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLWeaponTypes, m_AosWeaponTypes, m_WeaponTypes, m_JewelryTypes );
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEWeaponTypes, m_AosWeaponTypes, m_WeaponTypes, m_JewelryTypes );
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosWeaponTypes, m_WeaponTypes, m_JewelryTypes );
|
||||
|
||||
return Construct( m_WeaponTypes, m_JewelryTypes );
|
||||
}
|
||||
|
||||
public static BaseJewel RandomJewelry()
|
||||
{
|
||||
return Construct( m_JewelryTypes ) as BaseJewel;
|
||||
}
|
||||
|
||||
public static BaseArmor RandomArmor()
|
||||
{
|
||||
return RandomArmor( false, false );
|
||||
}
|
||||
|
||||
public static BaseArmor RandomArmor( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLArmorTypes, m_ArmorTypes ) as BaseArmor;
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEArmorTypes, m_ArmorTypes ) as BaseArmor;
|
||||
|
||||
return Construct( m_ArmorTypes ) as BaseArmor;
|
||||
}
|
||||
|
||||
public static BaseHat RandomHat()
|
||||
{
|
||||
return RandomHat( false );
|
||||
}
|
||||
|
||||
public static BaseHat RandomHat( bool inTokuno )
|
||||
{
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEHatTypes, m_AosHatTypes, m_HatTypes ) as BaseHat;
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosHatTypes, m_HatTypes ) as BaseHat;
|
||||
|
||||
return Construct( m_HatTypes ) as BaseHat;
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrHat()
|
||||
{
|
||||
return RandomArmorOrHat( false, false );
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrHat( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLArmorTypes, m_ArmorTypes, m_AosHatTypes, m_HatTypes );
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEArmorTypes, m_ArmorTypes, m_SEHatTypes, m_AosHatTypes, m_HatTypes );
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_ArmorTypes, m_AosHatTypes, m_HatTypes );
|
||||
|
||||
return Construct( m_ArmorTypes, m_HatTypes );
|
||||
}
|
||||
|
||||
public static BaseShield RandomShield()
|
||||
{
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosShieldTypes, m_ShieldTypes ) as BaseShield;
|
||||
|
||||
return Construct( m_ShieldTypes ) as BaseShield;
|
||||
}
|
||||
|
||||
public static BaseArmor RandomArmorOrShield()
|
||||
{
|
||||
return RandomArmorOrShield( false, false );
|
||||
}
|
||||
|
||||
public static BaseArmor RandomArmorOrShield( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLArmorTypes, m_ArmorTypes, m_AosShieldTypes, m_ShieldTypes ) as BaseArmor;
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEArmorTypes, m_ArmorTypes, m_AosShieldTypes, m_ShieldTypes ) as BaseArmor;
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_ArmorTypes, m_AosShieldTypes, m_ShieldTypes ) as BaseArmor;
|
||||
|
||||
return Construct( m_ArmorTypes, m_ShieldTypes ) as BaseArmor;
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrShieldOrJewelry()
|
||||
{
|
||||
return RandomArmorOrShieldOrJewelry( false, false );
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrShieldOrJewelry( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLArmorTypes, m_ArmorTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEArmorTypes, m_ArmorTypes, m_SEHatTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_ArmorTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
|
||||
return Construct( m_ArmorTypes, m_HatTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrShieldOrWeapon()
|
||||
{
|
||||
return RandomArmorOrShieldOrWeapon( false, false );
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrShieldOrWeapon( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLWeaponTypes, m_AosWeaponTypes, m_WeaponTypes, m_MLRangedWeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes, m_MLArmorTypes, m_ArmorTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes );
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEWeaponTypes, m_AosWeaponTypes, m_WeaponTypes, m_SERangedWeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes, m_SEArmorTypes, m_ArmorTypes, m_SEHatTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes );
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosWeaponTypes, m_WeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes, m_ArmorTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes );
|
||||
|
||||
return Construct( m_WeaponTypes, m_RangedWeaponTypes, m_ArmorTypes, m_HatTypes, m_ShieldTypes );
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrShieldOrWeaponOrJewelry()
|
||||
{
|
||||
return RandomArmorOrShieldOrWeaponOrJewelry( false, false );
|
||||
}
|
||||
|
||||
public static Item RandomArmorOrShieldOrWeaponOrJewelry( bool inTokuno, bool isMondain )
|
||||
{
|
||||
#region Mondain's Legacy
|
||||
if ( Core.ML && isMondain )
|
||||
return Construct( m_MLWeaponTypes, m_AosWeaponTypes, m_WeaponTypes, m_MLRangedWeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes, m_MLArmorTypes, m_ArmorTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
#endregion
|
||||
|
||||
if ( Core.SE && inTokuno )
|
||||
return Construct( m_SEWeaponTypes, m_AosWeaponTypes, m_WeaponTypes, m_SERangedWeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes, m_SEArmorTypes, m_ArmorTypes, m_SEHatTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
|
||||
if ( Core.AOS )
|
||||
return Construct( m_AosWeaponTypes, m_WeaponTypes, m_AosRangedWeaponTypes, m_RangedWeaponTypes, m_ArmorTypes, m_AosHatTypes, m_HatTypes, m_AosShieldTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
|
||||
return Construct( m_WeaponTypes, m_RangedWeaponTypes, m_ArmorTypes, m_HatTypes, m_ShieldTypes, m_JewelryTypes );
|
||||
}
|
||||
|
||||
#region Chest of Heirlooms
|
||||
public static Item ChestOfHeirloomsContains()
|
||||
{
|
||||
return Construct( m_SEArmorTypes, m_SEHatTypes, m_SEWeaponTypes, m_SERangedWeaponTypes, m_JewelryTypes );
|
||||
}
|
||||
#endregion
|
||||
|
||||
public static Item RandomGem()
|
||||
{
|
||||
return Construct( m_GemTypes );
|
||||
}
|
||||
|
||||
public static Item RandomReagent()
|
||||
{
|
||||
return Construct( m_RegTypes );
|
||||
}
|
||||
|
||||
public static Item RandomNecromancyReagent()
|
||||
{
|
||||
return Construct( m_NecroRegTypes );
|
||||
}
|
||||
|
||||
public static Item RandomPossibleReagent()
|
||||
{
|
||||
if ( Core.AOS )
|
||||
return Construct( m_RegTypes, m_NecroRegTypes );
|
||||
|
||||
return Construct( m_RegTypes );
|
||||
}
|
||||
|
||||
public static Item RandomPotion()
|
||||
{
|
||||
return Construct( m_PotionTypes );
|
||||
}
|
||||
|
||||
public static BaseInstrument RandomInstrument()
|
||||
{
|
||||
if ( Core.SE )
|
||||
return Construct( m_InstrumentTypes, m_SEInstrumentTypes ) as BaseInstrument;
|
||||
|
||||
return Construct( m_InstrumentTypes ) as BaseInstrument;
|
||||
}
|
||||
|
||||
public static Item RandomStatue()
|
||||
{
|
||||
return Construct( m_StatueTypes );
|
||||
}
|
||||
|
||||
public static SpellScroll RandomScroll( int minIndex, int maxIndex, SpellbookType type )
|
||||
{
|
||||
Type[] types;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
default:
|
||||
case SpellbookType.Regular: types = m_RegularScrollTypes; break;
|
||||
case SpellbookType.Necromancer: types = (Core.SE ? m_SENecromancyScrollTypes : m_NecromancyScrollTypes ); break;
|
||||
case SpellbookType.Paladin: types = m_PaladinScrollTypes; break;
|
||||
case SpellbookType.Arcanist: types = m_ArcanistScrollTypes; break;
|
||||
}
|
||||
|
||||
return Construct( types, Utility.RandomMinMax( minIndex, maxIndex ) ) as SpellScroll;
|
||||
}
|
||||
|
||||
public static BaseBook RandomGrimmochJournal()
|
||||
{
|
||||
return Construct( m_GrimmochJournalTypes ) as BaseBook;
|
||||
}
|
||||
|
||||
public static BaseBook RandomLysanderNotebook()
|
||||
{
|
||||
return Construct( m_LysanderNotebookTypes ) as BaseBook;
|
||||
}
|
||||
|
||||
public static BaseBook RandomTavarasJournal()
|
||||
{
|
||||
return Construct( m_TavarasJournalTypes ) as BaseBook;
|
||||
}
|
||||
|
||||
public static BaseBook RandomLibraryBook()
|
||||
{
|
||||
return Construct( m_LibraryBookTypes ) as BaseBook;
|
||||
}
|
||||
|
||||
public static BaseTalisman RandomTalisman()
|
||||
{
|
||||
BaseTalisman talisman = new BaseTalisman( BaseTalisman.GetRandomItemID() );
|
||||
|
||||
talisman.Summoner = BaseTalisman.GetRandomSummoner();
|
||||
|
||||
if ( talisman.Summoner.IsEmpty )
|
||||
{
|
||||
talisman.Removal = BaseTalisman.GetRandomRemoval();
|
||||
|
||||
if ( talisman.Removal != TalismanRemoval.None )
|
||||
{
|
||||
talisman.MaxCharges = BaseTalisman.GetRandomCharges();
|
||||
talisman.MaxChargeTime = 1200;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
talisman.MaxCharges = Utility.RandomMinMax( 10, 50 );
|
||||
|
||||
if ( talisman.Summoner.IsItem )
|
||||
talisman.MaxChargeTime = 60;
|
||||
else
|
||||
talisman.MaxChargeTime = 1800;
|
||||
}
|
||||
|
||||
talisman.Blessed = BaseTalisman.GetRandomBlessed();
|
||||
talisman.Slayer = BaseTalisman.GetRandomSlayer();
|
||||
talisman.Protection = BaseTalisman.GetRandomProtection();
|
||||
talisman.Killer = BaseTalisman.GetRandomKiller();
|
||||
talisman.Skill = BaseTalisman.GetRandomSkill();
|
||||
talisman.ExceptionalBonus = BaseTalisman.GetRandomExceptional();
|
||||
talisman.SuccessBonus = BaseTalisman.GetRandomSuccessful();
|
||||
talisman.Charges = talisman.MaxCharges;
|
||||
|
||||
return talisman;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Construction methods
|
||||
public static Item Construct( Type type )
|
||||
{
|
||||
try
|
||||
{
|
||||
return Activator.CreateInstance( type ) as Item;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Item Construct( Type[] types )
|
||||
{
|
||||
if ( types.Length > 0 )
|
||||
return Construct( types, Utility.Random( types.Length ) );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Item Construct( Type[] types, int index )
|
||||
{
|
||||
if ( index >= 0 && index < types.Length )
|
||||
return Construct( types[index] );
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Item Construct( params Type[][] types )
|
||||
{
|
||||
int totalLength = 0;
|
||||
|
||||
for ( int i = 0; i < types.Length; ++i )
|
||||
totalLength += types[i].Length;
|
||||
|
||||
if ( totalLength > 0 )
|
||||
{
|
||||
int index = Utility.Random( totalLength );
|
||||
|
||||
for ( int i = 0; i < types.Length; ++i )
|
||||
{
|
||||
if ( index >= 0 && index < types[i].Length )
|
||||
return Construct( types[i][index] );
|
||||
|
||||
index -= types[i].Length;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
994
Scripts/Misc/LootPack.cs
Normal file
994
Scripts/Misc/LootPack.cs
Normal file
|
|
@ -0,0 +1,994 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class LootPack
|
||||
{
|
||||
public static int GetLuckChance( Mobile killer, Mobile victim )
|
||||
{
|
||||
if ( !Core.AOS )
|
||||
return 0;
|
||||
|
||||
int luck = killer.Luck;
|
||||
|
||||
PlayerMobile pmKiller = killer as PlayerMobile;
|
||||
if( pmKiller != null && pmKiller.SentHonorContext != null && pmKiller.SentHonorContext.Target == victim )
|
||||
luck += pmKiller.SentHonorContext.PerfectionLuckBonus;
|
||||
|
||||
if ( luck < 0 )
|
||||
return 0;
|
||||
|
||||
if ( !Core.SE && luck > 1200 )
|
||||
luck = 1200;
|
||||
|
||||
return (int)(Math.Pow( luck, 1 / 1.8 ) * 100);
|
||||
}
|
||||
|
||||
public static int GetLuckChanceForKiller( Mobile dead )
|
||||
{
|
||||
List<DamageStore> list = BaseCreature.GetLootingRights( dead.DamageEntries, dead.HitsMax );
|
||||
|
||||
DamageStore highest = null;
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
DamageStore ds = list[i];
|
||||
|
||||
if ( ds.m_HasRight && (highest == null || ds.m_Damage > highest.m_Damage) )
|
||||
highest = ds;
|
||||
}
|
||||
|
||||
if ( highest == null )
|
||||
return 0;
|
||||
|
||||
return GetLuckChance( highest.m_Mobile, dead );
|
||||
}
|
||||
|
||||
public static bool CheckLuck( int chance )
|
||||
{
|
||||
return ( chance > Utility.Random( 10000 ) );
|
||||
}
|
||||
|
||||
private LootPackEntry[] m_Entries;
|
||||
|
||||
public LootPack( LootPackEntry[] entries )
|
||||
{
|
||||
m_Entries = entries;
|
||||
}
|
||||
|
||||
public void Generate( Mobile from, Container cont, bool spawning, int luckChance )
|
||||
{
|
||||
if ( cont == null )
|
||||
return;
|
||||
|
||||
bool checkLuck = Core.AOS;
|
||||
|
||||
for ( int i = 0; i < m_Entries.Length; ++i )
|
||||
{
|
||||
LootPackEntry entry = m_Entries[i];
|
||||
|
||||
bool shouldAdd = ( entry.Chance > Utility.Random( 10000 ) );
|
||||
|
||||
if ( !shouldAdd && checkLuck )
|
||||
{
|
||||
checkLuck = false;
|
||||
|
||||
if( LootPack.CheckLuck( luckChance ) )
|
||||
shouldAdd = ( entry.Chance > Utility.Random( 10000 ) );
|
||||
}
|
||||
|
||||
if ( !shouldAdd )
|
||||
continue;
|
||||
|
||||
Item item = entry.Construct( from, luckChance, spawning );
|
||||
|
||||
if ( item != null )
|
||||
{
|
||||
if ( !item.Stackable || !cont.TryDropItem( from, item, false ) )
|
||||
cont.DropItem( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly LootPackItem[] Gold = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( Gold ), 1 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] Instruments = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseInstrument ), 1 )
|
||||
};
|
||||
|
||||
|
||||
public static readonly LootPackItem[] LowScrollItems = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( ClumsyScroll ), 1 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] MedScrollItems = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( ArchCureScroll ), 1 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] HighScrollItems = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( SummonAirElementalScroll ), 1 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] GemItems = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( Amber ), 1 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] PotionItems = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( AgilityPotion ), 1 ),
|
||||
new LootPackItem( typeof( StrengthPotion ), 1 ),
|
||||
new LootPackItem( typeof( RefreshPotion ), 1 ),
|
||||
new LootPackItem( typeof( LesserCurePotion ), 1 ),
|
||||
new LootPackItem( typeof( LesserHealPotion ), 1 ),
|
||||
new LootPackItem( typeof( LesserPoisonPotion ), 1 )
|
||||
};
|
||||
|
||||
#region Old Magic Items
|
||||
public static readonly LootPackItem[] OldMagicItems = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseJewel ), 1 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 4 ),
|
||||
new LootPackItem( typeof( BaseWeapon ), 3 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 1 ),
|
||||
new LootPackItem( typeof( BaseShield ), 1 )
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region AOS Magic Items
|
||||
public static readonly LootPackItem[] AosMagicItemsPoor = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 3 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 1 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 4 ),
|
||||
new LootPackItem( typeof( BaseShield ), 1 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 2 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsMeagerType1 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 56 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 14 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 81 ),
|
||||
new LootPackItem( typeof( BaseShield ), 11 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 42 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsMeagerType2 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 28 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 7 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 40 ),
|
||||
new LootPackItem( typeof( BaseShield ), 5 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 21 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsAverageType1 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 90 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 23 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 130 ),
|
||||
new LootPackItem( typeof( BaseShield ), 17 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 68 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsAverageType2 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 54 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 13 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 77 ),
|
||||
new LootPackItem( typeof( BaseShield ), 10 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 40 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsRichType1 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 211 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 53 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 303 ),
|
||||
new LootPackItem( typeof( BaseShield ), 39 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 158 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsRichType2 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 170 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 43 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 245 ),
|
||||
new LootPackItem( typeof( BaseShield ), 32 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 128 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsFilthyRichType1 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 219 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 55 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 315 ),
|
||||
new LootPackItem( typeof( BaseShield ), 41 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 164 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsFilthyRichType2 = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 239 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 60 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 343 ),
|
||||
new LootPackItem( typeof( BaseShield ), 90 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 45 )
|
||||
};
|
||||
|
||||
public static readonly LootPackItem[] AosMagicItemsUltraRich = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( BaseWeapon ), 276 ),
|
||||
new LootPackItem( typeof( BaseRanged ), 69 ),
|
||||
new LootPackItem( typeof( BaseArmor ), 397 ),
|
||||
new LootPackItem( typeof( BaseShield ), 52 ),
|
||||
new LootPackItem( typeof( BaseJewel ), 207 )
|
||||
};
|
||||
#endregion
|
||||
|
||||
#region ML definitions
|
||||
public static readonly LootPack MlRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "4d50+450" ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 100.00, 1, 3, 0, 75 ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 80.00, 1, 3, 0, 75 ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 60.00, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, Instruments, 1.00, 1 )
|
||||
} );
|
||||
#endregion
|
||||
|
||||
#region SE definitions
|
||||
public static readonly LootPack SePoor = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "2d10+20" ),
|
||||
new LootPackEntry( false, AosMagicItemsPoor, 1.00, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, Instruments, 0.02, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack SeMeager = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "4d10+40" ),
|
||||
new LootPackEntry( false, AosMagicItemsMeagerType1, 20.40, 1, 2, 0, 50 ),
|
||||
new LootPackEntry( false, AosMagicItemsMeagerType2, 10.20, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, Instruments, 0.10, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack SeAverage = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "8d10+100" ),
|
||||
new LootPackEntry( false, AosMagicItemsAverageType1, 32.80, 1, 3, 0, 50 ),
|
||||
new LootPackEntry( false, AosMagicItemsAverageType1, 32.80, 1, 4, 0, 75 ),
|
||||
new LootPackEntry( false, AosMagicItemsAverageType2, 19.50, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, Instruments, 0.40, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack SeRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "15d10+225" ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 76.30, 1, 4, 0, 75 ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 76.30, 1, 4, 0, 75 ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType2, 61.70, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, Instruments, 1.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack SeFilthyRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "3d100+400" ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType1, 79.50, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType1, 79.50, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType2, 77.60, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack SeUltraRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "6d100+600" ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack SeSuperBoss = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "10d100+800" ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 50, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 50, 100 ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 )
|
||||
} );
|
||||
#endregion
|
||||
|
||||
#region AOS definitions
|
||||
public static readonly LootPack AosPoor = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "1d10+10" ),
|
||||
new LootPackEntry( false, AosMagicItemsPoor, 0.02, 1, 5, 0, 90 ),
|
||||
new LootPackEntry( false, Instruments, 0.02, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack AosMeager = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "3d10+20" ),
|
||||
new LootPackEntry( false, AosMagicItemsMeagerType1, 1.00, 1, 2, 0, 10 ),
|
||||
new LootPackEntry( false, AosMagicItemsMeagerType2, 0.20, 1, 5, 0, 90 ),
|
||||
new LootPackEntry( false, Instruments, 0.10, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack AosAverage = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "5d10+50" ),
|
||||
new LootPackEntry( false, AosMagicItemsAverageType1, 5.00, 1, 4, 0, 20 ),
|
||||
new LootPackEntry( false, AosMagicItemsAverageType1, 2.00, 1, 3, 0, 50 ),
|
||||
new LootPackEntry( false, AosMagicItemsAverageType2, 0.50, 1, 5, 0, 90 ),
|
||||
new LootPackEntry( false, Instruments, 0.40, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack AosRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "10d10+150" ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 20.00, 1, 4, 0, 40 ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType1, 10.00, 1, 5, 0, 60 ),
|
||||
new LootPackEntry( false, AosMagicItemsRichType2, 1.00, 1, 5, 0, 90 ),
|
||||
new LootPackEntry( false, Instruments, 1.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack AosFilthyRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "2d100+200" ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType1, 33.00, 1, 4, 0, 50 ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType1, 33.00, 1, 4, 0, 60 ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType2, 20.00, 1, 5, 0, 75 ),
|
||||
new LootPackEntry( false, AosMagicItemsFilthyRichType2, 5.00, 1, 5, 0, 100 ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack AosUltraRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "5d100+500" ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 35, 100 ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack AosSuperBoss = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "5d100+500" ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 25, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 33, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 50, 100 ),
|
||||
new LootPackEntry( false, AosMagicItemsUltraRich, 100.00, 1, 5, 50, 100 ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 )
|
||||
} );
|
||||
#endregion
|
||||
|
||||
#region Pre-AOS definitions
|
||||
public static readonly LootPack OldPoor = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "1d25" ),
|
||||
new LootPackEntry( false, Instruments, 0.02, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack OldMeager = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "5d10+25" ),
|
||||
new LootPackEntry( false, Instruments, 0.10, 1 ),
|
||||
new LootPackEntry( false, OldMagicItems, 1.00, 1, 1, 0, 60 ),
|
||||
new LootPackEntry( false, OldMagicItems, 0.20, 1, 1, 10, 70 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack OldAverage = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "10d10+50" ),
|
||||
new LootPackEntry( false, Instruments, 0.40, 1 ),
|
||||
new LootPackEntry( false, OldMagicItems, 5.00, 1, 1, 20, 80 ),
|
||||
new LootPackEntry( false, OldMagicItems, 2.00, 1, 1, 30, 90 ),
|
||||
new LootPackEntry( false, OldMagicItems, 0.50, 1, 1, 40, 100 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack OldRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "10d10+250" ),
|
||||
new LootPackEntry( false, Instruments, 1.00, 1 ),
|
||||
new LootPackEntry( false, OldMagicItems, 20.00, 1, 1, 60, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 10.00, 1, 1, 65, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 1.00, 1, 1, 70, 100 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack OldFilthyRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "2d125+400" ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 ),
|
||||
new LootPackEntry( false, OldMagicItems, 33.00, 1, 1, 50, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 33.00, 1, 1, 60, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 20.00, 1, 1, 70, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 5.00, 1, 1, 80, 100 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack OldUltraRich = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "5d100+500" ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 40, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 40, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 50, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 50, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 60, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 60, 100 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack OldSuperBoss = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( true, Gold, 100.00, "5d100+500" ),
|
||||
new LootPackEntry( false, Instruments, 2.00, 1 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 40, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 40, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 40, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 50, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 50, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 50, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 60, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 60, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 60, 100 ),
|
||||
new LootPackEntry( false, OldMagicItems, 100.00, 1, 1, 70, 100 )
|
||||
} );
|
||||
#endregion
|
||||
|
||||
#region Generic accessors
|
||||
public static LootPack Poor{ get{ return Core.SE ? SePoor : Core.AOS ? AosPoor : OldPoor; } }
|
||||
public static LootPack Meager{ get{ return Core.SE ? SeMeager : Core.AOS ? AosMeager : OldMeager; } }
|
||||
public static LootPack Average{ get{ return Core.SE ? SeAverage : Core.AOS ? AosAverage : OldAverage; } }
|
||||
public static LootPack Rich{ get{ return Core.SE ? SeRich : Core.AOS ? AosRich : OldRich; } }
|
||||
public static LootPack FilthyRich{ get{ return Core.SE ? SeFilthyRich : Core.AOS ? AosFilthyRich : OldFilthyRich; } }
|
||||
public static LootPack UltraRich{ get{ return Core.SE ? SeUltraRich : Core.AOS ? AosUltraRich : OldUltraRich; } }
|
||||
public static LootPack SuperBoss{ get{ return Core.SE ? SeSuperBoss : Core.AOS ? AosSuperBoss : OldSuperBoss; } }
|
||||
#endregion
|
||||
|
||||
public static readonly LootPack LowScrolls = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( false, LowScrollItems, 100.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack MedScrolls = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( false, MedScrollItems, 100.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack HighScrolls = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( false, HighScrollItems, 100.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack Gems = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( false, GemItems, 100.00, 1 )
|
||||
} );
|
||||
|
||||
public static readonly LootPack Potions = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( false, PotionItems, 100.00, 1 )
|
||||
} );
|
||||
|
||||
/*
|
||||
// TODO: Uncomment once added
|
||||
#region Mondain's Legacy
|
||||
public static readonly LootPackItem[] ParrotItem = new LootPackItem[]
|
||||
{
|
||||
new LootPackItem( typeof( ParrotItem ), 1 )
|
||||
};
|
||||
|
||||
public static readonly LootPack Parrot = new LootPack( new LootPackEntry[]
|
||||
{
|
||||
new LootPackEntry( false, ParrotItem, 10.00, 1 )
|
||||
} );
|
||||
#endregion
|
||||
*/
|
||||
}
|
||||
|
||||
public class LootPackEntry
|
||||
{
|
||||
private int m_Chance;
|
||||
private LootPackDice m_Quantity;
|
||||
|
||||
private int m_MaxProps, m_MinIntensity, m_MaxIntensity;
|
||||
|
||||
private bool m_AtSpawnTime;
|
||||
|
||||
private LootPackItem[] m_Items;
|
||||
|
||||
public int Chance
|
||||
{
|
||||
get{ return m_Chance; }
|
||||
set{ m_Chance = value; }
|
||||
}
|
||||
|
||||
public LootPackDice Quantity
|
||||
{
|
||||
get{ return m_Quantity; }
|
||||
set{ m_Quantity = value; }
|
||||
}
|
||||
|
||||
public int MaxProps
|
||||
{
|
||||
get{ return m_MaxProps; }
|
||||
set{ m_MaxProps = value; }
|
||||
}
|
||||
|
||||
public int MinIntensity
|
||||
{
|
||||
get{ return m_MinIntensity; }
|
||||
set{ m_MinIntensity = value; }
|
||||
}
|
||||
|
||||
public int MaxIntensity
|
||||
{
|
||||
get{ return m_MaxIntensity; }
|
||||
set{ m_MaxIntensity = value; }
|
||||
}
|
||||
|
||||
public LootPackItem[] Items
|
||||
{
|
||||
get{ return m_Items; }
|
||||
set{ m_Items = value; }
|
||||
}
|
||||
|
||||
private static bool IsInTokuno( Mobile m )
|
||||
{
|
||||
if ( m.Region.IsPartOf( "Fan Dancer's Dojo" ) )
|
||||
return true;
|
||||
|
||||
if ( m.Region.IsPartOf( "Yomotsu Mines" ) )
|
||||
return true;
|
||||
|
||||
return ( m.Map == Map.Tokuno );
|
||||
}
|
||||
|
||||
#region Mondain's Legacy
|
||||
private static bool IsMondain( Mobile m )
|
||||
{
|
||||
return MondainsLegacy.IsMLRegion( m.Region );
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Item Construct( Mobile from, int luckChance, bool spawning )
|
||||
{
|
||||
if ( m_AtSpawnTime != spawning )
|
||||
return null;
|
||||
|
||||
int totalChance = 0;
|
||||
|
||||
for ( int i = 0; i < m_Items.Length; ++i )
|
||||
totalChance += m_Items[i].Chance;
|
||||
|
||||
int rnd = Utility.Random( totalChance );
|
||||
|
||||
for ( int i = 0; i < m_Items.Length; ++i )
|
||||
{
|
||||
LootPackItem item = m_Items[i];
|
||||
|
||||
if ( rnd < item.Chance )
|
||||
return Mutate( from, luckChance, item.Construct( IsInTokuno( from ), IsMondain( from ) ) );
|
||||
|
||||
rnd -= item.Chance;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int GetRandomOldBonus()
|
||||
{
|
||||
int rnd = Utility.RandomMinMax( m_MinIntensity, m_MaxIntensity );
|
||||
|
||||
if ( 50 > rnd )
|
||||
return 1;
|
||||
else
|
||||
rnd -= 50;
|
||||
|
||||
if ( 25 > rnd )
|
||||
return 2;
|
||||
else
|
||||
rnd -= 25;
|
||||
|
||||
if ( 14 > rnd )
|
||||
return 3;
|
||||
else
|
||||
rnd -= 14;
|
||||
|
||||
if ( 8 > rnd )
|
||||
return 4;
|
||||
|
||||
return 5;
|
||||
}
|
||||
|
||||
public Item Mutate( Mobile from, int luckChance, Item item )
|
||||
{
|
||||
if ( item != null )
|
||||
{
|
||||
if ( item is BaseWeapon && 1 > Utility.Random( 100 ) )
|
||||
{
|
||||
item.Delete();
|
||||
item = new FireHorn();
|
||||
return item;
|
||||
}
|
||||
|
||||
if ( item is BaseWeapon || item is BaseArmor || item is BaseJewel || item is BaseHat )
|
||||
{
|
||||
if ( Core.AOS )
|
||||
{
|
||||
int bonusProps = GetBonusProperties();
|
||||
int min = m_MinIntensity;
|
||||
int max = m_MaxIntensity;
|
||||
|
||||
if ( bonusProps < m_MaxProps && LootPack.CheckLuck( luckChance ) )
|
||||
++bonusProps;
|
||||
|
||||
int props = 1 + bonusProps;
|
||||
|
||||
// Make sure we're not spawning items with 6 properties.
|
||||
if ( props > m_MaxProps )
|
||||
props = m_MaxProps;
|
||||
|
||||
if ( item is BaseWeapon )
|
||||
BaseRunicTool.ApplyAttributesTo( (BaseWeapon)item, false, luckChance, props, m_MinIntensity, m_MaxIntensity );
|
||||
else if ( item is BaseArmor )
|
||||
BaseRunicTool.ApplyAttributesTo( (BaseArmor)item, false, luckChance, props, m_MinIntensity, m_MaxIntensity );
|
||||
else if ( item is BaseJewel )
|
||||
BaseRunicTool.ApplyAttributesTo( (BaseJewel)item, false, luckChance, props, m_MinIntensity, m_MaxIntensity );
|
||||
else if ( item is BaseHat )
|
||||
BaseRunicTool.ApplyAttributesTo( (BaseHat)item, false, luckChance, props, m_MinIntensity, m_MaxIntensity );
|
||||
}
|
||||
else // not aos
|
||||
{
|
||||
if ( item is BaseWeapon )
|
||||
{
|
||||
BaseWeapon weapon = (BaseWeapon)item;
|
||||
|
||||
if ( 80 > Utility.Random( 100 ) )
|
||||
weapon.AccuracyLevel = (WeaponAccuracyLevel)GetRandomOldBonus();
|
||||
|
||||
if ( 60 > Utility.Random( 100 ) )
|
||||
weapon.DamageLevel = (WeaponDamageLevel)GetRandomOldBonus();
|
||||
|
||||
if ( 40 > Utility.Random( 100 ) )
|
||||
weapon.DurabilityLevel = (WeaponDurabilityLevel)GetRandomOldBonus();
|
||||
|
||||
if ( 5 > Utility.Random( 100 ) )
|
||||
weapon.Slayer = SlayerName.Silver;
|
||||
|
||||
if ( from != null && weapon.AccuracyLevel == 0 && weapon.DamageLevel == 0 && weapon.DurabilityLevel == 0 && weapon.Slayer == SlayerName.None && 5 > Utility.Random( 100 ) )
|
||||
weapon.Slayer = SlayerGroup.GetLootSlayerType( from.GetType() );
|
||||
}
|
||||
else if ( item is BaseArmor )
|
||||
{
|
||||
BaseArmor armor = (BaseArmor)item;
|
||||
|
||||
if ( 80 > Utility.Random( 100 ) )
|
||||
armor.ProtectionLevel = (ArmorProtectionLevel)GetRandomOldBonus();
|
||||
|
||||
if ( 40 > Utility.Random( 100 ) )
|
||||
armor.Durability = (ArmorDurabilityLevel)GetRandomOldBonus();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( item is BaseInstrument )
|
||||
{
|
||||
SlayerName slayer = SlayerName.None;
|
||||
|
||||
if ( Core.AOS )
|
||||
slayer = BaseRunicTool.GetRandomSlayer();
|
||||
else
|
||||
slayer = SlayerGroup.GetLootSlayerType( from.GetType() );
|
||||
|
||||
if ( slayer == SlayerName.None )
|
||||
{
|
||||
item.Delete();
|
||||
return null;
|
||||
}
|
||||
|
||||
BaseInstrument instr = (BaseInstrument)item;
|
||||
|
||||
instr.Quality = InstrumentQuality.Regular;
|
||||
instr.Slayer = slayer;
|
||||
}
|
||||
|
||||
if ( item.Stackable )
|
||||
item.Amount = m_Quantity.Roll();
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public LootPackEntry( bool atSpawnTime, LootPackItem[] items, double chance, string quantity ) : this( atSpawnTime, items, chance, new LootPackDice( quantity ), 0, 0, 0 )
|
||||
{
|
||||
}
|
||||
|
||||
public LootPackEntry( bool atSpawnTime, LootPackItem[] items, double chance, int quantity ) : this( atSpawnTime, items, chance, new LootPackDice( 0, 0, quantity ), 0, 0, 0 )
|
||||
{
|
||||
}
|
||||
|
||||
public LootPackEntry( bool atSpawnTime, LootPackItem[] items, double chance, string quantity, int maxProps, int minIntensity, int maxIntensity ) : this( atSpawnTime, items, chance, new LootPackDice( quantity ), maxProps, minIntensity, maxIntensity )
|
||||
{
|
||||
}
|
||||
|
||||
public LootPackEntry( bool atSpawnTime, LootPackItem[] items, double chance, int quantity, int maxProps, int minIntensity, int maxIntensity ) : this( atSpawnTime, items, chance, new LootPackDice( 0, 0, quantity ), maxProps, minIntensity, maxIntensity )
|
||||
{
|
||||
}
|
||||
|
||||
public LootPackEntry( bool atSpawnTime, LootPackItem[] items, double chance, LootPackDice quantity, int maxProps, int minIntensity, int maxIntensity )
|
||||
{
|
||||
m_AtSpawnTime = atSpawnTime;
|
||||
m_Items = items;
|
||||
m_Chance = (int)(100 * chance);
|
||||
m_Quantity = quantity;
|
||||
m_MaxProps = maxProps;
|
||||
m_MinIntensity = minIntensity;
|
||||
m_MaxIntensity = maxIntensity;
|
||||
}
|
||||
|
||||
public int GetBonusProperties()
|
||||
{
|
||||
int p0=0, p1=0, p2=0, p3=0, p4=0, p5=0;
|
||||
|
||||
switch ( m_MaxProps )
|
||||
{
|
||||
case 1: p0= 3; p1= 1; break;
|
||||
case 2: p0= 6; p1= 3; p2= 1; break;
|
||||
case 3: p0=10; p1= 6; p2= 3; p3= 1; break;
|
||||
case 4: p0=16; p1=12; p2= 6; p3= 5; p4=1; break;
|
||||
case 5: p0=30; p1=25; p2=20; p3=15; p4=9; p5=1; break;
|
||||
}
|
||||
|
||||
int pc = p0+p1+p2+p3+p4+p5;
|
||||
|
||||
int rnd = Utility.Random( pc );
|
||||
|
||||
if ( rnd < p5 )
|
||||
return 5;
|
||||
else
|
||||
rnd -= p5;
|
||||
|
||||
if ( rnd < p4 )
|
||||
return 4;
|
||||
else
|
||||
rnd -= p4;
|
||||
|
||||
if ( rnd < p3 )
|
||||
return 3;
|
||||
else
|
||||
rnd -= p3;
|
||||
|
||||
if ( rnd < p2 )
|
||||
return 2;
|
||||
else
|
||||
rnd -= p2;
|
||||
|
||||
if ( rnd < p1 )
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public class LootPackItem
|
||||
{
|
||||
private Type m_Type;
|
||||
private int m_Chance;
|
||||
|
||||
public Type Type
|
||||
{
|
||||
get{ return m_Type; }
|
||||
set{ m_Type = value; }
|
||||
}
|
||||
|
||||
public int Chance
|
||||
{
|
||||
get{ return m_Chance; }
|
||||
set{ m_Chance = value; }
|
||||
}
|
||||
|
||||
private static Type[] m_BlankTypes = new Type[]{ typeof( BlankScroll ) };
|
||||
private static Type[][] m_NecroTypes = new Type[][]
|
||||
{
|
||||
new Type[] // low
|
||||
{
|
||||
typeof( AnimateDeadScroll ), typeof( BloodOathScroll ), typeof( CorpseSkinScroll ), typeof( CurseWeaponScroll ),
|
||||
typeof( EvilOmenScroll ), typeof( HorrificBeastScroll ), typeof( MindRotScroll ), typeof( PainSpikeScroll ),
|
||||
typeof( SummonFamiliarScroll ), typeof( WraithFormScroll )
|
||||
},
|
||||
new Type[] // med
|
||||
{
|
||||
typeof( LichFormScroll ), typeof( PoisonStrikeScroll ), typeof( StrangleScroll ), typeof( WitherScroll )
|
||||
},
|
||||
|
||||
((Core.SE) ?
|
||||
new Type[] // high
|
||||
{
|
||||
typeof( VengefulSpiritScroll ), typeof( VampiricEmbraceScroll ), typeof( ExorcismScroll )
|
||||
} :
|
||||
new Type[] // high
|
||||
{
|
||||
typeof( VengefulSpiritScroll ), typeof( VampiricEmbraceScroll )
|
||||
})
|
||||
};
|
||||
|
||||
public static Item RandomScroll( int index, int minCircle, int maxCircle )
|
||||
{
|
||||
--minCircle;
|
||||
--maxCircle;
|
||||
|
||||
int scrollCount = ((maxCircle - minCircle) + 1) * 8;
|
||||
|
||||
if ( index == 0 )
|
||||
scrollCount += m_BlankTypes.Length;
|
||||
|
||||
if ( Core.AOS )
|
||||
scrollCount += m_NecroTypes[index].Length;
|
||||
|
||||
int rnd = Utility.Random( scrollCount );
|
||||
|
||||
if ( index == 0 && rnd < m_BlankTypes.Length )
|
||||
return Loot.Construct( m_BlankTypes );
|
||||
else if ( index == 0 )
|
||||
rnd -= m_BlankTypes.Length;
|
||||
|
||||
if ( Core.AOS && rnd < m_NecroTypes.Length )
|
||||
return Loot.Construct( m_NecroTypes[index] );
|
||||
else if ( Core.AOS )
|
||||
rnd -= m_NecroTypes[index].Length;
|
||||
|
||||
return Loot.RandomScroll( minCircle * 8, (maxCircle * 8) + 7, SpellbookType.Regular );
|
||||
}
|
||||
|
||||
public Item Construct( bool inTokuno, bool isMondain )
|
||||
{
|
||||
try
|
||||
{
|
||||
Item item;
|
||||
|
||||
if ( m_Type == typeof( BaseRanged ) )
|
||||
item = Loot.RandomRangedWeapon( inTokuno, isMondain );
|
||||
else if ( m_Type == typeof( BaseWeapon ) )
|
||||
item = Loot.RandomWeapon( inTokuno, isMondain );
|
||||
else if ( m_Type == typeof( BaseArmor ) )
|
||||
item = Loot.RandomArmorOrHat( inTokuno, isMondain );
|
||||
else if ( m_Type == typeof( BaseShield ) )
|
||||
item = Loot.RandomShield();
|
||||
else if ( m_Type == typeof( BaseJewel ) )
|
||||
item = Core.AOS ? Loot.RandomJewelry() : Loot.RandomArmorOrShieldOrWeapon();
|
||||
else if ( m_Type == typeof( BaseInstrument ) )
|
||||
item = Loot.RandomInstrument();
|
||||
else if ( m_Type == typeof( Amber ) ) // gem
|
||||
item = Loot.RandomGem();
|
||||
else if ( m_Type == typeof( ClumsyScroll ) ) // low scroll
|
||||
item = RandomScroll( 0, 1, 3 );
|
||||
else if ( m_Type == typeof( ArchCureScroll ) ) // med scroll
|
||||
item = RandomScroll( 1, 4, 7 );
|
||||
else if ( m_Type == typeof( SummonAirElementalScroll ) ) // high scroll
|
||||
item = RandomScroll( 2, 8, 8 );
|
||||
else
|
||||
item = Activator.CreateInstance( m_Type ) as Item;
|
||||
|
||||
return item;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public LootPackItem( Type type, int chance )
|
||||
{
|
||||
m_Type = type;
|
||||
m_Chance = chance;
|
||||
}
|
||||
}
|
||||
|
||||
public class LootPackDice
|
||||
{
|
||||
private int m_Count, m_Sides, m_Bonus;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get{ return m_Count; }
|
||||
set{ m_Count = value; }
|
||||
}
|
||||
|
||||
public int Sides
|
||||
{
|
||||
get{ return m_Sides; }
|
||||
set{ m_Sides = value; }
|
||||
}
|
||||
|
||||
public int Bonus
|
||||
{
|
||||
get{ return m_Bonus; }
|
||||
set{ m_Bonus = value; }
|
||||
}
|
||||
|
||||
public int Roll()
|
||||
{
|
||||
int v = m_Bonus;
|
||||
|
||||
for ( int i = 0; i < m_Count; ++i )
|
||||
v += Utility.Random( 1, m_Sides );
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public LootPackDice( string str )
|
||||
{
|
||||
int start = 0;
|
||||
int index = str.IndexOf( 'd', start );
|
||||
|
||||
if ( index < start )
|
||||
return;
|
||||
|
||||
m_Count = Utility.ToInt32( str.Substring( start, index-start ) );
|
||||
|
||||
bool negative;
|
||||
|
||||
start = index + 1;
|
||||
index = str.IndexOf( '+', start );
|
||||
|
||||
if ( negative = (index < start) )
|
||||
index = str.IndexOf( '-', start );
|
||||
|
||||
if ( index < start )
|
||||
index = str.Length;
|
||||
|
||||
m_Sides = Utility.ToInt32( str.Substring( start, index-start ) );
|
||||
|
||||
if ( index == str.Length )
|
||||
return;
|
||||
|
||||
start = index + 1;
|
||||
index = str.Length;
|
||||
|
||||
m_Bonus = Utility.ToInt32( str.Substring( start, index-start ) );
|
||||
|
||||
if ( negative )
|
||||
m_Bonus *= -1;
|
||||
}
|
||||
|
||||
public LootPackDice( int count, int sides, int bonus )
|
||||
{
|
||||
m_Count = count;
|
||||
m_Sides = sides;
|
||||
m_Bonus = bonus;
|
||||
}
|
||||
}
|
||||
}
|
||||
54
Scripts/Misc/MapDefinitions.cs
Normal file
54
Scripts/Misc/MapDefinitions.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class MapDefinitions
|
||||
{
|
||||
public static void Configure()
|
||||
{
|
||||
/* Here we configure all maps. Some notes:
|
||||
*
|
||||
* 1) The first 32 maps are reserved for core use.
|
||||
* 2) Map 0x7F is reserved for core use.
|
||||
* 3) Map 0xFF is reserved for core use.
|
||||
* 4) Changing or removing any predefined maps may cause server instability.
|
||||
*/
|
||||
|
||||
RegisterMap( 0, 0, 0, 7168, 4096, 4, "Felucca", MapRules.FeluccaRules );
|
||||
RegisterMap( 1, 1, 1, 7168, 4096, 0, "Trammel", MapRules.TrammelRules );
|
||||
RegisterMap( 2, 2, 2, 2304, 1600, 1, "Ilshenar", MapRules.TrammelRules );
|
||||
RegisterMap( 3, 3, 3, 2560, 2048, 1, "Malas", MapRules.TrammelRules );
|
||||
RegisterMap( 4, 4, 4, 1448, 1448, 1, "Tokuno", MapRules.TrammelRules );
|
||||
RegisterMap( 5, 5, 5, 1280, 4096, 1, "TerMur", MapRules.TrammelRules );
|
||||
|
||||
RegisterMap( 0x7F, 0x7F, 0x7F, Map.SectorSize, Map.SectorSize, 1, "Internal", MapRules.Internal );
|
||||
|
||||
/* Example of registering a custom map:
|
||||
* RegisterMap( 32, 0, 0, 6144, 4096, 3, "Iceland", MapRules.FeluccaRules );
|
||||
*
|
||||
* Defined:
|
||||
* RegisterMap( <index>, <mapID>, <fileIndex>, <width>, <height>, <season>, <name>, <rules> );
|
||||
* - <index> : An unreserved unique index for this map
|
||||
* - <mapID> : An identification number used in client communications. For any visible maps, this value must be from 0-5
|
||||
* - <fileIndex> : A file identification number. For any visible maps, this value must be from 0-5
|
||||
* - <width>, <height> : Size of the map (in tiles)
|
||||
* - <season> : Season of the map. 0 = Spring, 1 = Summer, 2 = Fall, 3 = Winter, 4 = Desolation
|
||||
* - <name> : Reference name for the map, used in props gump, get/set commands, region loading, etc
|
||||
* - <rules> : Rules and restrictions associated with the map. See documentation for details
|
||||
*/
|
||||
|
||||
TileMatrixPatch.Enabled = false; // OSI Client Patch 6.0.0.0
|
||||
|
||||
MultiComponentList.PostHSFormat = true; // OSI Client Patch 7.0.9.0
|
||||
}
|
||||
|
||||
public static void RegisterMap( int mapIndex, int mapID, int fileIndex, int width, int height, int season, string name, MapRules rules )
|
||||
{
|
||||
Map newMap = new Map( mapID, mapIndex, fileIndex, width, height, season, name, rules );
|
||||
|
||||
Map.Maps[mapIndex] = newMap;
|
||||
Map.AllMaps.Add( newMap );
|
||||
}
|
||||
}
|
||||
}
|
||||
130
Scripts/Misc/MapUO.cs
Normal file
130
Scripts/Misc/MapUO.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Guilds;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public static partial class MapUO
|
||||
{
|
||||
private static class Settings
|
||||
{
|
||||
public const bool PartyTrack = true;
|
||||
public const bool GuildTrack = true;
|
||||
public const bool GuildHitsPercent = true;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( Settings.PartyTrack )
|
||||
ProtocolExtensions.Register( 0x00, true, new OnPacketReceive( OnPartyTrack ) );
|
||||
|
||||
if ( Settings.GuildTrack )
|
||||
ProtocolExtensions.Register( 0x01, true, new OnPacketReceive( OnGuildTrack ) );
|
||||
}
|
||||
|
||||
private static void OnPartyTrack( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
Party party = Party.Get( from );
|
||||
|
||||
if ( party != null )
|
||||
{
|
||||
Packets.PartyTrack packet = new Packets.PartyTrack( from, party );
|
||||
|
||||
if ( packet.UnderlyingStream.Length > 8 )
|
||||
state.Send( packet );
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnGuildTrack( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
Guild guild = from.Guild as Guild;
|
||||
|
||||
if ( guild != null )
|
||||
{
|
||||
bool locations = pvSrc.ReadByte() != 0;
|
||||
|
||||
Packets.GuildTrack packet = new Packets.GuildTrack( from, guild, locations );
|
||||
|
||||
if ( packet.UnderlyingStream.Length > ( locations ? 9 : 5 ) )
|
||||
state.Send( packet );
|
||||
}
|
||||
else
|
||||
state.Send( new Packets.GuildTrack() );
|
||||
}
|
||||
|
||||
private static class Packets
|
||||
{
|
||||
public sealed class PartyTrack : ProtocolExtension
|
||||
{
|
||||
public PartyTrack( Mobile from, Party party ) : base( 0x01, ( ( party.Members.Count - 1 ) * 9 ) + 4 )
|
||||
{
|
||||
for ( int i = 0; i < party.Members.Count; ++i )
|
||||
{
|
||||
PartyMemberInfo pmi = (PartyMemberInfo)party.Members[i];
|
||||
|
||||
if ( pmi == null || pmi.Mobile == from )
|
||||
continue;
|
||||
|
||||
Mobile mob = pmi.Mobile;
|
||||
|
||||
if ( Utility.InUpdateRange( from, mob ) && from.CanSee( mob ) )
|
||||
continue;
|
||||
|
||||
m_Stream.Write( (int) mob.Serial );
|
||||
m_Stream.Write( (short) mob.X );
|
||||
m_Stream.Write( (short) mob.Y );
|
||||
m_Stream.Write( (byte) ( mob.Map == null ? 0 : mob.Map.MapID ) );
|
||||
}
|
||||
|
||||
m_Stream.Write( (int) 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class GuildTrack : ProtocolExtension
|
||||
{
|
||||
public GuildTrack() : base( 0x02, 5 )
|
||||
{
|
||||
m_Stream.Write( (byte) 0 );
|
||||
m_Stream.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public GuildTrack( Mobile from, Guild guild, bool locations ) : base( 0x02, ( ( guild.Members.Count - 1 ) * ( locations ? 10 : 4 ) ) + 5 )
|
||||
{
|
||||
m_Stream.Write( (byte) ( locations ? 1 : 0 ) );
|
||||
|
||||
for ( int i = 0; i < guild.Members.Count; ++i )
|
||||
{
|
||||
Mobile mob = guild.Members[i];
|
||||
|
||||
if ( mob == null || mob == from || mob.NetState == null )
|
||||
continue;
|
||||
|
||||
if ( locations && Utility.InUpdateRange( from, mob ) && from.CanSee( mob ) )
|
||||
continue;
|
||||
|
||||
m_Stream.Write( (int) mob.Serial );
|
||||
|
||||
if ( locations )
|
||||
{
|
||||
m_Stream.Write( (short) mob.X );
|
||||
m_Stream.Write( (short) mob.Y );
|
||||
m_Stream.Write( (byte) ( mob.Map == null ? 0 : mob.Map.MapID ) );
|
||||
|
||||
if ( Settings.GuildHitsPercent && mob.Alive )
|
||||
m_Stream.Write( (byte) ( mob.Hits / Math.Max( mob.HitsMax, 1.0 ) * 100 ) );
|
||||
else
|
||||
m_Stream.Write( (byte) 0 );
|
||||
}
|
||||
}
|
||||
|
||||
m_Stream.Write( (int) 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Scripts/Misc/MondainsLegacy.cs
Normal file
86
Scripts/Misc/MondainsLegacy.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public static class MondainsLegacy
|
||||
{
|
||||
public static Type[] Artifacts { get { return m_Artifacts; } }
|
||||
|
||||
private static Type[] m_Artifacts = new Type[]
|
||||
{
|
||||
typeof( AegisOfGrace ), typeof( BladeDance ), typeof( BloodwoodSpirit ), typeof( Bonesmasher ),
|
||||
typeof( Boomstick ), typeof( BrightsightLenses ), typeof( FeyLeggings ), typeof( FleshRipper ),
|
||||
typeof( HelmOfSwiftness ), typeof( PadsOfTheCuSidhe ), typeof( QuiverOfRage ), typeof( QuiverOfElements ),
|
||||
typeof( RaedsGlory ), typeof( RighteousAnger ), typeof( RobeOfTheEclipse ), typeof( RobeOfTheEquinox ),
|
||||
typeof( SoulSeeker ), typeof( TalonBite ), typeof( TotemOfVoid ), typeof( WildfireBow ),
|
||||
typeof( Windsong )
|
||||
};
|
||||
|
||||
public static bool CheckArtifactChance( Mobile m, BaseCreature bc )
|
||||
{
|
||||
if ( !Core.ML )
|
||||
return false;
|
||||
|
||||
return Paragon.CheckArtifactChance( m, bc );
|
||||
}
|
||||
|
||||
public static void GiveArtifactTo( Mobile m )
|
||||
{
|
||||
Item item = Activator.CreateInstance( m_Artifacts[Utility.Random( m_Artifacts.Length )] ) as Item;
|
||||
|
||||
if ( item == null )
|
||||
return;
|
||||
|
||||
if ( m.AddToBackpack( item ) )
|
||||
{
|
||||
m.SendLocalizedMessage( 1072223 ); // An item has been placed in your backpack.
|
||||
m.SendLocalizedMessage( 1062317 ); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
|
||||
}
|
||||
else if ( m.BankBox.TryDropItem( m, item, false ) )
|
||||
{
|
||||
m.SendLocalizedMessage( 1072224 ); // An item has been placed in your bank box.
|
||||
m.SendLocalizedMessage( 1062317 ); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
|
||||
}
|
||||
else
|
||||
{
|
||||
// Item was placed at feet by m.AddToBackpack
|
||||
m.SendLocalizedMessage( 1072523 ); // You find an artifact, but your backpack and bank are too full to hold it.
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckML( Mobile from )
|
||||
{
|
||||
return CheckML( from, true );
|
||||
}
|
||||
|
||||
public static bool CheckML( Mobile from, bool message )
|
||||
{
|
||||
if ( from == null || from.NetState == null )
|
||||
return false;
|
||||
|
||||
if ( from.NetState.SupportsExpansion( Expansion.ML ) )
|
||||
return true;
|
||||
|
||||
if ( message )
|
||||
from.SendLocalizedMessage( 1072791 ); // You must upgrade to Mondain's Legacy in order to use that item.
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool IsMLRegion( Region region )
|
||||
{
|
||||
return region.IsPartOf( "Twisted Weald" )
|
||||
|| region.IsPartOf( "Sanctuary" )
|
||||
|| region.IsPartOf( "The Prism of Light" )
|
||||
|| region.IsPartOf( "The Citadel" )
|
||||
|| region.IsPartOf( "Bedlam" )
|
||||
|| region.IsPartOf( "Blighted Grove" )
|
||||
|| region.IsPartOf( "The Painted Caves" )
|
||||
|| region.IsPartOf( "The Palace of Paroxysmus" )
|
||||
|| region.IsPartOf( "Labyrinth" );
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Scripts/Misc/NameList.cs
Normal file
109
Scripts/Misc/NameList.cs
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
using Server;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class NameList
|
||||
{
|
||||
private string m_Type;
|
||||
private string[] m_List;
|
||||
|
||||
public string Type{ get{ return m_Type; } }
|
||||
public string[] List{ get{ return m_List; } }
|
||||
|
||||
public bool ContainsName( string name )
|
||||
{
|
||||
for ( int i = 0; i < m_List.Length; i++ )
|
||||
if ( name == m_List[i] )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public NameList( string type, XmlElement xml )
|
||||
{
|
||||
m_Type = type;
|
||||
m_List = xml.InnerText.Split( ',' );
|
||||
|
||||
for ( int i = 0; i < m_List.Length; ++i )
|
||||
m_List[i] = Utility.Intern( m_List[i].Trim() );
|
||||
}
|
||||
|
||||
public string GetRandomName()
|
||||
{
|
||||
if ( m_List.Length > 0 )
|
||||
return m_List[Utility.Random( m_List.Length )];
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static NameList GetNameList( string type )
|
||||
{
|
||||
NameList n = null;
|
||||
m_Table.TryGetValue( type, out n );
|
||||
return n;
|
||||
}
|
||||
|
||||
public static string RandomName( string type )
|
||||
{
|
||||
NameList list = GetNameList( type );
|
||||
|
||||
if ( list != null )
|
||||
return list.GetRandomName();
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static Dictionary<string, NameList> m_Table;
|
||||
|
||||
static NameList()
|
||||
{
|
||||
m_Table = new Dictionary<string, NameList>( StringComparer.OrdinalIgnoreCase );
|
||||
|
||||
string filePath = Path.Combine( Core.BaseDirectory, "Data/names.xml" );
|
||||
|
||||
if ( !File.Exists( filePath ) )
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
Load( filePath );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
Console.WriteLine( "Warning: Exception caught loading name lists:" );
|
||||
Console.WriteLine( e );
|
||||
}
|
||||
}
|
||||
|
||||
private static void Load( string filePath )
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load( filePath );
|
||||
|
||||
XmlElement root = doc["names"];
|
||||
|
||||
foreach ( XmlElement element in root.GetElementsByTagName( "namelist" ) )
|
||||
{
|
||||
string type = element.GetAttribute( "type" );
|
||||
|
||||
if ( String.IsNullOrEmpty( type ) )
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
NameList list = new NameList( type, element );
|
||||
|
||||
m_Table[type] = list;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Scripts/Misc/NameVerification.cs
Normal file
207
Scripts/Misc/NameVerification.cs
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class NameVerification
|
||||
{
|
||||
public static readonly char[] SpaceDashPeriodQuote = new char[]
|
||||
{
|
||||
' ', '-', '.', '\''
|
||||
};
|
||||
|
||||
public static readonly char[] Empty = new char[0];
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "ValidateName", AccessLevel.Administrator, new CommandEventHandler( ValidateName_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "ValidateName" )]
|
||||
[Description( "Checks the result of NameValidation on the specified name." )]
|
||||
public static void ValidateName_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
if ( Validate( e.ArgString, 2, 16, true, false, true, 1, SpaceDashPeriodQuote ) )
|
||||
e.Mobile.SendMessage( 0x59, "That name is considered valid." );
|
||||
else
|
||||
e.Mobile.SendMessage( 0x22, "That name is considered invalid." );
|
||||
}
|
||||
|
||||
public static bool Validate( string name, int minLength, int maxLength, bool allowLetters, bool allowDigits, bool noExceptionsAtStart, int maxExceptions, char[] exceptions )
|
||||
{
|
||||
return Validate( name, minLength, maxLength, allowLetters, allowDigits, noExceptionsAtStart, maxExceptions, exceptions, m_Disallowed, m_StartDisallowed );
|
||||
}
|
||||
|
||||
public static bool Validate( string name, int minLength, int maxLength, bool allowLetters, bool allowDigits, bool noExceptionsAtStart, int maxExceptions, char[] exceptions, string[] disallowed, string[] startDisallowed )
|
||||
{
|
||||
if ( name == null || name.Length < minLength || name.Length > maxLength )
|
||||
return false;
|
||||
|
||||
int exceptCount = 0;
|
||||
|
||||
name = name.ToLower();
|
||||
|
||||
if ( !allowLetters || !allowDigits || (exceptions.Length > 0 && (noExceptionsAtStart || maxExceptions < int.MaxValue)) )
|
||||
{
|
||||
for ( int i = 0; i < name.Length; ++i )
|
||||
{
|
||||
char c = name[i];
|
||||
|
||||
if ( c >= 'a' && c <= 'z' )
|
||||
{
|
||||
if ( !allowLetters )
|
||||
return false;
|
||||
|
||||
exceptCount = 0;
|
||||
}
|
||||
else if ( c >= '0' && c <= '9' )
|
||||
{
|
||||
if ( !allowDigits )
|
||||
return false;
|
||||
|
||||
exceptCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool except = false;
|
||||
|
||||
for ( int j = 0; !except && j < exceptions.Length; ++j )
|
||||
if ( c == exceptions[j] )
|
||||
except = true;
|
||||
|
||||
if ( !except || (i == 0 && noExceptionsAtStart) )
|
||||
return false;
|
||||
|
||||
if ( exceptCount++ == maxExceptions )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < disallowed.Length; ++i )
|
||||
{
|
||||
int indexOf = name.IndexOf( disallowed[i] );
|
||||
|
||||
if ( indexOf == -1 )
|
||||
continue;
|
||||
|
||||
bool badPrefix = ( indexOf == 0 );
|
||||
|
||||
for ( int j = 0; !badPrefix && j < exceptions.Length; ++j )
|
||||
badPrefix = ( name[indexOf - 1] == exceptions[j] );
|
||||
|
||||
if ( !badPrefix )
|
||||
continue;
|
||||
|
||||
bool badSuffix = ( (indexOf + disallowed[i].Length) >= name.Length );
|
||||
|
||||
for ( int j = 0; !badSuffix && j < exceptions.Length; ++j )
|
||||
badSuffix = ( name[indexOf + disallowed[i].Length] == exceptions[j] );
|
||||
|
||||
if ( badSuffix )
|
||||
return false;
|
||||
}
|
||||
|
||||
for ( int i = 0; i < startDisallowed.Length; ++i )
|
||||
{
|
||||
if ( name.StartsWith( startDisallowed[i] ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string[] StartDisallowed { get { return m_StartDisallowed; } }
|
||||
public static string[] Disallowed { get { return m_Disallowed; } }
|
||||
|
||||
private static string[] m_StartDisallowed = new string[]
|
||||
{
|
||||
"seer",
|
||||
"counselor",
|
||||
"gm",
|
||||
"admin",
|
||||
"lady",
|
||||
"lord"
|
||||
};
|
||||
|
||||
private static string[] m_Disallowed = new string[]
|
||||
{
|
||||
"jigaboo",
|
||||
"chigaboo",
|
||||
"wop",
|
||||
"kyke",
|
||||
"kike",
|
||||
"tit",
|
||||
"spic",
|
||||
"prick",
|
||||
"piss",
|
||||
"lezbo",
|
||||
"lesbo",
|
||||
"felatio",
|
||||
"dyke",
|
||||
"dildo",
|
||||
"chinc",
|
||||
"chink",
|
||||
"cunnilingus",
|
||||
"cum",
|
||||
"cocksucker",
|
||||
"cock",
|
||||
"clitoris",
|
||||
"clit",
|
||||
"ass",
|
||||
"hitler",
|
||||
"penis",
|
||||
"nigga",
|
||||
"nigger",
|
||||
"klit",
|
||||
"kunt",
|
||||
"jiz",
|
||||
"jism",
|
||||
"jerkoff",
|
||||
"jackoff",
|
||||
"goddamn",
|
||||
"fag",
|
||||
"blowjob",
|
||||
"bitch",
|
||||
"asshole",
|
||||
"dick",
|
||||
"pussy",
|
||||
"snatch",
|
||||
"cunt",
|
||||
"twat",
|
||||
"shit",
|
||||
"fuck",
|
||||
"tailor",
|
||||
"smith",
|
||||
"scholar",
|
||||
"rogue",
|
||||
"novice",
|
||||
"neophyte",
|
||||
"merchant",
|
||||
"medium",
|
||||
"master",
|
||||
"mage",
|
||||
"lb",
|
||||
"journeyman",
|
||||
"grandmaster",
|
||||
"fisherman",
|
||||
"expert",
|
||||
"chef",
|
||||
"carpenter",
|
||||
"british",
|
||||
"blackthorne",
|
||||
"blackthorn",
|
||||
"beggar",
|
||||
"archer",
|
||||
"apprentice",
|
||||
"adept",
|
||||
"gamemaster",
|
||||
"frozen",
|
||||
"squelched",
|
||||
"invulnerable",
|
||||
"osi",
|
||||
"origin"
|
||||
};
|
||||
}
|
||||
}
|
||||
527
Scripts/Misc/Notoriety.cs
Normal file
527
Scripts/Misc/Notoriety.cs
Normal file
|
|
@ -0,0 +1,527 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Guilds;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Factions;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class NotorietyHandlers
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
Notoriety.Hues[Notoriety.Innocent] = 0x59;
|
||||
Notoriety.Hues[Notoriety.Ally] = 0x3F;
|
||||
Notoriety.Hues[Notoriety.CanBeAttacked] = 0x3B2;
|
||||
Notoriety.Hues[Notoriety.Criminal] = 0x3B2;
|
||||
Notoriety.Hues[Notoriety.Enemy] = 0x90;
|
||||
Notoriety.Hues[Notoriety.Murderer] = 0x22;
|
||||
Notoriety.Hues[Notoriety.Invulnerable] = 0x35;
|
||||
|
||||
Notoriety.Handler = new NotorietyHandler( MobileNotoriety );
|
||||
|
||||
Mobile.AllowBeneficialHandler = new AllowBeneficialHandler( Mobile_AllowBeneficial );
|
||||
Mobile.AllowHarmfulHandler = new AllowHarmfulHandler( Mobile_AllowHarmful );
|
||||
}
|
||||
|
||||
private enum GuildStatus { None, Peaceful, Waring }
|
||||
|
||||
private static GuildStatus GetGuildStatus( Mobile m )
|
||||
{
|
||||
if( m.Guild == null )
|
||||
return GuildStatus.None;
|
||||
else if( ((Guild)m.Guild).Enemies.Count == 0 && m.Guild.Type == GuildType.Regular )
|
||||
return GuildStatus.Peaceful;
|
||||
|
||||
return GuildStatus.Waring;
|
||||
}
|
||||
|
||||
private static bool CheckBeneficialStatus( GuildStatus from, GuildStatus target )
|
||||
{
|
||||
if( from == GuildStatus.Waring || target == GuildStatus.Waring )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*private static bool CheckHarmfulStatus( GuildStatus from, GuildStatus target )
|
||||
{
|
||||
if ( from == GuildStatus.Waring && target == GuildStatus.Waring )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}*/
|
||||
|
||||
public static bool Mobile_AllowBeneficial( Mobile from, Mobile target )
|
||||
{
|
||||
if( from == null || target == null || from.AccessLevel > AccessLevel.Player || target.AccessLevel > AccessLevel.Player )
|
||||
return true;
|
||||
|
||||
#region Dueling
|
||||
PlayerMobile pmFrom = from as PlayerMobile;
|
||||
PlayerMobile pmTarg = target as PlayerMobile;
|
||||
|
||||
if( pmFrom == null && from is BaseCreature )
|
||||
{
|
||||
BaseCreature bcFrom = (BaseCreature)from;
|
||||
|
||||
if( bcFrom.Summoned )
|
||||
pmFrom = bcFrom.SummonMaster as PlayerMobile;
|
||||
}
|
||||
|
||||
if( pmTarg == null && target is BaseCreature )
|
||||
{
|
||||
BaseCreature bcTarg = (BaseCreature)target;
|
||||
|
||||
if( bcTarg.Summoned )
|
||||
pmTarg = bcTarg.SummonMaster as PlayerMobile;
|
||||
}
|
||||
|
||||
if( pmFrom != null && pmTarg != null )
|
||||
{
|
||||
if( pmFrom.DuelContext != pmTarg.DuelContext && ((pmFrom.DuelContext != null && pmFrom.DuelContext.Started) || (pmTarg.DuelContext != null && pmTarg.DuelContext.Started)) )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext == pmTarg.DuelContext && ((pmFrom.DuelContext.StartedReadyCountdown && !pmFrom.DuelContext.Started) || pmFrom.DuelContext.Tied || pmFrom.DuelPlayer.Eliminated || pmTarg.DuelPlayer.Eliminated) )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelPlayer != null && !pmFrom.DuelPlayer.Eliminated && pmFrom.DuelContext != null && pmFrom.DuelContext.IsSuddenDeath )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext == pmTarg.DuelContext && pmFrom.DuelContext.m_Tournament != null && pmFrom.DuelContext.m_Tournament.IsNotoRestricted && pmFrom.DuelPlayer != null && pmTarg.DuelPlayer != null && pmFrom.DuelPlayer.Participant != pmTarg.DuelPlayer.Participant )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext == pmTarg.DuelContext && pmFrom.DuelContext.Started )
|
||||
return true;
|
||||
}
|
||||
|
||||
if( (pmFrom != null && pmFrom.DuelContext != null && pmFrom.DuelContext.Started) || (pmTarg != null && pmTarg.DuelContext != null && pmTarg.DuelContext.Started) )
|
||||
return false;
|
||||
|
||||
Engines.ConPVP.SafeZone sz = from.Region.GetRegion( typeof( Engines.ConPVP.SafeZone ) ) as Engines.ConPVP.SafeZone;
|
||||
|
||||
if( sz != null /*&& sz.IsDisabled()*/ )
|
||||
return false;
|
||||
|
||||
sz = target.Region.GetRegion( typeof( Engines.ConPVP.SafeZone ) ) as Engines.ConPVP.SafeZone;
|
||||
|
||||
if( sz != null /*&& sz.IsDisabled()*/ )
|
||||
return false;
|
||||
#endregion
|
||||
|
||||
Map map = from.Map;
|
||||
|
||||
#region Factions
|
||||
Faction targetFaction = Faction.Find( target, true );
|
||||
|
||||
if( (!Core.ML || map == Faction.Facet) && targetFaction != null )
|
||||
{
|
||||
if( Faction.Find( from, true ) != targetFaction )
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
if( map != null && (map.Rules & MapRules.BeneficialRestrictions) == 0 )
|
||||
return true; // In felucca, anything goes
|
||||
|
||||
if( !from.Player )
|
||||
return true; // NPCs have no restrictions
|
||||
|
||||
if( target is BaseCreature && !((BaseCreature)target).Controlled )
|
||||
return false; // Players cannot heal uncontrolled mobiles
|
||||
|
||||
if( from is PlayerMobile && ((PlayerMobile)from).Young && (!(target is PlayerMobile) || !((PlayerMobile)target).Young) )
|
||||
return false; // Young players cannot perform beneficial actions towards older players
|
||||
|
||||
Guild fromGuild = from.Guild as Guild;
|
||||
Guild targetGuild = target.Guild as Guild;
|
||||
|
||||
if( fromGuild != null && targetGuild != null && (targetGuild == fromGuild || fromGuild.IsAlly( targetGuild )) )
|
||||
return true; // Guild members can be beneficial
|
||||
|
||||
return CheckBeneficialStatus( GetGuildStatus( from ), GetGuildStatus( target ) );
|
||||
}
|
||||
|
||||
public static bool Mobile_AllowHarmful( Mobile from, Mobile target )
|
||||
{
|
||||
if( from == null || target == null || from.AccessLevel > AccessLevel.Player || target.AccessLevel > AccessLevel.Player )
|
||||
return true;
|
||||
|
||||
#region Dueling
|
||||
PlayerMobile pmFrom = from as PlayerMobile;
|
||||
PlayerMobile pmTarg = target as PlayerMobile;
|
||||
|
||||
if( pmFrom == null && from is BaseCreature )
|
||||
{
|
||||
BaseCreature bcFrom = (BaseCreature)from;
|
||||
|
||||
if( bcFrom.Summoned )
|
||||
pmFrom = bcFrom.SummonMaster as PlayerMobile;
|
||||
}
|
||||
|
||||
if( pmTarg == null && target is BaseCreature )
|
||||
{
|
||||
BaseCreature bcTarg = (BaseCreature)target;
|
||||
|
||||
if( bcTarg.Summoned )
|
||||
pmTarg = bcTarg.SummonMaster as PlayerMobile;
|
||||
}
|
||||
|
||||
if( pmFrom != null && pmTarg != null )
|
||||
{
|
||||
if( pmFrom.DuelContext != pmTarg.DuelContext && ((pmFrom.DuelContext != null && pmFrom.DuelContext.Started) || (pmTarg.DuelContext != null && pmTarg.DuelContext.Started)) )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext == pmTarg.DuelContext && ((pmFrom.DuelContext.StartedReadyCountdown && !pmFrom.DuelContext.Started) || pmFrom.DuelContext.Tied || pmFrom.DuelPlayer.Eliminated || pmTarg.DuelPlayer.Eliminated) )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext == pmTarg.DuelContext && pmFrom.DuelContext.m_Tournament != null && pmFrom.DuelContext.m_Tournament.IsNotoRestricted && pmFrom.DuelPlayer != null && pmTarg.DuelPlayer != null && pmFrom.DuelPlayer.Participant == pmTarg.DuelPlayer.Participant )
|
||||
return false;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext == pmTarg.DuelContext && pmFrom.DuelContext.Started )
|
||||
return true;
|
||||
}
|
||||
|
||||
if( (pmFrom != null && pmFrom.DuelContext != null && pmFrom.DuelContext.Started) || (pmTarg != null && pmTarg.DuelContext != null && pmTarg.DuelContext.Started) )
|
||||
return false;
|
||||
|
||||
Engines.ConPVP.SafeZone sz = from.Region.GetRegion( typeof( Engines.ConPVP.SafeZone ) ) as Engines.ConPVP.SafeZone;
|
||||
|
||||
if( sz != null /*&& sz.IsDisabled()*/ )
|
||||
return false;
|
||||
|
||||
sz = target.Region.GetRegion( typeof( Engines.ConPVP.SafeZone ) ) as Engines.ConPVP.SafeZone;
|
||||
|
||||
if( sz != null /*&& sz.IsDisabled()*/ )
|
||||
return false;
|
||||
#endregion
|
||||
|
||||
Map map = from.Map;
|
||||
|
||||
if( map != null && (map.Rules & MapRules.HarmfulRestrictions) == 0 )
|
||||
return true; // In felucca, anything goes
|
||||
|
||||
BaseCreature bc = from as BaseCreature;
|
||||
|
||||
if( !from.Player && !(bc != null && bc.GetMaster() != null && bc.GetMaster().AccessLevel == AccessLevel.Player ) )
|
||||
{
|
||||
if( !CheckAggressor( from.Aggressors, target ) && !CheckAggressed( from.Aggressed, target ) && target is PlayerMobile && ((PlayerMobile)target).CheckYoungProtection( from ) )
|
||||
return false;
|
||||
|
||||
return true; // Uncontrolled NPCs are only restricted by the young system
|
||||
}
|
||||
|
||||
Guild fromGuild = GetGuildFor( from.Guild as Guild, from );
|
||||
Guild targetGuild = GetGuildFor( target.Guild as Guild, target );
|
||||
|
||||
if( fromGuild != null && targetGuild != null && (fromGuild == targetGuild || fromGuild.IsAlly( targetGuild ) || fromGuild.IsEnemy( targetGuild )) )
|
||||
return true; // Guild allies or enemies can be harmful
|
||||
|
||||
if( target is BaseCreature && (((BaseCreature)target).Controlled || (((BaseCreature)target).Summoned && from != ((BaseCreature)target).SummonMaster)) )
|
||||
return false; // Cannot harm other controlled mobiles
|
||||
|
||||
if( target.Player )
|
||||
return false; // Cannot harm other players
|
||||
|
||||
if( !(target is BaseCreature && ((BaseCreature)target).InitialInnocent) )
|
||||
{
|
||||
if( Notoriety.Compute( from, target ) == Notoriety.Innocent )
|
||||
return false; // Cannot harm innocent mobiles
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Guild GetGuildFor( Guild def, Mobile m )
|
||||
{
|
||||
Guild g = def;
|
||||
|
||||
BaseCreature c = m as BaseCreature;
|
||||
|
||||
if( c != null && c.Controlled && c.ControlMaster != null )
|
||||
{
|
||||
c.DisplayGuildTitle = false;
|
||||
|
||||
if( c.Map != Map.Internal && (Core.AOS || Guild.NewGuildSystem || c.ControlOrder == OrderType.Attack || c.ControlOrder == OrderType.Guard) )
|
||||
g = (Guild)(c.Guild = c.ControlMaster.Guild);
|
||||
else if( c.Map == Map.Internal || c.ControlMaster.Guild == null )
|
||||
g = (Guild)(c.Guild = null);
|
||||
}
|
||||
|
||||
return g;
|
||||
}
|
||||
|
||||
public static int CorpseNotoriety( Mobile source, Corpse target )
|
||||
{
|
||||
if( target.AccessLevel > AccessLevel.Player )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
Body body = (Body)target.Amount;
|
||||
|
||||
BaseCreature cretOwner = target.Owner as BaseCreature;
|
||||
|
||||
if( cretOwner != null )
|
||||
{
|
||||
Guild sourceGuild = GetGuildFor( source.Guild as Guild, source );
|
||||
Guild targetGuild = GetGuildFor( target.Guild as Guild, target.Owner );
|
||||
|
||||
if( sourceGuild != null && targetGuild != null )
|
||||
{
|
||||
if( sourceGuild == targetGuild || sourceGuild.IsAlly( targetGuild ) )
|
||||
return Notoriety.Ally;
|
||||
else if( sourceGuild.IsEnemy( targetGuild ) )
|
||||
return Notoriety.Enemy;
|
||||
}
|
||||
|
||||
Faction srcFaction = Faction.Find( source, true, true );
|
||||
Faction trgFaction = Faction.Find( target.Owner, true, true );
|
||||
|
||||
if( srcFaction != null && trgFaction != null && srcFaction != trgFaction && source.Map == Faction.Facet )
|
||||
return Notoriety.Enemy;
|
||||
|
||||
if( CheckHouseFlag( source, target.Owner, target.Location, target.Map ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
int actual = Notoriety.CanBeAttacked;
|
||||
|
||||
if( target.Kills >= 5 || (body.IsMonster && IsSummoned( target.Owner as BaseCreature )) || (target.Owner is BaseCreature && (((BaseCreature)target.Owner).AlwaysMurderer || ((BaseCreature)target.Owner).IsAnimatedDead)) )
|
||||
actual = Notoriety.Murderer;
|
||||
|
||||
if( DateTime.UtcNow >= (target.TimeOfDeath + Corpse.MonsterLootRightSacrifice) )
|
||||
return actual;
|
||||
|
||||
Party sourceParty = Party.Get( source );
|
||||
|
||||
List<Mobile> list = target.Aggressors;
|
||||
|
||||
for( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
if( list[i] == source || (sourceParty != null && Party.Get( list[i] ) == sourceParty) )
|
||||
return actual;
|
||||
}
|
||||
|
||||
return Notoriety.Innocent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( target.Kills >= 5 || (body.IsMonster && IsSummoned( target.Owner as BaseCreature )) || (target.Owner is BaseCreature && (((BaseCreature)target.Owner).AlwaysMurderer || ((BaseCreature)target.Owner).IsAnimatedDead)) )
|
||||
return Notoriety.Murderer;
|
||||
|
||||
if (target.Criminal && target.Map != null && ((target.Map.Rules & MapRules.HarmfulRestrictions) == 0))
|
||||
return Notoriety.Criminal;
|
||||
|
||||
Guild sourceGuild = GetGuildFor( source.Guild as Guild, source );
|
||||
Guild targetGuild = GetGuildFor( target.Guild as Guild, target.Owner );
|
||||
|
||||
if( sourceGuild != null && targetGuild != null )
|
||||
{
|
||||
if( sourceGuild == targetGuild || sourceGuild.IsAlly( targetGuild ) )
|
||||
return Notoriety.Ally;
|
||||
else if( sourceGuild.IsEnemy( targetGuild ) )
|
||||
return Notoriety.Enemy;
|
||||
}
|
||||
|
||||
Faction srcFaction = Faction.Find( source, true, true );
|
||||
Faction trgFaction = Faction.Find( target.Owner, true, true );
|
||||
|
||||
if( srcFaction != null && trgFaction != null && srcFaction != trgFaction && source.Map == Faction.Facet )
|
||||
{
|
||||
List<Mobile> secondList = target.Aggressors;
|
||||
|
||||
for( int i = 0; i < secondList.Count; ++i )
|
||||
{
|
||||
if( secondList[i] == source || secondList[i] is BaseFactionGuard )
|
||||
return Notoriety.Enemy;
|
||||
}
|
||||
}
|
||||
|
||||
if( target.Owner != null && target.Owner is BaseCreature && ((BaseCreature)target.Owner).AlwaysAttackable )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( CheckHouseFlag( source, target.Owner, target.Location, target.Map ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( !(target.Owner is PlayerMobile) && !IsPet( target.Owner as BaseCreature ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
List<Mobile> list = target.Aggressors;
|
||||
|
||||
for( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
if( list[i] == source )
|
||||
return Notoriety.CanBeAttacked;
|
||||
}
|
||||
|
||||
return Notoriety.Innocent;
|
||||
}
|
||||
}
|
||||
|
||||
/* Must be thread-safe */
|
||||
|
||||
public static int MobileNotoriety( Mobile source, Mobile target )
|
||||
{
|
||||
if ( Core.AOS && ( target.Blessed || ( target is BaseCreature && ( (BaseCreature)target ).IsInvulnerable ) || target is PlayerVendor || target is TownCrier ) )
|
||||
return Notoriety.Invulnerable;
|
||||
|
||||
#region Dueling
|
||||
if( source is PlayerMobile && target is PlayerMobile )
|
||||
{
|
||||
PlayerMobile pmFrom = (PlayerMobile)source;
|
||||
PlayerMobile pmTarg = (PlayerMobile)target;
|
||||
|
||||
if( pmFrom.DuelContext != null && pmFrom.DuelContext.StartedBeginCountdown && !pmFrom.DuelContext.Finished && pmFrom.DuelContext == pmTarg.DuelContext )
|
||||
return pmFrom.DuelContext.IsAlly( pmFrom, pmTarg ) ? Notoriety.Ally : Notoriety.Enemy;
|
||||
}
|
||||
#endregion
|
||||
|
||||
if( target.AccessLevel > AccessLevel.Player )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( source.Player && !target.Player && source is PlayerMobile && target is BaseCreature )
|
||||
{
|
||||
BaseCreature bc = (BaseCreature)target;
|
||||
|
||||
Mobile master = bc.GetMaster();
|
||||
|
||||
if ( master != null && master.AccessLevel > AccessLevel.Player )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
master = bc.ControlMaster;
|
||||
|
||||
if ( Core.ML && master != null )
|
||||
{
|
||||
if ( ( source == master && CheckAggressor( target.Aggressors, source ) ) || ( CheckAggressor( source.Aggressors, bc ) ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
else
|
||||
return MobileNotoriety( source, master );
|
||||
}
|
||||
|
||||
if( !bc.Summoned && !bc.Controlled && ((PlayerMobile)source).EnemyOfOneType == target.GetType() )
|
||||
return Notoriety.Enemy;
|
||||
}
|
||||
|
||||
if ( target.Kills >= 5 || ( target.Body.IsMonster && IsSummoned( target as BaseCreature ) && !( target is BaseFamiliar ) && !( target is ArcaneFey ) && !( target is Golem ) ) || ( target is BaseCreature && ( ( (BaseCreature)target ).AlwaysMurderer || ( (BaseCreature)target ).IsAnimatedDead ) ) )
|
||||
return Notoriety.Murderer;
|
||||
|
||||
if( target.Criminal )
|
||||
return Notoriety.Criminal;
|
||||
|
||||
Guild sourceGuild = GetGuildFor( source.Guild as Guild, source );
|
||||
Guild targetGuild = GetGuildFor( target.Guild as Guild, target );
|
||||
|
||||
if( sourceGuild != null && targetGuild != null )
|
||||
{
|
||||
if( sourceGuild == targetGuild || sourceGuild.IsAlly( targetGuild ) )
|
||||
return Notoriety.Ally;
|
||||
else if( sourceGuild.IsEnemy( targetGuild ) )
|
||||
return Notoriety.Enemy;
|
||||
}
|
||||
|
||||
Faction srcFaction = Faction.Find( source, true, true );
|
||||
Faction trgFaction = Faction.Find( target, true, true );
|
||||
|
||||
if( srcFaction != null && trgFaction != null && srcFaction != trgFaction && source.Map == Faction.Facet )
|
||||
return Notoriety.Enemy;
|
||||
|
||||
if( SkillHandlers.Stealing.ClassicMode && target is PlayerMobile && ((PlayerMobile)target).PermaFlags.Contains( source ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( target is BaseCreature && ((BaseCreature)target).AlwaysAttackable )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( CheckHouseFlag( source, target, target.Location, target.Map ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( !(target is BaseCreature && ((BaseCreature)target).InitialInnocent) ) //If Target is NOT A baseCreature, OR it's a BC and the BC is initial innocent...
|
||||
{
|
||||
if( !target.Body.IsHuman && !target.Body.IsGhost && !IsPet( target as BaseCreature ) && !(target is PlayerMobile) || !Core.ML && !target.CanBeginAction( typeof( Server.Spells.Seventh.PolymorphSpell ) ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
}
|
||||
|
||||
if( CheckAggressor( source.Aggressors, target ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( CheckAggressed( source.Aggressed, target ) )
|
||||
return Notoriety.CanBeAttacked;
|
||||
|
||||
if( target is BaseCreature )
|
||||
{
|
||||
BaseCreature bc = (BaseCreature)target;
|
||||
|
||||
if( bc.Controlled && bc.ControlOrder == OrderType.Guard && bc.ControlTarget == source )
|
||||
return Notoriety.CanBeAttacked;
|
||||
}
|
||||
|
||||
if( source is BaseCreature )
|
||||
{
|
||||
BaseCreature bc = (BaseCreature)source;
|
||||
Mobile master = bc.GetMaster();
|
||||
|
||||
if( master != null )
|
||||
if( CheckAggressor( master.Aggressors, target ) || MobileNotoriety( master, target ) == Notoriety.CanBeAttacked || target is BaseCreature )
|
||||
return Notoriety.CanBeAttacked;
|
||||
}
|
||||
|
||||
return Notoriety.Innocent;
|
||||
}
|
||||
|
||||
public static bool CheckHouseFlag( Mobile from, Mobile m, Point3D p, Map map )
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( p, map, 16 );
|
||||
|
||||
if( house == null || house.Public || !house.IsFriend( from ) )
|
||||
return false;
|
||||
|
||||
if( m != null && house.IsFriend( m ) )
|
||||
return false;
|
||||
|
||||
BaseCreature c = m as BaseCreature;
|
||||
|
||||
if( c != null && !c.Deleted && c.Controlled && c.ControlMaster != null )
|
||||
return !house.IsFriend( c.ControlMaster );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool IsPet( BaseCreature c )
|
||||
{
|
||||
return (c != null && c.Controlled);
|
||||
}
|
||||
|
||||
public static bool IsSummoned( BaseCreature c )
|
||||
{
|
||||
return (c != null && /*c.Controlled &&*/ c.Summoned);
|
||||
}
|
||||
|
||||
public static bool CheckAggressor( List<AggressorInfo> list, Mobile target )
|
||||
{
|
||||
for( int i = 0; i < list.Count; ++i )
|
||||
if( list[i].Attacker == target )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CheckAggressed( List<AggressorInfo> list, Mobile target )
|
||||
{
|
||||
for( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
AggressorInfo info = list[i];
|
||||
|
||||
if( !info.CriminalAggression && info.Defender == target )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Scripts/Misc/Paperdoll.cs
Normal file
36
Scripts/Misc/Paperdoll.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Multis;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Paperdoll
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.PaperdollRequest += new PaperdollRequestEventHandler( EventSink_PaperdollRequest );
|
||||
}
|
||||
|
||||
public static void EventSink_PaperdollRequest( PaperdollRequestEventArgs e )
|
||||
{
|
||||
Mobile beholder = e.Beholder;
|
||||
Mobile beheld = e.Beheld;
|
||||
|
||||
beholder.Send( new DisplayPaperdoll( beheld, Titles.ComputeTitle( beholder, beheld ), beheld.AllowEquipFrom( beholder ) ) );
|
||||
|
||||
if ( ObjectPropertyList.Enabled )
|
||||
{
|
||||
List<Item> items = beheld.Items;
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
beholder.Send( items[i].OPLPacket );
|
||||
|
||||
// NOTE: OSI sends MobileUpdate when opening your own paperdoll.
|
||||
// It has a very bad rubber-banding affect. What positive affects does it have?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
156
Scripts/Misc/Poison.cs
Normal file
156
Scripts/Misc/Poison.cs
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Spells.Ninjitsu;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class PoisonImpl : Poison
|
||||
{
|
||||
[CallPriority( 10 )]
|
||||
public static void Configure()
|
||||
{
|
||||
if ( Core.AOS )
|
||||
{
|
||||
Register( new PoisonImpl( "Lesser", 0, 4, 16, 7.5, 3.0, 2.25, 10, 4 ) );
|
||||
Register( new PoisonImpl( "Regular", 1, 8, 18, 10.0, 3.0, 3.25, 10, 3 ) );
|
||||
Register( new PoisonImpl( "Greater", 2, 12, 20, 15.0, 3.0, 4.25, 10, 2 ) );
|
||||
Register( new PoisonImpl( "Deadly", 3, 16, 30, 30.0, 3.0, 5.25, 15, 2 ) );
|
||||
Register( new PoisonImpl( "Lethal", 4, 20, 50, 35.0, 3.0, 5.25, 20, 2 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
Register( new PoisonImpl( "Lesser", 0, 4, 26, 2.500, 3.5, 3.0, 10, 2 ) );
|
||||
Register( new PoisonImpl( "Regular", 1, 5, 26, 3.125, 3.5, 3.0, 10, 2 ) );
|
||||
Register( new PoisonImpl( "Greater", 2, 6, 26, 6.250, 3.5, 3.0, 10, 2 ) );
|
||||
Register( new PoisonImpl( "Deadly", 3, 7, 26, 12.500, 3.5, 4.0, 10, 2 ) );
|
||||
Register( new PoisonImpl( "Lethal", 4, 9, 26, 25.000, 3.5, 5.0, 10, 2 ) );
|
||||
}
|
||||
}
|
||||
|
||||
public static Poison IncreaseLevel( Poison oldPoison )
|
||||
{
|
||||
Poison newPoison = ( oldPoison == null ? null : GetPoison( oldPoison.Level + 1 ) );
|
||||
|
||||
return ( newPoison == null ? oldPoison : newPoison );
|
||||
}
|
||||
|
||||
// Info
|
||||
private string m_Name;
|
||||
private int m_Level;
|
||||
|
||||
// Damage
|
||||
private int m_Minimum, m_Maximum;
|
||||
private double m_Scalar;
|
||||
|
||||
// Timers
|
||||
private TimeSpan m_Delay;
|
||||
private TimeSpan m_Interval;
|
||||
private int m_Count, m_MessageInterval;
|
||||
|
||||
public PoisonImpl( string name, int level, int min, int max, double percent, double delay, double interval, int count, int messageInterval )
|
||||
{
|
||||
m_Name = name;
|
||||
m_Level = level;
|
||||
m_Minimum = min;
|
||||
m_Maximum = max;
|
||||
m_Scalar = percent * 0.01;
|
||||
m_Delay = TimeSpan.FromSeconds( delay );
|
||||
m_Interval = TimeSpan.FromSeconds( interval );
|
||||
m_Count = count;
|
||||
m_MessageInterval = messageInterval;
|
||||
}
|
||||
|
||||
public override string Name{ get{ return m_Name; } }
|
||||
public override int Level{ get{ return m_Level; } }
|
||||
|
||||
public class PoisonTimer : Timer
|
||||
{
|
||||
private PoisonImpl m_Poison;
|
||||
private Mobile m_Mobile;
|
||||
private Mobile m_From;
|
||||
private int m_LastDamage;
|
||||
private int m_Index;
|
||||
|
||||
public Mobile From{ get{ return m_From; } set{ m_From = value; } }
|
||||
|
||||
public PoisonTimer( Mobile m, PoisonImpl p ) : base( p.m_Delay, p.m_Interval )
|
||||
{
|
||||
m_From = m;
|
||||
m_Mobile = m;
|
||||
m_Poison = p;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( (Core.AOS && m_Poison.Level < 4 && TransformationSpellHelper.UnderTransformation( m_Mobile, typeof( VampiricEmbraceSpell ) )) ||
|
||||
(m_Poison.Level < 3 && OrangePetals.UnderEffect( m_Mobile )) ||
|
||||
AnimalForm.UnderTransformation( m_Mobile, typeof( Unicorn ) ) )
|
||||
{
|
||||
if ( m_Mobile.CurePoison( m_Mobile ) )
|
||||
{
|
||||
m_Mobile.LocalOverheadMessage( MessageType.Emote, 0x3F, true,
|
||||
"* You feel yourself resisting the effects of the poison *" );
|
||||
|
||||
m_Mobile.NonlocalOverheadMessage( MessageType.Emote, 0x3F, true,
|
||||
String.Format( "* {0} seems resistant to the poison *", m_Mobile.Name ) );
|
||||
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_Index++ == m_Poison.m_Count )
|
||||
{
|
||||
m_Mobile.SendLocalizedMessage( 502136 ); // The poison seems to have worn off.
|
||||
m_Mobile.Poison = null;
|
||||
|
||||
Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
int damage;
|
||||
|
||||
if ( !Core.AOS && m_LastDamage != 0 && Utility.RandomBool() )
|
||||
{
|
||||
damage = m_LastDamage;
|
||||
}
|
||||
else
|
||||
{
|
||||
damage = 1 + (int)(m_Mobile.Hits * m_Poison.m_Scalar);
|
||||
|
||||
if ( damage < m_Poison.m_Minimum )
|
||||
damage = m_Poison.m_Minimum;
|
||||
else if ( damage > m_Poison.m_Maximum )
|
||||
damage = m_Poison.m_Maximum;
|
||||
|
||||
m_LastDamage = damage;
|
||||
}
|
||||
|
||||
if ( m_From != null )
|
||||
m_From.DoHarmful( m_Mobile, true );
|
||||
|
||||
IHonorTarget honorTarget = m_Mobile as IHonorTarget;
|
||||
if ( honorTarget != null && honorTarget.ReceivedHonorContext != null )
|
||||
honorTarget.ReceivedHonorContext.OnTargetPoisoned();
|
||||
|
||||
AOS.Damage( m_Mobile, m_From, damage, 0, 0, 0, 100, 0 );
|
||||
|
||||
if ( 0.60 <= Utility.RandomDouble() ) // OSI: randomly revealed between first and third damage tick, guessing 60% chance
|
||||
m_Mobile.RevealingAction();
|
||||
|
||||
if ( (m_Index % m_Poison.m_MessageInterval) == 0 )
|
||||
m_Mobile.OnPoisoned( m_From, m_Poison, m_Poison );
|
||||
}
|
||||
}
|
||||
|
||||
public override Timer ConstructTimer( Mobile m )
|
||||
{
|
||||
return new PoisonTimer( m, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
124
Scripts/Misc/ProfanityProtection.cs
Normal file
124
Scripts/Misc/ProfanityProtection.cs
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public enum ProfanityAction
|
||||
{
|
||||
None, // no action taken
|
||||
Disallow, // speech is not displayed
|
||||
Criminal, // makes the player criminal, not killable by guards
|
||||
CriminalAction, // makes the player criminal, can be killed by guards
|
||||
Disconnect, // player is kicked
|
||||
Other // some other implementation
|
||||
}
|
||||
|
||||
public class ProfanityProtection
|
||||
{
|
||||
private static bool Enabled = false;
|
||||
private static ProfanityAction Action = ProfanityAction.Disallow; // change here what to do when profanity is detected
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( Enabled )
|
||||
EventSink.Speech += new SpeechEventHandler( EventSink_Speech );
|
||||
}
|
||||
|
||||
private static bool OnProfanityDetected( Mobile from, string speech )
|
||||
{
|
||||
switch ( Action )
|
||||
{
|
||||
case ProfanityAction.None: return true;
|
||||
case ProfanityAction.Disallow: return false;
|
||||
case ProfanityAction.Criminal: from.Criminal = true; return true;
|
||||
case ProfanityAction.CriminalAction: from.CriminalAction( false ); return true;
|
||||
case ProfanityAction.Disconnect:
|
||||
{
|
||||
NetState ns = from.NetState;
|
||||
|
||||
if ( ns != null )
|
||||
ns.Dispose();
|
||||
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
case ProfanityAction.Other: // TODO: Provide custom implementation if this is chosen
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void EventSink_Speech( SpeechEventArgs e )
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if ( from.AccessLevel > AccessLevel.Player )
|
||||
return;
|
||||
|
||||
if ( !NameVerification.Validate( e.Speech, 0, int.MaxValue, true, true, false, int.MaxValue, m_Exceptions, m_Disallowed, m_StartDisallowed ) )
|
||||
e.Blocked = !OnProfanityDetected( from, e.Speech );
|
||||
}
|
||||
|
||||
public static char[] Exceptions{ get{ return m_Exceptions; } }
|
||||
public static string[] StartDisallowed{ get{ return m_StartDisallowed; } }
|
||||
public static string[] Disallowed{ get{ return m_Disallowed; } }
|
||||
|
||||
private static char[] m_Exceptions = new char[]
|
||||
{
|
||||
' ', '-', '.', '\'', '"', ',', '_', '+', '=', '~', '`', '!', '^', '*', '\\', '/', ';', ':', '<', '>', '[', ']', '{', '}', '?', '|', '(', ')', '%', '$', '&', '#', '@'
|
||||
};
|
||||
|
||||
private static string[] m_StartDisallowed = new string[]{};
|
||||
|
||||
private static string[] m_Disallowed = new string[]
|
||||
{
|
||||
"jigaboo",
|
||||
"chigaboo",
|
||||
"wop",
|
||||
"kyke",
|
||||
"kike",
|
||||
"tit",
|
||||
"spic",
|
||||
"prick",
|
||||
"piss",
|
||||
"lezbo",
|
||||
"lesbo",
|
||||
"felatio",
|
||||
"dyke",
|
||||
"dildo",
|
||||
"chinc",
|
||||
"chink",
|
||||
"cunnilingus",
|
||||
"cum",
|
||||
"cocksucker",
|
||||
"cock",
|
||||
"clitoris",
|
||||
"clit",
|
||||
"ass",
|
||||
"hitler",
|
||||
"penis",
|
||||
"nigga",
|
||||
"nigger",
|
||||
"klit",
|
||||
"kunt",
|
||||
"jiz",
|
||||
"jism",
|
||||
"jerkoff",
|
||||
"jackoff",
|
||||
"goddamn",
|
||||
"fag",
|
||||
"blowjob",
|
||||
"bitch",
|
||||
"asshole",
|
||||
"dick",
|
||||
"pussy",
|
||||
"snatch",
|
||||
"cunt",
|
||||
"twat",
|
||||
"shit",
|
||||
"fuck"
|
||||
};
|
||||
}
|
||||
}
|
||||
98
Scripts/Misc/Profile.cs
Normal file
98
Scripts/Misc/Profile.cs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Accounting;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Profile
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.ProfileRequest += new ProfileRequestEventHandler( EventSink_ProfileRequest );
|
||||
EventSink.ChangeProfileRequest += new ChangeProfileRequestEventHandler( EventSink_ChangeProfileRequest );
|
||||
}
|
||||
|
||||
public static void EventSink_ChangeProfileRequest( ChangeProfileRequestEventArgs e )
|
||||
{
|
||||
Mobile from = e.Beholder;
|
||||
|
||||
if ( from.ProfileLocked )
|
||||
from.SendMessage( "Your profile is locked. You may not change it." );
|
||||
else
|
||||
from.Profile = e.Text;
|
||||
}
|
||||
|
||||
public static void EventSink_ProfileRequest( ProfileRequestEventArgs e )
|
||||
{
|
||||
Mobile beholder = e.Beholder;
|
||||
Mobile beheld = e.Beheld;
|
||||
|
||||
if ( !beheld.Player )
|
||||
return;
|
||||
|
||||
if ( beholder.Map != beheld.Map || !beholder.InRange( beheld, 12 ) || !beholder.CanSee( beheld ) )
|
||||
return;
|
||||
|
||||
string header = Titles.ComputeTitle( beholder, beheld );
|
||||
|
||||
string footer = "";
|
||||
|
||||
if ( beheld.ProfileLocked )
|
||||
{
|
||||
if ( beholder == beheld )
|
||||
footer = "Your profile has been locked.";
|
||||
else if ( beholder.AccessLevel >= AccessLevel.Counselor )
|
||||
footer = "This profile has been locked.";
|
||||
}
|
||||
|
||||
if ( footer.Length == 0 && beholder == beheld )
|
||||
footer = GetAccountDuration( beheld );
|
||||
|
||||
string body = beheld.Profile;
|
||||
|
||||
if ( body == null || body.Length <= 0 )
|
||||
body = "";
|
||||
|
||||
beholder.Send( new DisplayProfile( beholder != beheld || !beheld.ProfileLocked, beheld, header, body, footer ) );
|
||||
}
|
||||
|
||||
private static string GetAccountDuration( Mobile m )
|
||||
{
|
||||
Account a = m.Account as Account;
|
||||
|
||||
if ( a == null )
|
||||
return "";
|
||||
|
||||
TimeSpan ts = DateTime.UtcNow - a.Created;
|
||||
|
||||
string v;
|
||||
|
||||
if ( Format( ts.TotalDays, "This account is {0} day{1} old.", out v ) )
|
||||
return v;
|
||||
|
||||
if ( Format( ts.TotalHours, "This account is {0} hour{1} old.", out v ) )
|
||||
return v;
|
||||
|
||||
if ( Format( ts.TotalMinutes, "This account is {0} minute{1} old.", out v ) )
|
||||
return v;
|
||||
|
||||
if ( Format( ts.TotalSeconds, "This account is {0} second{1} old.", out v ) )
|
||||
return v;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static bool Format( double value, string format, out string op )
|
||||
{
|
||||
if ( value >= 1.0 )
|
||||
{
|
||||
op = String.Format( format, (int)value, (int)value != 1 ? "s" : "" );
|
||||
return true;
|
||||
}
|
||||
|
||||
op = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
65
Scripts/Misc/ProtocolExtensions.cs
Normal file
65
Scripts/Misc/ProtocolExtensions.cs
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.PartySystem;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class ProtocolExtensions
|
||||
{
|
||||
private static PacketHandler[] m_Handlers = new PacketHandler[0x100];
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
PacketHandlers.Register( 0xF0, 0, false, new OnPacketReceive( DecodeBundledPacket ) );
|
||||
}
|
||||
|
||||
public static void Register( int packetID, bool ingame, OnPacketReceive onReceive )
|
||||
{
|
||||
m_Handlers[packetID] = new PacketHandler( packetID, 0, ingame, onReceive );
|
||||
}
|
||||
|
||||
public static PacketHandler GetHandler( int packetID )
|
||||
{
|
||||
if ( packetID >= 0 && packetID < m_Handlers.Length )
|
||||
return m_Handlers[packetID];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void DecodeBundledPacket( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
int packetID = pvSrc.ReadByte();
|
||||
|
||||
PacketHandler ph = GetHandler( packetID );
|
||||
|
||||
if ( ph != null )
|
||||
{
|
||||
if ( ph.Ingame && state.Mobile == null )
|
||||
{
|
||||
Console.WriteLine( "Client: {0}: Sent ingame packet (0xF0x{1:X2}) before having been attached to a mobile", state, packetID );
|
||||
state.Dispose();
|
||||
}
|
||||
else if ( ph.Ingame && state.Mobile.Deleted )
|
||||
{
|
||||
state.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
ph.OnReceive( state, pvSrc );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class ProtocolExtension : Packet
|
||||
{
|
||||
public ProtocolExtension( int packetID, int capacity ) : base( 0xF0 )
|
||||
{
|
||||
EnsureCapacity( 4 + capacity );
|
||||
|
||||
m_Stream.Write( (byte) packetID );
|
||||
}
|
||||
}
|
||||
}
|
||||
337
Scripts/Misc/RaceDefinitions.cs
Normal file
337
Scripts/Misc/RaceDefinitions.cs
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class RaceDefinitions
|
||||
{
|
||||
public static void Configure()
|
||||
{
|
||||
/* Here we configure all races. Some notes:
|
||||
*
|
||||
* 1) The first 32 races are reserved for core use.
|
||||
* 2) Race 0x7F is reserved for core use.
|
||||
* 3) Race 0xFF is reserved for core use.
|
||||
* 4) Changing or removing any predefined races may cause server instability.
|
||||
*/
|
||||
|
||||
RegisterRace( new Human( 0, 0 ) );
|
||||
RegisterRace( new Elf( 1, 1 ) );
|
||||
RegisterRace( new Gargoyle( 2, 2 ) );
|
||||
}
|
||||
|
||||
public static void RegisterRace( Race race )
|
||||
{
|
||||
Race.Races[race.RaceIndex] = race;
|
||||
Race.AllRaces.Add( race );
|
||||
}
|
||||
|
||||
private class Human : Race
|
||||
{
|
||||
public Human( int raceID, int raceIndex )
|
||||
: base( raceID, raceIndex, "Human", "Humans", 400, 401, 402, 403, Expansion.None )
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ValidateHair( bool female, int itemID )
|
||||
{
|
||||
if( itemID == 0 )
|
||||
return true;
|
||||
|
||||
if( (female && itemID == 0x2048) || (!female && itemID == 0x2046 ) )
|
||||
return false; //Buns & Receeding Hair
|
||||
|
||||
if( itemID >= 0x203B && itemID <= 0x203D )
|
||||
return true;
|
||||
|
||||
if( itemID >= 0x2044 && itemID <= 0x204A )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int RandomHair( bool female ) //Random hair doesn't include baldness
|
||||
{
|
||||
switch( Utility.Random( 9 ) )
|
||||
{
|
||||
case 0: return 0x203B; //Short
|
||||
case 1: return 0x203C; //Long
|
||||
case 2: return 0x203D; //Pony Tail
|
||||
case 3: return 0x2044; //Mohawk
|
||||
case 4: return 0x2045; //Pageboy
|
||||
case 5: return 0x2047; //Afro
|
||||
case 6: return 0x2049; //Pig tails
|
||||
case 7: return 0x204A; //Krisna
|
||||
default: return (female ? 0x2046 : 0x2048); //Buns or Receeding Hair
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ValidateFacialHair( bool female, int itemID )
|
||||
{
|
||||
if( itemID == 0 )
|
||||
return true;
|
||||
|
||||
if( female )
|
||||
return false;
|
||||
|
||||
if( itemID >= 0x203E && itemID <= 0x2041 )
|
||||
return true;
|
||||
|
||||
if( itemID >= 0x204B && itemID <= 0x204D )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int RandomFacialHair( bool female )
|
||||
{
|
||||
if( female )
|
||||
return 0;
|
||||
|
||||
int rand = Utility.Random( 7 );
|
||||
|
||||
return ((rand < 4) ? 0x203E : 0x2047) + rand;
|
||||
}
|
||||
|
||||
public override int ClipSkinHue( int hue )
|
||||
{
|
||||
if( hue < 1002 )
|
||||
return 1002;
|
||||
else if( hue > 1058 )
|
||||
return 1058;
|
||||
else
|
||||
return hue;
|
||||
}
|
||||
|
||||
public override int RandomSkinHue()
|
||||
{
|
||||
return Utility.Random( 1002, 57 ) | 0x8000;
|
||||
}
|
||||
|
||||
public override int ClipHairHue( int hue )
|
||||
{
|
||||
if( hue < 1102 )
|
||||
return 1102;
|
||||
else if( hue > 1149 )
|
||||
return 1149;
|
||||
else
|
||||
return hue;
|
||||
}
|
||||
|
||||
public override int RandomHairHue()
|
||||
{
|
||||
return Utility.Random( 1102, 48 );
|
||||
}
|
||||
}
|
||||
|
||||
private class Elf : Race
|
||||
{
|
||||
private static int[] m_SkinHues = new int[]
|
||||
{
|
||||
0x0BF, 0x24D, 0x24E, 0x24F, 0x353, 0x361, 0x367, 0x374,
|
||||
0x375, 0x376, 0x381, 0x382, 0x383, 0x384, 0x385, 0x389,
|
||||
0x3DE, 0x3E5, 0x3E6, 0x3E8, 0x3E9, 0x430, 0x4A7, 0x4DE,
|
||||
0x51D, 0x53F, 0x579, 0x76B, 0x76C, 0x76D, 0x835, 0x903
|
||||
};
|
||||
|
||||
private static int[] m_HairHues = new int[]
|
||||
{
|
||||
0x034, 0x035, 0x036, 0x037, 0x038, 0x039, 0x058, 0x08E,
|
||||
0x08F, 0x090, 0x091, 0x092, 0x101, 0x159, 0x15A, 0x15B,
|
||||
0x15C, 0x15D, 0x15E, 0x128, 0x12F, 0x1BD, 0x1E4, 0x1F3,
|
||||
0x207, 0x211, 0x239, 0x251, 0x26C, 0x2C3, 0x2C9, 0x31D,
|
||||
0x31E, 0x31F, 0x320, 0x321, 0x322, 0x323, 0x324, 0x325,
|
||||
0x326, 0x369, 0x386, 0x387, 0x388, 0x389, 0x38A, 0x59D,
|
||||
0x6B8, 0x725, 0x853
|
||||
};
|
||||
|
||||
public Elf( int raceID, int raceIndex )
|
||||
: base( raceID, raceIndex, "Elf", "Elves", 605, 606, 607, 608, Expansion.ML )
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ValidateHair( bool female, int itemID )
|
||||
{
|
||||
if( itemID == 0 )
|
||||
return true;
|
||||
|
||||
if( (female && (itemID == 0x2FCD || itemID == 0x2FBF)) || (!female && (itemID == 0x2FCC || itemID == 0x2FD0)) )
|
||||
return false;
|
||||
|
||||
if( itemID >= 0x2FBF && itemID <= 0x2FC2 )
|
||||
return true;
|
||||
|
||||
if( itemID >= 0x2FCC && itemID <= 0x2FD1 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override int RandomHair( bool female ) //Random hair doesn't include baldness
|
||||
{
|
||||
switch( Utility.Random( 8 ) )
|
||||
{
|
||||
case 0: return 0x2FC0; //Long Feather
|
||||
case 1: return 0x2FC1; //Short
|
||||
case 2: return 0x2FC2; //Mullet
|
||||
case 3: return 0x2FCE; //Knob
|
||||
case 4: return 0x2FCF; //Braided
|
||||
case 5: return 0x2FD1; //Spiked
|
||||
case 6: return (female ? 0x2FCC : 0x2FBF); //Flower or Mid-long
|
||||
default: return (female ? 0x2FD0 : 0x2FCD); //Bun or Long
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ValidateFacialHair( bool female, int itemID )
|
||||
{
|
||||
return (itemID == 0);
|
||||
}
|
||||
|
||||
public override int RandomFacialHair( bool female )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override int ClipSkinHue( int hue )
|
||||
{
|
||||
for( int i = 0; i < m_SkinHues.Length; i++ )
|
||||
if( m_SkinHues[i] == hue )
|
||||
return hue;
|
||||
|
||||
return m_SkinHues[0];
|
||||
}
|
||||
|
||||
public override int RandomSkinHue()
|
||||
{
|
||||
return m_SkinHues[Utility.Random( m_SkinHues.Length )] | 0x8000;
|
||||
}
|
||||
|
||||
public override int ClipHairHue( int hue )
|
||||
{
|
||||
for( int i = 0; i < m_HairHues.Length; i++ )
|
||||
if( m_HairHues[i] == hue )
|
||||
return hue;
|
||||
|
||||
return m_HairHues[0];
|
||||
}
|
||||
|
||||
public override int RandomHairHue()
|
||||
{
|
||||
return m_HairHues[Utility.Random( m_HairHues.Length )];
|
||||
}
|
||||
}
|
||||
|
||||
#region SA
|
||||
private class Gargoyle : Race
|
||||
{
|
||||
public Gargoyle(int raceID, int raceIndex)
|
||||
: base(raceID, raceIndex, "Gargoyle", "Gargoyles", 666, 667, 402, 403, Expansion.SA)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool ValidateHair(bool female, int itemID)
|
||||
{
|
||||
if (female == false)
|
||||
{
|
||||
return itemID >= 0x4258 && itemID <= 0x425F;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((itemID == 0x4261 || itemID == 0x4262) || (itemID >= 0x4273 && itemID <= 0x4275) || (itemID == 0x42B0 || itemID == 0x42B1) || (itemID == 0x42AA || itemID == 0x42AB));
|
||||
}
|
||||
}
|
||||
|
||||
public override int RandomHair(bool female)
|
||||
{
|
||||
if (Utility.Random(9) == 0)
|
||||
return 0;
|
||||
else if (!female)
|
||||
return 0x4258 + Utility.Random(8);
|
||||
else
|
||||
{
|
||||
switch (Utility.Random(9))
|
||||
{
|
||||
case 0:
|
||||
return 0x4261;
|
||||
case 1:
|
||||
return 0x4262;
|
||||
case 2:
|
||||
return 0x4273;
|
||||
case 3:
|
||||
return 0x4274;
|
||||
case 4:
|
||||
return 0x4275;
|
||||
case 5:
|
||||
return 0x42B0;
|
||||
case 6:
|
||||
return 0x42B1;
|
||||
case 7:
|
||||
return 0x42AA;
|
||||
case 8:
|
||||
return 0x42AB;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool ValidateFacialHair(bool female, int itemID)
|
||||
{
|
||||
if (female)
|
||||
return false;
|
||||
else
|
||||
return itemID >= 0x42AD && itemID <= 0x42B0;
|
||||
}
|
||||
|
||||
public override int RandomFacialHair(bool female)
|
||||
{
|
||||
if (female)
|
||||
return 0;
|
||||
else
|
||||
return Utility.RandomList(0, 0x42AD, 0x42AE, 0x42AF, 0x42B0);
|
||||
}
|
||||
|
||||
// Todo Finish body hues
|
||||
private static readonly int[] m_BodyHues = new int[]
|
||||
{
|
||||
0x86DB, 0x86DC, 0x86DD, 0x86DE,
|
||||
0x86DF, 0x86E0, 0x86E1, 0x86E2,
|
||||
0x86E3, 0x86E4, 0x86E5, 0x86E6
|
||||
// 0x, 0x, 0x, 0x, // 86E7/86E8/86E9/86EA?
|
||||
// 0x, 0x, 0x, 0x, // 86EB/86EC/86ED/86EE?
|
||||
// 0x86F3, 0x86DB, 0x86DC, 0x86DD
|
||||
};
|
||||
|
||||
public override int ClipSkinHue(int hue)
|
||||
{
|
||||
return hue; // for hue infomation gathering
|
||||
}
|
||||
|
||||
public override int RandomSkinHue()
|
||||
{
|
||||
return m_BodyHues[Utility.Random(m_BodyHues.Length)] | 0x8000;
|
||||
}
|
||||
|
||||
private static readonly int[] m_HornHues = new int[]
|
||||
{
|
||||
0x709, 0x70B, 0x70D, 0x70F, 0x711, 0x763,
|
||||
0x765, 0x768, 0x76B, 0x6F3, 0x6F1, 0x6EF,
|
||||
0x6E4, 0x6E2, 0x6E0, 0x709, 0x70B, 0x70D
|
||||
};
|
||||
|
||||
public override int ClipHairHue(int hue)
|
||||
{
|
||||
for (int i = 0; i < m_HornHues.Length; i++)
|
||||
if (m_HornHues[i] == hue)
|
||||
return hue;
|
||||
|
||||
return m_HornHues[0];
|
||||
}
|
||||
|
||||
public override int RandomHairHue()
|
||||
{
|
||||
return m_HornHues[Utility.Random(m_HornHues.Length)];
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
219
Scripts/Misc/RegenRates.cs
Normal file
219
Scripts/Misc/RegenRates.cs
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Necromancy;
|
||||
using Server.Spells.Ninjitsu;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class RegenRates
|
||||
{
|
||||
[CallPriority( 10 )]
|
||||
public static void Configure()
|
||||
{
|
||||
Mobile.DefaultHitsRate = TimeSpan.FromSeconds( 11.0 );
|
||||
Mobile.DefaultStamRate = TimeSpan.FromSeconds( 7.0 );
|
||||
Mobile.DefaultManaRate = TimeSpan.FromSeconds( 7.0 );
|
||||
|
||||
Mobile.ManaRegenRateHandler = new RegenRateHandler( Mobile_ManaRegenRate );
|
||||
|
||||
if ( Core.AOS )
|
||||
{
|
||||
Mobile.StamRegenRateHandler = new RegenRateHandler( Mobile_StamRegenRate );
|
||||
Mobile.HitsRegenRateHandler = new RegenRateHandler( Mobile_HitsRegenRate );
|
||||
}
|
||||
}
|
||||
|
||||
private static void CheckBonusSkill( Mobile m, int cur, int max, SkillName skill )
|
||||
{
|
||||
if ( !m.Alive )
|
||||
return;
|
||||
|
||||
double n = (double)cur / max;
|
||||
double v = Math.Sqrt( m.Skills[skill].Value * 0.005 );
|
||||
|
||||
n *= (1.0 - v);
|
||||
n += v;
|
||||
|
||||
m.CheckSkill( skill, n );
|
||||
}
|
||||
|
||||
private static bool CheckTransform( Mobile m, Type type )
|
||||
{
|
||||
return TransformationSpellHelper.UnderTransformation( m, type );
|
||||
}
|
||||
|
||||
private static bool CheckAnimal( Mobile m, Type type )
|
||||
{
|
||||
return AnimalForm.UnderTransformation( m, type );
|
||||
}
|
||||
|
||||
private static TimeSpan Mobile_HitsRegenRate( Mobile from )
|
||||
{
|
||||
int points = AosAttributes.GetValue( from, AosAttribute.RegenHits );
|
||||
|
||||
if ( from is BaseCreature && !((BaseCreature)from).IsAnimatedDead )
|
||||
points += 4;
|
||||
|
||||
if ( (from is BaseCreature && ((BaseCreature)from).IsParagon) || from is Leviathan )
|
||||
points += 40;
|
||||
|
||||
if( Core.ML && from.Race == Race.Human ) //Is this affected by the cap?
|
||||
points += 2;
|
||||
|
||||
if ( points < 0 )
|
||||
points = 0;
|
||||
|
||||
if( Core.ML && from is PlayerMobile ) //does racial bonus go before/after?
|
||||
points = Math.Min( points, 18 );
|
||||
|
||||
if ( CheckTransform( from, typeof( HorrificBeastSpell ) ) )
|
||||
points += 20;
|
||||
|
||||
if ( CheckAnimal( from, typeof( Dog ) ) || CheckAnimal( from, typeof( Cat ) ) )
|
||||
points += from.Skills[SkillName.Ninjitsu].Fixed / 30;
|
||||
|
||||
return TimeSpan.FromSeconds( 1.0 / (0.1 * (1 + points)) );
|
||||
}
|
||||
|
||||
private static TimeSpan Mobile_StamRegenRate( Mobile from )
|
||||
{
|
||||
if ( from.Skills == null )
|
||||
return Mobile.DefaultStamRate;
|
||||
|
||||
CheckBonusSkill( from, from.Stam, from.StamMax, SkillName.Focus );
|
||||
|
||||
int points =(int)(from.Skills[SkillName.Focus].Value * 0.1);
|
||||
|
||||
if( (from is BaseCreature && ((BaseCreature)from).IsParagon) || from is Leviathan )
|
||||
points += 40;
|
||||
|
||||
int cappedPoints = AosAttributes.GetValue( from, AosAttribute.RegenStam );
|
||||
|
||||
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
|
||||
cappedPoints += 15;
|
||||
|
||||
if ( CheckAnimal( from, typeof( Kirin ) ) )
|
||||
cappedPoints += 20;
|
||||
|
||||
if( Core.ML && from is PlayerMobile )
|
||||
cappedPoints = Math.Min( cappedPoints, 24 );
|
||||
|
||||
points += cappedPoints;
|
||||
|
||||
if ( points < -1 )
|
||||
points = -1;
|
||||
|
||||
return TimeSpan.FromSeconds( 1.0 / (0.1 * (2 + points)) );
|
||||
}
|
||||
|
||||
private static TimeSpan Mobile_ManaRegenRate( Mobile from )
|
||||
{
|
||||
if ( from.Skills == null )
|
||||
return Mobile.DefaultManaRate;
|
||||
|
||||
if ( !from.Meditating )
|
||||
CheckBonusSkill( from, from.Mana, from.ManaMax, SkillName.Meditation );
|
||||
|
||||
double rate;
|
||||
double armorPenalty = GetArmorOffset( from );
|
||||
|
||||
if ( Core.AOS )
|
||||
{
|
||||
double medPoints = from.Int + (from.Skills[SkillName.Meditation].Value * 3);
|
||||
|
||||
medPoints *= ( from.Skills[SkillName.Meditation].Value < 100.0 ) ? 0.025 : 0.0275;
|
||||
|
||||
CheckBonusSkill( from, from.Mana, from.ManaMax, SkillName.Focus );
|
||||
|
||||
double focusPoints = (from.Skills[SkillName.Focus].Value * 0.05);
|
||||
|
||||
if ( armorPenalty > 0 )
|
||||
medPoints = 0; // In AOS, wearing any meditation-blocking armor completely removes meditation bonus
|
||||
|
||||
double totalPoints = focusPoints + medPoints + (from.Meditating ? (medPoints > 13.0 ? 13.0 : medPoints) : 0.0);
|
||||
|
||||
if( (from is BaseCreature && ((BaseCreature)from).IsParagon) || from is Leviathan )
|
||||
totalPoints += 40;
|
||||
|
||||
int cappedPoints = AosAttributes.GetValue( from, AosAttribute.RegenMana );
|
||||
|
||||
if ( CheckTransform( from, typeof( VampiricEmbraceSpell ) ) )
|
||||
cappedPoints += 3;
|
||||
else if ( CheckTransform( from, typeof( LichFormSpell ) ) )
|
||||
cappedPoints += 13;
|
||||
|
||||
if( Core.ML && from is PlayerMobile )
|
||||
cappedPoints = Math.Min( cappedPoints, 18 );
|
||||
|
||||
totalPoints += cappedPoints;
|
||||
|
||||
if ( totalPoints < -1 )
|
||||
totalPoints = -1;
|
||||
|
||||
if ( Core.ML )
|
||||
totalPoints = Math.Floor( totalPoints );
|
||||
|
||||
rate = 1.0 / (0.1 * (2 + totalPoints));
|
||||
}
|
||||
else
|
||||
{
|
||||
double medPoints = (from.Int + from.Skills[SkillName.Meditation].Value) * 0.5;
|
||||
|
||||
if ( medPoints <= 0 )
|
||||
rate = 7.0;
|
||||
else if ( medPoints <= 100 )
|
||||
rate = 7.0 - (239*medPoints/2400) + (19*medPoints*medPoints/48000);
|
||||
else if ( medPoints < 120 )
|
||||
rate = 1.0;
|
||||
else
|
||||
rate = 0.75;
|
||||
|
||||
rate += armorPenalty;
|
||||
|
||||
if ( from.Meditating )
|
||||
rate *= 0.5;
|
||||
|
||||
if ( rate < 0.5 )
|
||||
rate = 0.5;
|
||||
else if ( rate > 7.0 )
|
||||
rate = 7.0;
|
||||
}
|
||||
|
||||
return TimeSpan.FromSeconds( rate );
|
||||
}
|
||||
|
||||
public static double GetArmorOffset( Mobile from )
|
||||
{
|
||||
double rating = 0.0;
|
||||
|
||||
if ( !Core.AOS )
|
||||
rating += GetArmorMeditationValue( from.ShieldArmor as BaseArmor );
|
||||
|
||||
rating += GetArmorMeditationValue( from.NeckArmor as BaseArmor );
|
||||
rating += GetArmorMeditationValue( from.HandArmor as BaseArmor );
|
||||
rating += GetArmorMeditationValue( from.HeadArmor as BaseArmor );
|
||||
rating += GetArmorMeditationValue( from.ArmsArmor as BaseArmor );
|
||||
rating += GetArmorMeditationValue( from.LegsArmor as BaseArmor );
|
||||
rating += GetArmorMeditationValue( from.ChestArmor as BaseArmor );
|
||||
|
||||
return rating / 4;
|
||||
}
|
||||
|
||||
private static double GetArmorMeditationValue( BaseArmor ar )
|
||||
{
|
||||
if ( ar == null || ar.ArmorAttributes.MageArmor != 0 || ar.Attributes.SpellChanneling != 0 )
|
||||
return 0.0;
|
||||
|
||||
switch ( ar.MeditationAllowance )
|
||||
{
|
||||
default:
|
||||
case ArmorMeditationAllowance.None: return ar.BaseArmorRatingScaled;
|
||||
case ArmorMeditationAllowance.Half: return ar.BaseArmorRatingScaled / 2.0;
|
||||
case ArmorMeditationAllowance.All: return 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Misc/RenameRequests.cs
Normal file
51
Scripts/Misc/RenameRequests.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class RenameRequests
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.RenameRequest += new RenameRequestEventHandler( EventSink_RenameRequest );
|
||||
}
|
||||
|
||||
private static void EventSink_RenameRequest( RenameRequestEventArgs e )
|
||||
{
|
||||
Mobile from = e.From;
|
||||
Mobile targ = e.Target;
|
||||
string name = e.Name;
|
||||
|
||||
if ( from.CanSee( targ ) && from.InRange( targ, 12 ) && targ.CanBeRenamedBy( from ) )
|
||||
{
|
||||
name = name.Trim();
|
||||
|
||||
if( NameVerification.Validate( name, 1, 16, true, false, true, 0, NameVerification.Empty, NameVerification.StartDisallowed, ( Core.ML ? NameVerification.Disallowed : new string[]{} ) ) )
|
||||
{
|
||||
|
||||
if( Core.ML )
|
||||
{
|
||||
string[] disallowed = ProfanityProtection.Disallowed;
|
||||
|
||||
for( int i = 0; i < disallowed.Length; i++ )
|
||||
{
|
||||
if( name.IndexOf( disallowed[i] ) != -1 )
|
||||
{
|
||||
from.SendLocalizedMessage( 1072622 ); // That name isn't very polite.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage( 1072623, String.Format( "{0}\t{1}", targ.Name, name ) ); // Pet ~1_OLDPETNAME~ renamed to ~2_NEWPETNAME~.
|
||||
}
|
||||
|
||||
targ.Name = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "That name is unacceptable." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
726
Scripts/Misc/ResourceInfo.cs
Normal file
726
Scripts/Misc/ResourceInfo.cs
Normal file
|
|
@ -0,0 +1,726 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum CraftResource
|
||||
{
|
||||
None = 0,
|
||||
Iron = 1,
|
||||
DullCopper,
|
||||
ShadowIron,
|
||||
Copper,
|
||||
Bronze,
|
||||
Gold,
|
||||
Agapite,
|
||||
Verite,
|
||||
Valorite,
|
||||
|
||||
RegularLeather = 101,
|
||||
SpinedLeather,
|
||||
HornedLeather,
|
||||
BarbedLeather,
|
||||
|
||||
RedScales = 201,
|
||||
YellowScales,
|
||||
BlackScales,
|
||||
GreenScales,
|
||||
WhiteScales,
|
||||
BlueScales,
|
||||
|
||||
RegularWood = 301,
|
||||
OakWood,
|
||||
AshWood,
|
||||
YewWood,
|
||||
Heartwood,
|
||||
Bloodwood,
|
||||
Frostwood
|
||||
}
|
||||
|
||||
public enum CraftResourceType
|
||||
{
|
||||
None,
|
||||
Metal,
|
||||
Leather,
|
||||
Scales,
|
||||
Wood
|
||||
}
|
||||
|
||||
public class CraftAttributeInfo
|
||||
{
|
||||
private int m_WeaponFireDamage;
|
||||
private int m_WeaponColdDamage;
|
||||
private int m_WeaponPoisonDamage;
|
||||
private int m_WeaponEnergyDamage;
|
||||
private int m_WeaponChaosDamage;
|
||||
private int m_WeaponDirectDamage;
|
||||
private int m_WeaponDurability;
|
||||
private int m_WeaponLuck;
|
||||
private int m_WeaponGoldIncrease;
|
||||
private int m_WeaponLowerRequirements;
|
||||
|
||||
private int m_ArmorPhysicalResist;
|
||||
private int m_ArmorFireResist;
|
||||
private int m_ArmorColdResist;
|
||||
private int m_ArmorPoisonResist;
|
||||
private int m_ArmorEnergyResist;
|
||||
private int m_ArmorDurability;
|
||||
private int m_ArmorLuck;
|
||||
private int m_ArmorGoldIncrease;
|
||||
private int m_ArmorLowerRequirements;
|
||||
|
||||
private int m_RunicMinAttributes;
|
||||
private int m_RunicMaxAttributes;
|
||||
private int m_RunicMinIntensity;
|
||||
private int m_RunicMaxIntensity;
|
||||
|
||||
public int WeaponFireDamage{ get{ return m_WeaponFireDamage; } set{ m_WeaponFireDamage = value; } }
|
||||
public int WeaponColdDamage{ get{ return m_WeaponColdDamage; } set{ m_WeaponColdDamage = value; } }
|
||||
public int WeaponPoisonDamage{ get{ return m_WeaponPoisonDamage; } set{ m_WeaponPoisonDamage = value; } }
|
||||
public int WeaponEnergyDamage{ get{ return m_WeaponEnergyDamage; } set{ m_WeaponEnergyDamage = value; } }
|
||||
public int WeaponChaosDamage{ get{ return m_WeaponChaosDamage; } set{ m_WeaponChaosDamage = value; } }
|
||||
public int WeaponDirectDamage{ get{ return m_WeaponDirectDamage; } set{ m_WeaponDirectDamage = value; } }
|
||||
public int WeaponDurability{ get{ return m_WeaponDurability; } set{ m_WeaponDurability = value; } }
|
||||
public int WeaponLuck{ get{ return m_WeaponLuck; } set{ m_WeaponLuck = value; } }
|
||||
public int WeaponGoldIncrease{ get{ return m_WeaponGoldIncrease; } set{ m_WeaponGoldIncrease = value; } }
|
||||
public int WeaponLowerRequirements{ get{ return m_WeaponLowerRequirements; } set{ m_WeaponLowerRequirements = value; } }
|
||||
|
||||
public int ArmorPhysicalResist{ get{ return m_ArmorPhysicalResist; } set{ m_ArmorPhysicalResist = value; } }
|
||||
public int ArmorFireResist{ get{ return m_ArmorFireResist; } set{ m_ArmorFireResist = value; } }
|
||||
public int ArmorColdResist{ get{ return m_ArmorColdResist; } set{ m_ArmorColdResist = value; } }
|
||||
public int ArmorPoisonResist{ get{ return m_ArmorPoisonResist; } set{ m_ArmorPoisonResist = value; } }
|
||||
public int ArmorEnergyResist{ get{ return m_ArmorEnergyResist; } set{ m_ArmorEnergyResist = value; } }
|
||||
public int ArmorDurability{ get{ return m_ArmorDurability; } set{ m_ArmorDurability = value; } }
|
||||
public int ArmorLuck{ get{ return m_ArmorLuck; } set{ m_ArmorLuck = value; } }
|
||||
public int ArmorGoldIncrease{ get{ return m_ArmorGoldIncrease; } set{ m_ArmorGoldIncrease = value; } }
|
||||
public int ArmorLowerRequirements{ get{ return m_ArmorLowerRequirements; } set{ m_ArmorLowerRequirements = value; } }
|
||||
|
||||
public int RunicMinAttributes{ get{ return m_RunicMinAttributes; } set{ m_RunicMinAttributes = value; } }
|
||||
public int RunicMaxAttributes{ get{ return m_RunicMaxAttributes; } set{ m_RunicMaxAttributes = value; } }
|
||||
public int RunicMinIntensity{ get{ return m_RunicMinIntensity; } set{ m_RunicMinIntensity = value; } }
|
||||
public int RunicMaxIntensity{ get{ return m_RunicMaxIntensity; } set{ m_RunicMaxIntensity = value; } }
|
||||
|
||||
public CraftAttributeInfo()
|
||||
{
|
||||
}
|
||||
|
||||
public static readonly CraftAttributeInfo Blank;
|
||||
public static readonly CraftAttributeInfo DullCopper, ShadowIron, Copper, Bronze, Golden, Agapite, Verite, Valorite;
|
||||
public static readonly CraftAttributeInfo Spined, Horned, Barbed;
|
||||
public static readonly CraftAttributeInfo RedScales, YellowScales, BlackScales, GreenScales, WhiteScales, BlueScales;
|
||||
public static readonly CraftAttributeInfo OakWood, AshWood, YewWood, Heartwood, Bloodwood, Frostwood;
|
||||
|
||||
static CraftAttributeInfo()
|
||||
{
|
||||
Blank = new CraftAttributeInfo();
|
||||
|
||||
CraftAttributeInfo dullCopper = DullCopper = new CraftAttributeInfo();
|
||||
|
||||
dullCopper.ArmorPhysicalResist = 6;
|
||||
dullCopper.ArmorDurability = 50;
|
||||
dullCopper.ArmorLowerRequirements = 20;
|
||||
dullCopper.WeaponDurability = 100;
|
||||
dullCopper.WeaponLowerRequirements = 50;
|
||||
dullCopper.RunicMinAttributes = 1;
|
||||
dullCopper.RunicMaxAttributes = 2;
|
||||
if ( Core.ML )
|
||||
{
|
||||
dullCopper.RunicMinIntensity = 40;
|
||||
dullCopper.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
dullCopper.RunicMinIntensity = 10;
|
||||
dullCopper.RunicMaxIntensity = 35;
|
||||
}
|
||||
|
||||
CraftAttributeInfo shadowIron = ShadowIron = new CraftAttributeInfo();
|
||||
|
||||
shadowIron.ArmorPhysicalResist = 2;
|
||||
shadowIron.ArmorFireResist = 1;
|
||||
shadowIron.ArmorEnergyResist = 5;
|
||||
shadowIron.ArmorDurability = 100;
|
||||
shadowIron.WeaponColdDamage = 20;
|
||||
shadowIron.WeaponDurability = 50;
|
||||
shadowIron.RunicMinAttributes = 2;
|
||||
shadowIron.RunicMaxAttributes = 2;
|
||||
if ( Core.ML )
|
||||
{
|
||||
shadowIron.RunicMinIntensity = 45;
|
||||
shadowIron.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
shadowIron.RunicMinIntensity = 20;
|
||||
shadowIron.RunicMaxIntensity = 45;
|
||||
}
|
||||
|
||||
CraftAttributeInfo copper = Copper = new CraftAttributeInfo();
|
||||
|
||||
copper.ArmorPhysicalResist = 1;
|
||||
copper.ArmorFireResist = 1;
|
||||
copper.ArmorPoisonResist = 5;
|
||||
copper.ArmorEnergyResist = 2;
|
||||
copper.WeaponPoisonDamage = 10;
|
||||
copper.WeaponEnergyDamage = 20;
|
||||
copper.RunicMinAttributes = 2;
|
||||
copper.RunicMaxAttributes = 3;
|
||||
if ( Core.ML )
|
||||
{
|
||||
copper.RunicMinIntensity = 50;
|
||||
copper.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
copper.RunicMinIntensity = 25;
|
||||
copper.RunicMaxIntensity = 50;
|
||||
}
|
||||
|
||||
CraftAttributeInfo bronze = Bronze = new CraftAttributeInfo();
|
||||
|
||||
bronze.ArmorPhysicalResist = 3;
|
||||
bronze.ArmorColdResist = 5;
|
||||
bronze.ArmorPoisonResist = 1;
|
||||
bronze.ArmorEnergyResist = 1;
|
||||
bronze.WeaponFireDamage = 40;
|
||||
bronze.RunicMinAttributes = 3;
|
||||
bronze.RunicMaxAttributes = 3;
|
||||
if ( Core.ML )
|
||||
{
|
||||
bronze.RunicMinIntensity = 55;
|
||||
bronze.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
bronze.RunicMinIntensity = 30;
|
||||
bronze.RunicMaxIntensity = 65;
|
||||
}
|
||||
|
||||
CraftAttributeInfo golden = Golden = new CraftAttributeInfo();
|
||||
|
||||
golden.ArmorPhysicalResist = 1;
|
||||
golden.ArmorFireResist = 1;
|
||||
golden.ArmorColdResist = 2;
|
||||
golden.ArmorEnergyResist = 2;
|
||||
golden.ArmorLuck = 40;
|
||||
golden.ArmorLowerRequirements = 30;
|
||||
golden.WeaponLuck = 40;
|
||||
golden.WeaponLowerRequirements = 50;
|
||||
golden.RunicMinAttributes = 3;
|
||||
golden.RunicMaxAttributes = 4;
|
||||
if ( Core.ML )
|
||||
{
|
||||
golden.RunicMinIntensity = 60;
|
||||
golden.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
golden.RunicMinIntensity = 35;
|
||||
golden.RunicMaxIntensity = 75;
|
||||
}
|
||||
|
||||
CraftAttributeInfo agapite = Agapite = new CraftAttributeInfo();
|
||||
|
||||
agapite.ArmorPhysicalResist = 2;
|
||||
agapite.ArmorFireResist = 3;
|
||||
agapite.ArmorColdResist = 2;
|
||||
agapite.ArmorPoisonResist = 2;
|
||||
agapite.ArmorEnergyResist = 2;
|
||||
agapite.WeaponColdDamage = 30;
|
||||
agapite.WeaponEnergyDamage = 20;
|
||||
agapite.RunicMinAttributes = 4;
|
||||
agapite.RunicMaxAttributes = 4;
|
||||
if ( Core.ML )
|
||||
{
|
||||
agapite.RunicMinIntensity = 65;
|
||||
agapite.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
agapite.RunicMinIntensity = 40;
|
||||
agapite.RunicMaxIntensity = 80;
|
||||
}
|
||||
|
||||
CraftAttributeInfo verite = Verite = new CraftAttributeInfo();
|
||||
|
||||
verite.ArmorPhysicalResist = 3;
|
||||
verite.ArmorFireResist = 3;
|
||||
verite.ArmorColdResist = 2;
|
||||
verite.ArmorPoisonResist = 3;
|
||||
verite.ArmorEnergyResist = 1;
|
||||
verite.WeaponPoisonDamage = 40;
|
||||
verite.WeaponEnergyDamage = 20;
|
||||
verite.RunicMinAttributes = 4;
|
||||
verite.RunicMaxAttributes = 5;
|
||||
if ( Core.ML )
|
||||
{
|
||||
verite.RunicMinIntensity = 70;
|
||||
verite.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
verite.RunicMinIntensity = 45;
|
||||
verite.RunicMaxIntensity = 90;
|
||||
}
|
||||
|
||||
CraftAttributeInfo valorite = Valorite = new CraftAttributeInfo();
|
||||
|
||||
valorite.ArmorPhysicalResist = 4;
|
||||
valorite.ArmorColdResist = 3;
|
||||
valorite.ArmorPoisonResist = 3;
|
||||
valorite.ArmorEnergyResist = 3;
|
||||
valorite.ArmorDurability = 50;
|
||||
valorite.WeaponFireDamage = 10;
|
||||
valorite.WeaponColdDamage = 20;
|
||||
valorite.WeaponPoisonDamage = 10;
|
||||
valorite.WeaponEnergyDamage = 20;
|
||||
valorite.RunicMinAttributes = 5;
|
||||
valorite.RunicMaxAttributes = 5;
|
||||
if ( Core.ML )
|
||||
{
|
||||
valorite.RunicMinIntensity = 85;
|
||||
valorite.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
valorite.RunicMinIntensity = 50;
|
||||
valorite.RunicMaxIntensity = 100;
|
||||
}
|
||||
|
||||
CraftAttributeInfo spined = Spined = new CraftAttributeInfo();
|
||||
|
||||
spined.ArmorPhysicalResist = 5;
|
||||
spined.ArmorLuck = 40;
|
||||
spined.RunicMinAttributes = 1;
|
||||
spined.RunicMaxAttributes = 3;
|
||||
if ( Core.ML )
|
||||
{
|
||||
spined.RunicMinIntensity = 40;
|
||||
spined.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
spined.RunicMinIntensity = 20;
|
||||
spined.RunicMaxIntensity = 40;
|
||||
}
|
||||
|
||||
CraftAttributeInfo horned = Horned = new CraftAttributeInfo();
|
||||
|
||||
horned.ArmorPhysicalResist = 2;
|
||||
horned.ArmorFireResist = 3;
|
||||
horned.ArmorColdResist = 2;
|
||||
horned.ArmorPoisonResist = 2;
|
||||
horned.ArmorEnergyResist = 2;
|
||||
horned.RunicMinAttributes = 3;
|
||||
horned.RunicMaxAttributes = 4;
|
||||
if ( Core.ML )
|
||||
{
|
||||
horned.RunicMinIntensity = 45;
|
||||
horned.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
horned.RunicMinIntensity = 30;
|
||||
horned.RunicMaxIntensity = 70;
|
||||
}
|
||||
|
||||
CraftAttributeInfo barbed = Barbed = new CraftAttributeInfo();
|
||||
|
||||
barbed.ArmorPhysicalResist = 2;
|
||||
barbed.ArmorFireResist = 1;
|
||||
barbed.ArmorColdResist = 2;
|
||||
barbed.ArmorPoisonResist = 3;
|
||||
barbed.ArmorEnergyResist = 4;
|
||||
barbed.RunicMinAttributes = 4;
|
||||
barbed.RunicMaxAttributes = 5;
|
||||
if ( Core.ML )
|
||||
{
|
||||
barbed.RunicMinIntensity = 50;
|
||||
barbed.RunicMaxIntensity = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
barbed.RunicMinIntensity = 40;
|
||||
barbed.RunicMaxIntensity = 100;
|
||||
}
|
||||
|
||||
CraftAttributeInfo red = RedScales = new CraftAttributeInfo();
|
||||
|
||||
red.ArmorFireResist = 10;
|
||||
red.ArmorColdResist = -3;
|
||||
|
||||
CraftAttributeInfo yellow = YellowScales = new CraftAttributeInfo();
|
||||
|
||||
yellow.ArmorPhysicalResist = -3;
|
||||
yellow.ArmorLuck = 20;
|
||||
|
||||
CraftAttributeInfo black = BlackScales = new CraftAttributeInfo();
|
||||
|
||||
black.ArmorPhysicalResist = 10;
|
||||
black.ArmorEnergyResist = -3;
|
||||
|
||||
CraftAttributeInfo green = GreenScales = new CraftAttributeInfo();
|
||||
|
||||
green.ArmorFireResist = -3;
|
||||
green.ArmorPoisonResist = 10;
|
||||
|
||||
CraftAttributeInfo white = WhiteScales = new CraftAttributeInfo();
|
||||
|
||||
white.ArmorPhysicalResist = -3;
|
||||
white.ArmorColdResist = 10;
|
||||
|
||||
CraftAttributeInfo blue = BlueScales = new CraftAttributeInfo();
|
||||
|
||||
blue.ArmorPoisonResist = -3;
|
||||
blue.ArmorEnergyResist = 10;
|
||||
|
||||
//public static readonly CraftAttributeInfo OakWood, AshWood, YewWood, Heartwood, Bloodwood, Frostwood;
|
||||
|
||||
CraftAttributeInfo oak = OakWood = new CraftAttributeInfo();
|
||||
|
||||
CraftAttributeInfo ash = AshWood = new CraftAttributeInfo();
|
||||
|
||||
CraftAttributeInfo yew = YewWood = new CraftAttributeInfo();
|
||||
|
||||
CraftAttributeInfo heart = Heartwood = new CraftAttributeInfo();
|
||||
|
||||
CraftAttributeInfo blood = Bloodwood = new CraftAttributeInfo();
|
||||
|
||||
CraftAttributeInfo frost = Frostwood = new CraftAttributeInfo();
|
||||
}
|
||||
}
|
||||
|
||||
public class CraftResourceInfo
|
||||
{
|
||||
private int m_Hue;
|
||||
private int m_Number;
|
||||
private string m_Name;
|
||||
private CraftAttributeInfo m_AttributeInfo;
|
||||
private CraftResource m_Resource;
|
||||
private Type[] m_ResourceTypes;
|
||||
|
||||
public int Hue{ get{ return m_Hue; } }
|
||||
public int Number{ get{ return m_Number; } }
|
||||
public string Name{ get{ return m_Name; } }
|
||||
public CraftAttributeInfo AttributeInfo{ get{ return m_AttributeInfo; } }
|
||||
public CraftResource Resource{ get{ return m_Resource; } }
|
||||
public Type[] ResourceTypes{ get{ return m_ResourceTypes; } }
|
||||
|
||||
public CraftResourceInfo( int hue, int number, string name, CraftAttributeInfo attributeInfo, CraftResource resource, params Type[] resourceTypes )
|
||||
{
|
||||
m_Hue = hue;
|
||||
m_Number = number;
|
||||
m_Name = name;
|
||||
m_AttributeInfo = attributeInfo;
|
||||
m_Resource = resource;
|
||||
m_ResourceTypes = resourceTypes;
|
||||
|
||||
for ( int i = 0; i < resourceTypes.Length; ++i )
|
||||
CraftResources.RegisterType( resourceTypes[i], resource );
|
||||
}
|
||||
}
|
||||
|
||||
public class CraftResources
|
||||
{
|
||||
private static CraftResourceInfo[] m_MetalInfo = new CraftResourceInfo[]
|
||||
{
|
||||
new CraftResourceInfo( 0x000, 1053109, "Iron", CraftAttributeInfo.Blank, CraftResource.Iron, typeof( IronIngot ), typeof( IronOre ), typeof( Granite ) ),
|
||||
new CraftResourceInfo( 0x973, 1053108, "Dull Copper", CraftAttributeInfo.DullCopper, CraftResource.DullCopper, typeof( DullCopperIngot ), typeof( DullCopperOre ), typeof( DullCopperGranite ) ),
|
||||
new CraftResourceInfo( 0x966, 1053107, "Shadow Iron", CraftAttributeInfo.ShadowIron, CraftResource.ShadowIron, typeof( ShadowIronIngot ), typeof( ShadowIronOre ), typeof( ShadowIronGranite ) ),
|
||||
new CraftResourceInfo( 0x96D, 1053106, "Copper", CraftAttributeInfo.Copper, CraftResource.Copper, typeof( CopperIngot ), typeof( CopperOre ), typeof( CopperGranite ) ),
|
||||
new CraftResourceInfo( 0x972, 1053105, "Bronze", CraftAttributeInfo.Bronze, CraftResource.Bronze, typeof( BronzeIngot ), typeof( BronzeOre ), typeof( BronzeGranite ) ),
|
||||
new CraftResourceInfo( 0x8A5, 1053104, "Gold", CraftAttributeInfo.Golden, CraftResource.Gold, typeof( GoldIngot ), typeof( GoldOre ), typeof( GoldGranite ) ),
|
||||
new CraftResourceInfo( 0x979, 1053103, "Agapite", CraftAttributeInfo.Agapite, CraftResource.Agapite, typeof( AgapiteIngot ), typeof( AgapiteOre ), typeof( AgapiteGranite ) ),
|
||||
new CraftResourceInfo( 0x89F, 1053102, "Verite", CraftAttributeInfo.Verite, CraftResource.Verite, typeof( VeriteIngot ), typeof( VeriteOre ), typeof( VeriteGranite ) ),
|
||||
new CraftResourceInfo( 0x8AB, 1053101, "Valorite", CraftAttributeInfo.Valorite, CraftResource.Valorite, typeof( ValoriteIngot ), typeof( ValoriteOre ), typeof( ValoriteGranite ) ),
|
||||
};
|
||||
|
||||
private static CraftResourceInfo[] m_ScaleInfo = new CraftResourceInfo[]
|
||||
{
|
||||
new CraftResourceInfo( 0x66D, 1053129, "Red Scales", CraftAttributeInfo.RedScales, CraftResource.RedScales, typeof( RedScales ) ),
|
||||
new CraftResourceInfo( 0x8A8, 1053130, "Yellow Scales", CraftAttributeInfo.YellowScales, CraftResource.YellowScales, typeof( YellowScales ) ),
|
||||
new CraftResourceInfo( 0x455, 1053131, "Black Scales", CraftAttributeInfo.BlackScales, CraftResource.BlackScales, typeof( BlackScales ) ),
|
||||
new CraftResourceInfo( 0x851, 1053132, "Green Scales", CraftAttributeInfo.GreenScales, CraftResource.GreenScales, typeof( GreenScales ) ),
|
||||
new CraftResourceInfo( 0x8FD, 1053133, "White Scales", CraftAttributeInfo.WhiteScales, CraftResource.WhiteScales, typeof( WhiteScales ) ),
|
||||
new CraftResourceInfo( 0x8B0, 1053134, "Blue Scales", CraftAttributeInfo.BlueScales, CraftResource.BlueScales, typeof( BlueScales ) )
|
||||
};
|
||||
|
||||
private static CraftResourceInfo[] m_LeatherInfo = new CraftResourceInfo[]
|
||||
{
|
||||
new CraftResourceInfo( 0x000, 1049353, "Normal", CraftAttributeInfo.Blank, CraftResource.RegularLeather, typeof( Leather ), typeof( Hides ) ),
|
||||
new CraftResourceInfo( 0x283, 1049354, "Spined", CraftAttributeInfo.Spined, CraftResource.SpinedLeather, typeof( SpinedLeather ), typeof( SpinedHides ) ),
|
||||
new CraftResourceInfo( 0x227, 1049355, "Horned", CraftAttributeInfo.Horned, CraftResource.HornedLeather, typeof( HornedLeather ), typeof( HornedHides ) ),
|
||||
new CraftResourceInfo( 0x1C1, 1049356, "Barbed", CraftAttributeInfo.Barbed, CraftResource.BarbedLeather, typeof( BarbedLeather ), typeof( BarbedHides ) )
|
||||
};
|
||||
|
||||
private static CraftResourceInfo[] m_AOSLeatherInfo = new CraftResourceInfo[]
|
||||
{
|
||||
new CraftResourceInfo( 0x000, 1049353, "Normal", CraftAttributeInfo.Blank, CraftResource.RegularLeather, typeof( Leather ), typeof( Hides ) ),
|
||||
new CraftResourceInfo( 0x8AC, 1049354, "Spined", CraftAttributeInfo.Spined, CraftResource.SpinedLeather, typeof( SpinedLeather ), typeof( SpinedHides ) ),
|
||||
new CraftResourceInfo( 0x845, 1049355, "Horned", CraftAttributeInfo.Horned, CraftResource.HornedLeather, typeof( HornedLeather ), typeof( HornedHides ) ),
|
||||
new CraftResourceInfo( 0x851, 1049356, "Barbed", CraftAttributeInfo.Barbed, CraftResource.BarbedLeather, typeof( BarbedLeather ), typeof( BarbedHides ) ),
|
||||
};
|
||||
|
||||
private static CraftResourceInfo[] m_WoodInfo = new CraftResourceInfo[]
|
||||
{
|
||||
new CraftResourceInfo( 0x000, 1011542, "Normal", CraftAttributeInfo.Blank, CraftResource.RegularWood, typeof( Log ), typeof( Board ) ),
|
||||
new CraftResourceInfo( 0x7DA, 1072533, "Oak", CraftAttributeInfo.OakWood, CraftResource.OakWood, typeof( OakLog ), typeof( OakBoard ) ),
|
||||
new CraftResourceInfo( 0x4A7, 1072534, "Ash", CraftAttributeInfo.AshWood, CraftResource.AshWood, typeof( AshLog ), typeof( AshBoard ) ),
|
||||
new CraftResourceInfo( 0x4A8, 1072535, "Yew", CraftAttributeInfo.YewWood, CraftResource.YewWood, typeof( YewLog ), typeof( YewBoard ) ),
|
||||
new CraftResourceInfo( 0x4A9, 1072536, "Heartwood", CraftAttributeInfo.Heartwood, CraftResource.Heartwood, typeof( HeartwoodLog ), typeof( HeartwoodBoard ) ),
|
||||
new CraftResourceInfo( 0x4AA, 1072538, "Bloodwood", CraftAttributeInfo.Bloodwood, CraftResource.Bloodwood, typeof( BloodwoodLog ), typeof( BloodwoodBoard ) ),
|
||||
new CraftResourceInfo( 0x47F, 1072539, "Frostwood", CraftAttributeInfo.Frostwood, CraftResource.Frostwood, typeof( FrostwoodLog ), typeof( FrostwoodBoard ) )
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if '<paramref name="resource"/>' is None, Iron, RegularLeather or RegularWood. False if otherwise.
|
||||
/// </summary>
|
||||
public static bool IsStandard( CraftResource resource )
|
||||
{
|
||||
return ( resource == CraftResource.None || resource == CraftResource.Iron || resource == CraftResource.RegularLeather || resource == CraftResource.RegularWood );
|
||||
}
|
||||
|
||||
private static Dictionary<Type, CraftResource> m_TypeTable;
|
||||
|
||||
/// <summary>
|
||||
/// Registers that '<paramref name="resourceType"/>' uses '<paramref name="resource"/>' so that it can later be queried by <see cref="CraftResources.GetFromType"/>
|
||||
/// </summary>
|
||||
public static void RegisterType( Type resourceType, CraftResource resource )
|
||||
{
|
||||
if ( m_TypeTable == null )
|
||||
m_TypeTable = new Dictionary<Type, CraftResource>();
|
||||
|
||||
m_TypeTable[resourceType] = resource;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="CraftResource"/> value for which '<paramref name="resourceType"/>' uses -or- CraftResource.None if an unregistered type was specified.
|
||||
/// </summary>
|
||||
public static CraftResource GetFromType( Type resourceType )
|
||||
{
|
||||
if ( m_TypeTable == null )
|
||||
return CraftResource.None;
|
||||
|
||||
CraftResource res;
|
||||
|
||||
if (!m_TypeTable.TryGetValue(resourceType, out res))
|
||||
return CraftResource.None;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="CraftResourceInfo"/> instance describing '<paramref name="resource"/>' -or- null if an invalid resource was specified.
|
||||
/// </summary>
|
||||
public static CraftResourceInfo GetInfo( CraftResource resource )
|
||||
{
|
||||
CraftResourceInfo[] list = null;
|
||||
|
||||
switch ( GetType( resource ) )
|
||||
{
|
||||
case CraftResourceType.Metal: list = m_MetalInfo; break;
|
||||
case CraftResourceType.Leather: list = Core.AOS ? m_AOSLeatherInfo : m_LeatherInfo; break;
|
||||
case CraftResourceType.Scales: list = m_ScaleInfo; break;
|
||||
case CraftResourceType.Wood: list = m_WoodInfo; break;
|
||||
}
|
||||
|
||||
if ( list != null )
|
||||
{
|
||||
int index = GetIndex( resource );
|
||||
|
||||
if ( index >= 0 && index < list.Length )
|
||||
return list[index];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="CraftResourceType"/> value indiciating the type of '<paramref name="resource"/>'.
|
||||
/// </summary>
|
||||
public static CraftResourceType GetType( CraftResource resource )
|
||||
{
|
||||
if ( resource >= CraftResource.Iron && resource <= CraftResource.Valorite )
|
||||
return CraftResourceType.Metal;
|
||||
|
||||
if ( resource >= CraftResource.RegularLeather && resource <= CraftResource.BarbedLeather )
|
||||
return CraftResourceType.Leather;
|
||||
|
||||
if ( resource >= CraftResource.RedScales && resource <= CraftResource.BlueScales )
|
||||
return CraftResourceType.Scales;
|
||||
|
||||
if ( resource >= CraftResource.RegularWood && resource <= CraftResource.Frostwood )
|
||||
return CraftResourceType.Wood;
|
||||
|
||||
return CraftResourceType.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the first <see cref="CraftResource"/> in the series of resources for which '<paramref name="resource"/>' belongs.
|
||||
/// </summary>
|
||||
public static CraftResource GetStart( CraftResource resource )
|
||||
{
|
||||
switch ( GetType( resource ) )
|
||||
{
|
||||
case CraftResourceType.Metal: return CraftResource.Iron;
|
||||
case CraftResourceType.Leather: return CraftResource.RegularLeather;
|
||||
case CraftResourceType.Scales: return CraftResource.RedScales;
|
||||
case CraftResourceType.Wood: return CraftResource.RegularWood;
|
||||
}
|
||||
|
||||
return CraftResource.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of '<paramref name="resource"/>' in the seriest of resources for which it belongs.
|
||||
/// </summary>
|
||||
public static int GetIndex( CraftResource resource )
|
||||
{
|
||||
CraftResource start = GetStart( resource );
|
||||
|
||||
if ( start == CraftResource.None )
|
||||
return 0;
|
||||
|
||||
return (int)(resource - start);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="CraftResourceInfo.Number"/> property of '<paramref name="resource"/>' -or- 0 if an invalid resource was specified.
|
||||
/// </summary>
|
||||
public static int GetLocalizationNumber( CraftResource resource )
|
||||
{
|
||||
CraftResourceInfo info = GetInfo( resource );
|
||||
|
||||
return ( info == null ? 0 : info.Number );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="CraftResourceInfo.Hue"/> property of '<paramref name="resource"/>' -or- 0 if an invalid resource was specified.
|
||||
/// </summary>
|
||||
public static int GetHue( CraftResource resource )
|
||||
{
|
||||
CraftResourceInfo info = GetInfo( resource );
|
||||
|
||||
return ( info == null ? 0 : info.Hue );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="CraftResourceInfo.Name"/> property of '<paramref name="resource"/>' -or- an empty string if the resource specified was invalid.
|
||||
/// </summary>
|
||||
public static string GetName( CraftResource resource )
|
||||
{
|
||||
CraftResourceInfo info = GetInfo( resource );
|
||||
|
||||
return ( info == null ? String.Empty : info.Name );
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="CraftResource"/> value which represents '<paramref name="info"/>' -or- CraftResource.None if unable to convert.
|
||||
/// </summary>
|
||||
public static CraftResource GetFromOreInfo( OreInfo info )
|
||||
{
|
||||
if ( info.Name.IndexOf( "Spined" ) >= 0 )
|
||||
return CraftResource.SpinedLeather;
|
||||
else if ( info.Name.IndexOf( "Horned" ) >= 0 )
|
||||
return CraftResource.HornedLeather;
|
||||
else if ( info.Name.IndexOf( "Barbed" ) >= 0 )
|
||||
return CraftResource.BarbedLeather;
|
||||
else if ( info.Name.IndexOf( "Leather" ) >= 0 )
|
||||
return CraftResource.RegularLeather;
|
||||
|
||||
if ( info.Level == 0 )
|
||||
return CraftResource.Iron;
|
||||
else if ( info.Level == 1 )
|
||||
return CraftResource.DullCopper;
|
||||
else if ( info.Level == 2 )
|
||||
return CraftResource.ShadowIron;
|
||||
else if ( info.Level == 3 )
|
||||
return CraftResource.Copper;
|
||||
else if ( info.Level == 4 )
|
||||
return CraftResource.Bronze;
|
||||
else if ( info.Level == 5 )
|
||||
return CraftResource.Gold;
|
||||
else if ( info.Level == 6 )
|
||||
return CraftResource.Agapite;
|
||||
else if ( info.Level == 7 )
|
||||
return CraftResource.Verite;
|
||||
else if ( info.Level == 8 )
|
||||
return CraftResource.Valorite;
|
||||
|
||||
return CraftResource.None;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="CraftResource"/> value which represents '<paramref name="info"/>', using '<paramref name="material"/>' to help resolve leather OreInfo instances.
|
||||
/// </summary>
|
||||
public static CraftResource GetFromOreInfo( OreInfo info, ArmorMaterialType material )
|
||||
{
|
||||
if ( material == ArmorMaterialType.Studded || material == ArmorMaterialType.Leather || material == ArmorMaterialType.Spined ||
|
||||
material == ArmorMaterialType.Horned || material == ArmorMaterialType.Barbed )
|
||||
{
|
||||
if ( info.Level == 0 )
|
||||
return CraftResource.RegularLeather;
|
||||
else if ( info.Level == 1 )
|
||||
return CraftResource.SpinedLeather;
|
||||
else if ( info.Level == 2 )
|
||||
return CraftResource.HornedLeather;
|
||||
else if ( info.Level == 3 )
|
||||
return CraftResource.BarbedLeather;
|
||||
|
||||
return CraftResource.None;
|
||||
}
|
||||
|
||||
return GetFromOreInfo( info );
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: This class is only for compatability with very old RunUO versions.
|
||||
// No changes to it should be required for custom resources.
|
||||
public class OreInfo
|
||||
{
|
||||
public static readonly OreInfo Iron = new OreInfo( 0, 0x000, "Iron" );
|
||||
public static readonly OreInfo DullCopper = new OreInfo( 1, 0x973, "Dull Copper" );
|
||||
public static readonly OreInfo ShadowIron = new OreInfo( 2, 0x966, "Shadow Iron" );
|
||||
public static readonly OreInfo Copper = new OreInfo( 3, 0x96D, "Copper" );
|
||||
public static readonly OreInfo Bronze = new OreInfo( 4, 0x972, "Bronze" );
|
||||
public static readonly OreInfo Gold = new OreInfo( 5, 0x8A5, "Gold" );
|
||||
public static readonly OreInfo Agapite = new OreInfo( 6, 0x979, "Agapite" );
|
||||
public static readonly OreInfo Verite = new OreInfo( 7, 0x89F, "Verite" );
|
||||
public static readonly OreInfo Valorite = new OreInfo( 8, 0x8AB, "Valorite" );
|
||||
|
||||
private int m_Level;
|
||||
private int m_Hue;
|
||||
private string m_Name;
|
||||
|
||||
public OreInfo( int level, int hue, string name )
|
||||
{
|
||||
m_Level = level;
|
||||
m_Hue = hue;
|
||||
m_Name = name;
|
||||
}
|
||||
|
||||
public int Level
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Level;
|
||||
}
|
||||
}
|
||||
|
||||
public int Hue
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Hue;
|
||||
}
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
198
Scripts/Misc/ServerList.cs
Normal file
198
Scripts/Misc/ServerList.cs
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class ServerList
|
||||
{
|
||||
/*
|
||||
* The default setting for Address, a value of 'null', will use your local IP address. If all of your local IP addresses
|
||||
* are private network addresses and AutoDetect is 'true' then RunUO will attempt to discover your public IP address
|
||||
* for you automatically.
|
||||
*
|
||||
* If you do not plan on allowing clients outside of your LAN to connect, you can set AutoDetect to 'false' and leave
|
||||
* Address set to 'null'.
|
||||
*
|
||||
* If your public IP address cannot be determined, you must change the value of Address to your public IP address
|
||||
* manually to allow clients outside of your LAN to connect to your server. Address can be either an IP address or
|
||||
* a hostname that will be resolved when RunUO starts.
|
||||
*
|
||||
* If you want players outside your LAN to be able to connect to your server and you are behind a router, you must also
|
||||
* forward TCP port 2593 to your private IP address. The procedure for doing this varies by manufacturer but generally
|
||||
* involves configuration of the router through your web browser.
|
||||
*
|
||||
* ServerList will direct connecting clients depending on both the address they are connecting from and the address and
|
||||
* port they are connecting to. If it is determined that both ends of a connection are private IP addresses, ServerList
|
||||
* will direct the client to the local private IP address. If a client is connecting to a local public IP address, they
|
||||
* will be directed to whichever address and port they initially connected to. This allows multihomed servers to function
|
||||
* properly and fully supports listening on multiple ports. If a client with a public IP address is connecting to a
|
||||
* locally private address, the server will direct the client to either the AutoDetected IP address or the manually entered
|
||||
* IP address or hostname, whichever is applicable. Loopback clients will be directed to loopback.
|
||||
*
|
||||
* If you would like to listen on additional ports (i.e. 22, 23, 80, for clients behind highly restrictive egress
|
||||
* firewalls) or specific IP adddresses you can do so by modifying the file SocketOptions.cs found in this directory.
|
||||
*/
|
||||
|
||||
public static readonly string Address = null;
|
||||
public static readonly string ServerName = Settings.S_ServerName;
|
||||
|
||||
public static readonly bool AutoDetect = true;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( Address == null ) {
|
||||
if ( AutoDetect )
|
||||
AutoDetection();
|
||||
}
|
||||
else {
|
||||
Resolve( Address, out m_PublicAddress );
|
||||
}
|
||||
|
||||
EventSink.ServerList += new ServerListEventHandler( EventSink_ServerList );
|
||||
}
|
||||
|
||||
private static IPAddress m_PublicAddress;
|
||||
|
||||
private static void EventSink_ServerList( ServerListEventArgs e )
|
||||
{
|
||||
try
|
||||
{
|
||||
NetState ns = e.State;
|
||||
Socket s = ns.Socket;
|
||||
|
||||
IPEndPoint ipep = (IPEndPoint)s.LocalEndPoint;
|
||||
|
||||
IPAddress localAddress = ipep.Address;
|
||||
int localPort = ipep.Port;
|
||||
|
||||
if ( IsPrivateNetwork( localAddress ) ) {
|
||||
ipep = (IPEndPoint)s.RemoteEndPoint;
|
||||
if ( !IsPrivateNetwork( ipep.Address ) && m_PublicAddress != null )
|
||||
localAddress = m_PublicAddress;
|
||||
}
|
||||
|
||||
e.AddServer( ServerName, new IPEndPoint( localAddress, localPort ) );
|
||||
}
|
||||
catch
|
||||
{
|
||||
e.Rejected = true;
|
||||
}
|
||||
}
|
||||
|
||||
private static void AutoDetection()
|
||||
{
|
||||
if ( !HasPublicIPAddress() ) {
|
||||
Console.Write( "ServerList: Auto-detecting public IP address..." );
|
||||
m_PublicAddress = FindPublicAddress();
|
||||
|
||||
if ( m_PublicAddress != null )
|
||||
Console.WriteLine( "done ({0})", m_PublicAddress.ToString() );
|
||||
else
|
||||
Console.WriteLine( "failed" );
|
||||
}
|
||||
}
|
||||
|
||||
private static void Resolve( string addr, out IPAddress outValue )
|
||||
{
|
||||
if ( IPAddress.TryParse( addr, out outValue ) )
|
||||
return;
|
||||
|
||||
try {
|
||||
IPHostEntry iphe = Dns.GetHostEntry( addr );
|
||||
|
||||
if ( iphe.AddressList.Length > 0 )
|
||||
outValue = iphe.AddressList[iphe.AddressList.Length - 1];
|
||||
}
|
||||
catch {
|
||||
}
|
||||
}
|
||||
|
||||
private static bool HasPublicIPAddress()
|
||||
{
|
||||
NetworkInterface[] adapters = NetworkInterface.GetAllNetworkInterfaces();
|
||||
|
||||
foreach ( NetworkInterface adapter in adapters ) {
|
||||
IPInterfaceProperties properties = adapter.GetIPProperties();
|
||||
|
||||
foreach ( IPAddressInformation unicast in properties.UnicastAddresses ) {
|
||||
IPAddress ip = unicast.Address;
|
||||
|
||||
if ( !IPAddress.IsLoopback( ip ) && ip.AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork( ip ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
/*
|
||||
IPHostEntry iphe = Dns.GetHostEntry( Dns.GetHostName() );
|
||||
|
||||
IPAddress[] ips = iphe.AddressList;
|
||||
|
||||
for ( int i = 0; i < ips.Length; ++i )
|
||||
{
|
||||
if ( ips[i].AddressFamily != AddressFamily.InterNetworkV6 && !IsPrivateNetwork( ips[i] ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
*/
|
||||
}
|
||||
|
||||
private static bool IsPrivateNetwork( IPAddress ip )
|
||||
{
|
||||
// 10.0.0.0/8
|
||||
// 172.16.0.0/12
|
||||
// 192.168.0.0/16
|
||||
// 169.254.0.0/16
|
||||
// 100.64.0.0/10 RFC 6598
|
||||
|
||||
if ( ip.AddressFamily == AddressFamily.InterNetworkV6 )
|
||||
return false;
|
||||
|
||||
if ( Utility.IPMatch( "192.168.*", ip ) )
|
||||
return true;
|
||||
else if ( Utility.IPMatch( "10.*", ip ) )
|
||||
return true;
|
||||
else if ( Utility.IPMatch( "172.16-31.*", ip ) )
|
||||
return true;
|
||||
else if ( Utility.IPMatch( "169.254.*", ip ) )
|
||||
return true;
|
||||
else if ( Utility.IPMatch( "100.64-127.*", ip ) )
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IPAddress FindPublicAddress()
|
||||
{
|
||||
try {
|
||||
WebRequest req = HttpWebRequest.Create( "https://api.ipify.org" );
|
||||
|
||||
req.Timeout = 15000;
|
||||
|
||||
WebResponse res = req.GetResponse();
|
||||
|
||||
Stream s = res.GetResponseStream();
|
||||
|
||||
StreamReader sr = new StreamReader( s );
|
||||
|
||||
IPAddress ip = IPAddress.Parse( sr.ReadLine() );
|
||||
|
||||
sr.Close();
|
||||
s.Close();
|
||||
res.Close();
|
||||
|
||||
return ip;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
643
Scripts/Misc/ShardPoller.cs
Normal file
643
Scripts/Misc/ShardPoller.cs
Normal file
|
|
@ -0,0 +1,643 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Prompts;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class ShardPoller : Item
|
||||
{
|
||||
private string m_Title;
|
||||
|
||||
private ShardPollOption[] m_Options;
|
||||
private IPAddress[] m_Addresses;
|
||||
|
||||
private TimeSpan m_Duration;
|
||||
private DateTime m_StartTime;
|
||||
|
||||
private bool m_Active;
|
||||
|
||||
public ShardPollOption[] Options
|
||||
{
|
||||
get{ return m_Options; }
|
||||
set{ m_Options = value; }
|
||||
}
|
||||
|
||||
public IPAddress[] Addresses
|
||||
{
|
||||
get{ return m_Addresses; }
|
||||
set{ m_Addresses = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
|
||||
public string Title
|
||||
{
|
||||
get{ return m_Title; }
|
||||
set{ m_Title = ShardPollPrompt.UrlToHref( value ); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
|
||||
public TimeSpan Duration
|
||||
{
|
||||
get{ return m_Duration; }
|
||||
set{ m_Duration = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
|
||||
public DateTime StartTime
|
||||
{
|
||||
get{ return m_StartTime; }
|
||||
set{ m_StartTime = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
|
||||
public TimeSpan TimeRemaining
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_StartTime == DateTime.MinValue || !m_Active )
|
||||
return TimeSpan.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
TimeSpan ts = (m_StartTime + m_Duration) - DateTime.UtcNow;
|
||||
|
||||
if ( ts < TimeSpan.Zero )
|
||||
return TimeSpan.Zero;
|
||||
|
||||
return ts;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster, AccessLevel.Administrator )]
|
||||
public bool Active
|
||||
{
|
||||
get{ return m_Active; }
|
||||
set
|
||||
{
|
||||
if ( m_Active == value )
|
||||
return;
|
||||
|
||||
m_Active = value;
|
||||
|
||||
if ( m_Active )
|
||||
{
|
||||
m_StartTime = DateTime.UtcNow;
|
||||
m_ActivePollers.Add( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ActivePollers.Remove( this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasAlreadyVoted( NetState ns )
|
||||
{
|
||||
for ( int i = 0; i < m_Options.Length; ++i )
|
||||
{
|
||||
if ( m_Options[i].HasAlreadyVoted( ns ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void AddVote( NetState ns, ShardPollOption option )
|
||||
{
|
||||
option.AddVote( ns );
|
||||
}
|
||||
|
||||
public void RemoveOption( ShardPollOption option )
|
||||
{
|
||||
int index = Array.IndexOf( m_Options, option );
|
||||
|
||||
if ( index < 0 )
|
||||
return;
|
||||
|
||||
ShardPollOption[] old = m_Options;
|
||||
m_Options = new ShardPollOption[old.Length - 1];
|
||||
|
||||
for ( int i = 0; i < index; ++i )
|
||||
m_Options[i] = old[i];
|
||||
|
||||
for ( int i = index; i < m_Options.Length; ++i )
|
||||
m_Options[i] = old[i + 1];
|
||||
}
|
||||
|
||||
public void AddOption( ShardPollOption option )
|
||||
{
|
||||
ShardPollOption[] old = m_Options;
|
||||
m_Options = new ShardPollOption[old.Length + 1];
|
||||
|
||||
for ( int i = 0; i < old.Length; ++i )
|
||||
m_Options[i] = old[i];
|
||||
|
||||
m_Options[old.Length] = option;
|
||||
}
|
||||
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "shard poller"; }
|
||||
}
|
||||
|
||||
[Constructable( AccessLevel.Administrator )]
|
||||
public ShardPoller() : base( 0x1047 )
|
||||
{
|
||||
m_Duration = TimeSpan.FromHours( 24.0 );
|
||||
m_Options = new ShardPollOption[0];
|
||||
m_Addresses = new IPAddress[0];
|
||||
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Login += new LoginEventHandler( EventSink_Login );
|
||||
}
|
||||
|
||||
private static List<ShardPoller> m_ActivePollers = new List<ShardPoller>();
|
||||
|
||||
private static void EventSink_Login( LoginEventArgs e )
|
||||
{
|
||||
if ( m_ActivePollers.Count == 0 )
|
||||
return;
|
||||
|
||||
Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerStateCallback( EventSink_Login_Callback ), e.Mobile );
|
||||
}
|
||||
|
||||
private static void EventSink_Login_Callback( object state )
|
||||
{
|
||||
Mobile from = (Mobile)state;
|
||||
NetState ns = from.NetState;
|
||||
|
||||
if ( ns == null )
|
||||
return;
|
||||
|
||||
ShardPollGump spg = null;
|
||||
|
||||
for ( int i = 0; i < m_ActivePollers.Count; ++i )
|
||||
{
|
||||
ShardPoller poller = m_ActivePollers[i];
|
||||
|
||||
if ( poller.Deleted || !poller.Active )
|
||||
continue;
|
||||
|
||||
if ( poller.TimeRemaining > TimeSpan.Zero )
|
||||
{
|
||||
if ( poller.HasAlreadyVoted( ns ) )
|
||||
continue;
|
||||
|
||||
if ( spg == null )
|
||||
{
|
||||
spg = new ShardPollGump( from, poller, false, null );
|
||||
from.SendGump( spg );
|
||||
}
|
||||
else
|
||||
{
|
||||
spg.QueuePoll( poller );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
poller.Active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SendQueuedPoll_Callback( object state )
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
Mobile from = (Mobile)states[0];
|
||||
Queue<ShardPoller> queue = (Queue<ShardPoller>)states[1];
|
||||
|
||||
from.SendGump( new ShardPollGump( from, this, false, queue ) );
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.Administrator )
|
||||
from.SendGump( new ShardPollGump( from, this, true, null ) );
|
||||
}
|
||||
|
||||
public ShardPoller( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( m_Title );
|
||||
writer.Write( m_Duration );
|
||||
writer.Write( m_StartTime );
|
||||
writer.Write( m_Active );
|
||||
|
||||
writer.Write( m_Options.Length );
|
||||
|
||||
for ( int i = 0; i < m_Options.Length; ++i )
|
||||
m_Options[i].Serialize( writer );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Title = reader.ReadString();
|
||||
m_Duration = reader.ReadTimeSpan();
|
||||
m_StartTime = reader.ReadDateTime();
|
||||
m_Active = reader.ReadBool();
|
||||
|
||||
m_Options = new ShardPollOption[reader.ReadInt()];
|
||||
|
||||
for ( int i = 0; i < m_Options.Length; ++i )
|
||||
m_Options[i] = new ShardPollOption( reader );
|
||||
|
||||
if ( m_Active )
|
||||
m_ActivePollers.Add( this );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
Active = false;
|
||||
}
|
||||
}
|
||||
|
||||
public class ShardPollOption
|
||||
{
|
||||
private string m_Title;
|
||||
private int m_LineBreaks;
|
||||
private IPAddress[] m_Voters;
|
||||
|
||||
public string Title{ get{ return m_Title; } set{ m_Title = value; m_LineBreaks = GetBreaks( m_Title ); } }
|
||||
public int LineBreaks{ get{ return m_LineBreaks; } }
|
||||
|
||||
public int Votes{ get{ return m_Voters.Length; } }
|
||||
public IPAddress[] Voters{ get{ return m_Voters; } set{ m_Voters = value; } }
|
||||
|
||||
public ShardPollOption( string title )
|
||||
{
|
||||
m_Title = title;
|
||||
m_LineBreaks = GetBreaks( m_Title );
|
||||
m_Voters = new IPAddress[0];
|
||||
}
|
||||
|
||||
public bool HasAlreadyVoted( NetState ns )
|
||||
{
|
||||
if ( ns == null )
|
||||
return false;
|
||||
|
||||
IPAddress ipAddress = ns.Address;
|
||||
|
||||
for ( int i = 0; i < m_Voters.Length; ++i )
|
||||
{
|
||||
if ( Utility.IPMatchClassC( m_Voters[i], ipAddress ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void AddVote( NetState ns )
|
||||
{
|
||||
if ( ns == null )
|
||||
return;
|
||||
|
||||
IPAddress[] old = m_Voters;
|
||||
m_Voters = new IPAddress[old.Length + 1];
|
||||
|
||||
for ( int i = 0; i < old.Length; ++i )
|
||||
m_Voters[i] = old[i];
|
||||
|
||||
m_Voters[old.Length] = ns.Address;
|
||||
}
|
||||
|
||||
public int ComputeHeight()
|
||||
{
|
||||
int height = m_LineBreaks * 18;
|
||||
|
||||
if ( height > 30 )
|
||||
return height;
|
||||
|
||||
return 30;
|
||||
}
|
||||
|
||||
public int GetBreaks( string title )
|
||||
{
|
||||
if ( title == null )
|
||||
return 1;
|
||||
|
||||
int count = 0;
|
||||
int index = -1;
|
||||
|
||||
do
|
||||
{
|
||||
++count;
|
||||
index = title.IndexOf( "<br>", index + 1 );
|
||||
} while ( index >= 0 );
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public ShardPollOption( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Title = reader.ReadString();
|
||||
m_LineBreaks = GetBreaks( m_Title );
|
||||
|
||||
m_Voters = new IPAddress[reader.ReadInt()];
|
||||
|
||||
for ( int i = 0; i < m_Voters.Length; ++i )
|
||||
m_Voters[i] = Utility.Intern( reader.ReadIPAddress() );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( m_Title );
|
||||
|
||||
writer.Write( m_Voters.Length );
|
||||
|
||||
for ( int i = 0; i < m_Voters.Length; ++i )
|
||||
writer.Write( m_Voters[i] );
|
||||
}
|
||||
}
|
||||
|
||||
public class ShardPollGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private ShardPoller m_Poller;
|
||||
private bool m_Editing;
|
||||
private Queue<ShardPoller> m_Polls;
|
||||
|
||||
public bool Editing{ get{ return m_Editing; } }
|
||||
|
||||
public void QueuePoll( ShardPoller poller )
|
||||
{
|
||||
if ( m_Polls == null )
|
||||
m_Polls = new Queue<ShardPoller>( 4 );
|
||||
|
||||
m_Polls.Enqueue( poller );
|
||||
}
|
||||
|
||||
public string Center( string text )
|
||||
{
|
||||
return String.Format( "<CENTER>{0}</CENTER>", text );
|
||||
}
|
||||
|
||||
public string Color( string text, int color )
|
||||
{
|
||||
return String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", color, text );
|
||||
}
|
||||
|
||||
private const int LabelColor32 = 0xFFFFFF;
|
||||
|
||||
public ShardPollGump( Mobile from, ShardPoller poller, bool editing, Queue<ShardPoller> polls ) : base( 50, 50 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Poller = poller;
|
||||
m_Editing = editing;
|
||||
m_Polls = polls;
|
||||
|
||||
Closable = false;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
int totalVotes = 0;
|
||||
int totalOptionHeight = 0;
|
||||
|
||||
for ( int i = 0; i < poller.Options.Length; ++i )
|
||||
{
|
||||
totalVotes += poller.Options[i].Votes;
|
||||
totalOptionHeight += poller.Options[i].ComputeHeight() + 5;
|
||||
}
|
||||
|
||||
bool isViewingResults = editing && poller.Active;
|
||||
bool isCompleted = totalVotes > 0 && !poller.Active;
|
||||
|
||||
if ( editing && !isViewingResults )
|
||||
totalOptionHeight += 35;
|
||||
|
||||
int height = 115 + totalOptionHeight;
|
||||
|
||||
AddBackground( 1, 1, 398, height - 2, 3600 );
|
||||
AddAlphaRegion( 16, 15, 369, height - 31 );
|
||||
|
||||
AddItem( 308, 30, 0x1E5E );
|
||||
|
||||
string title;
|
||||
|
||||
if ( editing )
|
||||
title = ( isCompleted ? "Poll Completed" : "Poll Editor" );
|
||||
else
|
||||
title = "Shard Poll";
|
||||
|
||||
AddHtml( 22, 22, 294, 20, Color( Center( title ), LabelColor32 ), false, false );
|
||||
|
||||
if ( editing )
|
||||
{
|
||||
AddHtml( 22, 22, 294, 20, Color( String.Format( "{0} total", totalVotes ), LabelColor32 ), false, false );
|
||||
AddButton( 287, 23, 0x2622, 0x2623, 2, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
|
||||
AddHtml( 22, 50, 294, 40, Color( poller.Title, 0x99CC66 ), false, false );
|
||||
|
||||
AddImageTiled( 32, 88, 264, 1, 9107 );
|
||||
AddImageTiled( 42, 90, 264, 1, 9157 );
|
||||
|
||||
int y = 100;
|
||||
|
||||
for ( int i = 0; i < poller.Options.Length; ++i )
|
||||
{
|
||||
ShardPollOption option = poller.Options[i];
|
||||
string text = option.Title;
|
||||
|
||||
if ( editing && totalVotes > 0 )
|
||||
{
|
||||
double perc = option.Votes / (double)totalVotes;
|
||||
|
||||
text = String.Format( "[{1}: {2}%] {0}", text, option.Votes, (int)(perc*100) );
|
||||
}
|
||||
|
||||
int optHeight = option.ComputeHeight();
|
||||
|
||||
y += optHeight/2;
|
||||
|
||||
if ( isViewingResults )
|
||||
AddImage( 24, y - 15, 0x25FE );
|
||||
else
|
||||
AddRadio( 24, y - 15, 0x25F9, 0x25FC, false, 1 + i );
|
||||
|
||||
AddHtml( 60, y - (9 * option.LineBreaks), 250, 18 * option.LineBreaks, Color( text, LabelColor32 ), false, false );
|
||||
|
||||
y += optHeight/2;
|
||||
y += 5;
|
||||
}
|
||||
|
||||
if ( editing && !isViewingResults )
|
||||
{
|
||||
AddRadio( 24, y + 15 - 15, 0x25F9, 0x25FC, false, 1 + poller.Options.Length );
|
||||
AddHtml( 60, y + 15 - 9, 250, 18, Color( "Create new option.", 0x99CC66 ), false, false );
|
||||
}
|
||||
|
||||
AddButton( 314, height - 73, 247, 248, 1, GumpButtonType.Reply, 0 );
|
||||
AddButton( 314, height - 47, 242, 241, 0, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( m_Polls != null && m_Polls.Count > 0 )
|
||||
{
|
||||
ShardPoller poller = m_Polls.Dequeue();
|
||||
|
||||
if ( poller != null )
|
||||
Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerStateCallback( poller.SendQueuedPoll_Callback ), new object[]{ m_From, m_Polls } );
|
||||
}
|
||||
|
||||
if ( info.ButtonID == 1 )
|
||||
{
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if ( switches.Length == 0 )
|
||||
return;
|
||||
|
||||
int switched = switches[0] - 1;
|
||||
ShardPollOption opt = null;
|
||||
|
||||
if ( switched >= 0 && switched < m_Poller.Options.Length )
|
||||
opt = m_Poller.Options[switched];
|
||||
|
||||
if ( opt == null && !m_Editing )
|
||||
return;
|
||||
|
||||
if ( m_Editing )
|
||||
{
|
||||
if ( !m_Poller.Active )
|
||||
{
|
||||
m_From.SendMessage( "Enter a title for the option. Escape to cancel.{0}", opt == null ? "" : " Use \"DEL\" to delete." );
|
||||
m_From.Prompt = new ShardPollPrompt( m_Poller, opt );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_From.SendMessage( "You may not edit an active poll. Deactivate it first." );
|
||||
m_From.SendGump( new ShardPollGump( m_From, m_Poller, m_Editing, m_Polls ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !m_Poller.Active )
|
||||
m_From.SendMessage( "The poll has been deactivated." );
|
||||
else if ( m_Poller.HasAlreadyVoted( sender ) )
|
||||
m_From.SendMessage( "You have already voted on this poll." );
|
||||
else
|
||||
m_Poller.AddVote( sender, opt );
|
||||
}
|
||||
}
|
||||
else if ( info.ButtonID == 2 && m_Editing )
|
||||
{
|
||||
m_From.SendGump( new ShardPollGump( m_From, m_Poller, m_Editing, m_Polls ) );
|
||||
m_From.SendGump( new PropertiesGump( m_From, m_Poller ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ShardPollPrompt : Prompt
|
||||
{
|
||||
private ShardPoller m_Poller;
|
||||
private ShardPollOption m_Option;
|
||||
|
||||
public ShardPollPrompt( ShardPoller poller, ShardPollOption opt )
|
||||
{
|
||||
m_Poller = poller;
|
||||
m_Option = opt;
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
from.SendGump( new ShardPollGump( from, m_Poller, true, null ) );
|
||||
}
|
||||
|
||||
private static Regex m_UrlRegex = new Regex( @"\[url(?:=(.*?))?\](.*?)\[/url\]", RegexOptions.IgnoreCase | RegexOptions.Compiled );
|
||||
|
||||
private static string UrlRegex_Match( Match m )
|
||||
{
|
||||
if ( m.Groups[1].Success )
|
||||
{
|
||||
if ( m.Groups[2].Success )
|
||||
return String.Format( "<a href=\"{0}\">{1}</a>", m.Groups[1].Value, m.Groups[2].Value );
|
||||
}
|
||||
else if ( m.Groups[2].Success )
|
||||
{
|
||||
return String.Format( "<a href=\"{0}\">{0}</a>", m.Groups[2].Value );
|
||||
}
|
||||
|
||||
return m.Value;
|
||||
}
|
||||
|
||||
public static string UrlToHref( string text )
|
||||
{
|
||||
if ( text == null )
|
||||
return null;
|
||||
|
||||
return m_UrlRegex.Replace( text, new MatchEvaluator( UrlRegex_Match ) );
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
if ( m_Poller.Active )
|
||||
{
|
||||
from.SendMessage( "You may not edit an active poll. Deactivate it first." );
|
||||
}
|
||||
else if ( text == "DEL" )
|
||||
{
|
||||
if ( m_Option != null )
|
||||
m_Poller.RemoveOption( m_Option );
|
||||
}
|
||||
else
|
||||
{
|
||||
text = UrlToHref( text );
|
||||
|
||||
if ( m_Option == null )
|
||||
m_Poller.AddOption( new ShardPollOption( text ) );
|
||||
else
|
||||
m_Option.Title = text;
|
||||
}
|
||||
|
||||
from.SendGump( new ShardPollGump( from, m_Poller, true, null ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Scripts/Misc/ShrinkTable.cs
Normal file
86
Scripts/Misc/ShrinkTable.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class ShrinkTable
|
||||
{
|
||||
public const int DefaultItemID = 0x1870; // Yellow virtue stone
|
||||
|
||||
private static int[] m_Table;
|
||||
|
||||
public static int Lookup( Mobile m )
|
||||
{
|
||||
return Lookup( m.Body.BodyID, DefaultItemID );
|
||||
}
|
||||
|
||||
public static int Lookup( int body )
|
||||
{
|
||||
return Lookup( body, DefaultItemID );
|
||||
}
|
||||
|
||||
public static int Lookup( Mobile m, int defaultValue )
|
||||
{
|
||||
return Lookup( m.Body.BodyID, defaultValue );
|
||||
}
|
||||
|
||||
public static int Lookup( int body, int defaultValue )
|
||||
{
|
||||
if ( m_Table == null )
|
||||
Load();
|
||||
|
||||
int val = 0;
|
||||
|
||||
if ( body >= 0 && body < m_Table.Length )
|
||||
val = m_Table[body];
|
||||
|
||||
if ( val == 0 )
|
||||
val = defaultValue;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
private static void Load()
|
||||
{
|
||||
string path = Path.Combine( Core.BaseDirectory, "Data/shrink.cfg" );
|
||||
|
||||
if ( !File.Exists( path ) )
|
||||
{
|
||||
m_Table = new int[0];
|
||||
return;
|
||||
}
|
||||
|
||||
m_Table = new int[1000];
|
||||
|
||||
using ( StreamReader ip = new StreamReader( path ) )
|
||||
{
|
||||
string line;
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
{
|
||||
line = line.Trim();
|
||||
|
||||
if ( line.Length == 0 || line.StartsWith( "#" ) )
|
||||
continue;
|
||||
|
||||
try
|
||||
{
|
||||
string[] split = line.Split( '\t' );
|
||||
|
||||
if ( split.Length >= 2 )
|
||||
{
|
||||
int body = Utility.ToInt32( split[0] );
|
||||
int item = Utility.ToInt32( split[1] );
|
||||
|
||||
if ( body >= 0 && body < m_Table.Length )
|
||||
m_Table[body] = item;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
391
Scripts/Misc/SkillCheck.cs
Normal file
391
Scripts/Misc/SkillCheck.cs
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Factions;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class SkillCheck
|
||||
{
|
||||
private static readonly bool AntiMacroCode = !Core.ML; //Change this to false to disable anti-macro code
|
||||
|
||||
public static TimeSpan AntiMacroExpire = TimeSpan.FromMinutes( 5.0 ); //How long do we remember targets/locations?
|
||||
public const int Allowance = 3; //How many times may we use the same location/target for gain
|
||||
private const int LocationSize = 5; //The size of eeach location, make this smaller so players dont have to move as far
|
||||
private static bool[] UseAntiMacro = new bool[]
|
||||
{
|
||||
// true if this skill uses the anti-macro code, false if it does not
|
||||
false,// Alchemy = 0,
|
||||
true,// Anatomy = 1,
|
||||
true,// AnimalLore = 2,
|
||||
true,// ItemID = 3,
|
||||
true,// ArmsLore = 4,
|
||||
false,// Parry = 5,
|
||||
true,// Begging = 6,
|
||||
false,// Blacksmith = 7,
|
||||
false,// Fletching = 8,
|
||||
true,// Peacemaking = 9,
|
||||
true,// Camping = 10,
|
||||
false,// Carpentry = 11,
|
||||
false,// Cartography = 12,
|
||||
false,// Cooking = 13,
|
||||
true,// DetectHidden = 14,
|
||||
true,// Discordance = 15,
|
||||
true,// EvalInt = 16,
|
||||
true,// Healing = 17,
|
||||
true,// Fishing = 18,
|
||||
true,// Forensics = 19,
|
||||
true,// Herding = 20,
|
||||
true,// Hiding = 21,
|
||||
true,// Provocation = 22,
|
||||
false,// Inscribe = 23,
|
||||
true,// Lockpicking = 24,
|
||||
true,// Magery = 25,
|
||||
true,// MagicResist = 26,
|
||||
false,// Tactics = 27,
|
||||
true,// Snooping = 28,
|
||||
true,// Musicianship = 29,
|
||||
true,// Poisoning = 30,
|
||||
false,// Archery = 31,
|
||||
true,// SpiritSpeak = 32,
|
||||
true,// Stealing = 33,
|
||||
false,// Tailoring = 34,
|
||||
true,// AnimalTaming = 35,
|
||||
true,// TasteID = 36,
|
||||
false,// Tinkering = 37,
|
||||
true,// Tracking = 38,
|
||||
true,// Veterinary = 39,
|
||||
false,// Swords = 40,
|
||||
false,// Macing = 41,
|
||||
false,// Fencing = 42,
|
||||
false,// Wrestling = 43,
|
||||
true,// Lumberjacking = 44,
|
||||
true,// Mining = 45,
|
||||
true,// Meditation = 46,
|
||||
true,// Stealth = 47,
|
||||
true,// RemoveTrap = 48,
|
||||
true,// Necromancy = 49,
|
||||
false,// Focus = 50,
|
||||
true,// Chivalry = 51
|
||||
true,// Bushido = 52
|
||||
true,//Ninjitsu = 53
|
||||
true // Spellweaving
|
||||
};
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Mobile.SkillCheckLocationHandler = new SkillCheckLocationHandler( Mobile_SkillCheckLocation );
|
||||
Mobile.SkillCheckDirectLocationHandler = new SkillCheckDirectLocationHandler( Mobile_SkillCheckDirectLocation );
|
||||
|
||||
Mobile.SkillCheckTargetHandler = new SkillCheckTargetHandler( Mobile_SkillCheckTarget );
|
||||
Mobile.SkillCheckDirectTargetHandler = new SkillCheckDirectTargetHandler( Mobile_SkillCheckDirectTarget );
|
||||
}
|
||||
|
||||
public static bool Mobile_SkillCheckLocation( Mobile from, SkillName skillName, double minSkill, double maxSkill )
|
||||
{
|
||||
Skill skill = from.Skills[skillName];
|
||||
|
||||
if ( skill == null )
|
||||
return false;
|
||||
|
||||
double value = skill.Value;
|
||||
|
||||
if ( value < minSkill )
|
||||
return false; // Too difficult
|
||||
else if ( value >= maxSkill )
|
||||
return true; // No challenge
|
||||
|
||||
double chance = (value - minSkill) / (maxSkill - minSkill);
|
||||
|
||||
Point2D loc = new Point2D( from.Location.X / LocationSize, from.Location.Y / LocationSize );
|
||||
return CheckSkill( from, skill, loc, chance );
|
||||
}
|
||||
|
||||
public static bool Mobile_SkillCheckDirectLocation( Mobile from, SkillName skillName, double chance )
|
||||
{
|
||||
Skill skill = from.Skills[skillName];
|
||||
|
||||
if ( skill == null )
|
||||
return false;
|
||||
|
||||
if ( chance < 0.0 )
|
||||
return false; // Too difficult
|
||||
else if ( chance >= 1.0 )
|
||||
return true; // No challenge
|
||||
|
||||
Point2D loc = new Point2D( from.Location.X / LocationSize, from.Location.Y / LocationSize );
|
||||
return CheckSkill( from, skill, loc, chance );
|
||||
}
|
||||
|
||||
public static bool CheckSkill( Mobile from, Skill skill, object amObj, double chance )
|
||||
{
|
||||
if ( from.Skills.Cap == 0 )
|
||||
return false;
|
||||
double gainer = 2.0;
|
||||
gainer = gainer - ValidSettings.SkillGain();
|
||||
|
||||
bool success = ( chance >= Utility.RandomDouble() );
|
||||
double gc = (double)(from.Skills.Cap - from.Skills.Total) / from.Skills.Cap;
|
||||
gc += ( skill.Cap - skill.Base ) / skill.Cap;
|
||||
gc /= gainer;
|
||||
|
||||
gc += ( 1.0 - chance ) * ( success ? 0.5 : (Core.AOS ? 0.0 : 0.2) );
|
||||
gc /= gainer;
|
||||
|
||||
gc *= skill.Info.GainFactor;
|
||||
|
||||
if ( gc < 0.01 )
|
||||
gc = 0.01;
|
||||
|
||||
if ( from is BaseCreature && ((BaseCreature)from).Controlled )
|
||||
gc *= 2;
|
||||
|
||||
if ( from.Alive && ( ( gc >= Utility.RandomDouble() && AllowGain( from, skill, amObj ) ) || skill.Base < 10.0 ) )
|
||||
Gain( from, skill );
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public static bool Mobile_SkillCheckTarget( Mobile from, SkillName skillName, object target, double minSkill, double maxSkill )
|
||||
{
|
||||
Skill skill = from.Skills[skillName];
|
||||
|
||||
if ( skill == null )
|
||||
return false;
|
||||
|
||||
double value = skill.Value;
|
||||
|
||||
if ( value < minSkill )
|
||||
return false; // Too difficult
|
||||
else if ( value >= maxSkill )
|
||||
return true; // No challenge
|
||||
|
||||
double chance = (value - minSkill) / (maxSkill - minSkill);
|
||||
|
||||
return CheckSkill( from, skill, target, chance );
|
||||
}
|
||||
|
||||
public static bool Mobile_SkillCheckDirectTarget( Mobile from, SkillName skillName, object target, double chance )
|
||||
{
|
||||
Skill skill = from.Skills[skillName];
|
||||
|
||||
if ( skill == null )
|
||||
return false;
|
||||
|
||||
if ( chance < 0.0 )
|
||||
return false; // Too difficult
|
||||
else if ( chance >= 1.0 )
|
||||
return true; // No challenge
|
||||
|
||||
return CheckSkill( from, skill, target, chance );
|
||||
}
|
||||
|
||||
private static bool AllowGain( Mobile from, Skill skill, object obj )
|
||||
{
|
||||
if ( Core.AOS && Faction.InSkillLoss( from ) ) //Changed some time between the introduction of AoS and SE.
|
||||
return false;
|
||||
|
||||
if ( AntiMacroCode && from is PlayerMobile && UseAntiMacro[skill.Info.SkillID] )
|
||||
return ((PlayerMobile)from).AntiMacroCheck( skill, obj );
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
public enum Stat { Str, Dex, Int }
|
||||
|
||||
public static void Gain( Mobile from, Skill skill )
|
||||
{
|
||||
if ( from.Region.IsPartOf( typeof( Regions.Jail ) ) )
|
||||
return;
|
||||
|
||||
if ( from is BaseCreature && ((BaseCreature)from).IsDeadPet )
|
||||
return;
|
||||
|
||||
if ( skill.SkillName == SkillName.Focus && from is BaseCreature )
|
||||
return;
|
||||
|
||||
if ( skill.Base < skill.Cap && skill.Lock == SkillLock.Up )
|
||||
{
|
||||
int toGain = 1;
|
||||
|
||||
if ( skill.Base <= 10.0 )
|
||||
toGain = Utility.Random( 4 ) + 1;
|
||||
|
||||
Skills skills = from.Skills;
|
||||
|
||||
if ( from.Player && ( skills.Total / skills.Cap ) >= Utility.RandomDouble() )//( skills.Total >= skills.Cap )
|
||||
{
|
||||
for ( int i = 0; i < skills.Length; ++i )
|
||||
{
|
||||
Skill toLower = skills[i];
|
||||
|
||||
if ( toLower != skill && toLower.Lock == SkillLock.Down && toLower.BaseFixedPoint >= toGain )
|
||||
{
|
||||
toLower.BaseFixedPoint -= toGain;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Scroll of Alacrity
|
||||
PlayerMobile pm = from as PlayerMobile;
|
||||
|
||||
if ( pm != null && skill.SkillName == pm.AcceleratedSkill && pm.AcceleratedStart > DateTime.UtcNow )
|
||||
toGain *= Utility.RandomMinMax(2, 5);
|
||||
#endregion
|
||||
|
||||
if ( !from.Player || (skills.Total + toGain) <= skills.Cap )
|
||||
{
|
||||
skill.BaseFixedPoint += toGain;
|
||||
}
|
||||
}
|
||||
|
||||
if ( skill.Lock == SkillLock.Up )
|
||||
{
|
||||
SkillInfo info = skill.Info;
|
||||
|
||||
if ( from.StrLock == StatLockType.Up && (info.StrGain / ValidSettings.StatGain()) > Utility.RandomDouble() )
|
||||
GainStat( from, Stat.Str );
|
||||
else if ( from.DexLock == StatLockType.Up && (info.DexGain / ValidSettings.StatGain()) > Utility.RandomDouble() )
|
||||
GainStat( from, Stat.Dex );
|
||||
else if ( from.IntLock == StatLockType.Up && (info.IntGain / ValidSettings.StatGain()) > Utility.RandomDouble() )
|
||||
GainStat( from, Stat.Int );
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CanLower( Mobile from, Stat stat )
|
||||
{
|
||||
switch ( stat )
|
||||
{
|
||||
case Stat.Str: return ( from.StrLock == StatLockType.Down && from.RawStr > 10 );
|
||||
case Stat.Dex: return ( from.DexLock == StatLockType.Down && from.RawDex > 10 );
|
||||
case Stat.Int: return ( from.IntLock == StatLockType.Down && from.RawInt > 10 );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static bool CanRaise( Mobile from, Stat stat )
|
||||
{
|
||||
if ( !(from is BaseCreature && ((BaseCreature)from).Controlled) )
|
||||
{
|
||||
if ( from.RawStatTotal >= from.StatCap )
|
||||
return false;
|
||||
}
|
||||
|
||||
switch ( stat )
|
||||
{
|
||||
case Stat.Str: return ( from.StrLock == StatLockType.Up && from.RawStr < 125 );
|
||||
case Stat.Dex: return ( from.DexLock == StatLockType.Up && from.RawDex < 125 );
|
||||
case Stat.Int: return ( from.IntLock == StatLockType.Up && from.RawInt < 125 );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void IncreaseStat( Mobile from, Stat stat, bool atrophy )
|
||||
{
|
||||
atrophy = atrophy || (from.RawStatTotal >= from.StatCap);
|
||||
|
||||
switch ( stat )
|
||||
{
|
||||
case Stat.Str:
|
||||
{
|
||||
if ( atrophy )
|
||||
{
|
||||
if ( CanLower( from, Stat.Dex ) && (from.RawDex < from.RawInt || !CanLower( from, Stat.Int )) )
|
||||
--from.RawDex;
|
||||
else if ( CanLower( from, Stat.Int ) )
|
||||
--from.RawInt;
|
||||
}
|
||||
|
||||
if ( CanRaise( from, Stat.Str ) )
|
||||
++from.RawStr;
|
||||
|
||||
break;
|
||||
}
|
||||
case Stat.Dex:
|
||||
{
|
||||
if ( atrophy )
|
||||
{
|
||||
if ( CanLower( from, Stat.Str ) && (from.RawStr < from.RawInt || !CanLower( from, Stat.Int )) )
|
||||
--from.RawStr;
|
||||
else if ( CanLower( from, Stat.Int ) )
|
||||
--from.RawInt;
|
||||
}
|
||||
|
||||
if ( CanRaise( from, Stat.Dex ) )
|
||||
++from.RawDex;
|
||||
|
||||
break;
|
||||
}
|
||||
case Stat.Int:
|
||||
{
|
||||
if ( atrophy )
|
||||
{
|
||||
if ( CanLower( from, Stat.Str ) && (from.RawStr < from.RawDex || !CanLower( from, Stat.Dex )) )
|
||||
--from.RawStr;
|
||||
else if ( CanLower( from, Stat.Dex ) )
|
||||
--from.RawDex;
|
||||
}
|
||||
|
||||
if ( CanRaise( from, Stat.Int ) )
|
||||
++from.RawInt;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static TimeSpan m_StatGainDelay = ValidSettings.StatGainDelay(); //TimeSpan.FromMinutes( ( Core.ML ) ? 0.05 : 15 );
|
||||
private static TimeSpan m_PetStatGainDelay = TimeSpan.FromMinutes( 5.0 );
|
||||
|
||||
public static void GainStat( Mobile from, Stat stat )
|
||||
{
|
||||
switch( stat )
|
||||
{
|
||||
case Stat.Str:
|
||||
{
|
||||
if ( from is BaseCreature && ((BaseCreature)from).Controlled ) {
|
||||
if ( (from.LastStrGain + m_PetStatGainDelay) >= DateTime.UtcNow )
|
||||
return;
|
||||
}
|
||||
else if( (from.LastStrGain + m_StatGainDelay) >= DateTime.UtcNow )
|
||||
return;
|
||||
|
||||
from.LastStrGain = DateTime.UtcNow;
|
||||
break;
|
||||
}
|
||||
case Stat.Dex:
|
||||
{
|
||||
if ( from is BaseCreature && ((BaseCreature)from).Controlled ) {
|
||||
if ( (from.LastDexGain + m_PetStatGainDelay) >= DateTime.UtcNow )
|
||||
return;
|
||||
}
|
||||
else if( (from.LastDexGain + m_StatGainDelay) >= DateTime.UtcNow )
|
||||
return;
|
||||
|
||||
from.LastDexGain = DateTime.UtcNow;
|
||||
break;
|
||||
}
|
||||
case Stat.Int:
|
||||
{
|
||||
if ( from is BaseCreature && ((BaseCreature)from).Controlled ) {
|
||||
if ( (from.LastIntGain + m_PetStatGainDelay) >= DateTime.UtcNow )
|
||||
return;
|
||||
}
|
||||
|
||||
else if( (from.LastIntGain + m_StatGainDelay) >= DateTime.UtcNow )
|
||||
return;
|
||||
|
||||
from.LastIntGain = DateTime.UtcNow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool atrophy = ( (from.RawStatTotal / (double)from.StatCap) >= Utility.RandomDouble() );
|
||||
|
||||
IncreaseStat( from, stat, atrophy );
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Scripts/Misc/SocketOptions.cs
Normal file
42
Scripts/Misc/SocketOptions.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class SocketOptions
|
||||
{
|
||||
private const bool NagleEnabled = false; // Should the Nagle algorithm be enabled? This may reduce performance
|
||||
private const int CoalesceBufferSize = 512; // MSS that the core will use when buffering packets
|
||||
|
||||
private static IPEndPoint[] m_ListenerEndPoints = new IPEndPoint[] {
|
||||
new IPEndPoint( IPAddress.Any, Settings.S_Port ), // Default: Listen on port 2593 on all IP addresses
|
||||
|
||||
// Examples:
|
||||
// new IPEndPoint( IPAddress.Any, 80 ), // Listen on port 80 on all IP addresses
|
||||
// new IPEndPoint( IPAddress.Parse( "1.2.3.4" ), 2593 ), // Listen on port 2593 on IP address 1.2.3.4
|
||||
};
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
SendQueue.CoalesceBufferSize = CoalesceBufferSize;
|
||||
|
||||
EventSink.SocketConnect += new SocketConnectEventHandler( EventSink_SocketConnect );
|
||||
|
||||
Listener.EndPoints = m_ListenerEndPoints;
|
||||
}
|
||||
|
||||
private static void EventSink_SocketConnect( SocketConnectEventArgs e )
|
||||
{
|
||||
if ( !e.AllowConnection )
|
||||
return;
|
||||
|
||||
if ( !NagleEnabled )
|
||||
e.Socket.SetSocketOption( SocketOptionLevel.Tcp, SocketOptionName.NoDelay, 1 ); // RunUO uses its own algorithm
|
||||
}
|
||||
}
|
||||
}
|
||||
224
Scripts/Misc/TextDefinition.cs
Normal file
224
Scripts/Misc/TextDefinition.cs
Normal file
|
|
@ -0,0 +1,224 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
[Parsable]
|
||||
public class TextDefinition
|
||||
{
|
||||
private int m_Number;
|
||||
private string m_String;
|
||||
|
||||
public int Number { get { return m_Number; } }
|
||||
public string String { get { return m_String; } }
|
||||
|
||||
public bool IsEmpty { get { return ( m_Number <= 0 && m_String == null ); } }
|
||||
|
||||
public TextDefinition() : this( 0, null )
|
||||
{
|
||||
}
|
||||
|
||||
public TextDefinition( int number ) : this( number, null )
|
||||
{
|
||||
}
|
||||
|
||||
public TextDefinition( string text ) : this( 0, text )
|
||||
{
|
||||
}
|
||||
|
||||
public TextDefinition( int number, string text )
|
||||
{
|
||||
m_Number = number;
|
||||
m_String = text;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if ( m_Number > 0 )
|
||||
return String.Concat( "#", m_Number.ToString() );
|
||||
else if ( m_String != null )
|
||||
return m_String;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public string Format( bool propsGump )
|
||||
{
|
||||
if ( m_Number > 0 )
|
||||
return String.Format( "{0} (0x{0:X})", m_Number );
|
||||
else if ( m_String != null )
|
||||
return String.Format( "\"{0}\"", m_String );
|
||||
|
||||
return propsGump ? "-empty-" : "empty";
|
||||
}
|
||||
|
||||
public string GetValue()
|
||||
{
|
||||
if ( m_Number > 0 )
|
||||
return m_Number.ToString();
|
||||
else if ( m_String != null )
|
||||
return m_String;
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void Serialize( GenericWriter writer, TextDefinition def )
|
||||
{
|
||||
if ( def == null )
|
||||
{
|
||||
writer.WriteEncodedInt( 3 );
|
||||
}
|
||||
else if ( def.m_Number > 0 )
|
||||
{
|
||||
writer.WriteEncodedInt( 1 );
|
||||
writer.WriteEncodedInt( def.m_Number );
|
||||
}
|
||||
else if ( def.m_String != null )
|
||||
{
|
||||
writer.WriteEncodedInt( 2 );
|
||||
writer.Write( def.m_String );
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteEncodedInt( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
public static TextDefinition Deserialize( GenericReader reader )
|
||||
{
|
||||
int type = reader.ReadEncodedInt();
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case 0: return new TextDefinition();
|
||||
case 1: return new TextDefinition( reader.ReadEncodedInt() );
|
||||
case 2: return new TextDefinition( reader.ReadString() );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void AddTo( ObjectPropertyList list, TextDefinition def )
|
||||
{
|
||||
if ( def == null )
|
||||
return;
|
||||
|
||||
if ( def.m_Number > 0 )
|
||||
list.Add( def.m_Number );
|
||||
else if ( def.m_String != null )
|
||||
list.Add( def.m_String );
|
||||
}
|
||||
|
||||
public static implicit operator TextDefinition( int v )
|
||||
{
|
||||
return new TextDefinition( v );
|
||||
}
|
||||
|
||||
public static implicit operator TextDefinition( string s )
|
||||
{
|
||||
return new TextDefinition( s );
|
||||
}
|
||||
|
||||
public static implicit operator int( TextDefinition m )
|
||||
{
|
||||
if ( m == null )
|
||||
return 0;
|
||||
|
||||
return m.m_Number;
|
||||
}
|
||||
|
||||
public static implicit operator string( TextDefinition m )
|
||||
{
|
||||
if ( m == null )
|
||||
return null;
|
||||
|
||||
return m.m_String;
|
||||
}
|
||||
|
||||
public static void AddHtmlText( Gump g, int x, int y, int width, int height, TextDefinition def, bool back, bool scroll, int numberColor, int stringColor )
|
||||
{
|
||||
if ( def == null )
|
||||
return;
|
||||
|
||||
if ( def.m_Number > 0 )
|
||||
{
|
||||
if ( numberColor >= 0 ) // 5 bits per RGB component (15 bit RGB)
|
||||
g.AddHtmlLocalized( x, y, width, height, def.m_Number, numberColor, back, scroll );
|
||||
else
|
||||
g.AddHtmlLocalized( x, y, width, height, def.m_Number, back, scroll );
|
||||
}
|
||||
else if ( def.m_String != null )
|
||||
{
|
||||
if ( stringColor >= 0 ) // 8 bits per RGB component (24 bit RGB)
|
||||
g.AddHtml( x, y, width, height, String.Format( "<BASEFONT COLOR=#{0:X6}>{1}</BASEFONT>", stringColor, def.m_String ), back, scroll );
|
||||
else
|
||||
g.AddHtml( x, y, width, height, def.m_String, back, scroll );
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddHtmlText( Gump g, int x, int y, int width, int height, TextDefinition def, bool back, bool scroll )
|
||||
{
|
||||
AddHtmlText( g, x, y, width, height, def, back, scroll, -1, -1 );
|
||||
}
|
||||
|
||||
public static void SendMessageTo( Mobile m, TextDefinition def )
|
||||
{
|
||||
if ( def == null )
|
||||
return;
|
||||
|
||||
if ( def.m_Number > 0 )
|
||||
m.SendLocalizedMessage( def.m_Number );
|
||||
else if ( def.m_String != null )
|
||||
m.SendMessage( def.m_String );
|
||||
}
|
||||
|
||||
public static void SendMessageTo( Mobile m, TextDefinition def, int hue )
|
||||
{
|
||||
if ( def == null )
|
||||
return;
|
||||
|
||||
if ( def.m_Number > 0 )
|
||||
m.SendLocalizedMessage( def.m_Number, "", hue );
|
||||
else if ( def.m_String != null )
|
||||
m.SendMessage( hue, def.m_String );
|
||||
}
|
||||
|
||||
public static void PublicOverheadMessage( Mobile m, MessageType messageType, int hue, TextDefinition def )
|
||||
{
|
||||
if ( def == null )
|
||||
return;
|
||||
|
||||
if ( def.m_Number > 0 )
|
||||
m.PublicOverheadMessage( messageType, hue, def.m_Number );
|
||||
else if ( def.m_String != null )
|
||||
m.PublicOverheadMessage( messageType, hue, false, def.m_String );
|
||||
}
|
||||
|
||||
public static TextDefinition Parse( string value )
|
||||
{
|
||||
if ( value == null )
|
||||
return null;
|
||||
|
||||
int i;
|
||||
bool isInteger;
|
||||
|
||||
if ( value.StartsWith( "0x" ) )
|
||||
isInteger = int.TryParse( value.Substring( 2 ), NumberStyles.HexNumber, null, out i );
|
||||
else
|
||||
isInteger = int.TryParse( value, out i );
|
||||
|
||||
if ( isInteger )
|
||||
return new TextDefinition( i );
|
||||
else
|
||||
return new TextDefinition( value );
|
||||
}
|
||||
|
||||
public static bool IsNullOrEmpty( TextDefinition def )
|
||||
{
|
||||
return ( def == null || def.IsEmpty );
|
||||
}
|
||||
}
|
||||
}
|
||||
400
Scripts/Misc/Titles.cs
Normal file
400
Scripts/Misc/Titles.cs
Normal file
|
|
@ -0,0 +1,400 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CannedEvil;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Titles
|
||||
{
|
||||
public const int MinFame = 0;
|
||||
public const int MaxFame = 15000;
|
||||
|
||||
public static void AwardFame( Mobile m, int offset, bool message )
|
||||
{
|
||||
if ( offset > 0 )
|
||||
{
|
||||
if ( m.Fame >= MaxFame )
|
||||
return;
|
||||
|
||||
offset -= m.Fame / 100;
|
||||
|
||||
if ( offset < 0 )
|
||||
offset = 0;
|
||||
}
|
||||
else if ( offset < 0 )
|
||||
{
|
||||
if ( m.Fame <= MinFame )
|
||||
return;
|
||||
|
||||
offset -= m.Fame / 100;
|
||||
|
||||
if ( offset > 0 )
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if ( (m.Fame + offset) > MaxFame )
|
||||
offset = MaxFame - m.Fame;
|
||||
else if ( (m.Fame + offset) < MinFame )
|
||||
offset = MinFame - m.Fame;
|
||||
|
||||
m.Fame += offset;
|
||||
|
||||
if ( message )
|
||||
{
|
||||
if ( offset > 40 )
|
||||
m.SendLocalizedMessage( 1019054 ); // You have gained a lot of fame.
|
||||
else if ( offset > 20 )
|
||||
m.SendLocalizedMessage( 1019053 ); // You have gained a good amount of fame.
|
||||
else if ( offset > 10 )
|
||||
m.SendLocalizedMessage( 1019052 ); // You have gained some fame.
|
||||
else if ( offset > 0 )
|
||||
m.SendLocalizedMessage( 1019051 ); // You have gained a little fame.
|
||||
else if ( offset < -40 )
|
||||
m.SendLocalizedMessage( 1019058 ); // You have lost a lot of fame.
|
||||
else if ( offset < -20 )
|
||||
m.SendLocalizedMessage( 1019057 ); // You have lost a good amount of fame.
|
||||
else if ( offset < -10 )
|
||||
m.SendLocalizedMessage( 1019056 ); // You have lost some fame.
|
||||
else if ( offset < 0 )
|
||||
m.SendLocalizedMessage( 1019055 ); // You have lost a little fame.
|
||||
}
|
||||
}
|
||||
|
||||
public const int MinKarma = -15000;
|
||||
public const int MaxKarma = 15000;
|
||||
|
||||
public static void AwardKarma( Mobile m, int offset, bool message )
|
||||
{
|
||||
if ( offset > 0 )
|
||||
{
|
||||
if ( m is PlayerMobile && ((PlayerMobile)m).KarmaLocked )
|
||||
return;
|
||||
|
||||
if ( m.Karma >= MaxKarma )
|
||||
return;
|
||||
|
||||
offset -= m.Karma / 100;
|
||||
|
||||
if ( offset < 0 )
|
||||
offset = 0;
|
||||
}
|
||||
else if ( offset < 0 )
|
||||
{
|
||||
if ( m.Karma <= MinKarma )
|
||||
return;
|
||||
|
||||
offset -= m.Karma / 100;
|
||||
|
||||
if ( offset > 0 )
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
if ( (m.Karma + offset) > MaxKarma )
|
||||
offset = MaxKarma - m.Karma;
|
||||
else if ( (m.Karma + offset) < MinKarma )
|
||||
offset = MinKarma - m.Karma;
|
||||
|
||||
bool wasPositiveKarma = ( m.Karma >= 0 );
|
||||
|
||||
m.Karma += offset;
|
||||
|
||||
if ( message )
|
||||
{
|
||||
if ( offset > 40 )
|
||||
m.SendLocalizedMessage( 1019062 ); // You have gained a lot of karma.
|
||||
else if ( offset > 20 )
|
||||
m.SendLocalizedMessage( 1019061 ); // You have gained a good amount of karma.
|
||||
else if ( offset > 10 )
|
||||
m.SendLocalizedMessage( 1019060 ); // You have gained some karma.
|
||||
else if ( offset > 0 )
|
||||
m.SendLocalizedMessage( 1019059 ); // You have gained a little karma.
|
||||
else if ( offset < -40 )
|
||||
m.SendLocalizedMessage( 1019066 ); // You have lost a lot of karma.
|
||||
else if ( offset < -20 )
|
||||
m.SendLocalizedMessage( 1019065 ); // You have lost a good amount of karma.
|
||||
else if ( offset < -10 )
|
||||
m.SendLocalizedMessage( 1019064 ); // You have lost some karma.
|
||||
else if ( offset < 0 )
|
||||
m.SendLocalizedMessage( 1019063 ); // You have lost a little karma.
|
||||
}
|
||||
|
||||
if ( !Core.AOS && wasPositiveKarma && m.Karma < 0 && m is PlayerMobile && !((PlayerMobile)m).KarmaLocked )
|
||||
{
|
||||
((PlayerMobile)m).KarmaLocked = true;
|
||||
m.SendLocalizedMessage( 1042511, "", 0x22 ); // Karma is locked. A mantra spoken at a shrine will unlock it again.
|
||||
}
|
||||
}
|
||||
|
||||
public static string[] HarrowerTitles = new string[] { "Spite", "Opponent", "Hunter", "Venom", "Executioner", "Annihilator", "Champion", "Assailant", "Purifier", "Nullifier" };
|
||||
|
||||
public static string ComputeTitle( Mobile beholder, Mobile beheld )
|
||||
{
|
||||
StringBuilder title = new StringBuilder();
|
||||
|
||||
int fame = beheld.Fame;
|
||||
int karma = beheld.Karma;
|
||||
|
||||
bool showSkillTitle = beheld.ShowFameTitle && ( (beholder == beheld) || (fame >= 5000) );
|
||||
|
||||
/*if ( beheld.Kills >= 5 )
|
||||
{
|
||||
title.AppendFormat( beheld.Fame >= 10000 ? "The Murderer {1} {0}" : "The Murderer {0}", beheld.Name, beheld.Female ? "Lady" : "Lord" );
|
||||
}
|
||||
else*/if ( beheld.ShowFameTitle || (beholder == beheld) )
|
||||
{
|
||||
for ( int i = 0; i < m_FameEntries.Length; ++i )
|
||||
{
|
||||
FameEntry fe = m_FameEntries[i];
|
||||
|
||||
if ( fame <= fe.m_Fame || i == (m_FameEntries.Length - 1) )
|
||||
{
|
||||
KarmaEntry[] karmaEntries = fe.m_Karma;
|
||||
|
||||
for ( int j = 0; j < karmaEntries.Length; ++j )
|
||||
{
|
||||
KarmaEntry ke = karmaEntries[j];
|
||||
|
||||
if ( karma <= ke.m_Karma || j == (karmaEntries.Length - 1) )
|
||||
{
|
||||
title.AppendFormat( ke.m_Title, beheld.Name, beheld.Female ? "Lady" : "Lord" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
title.Append( beheld.Name );
|
||||
}
|
||||
|
||||
if( beheld is PlayerMobile && ((PlayerMobile)beheld).DisplayChampionTitle )
|
||||
{
|
||||
PlayerMobile.ChampionTitleInfo info = ((PlayerMobile)beheld).ChampionTitles;
|
||||
|
||||
if( info.Harrower > 0 )
|
||||
title.AppendFormat( ": {0} of Evil", HarrowerTitles[Math.Min( HarrowerTitles.Length, info.Harrower )-1] );
|
||||
else
|
||||
{
|
||||
int highestValue = 0, highestType = 0;
|
||||
for( int i = 0; i < ChampionSpawnInfo.Table.Length; i++ )
|
||||
{
|
||||
int v = info.GetValue( i );
|
||||
|
||||
if( v > highestValue )
|
||||
{
|
||||
highestValue = v;
|
||||
highestType = i;
|
||||
}
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
if( highestValue > 800 )
|
||||
offset = 3;
|
||||
else if( highestValue > 300 )
|
||||
offset = (int)(highestValue/300);
|
||||
|
||||
if( offset > 0 )
|
||||
{
|
||||
ChampionSpawnInfo champInfo = ChampionSpawnInfo.GetInfo( (ChampionSpawnType)highestType );
|
||||
title.AppendFormat( ": {0} of the {1}", champInfo.LevelNames[Math.Min( offset, champInfo.LevelNames.Length ) -1], champInfo.Name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string customTitle = beheld.Title;
|
||||
|
||||
if ( customTitle != null && (customTitle = customTitle.Trim()).Length > 0 )
|
||||
{
|
||||
title.AppendFormat( " {0}", customTitle );
|
||||
}
|
||||
else if ( showSkillTitle && beheld.Player )
|
||||
{
|
||||
string skillTitle = GetSkillTitle( beheld );
|
||||
|
||||
if ( skillTitle != null ) {
|
||||
title.Append( ", " ).Append( skillTitle );
|
||||
}
|
||||
}
|
||||
|
||||
return title.ToString();
|
||||
}
|
||||
|
||||
public static string GetSkillTitle( Mobile mob ) {
|
||||
Skill highest = GetHighestSkill( mob );// beheld.Skills.Highest;
|
||||
|
||||
if ( highest != null && highest.BaseFixedPoint >= 300 )
|
||||
{
|
||||
string skillLevel = GetSkillLevel( highest );
|
||||
string skillTitle = highest.Info.Title;
|
||||
|
||||
if ( mob.Female && skillTitle.EndsWith( "man" ) )
|
||||
skillTitle = skillTitle.Substring( 0, skillTitle.Length - 3 ) + "woman";
|
||||
|
||||
return String.Concat( skillLevel, " ", skillTitle );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Skill GetHighestSkill( Mobile m )
|
||||
{
|
||||
Skills skills = m.Skills;
|
||||
|
||||
if ( !Core.AOS )
|
||||
return skills.Highest;
|
||||
|
||||
Skill highest = null;
|
||||
|
||||
for ( int i = 0; i < m.Skills.Length; ++i )
|
||||
{
|
||||
Skill check = m.Skills[i];
|
||||
|
||||
if ( highest == null || check.BaseFixedPoint > highest.BaseFixedPoint )
|
||||
highest = check;
|
||||
else if ( highest != null && highest.Lock != SkillLock.Up && check.Lock == SkillLock.Up && check.BaseFixedPoint == highest.BaseFixedPoint )
|
||||
highest = check;
|
||||
}
|
||||
|
||||
return highest;
|
||||
}
|
||||
|
||||
private static string[,] m_Levels = new string[,]
|
||||
{
|
||||
{ "Neophyte", "Neophyte", "Neophyte" },
|
||||
{ "Novice", "Novice", "Novice" },
|
||||
{ "Apprentice", "Apprentice", "Apprentice" },
|
||||
{ "Journeyman", "Journeyman", "Journeyman" },
|
||||
{ "Expert", "Expert", "Expert" },
|
||||
{ "Adept", "Adept", "Adept" },
|
||||
{ "Master", "Master", "Master" },
|
||||
{ "Grandmaster", "Grandmaster", "Grandmaster" },
|
||||
{ "Elder", "Tatsujin", "Shinobi" },
|
||||
{ "Legendary", "Kengo", "Ka-ge" }
|
||||
};
|
||||
|
||||
private static string GetSkillLevel( Skill skill )
|
||||
{
|
||||
return m_Levels[GetTableIndex( skill ), GetTableType( skill )];
|
||||
}
|
||||
|
||||
private static int GetTableType( Skill skill )
|
||||
{
|
||||
switch ( skill.SkillName )
|
||||
{
|
||||
default: return 0;
|
||||
case SkillName.Bushido: return 1;
|
||||
case SkillName.Ninjitsu: return 2;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetTableIndex( Skill skill )
|
||||
{
|
||||
int fp = Math.Min( skill.BaseFixedPoint, 1200 );
|
||||
|
||||
return (fp - 300) / 100;
|
||||
}
|
||||
|
||||
private static FameEntry[] m_FameEntries = new FameEntry[]
|
||||
{
|
||||
new FameEntry( 1249, new KarmaEntry[]
|
||||
{
|
||||
new KarmaEntry( -10000, "The Outcast {0}" ),
|
||||
new KarmaEntry( -5000, "The Despicable {0}" ),
|
||||
new KarmaEntry( -2500, "The Scoundrel {0}" ),
|
||||
new KarmaEntry( -1250, "The Unsavory {0}" ),
|
||||
new KarmaEntry( -625, "The Rude {0}" ),
|
||||
new KarmaEntry( 624, "{0}" ),
|
||||
new KarmaEntry( 1249, "The Fair {0}" ),
|
||||
new KarmaEntry( 2499, "The Kind {0}" ),
|
||||
new KarmaEntry( 4999, "The Good {0}" ),
|
||||
new KarmaEntry( 9999, "The Honest {0}" ),
|
||||
new KarmaEntry( 10000, "The Trustworthy {0}" )
|
||||
} ),
|
||||
new FameEntry( 2499, new KarmaEntry[]
|
||||
{
|
||||
new KarmaEntry( -10000, "The Wretched {0}" ),
|
||||
new KarmaEntry( -5000, "The Dastardly {0}" ),
|
||||
new KarmaEntry( -2500, "The Malicious {0}" ),
|
||||
new KarmaEntry( -1250, "The Dishonorable {0}" ),
|
||||
new KarmaEntry( -625, "The Disreputable {0}" ),
|
||||
new KarmaEntry( 624, "The Notable {0}" ),
|
||||
new KarmaEntry( 1249, "The Upstanding {0}" ),
|
||||
new KarmaEntry( 2499, "The Respectable {0}" ),
|
||||
new KarmaEntry( 4999, "The Honorable {0}" ),
|
||||
new KarmaEntry( 9999, "The Commendable {0}" ),
|
||||
new KarmaEntry( 10000, "The Estimable {0}" )
|
||||
} ),
|
||||
new FameEntry( 4999, new KarmaEntry[]
|
||||
{
|
||||
new KarmaEntry( -10000, "The Nefarious {0}" ),
|
||||
new KarmaEntry( -5000, "The Wicked {0}" ),
|
||||
new KarmaEntry( -2500, "The Vile {0}" ),
|
||||
new KarmaEntry( -1250, "The Ignoble {0}" ),
|
||||
new KarmaEntry( -625, "The Notorious {0}" ),
|
||||
new KarmaEntry( 624, "The Prominent {0}" ),
|
||||
new KarmaEntry( 1249, "The Reputable {0}" ),
|
||||
new KarmaEntry( 2499, "The Proper {0}" ),
|
||||
new KarmaEntry( 4999, "The Admirable {0}" ),
|
||||
new KarmaEntry( 9999, "The Famed {0}" ),
|
||||
new KarmaEntry( 10000, "The Great {0}" )
|
||||
} ),
|
||||
new FameEntry( 9999, new KarmaEntry[]
|
||||
{
|
||||
new KarmaEntry( -10000, "The Dread {0}" ),
|
||||
new KarmaEntry( -5000, "The Evil {0}" ),
|
||||
new KarmaEntry( -2500, "The Villainous {0}" ),
|
||||
new KarmaEntry( -1250, "The Sinister {0}" ),
|
||||
new KarmaEntry( -625, "The Infamous {0}" ),
|
||||
new KarmaEntry( 624, "The Renowned {0}" ),
|
||||
new KarmaEntry( 1249, "The Distinguished {0}" ),
|
||||
new KarmaEntry( 2499, "The Eminent {0}" ),
|
||||
new KarmaEntry( 4999, "The Noble {0}" ),
|
||||
new KarmaEntry( 9999, "The Illustrious {0}" ),
|
||||
new KarmaEntry( 10000, "The Glorious {0}" )
|
||||
} ),
|
||||
new FameEntry( 10000, new KarmaEntry[]
|
||||
{
|
||||
new KarmaEntry( -10000, "The Dread {1} {0}" ),
|
||||
new KarmaEntry( -5000, "The Evil {1} {0}" ),
|
||||
new KarmaEntry( -2500, "The Dark {1} {0}" ),
|
||||
new KarmaEntry( -1250, "The Sinister {1} {0}" ),
|
||||
new KarmaEntry( -625, "The Dishonored {1} {0}" ),
|
||||
new KarmaEntry( 624, "{1} {0}" ),
|
||||
new KarmaEntry( 1249, "The Distinguished {1} {0}" ),
|
||||
new KarmaEntry( 2499, "The Eminent {1} {0}" ),
|
||||
new KarmaEntry( 4999, "The Noble {1} {0}" ),
|
||||
new KarmaEntry( 9999, "The Illustrious {1} {0}" ),
|
||||
new KarmaEntry( 10000, "The Glorious {1} {0}" )
|
||||
} )
|
||||
};
|
||||
}
|
||||
|
||||
public class FameEntry
|
||||
{
|
||||
public int m_Fame;
|
||||
public KarmaEntry[] m_Karma;
|
||||
|
||||
public FameEntry( int fame, KarmaEntry[] karma )
|
||||
{
|
||||
m_Fame = fame;
|
||||
m_Karma = karma;
|
||||
}
|
||||
}
|
||||
|
||||
public class KarmaEntry
|
||||
{
|
||||
public int m_Karma;
|
||||
public string m_Title;
|
||||
|
||||
public KarmaEntry( int karma, string title )
|
||||
{
|
||||
m_Karma = karma;
|
||||
m_Title = title;
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Scripts/Misc/ToggleItem.cs
Normal file
131
Scripts/Misc/ToggleItem.cs
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Commands;
|
||||
using Server.Commands.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ToggleItem : Item
|
||||
{
|
||||
public class ToggleCommand : BaseCommand
|
||||
{
|
||||
public ToggleCommand()
|
||||
{
|
||||
AccessLevel = AccessLevel.GameMaster;
|
||||
Supports = CommandSupport.AllItems;
|
||||
Commands = new string[]{ "Toggle" };
|
||||
ObjectTypes = ObjectTypes.Items;
|
||||
Usage = "Toggle";
|
||||
Description = "Toggles a targeted ToggleItem.";
|
||||
}
|
||||
|
||||
public override void Execute( CommandEventArgs e, object obj )
|
||||
{
|
||||
if ( obj is ToggleItem )
|
||||
{
|
||||
((ToggleItem)obj).Toggle();
|
||||
AddResponse( "The item has been toggled." );
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFailure( "That is not a ToggleItem." );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
TargetCommands.Register( new ToggleCommand() );
|
||||
}
|
||||
|
||||
private int m_InactiveItemID;
|
||||
private int m_ActiveItemID;
|
||||
private bool m_PlayersCanToggle;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int InactiveItemID
|
||||
{
|
||||
get { return m_InactiveItemID; }
|
||||
set { m_InactiveItemID = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ActiveItemID
|
||||
{
|
||||
get { return m_ActiveItemID; }
|
||||
set { m_ActiveItemID = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool PlayersCanToggle
|
||||
{
|
||||
get { return m_PlayersCanToggle; }
|
||||
set { m_PlayersCanToggle = value; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ToggleItem( int inactiveItemID, int activeItemID )
|
||||
: this( inactiveItemID, activeItemID, false )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ToggleItem( int inactiveItemID, int activeItemID, bool playersCanToggle )
|
||||
: base( inactiveItemID )
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_InactiveItemID = inactiveItemID;
|
||||
m_ActiveItemID = activeItemID;
|
||||
m_PlayersCanToggle = playersCanToggle;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
{
|
||||
Toggle();
|
||||
}
|
||||
else if ( m_PlayersCanToggle )
|
||||
{
|
||||
if ( from.InRange( GetWorldLocation(), 1 ) )
|
||||
Toggle();
|
||||
else
|
||||
from.SendLocalizedMessage( 500446 ); // That is too far away.
|
||||
}
|
||||
}
|
||||
|
||||
public void Toggle()
|
||||
{
|
||||
ItemID = ( ItemID == m_ActiveItemID ) ? m_InactiveItemID : m_ActiveItemID;
|
||||
Visible = ( ItemID != 0x1 );
|
||||
}
|
||||
|
||||
public ToggleItem( Serial serial )
|
||||
: base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( m_InactiveItemID );
|
||||
writer.Write( m_ActiveItemID );
|
||||
writer.Write( m_PlayersCanToggle );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
m_InactiveItemID = reader.ReadInt();
|
||||
m_ActiveItemID = reader.ReadInt();
|
||||
m_PlayersCanToggle = reader.ReadBool();
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Scripts/Misc/TreasureMapProtection.cs
Normal file
78
Scripts/Misc/TreasureMapProtection.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class TreasureRegion : BaseRegion
|
||||
{
|
||||
private const int Range = 5; // No house may be placed within 5 tiles of the treasure
|
||||
|
||||
public TreasureRegion( int x, int y, Map map ): base( null, map, Region.DefaultPriority, new Rectangle2D( x - Range, y - Range, 1 + (Range * 2), 1 + (Range * 2) ) )
|
||||
{
|
||||
GoLocation = new Point3D( x, y, map.GetAverageZ( x, y ) );
|
||||
|
||||
Register();
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
string filePath = Path.Combine( Core.BaseDirectory, "Data/treasure.cfg" );
|
||||
int i = 0, x = 0, y = 0;
|
||||
|
||||
if ( File.Exists( filePath ) )
|
||||
{
|
||||
using ( StreamReader ip = new StreamReader( filePath ) )
|
||||
{
|
||||
string line;
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
{
|
||||
i++;
|
||||
|
||||
try
|
||||
{
|
||||
string[] split = line.Split( ' ' );
|
||||
|
||||
x = Convert.ToInt32( split[0] );
|
||||
y = Convert.ToInt32( split[1] );
|
||||
|
||||
try
|
||||
{
|
||||
new TreasureRegion( x, y, Map.Felucca );
|
||||
new TreasureRegion( x, y, Map.Trammel );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
Console.WriteLine( "{0} {1} {2} {3}", i, x, y, e );
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Console.WriteLine( "Warning: Error in Line '{0}' of Data/treasure.cfg", line );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool AllowHousing( Mobile from, Point3D p )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnEnter( Mobile m )
|
||||
{
|
||||
if ( m.AccessLevel > AccessLevel.Player )
|
||||
m.SendMessage( "You have entered a protected treasure map area." );
|
||||
}
|
||||
|
||||
public override void OnExit( Mobile m )
|
||||
{
|
||||
if ( m.AccessLevel > AccessLevel.Player )
|
||||
m.SendMessage( "You have left a protected treasure map area." );
|
||||
}
|
||||
}
|
||||
}
|
||||
105
Scripts/Misc/ValidSettings.cs
Normal file
105
Scripts/Misc/ValidSettings.cs
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
class ValidSettings
|
||||
{
|
||||
// This file enforces some cap limites for some settings in Settings.cs
|
||||
public static double ServerSaveMinutes()
|
||||
{
|
||||
if (Settings.S_ServerSaveMinutes > 240)
|
||||
{
|
||||
Settings.S_ServerSaveMinutes = 240.0;
|
||||
}
|
||||
else if ( Settings.S_ServerSaveMinutes < 5 )
|
||||
{
|
||||
Settings.S_ServerSaveMinutes = 5.0;
|
||||
}
|
||||
return Settings.S_ServerSaveMinutes;
|
||||
}
|
||||
|
||||
public static double DeleteDaysDelay()
|
||||
{
|
||||
if (Settings.S_DeleteDaysDelay > 14)
|
||||
{
|
||||
Settings.S_DeleteDaysDelay = 14;
|
||||
}
|
||||
else if ( Settings.S_DeleteDaysDelay < 1 )
|
||||
{
|
||||
Settings.S_DeleteDaysDelay = 1;
|
||||
}
|
||||
return Settings.S_DeleteDaysDelay;
|
||||
}
|
||||
|
||||
public static double CorpseDecay()
|
||||
{
|
||||
if ( Settings.S_CorpseDecay < 1 )
|
||||
{
|
||||
Settings.S_CorpseDecay = 0;
|
||||
}
|
||||
return (double)Settings.S_CorpseDecay;
|
||||
}
|
||||
|
||||
public static double BoneDecay()
|
||||
{
|
||||
if ( Settings.S_BoneDecay < 1 )
|
||||
{
|
||||
Settings.S_BoneDecay = 0;
|
||||
}
|
||||
return (double)Settings.S_BoneDecay;
|
||||
}
|
||||
|
||||
public static double StatGain()
|
||||
{
|
||||
if ( Settings.S_StatGain > 50 )
|
||||
{
|
||||
Settings.S_StatGain = 50.0;
|
||||
}
|
||||
else if ( Settings.S_StatGain < 10 )
|
||||
{
|
||||
Settings.S_StatGain = 10.0;
|
||||
}
|
||||
return Settings.S_StatGain;
|
||||
}
|
||||
|
||||
public static TimeSpan StatGainDelay()
|
||||
{
|
||||
if ( Settings.S_StatGainDelay > 60 )
|
||||
{
|
||||
Settings.S_StatGainDelay = 60.0;
|
||||
}
|
||||
else if ( Settings.S_StatGainDelay < 5 )
|
||||
{
|
||||
Settings.S_StatGainDelay = 5.0;
|
||||
}
|
||||
return TimeSpan.FromMinutes( Settings.S_StatGainDelay );
|
||||
}
|
||||
|
||||
public static double SkillGain()
|
||||
{
|
||||
int skill = 0;
|
||||
if ( Settings.S_SkillGain > 10 )
|
||||
skill = 10;
|
||||
if ( Settings.S_SkillGain < 1 )
|
||||
skill = 0;
|
||||
return skill * 0.1;
|
||||
}
|
||||
|
||||
public static int StartingGold()
|
||||
{
|
||||
int min = Settings.S_MinGold;
|
||||
int max = Settings.S_MaxGold;
|
||||
if ( min > max )
|
||||
min = max;
|
||||
int gold = Utility.RandomMinMax(min, max);
|
||||
if ( gold < 0 )
|
||||
gold = 0;
|
||||
if ( gold > 10000 )
|
||||
gold = 10000;
|
||||
return gold;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
57
Scripts/Misc/ValidationQueue.cs
Normal file
57
Scripts/Misc/ValidationQueue.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Server;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public delegate void ValidationEventHandler();
|
||||
|
||||
public static class ValidationQueue
|
||||
{
|
||||
public static event ValidationEventHandler StartValidation;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if ( StartValidation != null )
|
||||
StartValidation();
|
||||
|
||||
StartValidation = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class ValidationQueue<T>
|
||||
{
|
||||
private static List<T> m_Queue;
|
||||
|
||||
static ValidationQueue()
|
||||
{
|
||||
m_Queue = new List<T>();
|
||||
ValidationQueue.StartValidation += new ValidationEventHandler( ValidateAll );
|
||||
}
|
||||
|
||||
public static void Add( T obj )
|
||||
{
|
||||
m_Queue.Add( obj );
|
||||
}
|
||||
|
||||
private static void ValidateAll()
|
||||
{
|
||||
Type type = typeof( T );
|
||||
|
||||
if ( type != null )
|
||||
{
|
||||
MethodInfo m = type.GetMethod( "Validate", BindingFlags.Instance | BindingFlags.Public );
|
||||
|
||||
if ( m != null )
|
||||
{
|
||||
for ( int i = 0; i < m_Queue.Count; ++i )
|
||||
m.Invoke( m_Queue[i], null );
|
||||
}
|
||||
}
|
||||
|
||||
m_Queue.Clear();
|
||||
m_Queue = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
532
Scripts/Misc/VendorGenerator.cs
Normal file
532
Scripts/Misc/VendorGenerator.cs
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Commands;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class VendorGenerator
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "VendorGen", AccessLevel.Administrator, new CommandEventHandler( VendorGenerator.VendorGen_OnCommand ) );
|
||||
}
|
||||
|
||||
private static Rectangle2D[] m_BritRegions = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D( new Point2D( 250, 750 ), new Point2D( 775, 1330 ) ),
|
||||
new Rectangle2D( new Point2D( 525, 2095 ), new Point2D( 925, 2430 ) ),
|
||||
new Rectangle2D( new Point2D( 1025, 2155 ), new Point2D( 1265, 2310 ) ),
|
||||
new Rectangle2D( new Point2D( 1635, 2430 ), new Point2D( 1705, 2508 ) ),
|
||||
new Rectangle2D( new Point2D( 1775, 2605 ), new Point2D( 2165, 2975 ) ),
|
||||
new Rectangle2D( new Point2D( 1055, 3520 ), new Point2D( 1570, 4075 ) ),
|
||||
new Rectangle2D( new Point2D( 2860, 3310 ), new Point2D( 3120, 3630 ) ),
|
||||
new Rectangle2D( new Point2D( 2470, 1855 ), new Point2D( 3950, 3045 ) ),
|
||||
new Rectangle2D( new Point2D( 3425, 990 ), new Point2D( 3900, 1455 ) ),
|
||||
new Rectangle2D( new Point2D( 4175, 735 ), new Point2D( 4840, 1600 ) ),
|
||||
new Rectangle2D( new Point2D( 2375, 330 ), new Point2D( 3100, 1045 ) ),
|
||||
new Rectangle2D( new Point2D( 2100, 1090 ), new Point2D( 2310, 1450 ) ),
|
||||
new Rectangle2D( new Point2D( 1495, 1400 ), new Point2D( 1550, 1475 ) ),
|
||||
new Rectangle2D( new Point2D( 1085, 1520 ), new Point2D( 1415, 1910 ) ),
|
||||
new Rectangle2D( new Point2D( 1410, 1500 ), new Point2D( 1745, 1795 ) ),
|
||||
new Rectangle2D( new Point2D( 5120, 2300 ), new Point2D( 6143, 4095 ) )
|
||||
};
|
||||
|
||||
private static Rectangle2D[] m_IlshRegions = new Rectangle2D[]
|
||||
{
|
||||
new Rectangle2D( new Point2D( 0, 0 ), new Point2D( 288*8, 200*8 ) )
|
||||
};
|
||||
|
||||
[Usage( "VendorGen" )]
|
||||
[Description( "Generates vendors based on display cases and floor plans. Analyzes the map files, slow." )]
|
||||
private static void VendorGen_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
Process( Map.Trammel, m_BritRegions );
|
||||
Process( Map.Felucca, m_BritRegions );
|
||||
Process( Map.Ilshenar, m_IlshRegions );
|
||||
}
|
||||
|
||||
private static bool GetFloorZ( Map map, int x, int y, out int z )
|
||||
{
|
||||
LandTile lt = map.Tiles.GetLandTile( x, y );
|
||||
|
||||
if ( IsFloor( lt.ID ) && map.CanFit( x, y, lt.Z, 16, false, false ) )
|
||||
{
|
||||
z = lt.Z;
|
||||
return true;
|
||||
}
|
||||
|
||||
StaticTile[] tiles = map.Tiles.GetStaticTiles( x, y );
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
{
|
||||
StaticTile t = tiles[i];
|
||||
ItemData id = TileData.ItemTable[t.ID & TileData.MaxItemValue];
|
||||
|
||||
if ( IsStaticFloor( t.ID ) && map.CanFit( x, y, t.Z + (id.Surface ? id.CalcHeight : 0), 16, false, false ) )
|
||||
{
|
||||
z = t.Z + (id.Surface ? id.CalcHeight : 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
z = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsFloor( Map map, int x, int y, bool canFit )
|
||||
{
|
||||
LandTile lt = map.Tiles.GetLandTile( x, y );
|
||||
|
||||
if ( IsFloor( lt.ID ) && (canFit||CanFit( map, x, y, lt.Z )) )
|
||||
return true;
|
||||
|
||||
StaticTile[] tiles = map.Tiles.GetStaticTiles( x, y );
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
{
|
||||
StaticTile t = tiles[i];
|
||||
ItemData id = TileData.ItemTable[t.ID & TileData.MaxItemValue];
|
||||
|
||||
if ( IsStaticFloor( t.ID ) && (canFit||CanFit( map, x, y, t.Z + (id.Surface ? id.CalcHeight : 0) )) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsFloor( int itemID )
|
||||
{
|
||||
itemID &= TileData.MaxLandValue;
|
||||
|
||||
return ( itemID >= 0x406 && itemID <= 0x51A );
|
||||
}
|
||||
|
||||
private static bool IsStaticFloor( int itemID )
|
||||
{
|
||||
return ( itemID >= 0x495 && itemID <= 0x514 )
|
||||
|| ( itemID >= 0x519 && itemID <= 0x53A );
|
||||
}
|
||||
|
||||
private static bool IsDisplayCase( int itemID )
|
||||
{
|
||||
return ( itemID >= 0xB00 && itemID <= 0xB02 )
|
||||
|| ( itemID >= 0xB06 && itemID <= 0xB0A )
|
||||
|| ( itemID >= 0xB0D && itemID <= 0xB17 );
|
||||
}
|
||||
|
||||
private static void Process( Map map, Rectangle2D[] regions )
|
||||
{
|
||||
m_ShopTable = new Hashtable();
|
||||
m_ShopList = new ArrayList();
|
||||
|
||||
World.Broadcast( 0x35, true, "Generating vendor spawns for {0}, please wait.", map );
|
||||
|
||||
for ( int i = 0; i < regions.Length; ++i )
|
||||
for ( int x = 0; x < map.Width; ++x )
|
||||
for ( int y = 0; y < map.Height; ++y )
|
||||
CheckPoint( map, regions[i].X + x, regions[i].Y + y );
|
||||
|
||||
for ( int i = 0; i < m_ShopList.Count; ++i )
|
||||
{
|
||||
ShopInfo si = (ShopInfo)m_ShopList[i];
|
||||
|
||||
int xTotal = 0;
|
||||
int yTotal = 0;
|
||||
|
||||
bool hasSpawner = false;
|
||||
|
||||
for ( int j = 0; !hasSpawner && j < si.m_Floor.Count; ++j )
|
||||
{
|
||||
Point2D fp = (Point2D)si.m_Floor[j];
|
||||
|
||||
xTotal += fp.X;
|
||||
yTotal += fp.Y;
|
||||
|
||||
IPooledEnumerable eable = map.GetItemsInRange( new Point3D( fp.X, fp.Y, 0 ), 0 );
|
||||
|
||||
foreach ( Item item in eable )
|
||||
{
|
||||
if ( item is Spawner )
|
||||
{
|
||||
hasSpawner = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if ( hasSpawner )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( hasSpawner )
|
||||
continue;
|
||||
|
||||
int xAvg = xTotal / si.m_Floor.Count;
|
||||
int yAvg = yTotal / si.m_Floor.Count;
|
||||
|
||||
ArrayList names = new ArrayList();
|
||||
ShopFlags flags = si.m_Flags;
|
||||
|
||||
if ( (flags & ShopFlags.Armor) != 0 )
|
||||
names.Add( "armorer" );
|
||||
|
||||
if ( (flags & ShopFlags.MetalWeapon) != 0 )
|
||||
names.Add( "weaponsmith" );
|
||||
|
||||
if ( (flags & ShopFlags.ArcheryWeapon) != 0 )
|
||||
names.Add( "bowyer" );
|
||||
|
||||
if ( (flags & ShopFlags.Scroll) != 0 )
|
||||
names.Add( "mage" );
|
||||
|
||||
if ( (flags & ShopFlags.Spellbook) != 0 )
|
||||
names.Add( "mage" );
|
||||
|
||||
if ( (flags & ShopFlags.Bread) != 0 )
|
||||
names.Add( "baker" );
|
||||
|
||||
if ( (flags & ShopFlags.Jewel) != 0 )
|
||||
names.Add( "jeweler" );
|
||||
|
||||
if ( (flags & ShopFlags.Potion) != 0 )
|
||||
{
|
||||
names.Add( "herbalist" );
|
||||
names.Add( "alchemist" );
|
||||
names.Add( "mage" );
|
||||
}
|
||||
|
||||
if ( (flags & ShopFlags.Reagent) != 0 )
|
||||
{
|
||||
names.Add( "mage" );
|
||||
names.Add( "herbalist" );
|
||||
}
|
||||
|
||||
if ( (flags & ShopFlags.Clothes) != 0 )
|
||||
{
|
||||
names.Add( "tailor" );
|
||||
names.Add( "weaver" );
|
||||
}
|
||||
|
||||
for ( int j = 0; j < names.Count; ++j )
|
||||
{
|
||||
Point2D cp = Point2D.Zero;
|
||||
int dist = 100000;
|
||||
int tz;
|
||||
|
||||
for ( int k = 0; k < si.m_Floor.Count; ++k )
|
||||
{
|
||||
Point2D fp = (Point2D)si.m_Floor[k];
|
||||
|
||||
int rx = fp.X - xAvg;
|
||||
int ry = fp.Y - yAvg;
|
||||
int fd = (int)Math.Sqrt( rx*rx + ry*ry );
|
||||
|
||||
if ( fd > 0 && fd < 5 )
|
||||
fd -= Utility.Random( 10 );
|
||||
|
||||
if ( fd < dist && GetFloorZ( map, fp.X, fp.Y, out tz ) )
|
||||
{
|
||||
dist = fd;
|
||||
cp = fp;
|
||||
}
|
||||
}
|
||||
|
||||
if ( cp == Point2D.Zero )
|
||||
continue;
|
||||
|
||||
int z;
|
||||
|
||||
if ( !GetFloorZ( map, cp.X, cp.Y, out z ) )
|
||||
continue;
|
||||
|
||||
new Spawner( 1, 1, 1, 0, 4, (string)names[j] ).MoveToWorld( new Point3D( cp.X, cp.Y, z ), map );
|
||||
}
|
||||
}
|
||||
|
||||
World.Broadcast( 0x35, true, "Generation complete. {0} spawners generated.", m_ShopList.Count );
|
||||
}
|
||||
|
||||
private static void CheckPoint( Map map, int x, int y )
|
||||
{
|
||||
if ( IsFloor( map, x, y, true ) )
|
||||
CheckFloor( map, x, y );
|
||||
}
|
||||
|
||||
private static void CheckFloor( Map map, int x, int y )
|
||||
{
|
||||
StaticTile[] tiles = map.Tiles.GetStaticTiles( x, y );
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
{
|
||||
if ( IsDisplayCase( tiles[i].ID ) )
|
||||
{
|
||||
ProcessDisplayCase( map, tiles, x, y );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Flags]
|
||||
private enum ShopFlags
|
||||
{
|
||||
None = 0x000,
|
||||
Armor = 0x001,
|
||||
MetalWeapon = 0x002,
|
||||
Jewel = 0x004,
|
||||
Reagent = 0x008,
|
||||
Potion = 0x010,
|
||||
Bread = 0x020,
|
||||
Clothes = 0x040,
|
||||
ArcheryWeapon = 0x080,
|
||||
Scroll = 0x100,
|
||||
Spellbook = 0x200
|
||||
}
|
||||
|
||||
private static bool IsClothes( int itemID )
|
||||
{
|
||||
if ( itemID >= 0x1515 && itemID <= 0x1518 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x152E && itemID <= 0x1531 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x1537 && itemID <= 0x154C )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x1EFD && itemID <= 0x1F04 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x170B && itemID <= 0x171C )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsArmor( int itemID )
|
||||
{
|
||||
if ( itemID >= 0x13BB && itemID <= 0x13E2 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13E5 && itemID <= 0x13F2 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x1408 && itemID <= 0x141A )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x144E && itemID <= 0x1457 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsMetalWeapon( int itemID )
|
||||
{
|
||||
if ( itemID >= 0xF43 && itemID <= 0xF4E )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0xF51 && itemID <= 0xF52 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0xF5C && itemID <= 0xF63 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13AF && itemID <= 0x13B0 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13B5 && itemID <= 0x13BA )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13FA && itemID <= 0x13FB )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13FE && itemID <= 0x1407 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x1438 && itemID <= 0x1443 )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool IsArcheryWeapon( int itemID )
|
||||
{
|
||||
if ( itemID >= 0xF4F && itemID <= 0xF50 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13B1 && itemID <= 0x13B2 )
|
||||
return true;
|
||||
|
||||
if ( itemID >= 0x13FC && itemID <= 0x13FD )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static ShopFlags ProcessDisplayedItem( int itemID )
|
||||
{
|
||||
itemID &= TileData.MaxItemValue;
|
||||
|
||||
ShopFlags res = ShopFlags.None;
|
||||
|
||||
ItemData id = TileData.ItemTable[itemID];
|
||||
TileFlag flags = id.Flags;
|
||||
|
||||
if ( (flags & TileFlag.Wearable) != 0 )
|
||||
{
|
||||
if ( IsClothes( itemID ) )
|
||||
res |= ShopFlags.Clothes;
|
||||
else if ( IsArmor( itemID ) )
|
||||
res |= ShopFlags.Armor;
|
||||
else if ( IsMetalWeapon( itemID ) )
|
||||
res |= ShopFlags.MetalWeapon;
|
||||
else if ( IsArcheryWeapon( itemID ) )
|
||||
res |= ShopFlags.ArcheryWeapon;
|
||||
}
|
||||
|
||||
if ( itemID == 0x98C || itemID == 0x103B || itemID == 0x103C )
|
||||
res |= ShopFlags.Bread;
|
||||
|
||||
if ( itemID >= 0xF0F && itemID <= 0xF30 )
|
||||
res |= ShopFlags.Jewel;
|
||||
|
||||
if ( itemID >= 0xEFB && itemID <= 0xF0D )
|
||||
res |= ShopFlags.Potion;
|
||||
|
||||
if ( itemID >= 0xF78 && itemID <= 0xF91 )
|
||||
res |= ShopFlags.Reagent;
|
||||
|
||||
if ( (itemID >= 0xE35 && itemID <= 0xE3A) || (itemID >= 0xEF4 && itemID <= 0xEF9) || (itemID >= 0x1F2D && itemID <= 0x1F72) )
|
||||
res |= ShopFlags.Scroll;
|
||||
|
||||
if ( itemID == 0xE38 || itemID == 0xEFA )
|
||||
res |= ShopFlags.Spellbook;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private static void ProcessDisplayCase( Map map, StaticTile[] tiles, int x, int y )
|
||||
{
|
||||
ShopFlags flags = ShopFlags.None;
|
||||
|
||||
for ( int i = 0; i < tiles.Length; ++i )
|
||||
flags |= ProcessDisplayedItem( tiles[i].ID );
|
||||
|
||||
if ( flags != ShopFlags.None )
|
||||
{
|
||||
Point2D p = new Point2D( x, y );
|
||||
ShopInfo si = (ShopInfo)m_ShopTable[p];
|
||||
|
||||
if ( si == null )
|
||||
{
|
||||
ArrayList floor = new ArrayList();
|
||||
|
||||
RecurseFindFloor( map, x, y, floor );
|
||||
|
||||
if ( floor.Count == 0 )
|
||||
return;
|
||||
|
||||
si = new ShopInfo();
|
||||
si.m_Flags = flags;
|
||||
si.m_Floor = floor;
|
||||
m_ShopList.Add( si );
|
||||
|
||||
for ( int i = 0; i < floor.Count; ++i )
|
||||
m_ShopTable[(Point2D)floor[i]] = si;
|
||||
}
|
||||
else
|
||||
{
|
||||
si.m_Flags |= flags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Hashtable m_ShopTable;
|
||||
private static ArrayList m_ShopList;
|
||||
|
||||
private class ShopInfo
|
||||
{
|
||||
public ShopFlags m_Flags;
|
||||
public ArrayList m_Floor;
|
||||
}
|
||||
|
||||
private static bool CanFit( Map map, int x, int y, int z )
|
||||
{
|
||||
bool hasSurface = false;
|
||||
|
||||
LandTile lt = map.Tiles.GetLandTile( x, y );
|
||||
int lowZ = 0, avgZ = 0, topZ = 0;
|
||||
|
||||
map.GetAverageZ( x, y, ref lowZ, ref avgZ, ref topZ );
|
||||
TileFlag landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;
|
||||
|
||||
if ( (landFlags & TileFlag.Impassable) != 0 && topZ > z && (z + 16) > lowZ )
|
||||
return false;
|
||||
else if ( (landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored )
|
||||
hasSurface = true;
|
||||
|
||||
StaticTile[] staticTiles = map.Tiles.GetStaticTiles( x, y );
|
||||
|
||||
bool surface, impassable;
|
||||
|
||||
for ( int i = 0; i < staticTiles.Length; ++i )
|
||||
{
|
||||
if ( IsDisplayCase( staticTiles[i].ID ) )
|
||||
continue;
|
||||
|
||||
ItemData id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue];
|
||||
|
||||
surface = id.Surface;
|
||||
impassable = id.Impassable;
|
||||
|
||||
if ( (surface || impassable) && (staticTiles[i].Z + id.CalcHeight) > z && (z + 16) > staticTiles[i].Z )
|
||||
return false;
|
||||
else if ( surface && !impassable && z == (staticTiles[i].Z + id.CalcHeight) )
|
||||
hasSurface = true;
|
||||
}
|
||||
|
||||
Sector sector = map.GetSector( x, y );
|
||||
List<Item> items = sector.Items;
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
{
|
||||
Item item = items[i];
|
||||
|
||||
if ( item.AtWorldPoint( x, y ) )
|
||||
{
|
||||
ItemData id = item.ItemData;
|
||||
surface = id.Surface;
|
||||
impassable = id.Impassable;
|
||||
|
||||
if ( (surface || impassable) && (item.Z + id.CalcHeight) > z && (z + 16) > item.Z )
|
||||
return false;
|
||||
else if ( surface && !impassable && z == (item.Z + id.CalcHeight) )
|
||||
hasSurface = true;
|
||||
}
|
||||
}
|
||||
|
||||
return hasSurface;
|
||||
}
|
||||
|
||||
private static void RecurseFindFloor( Map map, int x, int y, ArrayList floor )
|
||||
{
|
||||
Point2D p = new Point2D( x, y );
|
||||
|
||||
if ( floor.Contains( p ) )
|
||||
return;
|
||||
|
||||
floor.Add( p );
|
||||
|
||||
for ( int xo = -1; xo <= 1; ++xo )
|
||||
{
|
||||
for ( int yo = -1; yo <= 1; ++yo )
|
||||
{
|
||||
if ( (xo != 0 || yo != 0) && IsFloor( map, x + xo, y + yo, false ) )
|
||||
RecurseFindFloor( map, x + xo, y + yo, floor );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
394
Scripts/Misc/Weather.cs
Normal file
394
Scripts/Misc/Weather.cs
Normal file
|
|
@ -0,0 +1,394 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class Weather
|
||||
{
|
||||
private static Map[] m_Facets;
|
||||
private static Dictionary<Map, List<Weather>> m_WeatherByFacet = new Dictionary<Map, List<Weather>>();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
m_Facets = new Map[]{ Map.Felucca, Map.Trammel };
|
||||
|
||||
/* Static weather:
|
||||
*
|
||||
* Format:
|
||||
* AddWeather( temperature, chanceOfPercipitation, chanceOfExtremeTemperature, <area ...> );
|
||||
*/
|
||||
|
||||
// ice island
|
||||
AddWeather( -15, 100, 5, new Rectangle2D( 3850, 160, 390, 320 ), new Rectangle2D( 3900, 480, 380, 180 ), new Rectangle2D( 4160, 660, 150, 110 ) );
|
||||
|
||||
// covetous entrance, around vesper and minoc
|
||||
AddWeather( +15, 50, 5, new Rectangle2D( 2425, 725, 250, 250 ) );
|
||||
|
||||
// despise entrance, north of britain
|
||||
AddWeather( +15, 50, 5, new Rectangle2D( 1245, 1045, 250, 250 ) );
|
||||
|
||||
|
||||
/* Dynamic weather:
|
||||
*
|
||||
* Format:
|
||||
* AddDynamicWeather( temperature, chanceOfPercipitation, chanceOfExtremeTemperature, moveSpeed, width, height, bounds );
|
||||
*/
|
||||
|
||||
for ( int i = 0; i < 15; ++i )
|
||||
AddDynamicWeather( +15, 100, 5, 8, 400, 400, new Rectangle2D( 0, 0, 5120, 4096 ) );
|
||||
}
|
||||
|
||||
public static List<Weather> GetWeatherList( Map facet )
|
||||
{
|
||||
if ( facet == null )
|
||||
return null;
|
||||
|
||||
List<Weather> list = null;
|
||||
m_WeatherByFacet.TryGetValue( facet, out list );
|
||||
|
||||
if ( list == null )
|
||||
m_WeatherByFacet[facet] = list = new List<Weather>();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void AddDynamicWeather( int temperature, int chanceOfPercipitation, int chanceOfExtremeTemperature, int moveSpeed, int width, int height, Rectangle2D bounds )
|
||||
{
|
||||
for ( int i = 0; i < m_Facets.Length; ++i )
|
||||
{
|
||||
Rectangle2D area = new Rectangle2D();
|
||||
bool isValid = false;
|
||||
|
||||
for ( int j = 0; j < 10; ++j )
|
||||
{
|
||||
area = new Rectangle2D( bounds.X + Utility.Random( bounds.Width - width ), bounds.Y + Utility.Random( bounds.Height - height ), width, height );
|
||||
|
||||
if ( !CheckWeatherConflict( m_Facets[i], null, area ) )
|
||||
isValid = true;
|
||||
|
||||
if ( isValid )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isValid )
|
||||
continue;
|
||||
|
||||
Weather w = new Weather( m_Facets[i], new Rectangle2D[]{ area }, temperature, chanceOfPercipitation, chanceOfExtremeTemperature, TimeSpan.FromSeconds( 30.0 ) );
|
||||
|
||||
w.m_Bounds = bounds;
|
||||
w.m_MoveSpeed = moveSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddWeather( int temperature, int chanceOfPercipitation, int chanceOfExtremeTemperature, params Rectangle2D[] area )
|
||||
{
|
||||
for ( int i = 0; i < m_Facets.Length; ++i )
|
||||
new Weather( m_Facets[i], area, temperature, chanceOfPercipitation, chanceOfExtremeTemperature, TimeSpan.FromSeconds( 30.0 ) );
|
||||
}
|
||||
|
||||
public static bool CheckWeatherConflict( Map facet, Weather exclude, Rectangle2D area )
|
||||
{
|
||||
List<Weather> list = GetWeatherList( facet );
|
||||
|
||||
if ( list == null )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
Weather w = list[i];
|
||||
|
||||
if ( w != exclude && w.IntersectsWith( area ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Map m_Facet;
|
||||
private Rectangle2D[] m_Area;
|
||||
private int m_Temperature;
|
||||
private int m_ChanceOfPercipitation;
|
||||
private int m_ChanceOfExtremeTemperature;
|
||||
|
||||
public Map Facet{ get{ return m_Facet; } }
|
||||
public Rectangle2D[] Area{ get{ return m_Area; } set{ m_Area = value; } }
|
||||
public int Temperature{ get{ return m_Temperature; } set{ m_Temperature = value; } }
|
||||
public int ChanceOfPercipitation{ get{ return m_ChanceOfPercipitation; } set{ m_ChanceOfPercipitation = value; } }
|
||||
public int ChanceOfExtremeTemperature{ get{ return m_ChanceOfExtremeTemperature; } set{ m_ChanceOfExtremeTemperature = value; } }
|
||||
|
||||
// For dynamic weather:
|
||||
private Rectangle2D m_Bounds;
|
||||
private int m_MoveSpeed;
|
||||
private int m_MoveAngleX, m_MoveAngleY;
|
||||
|
||||
public Rectangle2D Bounds{ get{ return m_Bounds; } set{ m_Bounds = value; } }
|
||||
public int MoveSpeed{ get{ return m_MoveSpeed; } set{ m_MoveSpeed = value; } }
|
||||
public int MoveAngleX{ get{ return m_MoveAngleX; } set{ m_MoveAngleX = value; } }
|
||||
public int MoveAngleY{ get{ return m_MoveAngleY; } set{ m_MoveAngleY = value; } }
|
||||
|
||||
public static bool CheckIntersection( Rectangle2D r1, Rectangle2D r2 )
|
||||
{
|
||||
if ( r1.X >= (r2.X + r2.Width) )
|
||||
return false;
|
||||
|
||||
if ( r2.X >= (r1.X + r1.Width) )
|
||||
return false;
|
||||
|
||||
if ( r1.Y >= (r2.Y + r2.Height) )
|
||||
return false;
|
||||
|
||||
if ( r2.Y >= (r1.Y + r1.Height) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool CheckContains( Rectangle2D big, Rectangle2D small )
|
||||
{
|
||||
if ( small.X < big.X )
|
||||
return false;
|
||||
|
||||
if ( small.Y < big.Y )
|
||||
return false;
|
||||
|
||||
if ( (small.X + small.Width) > (big.X + big.Width) )
|
||||
return false;
|
||||
|
||||
if ( (small.Y + small.Height) > (big.Y + big.Height) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual bool IntersectsWith( Rectangle2D area )
|
||||
{
|
||||
for ( int i = 0; i < m_Area.Length; ++i )
|
||||
{
|
||||
if ( CheckIntersection( area, m_Area[i] ) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public Weather( Map facet, Rectangle2D[] area, int temperature, int chanceOfPercipitation, int chanceOfExtremeTemperature, TimeSpan interval )
|
||||
{
|
||||
m_Facet = facet;
|
||||
m_Area = area;
|
||||
m_Temperature = temperature;
|
||||
m_ChanceOfPercipitation = chanceOfPercipitation;
|
||||
m_ChanceOfExtremeTemperature = chanceOfExtremeTemperature;
|
||||
|
||||
List<Weather> list = GetWeatherList( facet );
|
||||
|
||||
if ( list != null )
|
||||
list.Add( this );
|
||||
|
||||
Timer.DelayCall( TimeSpan.FromSeconds( (0.2+(Utility.RandomDouble()*0.8)) * interval.TotalSeconds ), interval, new TimerCallback( OnTick ) );
|
||||
}
|
||||
|
||||
public virtual void Reposition()
|
||||
{
|
||||
if ( m_Area.Length == 0 )
|
||||
return;
|
||||
|
||||
int width = m_Area[0].Width;
|
||||
int height = m_Area[0].Height;
|
||||
|
||||
Rectangle2D area = new Rectangle2D();
|
||||
bool isValid = false;
|
||||
|
||||
for ( int j = 0; j < 10; ++j )
|
||||
{
|
||||
area = new Rectangle2D( m_Bounds.X + Utility.Random( m_Bounds.Width - width ), m_Bounds.Y + Utility.Random( m_Bounds.Height - height ), width, height );
|
||||
|
||||
if ( !CheckWeatherConflict( m_Facet, this, area ) )
|
||||
isValid = true;
|
||||
|
||||
if ( isValid )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !isValid )
|
||||
return;
|
||||
|
||||
m_Area[0] = area;
|
||||
}
|
||||
|
||||
public virtual void RecalculateMovementAngle()
|
||||
{
|
||||
double angle = Utility.RandomDouble() * Math.PI * 2.0;
|
||||
|
||||
double cos = Math.Cos( angle );
|
||||
double sin = Math.Sin( angle );
|
||||
|
||||
m_MoveAngleX = (int)(100 * cos);
|
||||
m_MoveAngleY = (int)(100 * sin);
|
||||
}
|
||||
|
||||
public virtual void MoveForward()
|
||||
{
|
||||
if ( m_Area.Length == 0 )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < 5; ++i ) // try 5 times to find a valid spot
|
||||
{
|
||||
int xOffset = (m_MoveSpeed * m_MoveAngleX) / 100;
|
||||
int yOffset = (m_MoveSpeed * m_MoveAngleY) / 100;
|
||||
|
||||
Rectangle2D oldArea = m_Area[0];
|
||||
Rectangle2D newArea = new Rectangle2D( oldArea.X + xOffset, oldArea.Y + yOffset, oldArea.Width, oldArea.Height );
|
||||
|
||||
if ( !CheckWeatherConflict( m_Facet, this, newArea ) && CheckContains( m_Bounds, newArea ) )
|
||||
{
|
||||
m_Area[0] = newArea;
|
||||
break;
|
||||
}
|
||||
|
||||
RecalculateMovementAngle();
|
||||
}
|
||||
}
|
||||
|
||||
private int m_Stage;
|
||||
private bool m_Active;
|
||||
private bool m_ExtremeTemperature;
|
||||
|
||||
public virtual void OnTick()
|
||||
{
|
||||
if ( m_Stage == 0 )
|
||||
{
|
||||
m_Active = ( m_ChanceOfPercipitation > Utility.Random( 100 ) );
|
||||
m_ExtremeTemperature = ( m_ChanceOfExtremeTemperature > Utility.Random( 100 ) );
|
||||
|
||||
if ( m_MoveSpeed > 0 )
|
||||
{
|
||||
Reposition();
|
||||
RecalculateMovementAngle();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_Active )
|
||||
{
|
||||
if ( m_Stage > 0 && m_MoveSpeed > 0 )
|
||||
MoveForward();
|
||||
|
||||
int type, density, temperature;
|
||||
|
||||
temperature = m_Temperature;
|
||||
|
||||
if ( m_ExtremeTemperature )
|
||||
temperature *= -1;
|
||||
|
||||
if ( m_Stage < 15 )
|
||||
{
|
||||
density = m_Stage * 5;
|
||||
}
|
||||
else
|
||||
{
|
||||
density = 150 - (m_Stage * 5);
|
||||
|
||||
if ( density < 10 )
|
||||
density = 10;
|
||||
else if ( density > 70 )
|
||||
density = 70;
|
||||
}
|
||||
|
||||
if ( density == 0 )
|
||||
type = 0xFE;
|
||||
else if ( temperature > 0 )
|
||||
type = 0;
|
||||
else
|
||||
type = 2;
|
||||
|
||||
List<NetState> states = NetState.Instances;
|
||||
|
||||
Packet weatherPacket = null;
|
||||
|
||||
for ( int i = 0; i < states.Count; ++i )
|
||||
{
|
||||
NetState ns = states[i];
|
||||
Mobile mob = ns.Mobile;
|
||||
|
||||
if ( mob == null || mob.Map != m_Facet )
|
||||
continue;
|
||||
|
||||
bool contains = ( m_Area.Length == 0 );
|
||||
|
||||
for ( int j = 0; !contains && j < m_Area.Length; ++j )
|
||||
contains = m_Area[j].Contains( mob.Location );
|
||||
|
||||
if ( !contains )
|
||||
continue;
|
||||
|
||||
if ( weatherPacket == null )
|
||||
weatherPacket = Packet.Acquire( new Server.Network.Weather( type, density, temperature ) );
|
||||
|
||||
ns.Send( weatherPacket );
|
||||
}
|
||||
|
||||
Packet.Release( weatherPacket );
|
||||
}
|
||||
|
||||
m_Stage++;
|
||||
m_Stage %= 30;
|
||||
}
|
||||
}
|
||||
|
||||
public class WeatherMap : MapItem
|
||||
{
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "weather map"; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public WeatherMap()
|
||||
{
|
||||
SetDisplay( 0, 0, 5119, 4095, 400, 400 );
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
Map facet = from.Map;
|
||||
|
||||
if ( facet == null )
|
||||
return;
|
||||
|
||||
List<Weather> list = Weather.GetWeatherList( facet );
|
||||
|
||||
ClearPins();
|
||||
|
||||
for ( int i = 0; i < list.Count; ++i )
|
||||
{
|
||||
Weather w = list[i];
|
||||
|
||||
for ( int j = 0; j < w.Area.Length; ++j )
|
||||
AddWorldPin( w.Area[j].X + (w.Area[j].Width/2), w.Area[j].Y + (w.Area[j].Height/2) );
|
||||
}
|
||||
|
||||
base.OnDoubleClick( from );
|
||||
}
|
||||
|
||||
public WeatherMap( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
194
Scripts/Misc/WebStatus.cs
Normal file
194
Scripts/Misc/WebStatus.cs
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
#region References
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
using Server.Guilds;
|
||||
using Server.Network;
|
||||
#endregion
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public class StatusPage : Timer
|
||||
{
|
||||
public static readonly bool Enabled = false;
|
||||
|
||||
private static HttpListener _Listener;
|
||||
|
||||
private static string _StatusPage = String.Empty;
|
||||
private static byte[] _StatusBuffer = new byte[0];
|
||||
|
||||
private static readonly object _StatusLock = new object();
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
if (!Enabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
new StatusPage().Start();
|
||||
|
||||
Listen();
|
||||
}
|
||||
|
||||
private static void Listen()
|
||||
{
|
||||
if (!HttpListener.IsSupported)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_Listener == null)
|
||||
{
|
||||
_Listener = new HttpListener();
|
||||
_Listener.Prefixes.Add("http://*:80/status/");
|
||||
_Listener.Start();
|
||||
}
|
||||
else if (!_Listener.IsListening)
|
||||
{
|
||||
_Listener.Start();
|
||||
}
|
||||
|
||||
if (_Listener.IsListening)
|
||||
{
|
||||
_Listener.BeginGetContext(ListenerCallback, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ListenerCallback(IAsyncResult result)
|
||||
{
|
||||
try
|
||||
{
|
||||
var context = _Listener.EndGetContext(result);
|
||||
|
||||
byte[] buffer;
|
||||
|
||||
lock (_StatusLock)
|
||||
{
|
||||
buffer = _StatusBuffer;
|
||||
}
|
||||
|
||||
context.Response.ContentLength64 = buffer.Length;
|
||||
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
|
||||
context.Response.OutputStream.Close();
|
||||
}
|
||||
catch
|
||||
{ }
|
||||
|
||||
Listen();
|
||||
}
|
||||
|
||||
private static string Encode(string input)
|
||||
{
|
||||
var sb = new StringBuilder(input);
|
||||
|
||||
sb.Replace("&", "&");
|
||||
sb.Replace("<", "<");
|
||||
sb.Replace(">", ">");
|
||||
sb.Replace("\"", """);
|
||||
sb.Replace("'", "'");
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public StatusPage()
|
||||
: base(TimeSpan.FromSeconds(5.0), TimeSpan.FromSeconds(60.0))
|
||||
{
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (!Directory.Exists("web"))
|
||||
{
|
||||
Directory.CreateDirectory("web");
|
||||
}
|
||||
|
||||
using (var op = new StreamWriter("web/status.html"))
|
||||
{
|
||||
op.WriteLine("<!DOCTYPE html>");
|
||||
op.WriteLine("<html>");
|
||||
op.WriteLine(" <head>");
|
||||
op.WriteLine(" <title>" + ServerList.ServerName + " Server Status</title>");
|
||||
op.WriteLine(" </head>");
|
||||
op.WriteLine(" <style type=\"text/css\">");
|
||||
op.WriteLine(" body { background: #999; }");
|
||||
op.WriteLine(" table { width: 100%; }");
|
||||
op.WriteLine(" tr.ruo-header td { background: #000; color: #FFF; }");
|
||||
op.WriteLine(" tr.odd td { background: #222; color: #DDD; }");
|
||||
op.WriteLine(" tr.even td { background: #DDD; color: #222; }");
|
||||
op.WriteLine(" </style>");
|
||||
op.WriteLine(" <body>");
|
||||
op.WriteLine(" <h1>RunUO Server Status</h1>");
|
||||
op.WriteLine(" <h3>Online clients</h3>");
|
||||
op.WriteLine(" <table cellpadding=\"0\" cellspacing=\"0\">");
|
||||
op.WriteLine(" <tr class=\"ruo-header\"><td>Name</td><td>Location</td><td>Kills</td><td>Karma/Fame</td></tr>");
|
||||
|
||||
var index = 0;
|
||||
|
||||
foreach (var m in NetState.Instances.Where(state => state.Mobile != null).Select(state => state.Mobile))
|
||||
{
|
||||
++index;
|
||||
|
||||
var g = m.Guild as Guild;
|
||||
|
||||
op.Write(" <tr class=\"ruo-result " + (index % 2 == 0 ? "even" : "odd") + "\"><td>");
|
||||
|
||||
if (g != null)
|
||||
{
|
||||
op.Write(Encode(m.Name));
|
||||
op.Write(" [");
|
||||
|
||||
var title = m.GuildTitle;
|
||||
|
||||
title = title != null ? title.Trim() : String.Empty;
|
||||
|
||||
if (title.Length > 0)
|
||||
{
|
||||
op.Write(Encode(title));
|
||||
op.Write(", ");
|
||||
}
|
||||
|
||||
op.Write(Encode(g.Abbreviation));
|
||||
|
||||
op.Write(']');
|
||||
}
|
||||
else
|
||||
{
|
||||
op.Write(Encode(m.Name));
|
||||
}
|
||||
|
||||
op.Write("</td><td>");
|
||||
op.Write(m.X);
|
||||
op.Write(", ");
|
||||
op.Write(m.Y);
|
||||
op.Write(", ");
|
||||
op.Write(m.Z);
|
||||
op.Write(" (");
|
||||
op.Write(m.Map);
|
||||
op.Write(")</td><td>");
|
||||
op.Write(m.Kills);
|
||||
op.Write("</td><td>");
|
||||
op.Write(m.Karma);
|
||||
op.Write(" / ");
|
||||
op.Write(m.Fame);
|
||||
op.WriteLine("</td></tr>");
|
||||
}
|
||||
|
||||
op.WriteLine(" <tr>");
|
||||
op.WriteLine(" </table>");
|
||||
op.WriteLine(" </body>");
|
||||
op.WriteLine("</html>");
|
||||
}
|
||||
|
||||
lock (_StatusLock)
|
||||
{
|
||||
_StatusPage = File.ReadAllText("web/status.html");
|
||||
_StatusBuffer = Encoding.UTF8.GetBytes(_StatusPage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
132
Scripts/Misc/WeightOverloading.cs
Normal file
132
Scripts/Misc/WeightOverloading.cs
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
public enum DFAlgorithm
|
||||
{
|
||||
Standard,
|
||||
PainSpike
|
||||
}
|
||||
|
||||
public class WeightOverloading
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
EventSink.Movement += new MovementEventHandler( EventSink_Movement );
|
||||
}
|
||||
|
||||
private static DFAlgorithm m_DFA;
|
||||
|
||||
public static DFAlgorithm DFA
|
||||
{
|
||||
get{ return m_DFA; }
|
||||
set{ m_DFA = value; }
|
||||
}
|
||||
|
||||
public static void FatigueOnDamage( Mobile m, int damage )
|
||||
{
|
||||
double fatigue = 0.0;
|
||||
|
||||
switch ( m_DFA )
|
||||
{
|
||||
case DFAlgorithm.Standard:
|
||||
{
|
||||
fatigue = (damage * (100.0 / m.Hits) * ((double)m.Stam / 100)) - 5.0;
|
||||
break;
|
||||
}
|
||||
case DFAlgorithm.PainSpike:
|
||||
{
|
||||
fatigue = (damage * ((100.0 / m.Hits) + ((50.0 + m.Stam) / 100) - 1.0)) - 5.0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( fatigue > 0 )
|
||||
m.Stam -= (int)fatigue;
|
||||
}
|
||||
|
||||
public const int OverloadAllowance = 4; // We can be four stones overweight without getting fatigued
|
||||
|
||||
public static int GetMaxWeight( Mobile m )
|
||||
{
|
||||
//return ((( Core.ML && m.Race == Race.Human) ? 100 : 40 ) + (int)(3.5 * m.Str));
|
||||
//Moved to core virtual method for use there
|
||||
|
||||
return m.MaxWeight;
|
||||
}
|
||||
|
||||
public static void EventSink_Movement( MovementEventArgs e )
|
||||
{
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if ( !from.Alive || from.AccessLevel > AccessLevel.Player )
|
||||
return;
|
||||
|
||||
if ( !from.Player )
|
||||
{
|
||||
// Else it won't work on monsters.
|
||||
Spells.Ninjitsu.DeathStrike.AddStep( from );
|
||||
return;
|
||||
}
|
||||
|
||||
int maxWeight = GetMaxWeight( from ) + OverloadAllowance;
|
||||
int overWeight = (Mobile.BodyWeight + from.TotalWeight) - maxWeight;
|
||||
|
||||
if ( overWeight > 0 )
|
||||
{
|
||||
from.Stam -= GetStamLoss( from, overWeight, (e.Direction & Direction.Running) != 0 );
|
||||
|
||||
if ( from.Stam == 0 )
|
||||
{
|
||||
from.SendLocalizedMessage( 500109 ); // You are too fatigued to move, because you are carrying too much weight!
|
||||
e.Blocked = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ((from.Stam * 100) / Math.Max( from.StamMax, 1 )) < 10 )
|
||||
--from.Stam;
|
||||
|
||||
if ( from.Stam == 0 )
|
||||
{
|
||||
from.SendLocalizedMessage( 500110 ); // You are too fatigued to move.
|
||||
e.Blocked = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( from is PlayerMobile )
|
||||
{
|
||||
int amt = ( from.Mounted ? 48 : 16 );
|
||||
PlayerMobile pm = (PlayerMobile)from;
|
||||
|
||||
if ( (++pm.StepsTaken % amt) == 0 )
|
||||
--from.Stam;
|
||||
}
|
||||
|
||||
Spells.Ninjitsu.DeathStrike.AddStep( from );
|
||||
}
|
||||
|
||||
public static int GetStamLoss( Mobile from, int overWeight, bool running )
|
||||
{
|
||||
int loss = 5 + (overWeight / 25);
|
||||
|
||||
if ( from.Mounted )
|
||||
loss /= 3;
|
||||
|
||||
if ( running )
|
||||
loss *= 2;
|
||||
|
||||
return loss;
|
||||
}
|
||||
|
||||
public static bool IsOverloaded( Mobile m )
|
||||
{
|
||||
if ( !m.Player || !m.Alive || m.AccessLevel > AccessLevel.Player )
|
||||
return false;
|
||||
|
||||
return ( (Mobile.BodyWeight + m.TotalWeight) > (GetMaxWeight( m ) + OverloadAllowance) );
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Scripts/Misc/WelcomeTimer.cs
Normal file
40
Scripts/Misc/WelcomeTimer.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Misc
|
||||
{
|
||||
/// <summary>
|
||||
/// This timer spouts some welcome messages to a user at a set interval. It is used on character creation and login.
|
||||
/// </summary>
|
||||
public class WelcomeTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private int m_State, m_Count;
|
||||
|
||||
private static string[] m_Messages =
|
||||
new string[]
|
||||
{
|
||||
"Welcome to Britannia.",
|
||||
"Please enjoy your stay."
|
||||
};
|
||||
|
||||
public WelcomeTimer( Mobile m ) : this( m, m_Messages.Length )
|
||||
{
|
||||
}
|
||||
|
||||
public WelcomeTimer( Mobile m, int count ) : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 10.0 ) )
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_Count = count;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( m_State < m_Count )
|
||||
m_Mobile.SendMessage( 0x35, m_Messages[m_State++] );
|
||||
|
||||
if ( m_State == m_Count )
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
353
Scripts/Misc/uoamVendors.cs
Normal file
353
Scripts/Misc/uoamVendors.cs
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using Server.Commands;
|
||||
|
||||
// Version 0.8
|
||||
|
||||
namespace Server
|
||||
{
|
||||
public class UOAMVendorGenerator
|
||||
{
|
||||
private static int m_Count;
|
||||
|
||||
//configuration
|
||||
private const int NPCCount = 2;//2 npcs per type (so a mage spawner will spawn 2 npcs, a alchemist and herbalist spawner will spawn 4 npcs total)
|
||||
private const int HomeRange = 5;//How far should they wander?
|
||||
private const bool TotalRespawn = true;//Should we spawn them up right away?
|
||||
private static TimeSpan MinTime = TimeSpan.FromMinutes( 2.5 );//min spawn time
|
||||
private static TimeSpan MaxTime = TimeSpan.FromMinutes( 10.0 );//max spawn time
|
||||
private const int Team = 0;//"team" the npcs are on
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "UOAMVendors", AccessLevel.Administrator, new CommandEventHandler( Generate_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "UOAMVendors" )]
|
||||
[Description( "Generates vendor spawners from Data/Common.MAP (taken from UOAutoMap)" )]
|
||||
private static void Generate_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
Parse( e.Mobile );
|
||||
}
|
||||
|
||||
public static void Parse( Mobile from )
|
||||
{
|
||||
string vendor_path = Path.Combine( Core.BaseDirectory, "Data/Common.map" );
|
||||
m_Count = 0;
|
||||
|
||||
if ( File.Exists( vendor_path ) )
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
from.SendMessage( "Generating Vendors..." );
|
||||
|
||||
using ( StreamReader ip = new StreamReader( vendor_path ) )
|
||||
{
|
||||
string line;
|
||||
|
||||
while ( (line = ip.ReadLine()) != null )
|
||||
{
|
||||
int indexOf = line.IndexOf( ':' );
|
||||
|
||||
if ( indexOf == -1 )
|
||||
continue;
|
||||
|
||||
string type = line.Substring( 0, ++indexOf ).Trim();
|
||||
string sub = line.Substring( indexOf ).Trim();
|
||||
|
||||
string[] split = sub.Split( ' ' );
|
||||
|
||||
if ( split.Length < 3 )
|
||||
continue;
|
||||
|
||||
split = new string[]{ type, split[0], split[1], split[2] };
|
||||
|
||||
switch(split[0].ToLower())
|
||||
{
|
||||
case "-healer:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Healer", "HealerGuildmaster" );
|
||||
break;
|
||||
case "-baker:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Baker" );
|
||||
break;
|
||||
case "-vet:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Veterinarian" );
|
||||
break;
|
||||
case "-gypsymaiden:":
|
||||
PlaceNPC( split[1], split[2], split[3], "GypsyMaiden" );
|
||||
break;
|
||||
case "-gypsybank:":
|
||||
PlaceNPC( split[1], split[2], split[3], "GypsyBanker" );
|
||||
break;
|
||||
case "-bank:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Banker", "Minter" );
|
||||
break;
|
||||
case "-inn:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Innkeeper" );
|
||||
break;
|
||||
case "-provisioner:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Provisioner", "Cobbler" );
|
||||
break;
|
||||
case "-tailor:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Tailor", "Weaver", "TailorGuildmaster" );
|
||||
break;
|
||||
case "-tavern:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Tavernkeeper", "Waiter", "Cook", "Barkeeper" );
|
||||
break;
|
||||
case "-reagents:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Herbalist", "Alchemist", "CustomHairstylist" );
|
||||
break;
|
||||
case "-fortuneteller:":
|
||||
PlaceNPC( split[1], split[2], split[3], "FortuneTeller" );
|
||||
break;
|
||||
case "-holymage:":
|
||||
PlaceNPC( split[1], split[2], split[3], "HolyMage" );
|
||||
break;
|
||||
case "-chivalrykeeper:":
|
||||
PlaceNPC( split[1], split[2], split[3], "KeeperOfChivalry" );
|
||||
break;
|
||||
case "-mage:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Mage", "Alchemist", "MageGuildmaster" );
|
||||
break;
|
||||
case "-arms:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Armorer", "Weaponsmith" );
|
||||
break;
|
||||
case "-tinker:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Tinker", "TinkerGuildmaster" );
|
||||
break;
|
||||
case "-gypsystable:":
|
||||
PlaceNPC( split[1], split[2], split[3], "GypsyAnimalTrainer" );
|
||||
break;
|
||||
case "-stable:":
|
||||
PlaceNPC( split[1], split[2], split[3], "AnimalTrainer" );
|
||||
break;
|
||||
case "-blacksmith:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Blacksmith", "BlacksmithGuildmaster" );
|
||||
break;
|
||||
case "-bowyer:":
|
||||
case "-fletcher:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Bowyer" );
|
||||
break;
|
||||
case "-carpenter:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Carpenter", "Architect", "RealEstateBroker" );
|
||||
break;
|
||||
case "-butcher:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Butcher" );
|
||||
break;
|
||||
case "-jeweler:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Jeweler" );
|
||||
break;
|
||||
case "-tanner:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Tanner", "Furtrader" );
|
||||
break;
|
||||
case "-bard:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Bard", "BardGuildmaster" );
|
||||
break;
|
||||
case "-market:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Butcher", "Farmer" );
|
||||
break;
|
||||
case "-library:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Scribe" );
|
||||
break;
|
||||
case "-shipwright:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Shipwright", "Mapmaker" );
|
||||
break;
|
||||
case "-docks:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Fisherman" );
|
||||
break;
|
||||
|
||||
case "-beekeeper:":
|
||||
PlaceNPC( split[1], split[2], split[3], "Beekeeper" );
|
||||
break;
|
||||
|
||||
|
||||
// Guilds & Misc
|
||||
case "-tinkers guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "TinkerGuildmaster" );
|
||||
break;
|
||||
case "-blacksmiths guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "BlacksmithGuildmaster" );
|
||||
break;
|
||||
case "-sorcerors guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "MageGuildmaster" );
|
||||
break;
|
||||
case "-customs:": break;
|
||||
case "-painter:": break;
|
||||
case "-theater:": break;
|
||||
case "-warriors guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "WarriorGuildmaster" );
|
||||
break;
|
||||
case "-archers guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "RangerGuildmaster" );
|
||||
break;
|
||||
case "-thieves guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "ThiefGuildmaster" );
|
||||
break;
|
||||
case "-miners guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "MinerGuildmaster" );
|
||||
break;
|
||||
case "-fishermans guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "FisherGuildmaster" );
|
||||
break;
|
||||
case "-merchants guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "MerchantGuildmaster" );
|
||||
break;
|
||||
case "-illusionists guild:": break;
|
||||
case "-armourers guild:": break;
|
||||
case "-sorcerers guild:": break;
|
||||
case "-mages guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "MageGuildmaster" );
|
||||
break;
|
||||
case "-weapons guild:": break;
|
||||
case "-bardic guild:":
|
||||
PlaceNPC( split[1], split[2], split[3], "BardGuildmaster" );
|
||||
break;
|
||||
case "-rogues guild:":
|
||||
break;
|
||||
|
||||
// Skip
|
||||
case "+landmark:":
|
||||
case "-point of interest:":
|
||||
case "+shrine:":
|
||||
case "+moongate:":
|
||||
case "+dungeon:":
|
||||
case "+scenic:":
|
||||
case "-gate:":
|
||||
case "+Body of Water:":
|
||||
case "+ruins:":
|
||||
case "+teleporter:":
|
||||
case "+Terrain:":
|
||||
case "-exit:":
|
||||
case "-bridge:":
|
||||
case "-other:":
|
||||
case "+champion:":
|
||||
case "-stairs:":
|
||||
case "-guild:":
|
||||
case "+graveyard:":
|
||||
case "+Island:":
|
||||
case "+town:":
|
||||
break;
|
||||
/*default:
|
||||
Console.WriteLine(split[0]);
|
||||
break;*/
|
||||
}
|
||||
}
|
||||
}
|
||||
from.SendMessage( "Done, added {0} spawners",m_Count );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "{0} not found!", vendor_path );
|
||||
}
|
||||
}
|
||||
|
||||
public static void PlaceNPC( string sx, string sy, string sm, params string[] types )
|
||||
{
|
||||
if ( types.Length == 0 )
|
||||
return;
|
||||
|
||||
int x = Utility.ToInt32( sx );
|
||||
int y = Utility.ToInt32( sy );
|
||||
int map = Utility.ToInt32( sm );
|
||||
|
||||
switch ( map )
|
||||
{
|
||||
case 0://Trammel and Felucca
|
||||
MakeSpawner( types, x, y, Map.Felucca );
|
||||
MakeSpawner( types, x, y, Map.Trammel );
|
||||
break;
|
||||
case 1://Felucca
|
||||
MakeSpawner( types, x, y, Map.Felucca );
|
||||
break;
|
||||
case 2:
|
||||
MakeSpawner( types, x, y, Map.Trammel );
|
||||
break;
|
||||
case 3:
|
||||
MakeSpawner( types, x, y, Map.Ilshenar );
|
||||
break;
|
||||
case 4:
|
||||
MakeSpawner( types, x, y, Map.Malas );
|
||||
break;
|
||||
default:
|
||||
Console.WriteLine( "UOAM Vendor Parser: Warning, unknown map {0}", map );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetSpawnerZ( int x, int y, Map map )
|
||||
{
|
||||
int z = map.GetAverageZ( x, y );
|
||||
|
||||
if ( map.CanFit( x, y, z, 16, false, false, true ) )
|
||||
return z;
|
||||
|
||||
for ( int i = 1; i <= 20; ++i )
|
||||
{
|
||||
if ( map.CanFit( x, y, z + i, 16, false, false, true ) )
|
||||
return z + i;
|
||||
|
||||
if ( map.CanFit( x, y, z - i, 16, false, false, true ) )
|
||||
return z - i;
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
|
||||
private static Queue m_ToDelete = new Queue();
|
||||
|
||||
public static void ClearSpawners( int x, int y, int z, Map map )
|
||||
{
|
||||
IPooledEnumerable eable = map.GetItemsInRange( new Point3D( x, y, z ), 0 );
|
||||
|
||||
foreach ( Item item in eable )
|
||||
{
|
||||
if ( item is Spawner && item.Z == z )
|
||||
m_ToDelete.Enqueue( item );
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
while ( m_ToDelete.Count > 0 )
|
||||
((Item)m_ToDelete.Dequeue()).Delete();
|
||||
}
|
||||
|
||||
private static void MakeSpawner( string[] types, int x, int y, Map map )
|
||||
{
|
||||
if ( types.Length == 0 )
|
||||
return;
|
||||
|
||||
int z = GetSpawnerZ( x, y, map );
|
||||
|
||||
ClearSpawners( x, y, z, map );
|
||||
|
||||
for ( int i = 0; i < types.Length; ++i )
|
||||
{
|
||||
bool isGuildmaster = ( types[i].EndsWith( "Guildmaster" ) );
|
||||
|
||||
Spawner sp = new Spawner( types[i] );
|
||||
|
||||
if ( isGuildmaster )
|
||||
sp.Count = 1;
|
||||
else
|
||||
sp.Count = NPCCount;
|
||||
|
||||
sp.MinDelay = MinTime;
|
||||
sp.MaxDelay = MaxTime;
|
||||
sp.Team = Team;
|
||||
sp.HomeRange = HomeRange;
|
||||
|
||||
sp.MoveToWorld( new Point3D( x, y, z ), map );
|
||||
|
||||
if ( TotalRespawn )
|
||||
{
|
||||
sp.Respawn();
|
||||
sp.BringToHome();
|
||||
}
|
||||
|
||||
++m_Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue