Plant gump issues
http://jira.runuo.com/browse/RUNUO-12 House decay stages should pass at random intervals http://jira.runuo.com/browse/RUNUO-113 Nature's Fury cast issues http://jira.runuo.com/browse/RUNUO-114 Animal Form inaccuracies and issue with Talisman of the Fey http://jira.runuo.com/browse/RUNUO-115 BaseWaterContainer fill messages and behavior http://jira.runuo.com/browse/RUNUO-116 AdminGump filter for accounts owning houses http://jira.runuo.com/browse/RUNUO-118 Seeds should be stackable http://jira.runuo.com/browse/RUNUO-119 Typo in case of a jailbreak http://jira.runuo.com/browse/RUNUO-120 Prevent creation of invalid account names http://jira.runuo.com/browse/RUNUO-121
This commit is contained in:
parent
d2f79e93ea
commit
4cba2c8d56
18 changed files with 440 additions and 137 deletions
|
|
@ -251,17 +251,31 @@ namespace Server.Misc
|
|||
|
||||
return m_IPTable;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly char[] m_ForbiddenChars = new char[]
|
||||
{
|
||||
'<', '>', ':', '"', '/', '\\', '|', '?', '*'
|
||||
};
|
||||
|
||||
private static bool IsForbiddenChar( char c )
|
||||
{
|
||||
for ( int i = 0; i < m_ForbiddenChars.Length; ++i )
|
||||
if ( c == m_ForbiddenChars[i] )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Account CreateAccount( NetState state, string un, string pw )
|
||||
{
|
||||
if ( un.Length == 0 || pw.Length == 0 )
|
||||
return null;
|
||||
|
||||
bool isSafe = true;
|
||||
bool isSafe = !( un.StartsWith( " " ) || un.EndsWith( " " ) || un.EndsWith( "." ) );
|
||||
|
||||
for ( int i = 0; isSafe && i < un.Length; ++i )
|
||||
isSafe = ( un[i] >= 0x20 && un[i] < 0x80 );
|
||||
isSafe = ( un[i] >= 0x20 && un[i] < 0x80 && !IsForbiddenChar( un[i] ) );
|
||||
|
||||
for ( int i = 0; isSafe && i < pw.Length; ++i )
|
||||
isSafe = ( pw[i] >= 0x20 && pw[i] < 0x80 );
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ namespace Server.Engines.Help
|
|||
}
|
||||
else if ( from.Region.IsPartOf( typeof( Server.Regions.Jail ) ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1041530, "", 0x35 ); // You'll need a better jailbreak plan then that!
|
||||
from.SendLocalizedMessage( 1114345, "", 0x35 ); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
else if ( Factions.Sigil.ExistsOn( from ) )
|
||||
{
|
||||
|
|
@ -290,7 +290,7 @@ namespace Server.Engines.Help
|
|||
{
|
||||
if ( from.Region.IsPartOf( typeof( Regions.Jail ) ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1041530, "", 0x35 ); // You'll need a better jailbreak plan then that!
|
||||
from.SendLocalizedMessage( 1114345, "", 0x35 ); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
else if ( from.Region.IsPartOf( "Haven Island" ) )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -44,19 +44,19 @@ namespace Server.Engines.Plants
|
|||
AddPlusMinus( 196, 67, system.Water );
|
||||
|
||||
AddButton( 209, 91, 0xD4, 0xD4, 7, GumpButtonType.Reply, 0 ); // Poison potion
|
||||
AddItem( 197, 91, 0xF0A );
|
||||
AddItem( 201, 91, 0xF0A );
|
||||
AddLevel( 196, 91, system.PoisonPotion );
|
||||
|
||||
AddButton( 209, 115, 0xD4, 0xD4, 8, GumpButtonType.Reply, 0 ); // Cure potion
|
||||
AddItem( 192, 115, 0xF07 );
|
||||
AddItem( 201, 115, 0xF07 );
|
||||
AddLevel( 196, 115, system.CurePotion );
|
||||
|
||||
AddButton( 209, 139, 0xD4, 0xD4, 9, GumpButtonType.Reply, 0 ); // Heal potion
|
||||
AddItem( 190, 139, 0xF0C );
|
||||
AddItem( 201, 139, 0xF0C );
|
||||
AddLevel( 196, 139, system.HealPotion );
|
||||
|
||||
AddButton( 209, 163, 0xD4, 0xD4, 10, GumpButtonType.Reply, 0 ); // Strength potion
|
||||
AddItem( 193, 163, 0xF09 );
|
||||
AddItem( 201, 163, 0xF09 );
|
||||
AddLevel( 196, 163, system.StrengthPotion );
|
||||
|
||||
AddImage( 48, 47, 0xD2 );
|
||||
|
|
@ -317,6 +317,8 @@ namespace Server.Engines.Plants
|
|||
from.SendLocalizedMessage( 1060808, "#" + m_Plant.GetLocalizedPlantStatus().ToString() ); // Target the container you wish to use to water the ~1_val~.
|
||||
}
|
||||
|
||||
from.SendGump( new MainPlantGump( m_Plant ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 7: // Poison potion
|
||||
|
|
|
|||
|
|
@ -386,7 +386,7 @@ namespace Server.Engines.Plants
|
|||
m_PlantHue = seed.PlantHue;
|
||||
m_ShowType = seed.ShowType;
|
||||
|
||||
seed.Delete();
|
||||
seed.Consume();
|
||||
|
||||
PlantStatus = PlantStatus.Seed;
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,9 @@ namespace Server.Engines.Plants
|
|||
{
|
||||
if ( !m_Plant.Deleted && m_Plant.PlantStatus < PlantStatus.DecorativePlant && from.InRange( m_Plant.GetWorldLocation(), 3 ) && m_Plant.IsUsableBy( from ) )
|
||||
{
|
||||
if ( from.HasGump( typeof( MainPlantGump ) ) )
|
||||
from.CloseGump( typeof( MainPlantGump ) );
|
||||
|
||||
from.SendGump( new MainPlantGump( m_Plant ) );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
|
||||
|
|
@ -76,6 +77,7 @@ namespace Server.Engines.Plants
|
|||
public Seed( PlantType plantType, PlantHue plantHue, bool showType ) : base( 0xDCF )
|
||||
{
|
||||
Weight = 1.0;
|
||||
Stackable = Core.SA;
|
||||
|
||||
m_PlantType = plantType;
|
||||
m_PlantHue = plantHue;
|
||||
|
|
@ -90,7 +92,7 @@ namespace Server.Engines.Plants
|
|||
|
||||
public override bool ForceShowProperties{ get{ return ObjectPropertyList.Enabled; } }
|
||||
|
||||
public override void AddNameProperty( ObjectPropertyList list )
|
||||
private int GetLabel( out string args )
|
||||
{
|
||||
PlantHueInfo hueInfo = PlantHueInfo.GetInfo( m_PlantHue );
|
||||
|
||||
|
|
@ -98,30 +100,50 @@ namespace Server.Engines.Plants
|
|||
if ( title == 0 ) // Not a bonsai
|
||||
title = hueInfo.Name;
|
||||
|
||||
int label;
|
||||
|
||||
if ( Amount == 1 )
|
||||
label = m_ShowType ? 1061917 : 1060838; // ~1_COLOR~ ~2_TYPE~ seed : ~1_val~ seed
|
||||
else
|
||||
label = m_ShowType ? 1113492 : 1113490; // ~1_amount~ ~2_color~ ~3_type~ seeds : ~1_amount~ ~2_val~ seeds
|
||||
|
||||
if ( hueInfo.IsBright() )
|
||||
++label;
|
||||
|
||||
StringBuilder ab = new StringBuilder();
|
||||
|
||||
if ( Amount != 1 )
|
||||
{
|
||||
ab.Append( Amount );
|
||||
ab.Append( '\t' );
|
||||
}
|
||||
|
||||
ab.Append( '#' );
|
||||
ab.Append( title );
|
||||
|
||||
if ( m_ShowType )
|
||||
{
|
||||
PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( m_PlantType );
|
||||
list.Add( hueInfo.IsBright() ? 1061918 : 1061917, String.Concat( "#", title.ToString(), "\t#", typeInfo.Name.ToString() ) ); // [bright] ~1_COLOR~ ~2_TYPE~ seed
|
||||
}
|
||||
else
|
||||
{
|
||||
list.Add( hueInfo.IsBright() ? 1060839 : 1060838, String.Concat( "#", title.ToString() ) ); // [bright] ~1_val~ seed
|
||||
|
||||
ab.Append( "\t#" );
|
||||
ab.Append( typeInfo.Name );
|
||||
}
|
||||
|
||||
args = ab.ToString();
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
public override void OnSingleClick ( Mobile from )
|
||||
public override void AddNameProperty( ObjectPropertyList list )
|
||||
{
|
||||
PlantHueInfo hueInfo = PlantHueInfo.GetInfo( m_PlantHue );
|
||||
string args;
|
||||
list.Add( GetLabel( out args ), args );
|
||||
}
|
||||
|
||||
if ( m_ShowType )
|
||||
{
|
||||
PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( m_PlantType );
|
||||
LabelTo( from, hueInfo.IsBright() ? 1061918 : 1061917, String.Concat( "#", hueInfo.Name.ToString(), "\t#", typeInfo.Name.ToString() ) ); // [bright] ~1_COLOR~ ~2_TYPE~ seed
|
||||
}
|
||||
else
|
||||
{
|
||||
LabelTo( from, hueInfo.IsBright() ? 1060839 : 1060838, String.Concat( "#", hueInfo.Name.ToString() ) ); // [bright] ~1_val~ seed
|
||||
}
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
string args;
|
||||
LabelTo( from, GetLabel( out args ), args );
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
|
|
@ -136,6 +158,31 @@ namespace Server.Engines.Plants
|
|||
LabelTo( from, 1061916 ); // Choose a bowl of dirt to plant this seed in.
|
||||
}
|
||||
|
||||
public override bool StackWith( Mobile from, Item dropped, bool playSound )
|
||||
{
|
||||
if ( dropped is Seed )
|
||||
{
|
||||
Seed other = (Seed)dropped;
|
||||
|
||||
if ( other.PlantType == m_PlantType && other.PlantHue == m_PlantHue && other.ShowType == m_ShowType )
|
||||
return base.StackWith( from, dropped, playSound );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnAfterDuped( Item newItem )
|
||||
{
|
||||
Seed newSeed = newItem as Seed;
|
||||
|
||||
if ( newSeed == null )
|
||||
return;
|
||||
|
||||
newSeed.PlantType = m_PlantType;
|
||||
newSeed.PlantHue = m_PlantHue;
|
||||
newSeed.ShowType = m_ShowType;
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private Seed m_Seed;
|
||||
|
|
@ -178,7 +225,7 @@ namespace Server.Engines.Plants
|
|||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
writer.Write( (int) 1 ); // version
|
||||
|
||||
writer.Write( (int) m_PlantType );
|
||||
writer.Write( (int) m_PlantHue );
|
||||
|
|
@ -197,6 +244,9 @@ namespace Server.Engines.Plants
|
|||
|
||||
if ( Weight != 1.0 )
|
||||
Weight = 1.0;
|
||||
|
||||
if ( version < 1 )
|
||||
Stackable = Core.SA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -174,7 +174,7 @@ namespace Server.Engines.Quests
|
|||
{
|
||||
if ( m.Region.IsPartOf( typeof( Regions.Jail ) ) )
|
||||
{
|
||||
m.SendLocalizedMessage( 1042632 ); // You'll need a better jailbreak plan then that!
|
||||
m.SendLocalizedMessage( 1114345 ); // You'll need a better jailbreak plan than that!
|
||||
}
|
||||
else if ( m == m_Caster )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using Server.Prompts;
|
|||
using Server.Network;
|
||||
using Server.Accounting;
|
||||
using Server.Commands;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Gumps
|
||||
{
|
||||
|
|
@ -756,7 +757,8 @@ namespace Server.Gumps
|
|||
AddButtonLabeled( 10, 390, GetButtonID( 5, 27 ), "Ban marked" );
|
||||
AddButtonLabeled( 10, 410, GetButtonID( 5, 28 ), "Delete marked" );
|
||||
|
||||
AddButtonLabeled( 210, 400, GetButtonID( 5, 29 ), "Mark all" );
|
||||
AddButtonLabeled( 210, 390, GetButtonID( 5, 29 ), "Mark all" );
|
||||
AddButtonLabeled( 210, 410, GetButtonID( 5, 33 ), "Unmark house owners" );
|
||||
}
|
||||
|
||||
for ( int i = 0, index = (listPage * 12); i < 12 && index >= 0 && index < m_List.Count; ++i, ++index )
|
||||
|
|
@ -2383,6 +2385,32 @@ namespace Server.Gumps
|
|||
|
||||
break;
|
||||
}
|
||||
case 33: // Unmark house owners
|
||||
{
|
||||
ArrayList list = m_List;
|
||||
ArrayList rads = m_State as ArrayList;
|
||||
|
||||
if ( list == null || rads == null )
|
||||
break;
|
||||
|
||||
ArrayList newRads = new ArrayList();
|
||||
|
||||
foreach ( Account acct in rads )
|
||||
{
|
||||
bool hasHouse = false;
|
||||
|
||||
for ( int i = 0; i < acct.Length && !hasHouse; ++i )
|
||||
if ( acct[i] != null && BaseHouse.HasHouse( acct[i] ) )
|
||||
hasHouse = true;
|
||||
|
||||
if ( !hasHouse )
|
||||
newRads.Add( acct );
|
||||
}
|
||||
|
||||
from.SendGump( new AdminGump( from, AdminGumpPage.Accounts, m_ListPage, m_List, null, newRads ) );
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
index -= 50;
|
||||
|
|
|
|||
|
|
@ -741,14 +741,14 @@ namespace Server.Items
|
|||
{
|
||||
BaseWaterContainer bwc = targ as BaseWaterContainer;
|
||||
|
||||
if( Quantity == 0 || ( this.Content == BeverageType.Water && !this.IsFull ) )
|
||||
if( Quantity == 0 || ( Content == BeverageType.Water && !IsFull ) )
|
||||
{
|
||||
int I_Need = Math.Min( ( MaxQuantity - Quantity ), bwc.Quantity );
|
||||
int iNeed = Math.Min( ( MaxQuantity - Quantity ), bwc.Quantity );
|
||||
|
||||
if( ( I_Need > 0 ) && !bwc.IsEmpty && !IsFull )
|
||||
if( iNeed > 0 && !bwc.IsEmpty && !IsFull )
|
||||
{
|
||||
bwc.Quantity -= I_Need;
|
||||
Quantity += I_Need;
|
||||
bwc.Quantity -= iNeed;
|
||||
Quantity += iNeed;
|
||||
Content = BeverageType.Water;
|
||||
|
||||
from.PlaySound( 0x4E );
|
||||
|
|
@ -1026,15 +1026,23 @@ namespace Server.Items
|
|||
else if( targ is BaseWaterContainer )
|
||||
{
|
||||
BaseWaterContainer bwc = targ as BaseWaterContainer;
|
||||
|
||||
if( ( !this.IsEmpty || this.Content == BeverageType.Water ) && bwc.Items.Count == 0 )
|
||||
|
||||
if( Content != BeverageType.Water )
|
||||
{
|
||||
int It_Needs = Math.Min( ( bwc.MaxQuantity - bwc.Quantity ), Quantity );
|
||||
from.SendLocalizedMessage( 500842 ); // Can't pour that in there.
|
||||
}
|
||||
else if( bwc.Items.Count != 0 )
|
||||
{
|
||||
from.SendLocalizedMessage( 500841 ); // That has something in it.
|
||||
}
|
||||
else
|
||||
{
|
||||
int itNeeds = Math.Min( ( bwc.MaxQuantity - bwc.Quantity ), Quantity );
|
||||
|
||||
if( It_Needs > 0 && ( !IsEmpty && !bwc.IsFull ) )
|
||||
if( itNeeds > 0 )
|
||||
{
|
||||
bwc.Quantity += It_Needs;
|
||||
Quantity -= It_Needs;
|
||||
bwc.Quantity += itNeeds;
|
||||
Quantity -= itNeeds;
|
||||
|
||||
from.PlaySound( 0x4E );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@
|
|||
|
||||
ItemID = ( IsEmpty ) ? voidItem_ID : fullItem_ID;
|
||||
|
||||
if( !IsEmpty )
|
||||
{
|
||||
IEntity rootParent = RootParentEntity;
|
||||
|
||||
if( rootParent != null && rootParent.Map != null && rootParent.Map != Map.Internal )
|
||||
MoveToWorld( rootParent.Location, rootParent.Map );
|
||||
}
|
||||
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ namespace Server.Items
|
|||
}
|
||||
else if ( from.Region.IsPartOf( typeof( Server.Regions.Jail ) ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1041530, "", 0x35 ); // You'll need a better jailbreak plan then that!
|
||||
from.SendLocalizedMessage( 1114345, "", 0x35 ); // You'll need a better jailbreak plan than that!
|
||||
return false;
|
||||
}
|
||||
else if ( boundRoot.Region.IsPartOf( typeof( Server.Regions.Jail ) ) )
|
||||
|
|
|
|||
|
|
@ -24,6 +24,34 @@ namespace Server.Multis
|
|||
public static int MaxFriends { get { return !Core.AOS ? 50 : 140; } }
|
||||
public static int MaxBans { get { return !Core.AOS ? 50 : 140; } }
|
||||
|
||||
#region Dynamic decay system
|
||||
private DecayLevel m_CurrentStage;
|
||||
private DateTime m_NextDecayStage;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime NextDecayStage
|
||||
{
|
||||
get { return m_NextDecayStage; }
|
||||
set { m_NextDecayStage = value; }
|
||||
}
|
||||
|
||||
public void ResetDynamicDecay()
|
||||
{
|
||||
m_CurrentStage = DecayLevel.Ageless;
|
||||
m_NextDecayStage = DateTime.MinValue;
|
||||
}
|
||||
|
||||
public void SetDynamicDecay( DecayLevel level )
|
||||
{
|
||||
m_CurrentStage = level;
|
||||
|
||||
if ( DynamicDecay.Decays( level ) )
|
||||
m_NextDecayStage = DateTime.Now + DynamicDecay.GetRandomDuration( level );
|
||||
else
|
||||
m_NextDecayStage = DateTime.MinValue;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public const bool DecayEnabled = true;
|
||||
|
||||
public static void Decay_OnTick()
|
||||
|
|
@ -128,37 +156,73 @@ namespace Server.Multis
|
|||
}
|
||||
}
|
||||
|
||||
private DecayLevel m_LastDecayLevel;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public virtual DecayLevel DecayLevel
|
||||
{
|
||||
get
|
||||
{
|
||||
DecayLevel result;
|
||||
|
||||
if ( !CanDecay )
|
||||
{
|
||||
if ( DynamicDecay.Enabled )
|
||||
ResetDynamicDecay();
|
||||
|
||||
m_LastRefreshed = DateTime.Now;
|
||||
return DecayLevel.Ageless;
|
||||
result = DecayLevel.Ageless;
|
||||
}
|
||||
else if ( DynamicDecay.Enabled )
|
||||
{
|
||||
DecayLevel stage = m_CurrentStage;
|
||||
|
||||
if ( stage == DecayLevel.Ageless || ( DynamicDecay.Decays( stage ) && m_NextDecayStage <= DateTime.Now ) )
|
||||
SetDynamicDecay( ++stage );
|
||||
|
||||
if ( stage == DecayLevel.Collapsed && ( HasRentedVendors || VendorInventories.Count > 0 ) )
|
||||
result = DecayLevel.DemolitionPending;
|
||||
else
|
||||
result = stage;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = GetOldDecayLevel();
|
||||
}
|
||||
|
||||
TimeSpan timeAfterRefresh = DateTime.Now - m_LastRefreshed;
|
||||
int percent = (int) ((timeAfterRefresh.Ticks * 1000) / DecayPeriod.Ticks);
|
||||
if ( result != m_LastDecayLevel )
|
||||
{
|
||||
m_LastDecayLevel = result;
|
||||
|
||||
if ( percent >= 1000 ) // 100.0%
|
||||
return ( HasRentedVendors || VendorInventories.Count > 0 ) ? DecayLevel.DemolitionPending : DecayLevel.Collapsed;
|
||||
else if ( percent >= 950 ) // 95.0% - 99.9%
|
||||
return DecayLevel.IDOC;
|
||||
else if ( percent >= 750 ) // 75.0% - 94.9%
|
||||
return DecayLevel.Greatly;
|
||||
else if ( percent >= 500 ) // 50.0% - 74.9%
|
||||
return DecayLevel.Fairly;
|
||||
else if ( percent >= 250 ) // 25.0% - 49.9%
|
||||
return DecayLevel.Somewhat;
|
||||
else if ( percent >= 005 ) // 00.5% - 24.9%
|
||||
return DecayLevel.Slightly;
|
||||
if ( m_Sign != null && !m_Sign.GettingProperties )
|
||||
m_Sign.InvalidateProperties();
|
||||
}
|
||||
|
||||
return DecayLevel.LikeNew;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public DecayLevel GetOldDecayLevel()
|
||||
{
|
||||
TimeSpan timeAfterRefresh = DateTime.Now - m_LastRefreshed;
|
||||
int percent = (int) ((timeAfterRefresh.Ticks * 1000) / DecayPeriod.Ticks);
|
||||
|
||||
if ( percent >= 1000 ) // 100.0%
|
||||
return ( HasRentedVendors || VendorInventories.Count > 0 ) ? DecayLevel.DemolitionPending : DecayLevel.Collapsed;
|
||||
else if ( percent >= 950 ) // 95.0% - 99.9%
|
||||
return DecayLevel.IDOC;
|
||||
else if ( percent >= 750 ) // 75.0% - 94.9%
|
||||
return DecayLevel.Greatly;
|
||||
else if ( percent >= 500 ) // 50.0% - 74.9%
|
||||
return DecayLevel.Fairly;
|
||||
else if ( percent >= 250 ) // 25.0% - 49.9%
|
||||
return DecayLevel.Somewhat;
|
||||
else if ( percent >= 005 ) // 00.5% - 24.9%
|
||||
return DecayLevel.Slightly;
|
||||
|
||||
return DecayLevel.LikeNew;
|
||||
}
|
||||
|
||||
public virtual bool RefreshDecay()
|
||||
{
|
||||
if ( DecayType == DecayType.Condemned )
|
||||
|
|
@ -168,6 +232,12 @@ namespace Server.Multis
|
|||
|
||||
m_LastRefreshed = DateTime.Now;
|
||||
|
||||
if ( DynamicDecay.Enabled )
|
||||
ResetDynamicDecay();
|
||||
|
||||
if ( m_Sign != null )
|
||||
m_Sign.InvalidateProperties();
|
||||
|
||||
return ( oldLevel > DecayLevel.LikeNew );
|
||||
}
|
||||
|
||||
|
|
@ -2336,7 +2406,17 @@ namespace Server.Multis
|
|||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 14 ); // version
|
||||
writer.Write( (int) 15 ); // version
|
||||
|
||||
if ( !DynamicDecay.Enabled )
|
||||
{
|
||||
writer.Write( (int) -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write( (int) m_CurrentStage );
|
||||
writer.Write( m_NextDecayStage );
|
||||
}
|
||||
|
||||
writer.Write( (Point3D) m_RelativeBanLocation );
|
||||
|
||||
|
|
@ -2434,9 +2514,23 @@ namespace Server.Multis
|
|||
|
||||
int version = reader.ReadInt();
|
||||
int count;
|
||||
bool loadedDynamicDecay = false;
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 15:
|
||||
{
|
||||
int stage = reader.ReadInt();
|
||||
|
||||
if ( stage != -1 )
|
||||
{
|
||||
m_CurrentStage = (DecayLevel)stage;
|
||||
m_NextDecayStage = reader.ReadDateTime();
|
||||
loadedDynamicDecay = true;
|
||||
}
|
||||
|
||||
goto case 14;
|
||||
}
|
||||
case 14:
|
||||
{
|
||||
m_RelativeBanLocation = reader.ReadPoint3D();
|
||||
|
|
@ -2631,6 +2725,16 @@ namespace Server.Multis
|
|||
if ( version < 11 )
|
||||
m_LastRefreshed = DateTime.Now + TimeSpan.FromHours( 24 * Utility.RandomDouble() );
|
||||
|
||||
if ( DynamicDecay.Enabled && !loadedDynamicDecay )
|
||||
{
|
||||
DecayLevel old = GetOldDecayLevel();
|
||||
|
||||
if ( old == DecayLevel.DemolitionPending )
|
||||
old = DecayLevel.Collapsed;
|
||||
|
||||
SetDynamicDecay( old );
|
||||
}
|
||||
|
||||
if ( !CheckDecay() )
|
||||
{
|
||||
if ( RelocatedEntities.Count > 0 )
|
||||
|
|
@ -2788,7 +2892,11 @@ namespace Server.Multis
|
|||
{
|
||||
get
|
||||
{
|
||||
return m_Region.GoLocation;
|
||||
if ( m_Region != null )
|
||||
return m_Region.GoLocation;
|
||||
|
||||
Point3D rel = m_RelativeBanLocation;
|
||||
return new Point3D( this.X + rel.X, this.Y + rel.Y, this.Z + rel.Z );
|
||||
}
|
||||
set
|
||||
{
|
||||
|
|
@ -2806,7 +2914,9 @@ namespace Server.Multis
|
|||
set
|
||||
{
|
||||
m_RelativeBanLocation = value;
|
||||
m_Region.GoLocation = new Point3D( this.X + value.X, this.Y + value.Y, this.Z + value.Z );
|
||||
|
||||
if ( m_Region != null )
|
||||
m_Region.GoLocation = new Point3D( this.X + value.X, this.Y + value.Y, this.Z + value.Z );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
74
Scripts/Multis/DynamicDecay.cs
Normal file
74
Scripts/Multis/DynamicDecay.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
|
||||
namespace Server.Multis
|
||||
{
|
||||
public class DynamicDecay
|
||||
{
|
||||
public static bool Enabled { get { return Core.ML; } }
|
||||
|
||||
private static Dictionary<DecayLevel, DecayStageInfo> m_Stages;
|
||||
|
||||
static DynamicDecay()
|
||||
{
|
||||
m_Stages = new Dictionary<DecayLevel, DecayStageInfo>();
|
||||
|
||||
Register( DecayLevel.LikeNew, TimeSpan.FromHours( 1 ), TimeSpan.FromHours( 1 ) );
|
||||
Register( DecayLevel.Slightly, TimeSpan.FromDays( 1 ), TimeSpan.FromDays( 2 ) );
|
||||
Register( DecayLevel.Somewhat, TimeSpan.FromDays( 1 ), TimeSpan.FromDays( 2 ) );
|
||||
Register( DecayLevel.Fairly, TimeSpan.FromDays( 1 ), TimeSpan.FromDays( 2 ) );
|
||||
Register( DecayLevel.Greatly, TimeSpan.FromDays( 1 ), TimeSpan.FromDays( 2 ) );
|
||||
Register( DecayLevel.IDOC, TimeSpan.FromHours( 12 ), TimeSpan.FromHours( 24 ) );
|
||||
}
|
||||
|
||||
public static void Register( DecayLevel level, TimeSpan min, TimeSpan max )
|
||||
{
|
||||
DecayStageInfo info = new DecayStageInfo( min, max );
|
||||
|
||||
if ( m_Stages.ContainsKey( level ) )
|
||||
m_Stages[level] = info;
|
||||
else
|
||||
m_Stages.Add( level, info );
|
||||
}
|
||||
|
||||
public static bool Decays( DecayLevel level )
|
||||
{
|
||||
return m_Stages.ContainsKey( level );
|
||||
}
|
||||
|
||||
public static TimeSpan GetRandomDuration( DecayLevel level )
|
||||
{
|
||||
if ( !m_Stages.ContainsKey( level ) )
|
||||
return TimeSpan.Zero;
|
||||
|
||||
DecayStageInfo info = m_Stages[level];
|
||||
long min = info.MinDuration.Ticks;
|
||||
long max = info.MaxDuration.Ticks;
|
||||
|
||||
return TimeSpan.FromTicks( min + (long)( Utility.RandomDouble() * ( max - min ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class DecayStageInfo
|
||||
{
|
||||
private TimeSpan m_MinDuration;
|
||||
private TimeSpan m_MaxDuration;
|
||||
|
||||
public TimeSpan MinDuration
|
||||
{
|
||||
get { return m_MinDuration; }
|
||||
}
|
||||
|
||||
public TimeSpan MaxDuration
|
||||
{
|
||||
get { return m_MaxDuration; }
|
||||
}
|
||||
|
||||
public DecayStageInfo( TimeSpan min, TimeSpan max )
|
||||
{
|
||||
m_MinDuration = min;
|
||||
m_MaxDuration = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -71,6 +71,13 @@ namespace Server.Multis
|
|||
|
||||
public override bool ForceShowProperties{ get{ return ObjectPropertyList.Enabled; } }
|
||||
|
||||
private bool m_GettingProperties;
|
||||
|
||||
public bool GettingProperties
|
||||
{
|
||||
get { return m_GettingProperties; }
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
|
@ -82,7 +89,9 @@ namespace Server.Multis
|
|||
{
|
||||
list.Add( m_Owner.Public ? 1061641 : 1061642 ); // This House is Open to the Public : This is a Private Home
|
||||
|
||||
m_GettingProperties = true;
|
||||
DecayLevel level = m_Owner.DecayLevel;
|
||||
m_GettingProperties = false;
|
||||
|
||||
if ( level == DecayLevel.DemolitionPending )
|
||||
{
|
||||
|
|
|
|||
|
|
@ -609,7 +609,7 @@ namespace Server.Spells
|
|||
|
||||
if( caster != null && caster.AccessLevel == AccessLevel.Player && caster.Region.IsPartOf( typeof( Regions.Jail ) ) )
|
||||
{
|
||||
caster.SendLocalizedMessage( 1042632 ); // You'll need a better jailbreak plan then that!
|
||||
caster.SendLocalizedMessage( 1114345 ); // You'll need a better jailbreak plan than that!
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,11 +69,19 @@ namespace Server.Spells.Ninjitsu
|
|||
return false;
|
||||
}
|
||||
|
||||
private bool CasterIsMoving()
|
||||
{
|
||||
return (DateTime.Now - Caster.LastMoveTime <= Caster.ComputeMovementSpeed(Caster.Direction));
|
||||
}
|
||||
|
||||
private bool m_WasMoving;
|
||||
|
||||
public override void OnBeginCast()
|
||||
{
|
||||
base.OnBeginCast();
|
||||
|
||||
Caster.FixedEffect(0x37C4, 10, 14, 4, 3);
|
||||
m_WasMoving = CasterIsMoving();
|
||||
}
|
||||
|
||||
public override bool CheckFizzle()
|
||||
|
|
@ -112,7 +120,9 @@ namespace Server.Spells.Ninjitsu
|
|||
}
|
||||
else if (Caster is PlayerMobile)
|
||||
{
|
||||
if (GetLastAnimalForm(Caster) == -1 || DateTime.Now - Caster.LastMoveTime > Caster.ComputeMovementSpeed(Caster.Direction))
|
||||
bool skipGump = (m_WasMoving || CasterIsMoving());
|
||||
|
||||
if (GetLastAnimalForm(Caster) == -1 || !skipGump)
|
||||
{
|
||||
Caster.CloseGump(typeof(AnimalFormGump));
|
||||
Caster.SendGump(new AnimalFormGump(Caster, m_Entries, this));
|
||||
|
|
@ -120,17 +130,27 @@ namespace Server.Spells.Ninjitsu
|
|||
else
|
||||
{
|
||||
if (Morph(Caster, GetLastAnimalForm(Caster)) == MorphResult.Fail)
|
||||
{
|
||||
DoFizzle();
|
||||
}
|
||||
else
|
||||
{
|
||||
Caster.FixedParticles(0x3728, 10, 13, 2023, EffectLayer.Waist);
|
||||
Caster.Mana -= mana;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Morph(Caster, GetLastAnimalForm(Caster)) == MorphResult.Fail)
|
||||
{
|
||||
DoFizzle();
|
||||
}
|
||||
else
|
||||
{
|
||||
Caster.FixedParticles(0x3728, 10, 13, 2023, EffectLayer.Waist);
|
||||
Caster.Mana -= mana;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -189,12 +209,13 @@ namespace Server.Spells.Ninjitsu
|
|||
|
||||
m.CheckSkill(SkillName.Ninjitsu, 0.0, 37.5);
|
||||
|
||||
if (!BaseFormTalisman.EntryEnabled(m, entry.Type))
|
||||
return MorphResult.Success; // Still consumes mana, just no effect
|
||||
|
||||
BaseMount.Dismount(m);
|
||||
|
||||
m.BodyMod = entry.BodyMod;
|
||||
|
||||
if (entry.HueMod > 0)
|
||||
m.HueMod = entry.HueMod;
|
||||
m.HueMod = entry.HueMod;
|
||||
|
||||
if (entry.SpeedBoost)
|
||||
m.Send(SpeedControl.MountSpeed);
|
||||
|
|
@ -461,6 +482,7 @@ namespace Server.Spells.Ninjitsu
|
|||
}
|
||||
else
|
||||
{
|
||||
m_Caster.FixedParticles(0x3728, 10, 13, 2023, EffectLayer.Waist);
|
||||
m_Caster.Mana -= mana;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,23 +17,10 @@ namespace Server.Mobiles
|
|||
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
private Mobile m_Target;
|
||||
|
||||
public override Mobile ConstantFocus { get { return m_Target; } }
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
if( m_Target != null && (!m_Target.Alive || m_Target.Deleted || !InRange( m_Target, 24 ) || !CanSee( m_Target )) )
|
||||
m_Target = null; //Go kill other stuffs
|
||||
|
||||
base.OnThink();
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public NatureFury( Mobile target )
|
||||
public NatureFury()
|
||||
: base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
m_Target = target;
|
||||
Name = "a nature's fury";
|
||||
Body = 0x33;
|
||||
Hue = 0x4001;
|
||||
|
|
@ -62,12 +49,6 @@ namespace Server.Mobiles
|
|||
ControlSlots = 1;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public NatureFury()
|
||||
: this( null ) //Null makes it act like any other mob
|
||||
{
|
||||
}
|
||||
|
||||
public override void MoveToWorld( Point3D loc, Map map )
|
||||
{
|
||||
base.MoveToWorld( loc, map );
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using Server.Multis;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Spells.Spellweaving
|
||||
{
|
||||
|
|
@ -23,26 +23,12 @@ namespace Server.Spells.Spellweaving
|
|||
{
|
||||
}
|
||||
|
||||
private bool m_MobileTarg;
|
||||
|
||||
public override int GetMana()
|
||||
{
|
||||
int mana = base.GetMana();
|
||||
|
||||
if( m_MobileTarg )
|
||||
mana *= 2;
|
||||
|
||||
return mana;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override bool CheckCast()
|
||||
{
|
||||
if( !base.CheckCast() )
|
||||
if ( !base.CheckCast() )
|
||||
return false;
|
||||
|
||||
if( (Caster.Followers + 1) > Caster.FollowersMax )
|
||||
if ( ( Caster.Followers + 1 ) > Caster.FollowersMax )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 1049645 ); // You have too many followers to summon that creature.
|
||||
return false;
|
||||
|
|
@ -58,46 +44,29 @@ namespace Server.Spells.Spellweaving
|
|||
|
||||
public void Target( IPoint3D point )
|
||||
{
|
||||
//What happens if you cast it on yourself? OSI ANSWER: You're an idiot for wasting the mana, and it'll just look for another target.
|
||||
Mobile m = point as Mobile;
|
||||
Point3D p = new Point3D( point );
|
||||
Map map = Caster.Map;
|
||||
|
||||
m_MobileTarg = (m != null);
|
||||
if ( map == null )
|
||||
return;
|
||||
|
||||
BaseHouse house = BaseHouse.FindHouseAt( p, map, 0 );
|
||||
if ( house != null)
|
||||
if ( !house.IsFriend ( Caster ) )
|
||||
return;
|
||||
if (m != null) //say "Target can not be seen" if you target directly a mobile, like in OSI
|
||||
{
|
||||
Caster.SendLocalizedMessage( 500237 ); // Target can not be seen.
|
||||
}
|
||||
else if ( map == null || !map.CanSpawnMobile( p.X, p.Y, p.Z ) )
|
||||
HouseRegion r = Region.Find( p, map ).GetRegion( typeof( HouseRegion ) ) as HouseRegion;
|
||||
|
||||
if ( r != null && r.House != null && !r.House.IsFriend( Caster ) )
|
||||
return;
|
||||
|
||||
if ( !map.CanSpawnMobile( p.X, p.Y, p.Z ) )
|
||||
{
|
||||
Caster.SendLocalizedMessage( 501942 ); // That location is blocked.
|
||||
}
|
||||
else if( SpellHelper.CheckTown( p, Caster ) && (m_MobileTarg ? CheckHSequence( m ) : CheckSequence()) )
|
||||
else if ( SpellHelper.CheckTown( p, Caster ) && CheckSequence() )
|
||||
{
|
||||
TimeSpan duration = TimeSpan.FromSeconds( Caster.Skills.Spellweaving.Value/24 + 25 + FocusLevel*2 );
|
||||
TimeSpan duration = TimeSpan.FromSeconds( Caster.Skills.Spellweaving.Value / 24 + 25 + FocusLevel * 2 );
|
||||
|
||||
if( m == Caster )
|
||||
m = null;
|
||||
NatureFury nf = new NatureFury();
|
||||
BaseCreature.Summon( nf, false, Caster, p, 0x5CB, duration );
|
||||
|
||||
NatureFury nf = new NatureFury( m );
|
||||
|
||||
BaseCreature.Summon( nf, false, Caster, p , 0x5CB, duration );
|
||||
|
||||
Timer t = null;
|
||||
|
||||
t = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ), delegate
|
||||
{
|
||||
if( !nf.Alive || nf.Deleted || nf.DamageMin > 20 ) //sanity
|
||||
t.Stop();
|
||||
|
||||
nf.DamageMin++;
|
||||
nf.DamageMax++;
|
||||
} );
|
||||
new InternalTimer( nf ).Start();
|
||||
}
|
||||
|
||||
FinishSequence();
|
||||
|
|
@ -107,22 +76,47 @@ namespace Server.Spells.Spellweaving
|
|||
{
|
||||
private NatureFurySpell m_Owner;
|
||||
|
||||
public InternalTarget( NatureFurySpell owner ) : base( 10, true, TargetFlags.None )
|
||||
public InternalTarget( NatureFurySpell owner )
|
||||
: base( 10, true, TargetFlags.None )
|
||||
{
|
||||
m_Owner = owner;
|
||||
CheckLOS = true;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object o )
|
||||
{
|
||||
if( o is IPoint3D )
|
||||
if ( o is IPoint3D )
|
||||
m_Owner.Target( (IPoint3D)o );
|
||||
}
|
||||
|
||||
protected override void OnTargetFinish( Mobile from )
|
||||
{
|
||||
if( m_Owner != null )
|
||||
if ( m_Owner != null )
|
||||
m_Owner.FinishSequence();
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private NatureFury m_NatureFury;
|
||||
|
||||
public InternalTimer( NatureFury nf )
|
||||
: base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
|
||||
{
|
||||
m_NatureFury = nf;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( m_NatureFury.Deleted || !m_NatureFury.Alive || m_NatureFury.DamageMin > 20 )
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
++m_NatureFury.DamageMin;
|
||||
++m_NatureFury.DamageMax;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue