RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

This Problem is Close to a Deal Breaker

I thought I had this solved but it has come up again today just before an event.

My players are losing their pets to the system. This applies both to stabled and shrunken pets. It seems to be some what random because it does not affect all players at the same time and it does not affect every pet a player owns. Some of the pets lost have been in storage for a while and others only a few hours. It has nothing to do with server reboots as some have been lost when the shrinking and retrieval attempt take place between reboots.

With the stabled pets that are lost they just get a message saying - "I have no animals stabled with me at the moment". With the shrunken pets they have a statue with no stats and on Double Click they get a message saying "Due to unforeseen circumstances your pet is lost forever"

I have a number of serious tamers and this is making everyone frustrated.

Here is the ShrinkItem script with the "... unforeseen circumstances ..." message:

Code:
#region AuthorHeader
//
//Shrink System version 2.1, by Xanthos
//
//
#endregion AuthorHeader
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.ContextMenus;
using Xanthos.Utilities;
using Xanthos.Interfaces;
using Server.Regions;
 
namespace Xanthos.ShrinkSystem
 
{
public class ShrinkItem : Item, IShrinkItem
{
// Persisted
private bool m_IsStatuette;
private bool m_Locked;
private Mobile m_Owner;
private BaseCreature m_Pet;
 
// Not persisted; lazy loaded.
private bool m_PropsLoaded;
private string m_Breed;
private string m_Gender;
private bool m_IsBonded;
private string m_Name;
private int m_RawStr;
private int m_RawDex;
private int m_RawInt;
private double m_Wrestling;
private double m_Tactics;
private double m_Anatomy;
private double m_Poisoning;
private double m_Magery;
private double m_EvalInt;
private double m_MagicResist;
private double m_Meditation;
private double m_Archery;
private double m_Fencing;
private double m_Macing;
private double m_Swords;
private double m_Parry;
private int m_EvoEp;
private int m_EvoStage;
 
private bool m_IgnoreLockDown;// Is only ever changed by staff
 
[CommandProperty( AccessLevel.GameMaster )]
public bool IsStatuette
{
get { return m_IsStatuette; }
set
{
if ( null == ShrunkenPet )
{
ItemID = 0xFAA;
Name = "unlinked shrink item!";
}
else if ( m_IsStatuette = value )
{
ItemID = ShrinkTable.Lookup( m_Pet );
Name = m_Name = m_Pet.Name +" (Shrunk)";
}
else
{
ItemID = 0x14EF;
Name = "a pet deed";
}
}
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool IgnoreLockDown
{
get { return m_IgnoreLockDown; }
set { m_IgnoreLockDown = value; InvalidateProperties(); }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public bool Locked
{
get { return m_Locked; }
set { m_Locked = value; InvalidateProperties(); }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Owner
{
get { return m_Owner; }
set { m_Owner = value; InvalidateProperties(); }
}
 
[CommandProperty( AccessLevel.GameMaster )]
public BaseCreature ShrunkenPet
{
get { return m_Pet; }
set { m_Pet = value; InvalidateProperties(); }
}
 
public ShrinkItem() : base()
{
}
 
public ShrinkItem( Serial serial ) : base( serial )
{
}
 
public ShrinkItem( BaseCreature pet ) : this()
{
ShrinkPet( pet );
IsStatuette = ShrinkConfig.PetAsStatuette;
m_IgnoreLockDown = false; // This is only used to allow GMs to bypass the lockdown, one pet at a time.
Weight = ShrinkConfig.ShrunkenWeight;
 
if ( !(m_Pet is IEvoCreature) || ((IEvoCreature)m_Pet).CanHue )
Hue = m_Pet.Hue;
}
 
public override void OnDoubleClick( Mobile from )
{
if ( !m_PropsLoaded )
PreloadProperties();
 
if ( !IsChildOf( from.Backpack ) )
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
 
else if ( m_Pet == null || m_Pet.Deleted || ItemID == 0xFAA )
from.SendMessage( "Due to unforseen circumstances your pet is lost forever." );
 
else if ( m_Locked && m_Owner != from )
{
from.SendMessage( "This is locked and only the owner can claim this pet while locked." );
from.SendMessage( "This item is now being returned to its owner." );
m_Owner.AddToBackpack( this );
m_Owner.SendMessage( "Your pet {0} has been returned to you because it was locked and {1} was trying to claim it.", m_Breed, from.Name );
}
else if ( from.Followers + m_Pet.ControlSlots > from.FollowersMax )
from.SendMessage( "You have to many followers to claim this pet." );
 
else if ( Server.Spells.SpellHelper.CheckCombat( from ) )
from.SendMessage( "You cannot reclaim your pet while your fighting." );
 
else if ( ShrinkCommands.LockDown == true && !m_IgnoreLockDown )
from.SendMessage( 54, "The server is on a shrinkitem lockdown. You cannot unshrink your pet at this time." );
 
else if ( !m_Pet.CanBeControlledBy( from ))
from.SendMessage( "You do not have the required skills to control this pet.");
 
else
UnshrinkPet( from );
}
 
private void ShrinkPet( BaseCreature pet )
{
m_Pet = pet;
m_Owner = pet.ControlMaster;
 
if ( ShrinkConfig.LootStatus == ShrinkConfig.BlessStatus.All
|| ( m_Pet.IsBonded && ShrinkConfig.LootStatus == ShrinkConfig.BlessStatus.BondedOnly ))
LootType = LootType.Blessed;
else
LootType = LootType.Regular;
 
m_Pet.Internalize();
m_Pet.SetControlMaster( null );
m_Pet.ControlOrder = OrderType.Stay;
m_Pet.SummonMaster = null;
m_Pet.IsStabled = true;
 
if ( pet is IEvoCreature )
((IEvoCreature)m_Pet).OnShrink( this );
}
 
private void UnshrinkPet( Mobile from )
{
m_Pet.SetControlMaster( from );
m_Pet.IsStabled = false;
m_Pet.MoveToWorld( from.Location, from.Map );
if ( from != m_Owner )
m_Pet.IsBonded = false;
 
m_Pet = null;
this.Delete();
}
 
// Summoning ball was used so dispose of the shrink item
public void OnPetSummoned()
{
m_Pet = null;
Delete();
}
 
public override void Delete()
{
if ( m_Pet != null )// Don't orphan pets on the internal map
m_Pet.Delete();
 
base.Delete();
}
 
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
 
if (( ShrinkConfig.AllowLocking || m_Locked == true ) && from.Alive && m_Owner == from )
{
if ( m_Locked == false )
list.Add( new LockShrinkItem( from, this ) );
else
list.Add( new UnLockShrinkItem( from, this ) );
}
}
 
public override void AddNameProperties( ObjectPropertyList list )
{
base.AddNameProperties( list );
 
if ( null == m_Pet || m_Pet.Deleted )
return;
 
if ( !m_PropsLoaded )
PreloadProperties();
 
if ( m_IsBonded && ShrinkConfig.BlessStatus.None == ShrinkConfig.LootStatus )// Only show bonded when the item is not blessed
list.Add( 1049608 );
 
if ( ShrinkConfig.AllowLocking || m_Locked )// Only show lock status when locking enabled or already locked
list.Add( 1049644, ( m_Locked == true ) ? "Locked" : "Unlocked" );
 
if ( ShrinkConfig.ShowPetDetails )
{
//list.Add( 1060663, "Name\t{0} Breed: {1} Gender: {2}", m_Name, m_Breed, m_Gender );
list.Add( 1060663, "Name\t{0} Bonded: {1} Gender: {2}", m_Name,m_IsBonded, m_Gender );
list.Add( 1061640, ( null == m_Owner ) ? "nobody (WILD)" : m_Owner.Name ); // Owner: ~1_OWNER~
list.Add( 1060659, "Stats\tStrength {0}, Dexterity {1}, Intelligence {2}", m_RawStr, m_RawDex, m_RawInt );
list.Add( 1060660, "Combat Skills\tWrestling {0}, Tactics {1}, Anatomy {2}, Poisoning {3}", m_Wrestling, m_Tactics, m_Anatomy, m_Poisoning );
list.Add( 1060661, "Magic Skills\tMagery {0}, Eval Intel {1}, Magic Resist {2}, Meditation {3}", m_Magery, m_EvalInt, m_MagicResist, m_Meditation );
if ( !( 0 == m_Parry && 0 == m_Archery ))
list.Add( 1060661, "Weapon Skills\tArchery {0}, Fencing {1}, Macing {2}, Parry {3}, Swords {4}", m_Archery, m_Fencing, m_Macing, m_Parry, m_Swords );
if ( m_EvoEp > 0 )
list.Add( 1060662, "EP\t{0}, Stage: {1}", m_EvoEp, m_EvoStage + 1 );
}
else
list.Add( 1060663, "Name\t{0}", m_Name );
}
 
private void PreloadProperties()
{
if ( null == m_Pet )
return;
 
m_IsBonded = m_Pet.IsBonded;
m_Name = m_Pet.Name;
 
m_Gender = (m_Pet.Female ? "Female" : "Male");
m_Breed = Xanthos.Utilities.Misc.GetFriendlyClassName( m_Pet.GetType().Name );
m_RawStr = m_Pet.RawStr;
m_RawDex = m_Pet.RawDex;
m_RawInt = m_Pet.RawInt;
m_Wrestling = m_Pet.Skills[SkillName.Wrestling].Base;
m_Tactics = m_Pet.Skills[SkillName.Tactics].Base;
m_Anatomy = m_Pet.Skills[SkillName.Anatomy].Base;
m_Poisoning = m_Pet.Skills[SkillName.Poisoning].Base;
m_Magery = m_Pet.Skills[SkillName.Magery].Base;
m_EvalInt = m_Pet.Skills[SkillName.EvalInt].Base;
m_MagicResist = m_Pet.Skills[SkillName.MagicResist].Base;
m_Meditation = m_Pet.Skills[SkillName.Meditation].Base;
m_Parry = m_Pet.Skills[SkillName.Parry].Base;
m_Archery = m_Pet.Skills[SkillName.Archery].Base;
m_Fencing = m_Pet.Skills[SkillName.Fencing].Base;
m_Swords = m_Pet.Skills[SkillName.Swords].Base;
m_Macing = m_Pet.Skills[SkillName.Macing].Base;
 
IEvoCreature evo = m_Pet as IEvoCreature;
 
if ( null != evo )
{
m_EvoEp = evo.Ep;
m_EvoStage = evo.Stage;
}
 
m_PropsLoaded = true;
}
 
public static bool IsPackAnimal( BaseCreature pet )
{
if ( null == pet || pet.Deleted )
return false;
 
Type breed = pet.GetType();
 
foreach ( Type packBreed in ShrinkConfig.PackAnimals )
if ( packBreed == breed )
return true;
 
return false;
}
 
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
 
writer.Write( (int)0 ); // version
writer.Write( m_IsStatuette );
writer.Write( m_Locked );
writer.Write( (Mobile)m_Owner );
writer.Write( (Mobile)m_Pet );
}
 
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
 
switch ( reader.ReadInt() )
{
case 0:
{
m_IsStatuette = reader.ReadBool();
m_Locked = reader.ReadBool();
m_Owner = (PlayerMobile)reader.ReadMobile();
m_Pet = (BaseCreature)reader.ReadMobile();
 
if (null != m_Pet )
m_Pet.IsStabled = true;
 
break;
}
}
}
}
 
public class LockShrinkItem : ContextMenuEntry
{
private Mobile m_From;
private ShrinkItem m_ShrinkItem;
 
public LockShrinkItem( Mobile from, ShrinkItem shrink ) : base( 2029, 5 )
{
m_From = from;
m_ShrinkItem = shrink;
}
 
public override void OnClick()
{
m_ShrinkItem.Locked = true;
m_From.SendMessage( 38, "You have locked this shrunken pet so only you can reclaim it." );
}
}
 
public class UnLockShrinkItem : ContextMenuEntry
{
private Mobile m_From;
private ShrinkItem m_ShrinkItem;
 
public UnLockShrinkItem( Mobile from, ShrinkItem shrink ) : base( 2033, 5 )
{
m_From = from;
m_ShrinkItem = shrink;
}
 
public override void OnClick()
{
m_ShrinkItem.Locked = false;
m_From.SendMessage( 38, "You have unlocked this shrunken pet, now anyone can reclaim it as theirs." );
}
}
}

