Zigholtul88 submitted a new resource:

Almhara Starter Pack Vol.2 - Goodie bag containing some fun ideas useful for your own potential projects

Hello there girls, guys and others if we're going by Ultima 3 standards. After some consideration and finally mustering up the energy to do so, I decided to finally release somewhat of a sequel to my previous Almhara Starter Pack. However keep in mind this is not simply a dump into your customs and forget about it package since the goal of this is merely to offer up ideas and concepts pertaining to how you wanna spice up your shard. Some scripts have been carried over from the previous...

Read more about this resource...
 
Can someone help me out, please? Trying to use this file but got these errors:
+ CUSTOM/AlmharaStarterPack/Mobiles/Custom Monsters/DrowSpiderTrainer.cs:
CS1502: Line 54: The best overloaded method match for 'Server.Items.BaseRunicTool.ApplyAttributesTo(Server.Items.BaseWeapon, int, int, int)' has some invalid arguments
CS1503: Line 54: Argument 1: cannot convert from 'Server.Items.Cloak' to 'Server.Items.BaseWeapon'
CS1502: Line 77: The best overloaded method match for 'Server.Items.BaseRunicTool.ApplyAttributesTo(Server.Items.BaseWeapon, int, int, int)' has some invalid arguments
CS1503: Line 77: Argument 1: cannot convert from 'Server.Items.WoodlandBelt' to 'Server.Items.BaseWeapon'
CS1502: Line 83: The best overloaded method match for 'Server.Items.BaseRunicTool.ApplyAttributesTo(Server.Items.BaseWeapon, int, int, int)' has some invalid arguments
CS1503: Line 83: Argument 1: cannot convert from 'Server.Items.ThighBoots' to 'Server.Items.BaseWeapon'

Here's the script:
C#:
using System;
using System.Collections;
using Server.ContextMenus;
using Server.Items;
using Server.Misc;
using Server.Mobiles; 
using Server.Spells;
using Server.Targeting;

namespace Server.Mobiles
{
    public class DrowSpiderTrainer : BaseCreature
    {
        public static TimeSpan TalkDelay = TimeSpan.FromSeconds( 20.0 ); //the delay between talks is 20 seconds
        public DateTime m_NextTalk;

        [Constructable]
        public DrowSpiderTrainer() : base( AIType.AI_Melee, FightMode.Closest, 12, 1, 0.175, 0.350 )
        {
            Name = NameList.RandomName( "elven female" );
            Title = "the spider trainer"; 
            Female = true;
            Body = 606;
            Hue = 33840;
            HairItemID = 12240;
            HairHue = 1153;

            SetStr( 147, 205 );
            SetDex( 97, 114 );
            SetInt( 54, 147 );

            SetHits( 225, 350 );

            SetDamage( 1, 4 );

            SetSkill( SkillName.MagicResist, 43.4, 60.2 );
            SetSkill( SkillName.Ninjitsu, 100.0 );
            SetSkill( SkillName.Tactics, 45.6, 54.4 );
            SetSkill( SkillName.Wrestling, 50.7, 59.6 );

            Circlet circlet = new Circlet();
                BaseRunicTool.ApplyAttributesTo( circlet, 5, 5, 35 );
            circlet.Hue = 1157; 
            circlet.Movable = true; 
            AddItem( circlet ); 

            WoodlandGorget gorget = new WoodlandGorget();
                BaseRunicTool.ApplyAttributesTo( gorget, 5, 5, 35 );
            gorget.Hue = 2075; 
            gorget.Movable = true; 
            AddItem( gorget ); 

            Cloak cloak = new Cloak();
                BaseRunicTool.ApplyAttributesTo( cloak, 5, 5, 35 );
            cloak.Movable = true; 
            AddItem( cloak ); 

            StuddedBustierArms bustier = new StuddedBustierArms();
                BaseRunicTool.ApplyAttributesTo( bustier, 5, 5, 35 );
            bustier.Hue = 2075; 
            bustier.Movable = true; 
            AddItem( bustier ); 

            DragonGloves gloves = new DragonGloves();
            gloves.Hue = 2075; 
            gloves.Movable = true; 
            AddItem( gloves ); 

            WildStaff staff = new WildStaff();
                BaseRunicTool.ApplyAttributesTo( staff, 5, 5, 35 );
            staff.Hue = 2704; 
            staff.Quality = ItemQuality.Exceptional; 
            staff.Movable = true; 
            AddItem( staff ); 

            WoodlandBelt belt = new WoodlandBelt();
                BaseRunicTool.ApplyAttributesTo( belt, 5, 5, 35 );
            belt.Hue = 2075; 
            belt.Movable = true; 
            AddItem( belt ); 

            ThighBoots boots = new ThighBoots();
                BaseRunicTool.ApplyAttributesTo( boots, 5, 5, 35 );
            boots.Hue = 1883; 
            boots.Movable = true; 
            AddItem( boots ); 

            PackGold( 212, 315 );

            Fame = 2000;
            Karma = -2000;

            m_NextAbilityTime = DateTime.Now + TimeSpan.FromSeconds( Utility.RandomMinMax( 2, 5 ) );
        }

