sahisahi

Member
Would like to know what script file handle bonded creatures and if theres a timer that deletes them if they didnt get ressed in X days
 
Ahhhh i found it, i was looking for ''bonded''


Code:
public virtual TimeSpan BondingDelay { get { return TimeSpan.FromDays(7.0); } }
        public virtual TimeSpan BondingAbandonDelay { get { return TimeSpan.FromDays(1.0); } }


That means 7 days till get bonded, 1 day to abandon master if pet dont get ressed?
 
I do believe this controls dead pet deletion. Living pets run down their loyalty, but dead ones only check the one-day timer. A bit odd, since pets lose 10 loyalty per hour of 100 max, meaning that's only just under 11 hours max (depending on the hourly check time) until living pets go wild.
Code:
            if (c.IsDeadPet)
             {
               Mobile owner = c.ControlMaster;

               if (!c.IsStabled &&
                 (owner == null || owner.Deleted || owner.Map != c.Map || !owner.InRange(c, 12) || !c.CanSee(owner) ||
                  !c.InLOS(owner)))
               {
                 if (c.OwnerAbandonTime == DateTime.MinValue)
                 {
                   c.OwnerAbandonTime = DateTime.UtcNow;
                 }
                 else if ((c.OwnerAbandonTime + c.BondingAbandonDelay) <= DateTime.UtcNow)
                 {
                   toRemove.Add(c);
                 }
               }
               else
               {
                 c.OwnerAbandonTime = DateTime.MinValue;
               }
             }
            else if (c.Controlled && c.Commandable)
             {
               c.OwnerAbandonTime = DateTime.MinValue;

               if (c.Map != Map.Internal)
               {
                 c.Loyalty -= (BaseCreature.MaxLoyalty / 10);

                 if (c.Loyalty < (BaseCreature.MaxLoyalty / 10))
                 {
                   c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                   c.PlaySound(c.GetIdleSound());
                 }

                 if (c.Loyalty <= 0)
                 {
                   toRelease.Add(c);
                 }
               }
             }
 
Last edited:
Easiest way is to simply change toRelease.Add(c); to toRemove.Add(c);
That would make living pets be deleted like dead ones.

If you want it to take longer for them to be deleted, you could very easily make it 25 hours. Note that Loyalty is an integer.
Code:
                            if (c.Map != Map.Internal)
                            {
                                c.Loyalty -= (BaseCreature.MaxLoyalty / 25);

                                if (c.Loyalty < (BaseCreature.MaxLoyalty / 25))
                                {
                                    c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                    c.PlaySound(c.GetIdleSound());
                                }

                                if (c.Loyalty <= 0)
                                {
                                    toRelease.Add(c);
                                }
                            }

You could also make the 25 hour timer specific to bonded pets. Also note that one could just as easily have both bonded and non-bonded pets look around desperately when below 10 Loyalty. (Actually, it should probably be <=[at or below], not <[below], since they go wild <=[at or below] 0, not <[below] 0; this version has the <=[at or below])
Code:
                                if (c.IsBonded)
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 25);

                                    if (c.Loyalty <= (BaseCreature.MaxLoyalty / 25))
                                    {
                                        c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                        c.PlaySound(c.GetIdleSound());
                                    }                                      
                                }
                                else
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 10);

                                    if (c.Loyalty <= (BaseCreature.MaxLoyalty / 10))
                                    {
                                        c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                        c.PlaySound(c.GetIdleSound());
                                    }
                                }
Here's the version that has looks around desperately whenever at or below /10
Code:
                                if (c.IsBonded)
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 25);
                                }
                                else
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 10);
                                }

                                if (c.Loyalty <= (BaseCreature.MaxLoyalty / 10))
                                {
                                    c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                    c.PlaySound(c.GetIdleSound());
                                }
 
Like this? 48 for bonded 24 for non bonded, both would get deleted


