What I'm trying (and failing) to do is script a mob that bleeds constantly. From time of spawning until its killed, it bleeds all over the place. I've tried parts of the BleedAttack, but so far, not one drop of blood. I don't want it dependent on damage, I just want it to leave puddles of blood whether its attacked or not. Any ideas? Is this even possible? What I've tried is in the following snippet.
Code:
        private static Hashtable m_Table = new Hashtable();
        public static bool IsBleeding(Mobile m)
        {
            return m_Table.Contains(m);
        }
        public static void DoBleed(Mobile m)
        {
          //  if (m.Alive)
          //  {
             //   int damage = Utility.RandomMinMax(level, level * 2);

            //    if (!m.Player)
            //        damage *= 2;

            //    m.PlaySound(0x133);
            //    m.Damage(damage, from);

                Blood blood = new Blood();

                blood.ItemID = Utility.Random(0x122A, 5);

                blood.MoveToWorld(m.Location, m.Map);
          //  }
        }
I've tried it with the if (m.Alive) & without to no avail. If this can be made to work somehow, it could be used for other leaking mobs as well... Water eles that drip water, critters that drip poison or slime or other delightful substances.
 
I've been doing a lot of going through old scripts to see what and how I did things but I had that saw mill addon where you double clicked the saw blade and you bleed for a short while, the code might point you in the right direction...

Code:
        // ****************************
        // *** BLOOD CODE FROM HERE ***
        // ****************************
        private static Hashtable m_BloodTable = new Hashtable();

        public static bool IsBleeding(Mobile m)
        {
            return m_BloodTable.Contains(m);
        }

        public static void BeginBleed(Mobile m)
        {
            Timer t = (Timer)m_BloodTable[m];

            if (t != null)
                t.Stop();

            t = new InternalTimer(m);
            m_BloodTable[m] = t;

            t.Start();
        }

        public static void DoBleed(Mobile m)
        {
            if (m.Alive)
            {
                m.PlaySound(0x133);

                Blood blood = new Blood();

                blood.ItemID = Utility.Random(0x122A, 5);

                blood.MoveToWorld(m.Location, m.Map);
            }
            else
            {
                EndBleed(m, false);
            }
        }

        public static void EndBleed(Mobile m, bool message)
        {
            Timer t = (Timer)m_BloodTable[m];

            if (t == null)
                return;

            t.Stop();
            m_BloodTable.Remove(m);

            if (message)
                m.SendLocalizedMessage(1060167); // The bleeding wounds have healed, you are no longer bleeding!
        }

        private class InternalTimer : Timer
        {
            private Mobile m_Mobile;
            private int m_Count;

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

            protected override void OnTick()
            {
                DoBleed(m_Mobile);

                if (++m_Count == 5)
                    EndBleed(m_Mobile, true);
            }
        }

        // ***************************

I'll post the script in custom releases if you want the full thing, hope it helps ;)
 
That's the coding from BleedAttack.cs as well. The timer & EndBleed aren't what I need. That's dependent on damage, just like the BleedAttack. I don't want this to be damage dependent, just a constant drip of blood. Thx for trying anyway. :)
 
Some possibilities:

Override the "OnThink" method from the AI. (He bleeds when he stands still.)
Override the "OnMove" method. (He bleeds when he moves.)
Override the "OnActionFlee" method. (He bleeds when he runs away.)
 
