This commit is contained in:
mark 2009-09-06 02:06:07 +00:00
parent 4ee6ca5951
commit 06e5c8b732
70 changed files with 2798 additions and 286 deletions

View file

@ -1069,8 +1069,16 @@ namespace Server.Mobiles
{
get
{
if ( m_HitsMax >= 0 )
return m_HitsMax + GetStatOffset( StatType.Str );
if ( m_HitsMax > 0 ) {
int value = m_HitsMax + GetStatOffset( StatType.Str );
if( value < 1 )
value = 1;
else if( value > 65000 )
value = 65000;
return value;
}
return Str;
}
@ -1088,8 +1096,16 @@ namespace Server.Mobiles
{
get
{
if ( m_StamMax >= 0 )
return m_StamMax + GetStatOffset( StatType.Dex );
if ( m_StamMax > 0 ) {
int value = m_StamMax + GetStatOffset( StatType.Dex );
if( value < 1 )
value = 1;
else if( value > 65000 )
value = 65000;
return value;
}
return Dex;
}
@ -1107,8 +1123,16 @@ namespace Server.Mobiles
{
get
{
if ( m_ManaMax >= 0 )
return m_ManaMax + GetStatOffset( StatType.Int );
if ( m_ManaMax > 0 ) {
int value = m_ManaMax + GetStatOffset( StatType.Int );
if( value < 1 )
value = 1;
else if( value > 65000 )
value = 65000;
return value;
}
return Int;
}

View file

@ -192,17 +192,17 @@ namespace Server.Engines.Craft
if ( context != null )
resIndex = ( m_CraftItem.UseSubRes2 ? context.LastResourceIndex2 : context.LastResourceIndex );
bool cropScroll = ( m_CraftItem.Ressources.Count > 1 )
&& m_CraftItem.Ressources.GetAt( m_CraftItem.Ressources.Count - 1 ).ItemType == typeofBlankScroll
bool cropScroll = ( m_CraftItem.Resources.Count > 1 )
&& m_CraftItem.Resources.GetAt( m_CraftItem.Resources.Count - 1 ).ItemType == typeofBlankScroll
&& typeofSpellScroll.IsAssignableFrom( m_CraftItem.ItemType );
for ( int i = 0; i < m_CraftItem.Ressources.Count - (cropScroll ? 1 : 0) && i < 4; i++ )
for ( int i = 0; i < m_CraftItem.Resources.Count - (cropScroll ? 1 : 0) && i < 4; i++ )
{
Type type;
string nameString;
int nameNumber;
CraftRes craftResource = m_CraftItem.Ressources.GetAt( i );
CraftRes craftResource = m_CraftItem.Resources.GetAt( i );
type = craftResource.ItemType;
nameString = craftResource.NameString;
@ -240,8 +240,8 @@ namespace Server.Engines.Craft
if ( m_CraftItem.NameNumber == 1041267 ) // runebook
{
AddHtmlLocalized( 170, 219 + (m_CraftItem.Ressources.Count * 20), 310, 18, 1044447, LabelColor, false, false );
AddLabel( 430, 219 + (m_CraftItem.Ressources.Count * 20), LabelHue, "1" );
AddHtmlLocalized( 170, 219 + (m_CraftItem.Resources.Count * 20), 310, 18, 1044447, LabelColor, false, false );
AddLabel( 430, 219 + (m_CraftItem.Resources.Count * 20), LabelHue, "1" );
}
if ( cropScroll )

View file

@ -226,7 +226,7 @@ namespace Server.Engines.Craft
get { return m_NameNumber; }
}
public CraftResCol Ressources
public CraftResCol Resources
{
get { return m_arCraftRes; }
}

View file

@ -36,7 +36,7 @@ namespace Server.Engines.Craft
CraftItem craftItem = craftSystem.CraftItems.SearchFor( item.GetType() );
if ( craftItem == null || craftItem.Ressources.Count == 0 )
if ( craftItem == null || craftItem.Resources.Count == 0 )
return EnhanceResult.BadItem;
bool allRequiredSkills = false;

View file

@ -336,7 +336,7 @@ namespace Server.Engines.Craft
toDelete = true;
}
}
else if ( (targeted is BaseClothing) )
else if ( targeted is BaseClothing )
{
BaseClothing clothing = (BaseClothing)targeted;
SkillName skill = m_CraftSystem.MainSkill;
@ -358,8 +358,8 @@ namespace Server.Engines.Craft
toWeaken = 3;
}
if (m_CraftSystem.CraftItems.SearchForSubclass(clothing.GetType()) == null && !IsSpecialClothing(clothing) && !((targeted is TribalMask) || (targeted is HornedTribalMask) || targeted.GetType().IsSubclassOf(typeof(HornedTribalMask)) || targeted.GetType().IsSubclassOf(typeof(TribalMask))))
{
if (m_CraftSystem.CraftItems.SearchForSubclass(clothing.GetType()) == null && !IsSpecialClothing(clothing) && !((targeted is TribalMask) || (targeted is HornedTribalMask)) )
{
number = (usingDeed) ? 1061136 : 1044277; // That item cannot be repaired. // You cannot repair that item with this type of repair contract.
}
else if ( !clothing.IsChildOf( from.Backpack ) )

View file

@ -5,6 +5,13 @@ using Server.Items;
namespace Server.Engines.Craft
{
public enum SmeltResult
{
Success,
Invalid,
NoSkill
}
public class Resmelt
{
public Resmelt()
@ -37,27 +44,44 @@ namespace Server.Engines.Craft
m_Tool = tool;
}
private bool Resmelt( Mobile from, Item item, CraftResource resource )
private SmeltResult Resmelt( Mobile from, Item item, CraftResource resource )
{
try
{
if ( CraftResources.GetType( resource ) != CraftResourceType.Metal )
return false;
return SmeltResult.Invalid;
CraftResourceInfo info = CraftResources.GetInfo( resource );
if ( info == null || info.ResourceTypes.Length == 0 )
return false;
return SmeltResult.Invalid;
CraftItem craftItem = m_CraftSystem.CraftItems.SearchFor( item.GetType() );
if ( craftItem == null || craftItem.Ressources.Count == 0 )
return false;
if ( craftItem == null || craftItem.Resources.Count == 0 )
return SmeltResult.Invalid;
CraftRes craftResource = craftItem.Ressources.GetAt( 0 );
CraftRes craftResource = craftItem.Resources.GetAt( 0 );
if ( craftResource.Amount < 2 )
return false; // Not enough metal to resmelt
return SmeltResult.Invalid; // Not enough metal to resmelt
double difficulty = 0.0;
switch ( resource )
{
case CraftResource.DullCopper: difficulty = 65.0; break;
case CraftResource.ShadowIron: difficulty = 70.0; break;
case CraftResource.Copper: difficulty = 75.0; break;
case CraftResource.Bronze: difficulty = 80.0; break;
case CraftResource.Gold: difficulty = 85.0; break;
case CraftResource.Agapite: difficulty = 90.0; break;
case CraftResource.Verite: difficulty = 95.0; break;
case CraftResource.Valorite: difficulty = 99.0; break;
}
if ( difficulty > from.Skills[ SkillName.Mining ].Value )
return SmeltResult.NoSkill;
Type resourceType = info.ResourceTypes[0];
Item ingot = (Item)Activator.CreateInstance( resourceType );
@ -72,13 +96,13 @@ namespace Server.Engines.Craft
from.PlaySound( 0x2A );
from.PlaySound( 0x240 );
return true;
return SmeltResult.Success;
}
catch
{
}
return false;
return SmeltResult.Invalid;
}
protected override void OnTarget( Mobile from, object targeted )
@ -91,29 +115,35 @@ namespace Server.Engines.Craft
}
else
{
bool success = false;
SmeltResult result = SmeltResult.Invalid;
bool isStoreBought = false;
int message;
if ( targeted is BaseArmor )
{
success = Resmelt( from, (BaseArmor)targeted, ((BaseArmor)targeted).Resource );
result = Resmelt( from, (BaseArmor)targeted, ((BaseArmor)targeted).Resource );
isStoreBought = !((BaseArmor)targeted).PlayerConstructed;
}
else if ( targeted is BaseWeapon )
{
success = Resmelt( from, (BaseWeapon)targeted, ((BaseWeapon)targeted).Resource );
result = Resmelt( from, (BaseWeapon)targeted, ((BaseWeapon)targeted).Resource );
isStoreBought = !((BaseWeapon)targeted).PlayerConstructed;
}
else if ( targeted is DragonBardingDeed )
{
success = Resmelt( from, (DragonBardingDeed)targeted, ((DragonBardingDeed)targeted).Resource );
result = Resmelt( from, (DragonBardingDeed)targeted, ((DragonBardingDeed)targeted).Resource );
isStoreBought = false;
}
if ( success )
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, isStoreBought ? 500418 : 1044270 ) ); // You melt the item down into ingots.
else
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, 1044272 ) ); // You can't melt that down into ingots.
switch ( result )
{
default:
case SmeltResult.Invalid: message = 1044272; break; // You can't melt that down into ingots.
case SmeltResult.NoSkill: message = 1044269; break; // You have no idea how to work this metal.
case SmeltResult.Success: message = isStoreBought ? 500418 : 1044270; break; // You melt the item down into ingots.
}
from.SendGump( new CraftGump( from, m_CraftSystem, m_Tool, message ) );
}
}
}