Code:
                    else if (c.Controlled && c.Commandable)
                    {
                        c.OwnerAbandonTime = DateTime.MinValue;

                        if (c.Map != Map.Internal)
                        {
                            if (c.IsBonded)
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 48);
                                    if (c.Loyalty <= (BaseCreature.MaxLoyalty / 48))
                                    {
                                        c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                        c.PlaySound(c.GetIdleSound());
                                    }                                   
                                }
                                else
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 24);
                                    if (c.Loyalty <= (BaseCreature.MaxLoyalty / 24))
                                    {
                         
                                c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                c.PlaySound(c.GetIdleSound());
                            }

                            if (c.Loyalty <= 0)
                                //toRelease.Add(c);
                                  toRemove.Add(c);
                        }
                    }

                    // added lines to check if a wild creature in a house region has to be removed or not
                    if ( /*(!c.Controlled && !c.IsStabled && ( c.Region.IsPartOf( typeof( HouseRegion ) ) && c.CanBeDamaged()) || */(c.RemoveIfUntamed && c.Spawner == null))
                    {
                        c.RemoveStep++;

                        if (c.RemoveStep >= 20)
                            toRemove.Add(c);
                    }
                    else
                    {
                        c.RemoveStep = 0;
                    }

                    /// edit:     homerange spawns
                                                                                                                                                   
                    if (c.Map != Map.Internal && c.Spawner != null)
                    {
                        if (!c.Controlled && c.LastOwner == null && !c.InRange(((Item)c.Spawner).Location, c.Spawner.HomeRange))
                        {
                            if (c.Spawner is XmlSpawner)
                            {
                                if (((XmlSpawner)c.Spawner).WayPoint != null)
                                    continue;
                            }
                            toMove.Add(c);
                        }
                    }
                }
 
MaxLoyalty is 100 and both are integers: Without jumping through hoops, easiest way would be /25 (-4) and /50 (-2). If anyone questions it, just tell dead pets don't consider that they might not have started with full loyalty, and out of the generosity of your heart you gave them extra time :p
 
Sorry for annoy you again, how to make only bonded ones go wild and non bonded get deleted?

Like this?
Code:
if (c.IsBonded) && c.Loyalty <= 0)

toRelease.Add(c);
}
else
 {
if c.Loyalty <= 0)                     

 toRemove.Add(c);

}
 
I would just embed the loyalty checks in the IsBonded/Else nests. In hindsight, I'm not sure why the Loyalty < 0 check isn't embedded within the loyalty <= maxloyalty /10 nest either.

Code:
                if (c.IsBonded)
                 {
                   c.Loyalty -= (BaseCreature.MaxLoyalty / 50);
                   if (c.Loyalty <= (BaseCreature.MaxLoyalty / 50))
                   {
                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                     c.PlaySound(c.GetIdleSound());

                     if (c.Loyalty <= 0)
                     {
                       toRelease.Add(c);
                     }
                   }   
                 }
                 else
                 {
                   c.Loyalty -= (BaseCreature.MaxLoyalty / 25);
                   if (c.Loyalty <= (BaseCreature.MaxLoyalty / 25))
                   {   
                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                     c.PlaySound(c.GetIdleSound());

                     if (c.Loyalty <= 0)
                     {
                       toRemove.Add(c);
                     }
                   }
                 }
 
So players have to keep feeding their pets to not let loyalty go down way too much?

what if pet is stabled loyalty still go down?

Im getting errors due last edit.

Errors:
+ Mobiles/BaseCreature.cs:
CS0136: Line 5893: A local variable named 'c' cannot be declared in this sco
pe because it would give a different meaning to 'c', which is already used in a
'parent or current' scope to denote something else
CS0136: Line 5912: A local variable named 'c' cannot be declared in this sco
pe because it would give a different meaning to 'c', which is already used in a

'parent or current' scope to denote something else


foreach(BaseCreature c in toRelease) this is the first error Line 5912
foreach (BaseCreature c in toMove) the second one Line 5893

