Spirit Master system

We try to put in new spawn areas, quests, events, items and scripts. This is where you submit your wish.
Locked
Zeddanzz
Passer by
Posts: 1
Joined: Wed Nov 05, 2008 2:45 pm

Spirit Master system

Post by Zeddanzz »

I have an old idea I submitted on the RunUO boards back in 2004 which could be implemented or adjusted or just tossed in the discarded folder LOL! I scripted a group of Spirit Masters. These RED humanoids tossed souls at you, similar to the orc brutes spawning orcs on you when they were hit. They dropped "souls" as loot (both the red spirit master and the summoned soul (possibly). There were three difficulties or levels of spiritmasters. The first summoned drakes and earth ellie types(seven types), the second summoned titan and blood ellie types (six types), and the final summoned champ boss types with a dark father possible (six types). If you looted a soul, you could summon a spirit to fight for you. This was based upon your Necromancy skill which determined the summoned spirits strength, life and duration (max time is @ 2 hours). I had planned on adding "SoulCrafting" in a later update and still could add this.

A system like this could be a part of the idea proposed by Jill which looks fantastic IMO and I would be happy to contribute to or work on that project!

I am posting the code for the final Spiritmaster here along with the soul and spirit codes for the Dark Father. And yes, I am FNP from the old RunUO board and Walker Oakroot here on Excelsior!

The Master of Spirits:

Code: Select all

////////////////////////////////////							//
//		Spirits by				//
//			FNP			//
//								//
//////////////////////////////////
using System; 
using Server;
using System.Collections;
using Server.Items;
using Server.Network;

namespace Server.Mobiles 
{ 
	[CorpseName( "a spirit master corpse" )] 
	public class SpiritMaster : BaseCreature 
	{ 
		[Constructable] 
		public SpiritMaster() : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 ) 
		{ 
			Name = "The Master of Spirits";
			Body = 770;

			Hue = 0x455;

			SetStr( 526, 750 );
			SetDex( 226, 320 );
			SetInt( 651, 975 );

			SetHits( 2500, 4000 );

			SetDamage( 18, 22 );

			SetDamageType( ResistanceType.Physical, 100 );

			SetResistance( ResistanceType.Physical, 30, 40 );
			SetResistance( ResistanceType.Fire, 45, 65 );
			SetResistance( ResistanceType.Cold, 35, 45 );
			SetResistance( ResistanceType.Poison, 25, 45 );
			SetResistance( ResistanceType.Energy, 35, 55 );

			SetSkill( SkillName.EvalInt, 110.1, 130.0 );
			SetSkill( SkillName.Magery, 115.1, 130.0 );
			SetSkill( SkillName.Meditation, 105.1, 120.0 );
			SetSkill( SkillName.MagicResist, 112.5, 135.0 );
			SetSkill( SkillName.Tactics, 85.0, 107.5 );
			SetSkill( SkillName.Wrestling, 95.0, 117.5 );

			Fame = 15000;
			Karma = -15000;

			VirtualArmor = 76;
			
			

		}

		public override bool CanRummageCorpses{ get{ return true; } }
		public override bool Unprovokable{ get{ return true; } }
		public override bool Uncalmable{ get{ return true; } }
		
		
		public override void GenerateLoot()
		{
			AddLoot( LootPack.UltraRich, 2 );
			switch ( Utility.Random( 7 ) )  
                { 
                  	case 0: AddItem( new BalronSoul( ) ); break; 
                   	case 1: AddItem( new AngelSoul( ) ); break; 
                   	case 2: AddItem( new BoneDemonSoul( ) ); break; 
                   	case 3: AddItem( new RiktorSoul( ) ); break; 
                   	case 4: AddItem( new SuccubusSoul( ) ); break; 
                   	case 5: AddItem( new ArachnidSoul( ) ); break; 
                   	case 6: AddItem( new AncientWyrmSoul( ) ); break; 
     	     	} 
			if ( 0.05 > Utility.RandomDouble() )
				AddItem( new DarkFatherSoul( ) );
		}

		public override void OnDamagedBySpell( Mobile caster )
		{
			if ( caster == this )
				return;

			AddSpirit( caster, 0.25 );
		}

		public override void OnGaveMeleeAttack( Mobile defender )
		{
			base.OnGaveMeleeAttack( defender );

			if ( 0.2 >= Utility.RandomDouble() ) // 20% chance to spawn a spirit
				AddSpirit( defender, 0.25 );
		}
		
		public override void OnGotMeleeAttack( Mobile attacker )
		{
			base.OnGotMeleeAttack( attacker );

			if ( 0.2 >= Utility.RandomDouble() ) // 20% chance to spawn a spirit
				AddSpirit( attacker, 0.25 );
		}

		public void AddSpirit( Mobile target, double chanceToThrow )
		{
			if ( chanceToThrow >= Utility.RandomDouble() )
			{
				Direction = GetDirectionTo( target );
				MovingEffect( target, 0xF7E, 10, 1, true, false, 0x496, 0 );

				Mobile spawn;

				switch ( Utility.Random( 7 ) )
				{
					default:
					case 0: spawn = new SpiritAncientWyrm(); break;
					case 1: spawn = new SpiritBalron(); break;
					case 2: spawn = new SpiritRiktor(); break;
					case 3: spawn = new SpiritBoneDemon(); break;
					case 4: spawn = new SpiritArachnid(); break;
					case 5: spawn = new SpiritSuccubus(); break;
					case 6: spawn = new SpiritDarkFather(); break;
				}
				
				spawn.MoveToWorld( Location, Map );
			}
		}

		public override bool ClickTitle{ get{ return false; } }
		public override bool ShowFameTitle{ get{ return false; } }
		public override bool AlwaysMurderer{ get{ return true; } }

		public SpiritMaster( Serial serial ) : base( serial ) 
		{ 
		} 

		public override void Serialize( GenericWriter writer ) 
		{ 
			base.Serialize( writer ); 
			writer.Write( (int) 0 ); 
		} 

		public override void Deserialize( GenericReader reader ) 
		{ 
			base.Deserialize( reader ); 
			int version = reader.ReadInt(); 
		} 
	} 
}
The Dark Father Spirit:

Code: Select all

//////////////////////////////////
//								//
//		Spirits by				//
//			FNP					//
//								//
//////////////////////////////////
using System;
using Server;
using Server.Items;

namespace Server.Mobiles
{
	[CorpseName( "a dark father corpse" )]
	public class SpiritDarkFather : BaseCreature
	{

		private DateTime m_ExpireTime;

		[CommandProperty( AccessLevel.GameMaster )]
		public DateTime ExpireTime
		{
			get{ return m_ExpireTime; }
			set{ m_ExpireTime = value; }
		}
		public override void OnThink()
		{
			bool expired;

			expired = ( DateTime.Now >= m_ExpireTime );


			if ( expired )
			{
				PlaySound( GetIdleSound() );
				Delete();
			}
			else
			{
				base.OnThink();
			}
		}

		[Constructable]
		public SpiritDarkFather() : this( false, 1.2 )
		{
		}

		[Constructable]
		public SpiritDarkFather ( bool summoned, double scalar ) : base( AIType.AI_Mage, FightMode.Closest, 10, 1, 0.2, 0.4 )
		{
			m_ExpireTime = DateTime.Now + TimeSpan.FromMinutes( (int)(60*scalar) + 45 );

			Name = "an dark father spirit";
			Body = 318;
			BaseSoundID = 0x165;
			Hue = 0x4001;

			SetStr( (int)(502*scalar), (int)(666*scalar) );
			SetDex( (int)(111*scalar), (int)(200*scalar) );
			SetInt( (int)(900*scalar), (int)(1100*scalar) );
			
			SetHits( (int)(29000*scalar), (int)(31000*scalar) );
			SetMana( 5000 );

			SetDamage( (int)(17*scalar), (int)(21*scalar) );

			SetDamageType( ResistanceType.Physical, 20 );
			SetDamageType( ResistanceType.Fire, 20 );
			SetDamageType( ResistanceType.Cold, 20 );
			SetDamageType( ResistanceType.Poison, 20 );
			SetDamageType( ResistanceType.Energy, 20 );

			SetResistance( ResistanceType.Physical, 30 );
			SetResistance( ResistanceType.Fire, 30 );
			SetResistance( ResistanceType.Cold, 30 );
			SetResistance( ResistanceType.Poison, 30 );
			SetResistance( ResistanceType.Energy, 30 );

			SetSkill( SkillName.EvalInt, 100.0 );
			SetSkill( SkillName.Magery, 100.0 );
			SetSkill( SkillName.Meditation, 120.0 );
			SetSkill( SkillName.MagicResist, 150.0 );
			SetSkill( SkillName.Tactics, 100.0 );
			SetSkill( SkillName.Wrestling, 120.0 );

			SetSkill( SkillName.EvalInt, (int)(95*scalar), (int)(115*scalar) );
			SetSkill( SkillName.Magery, (int)(95*scalar), (int)(110*scalar) );
			SetSkill( SkillName.Meditation, (int)(100*scalar), (int)(130*scalar) );
			SetSkill( SkillName.MagicResist, (int)(140*scalar), (int)(150*scalar) );
			SetSkill( SkillName.Tactics, (int)(100*scalar), (int)(110*scalar) );
			SetSkill( SkillName.Wrestling, (int)(110*scalar), (int)(130*scalar) );
			
			Fame = 22000;
			Karma = -22000;

			VirtualArmor = 88;
			ControlSlots = 4;
			
		}
		public override bool DeleteOnRelease{ get{ return true; } }