        public override void GenerateLoot()
        {
            AddLoot( LootPack.HighScrolls );
            AddLoot( LootPack.Gems, 3 );
        }

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

        public override void OnDamagedBySpell( Mobile from )
        {
            if( from != null && from.Alive && 0.5 > Utility.RandomDouble() )
            {
                ThrowLightningBolt( from );
                    DoSpecialAbility( from );
                Animate( 31, 5, 1, true, false, 0 );
            }
        }

        public override void OnGotMeleeAttack( Mobile attacker )
        {
            base.OnGotMeleeAttack( attacker );

                        if ( 0.5 >= Utility.RandomDouble() )
                        {
                    DoSpecialAbility( attacker );
                Animate( 31, 5, 1, true, false, 0 );
                        }

                        if ( 0.5 >= Utility.RandomDouble() )
                        {
                    ThrowLightningBolt( attacker );
                Animate( 31, 5, 1, true, false, 0 );
                        }
        }

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

                        if ( 0.5 >= Utility.RandomDouble() )
                        {
                    DoSpecialAbility( defender );
                Animate( 31, 5, 1, true, false, 0 );
                        }

                        if ( 0.5 >= Utility.RandomDouble() )
                        {
                    ThrowLightningBolt( defender );
                Animate( 31, 5, 1, true, false, 0 );
                        }
        }

        public override void OnMovement( Mobile m, Point3D oldLocation )
        {
            if ( DateTime.Now >= m_NextTalk && InRange( m, 10 ) && InLOS( m ) && m is PlayerMobile && !m.Hidden && m.Combatant != null ) // check if it's time to talk & mobile in range & in los.
            {
                ThrowLightningBolt( m );

                    RangePerception = 300;
                this.Combatant = m;

                m_NextTalk = DateTime.Now + TalkDelay; // set next talk time 
                switch ( Utility.Random( 15 ) )
                {
                    case 0: Say("Take this!");
                        break;
                    case 1: Say("Booyah!"); 
                        break;    
                    case 2: Say("Light 'em up, baby!");
                        break;
                    case 3: Say("You wanna a piece of me! Try this!");
                        break;
                    case 4: Say("Shock treatment!"); 
                        break;    
                    case 5: Say("Eat this!");
                        break;
                    case 6: Say("Lightning Bolt!");
                        break;
                    case 7: Say("PWHOOSH!"); 
                        break;    
                    case 8: Say("Game over!");
                        break;
                    case 9: Say("Swallow this!");
                        break;
                    case 10: Say("Groovy!"); 
                        break;    
                    case 11: Say("It's time to stop!");
                        break;
                    case 12: Say("BOOM!");
                        break;
                    case 13: Say("Hah!"); 
                        break;    
                    case 14: Say("Hiiyah!");
                        break;
                };
            }
        }

//<*************//Summon Spider Minions
        public void DoSpecialAbility( Mobile target )
        {
            if ( 0.10 >= Utility.RandomDouble() ) // 10% chance to spawn spider minions
                SpawnMobiles( target );
        }