View file

@ -0,0 +1,87 @@
using System;
using Server;
using Server.Items;
using Server.Engines.Doom;
namespace Server.Mobiles
{
[CorpseName( "a dark guardians' corpse" )]
public class DarkGuardian : BaseCreature
{
[Constructable]
public DarkGuardian() : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Name = "a dark guardian";
Body = 78;
BaseSoundID = 0x3E9;
SetStr( 125, 150 );
SetDex( 100, 120 );
SetInt( 200, 235 );
SetHits( 150, 180 );
SetDamage( 43, 48 );
SetDamageType( ResistanceType.Physical, 10 );
SetDamageType( ResistanceType.Cold, 40 );
SetDamageType( ResistanceType.Energy, 50 );
SetResistance( ResistanceType.Physical, 40, 50 );
SetResistance( ResistanceType.Fire, 20, 45 );
SetResistance( ResistanceType.Cold, 50, 60 );
SetResistance( ResistanceType.Poison, 20, 45 );
SetResistance( ResistanceType.Energy, 30, 40 );
SetSkill( SkillName.EvalInt, 40.1, 50);
SetSkill( SkillName.Magery, 50.1, 60.0 );
SetSkill( SkillName.Meditation, 85.1, 95.0 );
SetSkill( SkillName.MagicResist, 50.1, 70.0 );
SetSkill( SkillName.Tactics, 50.1, 70.0 );
Fame = 5000;
Karma = -5000;
VirtualArmor = 50;
PackNecroReg( 15, 25 );
PackItem( new DaemonBone( 30 ) );
}
public DarkGuardian( Serial serial ) : base( serial )
{
}
public override void GenerateLoot()
{
AddLoot( LootPack.Rich );
AddLoot( LootPack.MedScrolls, 2 );
}
public override OppositionGroup OppositionGroup
{
get{ return OppositionGroup.FeyAndUndead; }
}
public override int TreasureMapLevel{ get{ return 2; } }
public override bool BleedImmune{ get{ return true; } }
public override Poison PoisonImmune{ get{ return Poison.Lethal; } }
public override bool Unprovokable { get { return true; } }
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
if ( Region is GuardianRoomRegion )
Delete();
}
}
}

View file