I have been through a number of stable and shrink related scripts looking for problems and I have searched extensively here all to no avail.
Has anyone faced and solved this? or . . can any one point me out of this fix?
Many Thanks
*bows*
 
I have looked closely but can find nothing that looks like it tries to clean the internal map. I searched all scripts for 'internal' and 'clean' but nothing there that looks like the it would do that.

Still a head scratcher for me.
 
Well . . I now have all pets being set to full Loyalty when being stabled or shrunk (as well as when being claimed or unshrunk) but we still have players losing pets to the Stabling and Shrink systems. Our Xanthos shrink system uses a Hitching Post and a Pet Leash. We also have a Shrink Potion but no one has been able to make or use the potion yet.

This does not appear to be a case of things going wild while stabled or shrunk and so far I have found no trace of anything trying to clean the Internal Map. It looks like somehow the pet information is not getting retrieved. I have no idea why this would work some of the time but not all of the time.

Has anyone at all experienced this? If so were you able to solve it (script or work-around)?

Open to all ideas.
Many Thanks
 

milva

Sorceror
We had Xanto's shrink for a long time and never experienced this problem, have you done edits to any animal scripts, lore etc? Of course players need to remember they have to feed pets, I can't count the amount of times for reminding players to feed their pets. The more they battle with them the more feeding they need.
 