        public void SpawnMobiles( Mobile target )
        {
            Map map = this.Map;

            if ( map == null )
                return;

            int red = 0;

            foreach ( Mobile m in this.GetMobilesInRange( 10 ) )
            {
                if ( m is SummonedYatsukahag )
                    ++red;
            }

            if ( red < 5 )
            {
                PlaySound( 0x51A );

                int newblue = Utility.RandomMinMax( 1, 2 );

                for ( int i = 0; i < newblue; ++i )
                {
                    BaseCreature yellow;

                    switch ( Utility.Random( 2 ) )
                    {
                        default:
                        case 0: yellow = new SummonedYatsukahag(); break;
                        case 1: yellow = new SummonedYatsukahag(); break;
                    }

                    yellow.Team = this.Team;

                    bool validLocation = false;
                    Point3D loc = this.Location;

                    for ( int j = 0; !validLocation && j < 10; ++j )
                    {
                        int x = X + Utility.Random( 3 ) - 1;
                        int y = Y + Utility.Random( 3 ) - 1;
                        int z = map.GetAverageZ( x, y );

                        if ( validLocation = map.CanFit( x, y, this.Z, 16, false, false ) )
                            loc = new Point3D( x, y, Z );
                        else if ( validLocation = map.CanFit( x, y, z, 16, false, false ) )
                            loc = new Point3D( x, y, z );
                    }

                    yellow.MoveToWorld( loc, map );
                    yellow.Combatant = target;
                }
            }
        }
//<*************//end summon spider minions

//////////////////////////////////////////////////// Throw Lightning Bolt ////////////////////////////////////////////////////

        #region Randomize
        private static int[] m_ItemID = new int[]
        {
                        13920
        };

        public static int GetRandomItemID()
        {
            return Utility.RandomList( m_ItemID );
        }

        private DateTime m_NextLightningBolt;
        private int m_Thrown;

        public override void OnActionCombat()
        {
            Mobile combatant = Combatant;

            if ( combatant == null || combatant.Deleted || combatant.Map != Map || !InRange( combatant, 12 ) || !CanBeHarmful( combatant ) || !InLOS( combatant ) )
                return;

            if ( DateTime.Now >= m_NextLightningBolt )
            {
                ThrowLightningBolt( combatant );

                m_Thrown++;

                if ( 0.75 >= Utility.RandomDouble() && (m_Thrown % 2) == 1 ) // 75% chance to quickly throw another lightning bolt
                    m_NextLightningBolt = DateTime.Now + TimeSpan.FromSeconds( 10.0 );
                else
                    m_NextLightningBolt = DateTime.Now + TimeSpan.FromSeconds( 15.0 + (10.0 * Utility.RandomDouble()) ); // 15-25 seconds
            }
        }

        public void ThrowLightningBolt( Mobile m )
        {
            this.MovingEffect( m, Utility.RandomList( m_ItemID ), 10, 0, false, false );
            this.DoHarmful( m );
            this.PlaySound( 0x20A ); // energy bolt

            new InternalTimer( m, this ).Start();
        }

        private class InternalTimer : Timer
        {
            private Mobile m_Mobile, m_From;

            public InternalTimer( Mobile m, Mobile from ) : base( TimeSpan.FromSeconds( 1.0 ) )
            {
                m_Mobile = m;
                m_From = from;
                Priority = TimerPriority.TwoFiftyMS;
            }

            protected override void OnTick()
            {
                        m_Mobile.BoltEffect( 0x480 );
                m_Mobile.PlaySound( 0x5CE ); // lightning strike
                        m_Mobile.Hits -= ( Utility.Random( 5, 15 ) );
            }
        }
        #endregion

        private DateTime m_NextAbilityTime;