@ -0,0 +1,599 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Regions;
using Server.Commands;
namespace Server.Engines.Doom
{
public class GuardianRoomRegion : BaseRegion
{
private static GuardianRoomRegion m_Region;
public static void Initialize()
{
CommandSystem.Register( "GenGuardianRoom", AccessLevel.Administrator, new CommandEventHandler( GenRoom_OnCommand ) );
}
[Usage( "GenGuardianRoom" )]
[Description( "Generates guardian room in doom." )]
public static void GenRoom_OnCommand( CommandEventArgs e )
{
e.Mobile.SendMessage( "Generating room, please wait." );
int count = 0;
// doors
MetalDoor north = FindItem( new GuardianRoomDoor( DoorFacing.NorthCCW ), 0, 355, 14, -1, Map.Malas, ref count ) as MetalDoor;
MetalDoor south = FindItem( new GuardianRoomDoor( DoorFacing.SouthCW ), 0, 355, 15, -1, Map.Malas, ref count ) as MetalDoor;
if ( north != null && south != null )
{
north.Link = south;
south.Link = north;
}
// pentagram center
FindItem( new Static( 0xFEA ), 0x835, 365, 15, -1, Map.Malas, ref count );
// ghost teleporters
Teleporter tele;
tele = FindItem( new GhostTeleporter(), 0x835, 354, 14, -1, Map.Malas, ref count ) as Teleporter;
if ( tele != null )
{
tele.PointDest = new Point3D( 349, 176, 14 );
tele.MapDest = Map.Malas;
}
tele = FindItem( new GhostTeleporter(), 0x835, 354, 15, -1, Map.Malas, ref count ) as Teleporter;
if ( tele != null )
{
tele.PointDest = new Point3D( 349, 176, 14 );
tele.MapDest = Map.Malas;
}
// treasure chest spawner
Spawner spawner = new Spawner( 3, 1, 5, 0, 9, "GuardianTreasureChest" );
spawner = FindItem( spawner, 0, 365, 15, 0, Map.Malas, ref count ) as Spawner;
if ( spawner != null )
{
spawner.Movable = false;
spawner.Respawn();
}
if ( count > 0 )
e.Mobile.SendMessage( "Room generating complete. {0} items were generated.", count );
else
e.Mobile.SendMessage( "Room generating complete. No changes neccessary." );
}
public static Item FindItem( Item item, int hue, int x, int y, int z, Map map, ref int count )
{
Point3D p = new Point3D( x, y, z );
Type type = item.GetType();
foreach ( Item i in map.GetItemsInRange( p, 0 ) )
{
if ( i.GetType() == type && i.ItemID == item.ItemID && i.Hue == hue )
{
item.Delete();
return i;
}
}
count++;
item.MoveToWorld( p, map );
if ( hue > 0 )
item.Hue = hue;
return item;
}
private BaseDoor m_Door;
private List<Mobile> m_Dead;
private Timer m_Timer;
private int m_LightLevel;
public List<Mobile> Dead
{
get { return m_Dead; }
}
public bool Active
{
get { return m_Timer != null && m_Timer.Running; }
}
private static Rectangle2D[] m_Bounds = new Rectangle2D[]
{
new Rectangle2D( new Point2D( 356, 5 ), new Point2D( 375, 25 ) )
};
public GuardianRoomRegion( BaseDoor door ) : base( "NorthDoomPoisonRoom", Map.Malas, 51, m_Bounds )
{
m_Door = door;
m_Dead = new List<Mobile>();
m_LightLevel = LightCycle.DungeonLevel;
m_Guardians = new List<Mobile>();
ExcludeFromParentSpawns = true;
}
public override void OnEnter( Mobile m )
{
if ( !Active && IsTrappable( m, true ) )
m_Timer = Timer.DelayCall( TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 35 ) ), new TimerCallback( StartTrap ) );
}
public override void OnDeath( Mobile m )
{
base.OnDeath( m );
if ( m.IsDeadBondedPet || ( m.Player && m.AccessLevel == AccessLevel.Player ) )
m_Dead.Add( m );
if ( m is DarkGuardian )
m_Guardians.Remove( m );
if ( m_Guardians.Count == 0 )
Timer.DelayCall( TimeSpan.FromSeconds( 5 ), new TimerCallback( StopTrap ) );
List<Mobile> list = GetPoisonableMobiles();
list.Remove( m );
if ( list.Count == 0 )
Timer.DelayCall( TimeSpan.FromSeconds( 5 ), new TimerCallback( StopTrap ) );
}
public override void AlterLightLevel( Mobile m, ref int global, ref int personal )
{
global = m_LightLevel;
}
public virtual void PoisonMobiles( Poison poison, int ticks )
{
List<Mobile> list = GetPoisonableMobiles();
int number = 0;
int hue = 0x485;
if ( ticks % 12 == 0 ) // every 60 seconds
{
switch ( poison.Level )
{
// It is becoming more difficult for you to breathe as the poisons in the room become more concentrated.
case 1: number = 1050001; break;
// You begin to panic as the poison clouds thicken.
case 2: number = 1050003; break;
// Terror grips your spirit as you realize you may never leave this room alive.
case 3: number = 1050056; break;
case 4:
if ( ticks < 50 )
{
number = 1050057; // The end is near. You feel hopeless and desolate. The poison is beginning to stiffen your muscles.
}
else
{
hue = 0x23F3;
number = 1062091; // The poison is becoming too much for you to bear. You fear that you may die at any moment.
}
break;
}
}
foreach ( Mobile m in list )
{
if ( m.Player && number > 0 )
m.SendLocalizedMessage( number, null, hue );
if ( ( m.Poison == null || m.Poison.Level < poison.Level ) )
m.ApplyPoison( null, poison );
}
}
public virtual void HurtMobiles( int level )
{
foreach ( Mobile m in GetPoisonableMobiles() )
{
if ( m.Player )
{
m.Say( 1062092 ); // Your body reacts violently from the pain.
m.Animate( 32, 5, 1, true, false, 0 );
}
m.Damage( Utility.Random( 15, 20 ) );
if ( level >= 10 )
m.Kill();
}
}
public virtual List<Mobile> GetPoisonableMobiles()
{
List<Mobile> list = new List<Mobile>();
foreach ( Mobile m in GetMobiles() )
{
if ( IsTrappable( m, false ) )
list.Add( m );
}
return list;
}
public virtual bool IsTrappable( Mobile m, bool trapStart )
{
if ( m.Alive )
{
if ( m.Player && m.AccessLevel == AccessLevel.Player )
return true;
BaseCreature bc = m as BaseCreature;
if ( bc != null )
{
Mobile master = null;
if ( bc.Controlled && bc.ControlMaster != null )
master = bc.ControlMaster;
else if ( !trapStart && bc.Summoned && bc.SummonMaster != null )
master = bc.SummonMaster;
if ( master != null )
return master.Player && master.AccessLevel == AccessLevel.Player;
}
}
return false;
}
public virtual bool CanStart( List<Mobile> list )
{
foreach ( Mobile m in list )
if ( IsTrappable( m, true ) )
return true;
return false;
}
public virtual void RestartTrap()
{
if ( !Active )
StartTrap();
}
public virtual void StartTrap()
{
List<Mobile> list = GetPoisonableMobiles();
if ( !CanStart( list ) )
return;
m_Timer = new PoisonRoomTimer( this );
m_Timer.Start();
if ( m_Door != null )
{
m_Door.Locked = true;
m_Door.Open = false;
if ( m_Door.Link != null )
{
m_Door.Link.Locked = true;
m_Door.Link.Open = false;
Effects.PlaySound( m_Door.Link.Location, Map, 0x1FF );
}
Effects.PlaySound( m_Door.Location, Map, 0x1FF );
}
foreach ( Mobile m in list )
m.SendLocalizedMessage( 1050000, null, 0x41 ); // The locks on the door click loudly and you begin to hear a faint hissing near the walls.
for ( int i = m_Dead.Count - 1; i >= 0; i-- )
if ( m_Dead[ i ].Alive )
m_Dead.RemoveAt( i );
SpawnGuardians( list.Count * 2 );
}
public virtual void StopTrap()
{
Timer.DelayCall( TimeSpan.FromSeconds( Utility.RandomMinMax( 30, 60 ) ), new TimerCallback( RestartTrap ) );
if ( m_Door != null )
{
m_Door.Locked = false;
if ( m_Door.Link != null )
{
m_Door.Link.Locked = false;
Effects.PlaySound( m_Door.Link.Location, Map, 0x1FF );
}
Effects.PlaySound( m_Door.Location, Map, 0x1FF );
}
if ( m_Timer != null && m_Timer.Running )
m_Timer.Stop();
foreach ( Mobile m in GetPlayers() )
m.SendLocalizedMessage( 1050055, null, 0x41 ); // You hear the doors unlocking and the hissing stops.
ClearGuardians();
}
#region Spawns
private List<Mobile> m_Guardians;
public void SpawnGuardians( int amount )
{
for ( int i = 0; i < amount; ++i )
{
DarkGuardian guardian = new DarkGuardian();
switch ( Utility.Random( 4 ) )
{
case 0: guardian.MoveToWorld( new Point3D( 364, 15, -1 ), Map.Malas ); break;
case 1: guardian.MoveToWorld( new Point3D( 366, 15, -1 ), Map.Malas ); break;
case 2: guardian.MoveToWorld( new Point3D( 365, 14, -1 ), Map.Malas ); break;
case 3: guardian.MoveToWorld( new Point3D( 365, 16, -1 ), Map.Malas ); break;
}
m_Guardians.Add( guardian );
}
}
public void ClearGuardians()
{
foreach ( Mobile m in m_Guardians )
{
if ( m.Alive && !m.Deleted )
{
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
Effects.PlaySound( m, m.Map, 0x201 );
m.Delete();
}
}
m_Guardians.Clear();
}
#endregion
#region Effects
private static Point3D[] m_GasLocations = new Point3D[]
{
// west
new Point3D( 356, 7, -1 ), new Point3D( 356, 13, -1 ),
new Point3D( 356, 16, -1 ), new Point3D( 356, 22, -1 ),
// north
new Point3D( 358, 6, -1 ), new Point3D( 363, 6, -1 ),
new Point3D( 368, 6, -1 ), new Point3D( 373, 6, -1 )
};
public virtual void DoGasEffect()
{
for ( int i = Utility.RandomMinMax( 2, 4 ); i > 0; i-- )
{
int pos = Utility.Random( m_GasLocations.Length );
int itemID;
if ( pos <= 3 )
itemID = 0x1145;
else
itemID = 0x113A;
Effects.SendLocationParticles( EffectItem.Create( m_GasLocations[ pos ], Map, EffectItem.DefaultDuration ), itemID, 1, 100, 0, 4, 0x139D, 0 );
}
}
private static int[] m_PoisonEffects = new int[]
{
0x36B0, 0x36BD, 0x36CB
};
public virtual void DoPoisonEffect( int level )
{
int hue = 0;
switch ( level )
{
default:
case 0: hue = 0xA6; break;
case 1: hue = 0xAA; break;
case 2: hue = 0xAC; break;
case 3: hue = 0xA8; break;
case 4: hue = 0xA4; break;
}
for ( int i = Utility.RandomMinMax( 5, 7 ); i > 0; i-- )
{
Point3D p = RandomSpawnLocation( 0, true, true, Point3D.Zero, 0 );
if ( p != Point3D.Zero )
{
IEntity e = EffectItem.Create( p, Map, EffectItem.DefaultDuration );
int itemID = Utility.RandomList( m_PoisonEffects );
int duration = Utility.RandomMinMax( 150, 200 );
Effects.SendLocationParticles( e, itemID, 1, duration, hue, 0, 0x139D, 0 );
}
}
}
#endregion
public class PoisonRoomTimer : Timer
{
private GuardianRoomRegion m_Room;
private int m_Count;
public PoisonRoomTimer( GuardianRoomRegion room ) : base( TimeSpan.FromSeconds( 1 ), TimeSpan.FromSeconds( 1 ) )
{
m_Room = room;
m_Count = 0;
}
public int CurrentPoisonLevel()
{
int poisonLevel = 1 + m_Count / 20;
if ( poisonLevel > 4 )
poisonLevel = 4;
return poisonLevel;
}
protected override void OnTick()
{
m_Count++;
if ( m_Count % 5 == 0 && m_Room.Active )
{
int level = CurrentPoisonLevel();
m_Room.PoisonMobiles( Poison.GetPoison( level ), m_Count / 5 );
}
if ( m_Count % 8 == 0 && m_Room.Active )
{
m_Room.DoPoisonEffect( CurrentPoisonLevel() );
m_Room.DoGasEffect();
}
if ( m_Count >= 720 && m_Count % 10 == 0 && m_Room.Active )
m_Room.HurtMobiles( ( m_Count - 720 ) / 10 );
}
}
public class GhostTeleporter : Teleporter
{
private static BaseRegion m_GhostRegion;
private static Rectangle2D[] m_GhostRegionBounds = new Rectangle2D[]
{
new Rectangle2D( new Point2D( 345, 180 ), new Point2D( 352, 184 ) ),
new Rectangle2D( new Point2D( 342, 172 ), new Point2D( 344, 181 ) ),
new Rectangle2D( new Point2D( 345, 169 ), new Point2D( 352, 172 ) )
};
[Constructable]
public GhostTeleporter() : base()
{
Name = "GhostTeleporter";
if ( m_GhostRegion == null )
{
m_GhostRegion = new BaseRegion( "DoomGhostTeleportRegion", Map.Malas, 55, m_GhostRegionBounds );
m_GhostRegion.Register();
}
}
public GhostTeleporter( Serial serial ) : base( serial )
{
}
public override bool OnMoveOver( Mobile m )
{
if ( !DiedInside( m ) )
return true;
return base.OnMoveOver( m );
}
public bool DiedInside( Mobile m )
{
bool valid = false;
if ( m_Region != null )
valid = m_Region.Dead.Remove( m );
return valid && !m.Alive;
}
public override void DoTeleport( Mobile m )
{
if ( m.Corpse != null && !m.Corpse.Deleted )
{
Point3D location = Point3D.Zero;
if ( m_GhostRegion != null )
location = m_GhostRegion.RandomSpawnLocation( 0, true, false, Point3D.Zero, 0 );
if ( location == Point3D.Zero )
location = new Point3D( 349, 176, 14 );
m.Corpse.MoveToWorld( location, Map.Malas );
m.MoveToWorld( location, Map.Malas );
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
if ( m_GhostRegion == null )
{
m_GhostRegion = new BaseRegion( "DoomGhostTeleportRegion", Map.Malas, 55, m_GhostRegionBounds );
m_GhostRegion.Register();
}
}
}
public class GuardianRoomDoor : MetalDoor
{
public GuardianRoomDoor( DoorFacing facing ) : base( facing )
{
if ( m_Region == null )
{
m_Region = new GuardianRoomRegion( this );
m_Region.Register();
}
}
public GuardianRoomDoor( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
Locked = false;
if ( m_Region == null )
{
m_Region = new GuardianRoomRegion( this );
m_Region.Register();
}
}
}
}
}

View file