		public override Poison PoisonImmune{ get{ return Poison.Regular; } } // TODO: Immune to poison?

		public override void GenerateLoot()
		{
			if ( 0.1 > Utility.RandomDouble() )
				AddItem( new DarkFatherSoul() );
		}

		public SpiritDarkFather( Serial serial ) : base( serial )
		{
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );
			writer.Write( (int) 0 );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );
			int version = reader.ReadInt();
		}
	}
}
The Dark Father Soul (looks like an urn)

Code: Select all

//////////////////////////////////
//								//
//		Spirits by				//
//			FNP					//
//								//
//////////////////////////////////
using System;
using Server;
using Server.Mobiles;
using Server.Network;
using Server.Spells;


namespace Server.Items
{
	public class DarkFatherSoul : Item
	{

		[Constructable]
		public DarkFatherSoul() : base( 0x241D )
		{
			Movable = true;
			Name = "a dark father soul";
			Stackable = false;
			Weight = 1.0;

		}


		public DarkFatherSoul( Serial serial ) : base( serial )
		{
		}
		
	
		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int) 0 ); // version
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

		}

		public override void OnDoubleClick( Mobile from )
		{
			if ( (from.Followers + 4) > from.FollowersMax )
			{
				from.SendLocalizedMessage( 1049607 ); // You have too many followers to control that creature.
				return;
			}

			double necroSkill = from.Skills[SkillName.SpiritSpeak].Value;

			double scalar;

			if ( necroSkill >= 140.0 )
				scalar = 1.4;
			else if ( necroSkill >= 120.0 )
				scalar = 1.2;
			else if ( necroSkill >= 100.0 )
				scalar = 1.0;
			else if ( necroSkill >= 70.0 )
				scalar = 0.9;
			else
				scalar = 0.8;


				{
					SpiritDarkFather g = new SpiritDarkFather( true, scalar );

					if ( g.SetControlMaster( from ) )
					{
						Delete();
						g.MoveToWorld( from.Location, from.Map );
					}

				}

		}

	}
}
This code is about 4 years old and I am not sure what has changed with RunUO since then. I would need to brush up on that.

Respectfully,
Walker
Mogster
Apprentice Scribe
Posts: 13
Joined: Sat Jan 17, 2009 7:44 pm

Re: Spirit Master system

Post by Mogster »

Hi all

I really like the sound of this. Once again this is a really nice extra to the shard would be ace as an event and has a really nice reward.

Thanks BolO
jeffcarley
Apprentice Scribe
Posts: 11
Joined: Wed Nov 26, 2008 1:25 am
Location: Dallas, Texas

Re: Spirit Master system

Post by jeffcarley »

Awesome, these are the kind of thing I like to see on a custom shard...keep up the good work and script away:) I love quests so if you are inclined I would like some of those on this shard!
Locked