RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Champion Cleaner for 2.5 core

zzluis12

Sorceror
Hey, I was trying to apply the old A_Li_N champion cleaner script in a 2.5 core

The original script is this one

Code:
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
 
namespace Server.Engines.CannedEvil
{
public class ChampionSpawn : Item
{
private bool m_Active;
private bool m_RandomizeType;
private ChampionSpawnType m_Type;
private ArrayList m_Creatures;
private ArrayList m_RedSkulls;
private ArrayList m_WhiteSkulls;
private ChampionPlatform m_Platform;
private ChampionAltar m_Altar;
private int m_Kills;
private Mobile m_Champion;
private int m_SpawnRange;
 
private TimeSpan m_ExpireDelay;
private DateTime m_ExpireTime;
 
private TimeSpan m_RestartDelay;
private DateTime m_RestartTime;
 
private Timer m_Timer, m_RestartTimer;
 
[Constructable]
public ChampionSpawn() : base( 0xBD2 )
{
Movable = false;
Visible = false;
 
m_Creatures = new ArrayList();
m_RedSkulls = new ArrayList();
m_WhiteSkulls = new ArrayList();
 
m_Platform = new ChampionPlatform( this );
m_Altar = new ChampionAltar( this );
 
m_ExpireDelay = TimeSpan.FromMinutes( 10.0 );
m_RestartDelay = TimeSpan.FromMinutes( 5.0 );
 
m_SpawnRange = 24;
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool RandomizeType
{
get{ return m_RandomizeType; }
set{ m_RandomizeType = value; }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Kills
{
get
{
return m_Kills;
}
set
{
m_Kills = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int SpawnRange
{
get
{
return m_SpawnRange;
}
set
{
m_SpawnRange = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan RestartDelay
{
get
{
return m_RestartDelay;
}
set
{
m_RestartDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime RestartTime
{
get
{
return m_RestartTime;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan ExpireDelay
{
get
{
return m_ExpireDelay;
}
set
{
m_ExpireDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime ExpireTime
{
get
{
return m_ExpireTime;
}
set
{
m_ExpireTime = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSpawnType Type
{
get
{
return m_Type;
}
set
{
m_Type = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get
{
return m_Active;
}
set
{
if ( value )
Start();
else
Stop();
 
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Champion
{
get
{
return m_Champion;
}
set
{
m_Champion = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Level
{
get
{
return m_RedSkulls.Count;
}
set
{
for ( int i = m_RedSkulls.Count - 1; i >= value; --i )
{
((Item)m_RedSkulls[i]).Delete();
m_RedSkulls.RemoveAt( i );
}
 
for ( int i = m_RedSkulls.Count; i < value; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Hue = 0x26;
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetRedSkullLocation( i ), Map );
 
m_RedSkulls.Add( skull );
}
 
InvalidateProperties();
}
}
 
public int MaxKills
{
get
{
return 250 - (Level * 12);
}
}
 
public void SetWhiteSkullCount( int val )
{
for ( int i = m_WhiteSkulls.Count - 1; i >= val; --i )
{
((Item)m_WhiteSkulls[i]).Delete();
m_WhiteSkulls.RemoveAt( i );
}
 
for ( int i = m_WhiteSkulls.Count; i < val; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetWhiteSkullLocation( i ), Map );
 
m_WhiteSkulls.Add( skull );
 
Effects.PlaySound( skull.Location, skull.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( skull.X + 1, skull.Y + 1, skull.Z ), skull.Map, 0x3728, 10 );
 
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInRange( Location, m_SpawnRange ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner
}
}
 
public void Start()
{
if ( m_Active || Deleted )
return;
 
m_Active = true;
 
if ( m_Timer != null )
m_Timer.Stop();
 
m_Timer = new SliceTimer( this );
m_Timer.Start();
 
if ( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if ( m_Altar != null )
m_Altar.Hue = 0;
}
 
public void Stop()
{
if ( !m_Active || Deleted )
return;
 
m_Active = false;
 
if ( m_Timer != null )
m_Timer.Stop();
 
m_Timer = null;
 
if ( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if ( m_Altar != null )
m_Altar.Hue = 0;
}
 
public void BeginRestart( TimeSpan ts )
{
if ( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTime = DateTime.Now + ts;
 
m_RestartTimer = new RestartTimer( this, ts );
m_RestartTimer.Start();
}
 
public void EndRestart()
{
if ( RandomizeType )
{
switch ( Utility.Random( 5 ) )
{
case 0: Type = ChampionSpawnType.VerminHorde; break;
case 1: Type = ChampionSpawnType.UnholyTerror; break;
case 2: Type = ChampionSpawnType.ColdBlood; break;
case 3: Type = ChampionSpawnType.Abyss; break;
case 4: Type = ChampionSpawnType.Arachnid; break;
}
}
 
Start();
}
 
public void OnSlice()
{
if ( !m_Active || Deleted )
return;
 
if ( m_Champion != null )
{
if ( m_Champion.Deleted )
{
if ( m_Altar != null )
{
m_Altar.Hue = 0;
new StarRoomGate( true, m_Altar.Location, m_Altar.Map );
}
 
m_Champion = null;
Stop();
 
BeginRestart( m_RestartDelay );
}
}
else
{
for ( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile m = (Mobile)m_Creatures[i];
 
if ( m.Deleted )
{
m_Creatures.RemoveAt( i );
--i;
++m_Kills;
InvalidateProperties();
}
}
 
double n = m_Kills / (double)MaxKills;
int p = (int)(n * 100);
 
if ( p >= 90 )
AdvanceLevel();
else if ( p > 0 )
SetWhiteSkullCount( p / 20 );
 
if ( DateTime.Now >= m_ExpireTime )
Expire();
 
Respawn();
}
}
 
public void AdvanceLevel()
{
m_ExpireTime = DateTime.Now + m_ExpireDelay;
 
if ( Level < 16 )
{
m_Kills = 0;
++Level;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
if ( m_Altar != null )
{
Effects.PlaySound( m_Altar.Location, m_Altar.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( m_Altar.X + 1, m_Altar.Y + 1, m_Altar.Z ), m_Altar.Map, 0x3728, 10 );
}
}
else
{
SpawnChampion();
}
}
 
public void SpawnChampion()
{
if ( m_Altar != null )
m_Altar.Hue = 0x26;
 
m_Kills = 0;
Level = 0;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
switch ( m_Type )
{
default:
case ChampionSpawnType.UnholyTerror: m_Champion = new Neira(); break;
case ChampionSpawnType.VerminHorde: m_Champion = new Barracoon(); break;
case ChampionSpawnType.ForestLord: m_Champion = new LordOaks(); break;
case ChampionSpawnType.ColdBlood: m_Champion = new Rikktor(); break;
case ChampionSpawnType.Arachnid: m_Champion = new Mephitis(); break;
case ChampionSpawnType.Abyss: m_Champion = new Semidar(); break;
}
 
m_Champion.MoveToWorld( new Point3D( X, Y, Z - 15 ), Map );
}
 
public void Respawn()
{
if ( !m_Active || Deleted || m_Champion != null )
return;
 
while ( m_Creatures.Count < (50 - (GetSubLevel() * 10)) )
{
Mobile m = Spawn();
 
if ( m == null )
return;
 
m_Creatures.Add( m );
m.MoveToWorld( GetSpawnLocation(), Map );
 
if ( m is BaseCreature )
{
((BaseCreature)m).Tamable = false;
((BaseCreature)m).Home = Location;
((BaseCreature)m).RangeHome = m_SpawnRange;
}
}
}
 
public Point3D GetSpawnLocation()
{
Map map = Map;
 
if ( map == null )
return Location;
 
// Try 20 times to find a spawnable location.
for ( int i = 0; i < 20; i++ )
{
int x = Location.X + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
int y = Location.Y + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
int z = Map.GetAverageZ( x, y );
 
if ( Map.CanSpawnMobile( new Point2D( x, y ), z ) )
return new Point3D( x, y, z );
}
 
return Location;
}
 
private const int Level1 = 5;  // First spawn level from 0-5 red skulls
private const int Level2 = 9;  // Second spawn level from 6-9 red skulls
private const int Level3 = 13; // Third spawn level from 10-13 red skulls
 
private static Type[][][] m_Types = new Type[6][][]
{
new Type[][]
{// Abyss
new Type[]{ typeof( Mongbat ), typeof( Imp ) },// Level 1
new Type[]{ typeof( Gargoyle ), typeof( Harpy ) },// Level 2
new Type[]{ typeof( FireGargoyle ), typeof( StoneGargoyle ) },// Level 3
new Type[]{ typeof( Daemon ), typeof( Succubus ) }// Level 4
},
new Type[][]
{// Arachnid
new Type[]{ typeof( Scorpion ), typeof( GiantSpider ) },// Level 1
new Type[]{ typeof( TerathanDrone ), typeof( TerathanWarrior ) },// Level 2
new Type[]{ typeof( DreadSpider ), typeof( TerathanMatriarch ) },// Level 3
new Type[]{ typeof( PoisonElemental ), typeof( TerathanAvenger ) }// Level 4
},
new Type[][]
{// Cold Blood
new Type[]{ typeof( Lizardman ), typeof( Snake ) },// Level 1
new Type[]{ typeof( LavaLizard ), typeof( OphidianWarrior ) },// Level 2
new Type[]{ typeof( Drake ), typeof( OphidianArchmage ) },// Level 3
new Type[]{ typeof( Dragon ), typeof( OphidianKnight ) }// Level 4
},
new Type[][]
{// Forest Lord
new Type[]{ typeof( Pixie ), typeof( ShadowWisp ) },// Level 1
new Type[]{ typeof( Kirin ), typeof( Wisp ) },// Level 2
new Type[]{ typeof( Centaur ), typeof( Unicorn ) },// Level 3
new Type[]{ typeof( EtherealWarrior ), typeof( SerpentineDragon ) }// Level 4
},
new Type[][]
{// Vermin Horde
new Type[]{ typeof( GiantRat ), typeof( Slime ) },// Level 1
new Type[]{ typeof( DireWolf ), typeof( Ratman ) },// Level 2
new Type[]{ typeof( HellHound ), typeof( RatmanMage ) },// Level 3
new Type[]{ typeof( RatmanArcher ), typeof( SilverSerpent ) }// Level 4
},
new Type[][]
{// Unholy Terror
new Type[]{ typeof( Bogle ), typeof( Ghoul ), typeof( Shade ), typeof( Spectre ), typeof( Wraith ) },// Level 1
new Type[]{ typeof( BoneMagi ), typeof( Mummy ), typeof( SkeletalMage ) },// Level 2
new Type[]{ typeof( BoneKnight ), typeof( Lich ), typeof( SkeletalKnight ) },// Level 3
new Type[]{ typeof( LichLord ), typeof( RottingCorpse ) }// Level 4
}
};
 
public int GetSubLevel()
{
int level = this.Level;
 
if ( level <= Level1 )
return 0;
else if ( level <= Level2 )
return 1;
else if ( level <= Level3 )
return 2;
 
return 3;
}
 
public Mobile Spawn()
{
int v = (int)m_Type;
 
if ( v >= 0 && v < m_Types.Length )
{
Type[][] types = m_Types[v];
 
v = GetSubLevel();
 
if ( v >= 0 && v < types.Length )
return Spawn( types[v] );
}
 
return null;
}
 
public Mobile Spawn( params Type[] types )
{
try
{
return Activator.CreateInstance( types[Utility.Random( types.Length )] ) as Mobile;
}
catch
{
return null;
}
}
 
public void Expire()
{
m_Kills = 0;
 
if ( m_WhiteSkulls.Count == 0 )
{
// They didn't even get 20%, go back a level
 
if ( Level > 0 )
--Level;
 
InvalidateProperties();
}
else
{
SetWhiteSkullCount( 0 );
}
 
m_ExpireTime = DateTime.Now + m_ExpireDelay;
}
 
public Point3D GetRedSkullLocation( int index )
{
int x, y;
 
if ( index < 5 )
{
x = index - 2;
y = -2;
}
else if ( index < 9 )
{
x = 2;
y = index - 6;
}
else if ( index < 13 )
{
x = 10 - index;
y = 2;
}
else
{
x = -2;
y = 14 - index;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public Point3D GetWhiteSkullLocation( int index )
{
int x, y;
 
switch ( index )
{
default:
case 0: x = -1; y = -1; break;
case 1: x =  1; y = -1; break;
case 2: x =  1; y =  1; break;
case 3: x = -1; y =  1; break;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( "champion spawn" );
}
 
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
 
if ( m_Active )
{
list.Add( 1060742 ); // active
list.Add( 1060658, "Type\t{0}", m_Type ); // ~1_val~: ~2_val~
list.Add( 1060659, "Level\t{0}", Level ); // ~1_val~: ~2_val~
list.Add( 1060660, "Kills\t{0} of {1} ({2:F1}%)", m_Kills, MaxKills, 100.0 * ((double)m_Kills / MaxKills) ); // ~1_val~: ~2_val~
list.Add( 1060661, "Spawn Range\t{0}", m_SpawnRange ); // ~1_val~: ~2_val~
}
else
{
list.Add( 1060743 ); // inactive
}
}
 
public override void OnSingleClick( Mobile from )
{
if ( m_Active )
LabelTo( from, "{0} (Active; Level: {1}; Kills: {2}/{3})", m_Type, Level, m_Kills, MaxKills );
else
LabelTo( from, "{0} (Inactive)", m_Type );
}
 
public override void OnDoubleClick( Mobile from )
{
from.SendGump( new PropertiesGump( from, this ) );
}
 
public override void OnLocationChange( Point3D oldLoc )
{
if ( Deleted )
return;
 
if ( m_Platform != null )
m_Platform.Location = new Point3D( X, Y, Z - 20 );
 
if ( m_Altar != null )
m_Altar.Location = new Point3D( X, Y, Z - 15 );
 
if ( m_RedSkulls != null )
{
for ( int i = 0; i < m_RedSkulls.Count; ++i )
((Item)m_RedSkulls[i]).Location = GetRedSkullLocation( i );
}
 
if ( m_WhiteSkulls != null )
{
for ( int i = 0; i < m_WhiteSkulls.Count; ++i )
((Item)m_WhiteSkulls[i]).Location = GetWhiteSkullLocation( i );
}
}
 
public override void OnMapChange()
{
if ( Deleted )
return;
 
if ( m_Platform != null )
m_Platform.Map = Map;
 
if ( m_Altar != null )
m_Altar.Map = Map;
 
if ( m_RedSkulls != null )
{
for ( int i = 0; i < m_RedSkulls.Count; ++i )
((Item)m_RedSkulls[i]).Map = Map;
}
 
if ( m_WhiteSkulls != null )
{
for ( int i = 0; i < m_WhiteSkulls.Count; ++i )
((Item)m_WhiteSkulls[i]).Map = Map;
}
}
 
public override void OnDelete()
{
base.OnDelete ();
}
 
public override void OnAfterDelete()
{
base.OnAfterDelete();
 
if ( m_Platform != null )
m_Platform.Delete();
 
if ( m_Altar != null )
m_Altar.Delete();
 
if ( m_RedSkulls != null )
{
for ( int i = 0; i < m_RedSkulls.Count; ++i )
((Item)m_RedSkulls[i]).Delete();
 
m_RedSkulls.Clear();
}
 
if ( m_WhiteSkulls != null )
{
for ( int i = 0; i < m_WhiteSkulls.Count; ++i )
((Item)m_WhiteSkulls[i]).Delete();
 
m_WhiteSkulls.Clear();
}
 
if ( m_Creatures != null )
{
for ( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile mob = (Mobile)m_Creatures[i];
 
if ( !mob.Player )
mob.Delete();
}
 
m_Creatures.Clear();
}
 
if ( m_Champion != null && !m_Champion.Player )
m_Champion.Delete();
 
Stop();
}
 
public ChampionSpawn( Serial serial ) : base( serial )
{
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int) 2 ); // version
 
writer.Write( m_RandomizeType );
 
writer.Write( m_SpawnRange );
writer.Write( m_Kills );
 
writer.Write( (bool) m_Active );
writer.Write( (int) m_Type );
writer.WriteMobileList( m_Creatures, true );
writer.WriteItemList( m_RedSkulls, true );
writer.WriteItemList( m_WhiteSkulls, true );
writer.Write( m_Platform );
writer.Write( m_Altar );
writer.Write( m_ExpireDelay );
writer.WriteDeltaTime( m_ExpireTime );
writer.Write( m_Champion );
writer.Write( m_RestartDelay );
 
writer.Write( m_RestartTimer != null );
 
if ( m_RestartTimer != null )
writer.WriteDeltaTime( m_RestartTime );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
int version = reader.ReadInt();
 
switch ( version )
{
case 2:
{
m_RandomizeType = reader.ReadBool();
 
goto case 1;
}
case 1:
{
m_SpawnRange = reader.ReadInt();
m_Kills = reader.ReadInt();
 
goto case 0;
}
case 0:
{
if ( version < 1 )
m_SpawnRange = 24;
 
bool active = reader.ReadBool();
m_Type = (ChampionSpawnType)reader.ReadInt();
m_Creatures = reader.ReadMobileList();
m_RedSkulls = reader.ReadItemList();
m_WhiteSkulls = reader.ReadItemList();
m_Platform = reader.ReadItem() as ChampionPlatform;
m_Altar = reader.ReadItem() as ChampionAltar;
m_ExpireDelay = reader.ReadTimeSpan();
m_ExpireTime = reader.ReadDeltaTime();
m_Champion = reader.ReadMobile();
m_RestartDelay = reader.ReadTimeSpan();
 
if ( reader.ReadBool() )
{
m_RestartTime = reader.ReadDeltaTime();
BeginRestart( m_RestartTime - DateTime.Now );
}
 
if ( m_Platform == null || m_Altar == null )
Delete();
else if ( active )
Start();
 
break;
}
}
}
}
}

Which its all the same, but this part

Code:
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInSpawnArea( Location, m_SpawnArea ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner


I fix some errors, when tryed to mod this I just saw that now the script now defines a SpawnArea in X Y Z instead of a SpawnRange

Code:
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInSpawnArea( Location, m_SpawnArea ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner

But now it gives me this... and i have no clue :DD

Code:
Errors:
 + Engines/CannedEvil/ChampionSpawn.cs:
    CS1061: Line 323: 'Server.Map' no contiene una definición de 'GetItemsInSpaw
nArea' ni se encontró ningún método de extensión 'GetItemsInSpawnArea' que acept
e un primer argumento de tipo 'Server.Map' (¿falta una directiva using o una ref
erencia de ensamblado?)
 

zzluis12

Sorceror
Sure :) you go

Code:
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Regions;
using System.Collections.Generic;
 
namespace Server.Engines.CannedEvil
{
public class ChampionSpawn : Item
{
[CommandProperty( AccessLevel.GameMaster )]
public int SpawnSzMod
{
get
{
return ( m_SPawnSzMod < 1 || m_SPawnSzMod > 12 ) ? 12 : m_SPawnSzMod;
}
set
{
m_SPawnSzMod = ( value < 1 || value > 12 ) ? 12 : value;
}
}
private int m_SPawnSzMod;
 
private bool m_Active;
private bool m_RandomizeType;
private ChampionSpawnType m_Type;
private List<Mobile> m_Creatures;
private List<Item> m_RedSkulls;
private List<Item> m_WhiteSkulls;
private ChampionPlatform m_Platform;
private ChampionAltar m_Altar;
private int m_Kills;
private Mobile m_Champion;
 
//private int m_SpawnRange;
private Rectangle2D m_SpawnArea;
private ChampionSpawnRegion m_Region;
 
private TimeSpan m_ExpireDelay;
private DateTime m_ExpireTime;
 
private TimeSpan m_RestartDelay;
private DateTime m_RestartTime;
 
private Timer m_Timer, m_RestartTimer;
 
private IdolOfTheChampion m_Idol;
 
private bool m_HasBeenAdvanced;
private bool m_ConfinedRoaming;
 
private Dictionary<Mobile, int> m_DamageEntries;
 
[CommandProperty( AccessLevel.GameMaster )]
public bool ConfinedRoaming
{
get { return m_ConfinedRoaming; }
set { m_ConfinedRoaming = value; }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool HasBeenAdvanced
{
get { return m_HasBeenAdvanced; }
set { m_HasBeenAdvanced = value; }
}
 
[Constructable]
public ChampionSpawn() : base( 0xBD2 )
{
Movable = false;
Visible = false;
 
m_Creatures = new List<Mobile>();
m_RedSkulls = new List<Item>();
m_WhiteSkulls = new List<Item>();
 
m_Platform = new ChampionPlatform( this );
m_Altar = new ChampionAltar( this );
m_Idol = new IdolOfTheChampion( this );
 
m_ExpireDelay = TimeSpan.FromMinutes( 10.0 );
m_RestartDelay = TimeSpan.FromMinutes( 10.0 );
 
m_DamageEntries = new Dictionary<Mobile, int>();
 
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( SetInitialSpawnArea ) );
}
 
public void SetInitialSpawnArea()
{
//Previous default used to be 24;
SpawnArea = new Rectangle2D( new Point2D( X - 24, Y - 24 ), new Point2D( X + 24, Y + 24 ) );
}
 
public void UpdateRegion()
{
if( m_Region != null )
m_Region.Unregister();
 
if( !Deleted && this.Map != Map.Internal )
{
m_Region = new ChampionSpawnRegion( this );
m_Region.Register();
}
 
/*
if( m_Region == null )
{
m_Region = new ChampionSpawnRegion( this );
}
else
{
m_Region.Unregister();
//Why doesn't Region allow me to set it's map/Area meself? ><
m_Region = new ChampionSpawnRegion( this );
}
*/
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool RandomizeType
{
get { return m_RandomizeType; }
set { m_RandomizeType = value; }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Kills
{
get
{
return m_Kills;
}
set
{
m_Kills = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Rectangle2D SpawnArea
{
get
{
return m_SpawnArea;
}
set
{
m_SpawnArea = value;
InvalidateProperties();
UpdateRegion();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan RestartDelay
{
get
{
return m_RestartDelay;
}
set
{
m_RestartDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime RestartTime
{
get
{
return m_RestartTime;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan ExpireDelay
{
get
{
return m_ExpireDelay;
}
set
{
m_ExpireDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime ExpireTime
{
get
{
return m_ExpireTime;
}
set
{
m_ExpireTime = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSpawnType Type
{
get
{
return m_Type;
}
set
{
m_Type = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get
{
return m_Active;
}
set
{
if( value )
Start();
else
Stop();
 
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Champion
{
get
{
return m_Champion;
}
set
{
m_Champion = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Level
{
get
{
return m_RedSkulls.Count;
}
set
{
for( int i = m_RedSkulls.Count - 1; i >= value; --i )
{
m_RedSkulls[i].Delete();
m_RedSkulls.RemoveAt( i );
}
 
for( int i = m_RedSkulls.Count; i < value; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Hue = 0x26;
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetRedSkullLocation( i ), Map );
 
m_RedSkulls.Add( skull );
}
 
InvalidateProperties();
}
}
 
public int MaxKills
{
get
{
return ( m_SPawnSzMod * ( 250 / 12 ) ) - ( Level * m_SPawnSzMod );
}
}
 
public bool IsChampionSpawn( Mobile m )
{
return m_Creatures.Contains( m );
}
 
public void SetWhiteSkullCount( int val )
{
for( int i = m_WhiteSkulls.Count - 1; i >= val; --i )
{
m_WhiteSkulls[i].Delete();
m_WhiteSkulls.RemoveAt( i );
}
 
for( int i = m_WhiteSkulls.Count; i < val; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetWhiteSkullLocation( i ), Map );
 
m_WhiteSkulls.Add( skull );
 
Effects.PlaySound( skull.Location, skull.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( skull.X + 1, skull.Y + 1, skull.Z ), skull.Map, 0x3728, 10 );
 
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInArea( Location, m_SpawnArea ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner
}
}
 
public void Start()
{
if( m_Active || Deleted )
return;
 
m_Active = true;
m_HasBeenAdvanced = false;
 
if( m_Timer != null )
m_Timer.Stop();
 
m_Timer = new SliceTimer( this );
m_Timer.Start();
 
if( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if( m_Altar != null )
{
if ( m_Champion != null )
m_Altar.Hue = 0x26;
else
m_Altar.Hue = 0;
}
 
if ( m_Platform != null )
m_Platform.Hue = 0x452;
}
 
public void Stop()
{
if( !m_Active || Deleted )
return;
 
m_Active = false;
m_HasBeenAdvanced = false;
 
if( m_Timer != null )
m_Timer.Stop();
 
m_Timer = null;
 
if( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if( m_Altar != null )
m_Altar.Hue = 0;
 
if ( m_Platform != null )
m_Platform.Hue = 0x497;
}
 
public void BeginRestart( TimeSpan ts )
{
if( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTime = DateTime.UtcNow + ts;
 
m_RestartTimer = new RestartTimer( this, ts );
m_RestartTimer.Start();
}
 
public void EndRestart()
{
if( RandomizeType )
{
switch( Utility.Random( 5 ) )
{
case 0: Type = ChampionSpawnType.VerminHorde; break;
case 1: Type = ChampionSpawnType.UnholyTerror; break;
case 2: Type = ChampionSpawnType.ColdBlood; break;
case 3: Type = ChampionSpawnType.Abyss; break;
case 4: Type = ChampionSpawnType.Arachnid; break;
}
}
 
m_HasBeenAdvanced = false;
 
Start();
}
 
#region Scroll of Transcendence
private ScrollofTranscendence CreateRandomSoT( bool felucca )
{
int level = Utility.RandomMinMax( 1, 5 );
 
if ( felucca )
level += 5;
 
return ScrollofTranscendence.CreateRandom(level, level);
}
#endregion
 
public static void GiveScrollTo( Mobile killer, SpecialScroll scroll )
{
if( scroll == null || killer == null )//sanity
return;
 
if ( scroll is ScrollofTranscendence )
killer.SendLocalizedMessage( 1094936 ); // You have received a Scroll of Transcendence!
else
killer.SendLocalizedMessage( 1049524 ); // You have received a scroll of power!
 
if ( killer.Alive )
killer.AddToBackpack( scroll );
else
{
if( killer.Corpse != null && !killer.Corpse.Deleted )
killer.Corpse.DropItem( scroll );
else
killer.AddToBackpack( scroll );
}
 
// Justice reward
PlayerMobile pm = (PlayerMobile)killer;
for (int j = 0; j < pm.JusticeProtectors.Count; ++j)
{
Mobile prot = (Mobile)pm.JusticeProtectors[j];
 
if ( prot.Map != killer.Map || prot.Kills >= 5 || prot.Criminal || !JusticeVirtue.CheckMapRegion( killer, prot ) )
continue;
 
int chance = 0;
 
switch ( VirtueHelper.GetLevel( prot, VirtueName.Justice ) )
{
case VirtueLevel.Seeker: chance = 60; break;
case VirtueLevel.Follower: chance = 80; break;
case VirtueLevel.Knight: chance = 100; break;
}
 
if ( chance > Utility.Random( 100 ) )
{
try
{
prot.SendLocalizedMessage( 1049368 ); // You have been rewarded for your dedication to Justice!
 
SpecialScroll scrollDupe = Activator.CreateInstance( scroll.GetType() ) as SpecialScroll;
 
if ( scrollDupe != null )
{
scrollDupe.Skill = scroll.Skill;
scrollDupe.Value = scroll.Value;
prot.AddToBackpack( scrollDupe );
}
}
catch{}
}
}
}
 
public void OnSlice()
{
if( !m_Active || Deleted )
return;
 
if( m_Champion != null )
{
if( m_Champion.Deleted )
{
RegisterDamageTo( m_Champion );
 
if( m_Champion is BaseChampion )
AwardArtifact( ((BaseChampion)m_Champion).GetArtifact() );
 
m_DamageEntries.Clear();
 
if( m_Platform != null )
m_Platform.Hue = 0x497;
 
if( m_Altar != null )
{
m_Altar.Hue = 0;
 
if( !Core.ML || Map == Map.Felucca )
{
new StarRoomGate( true, m_Altar.Location, m_Altar.Map );
}
}
 
m_Champion = null;
Stop();
 
BeginRestart( m_RestartDelay );
}
}
else
{
int kills = m_Kills;
 
for ( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile m = m_Creatures[i];
 
if ( m.Deleted )
{
if( m.Corpse != null && !m.Corpse.Deleted )
{
((Corpse)m.Corpse).BeginDecay( TimeSpan.FromMinutes( 1 ));
}
m_Creatures.RemoveAt( i );
--i;
++m_Kills;
 
Mobile killer = m.FindMostRecentDamager( false );
 
RegisterDamageTo( m );
 
if( killer is BaseCreature )
killer = ((BaseCreature)killer).GetMaster();
 
if( killer is PlayerMobile )
{
#region Scroll of Transcendence
if ( Core.ML )
{
if ( Map == Map.Felucca )
{
if ( Utility.RandomDouble() < 0.001 )
{
PlayerMobile pm = (PlayerMobile)killer;
double random = Utility.Random ( 49 );
 
if ( random <= 24 )
{
ScrollofTranscendence SoTF = CreateRandomSoT( true );
GiveScrollTo( pm, (SpecialScroll)SoTF );
}
else
{
PowerScroll PS = PowerScroll.CreateRandomNoCraft(5, 5);
GiveScrollTo( pm, (SpecialScroll)PS );
}
}
}
 
if ( Map == Map.Ilshenar || Map == Map.Tokuno || Map == Map.Malas )
{
if ( Utility.RandomDouble() < 0.0015 )
{
killer.SendLocalizedMessage( 1094936 ); // You have received a Scroll of Transcendence!
ScrollofTranscendence SoTT = CreateRandomSoT( false );
killer.AddToBackpack( SoTT );
}
}
}
#endregion
 
int mobSubLevel = GetSubLevelFor( m ) + 1;
 
if( mobSubLevel >= 0 )
{
bool gainedPath = false;
 
int pointsToGain = mobSubLevel * 40;
 
if( VirtueHelper.Award( killer, VirtueName.Valor, pointsToGain, ref gainedPath ) )
{
if( gainedPath )
m.SendLocalizedMessage( 1054032 ); // You have gained a path in Valor!
else
m.SendLocalizedMessage( 1054030 ); // You have gained in Valor!
 
//No delay on Valor gains
}
 
PlayerMobile.ChampionTitleInfo info = ((PlayerMobile)killer).ChampionTitles;
 
info.Award( m_Type, mobSubLevel );
}
}
}
}
 
// Only really needed once.
if ( m_Kills > kills )
InvalidateProperties();
 
double n = m_Kills / (double)MaxKills;
int p = (int)(n * 100);
 
if( p >= 90 )
AdvanceLevel();
else if( p > 0 )
SetWhiteSkullCount( p / 20 );
 
if( DateTime.UtcNow >= m_ExpireTime )
Expire();
 
Respawn();
}
}
 
public void AdvanceLevel()
{
m_ExpireTime = DateTime.UtcNow + m_ExpireDelay;
 
if( Level < 16 )
{
m_Kills = 0;
++Level;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
if( m_Altar != null )
{
Effects.PlaySound( m_Altar.Location, m_Altar.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( m_Altar.X + 1, m_Altar.Y + 1, m_Altar.Z ), m_Altar.Map, 0x3728, 10 );
}
}
else
{
SpawnChampion();
}
}
 
public void SpawnChampion()
{
if( m_Altar != null )
m_Altar.Hue = 0x26;
 
if ( m_Platform != null )
m_Platform.Hue = 0x452;
 
m_Kills = 0;
Level = 0;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
try
{
m_Champion = Activator.CreateInstance( ChampionSpawnInfo.GetInfo( m_Type ).Champion ) as Mobile;
}
catch { }
 
if( m_Champion != null )
m_Champion.MoveToWorld( new Point3D( X, Y, Z - 15 ), Map );
}
 
public void Respawn()
{
if( !m_Active || Deleted || m_Champion != null )
return;
 
while( m_Creatures.Count < ( ( m_SPawnSzMod * ( 200 / 12 ) ) ) - ( GetSubLevel() * ( m_SPawnSzMod * ( 40 / 12 ) ) ) )
{
Mobile m = Spawn();
 
if( m == null )
return;
 
Point3D loc = GetSpawnLocation();
 
// Allow creatures to turn into Paragons at Ilshenar champions.
m.OnBeforeSpawn( loc, Map );
 
m_Creatures.Add( m );
m.MoveToWorld( loc, Map );
 
if( m is BaseCreature )
{
BaseCreature bc = m as BaseCreature;
bc.Tamable = false;
 
if( !m_ConfinedRoaming )
{
bc.Home = this.Location;
bc.RangeHome = (int)(Math.Sqrt( m_SpawnArea.Width * m_SpawnArea.Width + m_SpawnArea.Height * m_SpawnArea.Height )/2);
}
else
{
bc.Home = bc.Location;
 
Point2D xWall1 = new Point2D( m_SpawnArea.X, bc.Y );
Point2D xWall2 = new Point2D( m_SpawnArea.X + m_SpawnArea.Width, bc.Y );
Point2D yWall1 = new Point2D( bc.X, m_SpawnArea.Y );
Point2D yWall2 = new Point2D( bc.X, m_SpawnArea.Y + m_SpawnArea.Height );
 
double minXDist = Math.Min( bc.GetDistanceToSqrt( xWall1 ), bc.GetDistanceToSqrt( xWall2 ) );
double minYDist = Math.Min( bc.GetDistanceToSqrt( yWall1 ), bc.GetDistanceToSqrt( yWall2 ) );
 
bc.RangeHome = (int)Math.Min( minXDist, minYDist );
}
}
}
}
 
public Point3D GetSpawnLocation()
{
Map map = Map;
 
if( map == null )
return Location;
 
// Try 20 times to find a spawnable location.
for( int i = 0; i < 20; i++ )
{
/*
int x = Location.X + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
int y = Location.Y + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
*/
 
int x = Utility.Random( m_SpawnArea.X, m_SpawnArea.Width );
int y = Utility.Random( m_SpawnArea.Y, m_SpawnArea.Height );
 
int z = Map.GetAverageZ( x, y );
 
if( Map.CanSpawnMobile( new Point2D( x, y ), z ) )
return new Point3D( x, y, z );
 
/* try @ platform Z if map z fails */
else if( Map.CanSpawnMobile( new Point2D( x, y ), m_Platform.Location.Z ) )
return new Point3D( x, y, m_Platform.Location.Z );
}
 
return Location;
}
 
private const int Level1 = 4;  // First spawn level from 0-4 red skulls
private const int Level2 = 8;  // Second spawn level from 5-8 red skulls
private const int Level3 = 12; // Third spawn level from 9-12 red skulls
 
public int GetSubLevel()
{
int level = this.Level;
 
if( level <= Level1 )
return 0;
else if( level <= Level2 )
return 1;
else if( level <= Level3 )
return 2;
 
return 3;
}
 
public int GetSubLevelFor( Mobile m )
{
Type[][] types = ChampionSpawnInfo.GetInfo( m_Type ).SpawnTypes;
Type t = m.GetType();
 
for( int i = 0; i < types.GetLength( 0 ); i++ )
{
Type[] individualTypes = types[i];
 
for( int j = 0; j < individualTypes.Length; j++ )
{
if( t == individualTypes[j] )
return i;
}
}
 
return -1;
}
 
public Mobile Spawn()
{
Type[][] types = ChampionSpawnInfo.GetInfo( m_Type ).SpawnTypes;
 
int v = GetSubLevel();
 
if( v >= 0 && v < types.Length )
return Spawn( types[v] );
 
return null;
}
 
public Mobile Spawn( params Type[] types )
{
try
{
return Activator.CreateInstance( types[Utility.Random( types.Length )] ) as Mobile;
}
catch
{
return null;
}
}
 
public void Expire()
{
m_Kills = 0;
 
if( m_WhiteSkulls.Count == 0 )
{
// They didn't even get 20%, go back a level
 
if( Level > 0 )
--Level;
 
InvalidateProperties();
}
else
{
SetWhiteSkullCount( 0 );
}
 
m_ExpireTime = DateTime.UtcNow + m_ExpireDelay;
}
 
public Point3D GetRedSkullLocation( int index )
{
int x, y;
 
if( index < 5 )
{
x = index - 2;
y = -2;
}
else if( index < 9 )
{
x = 2;
y = index - 6;
}
else if( index < 13 )
{
x = 10 - index;
y = 2;
}
else
{
x = -2;
y = 14 - index;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public Point3D GetWhiteSkullLocation( int index )
{
int x, y;
 
switch( index )
{
default:
case 0: x = -1; y = -1; break;
case 1: x =  1; y = -1; break;
case 2: x =  1; y =  1; break;
case 3: x = -1; y =  1; break;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( "champion spawn" );
}
 
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
 
if( m_Active )
{
list.Add( 1060742 ); // active
list.Add( 1060658, "Type\t{0}", m_Type ); // ~1_val~: ~2_val~
list.Add( 1060659, "Level\t{0}", Level ); // ~1_val~: ~2_val~
list.Add( 1060660, "Kills\t{0} of {1} ({2:F1}%)", m_Kills, MaxKills, 100.0 * ((double)m_Kills / MaxKills) ); // ~1_val~: ~2_val~
//list.Add( 1060661, "Spawn Range\t{0}", m_SpawnRange ); // ~1_val~: ~2_val~
}
else
{
list.Add( 1060743 ); // inactive
}
}
 
public override void OnSingleClick( Mobile from )
{
if( m_Active )
LabelTo( from, "{0} (Active; Level: {1}; Kills: {2}/{3})", m_Type, Level, m_Kills, MaxKills );
else
LabelTo( from, "{0} (Inactive)", m_Type );
}
 
public override void OnDoubleClick( Mobile from )
{
from.SendGump( new PropertiesGump( from, this ) );
}
 
public override void OnLocationChange( Point3D oldLoc )
{
if( Deleted )
return;
 
if( m_Platform != null )
m_Platform.Location = new Point3D( X, Y, Z - 20 );
 
if( m_Altar != null )
m_Altar.Location = new Point3D( X, Y, Z - 15 );
 
if( m_Idol != null )
m_Idol.Location = new Point3D( X, Y, Z - 15 );
 
if( m_RedSkulls != null )
{
for( int i = 0; i < m_RedSkulls.Count; ++i )
m_RedSkulls[i].Location = GetRedSkullLocation( i );
}
 
if( m_WhiteSkulls != null )
{
for( int i = 0; i < m_WhiteSkulls.Count; ++i )
m_WhiteSkulls[i].Location = GetWhiteSkullLocation( i );
}
 
m_SpawnArea.X += Location.X - oldLoc.X;
m_SpawnArea.Y += Location.Y - oldLoc.Y;
 
UpdateRegion();
}
 
public override void OnMapChange()
{
if( Deleted )
return;
 
if( m_Platform != null )
m_Platform.Map = Map;
 
if( m_Altar != null )
m_Altar.Map = Map;
 
if( m_Idol != null )
m_Idol.Map = Map;
 
if( m_RedSkulls != null )
{
for( int i = 0; i < m_RedSkulls.Count; ++i )
m_RedSkulls[i].Map = Map;
}
 
if( m_WhiteSkulls != null )
{
for( int i = 0; i < m_WhiteSkulls.Count; ++i )
m_WhiteSkulls[i].Map = Map;
}
 
UpdateRegion();
}
 
public override void OnAfterDelete()
{
base.OnAfterDelete();
 
if( m_Platform != null )
m_Platform.Delete();
 
if( m_Altar != null )
m_Altar.Delete();
 
if( m_Idol != null )
m_Idol.Delete();
 
if( m_RedSkulls != null )
{
for( int i = 0; i < m_RedSkulls.Count; ++i )
m_RedSkulls[i].Delete();
 
m_RedSkulls.Clear();
}
 
if( m_WhiteSkulls != null )
{
for( int i = 0; i < m_WhiteSkulls.Count; ++i )
m_WhiteSkulls[i].Delete();
 
m_WhiteSkulls.Clear();
}
 
if( m_Creatures != null )
{
for( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile mob = m_Creatures[i];
 
if( !mob.Player )
mob.Delete();
}
 
m_Creatures.Clear();
}
 
if( m_Champion != null && !m_Champion.Player )
m_Champion.Delete();
 
Stop();
 
UpdateRegion();
}
 
public ChampionSpawn( Serial serial ) : base( serial )
{
}
 
public virtual void RegisterDamageTo( Mobile m )
{
if( m == null )
return;
 
foreach( DamageEntry de in m.DamageEntries )
{
if( de.HasExpired )
continue;
 
Mobile damager = de.Damager;
 
Mobile master = damager.GetDamageMaster( m );
 
if( master != null )
damager = master;
 
RegisterDamage( damager, de.DamageGiven );
}
}
 
public void RegisterDamage( Mobile from, int amount )
{
if( from == null || !from.Player )
return;
 
if( m_DamageEntries.ContainsKey( from ) )
m_DamageEntries[from] += amount;
else
m_DamageEntries.Add( from, amount );
}
 
public void AwardArtifact( Item artifact )
{
if (artifact == null )
return;
 
int totalDamage = 0;
 
Dictionary<Mobile, int> validEntries = new Dictionary<Mobile, int>();
 
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
{
if( IsEligible( kvp.Key, artifact ) )
{
validEntries.Add( kvp.Key, kvp.Value );
totalDamage += kvp.Value;
}
}
 
int randomDamage = Utility.RandomMinMax( 1, totalDamage );
 
totalDamage = 0;
 
foreach (KeyValuePair<Mobile, int> kvp in validEntries)
{
totalDamage += kvp.Value;
 
if( totalDamage >= randomDamage )
{
GiveArtifact( kvp.Key, artifact );
return;
}
}
 
artifact.Delete();
}
 
public void GiveArtifact( Mobile to, Item artifact )
{
if ( to == null || artifact == null )
return;
 
Container pack = to.Backpack;
 
if ( pack == null || !pack.TryDropItem( to, artifact, false ) )
artifact.Delete();
else
to.SendLocalizedMessage( 1062317 ); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
}
 
public bool IsEligible( Mobile m, Item Artifact )
{
return m.Player && m.Alive && m.Region != null && m.Region == m_Region && m.Backpack != null && m.Backpack.CheckHold( m, Artifact, false );
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int)6 ); // version
 
writer.Write( ( int ) m_SPawnSzMod );
writer.Write( m_DamageEntries.Count );
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
{
writer.Write( kvp.Key );
writer.Write( kvp.Value );
}
 
writer.Write( m_ConfinedRoaming );
writer.WriteItem<IdolOfTheChampion>( m_Idol );
writer.Write( m_HasBeenAdvanced );
writer.Write( m_SpawnArea );
 
writer.Write( m_RandomizeType );
 
//writer.Write( m_SpawnRange );
writer.Write( m_Kills );
 
writer.Write( (bool)m_Active );
writer.Write( (int)m_Type );
writer.Write( m_Creatures, true );
writer.Write( m_RedSkulls, true );
writer.Write( m_WhiteSkulls, true );
writer.WriteItem<ChampionPlatform>( m_Platform );
writer.WriteItem<ChampionAltar>( m_Altar );
writer.Write( m_ExpireDelay );
writer.WriteDeltaTime( m_ExpireTime );
writer.Write( m_Champion );
writer.Write( m_RestartDelay );
 
writer.Write( m_RestartTimer != null );
 
if( m_RestartTimer != null )
writer.WriteDeltaTime( m_RestartTime );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
m_DamageEntries = new Dictionary<Mobile, int>();
 
int version = reader.ReadInt();
 
switch( version )
{
case 6:
{
m_SPawnSzMod = reader.ReadInt();
goto case 5;
}
case 5:
{
int entries = reader.ReadInt();
Mobile m;
int damage;
for( int i = 0; i < entries; ++i )
{
m = reader.ReadMobile();
damage = reader.ReadInt();
 
if ( m == null )
continue;
 
m_DamageEntries.Add( m, damage );
}
 
goto case 4;
}
case 4:
{
m_ConfinedRoaming = reader.ReadBool();
m_Idol = reader.ReadItem<IdolOfTheChampion>();
m_HasBeenAdvanced = reader.ReadBool();
 
goto case 3;
}
case 3:
{
m_SpawnArea = reader.ReadRect2D();
 
goto case 2;
}
case 2:
{
m_RandomizeType = reader.ReadBool();
 
goto case 1;
}
case 1:
{
if( version < 3 )
{
int oldRange = reader.ReadInt();
 
m_SpawnArea = new Rectangle2D( new Point2D( X - oldRange, Y - oldRange ), new Point2D( X + oldRange, Y + oldRange ) );
}
 
m_Kills = reader.ReadInt();
 
goto case 0;
}
case 0:
{
if( version < 1 )
m_SpawnArea = new Rectangle2D( new Point2D( X - 24, Y - 24 ), new Point2D( X + 24, Y + 24 ) );//Default was 24
 
bool active = reader.ReadBool();
m_Type = (ChampionSpawnType)reader.ReadInt();
m_Creatures = reader.ReadStrongMobileList();
m_RedSkulls = reader.ReadStrongItemList();
m_WhiteSkulls = reader.ReadStrongItemList();
m_Platform = reader.ReadItem<ChampionPlatform>();
m_Altar = reader.ReadItem<ChampionAltar>();
m_ExpireDelay = reader.ReadTimeSpan();
m_ExpireTime = reader.ReadDeltaTime();
m_Champion = reader.ReadMobile();
m_RestartDelay = reader.ReadTimeSpan();
 
if( reader.ReadBool() )
{
m_RestartTime = reader.ReadDeltaTime();
BeginRestart( m_RestartTime - DateTime.UtcNow );
}
 
if( version < 4 )
{
m_Idol = new IdolOfTheChampion( this );
m_Idol.MoveToWorld( new Point3D( X, Y, Z - 15 ), Map );
}
 
if( m_Platform == null || m_Altar == null || m_Idol == null )
Delete();
else if( active )
Start();
 
break;
}
}
 
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( UpdateRegion ) );
}
}
 
public class ChampionSpawnRegion : BaseRegion
{
public override bool YoungProtected { get { return false; } }
 
private ChampionSpawn m_Spawn;
 
public ChampionSpawn ChampionSpawn
{
get { return m_Spawn; }
}
 
public ChampionSpawnRegion( ChampionSpawn spawn ) : base( null, spawn.Map, Region.Find( spawn.Location, spawn.Map ), spawn.SpawnArea )
{
m_Spawn = spawn;
}
 
public override bool AllowHousing( Mobile from, Point3D p )
{
return false;
}
 
public override void AlterLightLevel( Mobile m, ref int global, ref int personal )
{
base.AlterLightLevel( m, ref global, ref personal );
global = Math.Max( global, 1 + m_Spawn.Level );//This is a guesstimate.  TODO: Verify & get exact values // OSI testing: at 2 red skulls, light = 0x3 ; 1 red = 0x3.; 3 = 8; 9 = 0xD 8 = 0xD 12 = 0x12 10 = 0xD
}
}
 
public class IdolOfTheChampion : Item
{
private ChampionSpawn m_Spawn;
 
public ChampionSpawn Spawn { get { return m_Spawn; } }
 
public override string DefaultName
{
get { return "Idol of the Champion"; }
}
 
 
public IdolOfTheChampion( ChampionSpawn spawn ): base( 0x1F18 )
{
m_Spawn = spawn;
Movable = false;
}
 
public override void OnAfterDelete()
{
base.OnAfterDelete();
 
if ( m_Spawn != null )
m_Spawn.Delete();
}
 
public IdolOfTheChampion( Serial serial ) : base( serial )
{
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int) 0 ); // version
 
writer.Write( m_Spawn );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
int version = reader.ReadInt();
 
switch ( version )
{
case 0:
{
m_Spawn = reader.ReadItem() as ChampionSpawn;
 
if ( m_Spawn == null )
Delete();
 
break;
}
}
}
}
}
 

daat99

Moderator
Staff member
I don't see anything about "GetItemsInSpawnArea" in the code you posted.
Can you post both the code you are actually using and the exact error (no need to translate it, just copy/paste as it appears in the console).
 

zzluis12

Sorceror
Sorry i misspelled the scripts words

I have this : (from a RunUO 2.5 clean install)

Code:
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Regions;
using System.Collections.Generic;
 
namespace Server.Engines.CannedEvil
{
public class ChampionSpawn : Item
{
[CommandProperty( AccessLevel.GameMaster )]
public int SpawnSzMod
{
get
{
return ( m_SPawnSzMod < 1 || m_SPawnSzMod > 12 ) ? 12 : m_SPawnSzMod;
}
set
{
m_SPawnSzMod = ( value < 1 || value > 12 ) ? 12 : value;
}
}
private int m_SPawnSzMod;
 
private bool m_Active;
private bool m_RandomizeType;
private ChampionSpawnType m_Type;
private List<Mobile> m_Creatures;
private List<Item> m_RedSkulls;
private List<Item> m_WhiteSkulls;
private ChampionPlatform m_Platform;
private ChampionAltar m_Altar;
private int m_Kills;
private Mobile m_Champion;
 
//private int m_SpawnRange;
private Rectangle2D m_SpawnArea;
private ChampionSpawnRegion m_Region;
 
private TimeSpan m_ExpireDelay;
private DateTime m_ExpireTime;
 
private TimeSpan m_RestartDelay;
private DateTime m_RestartTime;
 
private Timer m_Timer, m_RestartTimer;
 
private IdolOfTheChampion m_Idol;
 
private bool m_HasBeenAdvanced;
private bool m_ConfinedRoaming;
 
private Dictionary<Mobile, int> m_DamageEntries;
 
[CommandProperty( AccessLevel.GameMaster )]
public bool ConfinedRoaming
{
get { return m_ConfinedRoaming; }
set { m_ConfinedRoaming = value; }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool HasBeenAdvanced
{
get { return m_HasBeenAdvanced; }
set { m_HasBeenAdvanced = value; }
}
 
[Constructable]
public ChampionSpawn() : base( 0xBD2 )
{
Movable = false;
Visible = false;
 
m_Creatures = new List<Mobile>();
m_RedSkulls = new List<Item>();
m_WhiteSkulls = new List<Item>();
 
m_Platform = new ChampionPlatform( this );
m_Altar = new ChampionAltar( this );
m_Idol = new IdolOfTheChampion( this );
 
m_ExpireDelay = TimeSpan.FromMinutes( 10.0 );
m_RestartDelay = TimeSpan.FromMinutes( 10.0 );
 
m_DamageEntries = new Dictionary<Mobile, int>();
 
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( SetInitialSpawnArea ) );
}
 
public void SetInitialSpawnArea()
{
//Previous default used to be 24;
SpawnArea = new Rectangle2D( new Point2D( X - 24, Y - 24 ), new Point2D( X + 24, Y + 24 ) );
}
 
public void UpdateRegion()
{
if( m_Region != null )
m_Region.Unregister();
 
if( !Deleted && this.Map != Map.Internal )
{
m_Region = new ChampionSpawnRegion( this );
m_Region.Register();
}
 
/*
if( m_Region == null )
{
m_Region = new ChampionSpawnRegion( this );
}
else
{
m_Region.Unregister();
//Why doesn't Region allow me to set it's map/Area meself? ><
m_Region = new ChampionSpawnRegion( this );
}
*/
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool RandomizeType
{
get { return m_RandomizeType; }
set { m_RandomizeType = value; }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Kills
{
get
{
return m_Kills;
}
set
{
m_Kills = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Rectangle2D SpawnArea
{
get
{
return m_SpawnArea;
}
set
{
m_SpawnArea = value;
InvalidateProperties();
UpdateRegion();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan RestartDelay
{
get
{
return m_RestartDelay;
}
set
{
m_RestartDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime RestartTime
{
get
{
return m_RestartTime;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan ExpireDelay
{
get
{
return m_ExpireDelay;
}
set
{
m_ExpireDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime ExpireTime
{
get
{
return m_ExpireTime;
}
set
{
m_ExpireTime = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSpawnType Type
{
get
{
return m_Type;
}
set
{
m_Type = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get
{
return m_Active;
}
set
{
if( value )
Start();
else
Stop();
 
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Champion
{
get
{
return m_Champion;
}
set
{
m_Champion = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Level
{
get
{
return m_RedSkulls.Count;
}
set
{
for( int i = m_RedSkulls.Count - 1; i >= value; --i )
{
m_RedSkulls[i].Delete();
m_RedSkulls.RemoveAt( i );
}
 
for( int i = m_RedSkulls.Count; i < value; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Hue = 0x26;
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetRedSkullLocation( i ), Map );
 
m_RedSkulls.Add( skull );
}
 
InvalidateProperties();
}
}
 
public int MaxKills
{
get
{
return ( m_SPawnSzMod * ( 250 / 12 ) ) - ( Level * m_SPawnSzMod );
}
}
 
public bool IsChampionSpawn( Mobile m )
{
return m_Creatures.Contains( m );
}
 
public void SetWhiteSkullCount( int val )
{
for( int i = m_WhiteSkulls.Count - 1; i >= val; --i )
{
m_WhiteSkulls[i].Delete();
m_WhiteSkulls.RemoveAt( i );
}
 
for( int i = m_WhiteSkulls.Count; i < val; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetWhiteSkullLocation( i ), Map );
 
m_WhiteSkulls.Add( skull );
 
Effects.PlaySound( skull.Location, skull.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( skull.X + 1, skull.Y + 1, skull.Z ), skull.Map, 0x3728, 10 );
}
}
 
public void Start()
{
if( m_Active || Deleted )
return;
 
m_Active = true;
m_HasBeenAdvanced = false;
 
if( m_Timer != null )
m_Timer.Stop();
 
m_Timer = new SliceTimer( this );
m_Timer.Start();
 
if( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if( m_Altar != null )
{
if ( m_Champion != null )
m_Altar.Hue = 0x26;
else
m_Altar.Hue = 0;
}
 
if ( m_Platform != null )
m_Platform.Hue = 0x452;
}
 
public void Stop()
{
if( !m_Active || Deleted )
return;
 
m_Active = false;
m_HasBeenAdvanced = false;
 
if( m_Timer != null )
m_Timer.Stop();
 
m_Timer = null;
 
if( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if( m_Altar != null )
m_Altar.Hue = 0;
 
if ( m_Platform != null )
m_Platform.Hue = 0x497;
}
 
public void BeginRestart( TimeSpan ts )
{
if( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTime = DateTime.UtcNow + ts;
 
m_RestartTimer = new RestartTimer( this, ts );
m_RestartTimer.Start();
}
 
public void EndRestart()
{
if( RandomizeType )
{
switch( Utility.Random( 5 ) )
{
case 0: Type = ChampionSpawnType.VerminHorde; break;
case 1: Type = ChampionSpawnType.UnholyTerror; break;
case 2: Type = ChampionSpawnType.ColdBlood; break;
case 3: Type = ChampionSpawnType.Abyss; break;
case 4: Type = ChampionSpawnType.Arachnid; break;
}
}
 
m_HasBeenAdvanced = false;
 
Start();
}
 
#region Scroll of Transcendence
private ScrollofTranscendence CreateRandomSoT( bool felucca )
{
int level = Utility.RandomMinMax( 1, 5 );
 
if ( felucca )
level += 5;
 
return ScrollofTranscendence.CreateRandom(level, level);
}
#endregion
 
public static void GiveScrollTo( Mobile killer, SpecialScroll scroll )
{
if( scroll == null || killer == null )//sanity
return;
 
if ( scroll is ScrollofTranscendence )
killer.SendLocalizedMessage( 1094936 ); // You have received a Scroll of Transcendence!
else
killer.SendLocalizedMessage( 1049524 ); // You have received a scroll of power!
 
if ( killer.Alive )
killer.AddToBackpack( scroll );
else
{
if( killer.Corpse != null && !killer.Corpse.Deleted )
killer.Corpse.DropItem( scroll );
else
killer.AddToBackpack( scroll );
}
 
// Justice reward
PlayerMobile pm = (PlayerMobile)killer;
for (int j = 0; j < pm.JusticeProtectors.Count; ++j)
{
Mobile prot = (Mobile)pm.JusticeProtectors[j];
 
if ( prot.Map != killer.Map || prot.Kills >= 5 || prot.Criminal || !JusticeVirtue.CheckMapRegion( killer, prot ) )
continue;
 
int chance = 0;
 
switch ( VirtueHelper.GetLevel( prot, VirtueName.Justice ) )
{
case VirtueLevel.Seeker: chance = 60; break;
case VirtueLevel.Follower: chance = 80; break;
case VirtueLevel.Knight: chance = 100; break;
}
 
if ( chance > Utility.Random( 100 ) )
{
try
{
prot.SendLocalizedMessage( 1049368 ); // You have been rewarded for your dedication to Justice!
 
SpecialScroll scrollDupe = Activator.CreateInstance( scroll.GetType() ) as SpecialScroll;
 
if ( scrollDupe != null )
{
scrollDupe.Skill = scroll.Skill;
scrollDupe.Value = scroll.Value;
prot.AddToBackpack( scrollDupe );
}
}
catch{}
}
}
}
 
public void OnSlice()
{
if( !m_Active || Deleted )
return;
 
if( m_Champion != null )
{
if( m_Champion.Deleted )
{
RegisterDamageTo( m_Champion );
 
if( m_Champion is BaseChampion )
AwardArtifact( ((BaseChampion)m_Champion).GetArtifact() );
 
m_DamageEntries.Clear();
 
if( m_Platform != null )
m_Platform.Hue = 0x497;
 
if( m_Altar != null )
{
m_Altar.Hue = 0;
 
if( !Core.ML || Map == Map.Felucca )
{
new StarRoomGate( true, m_Altar.Location, m_Altar.Map );
}
}
 
m_Champion = null;
Stop();
 
BeginRestart( m_RestartDelay );
}
}
else
{
int kills = m_Kills;
 
for ( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile m = m_Creatures[i];
 
if ( m.Deleted )
{
if( m.Corpse != null && !m.Corpse.Deleted )
{
((Corpse)m.Corpse).BeginDecay( TimeSpan.FromMinutes( 1 ));
}
m_Creatures.RemoveAt( i );
--i;
++m_Kills;
 
Mobile killer = m.FindMostRecentDamager( false );
 
RegisterDamageTo( m );
 
if( killer is BaseCreature )
killer = ((BaseCreature)killer).GetMaster();
 
if( killer is PlayerMobile )
{
#region Scroll of Transcendence
if ( Core.ML )
{
if ( Map == Map.Felucca )
{
if ( Utility.RandomDouble() < 0.001 )
{
PlayerMobile pm = (PlayerMobile)killer;
double random = Utility.Random ( 49 );
 
if ( random <= 24 )
{
ScrollofTranscendence SoTF = CreateRandomSoT( true );
GiveScrollTo( pm, (SpecialScroll)SoTF );
}
else
{
PowerScroll PS = PowerScroll.CreateRandomNoCraft(5, 5);
GiveScrollTo( pm, (SpecialScroll)PS );
}
}
}
 
if ( Map == Map.Ilshenar || Map == Map.Tokuno || Map == Map.Malas )
{
if ( Utility.RandomDouble() < 0.0015 )
{
killer.SendLocalizedMessage( 1094936 ); // You have received a Scroll of Transcendence!
ScrollofTranscendence SoTT = CreateRandomSoT( false );
killer.AddToBackpack( SoTT );
}
}
}
#endregion
 
int mobSubLevel = GetSubLevelFor( m ) + 1;
 
if( mobSubLevel >= 0 )
{
bool gainedPath = false;
 
int pointsToGain = mobSubLevel * 40;
 
if( VirtueHelper.Award( killer, VirtueName.Valor, pointsToGain, ref gainedPath ) )
{
if( gainedPath )
m.SendLocalizedMessage( 1054032 ); // You have gained a path in Valor!
else
m.SendLocalizedMessage( 1054030 ); // You have gained in Valor!
 
//No delay on Valor gains
}
 
PlayerMobile.ChampionTitleInfo info = ((PlayerMobile)killer).ChampionTitles;
 
info.Award( m_Type, mobSubLevel );
}
}
}
}
 
// Only really needed once.
if ( m_Kills > kills )
InvalidateProperties();
 
double n = m_Kills / (double)MaxKills;
int p = (int)(n * 100);
 
if( p >= 90 )
AdvanceLevel();
else if( p > 0 )
SetWhiteSkullCount( p / 20 );
 
if( DateTime.UtcNow >= m_ExpireTime )
Expire();
 
Respawn();
}
}
 
public void AdvanceLevel()
{
m_ExpireTime = DateTime.UtcNow + m_ExpireDelay;
 
if( Level < 16 )
{
m_Kills = 0;
++Level;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
if( m_Altar != null )
{
Effects.PlaySound( m_Altar.Location, m_Altar.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( m_Altar.X + 1, m_Altar.Y + 1, m_Altar.Z ), m_Altar.Map, 0x3728, 10 );
}
}
else
{
SpawnChampion();
}
}
 
public void SpawnChampion()
{
if( m_Altar != null )
m_Altar.Hue = 0x26;
 
if ( m_Platform != null )
m_Platform.Hue = 0x452;
 
m_Kills = 0;
Level = 0;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
try
{
m_Champion = Activator.CreateInstance( ChampionSpawnInfo.GetInfo( m_Type ).Champion ) as Mobile;
}
catch { }
 
if( m_Champion != null )
m_Champion.MoveToWorld( new Point3D( X, Y, Z - 15 ), Map );
}
 
public void Respawn()
{
if( !m_Active || Deleted || m_Champion != null )
return;
 
while( m_Creatures.Count < ( ( m_SPawnSzMod * ( 200 / 12 ) ) ) - ( GetSubLevel() * ( m_SPawnSzMod * ( 40 / 12 ) ) ) )
{
Mobile m = Spawn();
 
if( m == null )
return;
 
Point3D loc = GetSpawnLocation();
 
// Allow creatures to turn into Paragons at Ilshenar champions.
m.OnBeforeSpawn( loc, Map );
 
m_Creatures.Add( m );
m.MoveToWorld( loc, Map );
 
if( m is BaseCreature )
{
BaseCreature bc = m as BaseCreature;
bc.Tamable = false;
 
if( !m_ConfinedRoaming )
{
bc.Home = this.Location;
bc.RangeHome = (int)(Math.Sqrt( m_SpawnArea.Width * m_SpawnArea.Width + m_SpawnArea.Height * m_SpawnArea.Height )/2);
}
else
{
bc.Home = bc.Location;
 
Point2D xWall1 = new Point2D( m_SpawnArea.X, bc.Y );
Point2D xWall2 = new Point2D( m_SpawnArea.X + m_SpawnArea.Width, bc.Y );
Point2D yWall1 = new Point2D( bc.X, m_SpawnArea.Y );
Point2D yWall2 = new Point2D( bc.X, m_SpawnArea.Y + m_SpawnArea.Height );
 
double minXDist = Math.Min( bc.GetDistanceToSqrt( xWall1 ), bc.GetDistanceToSqrt( xWall2 ) );
double minYDist = Math.Min( bc.GetDistanceToSqrt( yWall1 ), bc.GetDistanceToSqrt( yWall2 ) );
 
bc.RangeHome = (int)Math.Min( minXDist, minYDist );
}
}
}
}
 
public Point3D GetSpawnLocation()
{
Map map = Map;
 
if( map == null )
return Location;
 
// Try 20 times to find a spawnable location.
for( int i = 0; i < 20; i++ )
{
/*
int x = Location.X + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
int y = Location.Y + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
*/
 
int x = Utility.Random( m_SpawnArea.X, m_SpawnArea.Width );
int y = Utility.Random( m_SpawnArea.Y, m_SpawnArea.Height );
 
int z = Map.GetAverageZ( x, y );
 
if( Map.CanSpawnMobile( new Point2D( x, y ), z ) )
return new Point3D( x, y, z );
 
/* try @ platform Z if map z fails */
else if( Map.CanSpawnMobile( new Point2D( x, y ), m_Platform.Location.Z ) )
return new Point3D( x, y, m_Platform.Location.Z );
}
 
return Location;
}
 
private const int Level1 = 4;  // First spawn level from 0-4 red skulls
private const int Level2 = 8;  // Second spawn level from 5-8 red skulls
private const int Level3 = 12; // Third spawn level from 9-12 red skulls
 
public int GetSubLevel()
{
int level = this.Level;
 
if( level <= Level1 )
return 0;
else if( level <= Level2 )
return 1;
else if( level <= Level3 )
return 2;
 
return 3;
}
 
public int GetSubLevelFor( Mobile m )
{
Type[][] types = ChampionSpawnInfo.GetInfo( m_Type ).SpawnTypes;
Type t = m.GetType();
 
for( int i = 0; i < types.GetLength( 0 ); i++ )
{
Type[] individualTypes = types[i];
 
for( int j = 0; j < individualTypes.Length; j++ )
{
if( t == individualTypes[j] )
return i;
}
}
 
return -1;
}
 
public Mobile Spawn()
{
Type[][] types = ChampionSpawnInfo.GetInfo( m_Type ).SpawnTypes;
 
int v = GetSubLevel();
 
if( v >= 0 && v < types.Length )
return Spawn( types[v] );
 
return null;
}
 
public Mobile Spawn( params Type[] types )
{
try
{
return Activator.CreateInstance( types[Utility.Random( types.Length )] ) as Mobile;
}
catch
{
return null;
}
}
 
public void Expire()
{
m_Kills = 0;
 
if( m_WhiteSkulls.Count == 0 )
{
// They didn't even get 20%, go back a level
 
if( Level > 0 )
--Level;
 
InvalidateProperties();
}
else
{
SetWhiteSkullCount( 0 );
}
 
m_ExpireTime = DateTime.UtcNow + m_ExpireDelay;
}
 
public Point3D GetRedSkullLocation( int index )
{
int x, y;
 
if( index < 5 )
{
x = index - 2;
y = -2;
}
else if( index < 9 )
{
x = 2;
y = index - 6;
}
else if( index < 13 )
{
x = 10 - index;
y = 2;
}
else
{
x = -2;
y = 14 - index;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public Point3D GetWhiteSkullLocation( int index )
{
int x, y;
 
switch( index )
{
default:
case 0: x = -1; y = -1; break;
case 1: x =  1; y = -1; break;
case 2: x =  1; y =  1; break;
case 3: x = -1; y =  1; break;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( "champion spawn" );
}
 
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
 
if( m_Active )
{
list.Add( 1060742 ); // active
list.Add( 1060658, "Type\t{0}", m_Type ); // ~1_val~: ~2_val~
list.Add( 1060659, "Level\t{0}", Level ); // ~1_val~: ~2_val~
list.Add( 1060660, "Kills\t{0} of {1} ({2:F1}%)", m_Kills, MaxKills, 100.0 * ((double)m_Kills / MaxKills) ); // ~1_val~: ~2_val~
//list.Add( 1060661, "Spawn Range\t{0}", m_SpawnRange ); // ~1_val~: ~2_val~
}
else
{
list.Add( 1060743 ); // inactive
}
}
 
public override void OnSingleClick( Mobile from )
{
if( m_Active )
LabelTo( from, "{0} (Active; Level: {1}; Kills: {2}/{3})", m_Type, Level, m_Kills, MaxKills );
else
LabelTo( from, "{0} (Inactive)", m_Type );
}
 
public override void OnDoubleClick( Mobile from )
{
from.SendGump( new PropertiesGump( from, this ) );
}
 
public override void OnLocationChange( Point3D oldLoc )
{
if( Deleted )
return;
 
if( m_Platform != null )
m_Platform.Location = new Point3D( X, Y, Z - 20 );
 
if( m_Altar != null )
m_Altar.Location = new Point3D( X, Y, Z - 15 );
 
if( m_Idol != null )
m_Idol.Location = new Point3D( X, Y, Z - 15 );
 
if( m_RedSkulls != null )
{
for( int i = 0; i < m_RedSkulls.Count; ++i )
m_RedSkulls[i].Location = GetRedSkullLocation( i );
}
 
if( m_WhiteSkulls != null )
{
for( int i = 0; i < m_WhiteSkulls.Count; ++i )
m_WhiteSkulls[i].Location = GetWhiteSkullLocation( i );
}
 
m_SpawnArea.X += Location.X - oldLoc.X;
m_SpawnArea.Y += Location.Y - oldLoc.Y;
 
UpdateRegion();
}
 
public override void OnMapChange()
{
if( Deleted )
return;
 
if( m_Platform != null )
m_Platform.Map = Map;
 
if( m_Altar != null )
m_Altar.Map = Map;
 
if( m_Idol != null )
m_Idol.Map = Map;
 
if( m_RedSkulls != null )
{
for( int i = 0; i < m_RedSkulls.Count; ++i )
m_RedSkulls[i].Map = Map;
}
 
if( m_WhiteSkulls != null )
{
for( int i = 0; i < m_WhiteSkulls.Count; ++i )
m_WhiteSkulls[i].Map = Map;
}
 
UpdateRegion();
}
 
public override void OnAfterDelete()
{
base.OnAfterDelete();
 
if( m_Platform != null )
m_Platform.Delete();
 
if( m_Altar != null )
m_Altar.Delete();
 
if( m_Idol != null )
m_Idol.Delete();
 
if( m_RedSkulls != null )
{
for( int i = 0; i < m_RedSkulls.Count; ++i )
m_RedSkulls[i].Delete();
 
m_RedSkulls.Clear();
}
 
if( m_WhiteSkulls != null )
{
for( int i = 0; i < m_WhiteSkulls.Count; ++i )
m_WhiteSkulls[i].Delete();
 
m_WhiteSkulls.Clear();
}
 
if( m_Creatures != null )
{
for( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile mob = m_Creatures[i];
 
if( !mob.Player )
mob.Delete();
}
 
m_Creatures.Clear();
}
 
if( m_Champion != null && !m_Champion.Player )
m_Champion.Delete();
 
Stop();
 
UpdateRegion();
}
 
public ChampionSpawn( Serial serial ) : base( serial )
{
}
 
public virtual void RegisterDamageTo( Mobile m )
{
if( m == null )
return;
 
foreach( DamageEntry de in m.DamageEntries )
{
if( de.HasExpired )
continue;
 
Mobile damager = de.Damager;
 
Mobile master = damager.GetDamageMaster( m );
 
if( master != null )
damager = master;
 
RegisterDamage( damager, de.DamageGiven );
}
}
 
public void RegisterDamage( Mobile from, int amount )
{
if( from == null || !from.Player )
return;
 
if( m_DamageEntries.ContainsKey( from ) )
m_DamageEntries[from] += amount;
else
m_DamageEntries.Add( from, amount );
}
 
public void AwardArtifact( Item artifact )
{
if (artifact == null )
return;
 
int totalDamage = 0;
 
Dictionary<Mobile, int> validEntries = new Dictionary<Mobile, int>();
 
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
{
if( IsEligible( kvp.Key, artifact ) )
{
validEntries.Add( kvp.Key, kvp.Value );
totalDamage += kvp.Value;
}
}
 
int randomDamage = Utility.RandomMinMax( 1, totalDamage );
 
totalDamage = 0;
 
foreach (KeyValuePair<Mobile, int> kvp in validEntries)
{
totalDamage += kvp.Value;
 
if( totalDamage >= randomDamage )
{
GiveArtifact( kvp.Key, artifact );
return;
}
}
 
artifact.Delete();
}
 
public void GiveArtifact( Mobile to, Item artifact )
{
if ( to == null || artifact == null )
return;
 
Container pack = to.Backpack;
 
if ( pack == null || !pack.TryDropItem( to, artifact, false ) )
artifact.Delete();
else
to.SendLocalizedMessage( 1062317 ); // For your valor in combating the fallen beast, a special artifact has been bestowed on you.
}
 
public bool IsEligible( Mobile m, Item Artifact )
{
return m.Player && m.Alive && m.Region != null && m.Region == m_Region && m.Backpack != null && m.Backpack.CheckHold( m, Artifact, false );
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int)6 ); // version
 
writer.Write( ( int ) m_SPawnSzMod );
writer.Write( m_DamageEntries.Count );
foreach (KeyValuePair<Mobile, int> kvp in m_DamageEntries)
{
writer.Write( kvp.Key );
writer.Write( kvp.Value );
}
 
writer.Write( m_ConfinedRoaming );
writer.WriteItem<IdolOfTheChampion>( m_Idol );
writer.Write( m_HasBeenAdvanced );
writer.Write( m_SpawnArea );
 
writer.Write( m_RandomizeType );
 
//writer.Write( m_SpawnRange );
writer.Write( m_Kills );
 
writer.Write( (bool)m_Active );
writer.Write( (int)m_Type );
writer.Write( m_Creatures, true );
writer.Write( m_RedSkulls, true );
writer.Write( m_WhiteSkulls, true );
writer.WriteItem<ChampionPlatform>( m_Platform );
writer.WriteItem<ChampionAltar>( m_Altar );
writer.Write( m_ExpireDelay );
writer.WriteDeltaTime( m_ExpireTime );
writer.Write( m_Champion );
writer.Write( m_RestartDelay );
 
writer.Write( m_RestartTimer != null );
 
if( m_RestartTimer != null )
writer.WriteDeltaTime( m_RestartTime );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
m_DamageEntries = new Dictionary<Mobile, int>();
 
int version = reader.ReadInt();
 
switch( version )
{
case 6:
{
m_SPawnSzMod = reader.ReadInt();
goto case 5;
}
case 5:
{
int entries = reader.ReadInt();
Mobile m;
int damage;
for( int i = 0; i < entries; ++i )
{
m = reader.ReadMobile();
damage = reader.ReadInt();
 
if ( m == null )
continue;
 
m_DamageEntries.Add( m, damage );
}
 
goto case 4;
}
case 4:
{
m_ConfinedRoaming = reader.ReadBool();
m_Idol = reader.ReadItem<IdolOfTheChampion>();
m_HasBeenAdvanced = reader.ReadBool();
 
goto case 3;
}
case 3:
{
m_SpawnArea = reader.ReadRect2D();
 
goto case 2;
}
case 2:
{
m_RandomizeType = reader.ReadBool();
 
goto case 1;
}
case 1:
{
if( version < 3 )
{
int oldRange = reader.ReadInt();
 
m_SpawnArea = new Rectangle2D( new Point2D( X - oldRange, Y - oldRange ), new Point2D( X + oldRange, Y + oldRange ) );
}
 
m_Kills = reader.ReadInt();
 
goto case 0;
}
case 0:
{
if( version < 1 )
m_SpawnArea = new Rectangle2D( new Point2D( X - 24, Y - 24 ), new Point2D( X + 24, Y + 24 ) );//Default was 24
 
bool active = reader.ReadBool();
m_Type = (ChampionSpawnType)reader.ReadInt();
m_Creatures = reader.ReadStrongMobileList();
m_RedSkulls = reader.ReadStrongItemList();
m_WhiteSkulls = reader.ReadStrongItemList();
m_Platform = reader.ReadItem<ChampionPlatform>();
m_Altar = reader.ReadItem<ChampionAltar>();
m_ExpireDelay = reader.ReadTimeSpan();
m_ExpireTime = reader.ReadDeltaTime();
m_Champion = reader.ReadMobile();
m_RestartDelay = reader.ReadTimeSpan();
 
if( reader.ReadBool() )
{
m_RestartTime = reader.ReadDeltaTime();
BeginRestart( m_RestartTime - DateTime.UtcNow );
}
 
if( version < 4 )
{
m_Idol = new IdolOfTheChampion( this );
m_Idol.MoveToWorld( new Point3D( X, Y, Z - 15 ), Map );
}
 
if( m_Platform == null || m_Altar == null || m_Idol == null )
Delete();
else if( active )
Start();
 
break;
}
}
 
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( UpdateRegion ) );
}
}
 
public class ChampionSpawnRegion : BaseRegion
{
public override bool YoungProtected { get { return false; } }
 
private ChampionSpawn m_Spawn;
 
public ChampionSpawn ChampionSpawn
{
get { return m_Spawn; }
}
 
public ChampionSpawnRegion( ChampionSpawn spawn ) : base( null, spawn.Map, Region.Find( spawn.Location, spawn.Map ), spawn.SpawnArea )
{
m_Spawn = spawn;
}
 
public override bool AllowHousing( Mobile from, Point3D p )
{
return false;
}
 
public override void AlterLightLevel( Mobile m, ref int global, ref int personal )
{
base.AlterLightLevel( m, ref global, ref personal );
global = Math.Max( global, 1 + m_Spawn.Level );//This is a guesstimate.  TODO: Verify & get exact values // OSI testing: at 2 red skulls, light = 0x3 ; 1 red = 0x3.; 3 = 8; 9 = 0xD 8 = 0xD 12 = 0x12 10 = 0xD
}
}
 
public class IdolOfTheChampion : Item
{
private ChampionSpawn m_Spawn;
 
public ChampionSpawn Spawn { get { return m_Spawn; } }
 
public override string DefaultName
{
get { return "Idol of the Champion"; }
}
 
 
public IdolOfTheChampion( ChampionSpawn spawn ): base( 0x1F18 )
{
m_Spawn = spawn;
Movable = false;
}
 
public override void OnAfterDelete()
{
base.OnAfterDelete();
 
if ( m_Spawn != null )
m_Spawn.Delete();
}
 
public IdolOfTheChampion( Serial serial ) : base( serial )
{
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int) 0 ); // version
 
writer.Write( m_Spawn );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
int version = reader.ReadInt();
 
switch ( version )
{
case 0:
{
m_Spawn = reader.ReadItem() as ChampionSpawn;
 
if ( m_Spawn == null )
Delete();
 
break;
}
}
}
}
}


And i'm trying to make the A_Li_N champion spawner (from 1.0 RunUO core) :

Code:
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
 
namespace Server.Engines.CannedEvil
{
public class ChampionSpawn : Item
{
private bool m_Active;
private bool m_RandomizeType;
private ChampionSpawnType m_Type;
private ArrayList m_Creatures;
private ArrayList m_RedSkulls;
private ArrayList m_WhiteSkulls;
private ChampionPlatform m_Platform;
private ChampionAltar m_Altar;
private int m_Kills;
private Mobile m_Champion;
private int m_SpawnRange;
 
private TimeSpan m_ExpireDelay;
private DateTime m_ExpireTime;
 
private TimeSpan m_RestartDelay;
private DateTime m_RestartTime;
 
private Timer m_Timer, m_RestartTimer;
 
[Constructable]
public ChampionSpawn() : base( 0xBD2 )
{
Movable = false;
Visible = false;
 
m_Creatures = new ArrayList();
m_RedSkulls = new ArrayList();
m_WhiteSkulls = new ArrayList();
 
m_Platform = new ChampionPlatform( this );
m_Altar = new ChampionAltar( this );
 
m_ExpireDelay = TimeSpan.FromMinutes( 10.0 );
m_RestartDelay = TimeSpan.FromMinutes( 5.0 );
 
m_SpawnRange = 24;
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool RandomizeType
{
get{ return m_RandomizeType; }
set{ m_RandomizeType = value; }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Kills
{
get
{
return m_Kills;
}
set
{
m_Kills = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int SpawnRange
{
get
{
return m_SpawnRange;
}
set
{
m_SpawnRange = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan RestartDelay
{
get
{
return m_RestartDelay;
}
set
{
m_RestartDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime RestartTime
{
get
{
return m_RestartTime;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan ExpireDelay
{
get
{
return m_ExpireDelay;
}
set
{
m_ExpireDelay = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public DateTime ExpireTime
{
get
{
return m_ExpireTime;
}
set
{
m_ExpireTime = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public ChampionSpawnType Type
{
get
{
return m_Type;
}
set
{
m_Type = value;
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get
{
return m_Active;
}
set
{
if ( value )
Start();
else
Stop();
 
InvalidateProperties();
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Champion
{
get
{
return m_Champion;
}
set
{
m_Champion = value;
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public int Level
{
get
{
return m_RedSkulls.Count;
}
set
{
for ( int i = m_RedSkulls.Count - 1; i >= value; --i )
{
((Item)m_RedSkulls[i]).Delete();
m_RedSkulls.RemoveAt( i );
}
 
for ( int i = m_RedSkulls.Count; i < value; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Hue = 0x26;
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetRedSkullLocation( i ), Map );
 
m_RedSkulls.Add( skull );
}
 
InvalidateProperties();
}
}
 
public int MaxKills
{
get
{
return 250 - (Level * 12);
}
}
 
public void SetWhiteSkullCount( int val )
{
for ( int i = m_WhiteSkulls.Count - 1; i >= val; --i )
{
((Item)m_WhiteSkulls[i]).Delete();
m_WhiteSkulls.RemoveAt( i );
}
 
for ( int i = m_WhiteSkulls.Count; i < val; ++i )
{
Item skull = new Item( 0x1854 );
 
skull.Movable = false;
skull.Light = LightType.Circle150;
 
skull.MoveToWorld( GetWhiteSkullLocation( i ), Map );
 
m_WhiteSkulls.Add( skull );
 
Effects.PlaySound( skull.Location, skull.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( skull.X + 1, skull.Y + 1, skull.Z ), skull.Map, 0x3728, 10 );
 
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInRange( Location, m_SpawnRange ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner
}
}
 
public void Start()
{
if ( m_Active || Deleted )
return;
 
m_Active = true;
 
if ( m_Timer != null )
m_Timer.Stop();
 
m_Timer = new SliceTimer( this );
m_Timer.Start();
 
if ( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if ( m_Altar != null )
m_Altar.Hue = 0;
}
 
public void Stop()
{
if ( !m_Active || Deleted )
return;
 
m_Active = false;
 
if ( m_Timer != null )
m_Timer.Stop();
 
m_Timer = null;
 
if ( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTimer = null;
 
if ( m_Altar != null )
m_Altar.Hue = 0;
}
 
public void BeginRestart( TimeSpan ts )
{
if ( m_RestartTimer != null )
m_RestartTimer.Stop();
 
m_RestartTime = DateTime.Now + ts;
 
m_RestartTimer = new RestartTimer( this, ts );
m_RestartTimer.Start();
}
 
public void EndRestart()
{
if ( RandomizeType )
{
switch ( Utility.Random( 5 ) )
{
case 0: Type = ChampionSpawnType.VerminHorde; break;
case 1: Type = ChampionSpawnType.UnholyTerror; break;
case 2: Type = ChampionSpawnType.ColdBlood; break;
case 3: Type = ChampionSpawnType.Abyss; break;
case 4: Type = ChampionSpawnType.Arachnid; break;
}
}
 
Start();
}
 
public void OnSlice()
{
if ( !m_Active || Deleted )
return;
 
if ( m_Champion != null )
{
if ( m_Champion.Deleted )
{
if ( m_Altar != null )
{
m_Altar.Hue = 0;
new StarRoomGate( true, m_Altar.Location, m_Altar.Map );
}
 
m_Champion = null;
Stop();
 
BeginRestart( m_RestartDelay );
}
}
else
{
for ( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile m = (Mobile)m_Creatures[i];
 
if ( m.Deleted )
{
m_Creatures.RemoveAt( i );
--i;
++m_Kills;
InvalidateProperties();
}
}
 
double n = m_Kills / (double)MaxKills;
int p = (int)(n * 100);
 
if ( p >= 90 )
AdvanceLevel();
else if ( p > 0 )
SetWhiteSkullCount( p / 20 );
 
if ( DateTime.Now >= m_ExpireTime )
Expire();
 
Respawn();
}
}
 
public void AdvanceLevel()
{
m_ExpireTime = DateTime.Now + m_ExpireDelay;
 
if ( Level < 16 )
{
m_Kills = 0;
++Level;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
if ( m_Altar != null )
{
Effects.PlaySound( m_Altar.Location, m_Altar.Map, 0x29 );
Effects.SendLocationEffect( new Point3D( m_Altar.X + 1, m_Altar.Y + 1, m_Altar.Z ), m_Altar.Map, 0x3728, 10 );
}
}
else
{
SpawnChampion();
}
}
 
public void SpawnChampion()
{
if ( m_Altar != null )
m_Altar.Hue = 0x26;
 
m_Kills = 0;
Level = 0;
InvalidateProperties();
SetWhiteSkullCount( 0 );
 
switch ( m_Type )
{
default:
case ChampionSpawnType.UnholyTerror: m_Champion = new Neira(); break;
case ChampionSpawnType.VerminHorde: m_Champion = new Barracoon(); break;
case ChampionSpawnType.ForestLord: m_Champion = new LordOaks(); break;
case ChampionSpawnType.ColdBlood: m_Champion = new Rikktor(); break;
case ChampionSpawnType.Arachnid: m_Champion = new Mephitis(); break;
case ChampionSpawnType.Abyss: m_Champion = new Semidar(); break;
}
 
m_Champion.MoveToWorld( new Point3D( X, Y, Z - 15 ), Map );
}
 
public void Respawn()
{
if ( !m_Active || Deleted || m_Champion != null )
return;
 
while ( m_Creatures.Count < (50 - (GetSubLevel() * 10)) )
{
Mobile m = Spawn();
 
if ( m == null )
return;
 
m_Creatures.Add( m );
m.MoveToWorld( GetSpawnLocation(), Map );
 
if ( m is BaseCreature )
{
((BaseCreature)m).Tamable = false;
((BaseCreature)m).Home = Location;
((BaseCreature)m).RangeHome = m_SpawnRange;
}
}
}
 
public Point3D GetSpawnLocation()
{
Map map = Map;
 
if ( map == null )
return Location;
 
// Try 20 times to find a spawnable location.
for ( int i = 0; i < 20; i++ )
{
int x = Location.X + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
int y = Location.Y + (Utility.Random( (m_SpawnRange * 2) + 1 ) - m_SpawnRange);
int z = Map.GetAverageZ( x, y );
 
if ( Map.CanSpawnMobile( new Point2D( x, y ), z ) )
return new Point3D( x, y, z );
}
 
return Location;
}
 
private const int Level1 = 5;  // First spawn level from 0-5 red skulls
private const int Level2 = 9;  // Second spawn level from 6-9 red skulls
private const int Level3 = 13; // Third spawn level from 10-13 red skulls
 
private static Type[][][] m_Types = new Type[6][][]
{
new Type[][]
{// Abyss
new Type[]{ typeof( Mongbat ), typeof( Imp ) },// Level 1
new Type[]{ typeof( Gargoyle ), typeof( Harpy ) },// Level 2
new Type[]{ typeof( FireGargoyle ), typeof( StoneGargoyle ) },// Level 3
new Type[]{ typeof( Daemon ), typeof( Succubus ) }// Level 4
},
new Type[][]
{// Arachnid
new Type[]{ typeof( Scorpion ), typeof( GiantSpider ) },// Level 1
new Type[]{ typeof( TerathanDrone ), typeof( TerathanWarrior ) },// Level 2
new Type[]{ typeof( DreadSpider ), typeof( TerathanMatriarch ) },// Level 3
new Type[]{ typeof( PoisonElemental ), typeof( TerathanAvenger ) }// Level 4
},
new Type[][]
{// Cold Blood
new Type[]{ typeof( Lizardman ), typeof( Snake ) },// Level 1
new Type[]{ typeof( LavaLizard ), typeof( OphidianWarrior ) },// Level 2
new Type[]{ typeof( Drake ), typeof( OphidianArchmage ) },// Level 3
new Type[]{ typeof( Dragon ), typeof( OphidianKnight ) }// Level 4
},
new Type[][]
{// Forest Lord
new Type[]{ typeof( Pixie ), typeof( ShadowWisp ) },// Level 1
new Type[]{ typeof( Kirin ), typeof( Wisp ) },// Level 2
new Type[]{ typeof( Centaur ), typeof( Unicorn ) },// Level 3
new Type[]{ typeof( EtherealWarrior ), typeof( SerpentineDragon ) }// Level 4
},
new Type[][]
{// Vermin Horde
new Type[]{ typeof( GiantRat ), typeof( Slime ) },// Level 1
new Type[]{ typeof( DireWolf ), typeof( Ratman ) },// Level 2
new Type[]{ typeof( HellHound ), typeof( RatmanMage ) },// Level 3
new Type[]{ typeof( RatmanArcher ), typeof( SilverSerpent ) }// Level 4
},
new Type[][]
{// Unholy Terror
new Type[]{ typeof( Bogle ), typeof( Ghoul ), typeof( Shade ), typeof( Spectre ), typeof( Wraith ) },// Level 1
new Type[]{ typeof( BoneMagi ), typeof( Mummy ), typeof( SkeletalMage ) },// Level 2
new Type[]{ typeof( BoneKnight ), typeof( Lich ), typeof( SkeletalKnight ) },// Level 3
new Type[]{ typeof( LichLord ), typeof( RottingCorpse ) }// Level 4
}
};
 
public int GetSubLevel()
{
int level = this.Level;
 
if ( level <= Level1 )
return 0;
else if ( level <= Level2 )
return 1;
else if ( level <= Level3 )
return 2;
 
return 3;
}
 
public Mobile Spawn()
{
int v = (int)m_Type;
 
if ( v >= 0 && v < m_Types.Length )
{
Type[][] types = m_Types[v];
 
v = GetSubLevel();
 
if ( v >= 0 && v < types.Length )
return Spawn( types[v] );
}
 
return null;
}
 
public Mobile Spawn( params Type[] types )
{
try
{
return Activator.CreateInstance( types[Utility.Random( types.Length )] ) as Mobile;
}
catch
{
return null;
}
}
 
public void Expire()
{
m_Kills = 0;
 
if ( m_WhiteSkulls.Count == 0 )
{
// They didn't even get 20%, go back a level
 
if ( Level > 0 )
--Level;
 
InvalidateProperties();
}
else
{
SetWhiteSkullCount( 0 );
}
 
m_ExpireTime = DateTime.Now + m_ExpireDelay;
}
 
public Point3D GetRedSkullLocation( int index )
{
int x, y;
 
if ( index < 5 )
{
x = index - 2;
y = -2;
}
else if ( index < 9 )
{
x = 2;
y = index - 6;
}
else if ( index < 13 )
{
x = 10 - index;
y = 2;
}
else
{
x = -2;
y = 14 - index;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public Point3D GetWhiteSkullLocation( int index )
{
int x, y;
 
switch ( index )
{
default:
case 0: x = -1; y = -1; break;
case 1: x =  1; y = -1; break;
case 2: x =  1; y =  1; break;
case 3: x = -1; y =  1; break;
}
 
return new Point3D( X + x, Y + y, Z - 15 );
}
 
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( "champion spawn" );
}
 
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
 
if ( m_Active )
{
list.Add( 1060742 ); // active
list.Add( 1060658, "Type\t{0}", m_Type ); // ~1_val~: ~2_val~
list.Add( 1060659, "Level\t{0}", Level ); // ~1_val~: ~2_val~
list.Add( 1060660, "Kills\t{0} of {1} ({2:F1}%)", m_Kills, MaxKills, 100.0 * ((double)m_Kills / MaxKills) ); // ~1_val~: ~2_val~
list.Add( 1060661, "Spawn Range\t{0}", m_SpawnRange ); // ~1_val~: ~2_val~
}
else
{
list.Add( 1060743 ); // inactive
}
}
 
public override void OnSingleClick( Mobile from )
{
if ( m_Active )
LabelTo( from, "{0} (Active; Level: {1}; Kills: {2}/{3})", m_Type, Level, m_Kills, MaxKills );
else
LabelTo( from, "{0} (Inactive)", m_Type );
}
 
public override void OnDoubleClick( Mobile from )
{
from.SendGump( new PropertiesGump( from, this ) );
}
 
public override void OnLocationChange( Point3D oldLoc )
{
if ( Deleted )
return;
 
if ( m_Platform != null )
m_Platform.Location = new Point3D( X, Y, Z - 20 );
 
if ( m_Altar != null )
m_Altar.Location = new Point3D( X, Y, Z - 15 );
 
if ( m_RedSkulls != null )
{
for ( int i = 0; i < m_RedSkulls.Count; ++i )
((Item)m_RedSkulls[i]).Location = GetRedSkullLocation( i );
}
 
if ( m_WhiteSkulls != null )
{
for ( int i = 0; i < m_WhiteSkulls.Count; ++i )
((Item)m_WhiteSkulls[i]).Location = GetWhiteSkullLocation( i );
}
}
 
public override void OnMapChange()
{
if ( Deleted )
return;
 
if ( m_Platform != null )
m_Platform.Map = Map;
 
if ( m_Altar != null )
m_Altar.Map = Map;
 
if ( m_RedSkulls != null )
{
for ( int i = 0; i < m_RedSkulls.Count; ++i )
((Item)m_RedSkulls[i]).Map = Map;
}
 
if ( m_WhiteSkulls != null )
{
for ( int i = 0; i < m_WhiteSkulls.Count; ++i )
((Item)m_WhiteSkulls[i]).Map = Map;
}
}
 
public override void OnDelete()
{
base.OnDelete ();
}
 
public override void OnAfterDelete()
{
base.OnAfterDelete();
 
if ( m_Platform != null )
m_Platform.Delete();
 
if ( m_Altar != null )
m_Altar.Delete();
 
if ( m_RedSkulls != null )
{
for ( int i = 0; i < m_RedSkulls.Count; ++i )
((Item)m_RedSkulls[i]).Delete();
 
m_RedSkulls.Clear();
}
 
if ( m_WhiteSkulls != null )
{
for ( int i = 0; i < m_WhiteSkulls.Count; ++i )
((Item)m_WhiteSkulls[i]).Delete();
 
m_WhiteSkulls.Clear();
}
 
if ( m_Creatures != null )
{
for ( int i = 0; i < m_Creatures.Count; ++i )
{
Mobile mob = (Mobile)m_Creatures[i];
 
if ( !mob.Player )
mob.Delete();
}
 
m_Creatures.Clear();
}
 
if ( m_Champion != null && !m_Champion.Player )
m_Champion.Delete();
 
Stop();
}
 
public ChampionSpawn( Serial serial ) : base( serial )
{
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int) 2 ); // version
 
writer.Write( m_RandomizeType );
 
writer.Write( m_SpawnRange );
writer.Write( m_Kills );
 
writer.Write( (bool) m_Active );
writer.Write( (int) m_Type );
writer.WriteMobileList( m_Creatures, true );
writer.WriteItemList( m_RedSkulls, true );
writer.WriteItemList( m_WhiteSkulls, true );
writer.Write( m_Platform );
writer.Write( m_Altar );
writer.Write( m_ExpireDelay );
writer.WriteDeltaTime( m_ExpireTime );
writer.Write( m_Champion );
writer.Write( m_RestartDelay );
 
writer.Write( m_RestartTimer != null );
 
if ( m_RestartTimer != null )
writer.WriteDeltaTime( m_RestartTime );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
int version = reader.ReadInt();
 
switch ( version )
{
case 2:
{
m_RandomizeType = reader.ReadBool();
 
goto case 1;
}
case 1:
{
m_SpawnRange = reader.ReadInt();
m_Kills = reader.ReadInt();
 
goto case 0;
}
case 0:
{
if ( version < 1 )
m_SpawnRange = 24;
 
bool active = reader.ReadBool();
m_Type = (ChampionSpawnType)reader.ReadInt();
m_Creatures = reader.ReadMobileList();
m_RedSkulls = reader.ReadItemList();
m_WhiteSkulls = reader.ReadItemList();
m_Platform = reader.ReadItem() as ChampionPlatform;
m_Altar = reader.ReadItem() as ChampionAltar;
m_ExpireDelay = reader.ReadTimeSpan();
m_ExpireTime = reader.ReadDeltaTime();
m_Champion = reader.ReadMobile();
m_RestartDelay = reader.ReadTimeSpan();
 
if ( reader.ReadBool() )
{
m_RestartTime = reader.ReadDeltaTime();
BeginRestart( m_RestartTime - DateTime.Now );
}
 
if ( m_Platform == null || m_Altar == null )
Delete();
else if ( active )
Start();
 
break;
}
}
}
}
}

To work in the RunUO 2.5 core... so, i tried to make some changes, because as i said, i figured out that RunUO 2.5 defines a SpawnArea instead of a SpawnRange (runuo1.0)

and i tried to

Code:
//Cleaner
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInRange( Location, m_SpawnRange ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner

to

Code:
//Cleaner
ArrayList onGround = new ArrayList();
foreach( Item item in Map.GetItemsInSpawnArea( Location, m_SpawnArea ) )
if( item is Corpse && !( ((Corpse)item).Owner is PlayerMobile ) )
onGround.Add(item);
 
foreach( Corpse c in onGround )
c.Delete();
//End Cleaner


But it gives me this

Code:
Errors:
 + Engines/CannedEvil/ChampionSpawn.cs:
    CS1061: Line 323: 'Server.Map' no contiene una definición de 'GetItemsInSpaw
nArea' ni se encontró ningún método de extensión 'GetItemsInSpawnArea' que acept
e un primer argumento de tipo 'Server.Map' (¿falta una directiva using o una ref
erencia de ensamblado?)

So i'm looking for a way thats defined by an area (where the champion spawn its planned to be) that deletes the NPCs corpses on death

something like DeleteNPCCorpse = true; defined in a region area, but that does not delete the champion corpses... the point is that so many monster at time, causes so much lag spikes because its a little fun shard that only have 512kbps bandwitch...

And the A_Li_N champion spawn cleaner used to delete the corpses when a whiteskull appear in the champion spawner plataform, but i guess that even that, or the fact that the NPCs themselves delete their bodies when die will also works
 

daat99

Moderator
Staff member
I've added A_Li_N champ clean system in the OWLTR and updated it to RunUO 2.2, you may compare it to the original and see what I changed.
 

zzluis12

Sorceror
I compared yours changed on mine, and it does compile now, but when a white skull spawns, the code who its trying to clean the corpses, crashes the servers.

Since I dont have your Gatherer in there, i removed the lines in the cleaner from this

Code:
//daat99 OWLTR start - Champ Cleaner
ArrayList onGround = new ArrayList();
foreach (Item item in Map.GetItemsInRange(Location, (int)(Math.Max(m_SpawnArea.Width, m_SpawnArea.Height) * 1.5)))
{
if (item is Corpse && ((Corpse)item).Owner != null)
{
if (!(((Corpse)item).Owner is PlayerMobile))
{
BaseCreature bc = ((Corpse)item).Owner as BaseCreature;
if (bc.ControlMaster == null)
onGround.Add(item);
 
foreach (Corpse c in onGround)
c.Delete();
}
}
}
//daat99 OWLTR end - Champ Cleaner

To this

Code:
//Thesuperchampcleaner who i leech from daat99 starts here
 
ArrayList onGround = new ArrayList();
foreach (Item item in Map.GetItemsInRange(Location, (int)(Math.Max(m_SpawnArea.Width, m_SpawnArea.Height) * 1.5)))
{
if (item is Corpse && ((Corpse)item).Owner != null)
{
if (!(((Corpse)item).Owner is PlayerMobile))
{
BaseCreature bc = ((Corpse)item).Owner as BaseCreature;
if (bc.ControlMaster == null)
onGround.Add(item);
 
foreach (Corpse c in onGround)
c.Delete();
}
}
}
//and ends here*

It does compile, but as i said, when it tries to "clean" the corpses, the server dies in a crash, there's the crash log
Code:
Server Crash Report
===================
 
RunUO Version 2.5, Build 0.42173
Operating System: Microsoft Windows NT 6.1.7601 Service Pack 1
.NET Framework: 4.0.30319.1
Time: 24/04/2014 04:43:33 a.m.
Mobiles: 48504
Items: 222843
Exception:
System.ArgumentOutOfRangeException: El índice estaba fuera del intervalo. Debe ser un valor no negativo e inferior al tamaño de la colección.
Nombre del parámetro: index
   en System.ThrowHelper.ThrowArgumentOutOfRangeException()
   en Server.Map.ItemEnumerator.MoveNext() en f:\RunUO2.5\RunUO-2.5\Server\Map.cs:línea 1523
   en Server.Engines.CannedEvil.ChampionSpawn.SetWhiteSkullCount(Int32 val)
   en Server.Engines.CannedEvil.ChampionSpawn.OnSlice()
   en Server.Engines.CannedEvil.SliceTimer.OnTick()
   en Server.Timer.Slice() en f:\RunUO2.5\RunUO-2.5\Server\Timer.cs:línea 387
   en Server.Core.Main(String[] args) en f:\RunUO2.5\RunUO-2.5\Server\Main.cs:línea 577

It says : The index was out of the interval. must be a not negative value, or smaller than the size of the collection

maybe i misspelled the translation : D but it does says something like that...
 

daat99

Moderator
Staff member
You have miss-placed the brackets.
Look at the code I used again and make sure you have the same brackets between the same lines again.
 
Top