@ -0,0 +1,179 @@
using System;
using Server;
using Server.Engines.Doom;
namespace Server.Items
{
public class GuardianTreasureChest : LockableContainer
{
private const int m_Level = 6;
public override bool Decays { get { return true; } }
public override int DefaultGumpID { get { return 0x42; } }
public override int DefaultDropSound { get { return 0x42; } }
public override Rectangle2D Bounds
{
get { return new Rectangle2D( 18, 105, 144, 73 ); }
}
private Timer m_DecayTimer;
[Constructable]
public GuardianTreasureChest() : base( 0xE41 )
{
SetChestAppearance();
Movable = false;
/* TrapType = TrapType.ExplosionTrap;
TrapPower = m_Level * Utility.Random( 20, 35 );*/
Locked = true;
RequiredSkill = 99;
LockLevel = RequiredSkill - Utility.Random( 1, 10 );
MaxLockLevel = RequiredSkill + 21;
// According to OSI, loot in level 4 chest is:
// Gold 500 - 900
// Reagents
// Scrolls
// Blank scrolls
// Potions
// Gems
// Magic Wand
// Magic weapon
// Magic armour
// Magic clothing (not implemented)
// Magic jewelry (not implemented)
// Crystal ball (not implemented)
// Gold
DropItem( new Gold( Utility.Random( 300, 325 ) ) );
// Reagents
for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- )
{
Item ReagentLoot = Loot.RandomReagent();
ReagentLoot.Amount = 12;
DropItem( ReagentLoot );
}
// Scrolls
for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- )
{
Item ScrollLoot = Loot.RandomScroll( 0, 47, SpellbookType.Regular );
ScrollLoot.Amount = 16;
DropItem( ScrollLoot );
}
// Drop blank scrolls
DropItem( new BlankScroll( Utility.Random( 1, m_Level ) ) );
// Potions
for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- )
{
Item PotionLoot = Loot.RandomPotion();
DropItem( PotionLoot );
}
// Gems
for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- )
{
Item GemLoot = Loot.RandomGem();
GemLoot.Amount = 15;
DropItem( GemLoot );
}
// Magic Wand
for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- )
DropItem( Loot.RandomWand() );
// Equipment
for ( int i = Utility.Random( 1, m_Level ); i > 1; i-- )
{
Item item = Loot.RandomArmorOrShieldOrWeapon();
if ( item is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon) item;
weapon.DamageLevel = (WeaponDamageLevel) Utility.Random( m_Level );
weapon.AccuracyLevel = (WeaponAccuracyLevel) Utility.Random( m_Level );
weapon.DurabilityLevel = (WeaponDurabilityLevel) Utility.Random( m_Level );
weapon.Quality = WeaponQuality.Regular;
}
else if ( item is BaseArmor )
{
BaseArmor armor = (BaseArmor) item;
armor.ProtectionLevel = (ArmorProtectionLevel) Utility.Random( m_Level );
armor.Durability = (ArmorDurabilityLevel) Utility.Random( m_Level );
armor.Quality = ArmorQuality.Regular;
}
DropItem( item );
}
// Clothing
for ( int i = Utility.Random( 1, 2 ); i > 1; i-- )
DropItem( Loot.RandomClothing() );
// Jewelry
for ( int i = Utility.Random( 1, 2 ); i > 1; i-- )
DropItem( Loot.RandomJewelry() );
// Crystal ball (not implemented)
m_DecayTimer = Timer.DelayCall( TimeSpan.FromMinutes( Utility.RandomMinMax( 1, 5 ) ), new TimerCallback( Delete ) );
}
private void SetChestAppearance()
{
bool facing = Utility.RandomBool();
switch ( Utility.RandomList( 0, 1, 2 ) )
{
case 0:// Wooden Chest
ItemID = ( facing ? 0xE42 : 0xE43 );
GumpID = 0x49;
break;
case 1:// Metal Chest
ItemID = ( facing ? 0x9AB : 0xE7C );
GumpID = 0x4A;
break;
case 2:// Metal Golden Chest
ItemID = ( facing ? 0xE40 : 0xE41 );
GumpID = 0x42;
break;
}
}
public override void OnAfterDelete()
{
if ( m_DecayTimer != null || m_DecayTimer.Running )
m_DecayTimer.Stop();
m_DecayTimer = null;
}
public GuardianTreasureChest( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_DecayTimer = Timer.DelayCall( TimeSpan.FromMinutes( Utility.RandomMinMax( 1, 5 ) ), new TimerCallback( Delete ) );
}
}
}

View file

@ -0,0 +1,230 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Mobiles;
using Server.Regions;
using Server.Spells.Fourth;
using Server.Spells.Sixth;
using Server.Spells.Seventh;
using Server.Spells.Chivalry;
namespace Server.Misc
{
public class PoisonRoom
{
public virtual int GasEffects { get { return 3; } }
public virtual double TimePerPoisonCast { get { return 3; } }
public virtual int TicksPerPoisonLevel { get { return 15; } }
public virtual Poison MinPoisonLevel { get { return Poison.Lesser; } }
public virtual Poison MaxPoisonLevel { get { return Poison.Lethal; } }
public virtual int GasEffectHeight { get { return 0; } }
public virtual bool HasPoisonSoundEffect { get { return true; } }
protected PoisonRoomRegion m_Region;
protected PoisonRoomTimer m_Timer;
protected int m_EffectHue = 1166;
protected int m_EffectId = 4518;
protected int m_EffectDuration = 16;
protected List<Mobile> m_Dead;
public List<Mobile> Dead
{
get { return m_Dead; }
}
public PoisonRoom( string name, Map map, int priority, Rectangle2D[] rect, int LightLevel )
{
m_Region = new PoisonRoomRegion( this, name, map, priority, rect, LightLevel );
m_Region.Register();
m_Dead = new List<Mobile>();
}
public virtual void OnEnter( Mobile m )
{
if ( m.AccessLevel == AccessLevel.Player && m_Timer == null )
StartGas();
}
public virtual void OnPoison( Poison poison, int tick )
{
}
public virtual void StartGas()
{
m_Timer = new PoisonRoomTimer( this );
m_Timer.Start();
}
public virtual void StopGas()
{
if ( m_Timer != null )
m_Timer.Stop();
m_Timer = null;
}
public virtual void OnExit( Mobile m )
{
if ( GetPoisonableMobiles( m ).Count == 0 )
{
StopGas();
return;
}
}
public virtual void OnDeath( Mobile m )
{
m_Dead.Add( m );
}
public virtual void DoGasEffect()
{
for ( int i = 0; i < this.GasEffects; ++i )
RandomGasEffect();
}
public virtual void RandomGasEffect()
{
Point3D location = m_Region.RandomSpawnLocation( GasEffectHeight, true, true, Point3D.Zero, 0 );
if ( location != Point3D.Zero )
{
Effects.SendLocationEffect( location, m_Region.Map, 4518, 16, 1, 1166, 0 );
if ( HasPoisonSoundEffect )
Effects.PlaySound( location, m_Region.Map, 0x231 );
}
}
public virtual void PoisonPlayers( Poison poison )
{
List<Mobile> list = GetPoisonableMobiles( null );
foreach ( Mobile m in list )
{
if ( ( m.Poison == null || m.Poison.Level < poison.Level ) )
m.ApplyPoison( null, poison );
}
}
public int CurrentPoisonLevel()
{
if ( m_Timer != null )
return m_Timer.CurrentPoisonLevel();
return 0;
}
protected virtual bool IsPoisonable( Mobile m )
{
if ( m.AccessLevel == AccessLevel.Player && m.CheckAlive() && ( m.Player || ( m is BaseCreature && ((BaseCreature)m).Controlled ) ) )
return true;
return false;
}
public virtual List<Mobile> GetPoisonableMobiles( Mobile toexclude )
{
List<Mobile> list = new List<Mobile>();
List<Mobile> templist = m_Region.GetMobiles();
foreach ( Mobile m in templist )
{
if ( IsPoisonable( m ) )
list.Add( m );
}
if ( toexclude != null )
list.Remove( toexclude );
return list;
}
public class PoisonRoomTimer : Timer
{
private PoisonRoom m_Room;
private int m_Count = 0;
public PoisonRoomTimer( PoisonRoom room ) : base( TimeSpan.FromSeconds( 0 ), TimeSpan.FromSeconds( room.TimePerPoisonCast ) )
{
m_Room = room;
}
public int CurrentPoisonLevel()
{
int poisonLevel = m_Room.MinPoisonLevel.Level + m_Count / m_Room.TicksPerPoisonLevel;
if ( poisonLevel > m_Room.MaxPoisonLevel.Level )
poisonLevel = m_Room.MaxPoisonLevel.Level;
return poisonLevel;
}
protected override void OnTick()
{
m_Count++;
int poisonLevel = CurrentPoisonLevel();
m_Room.OnPoison( Poison.GetPoison( poisonLevel ), m_Count );
m_Room.PoisonPlayers( Poison.GetPoison( poisonLevel ) );
m_Room.DoGasEffect();
}
}
public class PoisonRoomRegion : BaseRegion
{
private PoisonRoom m_Room;
private int m_LightLevel;
public PoisonRoomRegion( PoisonRoom room, string name, Map map, int priority, Rectangle2D[] rect, int lightlevel ) : base( name, map, priority, rect )
{
ExcludeFromParentSpawns = true;
m_Room = room;
m_LightLevel = lightlevel;
}
public override void OnEnter( Mobile m )
{
base.OnEnter( m );
m_Room.OnEnter( m );
}
public override void OnExit( Mobile m )
{
base.OnExit( m );
m_Room.OnExit( m );
}
public override void OnDeath( Mobile m )
{
base.OnDeath( m );
m_Room.OnDeath( m );
}
public override bool OnResurrect( Mobile from )
{
return true;
}
public override void AlterLightLevel( Mobile m, ref int global, ref int personal )
{
global = m_LightLevel;
}
public override bool OnBeginSpellCast( Mobile m, ISpell s )
{
if ( ( s is MarkSpell || s is GateTravelSpell || s is RecallSpell || s is SacredJourneySpell ) && m.AccessLevel == AccessLevel.Player )
{
m.SendLocalizedMessage( 501802 ); // Thy spell doth not appear to work...
return false;
}
return base.OnBeginSpellCast( m, s );
}
}
}
}