daat99

Moderator
Staff member
You can start debugging this by adding console messages when player are trying to "shrink/unshrink" their pets.
There might be a problem there that doesn't save the information right.
 
We had Xanto's shrink for a long time and never experienced this problem, have you done edits to any animal scripts, lore etc? Of course players need to remember they have to feed pets, I can't count the amount of times for reminding players to feed their pets. The more they battle with them the more feeding they need.

I have not changed any animal scripts in this way that I can recall. I have edited the Evo Mercenary and I have created a new Evo Drow Dragon. Two of the pets that have been lost are Hiryu and Lesser Hiryu but I made no changes to them. Yes I have warned players about feeding. Some of my Veteran Tamers claim they fed their pets before shrinking and/or stabling but still lost them. Also my edit - setting pet loyalty to max on stabling/shrinking should have solved that.

I really appreciate the help.


You can start debugging this by adding console messages when player are trying to "shrink/unshrink" their pets.
There might be a problem there that doesn't save the information right.

This sounds like it could be a promising way to find the problem but I would not know how to do this or what to look for. Thanks Daat - still that dumb after 2 years here.
 

milva

Sorceror
We didn't have the merc scripts in, did you by chance edit anything for players to be able
to shrink those?
 

seraph035

Sorceror
A thought that occurs to me is that, if the pets are still in some way linked to the spawner that generated them, when the spawner resets or does a forced respawn, the pet would be deleted.