Code:
        protected override void OnTick()
        {
            if (DateTime.Now >= m_NextHourlyCheck)
                m_NextHourlyCheck = DateTime.Now + TimeSpan.FromHours(1.0);
            else
                return;

            List<BaseCreature> toRelease = new List<BaseCreature>();

            // added array for wild creatures in house regions to be removed
            List<BaseCreature> toRemove = new List<BaseCreature>();

            // Taran: Added array for untamed mobiles moving back to their spawnpoint
            List<BaseCreature> toMove = new List<BaseCreature>();

            foreach (Mobile m in World.Mobiles.Values)
            {
                if (m is BaseMount && ((BaseMount)m).Rider != null)
                {
                    ((BaseCreature)m).OwnerAbandonTime = DateTime.MinValue;
                    continue;
                }

                if (m is BaseCreature)
                {
                    BaseCreature c = (BaseCreature)m;

                    if (c.IsDeadPet)
                    {
                        Mobile owner = c.ControlMaster;

                        if (!c.IsStabled && (owner == null || owner.Deleted || owner.Map != c.Map || !owner.InRange(c, 12) || !c.CanSee(owner) || !c.InLOS(owner)))
                        {
                            if (c.OwnerAbandonTime == DateTime.MinValue)
                                c.OwnerAbandonTime = DateTime.Now;
                            else if ((c.OwnerAbandonTime + c.BondingAbandonDelay) <= DateTime.Now)
                                toRemove.Add(c);
                        }
                        else
                        {
                            c.OwnerAbandonTime = DateTime.MinValue;
                        }
                    }
                    else if (c.Controlled && c.Commandable)
                    {
                        c.OwnerAbandonTime = DateTime.MinValue;

                        if (c.Map != Map.Internal)
                        {
                       if (c.IsBonded) //CRIATURAS LEALES DEJAN DE SERLO TRAS DOS DIAS SIN SER RESUCITADAS
                      {
                         c.Loyalty -= (BaseCreature.MaxLoyalty / 50);
                      if (c.Loyalty <= (BaseCreature.MaxLoyalty / 50))
                     {
                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                     c.PlaySound(c.GetIdleSound());
                     if (c.Loyalty <= 0)
                     {
                       toRelease.Add(c);
                     }
                   }
                 }
                 else
                 {
                   c.Loyalty -= (BaseCreature.MaxLoyalty / 25);
                   if (c.Loyalty <= (BaseCreature.MaxLoyalty / 25))
                   {
                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                     c.PlaySound(c.GetIdleSound());
                     if (c.Loyalty <= 0)
                     {
                       toRemove.Add(c);
                     }
                   }
               

                    // added lines to check if a wild creature in a house region has to be removed or not
                    if ( /*(!c.Controlled && !c.IsStabled && ( c.Region.IsPartOf( typeof( HouseRegion ) ) && c.CanBeDamaged()) || */(c.RemoveIfUntamed && c.Spawner == null))
                    {
                        c.RemoveStep++;

                        if (c.RemoveStep >= 20)
                            toRemove.Add(c);
                    }
                    else
                    {
                        c.RemoveStep = 0;
                    }

                    /* Taran: Added check to see if any mobile that has a spawner is further away than *
                     * their spawners homerange. In that case the mobile teleports back to the spawner *
                     * again.                                                                          *
                     *                                                                                 */
                    if (c.Map != Map.Internal && c.Spawner != null)
                    {
                        if (!c.Controlled && c.LastOwner == null && !c.InRange(((Item)c.Spawner).Location, c.Spawner.HomeRange))
                        {
                            if (c.Spawner is XmlSpawner)
                            {
                                if (((XmlSpawner)c.Spawner).WayPoint != null) //Mobiles with waypoints will not be moved
                                    continue;
                            }
                            toMove.Add(c);
                        }
                    }
                }
            }

            foreach (BaseCreature c in toRelease)
            {
                c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master!
                c.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
                c.IsBonded = false;
                c.BondingBegin = DateTime.MinValue;
                c.OwnerAbandonTime = DateTime.MinValue;
                c.ControlTarget = null;
                //c.ControlOrder = OrderType.Release;
                c.AIObject.DoOrderRelease(); // this will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers)
                c.DropBackpack();
            }

            //// added code to handle removing of wild creatures in house regions
            //foreach ( BaseCreature c in toRemove )
            //{
            //    c.Delete();
            //}

            foreach (BaseCreature c in toMove)
            {
                Item spawner = c.Spawner as Item;

                Point3D from = c.Location;
                if (spawner != null)
                {
                    Point3D to = spawner.Location;

                    Effects.SendLocationParticles(EffectItem.Create(from, c.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
                    Effects.SendLocationParticles(EffectItem.Create(to, spawner.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);

                    c.MoveToWorld(to, spawner.Map);
                }

                c.PlaySound(0x1FE);
            }
        }
      }
    }
   }
  }
}
    //bonded pets edit 5/11/2016

Thank you
 
Last edited:
I do believe stabled and mounted pets are in the internal map and are excluded.
As for the error, you've misplaced some braces (Which is one of the main reasons why tabs are superior to spaces for indents :p)

What version are you running, and which program are you using to edit?
 
Ahh yes, braces are my enemy nº1, always gave me problems

I also hated dental braces so much when i had them :p

i cant find what braces are causing the errors :S lol, sad day!
 
Last edited:
I cant stress this enough, use Visual Studio. Its free and you will see the missing brace immediately when the rest of your code turns red, lol.
 
Okey, that program size is big, isnt it? i had it installed long ago, it took like 40 min until installation finished
 
Heh, I use Notepad++. Note quite THAT obvious, but the tab indicator runs off either into nowhere or into text if you have it indented corectly and make a mistake :)
 