View file

@ -0,0 +1,744 @@
using System;
using System.Collections;
using Server.Commands;
using Server;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class LampController : Item
{
public static void Initialize()
{
CommandSystem.Register( "GenLampPuzzle", AccessLevel.Administrator, new CommandEventHandler( GenLampPuzzle_OnCommand ) );
}
[Usage( "GenLampPuzzle" )]
[Description( "Generates lamp room puzzle in doom." )]
public static void GenLampPuzzle_OnCommand( CommandEventArgs e )
{
e.Mobile.SendMessage( "Generating puzzle, please wait." );
Point3D loc = new Point3D( 324, 64, -1 );
bool exists = false;
foreach ( Item item in Map.Malas.GetItemsInRange( loc, 0 ) )
{
if ( item is LampController )
{
exists = true;
break;
}
}
if ( !exists )
{
LampController controller = new LampController();
controller.MoveToWorld( loc, Map.Malas );
e.Mobile.SendMessage( "Puzzle generating complete. Puzzle were generated." );
}
else
e.Mobile.SendMessage( "Puzzle generating complete. Puzzle aleardy exists." );
}
public Rectangle2D Rect = new Rectangle2D( 464, 91, 10, 10 );
public PoisonTimer m_Timer;
private string m_Code;
private string m_PuzzleCode;
[CommandProperty( AccessLevel.GameMaster )]
public string PuzzleCode { get { return m_PuzzleCode; } set { m_PuzzleCode = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public string Code
{
get { return m_Code; }
set
{
m_Code = value;
if ( m_Code.Length == 4 )
{
CheckCode();
}
}
}
private ArrayList m_Levers;
private ArrayList m_Statues;
private ArrayList m_Pads;
private PuzzleBox m_Box;
private bool m_CanActive;
[CommandProperty( AccessLevel.GameMaster )]
public bool CanActive { get { return m_CanActive; } set { m_CanActive = value; } }
private bool Check()
{
foreach ( Item item in World.Items.Values )
{
if ( item is LampController && !item.Deleted && item != this )
{
return true;
}
}
return false;
}
[Constructable]
public LampController() : base( 0x1BC3 )
{
if ( Check() )
{
World.Broadcast( 0x35, true, "Another Lamp's room controller exists in the world!" );
Delete();
return;
}
Visible = false;
Movable = false;
Setup();
}
public void Setup()
{
m_CanActive = true;
m_Code = "";
m_PuzzleCode = "";
m_Levers = new ArrayList();
m_Statues = new ArrayList();
m_Pads = new ArrayList();
PuzzleLever lever1 = new PuzzleLever( 1 );
lever1.Controller = this;
lever1.MoveToWorld( new Point3D( 316, 64, 5 ), Map.Malas );
m_Levers.Add( lever1 );
PuzzleLever lever2 = new PuzzleLever( 2 );
lever2.Controller = this;
lever2.MoveToWorld( new Point3D( 323, 58, 5 ), Map.Malas );
m_Levers.Add( lever2 );
PuzzleLever lever3 = new PuzzleLever( 3 );
lever3.Controller = this;
lever3.MoveToWorld( new Point3D( 332, 63, 5 ), Map.Malas );
m_Levers.Add( lever3 );
PuzzleLever lever4 = new PuzzleLever( 4 );
lever4.Controller = this;
lever4.MoveToWorld( new Point3D( 323, 71, 5 ), Map.Malas );
m_Levers.Add( lever4 );
PuzzleStatue statue1 = new PuzzleStatue( 0x12D8 );
statue1.MoveToWorld( new Point3D( 319, 70, 18 ), Map.Malas );
m_Statues.Add( statue1 );
PuzzleStatue statue2 = new PuzzleStatue( 0x12D9 );
statue2.MoveToWorld( new Point3D( 329, 60, 18 ), Map.Malas );
m_Statues.Add( statue2 );
PuzzlePad pad1 = new PuzzlePad();
pad1.MoveToWorld( new Point3D( 324, 58, -1 ), Map.Malas );
pad1.Visible = false;
m_Pads.Add( pad1 );
PuzzlePad pad2 = new PuzzlePad();
pad2.MoveToWorld( new Point3D( 332, 64, -1 ), Map.Malas );
pad2.Visible = false;
m_Pads.Add( pad2 );
PuzzlePad pad3 = new PuzzlePad();
pad3.MoveToWorld( new Point3D( 323, 72, -1 ), Map.Malas );
pad3.Visible = false;
m_Pads.Add( pad3 );
PuzzlePad pad4 = new PuzzlePad();
pad4.MoveToWorld( new Point3D( 316, 65, -1 ), Map.Malas );
pad4.Visible = false;
m_Pads.Add( pad4 );
PuzzlePad pad5 = new PuzzlePad();
pad5.MoveToWorld( new Point3D( 324, 64, -1 ), Map.Malas );
m_Pads.Add( pad5 );
Teleporter teleporter1 = new Teleporter();
teleporter1.MapDest = Map.Malas;
teleporter1.PointDest = new Point3D( 353, 172, -1 );
teleporter1.MoveToWorld( new Point3D( 468, 92, -1 ), Map.Malas );
Teleporter teleporter2 = new Teleporter();
teleporter2.MapDest = Map.Malas;
teleporter2.PointDest = new Point3D( 353, 172, -1 );
teleporter2.MoveToWorld( new Point3D( 469, 92, -1 ), Map.Malas );
Teleporter teleporter3 = new Teleporter();
teleporter3.MapDest = Map.Malas;
teleporter3.PointDest = new Point3D( 353, 172, -1 );
teleporter3.MoveToWorld( new Point3D( 470, 92, -1 ), Map.Malas );
m_Box = new PuzzleBox();
m_Box.CanSummon = true;
m_Box.MoveToWorld( new Point3D( 469, 96, 6 ), Map.Malas );
m_PuzzleCode = GenerateCode( m_PuzzleCode );
}
public void ClearRoom()
{
IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( Rect );
ArrayList list = new ArrayList();
foreach ( object obj in eable )
{
if ( obj is Mobile )
{
Mobile mobile = obj as Mobile;
list.Add( mobile );
}
}
for ( int i = 0; i < list.Count; i++ )
{
Mobile m = list[ i ] as Mobile;
if ( m is WandererOfTheVoid )
{
m.Delete();
}
else
{
Rectangle2D rect = new Rectangle2D( 342, 168, 16, 16 );
int x = Utility.Random( rect.X, rect.Width );
int y = Utility.Random( rect.Y, rect.Height );
if ( x >= 345 && x <= 352 && y >= 173 && y <= 179 )
{
x = 353;
y = 172;
}
m.MoveToWorld( new Point3D( x, y, -1 ), Map.Malas );
}
}
if ( m_Timer != null )
{
m_Timer.Stop();
}
m_CanActive = true;
m_Box.CanSummon = true;
m_PuzzleCode = "";
m_PuzzleCode = GenerateCode( m_PuzzleCode );
}
public static string[] m_Combinations = new string[] { "1234", "1243", "1324", "1342", "1423", "1432", "2134", "2143", "2314", "2341", "2413", "2431", "3124", "3142", "3214", "3241", "3412", "3421", "4123", "4132", "4213", "4231", "4312", "4321" };
public void FreeLevers()
{
for ( int i = 0; i < m_Levers.Count; i++ )
{
PuzzleLever lever = m_Levers[ i ] as PuzzleLever;
lever.ItemID = 0x108E;
}
m_Code = "";
Timer.DelayCall( TimeSpan.FromSeconds( 30.0 ), new TimerCallback( SayQuitMessage ) );
}
public void SayQuitMessage()
{
SayStatues( 1062053, -1 ); // The sands of time have run their course.
for ( int i = 0; i < m_Levers.Count; i++ )
{
PuzzleLever lever = m_Levers[ i ] as PuzzleLever;
lever.ItemID = 0x108E;
}
}
public static string GenerateCode( string puzzle )
{
// at OSI code scheme is right order of pressed levers
// any press at any of 4 levers is one bit of code
// orientation of lever doesn't play any role
// code can't have equal numbers in it, only different, i.e: 1-4-2-3, no 1-1-1-1
// so, we have 24 combinations for solving
string old_code = puzzle;
string new_code = "";
while ( new_code == old_code )
{
new_code = m_Combinations[ Utility.Random( m_Combinations.Length ) ];
}
return new_code;
}
public int CompareCodes( string puzzle, string player )
{
int result = 0;
if ( puzzle.Length != player.Length || puzzle.Length > 4 || player.Length > 4 )
{
return 0;
}
for ( int i = 0; i < puzzle.Length; i++ )
{
if ( puzzle[ i ] == player[ i ] )
{
result++;
}
}
return result;
}
public void SayStatues( int message, int souls )
{
string args = "";
if ( souls != -1 )
{
args = souls.ToString();
}
for ( int i = 0; i < m_Statues.Count; i++ )
{
PuzzleStatue statue = m_Statues[ i ] as PuzzleStatue;
if ( statue != null )
{
statue.PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, message, args );
}
}
}
public void CheckCode()
{
bool incomplete = false;
int correct_souls = 0;
for ( int i = 0; i < m_Pads.Count; i++ )
{
PuzzlePad pad = m_Pads[ i ] as PuzzlePad;
if ( pad == null || !pad.Busy )
{
incomplete = true;
}
}
correct_souls = CompareCodes( m_PuzzleCode, m_Code );
if ( incomplete )
{
SayStatues( 1050004, -1 ); // The circle is the key, the key is incomplete and so the gate remains closed.
}
else
{
// we don't guess code
if ( correct_souls >= 0 && correct_souls < 4 )
{
ArrayList players = new ArrayList();
for ( int i = 0; i < m_Pads.Count; i++ )
{
PuzzlePad pad = m_Pads[ i ] as PuzzlePad;
if ( pad != null && pad.Stander != null && pad.Stander.Alive )
{
players.Add( pad.Stander );
}
}
for ( int j = 0; j < players.Count; j++ )
{
PlayerMobile player = players[ j ] as PlayerMobile;
if ( player != null )
{
Point3D location1 = player.Location;
location1.Z = 49;
Point3D location2 = player.Location;
location2.Z = -1;
Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.Moving, Serial.Zero, player.Serial, 0x11B7, location1, location2, 20, 0, true, true, 0, 0 ) );
Effects.PlaySound( new Point3D( 324, 64, -1 ), Map.Malas, 0x144 );
Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), Map.Malas, Utility.RandomList( 0x154, 0x14B ) );
player.Send( new AsciiMessage( Serial.MinusOne, 0xFFFF, MessageType.Label, 0x66D, 3, "", "You are pinned down by the weight of the boulder!!!" ) );
}
}
switch ( correct_souls )
{
case 0:
SayStatues( 1050009, correct_souls );
break; // The circle of souls has failed to turn the key. The gate remains closed...
case 1:
SayStatues( 1050007, correct_souls );
break; // ~1_NUM~ soul has turned the key correctly, but the rest have forsaken the circle...
default:
SayStatues( 1050008, correct_souls );
break; // ~1_NUM~ souls have turned the key correctly, but the rest have forsaken the circle...
}
for ( int j = 0; j < players.Count; j++ )
{
PlayerMobile player = players[ j ] as PlayerMobile;
if ( player != null )
{
Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.FixedXYZ, Serial.Zero, Serial.Zero, 0x36BD, new Point3D( player.X, player.Y, 0 ), new Point3D( player.X, player.Y, 0 ), 20, 10, true, false, 0, 0 ) );
Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.FixedFrom, player.Serial, Serial.Zero, 0x36BD, new Point3D( player.X, player.Y, -1 ), new Point3D( player.X, player.Y, -1 ), 20, 10, true, false, 0, 0 ) );
Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), player.Map, 0x307 );
for ( int k = 0; k < 5; k++ )
{
Effects.SendPacket( player, player.Map, new HuedEffect( EffectType.Moving, Serial.Zero, Serial.Zero, 0x1363 + Utility.Random( 0, 11 ), new Point3D( player.X, player.Y, 0 ), new Point3D( player.X, player.Y, 0 ), 5, 0, false, false, 0, 0 ) );
Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), Map.Malas, 0x13F );
Effects.PlaySound( new Point3D( player.X, player.Y, -1 ), Map.Malas, 0x154 );
player.Say( "OUCH!" );
}
player.Damage( 90, null );
player.Send( new AsciiMessage( Serial.MinusOne, 0xFFFF, MessageType.Label, 0x66D, 3, "", "A speeding rock hits you in the head!" ) );
player.SendLocalizedMessage( 502382 ); // You can move!
}
}
}
else
{
// we done it!
PlayerMobile center = ( (PuzzlePad) m_Pads[ 4 ] ).Stander;
for ( int i = 0; i < m_Pads.Count; i++ )
{
PuzzlePad pad = m_Pads[ i ] as PuzzlePad;
if ( pad != null && pad.Stander != null && pad.Stander.Alive )
{
Effects.SendPacket( pad.Stander, Map.Malas, new HuedEffect( EffectType.FixedXYZ, Serial.Zero, Serial.Zero, 0x1153, new Point3D( 325, 64, -1 ), new Point3D( 325, 64, -1 ), 1, 60, true, false, 0, 0 ) );
Effects.SendPacket( pad.Stander, Map.Malas, new HuedEffect( EffectType.FixedXYZ, Serial.Zero, Serial.Zero, 0x1153, new Point3D( 325, 64, -1 ), new Point3D( 325, 64, -1 ), 1, 60, true, false, 0, 0 ) );
Effects.PlaySound( new Point3D( 325, 64, -1 ), Map.Malas, 0x244 );
if ( center != null )
{
Effects.SendPacket( pad.Stander, Map.Malas, new HuedEffect( EffectType.Lightning, center.Serial, Serial.Zero, 0x0, new Point3D( 324, 64, -1 ), new Point3D( 324, 64, -1 ), 0, 0, false, false, 0, 0 ) );
Effects.SendPacket( pad.Stander, Map.Malas, new ParticleEffect( EffectType.FixedFrom, center.Serial, Serial.Zero, 0x0, new Point3D( 324, 64, -1 ), new Point3D( 324, 64, -1 ), 0, 0, false, false, 0, 0, 0x13A7, 0, 0, center.Serial, 3, 0 ) );
}
}
}
if ( center != null )
{
center.MoveToWorld( new Point3D( 467, 96, -1 ), Map.Malas );
if ( m_Timer != null )
{
m_Timer.Stop();
}
m_Timer = new PoisonTimer( this );
m_Timer.Start();
m_CanActive = false;
m_Box.CanSummon = true;
}
}
}
FreeLevers();
}
public LampController( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.WriteItemList( m_Levers, true );
writer.WriteItemList( m_Statues, true );
writer.WriteItemList( m_Pads, true );
writer.Write( m_Box );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Code = "";
m_PuzzleCode = "";
m_PuzzleCode = GenerateCode( m_PuzzleCode );
m_Levers = reader.ReadItemList();
m_Statues = reader.ReadItemList();
m_Pads = reader.ReadItemList();
m_Box = reader.ReadItem() as PuzzleBox;
m_CanActive = true;
m_Box.CanSummon = true;
}
public class PoisonTimer : Timer
{
public LampController m_Controller;
public int count = 1;
public PoisonTimer( LampController controller ) : base( TimeSpan.FromSeconds( 8.0 ), TimeSpan.FromSeconds( 1.0 ) )
{
m_Controller = controller;
}
public void CheckAlive()
{
bool AliveCreatures = false;
IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect );
foreach ( object obj in eable )
{
if ( obj is Mobile )
{
Mobile mobile = obj as Mobile;
if ( mobile != null && mobile.Alive && !( mobile is WandererOfTheVoid ) )
{
AliveCreatures = true;
}
}
}
eable.Free();
if ( !AliveCreatures )
{
m_Controller.ClearRoom();
Stop();
}
}
public void Gas( int level )
{
int[] x = new int[ 3 ], y = new int[ 3 ];
for ( int i = 0; i < x.Length; i++ )
{
x[ i ] = Utility.Random( m_Controller.Rect.X, m_Controller.Rect.Width );
y[ i ] = Utility.Random( m_Controller.Rect.Y, m_Controller.Rect.Height );
}
int hue = 0xAC;
Poison poison = null;
switch ( level )
{
case 0:
hue = 0xA6;
poison = Poison.Lesser;
break;
case 1:
hue = 0xAA;
poison = Poison.Regular;
break;
case 2:
hue = 0xAC;
poison = Poison.Greater;
break;
case 3:
hue = 0xA8;
poison = Poison.Deadly;
break;
case 4:
hue = 0xA4;
poison = Poison.Lethal;
break;
case 5:
hue = 0xAC;
poison = Poison.Lethal;
break;
}
Effects.SendLocationParticles( EffectItem.Create( new Point3D( x[ 0 ], y[ 0 ], -1 ), Map.Malas, EffectItem.DefaultDuration ), 0x36B0, 1, Utility.Random( 160, 200 ), hue, 0, 0x1F78, 0 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( x[ 1 ], y[ 1 ], -1 ), Map.Malas, EffectItem.DefaultDuration ), 0x36CB, 1, Utility.Random( 160, 200 ), hue, 0, 0x1F78, 0 );
Effects.SendLocationParticles( EffectItem.Create( new Point3D( x[ 2 ], y[ 2 ], -1 ), Map.Malas, EffectItem.DefaultDuration ), 0x36BD, 1, Utility.Random( 160, 200 ), hue, 0, 0x1F78, 0 );
IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect );
foreach ( object obj in eable )
{
if ( obj is Mobile )
{
Mobile mobile = obj as Mobile;
if ( mobile != null && poison != null && mobile.Poison == null && !( mobile is WandererOfTheVoid ) )
{
double chance = ( level + 1 ) * 0.3;
if ( chance >= Utility.RandomDouble() )
{
mobile.ApplyPoison( mobile, poison );
}
}
}
}
eable.Free();
}
protected override void OnTick()
{
CheckAlive();
count++;
int level = (int) ( count / 60 );
if ( count % 60 == 0 ) // every minute we need send message to player about level's change
{
int number = 0;
int hue = 0x485;
switch ( level )
{
case 1:
number = 1050001;
break; // It is becoming more difficult for you to breathe as the poisons in the room become more concentrated.
case 2:
number = 1050003;
break; // You begin to panic as the poison clouds thicken.
case 3:
number = 1050056;
break; // Terror grips your spirit as you realize you may never leave this room alive.
case 4:
number = 1050057;
break; // The end is near. You feel hopeless and desolate. The poison is beginning to stiffen your muscles.
case 5:
number = 1062091;
hue = 0x23F3;
break; // The poison is becoming too much for you to bear. You fear that you may die at any moment.
}
IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect );
foreach ( object obj in eable )
{
if ( obj is Mobile )
{
Mobile mobile = obj as Mobile;
if ( mobile != null && mobile.Player )
{
if ( number != 0 )
{
mobile.SendLocalizedMessage( number, null, hue );
}
}
}
}
eable.Free();
if ( level == 5 )
{
PainTimer timer = new PainTimer( m_Controller );
timer.Start();
}
}
if ( count % 5 == 0 ) // every 5 seconds we fill room with a gas
{
Gas( level );
}
}
}
public class PainTimer : Timer
{
public LampController m_Controller;
public int count = 1;
public PainTimer( LampController controller ) : base( TimeSpan.FromSeconds( 10.0 ), TimeSpan.FromSeconds( 10.0 ) )
{
m_Controller = controller;
}
protected override void OnTick()
{
count++;
IPooledEnumerable eable = Map.Malas.GetMobilesInBounds( m_Controller.Rect );
ArrayList targets = new ArrayList();
foreach ( Mobile mobile in eable )
{
targets.Add( mobile );
}
for ( int i = 0; i < targets.Count; ++i )
{
Mobile mobile = targets[ i ] as Mobile;
if ( mobile != null && !( mobile is WandererOfTheVoid ) )
{
if ( mobile.Player )
{
mobile.Say( 1062092 ); // Your body reacts violently from the pain.
mobile.Animate( 32, 5, 1, true, false, 0 );
}
mobile.Damage( Utility.Random( 15, 20 ) );
if ( count == 10 ) // at OSI at this second all mobiles is killed and room is cleared
{
mobile.Kill();
}
}
}
eable.Free();
if ( count == 10 )
{
if ( m_Controller != null )
{
m_Controller.ClearRoom(); // clear room
if ( m_Controller.m_Timer != null )
{
m_Controller.m_Timer.Stop(); // stop gas effects
}
Stop(); // stop convulsions
}
}
}
}
}
}