Such a condition could explain why some pets are lost and others are not, and the time of loss is also variable. Testing for this should be simple: tame, stable, then reset the spawner (preferably one that is known to have generated a lost pet). If the newly stabled pet is lost in this case, That may be informative.

Fixing the issue, on the other hand .. meh, no idea as of now. I hope you can get it fixed, good fortune!
 

Vorspire

Knight
We had this issue with Xanthos' Shrink System on both of our shards which prompted me to completely re-write the entire thing.

Turns out, if people shrink pets that are poisoned or mortally wounded, there's a chance they can die after being shrunk and that would delete them if they weren't bonded.
(Resulting in "your pet has been lost forever")

Instead of losing the pet forever, I have it "reincarnated, but may not be as strong as before"
 
First - Thank you thank you for the flow of ideas. This is really helping me and letting me know I am not swinging in the breeze by myself.


We didn't have the merc scripts in, did you by chance edit anything for players to be able
to shrink those?

No I did not touch the Xanthos Shrink system other then making a Leash version of the Hitching Post to give players options.


A thought that occurs to me is that, if the pets are still in some way linked to the spawner that generated them, when the spawner resets or does a forced respawn, the pet would be deleted.

Such a condition could explain why some pets are lost and others are not, and the time of loss is also variable. Testing for this should be simple: tame, stable, then reset the spawner (preferably one that is known to have generated a lost pet). If the newly stabled pet is lost in this case, That may be informative.