Heh, I use Notepad++. Note quite THAT obvious, but the tab indicator runs off either into nowhere or into text if you have it indented corectly and make a mistake :)
Me too! very easy ,intuitive and light :)

Edit:

No errors now, not sure if i fixed the braces problem or i just messed something else up, does this look correct?:

Code:
        protected override void OnTick()
        {
            if (DateTime.Now >= m_NextHourlyCheck)
                m_NextHourlyCheck = DateTime.Now + TimeSpan.FromHours(1.0);
            else
                return;

            List<BaseCreature> toRelease = new List<BaseCreature>();

            // added array for wild creatures in house regions to be removed
            List<BaseCreature> toRemove = new List<BaseCreature>();

            // : Added array for untamed mobiles moving back to their spawnpoint
            List<BaseCreature> toMove = new List<BaseCreature>();

            foreach (Mobile m in World.Mobiles.Values)
            {
                if (m is BaseMount && ((BaseMount)m).Rider != null)
                {
                    ((BaseCreature)m).OwnerAbandonTime = DateTime.MinValue;
                    continue;
                }

                if (m is BaseCreature)
                {
                    BaseCreature c = (BaseCreature)m;

                    if (c.IsDeadPet)
                    {
                        Mobile owner = c.ControlMaster;

                        if (!c.IsStabled && (owner == null || owner.Deleted || owner.Map != c.Map || !owner.InRange(c, 12) || !c.CanSee(owner) || !c.InLOS(owner)))
                        {
                            if (c.OwnerAbandonTime == DateTime.MinValue)
                                c.OwnerAbandonTime = DateTime.Now;
                            else if ((c.OwnerAbandonTime + c.BondingAbandonDelay) <= DateTime.Now)
                                toRemove.Add(c);
                        }
                        else
                        {
                            c.OwnerAbandonTime = DateTime.MinValue;
                        }
                    }
                    else if (c.Controlled && c.Commandable)
                    {
                        c.OwnerAbandonTime = DateTime.MinValue;

                       
                 if (c.Map != Map.Internal)
                 {
                 if (c.IsBonded)
                 {
                   c.Loyalty -= (BaseCreature.MaxLoyalty / 50);
                   if (c.Loyalty <= (BaseCreature.MaxLoyalty / 50))
                   {
                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                     c.PlaySound(c.GetIdleSound());
                     if (c.Loyalty <= 0)
                     {
                       toRelease.Add(c);
                     }
                   } 
                 }
                 else
                 {
                   c.Loyalty -= (BaseCreature.MaxLoyalty / 25);
                   if (c.Loyalty <= (BaseCreature.MaxLoyalty / 25))
                   { 
                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                     c.PlaySound(c.GetIdleSound());
                     if (c.Loyalty <= 0)
                     {
                       toRemove.Add(c);
                     }
                   }

                    // added lines to check if a wild creature in a house region has to be removed or not
                    if ( /*(!c.Controlled && !c.IsStabled && ( c.Region.IsPartOf( typeof( HouseRegion ) ) && c.CanBeDamaged()) || */(c.RemoveIfUntamed && c.Spawner == null))
                    {
                        c.RemoveStep++;

                        if (c.RemoveStep >= 20)
                            toRemove.Add(c);
                    }
                    else
                    {
                        c.RemoveStep = 0;
                    }

                    /* check to see if any mobile that has a spawner is further away than *
                     * their spawners homerange. In that case the mobile teleports back to the spawner *
                     * again.                                                                          *
                     *                                                                                 */
                    if (c.Map != Map.Internal && c.Spawner != null)
                    {
                        if (!c.Controlled && c.LastOwner == null && !c.InRange(((Item)c.Spawner).Location, c.Spawner.HomeRange))
                        {
                            if (c.Spawner is XmlSpawner)
                            {
                                if (((XmlSpawner)c.Spawner).WayPoint != null) //Mobiles with waypoints will not be moved
                                    continue;
                            }
                            toMove.Add(c);
                        }
                    }
                }
            }
                    }
                }

            foreach (BaseCreature c in toRelease)
            {
                c.Say(1043255, c.Name); // ~1_NAME~ appears to have decided that is better off without a master!
                c.Loyalty = BaseCreature.MaxLoyalty; // Wonderfully Happy
                c.IsBonded = false;
                c.BondingBegin = DateTime.MinValue;
                c.OwnerAbandonTime = DateTime.MinValue;
                c.ControlTarget = null;
                //c.ControlOrder = OrderType.Release;
                c.AIObject.DoOrderRelease(); // this will prevent no release of creatures left alone with AI disabled (and consequent bug of Followers)
                c.DropBackpack();
            }

            //// added code to handle removing of wild creatures in house regions
            //foreach ( BaseCreature c in toRemove )
            //{
            //    c.Delete();
            //}

            foreach (BaseCreature c in toMove)
            {
                Item spawner = c.Spawner as Item;

                Point3D from = c.Location;
                if (spawner != null)
                {
                    Point3D to = spawner.Location;

                    Effects.SendLocationParticles(EffectItem.Create(from, c.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 2023);
                    Effects.SendLocationParticles(EffectItem.Create(to, spawner.Map, EffectItem.DefaultDuration), 0x3728, 10, 10, 5023);

                    c.MoveToWorld(to, spawner.Map);
                }

                c.PlaySound(0x1FE);
            }
         }
     
      }
    }
}
 