There ya go.. talking (typing) over my head. :confused: Remember, I'm not an expert. I'm still learning here & there. :( I've got an item that does drip blood (modified from the old bleeding knife), but it requires that it be equipped. If I could make the mob "equip" the item, I wouldn't have to add extra coding or override things. The bleeding item will also be an occasional drop from the mob and the mob will have it on as well. Just having it on the mob doesn't make the bleed effect work, it needs to be equipped. I'm sure theres a way to have the mob equip it as it spawns, I just haven't found it yet.
 
Last edited:
Take a look at guards files, they spawn with equiped items:

(Using runuo)

Code:
 #region Weapon
            BaseWeapon weapon;

            switch(Utility.Random(2))
            {
                case 1: weapon = new Halberd(); break;
                case 2:
                    weapon = new Longsword();
                    BaseShield shield = new OrderShield();
                   // shield.Resource
                    AddItem(shield);
                    shield.Movable = false;
                    break;
                default:
                    weapon = new Halberd(); break;
            }

            weapon.Crafter = this;
          // weapon.Resource
            weapon.Quality = WeaponQuality.Exceptional;
            weapon.Speed = 200;
            weapon.MinDamage = 150;
            weapon.MaxDamage = 185;
            AddItem(weapon);
            weapon.Movable = false;
            #endregion
 
Yes they do, but that wont work. I need to have the mob "equip" it just after the mob spawns. If it spawns with the mob, it doesnt work. So things like AddItem wont work.
 
There ya go.. talking (typing) over my head. :confused: Remember, I'm not an expert. I'm still learning here & there. :( I've got an item that does drip blood (modified from the old bleeding knife), but it requires that it be equipped. If I could make the mob "equip" the item, I wouldn't have to add extra coding or override things. The bleeding item will also be an occasional drop from the mob and the mob will have it on as well. Just having it on the mob doesn't make the bleed effect work, it needs to be equipped. I'm sure theres a way to have the mob equip it as it spawns, I just haven't found it yet.

I just mean something simple like this inside your mob's script:

Code:
        protected override bool OnMove(Direction d)
        {
            int chance = 12;
            if (Utility.Random(chance) == 1)
            {
                Blood blood = new Blood();
                blood.ItemID = Utility.Random(0x122A, 5);
                blood.MoveToWorld(m.Location, m.Map);
            }
           
            return base.OnMove(d);
        }

That would make it about a 1 in 12 chance that when it moves it drips blood. You can increase or decrease the chance by changing the number.
 
So close.. I removed the bleed chance & the m. from map & location & it works when the mob moves. Now if it would just bleed when it wasnt moving. I know, I know.. getting picky. lol
 
Cant you add the same code to the OnThink method? ^^
that would cause the mob to just sit there constantly bleeding

OnThink is bascially a timer that uses a property of the mobile as a delay between checks...i forget which one

How so? Not really sure this mob thinks too much.. ;)

use the method:
Code:
public override void OnThink()
{
	// Lokai's code here

	base.OnThink();
}

instead of OnMove and use the same code that Lokai gave above
 
This is the result.
Code:
--------------------------------------------------------------------------------

ServUO - [http://www.servuo.com] Version 0.5, Build 6110.33815
Publish 54
Core: Running with arguments: -debug
Core: Optimizing for 6 64-bit processors
RandomImpl: CSPRandom (Software)
Core: Loading config...
Scripts: Compiling C# scripts...Failed with: 1 errors, 0 warnings
Errors:
+ Custom/*********.cs:
    CS0127: Line 109: Since 'Server.Mobiles.********.OnThink()' returns void,
a return keyword must not be followed by an object expression
Scripts: One or more scripts failed to compile or no script files were found.
- Press return to exit, or R to try again.
Code:
        public override void OnThink()
        {
            {
               Blood blood = new Blood();

                blood.ItemID = Utility.Random(0x122A, 5);

                blood.MoveToWorld(Location, Map);
            }

            return base.OnThink();

        }
 
Don't know if this will fix your error, but you have curly brackets without an if/else statement

Edit: my bad, better if you use the utility.random as Lokai mentioned

Code:
        public override void OnThink()
        {
        	int chance = 12;
		if (Utility.Random(chance) == 1)
 	  {
               Blood blood = new Blood();

                blood.ItemID = Utility.Random(0x122A, 5);

                blood.MoveToWorld(Location, Map);
           }

            return base.OnThink();

        }
 
With or without the Utility.Random & with or without the brackets, I get the previous post error. Removing the return base.OnThink() stops the error and also stops the bleed effect completely. I'll just stick with the OnMove coding unless someone knows how to have a mobile equip an item just after the mobile spawns instead of spawning it ON the mobile to begin with. The item has the OnEquip/OnRemove coding to make it work.
 
With or without the Utility.Random & with or without the brackets, I get the previous post error. Removing the return base.OnThink() stops the error and also stops the bleed effect completely. I'll just stick with the OnMove coding unless someone knows how to have a mobile equip an item just after the mobile spawns instead of spawning it ON the mobile to begin with. The item has the OnEquip/OnRemove coding to make it work.
sorry, been away from coding for too long, should be

base.OnThink(); -- not -- return base.OnThink();

Code:
public override void OnThink()
        {
            base.OnThink();
           
            int chance = 12;
            if (Utility.Random(chance) == 1)
            {
                Blood blood = new Blood();
                blood.ItemID = Utility.Random(0x122A, 5);
                blood.MoveToWorld(Location, Map);
            }
        }

attached full script to test below

To equip something after the mobile is created, i use this:

Timer.DelayCall(TimeSpan.Zero, OnCreate);
in the constructor of the mobile, where OnCreate is the method you're calling to do or add something once the mobile or item is created or spawned
 

Attachments

  • BleedingEarthElemental.cs
    2.9 KB · Views: 4
That worked, especially after removing the utility random. So now instead of bleeding here & there, the mob is now like a victim in a Japanese gore movie. So much blood, everywhere it goes.. nasty.. Its perfect! I'll release it after a few more tweaks. Just in time for Halloween. :D Thankyou.
 
Back