View file

@ -0,0 +1,80 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class PuzzleBox : Item
{
private bool m_CanSummon;
[CommandProperty( AccessLevel.GameMaster )]
public bool CanSummon { get { return m_CanSummon; } set { m_CanSummon = value; } }
private WandererOfTheVoid m_Wanderer;
[CommandProperty( AccessLevel.GameMaster )]
public WandererOfTheVoid Wanderer { get { return m_Wanderer; } set { m_Wanderer = value; } }
public override bool ForceShowProperties { get { return true; } }
[Constructable]
public PuzzleBox() : base( 0xE80 )
{
Movable = false;
m_Wanderer = null;
}
public PuzzleBox( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( this.GetWorldLocation(), 3 ) )
return;
if ( m_CanSummon && ( m_Wanderer == null || !m_Wanderer.Alive ) )
{
m_Wanderer = new WandererOfTheVoid();
m_Wanderer.MoveToWorld( new Point3D( 467, 94, -1 ), Map.Malas );
// I am the guardian of the Tomb of Sektu. Suffer my wrath!
m_Wanderer.PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, 1060002, "" );
Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerCallback( SayFakeMessage ) );
m_CanSummon = false;
}
}
public void SayFakeMessage()
{
// You try to pry the box open, when you notice that there is no opening. It's a fake box.
PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, 1060003, "" );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Wanderer );
writer.Write( (bool) m_CanSummon );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Wanderer = reader.ReadMobile() as WandererOfTheVoid;
m_CanSummon = reader.ReadBool();
}
}
}