        public override void OnThink()
        {
            if ( DateTime.Now >= m_NextAbilityTime )
            {
                SummonedYatsukahag toBuff = null;

                foreach ( Mobile m in this.GetMobilesInRange( 8 ) )
                {
                    if ( m is SummonedYatsukahag && IsFriend( m ) && m.Combatant != null && CanBeBeneficial( m ) && m.CanBeginAction( typeof( DrowSpiderTrainer ) ) && InLOS( m ) )
                    {
                        toBuff = (SummonedYatsukahag)m;
                        break;
                    }
                }

                if ( toBuff != null )
                {
                    if ( CanBeBeneficial( toBuff ) && toBuff.BeginAction( typeof( DrowSpiderTrainer ) ) )
                    {
                        m_NextAbilityTime = DateTime.Now + TimeSpan.FromSeconds( Utility.RandomMinMax( 30, 60 ) );

                        toBuff.Say( true, "Oooga Booga!" );
                        this.Say( true, "Purge this jungle of the uncleansed!" );

                        DoBeneficial( toBuff );

                        object[] state = new object[]{ toBuff, toBuff.HitsMaxSeed, toBuff.RawStr, toBuff.RawDex };

                        SpellHelper.Turn( this, toBuff );

                        int toScale = toBuff.HitsMaxSeed;

                        if ( toScale > 0 )
                        {
                            toBuff.HitsMaxSeed += AOS.Scale( toScale, 100 );
                            toBuff.Hits += AOS.Scale( toScale, 100 );
                        }

                        toScale = toBuff.RawStr;

                        if ( toScale > 0 )
                            toBuff.RawStr += AOS.Scale( toScale, 10 );

                        toScale = toBuff.RawDex;

                        if ( toScale > 0 )
                        {
                            toBuff.RawDex += AOS.Scale( toScale, 10 );
                            toBuff.Stam += AOS.Scale( toScale, 100 );
                        }

                        toBuff.Hits = toBuff.Hits;
                        toBuff.Stam = toBuff.Stam;

                        toBuff.FixedParticles( 0x375A, 10, 15, 5017, EffectLayer.Waist );
                        toBuff.PlaySound( 0x1EE );

                        Timer.DelayCall( TimeSpan.FromSeconds( 20.0 ), new TimerStateCallback( Unbuff ), state );
                    }
                }
                else
                {
                    m_NextAbilityTime = DateTime.Now + TimeSpan.FromSeconds( Utility.RandomMinMax( 2, 5 ) );
                }
            }

            base.OnThink();
        }

        private void Unbuff( object state )
        {
            object[] states = (object[])state;

            SummonedYatsukahag toDebuff = (SummonedYatsukahag)states[0];

            toDebuff.EndAction( typeof( DrowSpiderTrainer ) );

            if ( toDebuff.Deleted )
                return;

            toDebuff.HitsMaxSeed = (int)states[1];
            toDebuff.RawStr = (int)states[2];
            toDebuff.RawDex = (int)states[3];

            toDebuff.Hits = toDebuff.Hits;
            toDebuff.Stam = toDebuff.Stam;
        }

        public DrowSpiderTrainer( 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();
        }
    }
}
Post automatically merged:

I figured it out. I added instances in BaseRunicTool for Cloak, WoodlandBelt, and Thighboots.... Yay!
 
Last edited:
Hey, I noticed that you can carve alot of the corpses to get other items. The script shows this: int amount = 1 + (int)( from.Skills[SkillName.Forensics].Value / 25 );
Is this meant that if your Forensics ain't 25.0 you can't carve?
Here's your bit of code that i'm refering to:
C#:
[/QUOTE]
                public override void OnCarve( Mobile from, Corpse corpse, Item with )
        {
            if ( corpse.Carved == false )
            {
                  base.OnCarve( from, corpse, with );

                  int amount = 1 + (int)( from.Skills[SkillName.Forensics].Value / 25 );                  
                      corpse.AddCarvedItem(new CliffStriderPowder( amount ), from );

                              from.SendMessage( "You carve up the corpse and notice a powdery substance!" );
                              corpse.Carved = true;
                          }
                }

[QUOTE]
 
Hey, I noticed that you can carve alot of the corpses to get other items. The script shows this: int amount = 1 + (int)( from.Skills[SkillName.Forensics].Value / 25 );
Is this meant that if your Forensics ain't 25.0 you can't carve?
Here's your bit of code that i'm refering to:
Honestly its been awhile since I last dabbled with this particular set of events, so I'm not entirely sure if you wind up empty handed or if its below 25.0 you only end up with 1 of the item. What I do remember was I originally set it up like this with a ton of mobiles since I wanted to make Forensics skill just a little more useful by allowing for extra material gathered from certain critters.
 