Fixing the issue, on the other hand .. meh, no idea as of now. I hope you can get it fixed, good fortune!

The Lesser Hiryu and the Hiryu do come from spawners but should be like any critter Tamed after spawning. I am assuming *bad idea* that spawners would treat Taming a critter the same as they would killing the critter. The Evo Mercenary and Evo Dragon are dropped as a deed and an egg from the Guardians on death. We are losing both Hiryu and Mercs so the spawners are not a common denominator.



We had this issue with Xanthos' Shrink System on both of our shards which prompted me to completely re-write the entire thing.

Turns out, if people shrink pets that are poisoned or mortally wounded, there's a chance they can die after being shrunk and that would delete them if they weren't bonded.
(Resulting in "your pet has been lost forever")

Instead of losing the pet forever, I have it "reincarnated, but may not be as strong as before"

Interesting - when you say you completely re-wrote the entire thing, that sounds ominous . . . or . . . did you just re-do the part giving the message ". . . pet has been lost forever" ?
 

Vorspire

Knight
I re-wrote the entire system :)

You can use this for reference;

ShrinkFunctions.cs:
Code:
#region References
using System;

using Server.Items;
using Server.Mobiles;
#endregion

namespace Server
{
	public static class ShrinkFunctions
	{
		public static bool Shrink(BaseCreature c, Mobile owner = null, bool message = true)
		{
			if (c == null || c.Deleted || c.Map == null || c.Map == Map.Internal ||
				(owner != null && (owner.Deleted || owner.Map == null || owner.Map == Map.Internal || owner == c)))
			{
				return false;
			}

			bool gm = (owner != null && owner.AccessLevel >= AccessLevel.GameMaster);
			bool shrink = false;
			string msg = String.Empty;

			if (c.Summoned)
			{
				msg = "You can't shrink a summoned creature.";
			}
			else if (!c.Alive || c.IsDeadPet)
			{
				msg = "You can't shrink a dead creature.";
			}
			else if (c.Poisoned && (owner == null || !c.Poison.TryCure(c, owner, false, false)))
			{
				msg = "You can't shrink a poisoned creature.";
			}
			else if (BleedAttack.IsBleeding(c))
			{
				msg = "You can't shrink a bleeding creature.";
			}
			else if (MortalStrike.IsWounded(c))
			{
				msg = "You can't shrink a mortally wounded creature.";
			}
			else if (c.Hits < (c.HitsMax / 2) && !gm)
			{
				msg = "You can't shrink a creature with less than half health.";
			}
			else if (c.Allured && !gm)
			{
				msg = "You can't shrink am allured creature.";
			}
			else if (!c.Controlled && !gm)
			{
				msg = "You can't shrink an uncontrolled creature.";
			}
			else if ((c.InCombat() || (c.Combatant != null && c.InRange(c.Combatant, 12) && c.Map == c.Combatant.Map)) && !gm)
			{
				msg = "You can't shrink an aggressed creature.";
			}
			else if (owner != null && !gm && c.ControlMaster != owner)
			{
				msg = "You can't shrink a creature that you can't control.";
			}
			/*else if (c.Backpack is StrongBackpack && c.Backpack.Items.Count > 0)
			{
				msg = "You can't shrink a creature while it's carrying a load.";
			}*/
			else
			{
				shrink = true;
			}

			if (shrink)
			{
				Item s;
				Point3D loc = c.Location;
				Map map = c.Map;

				if (c.CanSwim)
				{
					s = new ShrinkItemWater(c);
				}
				else
				{
					s = new ShrinkItem(c);
				}

				if (owner == null)
				{
					s.MoveToWorld(loc, map);
				}
				else
				{
					if (owner.AddToBackpack(s))
					{
						msg = "You place the " + s.Name + " into your pack.";
					}
					else
					{
						s.MoveToWorld(owner.Location, owner.Map);
						msg = "The " + s.Name + " falls at your feet.";
					}
				}
			}

			if (owner != null && message && !String.IsNullOrWhiteSpace(msg))
			{
				owner.SendMessage(msg);
			}

			return shrink;
		}