View file

@ -0,0 +1,87 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class PuzzleLever : Item
{
private LampController m_Controller;
private int m_Code;
[CommandProperty( AccessLevel.GameMaster )]
public LampController Controller
{
get { return m_Controller; }
set { m_Controller = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Code
{
get { return m_Code; }
set { m_Code = value; }
}
[Constructable]
public PuzzleLever( int code ) : base( 0x108E )
{
m_Code = code;
Hue = 0x66D;
Movable = false;
}
public PuzzleLever( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( m_Controller != null && m_Controller.CanActive )
{
if ( m_Controller.Code.Length < 4 )
{
m_Controller.Code += m_Code;
if ( ItemID == 0x108E )
{
ItemID = 0x108C;
}
else if ( ItemID == 0x108C )
{
ItemID = 0x108E;
}
Effects.PlaySound( Location, Map, 0x3E8 );
}
}
else
{
from.SendLocalizedMessage( 1060001 ); // You throw the switch, but the mechanism cannot be engaged again so soon.
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int) m_Code );
writer.Write( m_Controller );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_Code = reader.ReadInt();
m_Controller = reader.ReadItem() as LampController;
}
}
}

View file

@ -0,0 +1,124 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class PuzzlePad : Item
{
private PlayerMobile m_Stander;
private bool m_Busy;
[CommandProperty( AccessLevel.GameMaster )]
public PlayerMobile Stander
{
get { return m_Stander; }
set { m_Stander = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Busy
{
get { return m_Busy; }
set { m_Busy = value; }
}
private InternalStandTimer m_Timer;
[Constructable]
public PuzzlePad() : base( 0x1822 )
{
m_Busy = false;
m_Stander = null;
m_Timer = null;
Hue = 0x4C;
Movable = false;
}
public override bool HandlesOnMovement { get { return true; } } // Tell the core that we implement OnMovement
public override bool OnMoveOver( Mobile m )
{
if ( ( m != null ) && ( m is PlayerMobile ) )
{
if ( m_Stander == null )
{
m_Stander = (PlayerMobile) m;
if ( m_Timer != null )
{
m_Timer.Stop();
}
m_Timer = new InternalStandTimer( this );
m_Timer.Start();
}
}
return base.OnMoveOver( m );
}
public PuzzlePad( 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();
}
private class InternalStandTimer : Timer
{
private PuzzlePad m_Pad;
public InternalStandTimer( PuzzlePad pad ) : base( TimeSpan.FromSeconds( 0.25 ), TimeSpan.FromSeconds( 0.25 ) )
{
m_Pad = pad;
Priority = TimerPriority.FiftyMS;
}
private void Vacance()
{
if ( m_Pad != null )
{
m_Pad.Stander = null;
m_Pad.Busy = false;
}
Stop();
}
protected override void OnTick()
{
if ( m_Pad != null && !m_Pad.Deleted && m_Pad.Stander != null )
{
if ( !m_Pad.Stander.Deleted && m_Pad.Stander.Alive && m_Pad.Stander.Location == m_Pad.Location )
{
m_Pad.Busy = true;
}
else
{
Vacance();
}
}
else
{
Vacance();
}
}
}
}
}

View file

@ -0,0 +1,36 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class PuzzleStatue : Item
{
[Constructable]
public PuzzleStatue( int itemID ) : base( itemID )
{
Hue = 0x44E;
Movable = false;
}
public PuzzleStatue( 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();
}
}
}

View file

@ -129,7 +129,11 @@ namespace Server.Engines.Plants
PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( m_Plant.PlantType );
PlantHueInfo hueInfo = PlantHueInfo.GetInfo( m_Plant.PlantHue );
AddItem( 130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, typeInfo.ItemID, hueInfo.Hue );
// The large images for these trees trigger a client crash, so use a smaller, generic tree.
if ( m_Plant.PlantType == PlantType.CypressTwisted || m_Plant.PlantType == PlantType.CypressStraight )
AddItem( 130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, 0x0CCA, hueInfo.Hue );
else
AddItem( 130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, typeInfo.ItemID, hueInfo.Hue );
}
if ( status != PlantStatus.BowlOfDirt )

View file