Great idea! I think I see how it works. If char is under 25 Forensics you get 1 CliffStriderPowder and over 25 you get more than 1 CliffStriderPowder. I was wondering if maybe it could be set to if your Forensics is below 25 you won't get the CliffStriderPowder?
 
Last edited:
Great idea! I think I see how it works. If char is under 25 Forensics you get 1 CliffStriderPowder and over 25 you get more than 1 CliffStriderPowder. I was wondering if maybe it could be set to if your Forensics is below 25 you won't get the CliffStriderPowder?
Shoot, why did I not think of that because that is an excellent idea right there.
 
Not sure just how to word your coding to do that... haha. I substituted a 0 instead of a 1 thinking you'd get 0 if below 25 Forensics but it just gave me 1 CliffStriderPowders so, nope it didn't work. Here's your original coding:

int amount = 1 + (int)( from.Skills[SkillName.Forensics].Value / 25 );
 
Last edited:
Now my memory towards why I originally set this up the way I did is slowly coming back to me. It was because I was attempting to mimic the looting system from Final Fantasy XII and how monsters usually didn't drop gold, but rather stuff in the form of vendor trash that could be resold to vendors and thus that's how you'd largely make money in the process.

And in the case of some of the loot tailored specific to certain mobiles and how some items came with a Forensics check in order to procure extra amounts it was my feeble way of trying to make that skill a little more useful if only so that it could prove to be extremely valuable towards making more money since basically all of the tailor made items made for certain mobs sold for a lot of gold if you sold them to butchers.
Not sure just how to word your coding to do that... haha. I substituted a 0 instead of a 1 thinking you'd get 0 if below 25 Forensics but it just gave me some off the wall number of CliffStriderPowders so, nope it didn't work. Here's your original coding:

int amount = 1 + (int)( from.Skills[SkillName.Forensics].Value / 25 );
Well I learn something new everyday. I was hoping with the way it was set up would allow for players (based off of their Forensics skill) to gather between 1 and 4 x amounts of that specific items, hence why the value of said skill was divisible by 25.
 
Thanks buddy, you've just had to go and motivate me a bit. Reason I say that is because maybe since I've made more progress on my RunUO server I could see about trying to release a Vol 3 if anyone is interested since I'd like to believe my coding skills have gotten better recently.

Which is more than I can say about my paperdoll gump projects, lol.
 
Last edited:
I could use them... most definately!!!
Which one, lol. Because not only could I make a Vol. 3, but could also redo the entire paperdoll project to where it's more classics inspired in terms of equipment actually resembling the animation files. And hopefully there won't be issues unlike before.
 
The Vol. 3 first please... lol
FUDGE!!!!!!!!!!!!!!!!!!!!!!!!!!!

Okay, that I can do. Though keep in mind, the scripts from these mobiles seem to only be compatible with RunUO, and last time I checked it turns out some of the mobiles (such as the annoying llamas) come in direct violation against ServUOs coding structure.

That being said, I'll see what I can do on my end.
 
I run a ServUO repo (LOA - Land Of Archon) which I did have a few problems when I installed your package... just worked through them... lol.
 
That's pretty dang awesome how you managed to rework the original coding in order to make it compatible with ServUO.

Honestly I wish I could transfer everything from my RunUO server over onto ServUO, but really I just can't bring myself to feel at ease with some of its coding quirks and how for me personally leaves out a ton of room for customizing options. And I'm technically not a fan of most of the newer content added to it, though I don't blame the folks behind the emulation scene, but rather EA/Mythic/Broadsword for continuing to add more content to this game and yet if you actually look into the base client files themselves you're notice tons of issues in addition to how unorganized everything is to the point of including spelling mistakes on certain items.
 
Right, I too have seen alot of spelling mistakes that would have came from EA. Well, off to bed it's already 10:50 p.m.
 
Shepards Crook for starters. And we can't forget about their infamous Gimp masks within the Gump muls. lol
Shoot, if I do eventually get around towards working on that Paperdoll Project Classics Edition I might actually keep them in for the hell of it.
 
Back