Spirit Master system
Posted: Mon Jan 26, 2009 4:02 am
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:
The Dark Father Spirit:
The Dark Father Soul (looks like an urn)
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
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();
}
}
}
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();
}
}
}
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 );
}
}
}
}
}
Respectfully,
Walker