@ -259,23 +259,38 @@ namespace Server.Engines.Plants
if ( m_PlantStatus < PlantStatus.DecorativePlant )
{
string args = string.Format( "#{0}\t#{1}\t#{2}", m_PlantSystem.GetLocalizedHealth(), title, typeInfo.Name );
if ( typeInfo.ContainsPlant )
if ( m_PlantType == PlantType.SugarCanes )
{
// a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~
list.Add( hueInfo.IsBright() ? 1061891 : 1061889, args );
string args = string.Format( "#{0}", m_PlantSystem.GetLocalizedHealth() );
list.Add ( 1094702, args );
}
else
{
// a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~ plant
list.Add( hueInfo.IsBright() ? 1061892 : 1061890, args );
string args = string.Format( "#{0}\t#{1}\t#{2}", m_PlantSystem.GetLocalizedHealth(), title, typeInfo.Name );
if ( typeInfo.ContainsPlant )
{
// a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~
list.Add( hueInfo.IsBright() ? 1061891 : 1061889, args );
}
else
{
// a ~1_HEALTH~ [bright] ~2_COLOR~ ~3_NAME~ plant
list.Add( hueInfo.IsBright() ? 1061892 : 1061890, args );
}
}
}
else
{
// a decorative ~1_COLOR~ ~2_TYPE~ plant
list.Add( hueInfo.IsBright() ? 1074267 : 1070973, string.Format( "#{0}\t#{1}", title, typeInfo.Name ) );
if ( m_PlantType == PlantType.SugarCanes )
list.Add ( 1094703 );
else if ( title == 1080528 )
// a decorative ~2_TYPE~
list.Add( 1080539, string.Format( "#{0}\t#{1}", title, typeInfo.Name ) );
else
// a decorative ~1_COLOR~ ~2_TYPE~ plant
list.Add( hueInfo.IsBright() ? 1074267 : 1070973, string.Format( "#{0}\t#{1}", title, typeInfo.Name ) );
}
}
else if ( m_PlantStatus >= PlantStatus.Seed )

View file

@ -29,7 +29,24 @@ namespace Server.Engines.Plants
RareGreenBonsai,
RarePinkBonsai,
ExceptionalBonsai,
ExoticBonsai
ExoticBonsai,
Cactus,
FlaxFlowers,
FoxgloveFlowers,
HopsEast,
OrfluerFlowers,
CypressTwisted,
HedgeShort,
JuniperBush,
SnowdropPatch,
Cattails,
PoppyPatch,
SpiderTree,
WaterLily,
CypressStraight,
HedgeTall,
HopsSouth,
SugarCanes
}
public class PlantTypeInfo
@ -60,7 +77,24 @@ namespace Server.Engines.Plants
new PlantTypeInfo( 0x28DE, -5, 5, PlantType.RareGreenBonsai, true, false, false ),
new PlantTypeInfo( 0x28E1, -5, 5, PlantType.RarePinkBonsai, true, false, false ),
new PlantTypeInfo( 0x28E2, -5, 5, PlantType.ExceptionalBonsai, true, false, false ),
new PlantTypeInfo( 0x28E3, -5, 5, PlantType.ExoticBonsai, true, false, false )
new PlantTypeInfo( 0x28E3, -5, 5, PlantType.ExoticBonsai, true, false, false ),
new PlantTypeInfo( 0x0D25, 0, 0, PlantType.Cactus, false, false, false ),
new PlantTypeInfo( 0x1A9A, 5, 10, PlantType.FlaxFlowers, false, true, false ),
new PlantTypeInfo( 0x0C84, 0, 0, PlantType.FoxgloveFlowers, false, true, false ),
new PlantTypeInfo( 0x1A9F, 5, -25, PlantType.HopsEast, false, false, false ),
new PlantTypeInfo( 0x0CC1, 0, 0, PlantType.OrfluerFlowers, false, true, false ),
new PlantTypeInfo( 0x0CFE, -45, -30, PlantType.CypressTwisted, false, false, false ),
new PlantTypeInfo( 0x0C8F, 0, 0, PlantType.HedgeShort, false, false, false ),
new PlantTypeInfo( 0x0CC8, 0, 0, PlantType.JuniperBush, true, false, false ),
new PlantTypeInfo( 0x0C8E, -20, 0, PlantType.SnowdropPatch, false, true, false ),
new PlantTypeInfo( 0x0CB7, 0, 0, PlantType.Cattails, false, false, false ),
new PlantTypeInfo( 0x0CBE, -20, 0, PlantType.PoppyPatch, false, true, false ),
new PlantTypeInfo( 0x0CC9, 0, 0, PlantType.SpiderTree, false, false, false ),
new PlantTypeInfo( 0x0DC1, -5, 15, PlantType.WaterLily, false, true, false ),
new PlantTypeInfo( 0x0CFB, -45, -30, PlantType.CypressStraight, false, false, false ),
new PlantTypeInfo( 0x0DB8, 0, -20, PlantType.HedgeTall, false, false, false ),
new PlantTypeInfo( 0x1AA1, 10, -25, PlantType.HopsSouth, false, false, false ),
new PlantTypeInfo( 0x246C, -25, -20, PlantType.SugarCanes, false, false, false )
};
public static PlantTypeInfo GetInfo( PlantType plantType )
@ -83,6 +117,51 @@ namespace Server.Engines.Plants
}
}
public static PlantType RandomPeculiarGroupOne()
{
switch ( Utility.Random( 5 ) )
{
case 0: return PlantType.Cactus;
case 1: return PlantType.FlaxFlowers;
case 2: return PlantType.FoxgloveFlowers;
case 3: return PlantType.HopsEast;
default: return PlantType.OrfluerFlowers;
}
}
public static PlantType RandomPeculiarGroupTwo()
{
switch ( Utility.Random( 4 ) )
{
case 0: return PlantType.CypressTwisted;
case 1: return PlantType.HedgeShort;
case 2: return PlantType.JuniperBush;
default: return PlantType.SnowdropPatch;
}
}
public static PlantType RandomPeculiarGroupThree()
{
switch ( Utility.Random( 4 ) )
{
case 0: return PlantType.Cattails;
case 1: return PlantType.PoppyPatch;
case 2: return PlantType.SpiderTree;
default: return PlantType.WaterLily;
}
}
public static PlantType RandomPeculiarGroupFour()
{
switch ( Utility.Random( 4 ) )
{
case 0: return PlantType.CypressStraight;
case 1: return PlantType.HedgeTall;
case 2: return PlantType.HopsSouth;
default: return PlantType.SugarCanes;
}
}
public static PlantType RandomBonsai( double increaseRatio )
{
/* Chances of each plant type are equal to the chances of the previous plant type * increaseRatio:
@ -152,6 +231,25 @@ namespace Server.Engines.Plants
{
switch ( plantType )
{
case PlantType.Cactus:
case PlantType.FlaxFlowers:
case PlantType.FoxgloveFlowers:
case PlantType.HopsEast:
case PlantType.OrfluerFlowers:
case PlantType.CypressTwisted:
case PlantType.HedgeShort:
case PlantType.JuniperBush:
case PlantType.SnowdropPatch:
case PlantType.Cattails:
case PlantType.PoppyPatch:
case PlantType.SpiderTree:
case PlantType.WaterLily:
case PlantType.CypressStraight:
case PlantType.HedgeTall:
case PlantType.HopsSouth:
case PlantType.SugarCanes:
return 1080528; // peculiar
case PlantType.CommonGreenBonsai:
case PlantType.CommonPinkBonsai:
return 1063335; // common

View file

@ -56,6 +56,17 @@ namespace Server.Engines.Plants
return new Seed( PlantTypeInfo.RandomBonsai( increaseRatio ), PlantHue.Plain, false );
}
public static Seed RandomPeculiarSeed( int group )
{
switch ( group )
{
case 1: return new Seed ( PlantTypeInfo.RandomPeculiarGroupOne(), PlantHue.Plain, false );
case 2: return new Seed ( PlantTypeInfo.RandomPeculiarGroupTwo(), PlantHue.Plain, false );
case 3: return new Seed ( PlantTypeInfo.RandomPeculiarGroupThree(), PlantHue.Plain, false );
default: return new Seed ( PlantTypeInfo.RandomPeculiarGroupFour(), PlantHue.Plain, false );
}
}
[Constructable]
public Seed() : this( PlantTypeInfo.RandomFirstGeneration(), PlantHueInfo.RandomFirstGeneration(), false )
{

View file

@ -594,8 +594,6 @@ namespace Server.Mobiles
from.SendLocalizedMessage( 500269 ); // You cannot build that there.
else if ( result == AddonFitResult.NotInHouse )
from.SendLocalizedMessage( 1076192 ); // Statues can only be placed in houses where you are the owner or co-owner.
else if ( result == AddonFitResult.DoorsNotClosed )
from.SendMessage( "You must close all house doors before placing this." );
else if ( result == AddonFitResult.DoorTooClose )
from.SendLocalizedMessage( 500271 ); // You cannot build near the door.
}
@ -621,9 +619,6 @@ namespace Server.Mobiles
{
BaseDoor door = doors[ i ] as BaseDoor;
if ( door != null && door.Open )
return AddonFitResult.DoorsNotClosed;
Point3D doorLoc = door.GetWorldLocation();
int doorHeight = door.ItemData.CalcHeight;