Last edited:
Oh, don't get me wrong, I love Notepad++ for a lightweight solution when I'm messing with a single file. I used to use Notepad++ for everything until Voxpire and Tresdni turned me on to the ooey goodness of VS. You just cant beat the ability for the program to see the entire project and how each file relates to the next file. You can track when a method is being called from another script in seconds.

Anyway, enough advertisement, lol. I'm loving the ideas for pets in this thread!! While ServUO is dedicated to OSI accuracy (even when the implementation is stupid), I love seeing the better ways of implementing the existing systems.
 
Hmm im monitoring a non bonded mustang looks like loyalty doesnt go below 1 :/

and if i set it to 0 it doesnt even go wild, uuughhhh
 
That's because you set non bonded animals to be removed:
Code:
[*]else
[*]                 {
[*]                   c.Loyalty -= (BaseCreature.MaxLoyalty / 25);
[*]                   if (c.Loyalty <= (BaseCreature.MaxLoyalty / 25))
[*]                   {
[*]                     c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
[*]                     c.PlaySound(c.GetIdleSound());
[*]                     if (c.Loyalty <= 0)
[*]                     {
[*]                       toRemove.Add(c);
[*]                     }
[*]                   }

But toRemove method is commented out...

Code:
[*]            //// added code to handle removing of wild creatures in house regions
[*]            //foreach ( BaseCreature c in toRemove )
[*]            //{
[*]            //    c.Delete();
[*]            //}
 
This is the way i currently have it;



Code:
 if (c.Map != Map.Internal)
                        {
                            if (c.IsBonded)
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 50);
                                    if (c.Loyalty <= (BaseCreature.MaxLoyalty / 50))
                                    {
                                        c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                        c.PlaySound(c.GetIdleSound());
                                    }                                
                                }
                          
                           else
                                {
                                    c.Loyalty -= (BaseCreature.MaxLoyalty / 25);
                                    if (c.Loyalty <= (BaseCreature.MaxLoyalty / 25))
                                    {
                       
                                c.Say(1043270, c.Name); // * ~1_NAME~ looks around desperately *
                                c.PlaySound(c.GetIdleSound());
                            }
                            if (c.Loyalty <= 0)
                                toRelease.Add(c);
                                  //toRemove.Add(c);
                        }
                    }
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back