		public static bool UnShrink(ShrinkItem s, Mobile owner, bool message)
		{
			return s != null && !s.Deleted && s.UnShrink(owner, message);
		}

		public static bool UnShrink(ShrinkItemWater s, Mobile owner, bool target, bool message)
		{
			return s != null && !s.Deleted && s.UnShrink(owner, target, message);
		}
	}
}

ShrinkItem (Constructor, handles shrinking)
Code:
public ShrinkItem(BaseCreature c)
			: base(ShrinkTable.DefaultItemID)
		{
			if (c != null && !c.Deleted)
			{
				Link = c;
				LinkType = c.GetType();
				LinkName = c.RawName;

				Link.ControlTarget = null;
				Link.ControlOrder = OrderType.Stay;
				Link.Internalize();
				Link.SetControlMaster(null);
				Link.SummonMaster = null;
				Link.IsStabled = true;

				Name = LinkName + " Idol";
			}
			else
			{
				Name = "Creature Idol";
			}

			Weight = 2 + (Linked ? (Link.TotalWeight / 4) : 0);
			LootType = LootType.Blessed;
		}

ShrinkItem (Unshrink Method):
Code:
		public virtual bool UnShrink(Mobile owner, bool message)
		{
			if (owner == null || owner.Deleted || owner.Map == null || owner.Map == Map.Internal)
			{
				return false;
			}

			if (!Linked)
			{
				if (message)
				{
					owner.SendMessage("The creature linked to this idol has been lost in the void.");
				}

				if (LinkType == null)
				{
					return false;
				}

				Link = LinkType.CreateInstanceSafe<BaseCreature>();

				if (!Linked)
				{
					return false;
				}

				Link.ControlTarget = null;
				Link.ControlOrder = OrderType.Stay;
				Link.Internalize();
				Link.SetControlMaster(null);
				Link.SummonMaster = null;
				Link.IsStabled = true;

				if (message)
				{
					owner.SendMessage("The creature has been reincarnated, it may be somewhat weaker than before.");
				}
			}

			bool gm = (owner.AccessLevel >= AccessLevel.GameMaster);

			if ((owner.Followers + Link.ControlSlots) > owner.FollowersMax && !gm)
			{
				if (message)
				{
					owner.SendMessage("You can't control this creature, you have too many followers.");
				}
				return false;
			}

			if (!Link.Owners.Contains(owner))
			{
				Link.Owners.Add(owner);
			}

			Link.SetControlMaster(owner);
			Link.ControlTarget = owner;
			Link.ControlOrder = OrderType.Follow;
			Link.MoveToWorld(owner.Location, owner.Map);
			Link.IsStabled = false;
			Link = null;

			Delete();
			return true;
		}

This code can't be copy and pasted in full, it will break your own version - use it strictly as a reference for making your own changes.

I can't release the entire system simply because it has too many outside variables and uses many of my VNc project's extensions.
 

seraph035

Sorceror
We had this issue with Xanthos' Shrink System on both of our shards which prompted me to completely re-write the entire thing.

Turns out, if people shrink pets that are poisoned or mortally wounded, there's a chance they can die after being shrunk and that would delete them if they weren't bonded.
(Resulting in "your pet has been lost forever")

Instead of losing the pet forever, I have it "reincarnated, but may not be as strong as before"

Another way to resolve this sort of issue would be to insert a condition test on pets when they are targeted for shrinking or stableing, and if they are mortally wounded|bleeding|poisoned return with "I am sorry, but I cannot stable/shrink this pet in it's current condition"
(**Insert EDIT** Ahh, I see that IS in the code, very good!)
-or-
Upon stable/shrink set these conditions to false ... although one might see players using the pet leash as an alternative to honest veterinary skill.
 
Okay I will look close at the above suggestions.

Also - I just discovered something I had not noticed before.

When players shrink pets I can see them on the Internal map using [global interface WHERE mobile Map = Internal

The shrunken ones that are retrievable are on the Internal Map (with the names given to them by the player). But the ones that cannot be retrieved are missing - gone off the Internal Map. Players tell me that all pets shrunken were in perfect health and well fed before shrinking.

I had done script searches for looking for anything that might trey cleaning the Internal Map but found nothing. I was using searches on 'internal' and 'clean' but found nothing. Is there something else I should be looking for in that regard?

Thanks again for the amazing feed back.

*bows*
 

seraph035

Sorceror
To be perfectly honest, looking at this code is making my head hurt, so I know what you must be going through, eh. There seem to be numerous cases that could cause m_pet variable to return null, which seems to be one cause of deletion, but there are three cases that return the unforseen circumstances message:
else if ( m_Pet == null || m_Pet.Deleted || ItemID == 0xFAA )
from.SendMessage( "Due to unforseen circumstances your pet is lost forever." );

Itemid 0xFAA is itemid 4010. Is there anything in your shrink table or systems that might interact with it that might be setting this value?

lost pets not showing on the internal map would be expected, if the cleanup was working properly, there is a cleanup implied in the code:

public override void Delete()
{
if ( m_Pet != null )// Don't orphan pets on the internal map
m_Pet.Delete();

base.Delete();
}
This one has me scratching my head, because it _seems_ to imply that, if m_pet has a value at all, it should be deleted. (The version of shrinksystem 2.1 that I found on the boards has the exact same line, so, if it works elsewhere, I'm going to assume *cough* that this bit is intended to be implemented only under certain circumstances (accounts deleted, or something of that nature that would ordainarily leave this item on the internal map, with a value)

Lets see, where else to look ... We have this, as the pet is shrinking, it seems:
m_Pet.Internalize();
m_Pet.SetControlMaster( null );
m_Pet.ControlOrder = OrderType.Stay;
m_Pet.SummonMaster = null;
m_Pet.IsStabled = true;
Looking at the basecreature.cs, in version 14 there is a (in my case) remarked section
that is intended to remove if untamed (ie, no controlmaster)
It's probably nothing, but due diligence and all .. double check to make sure that
creatures are not getting remove if untamed true if they are intended to be pets.

Other considerations: are there a set of alterations that were conducted prior to the beginning of the pet losses? anything in these alterations that influences the systems used to compose the pet handling script? ie, any of these:
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.ContextMenus;
using Xanthos.Utilities;
using Xanthos.Interfaces;
using Server.Regions;
 
Okay - first "Wow" thank you for the time and feed back here. Here is what I have found. I hope this helps lift the fog on my dilema further.

but there are three cases that return the unforseen circumstances message:
else if ( m_Pet == null || m_Pet.Deleted || ItemID == 0xFAA )
from.SendMessage( "Due to unforseen circumstances your pet is lost forever." );

Itemid 0xFAA is itemid 4010. Is there anything in your shrink table or systems that might interact with it that might be setting this value?

Good idea - okay, I checked and double checked this. No - there is nothing in my shrink table relating to 0xFAA or 4010.



lost pets not showing on the internal map would be expected, if the cleanup was working properly, there is a cleanup implied in the code:

public override void Delete()
{
if ( m_Pet != null )// Don't orphan pets on the internal map
m_Pet.Delete();

base.Delete();
}
This one has me scratching my head, because it _seems_ to imply that, if m_pet has a value at all, it should be deleted. (The version of shrinksystem 2.1 that I found on the boards has the exact same line, so, if it works elsewhere, I'm going to assume *cough* that this bit is intended to be implemented only under certain circumstances (accounts deleted, or something of that nature that would ordainarily leave this item on the internal map, with a value)

Yes - this bit of code is poking me in the ribs too. It just seems to run against the grain. I am tempted to play with it but nervous about changing it too - fearing the 'house of cards'. Still . . part of me is also wondering if this could be the reason other shards have had shrunken pets disappear as well. Could it explain too why the disapearance of pets seems to be random (some go quickly others last days).

Conversely . . could be wrong but I don't think the code above would affect the stable system. Remember . . I have had players reporting stabled pets disappearing too but have no shrunken item to trace or prove that and only their word that stabled pets were healthy and fed before stabling.




Lets see, where else to look ... We have this, as the pet is shrinking, it seems:
m_Pet.Internalize();
m_Pet.SetControlMaster( null );
m_Pet.ControlOrder = OrderType.Stay;
m_Pet.SummonMaster = null;
m_Pet.IsStabled = true;
Looking at the basecreature.cs, in version 14 there is a (in my case) remarked section
that is intended to remove if untamed (ie, no controlmaster)
It's probably nothing, but due diligence and all .. double check to make sure that
creatures are not getting remove if untamed true if they are intended to be pets.


This is also an interesting trail - In BaseCreature:

I have this in Serialize:
Code:
            // Version 14
            writer.Write((bool)m_RemoveIfUntamed);
            writer.Write((int)m_RemoveStep);

and . . this in Deserialize
Code:
            if (version >= 14)
            {
                m_RemoveIfUntamed = reader.ReadBool();
                m_RemoveStep = reader.ReadInt();
            }


all followed later with
Code:
        private bool m_RemoveIfUntamed;
 
        // used for deleting untamed creatures [in houses]
        private int m_RemoveStep;
 
        [CommandProperty(AccessLevel.GameMaster)]
        public bool RemoveIfUntamed { get { return m_RemoveIfUntamed; } set { m_RemoveIfUntamed = value; } }
 
        [CommandProperty(AccessLevel.GameMaster)]
        public int RemoveStep { get { return m_RemoveStep; } set { m_RemoveStep = value; } }
    }

and then . . followed further with
Code:
                    // added lines to check if a wild creature in a house region has to be removed or not
                    if ((!c.Controlled && (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;
                    }

These all appear (hate that term) to be dealing with cleaning up unwanted animals in or around houses. I am not sure if the code could be more sinister than that.




Other considerations: are there a set of alterations that were conducted prior to the beginning of the pet losses? anything in these alterations that influences the systems used to compose the pet handling script? ie, any of these:
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using System.Collections;
using System.Collections.Generic;
using Server.ContextMenus;
using Xanthos.Utilities;
using Xanthos.Interfaces;
using Server.Regions;

That is a big question. *scratches head* To my knowledge I have done nothing that would negatively affect these systems but a lot has been done. I did apply a cleanup to Champs to remove corpses and add the loot to the end boss for final distribution but doubt that would cause my current problem.
 

Vorspire

Knight
The ShrinkItem's Delete method will call Delete on the linked creature, so that when the ShrinkItem is deleted, it will make sure the link isn't "orphaned", ending up inaccessible and stuck in memory on the Internal facet.

If the ShrinkItem is deleted after the linked creature is un-shrunk, and the ShrinkItem retains the link reference to the creature, it will still delete the creature regardless.

Fortunately, your code sets 'm_pet' to null before deleting, so it's safe - but check other places that might bypass the un-shrink methods.
 
The ShrinkItem's Delete method will call Delete on the linked creature, so that when the ShrinkItem is deleted, it will make sure the link isn't "orphaned", ending up inaccessible and stuck in memory on the Internal facet.

If the ShrinkItem is deleted after the linked creature is un-shrunk, and the ShrinkItem retains the link reference to the creature, it will still delete the creature regardless.

Fortunately, your code sets 'm_pet' to null before deleting, so it's safe - but check other places that might bypass the un-shrink methods.


Sorry - To my challenged scripting that seems a bit like a chicken or egg situation. I just do not see how the statue can delete the pet by itself. Seems it has to be Double Clicked to be able to do anything (no timer involved) and DBL click brings the pet back if the link is valid.

In case I was not saying it right, here is the actual sequence.

When players use the Hitching Post or the Pet Leash they get a statue.
If they simply single click on the statue (not trying to retrieve the pet) the pet's stats are shown.
If they are able to do this and see the stats then all is fine. It means the link is good and the pet can be retrieved.
After a random amount of time has passed some of these statues no longer show the pet's stats. When this happens the pet can no longer be retrieved.

So - the mystery is - what is causing the link to break?

For the code of the 'Shrunken' items is appears the problem is caused by the pet on the internal map being deleted or made null by something I have not discovered.
For the 'Stabled' pets I am assuming (hate that) the same thing is happening but of course we do not have a statue to tell us when it has been done.
 

UOF

Traveler
Having this problem on my shard, as well
I might end up ditching the system and just using a stable stone at this rate.
 
Top