Thoughts on "Storing" Stabled Animals

Want to discuss changes to the UOX3 source code? Got a code-snippet you'd like to post? Anything related to coding/programming goes here!
Post Reply
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Thoughts on "Storing" Stabled Animals

Post by giwo »

Before I begin, note that it is likely whatever method we come up with to store stabled pets will also be used for mounted pets (and thus will be a heavily-used process).

One objective I have for 0.98-3.8 is a good way to handle Stablemasters. This will basically be an entirely new feature to UOX3, and one that could be a big performance hit, if not done properly (even OSI had performance issues with stablemasters).

Currently I am fielding ideas on what the best method of implementing these NPC's would be, focusing on the storage mechanism for stabled pets.

One thought I had was "converting" the stabled pets into items. Using this method we could store them inside the bank layer of the NPC and not have to worry about locating an NPC somewhere on the map. The downside of doing this is, apart from a huge amount of special tags, stabled pets would loose much of their uniqueness. In other words, say you had a system by which tamed pets gained skill as they fought for you, we'd have to make sure to store all of their skills and such on the item.

Another idea I've been tossing around is doing the same thing we do with mounts. Keep the NPC object, move it off the map, and have some way to link it back to the stablemaster. The problem with this is we have to decide on a specific location that would be considered "out of bounds" possibly limiting players who created their own custom maps (even 7000,7000 currently used for mounted pets is not the best implementation).

One final thought I've had is creating a new Object class, likely one that would exist between CBaseObject and CChar. This class would be specially built for NPC's we did not want to exist on the map, and thus any objects of this class would not get added to a mapregion. The upside of this is we can keep any uniqueness we have for the NPC, without placing them somewhere on the map. The downside is it would add another layer of abstraction to the CBaseObject line, and possibly create some confusing code.

These are all very rough ideas, and I have not yet spent much time considering the full ramifications of any of these choices.

Questions, Comments, Suggestions, Flames?
Scott
Grimson
Developer
Posts: 802
Joined: Sat Jun 04, 2005 1:52 am
Location: Germany
Has thanked: 0
Been thanked: 0

Post by Grimson »

The problem with this is we have to decide on a specific location that would be considered "out of bounds" possibly limiting players who created their own custom maps (even 7000,7000 currently used for mounted pets is not the best implementation).
A "save location" tag in maps.dfn could take care of this.

I'm planning for some time now to try and do stablemasters via JS, but I'm not shure if this is going to work.

Edit:
Just a random thought: With the above way we might need to have some type of on/off switch for NPCs, so they don't interact with each other or suffer from other effects.
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

I've also considered making use of the "Overflow" region. This should prevent said NPC's from being sent to anyone that didn't somehow get outside a map boundaries (which are set in maps.dfn).

[EDIT]

As a response to your edit, the benefit of the method I just described is that unless a player did get into that region, they would be "off". The benefit of how UOX3 stops checking NPC's that are not in a region near PC's.
Scott
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

If taking the "move the pets"-approach, what about moving them to a location with negative coordinates? I don't see that ever being used on maps.
-= Ho Eyo He Hum =-
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

That's because our SI16 storage of x and y is a misnomer.

The map can go (currently) from 0 to 65535. While I can't say with certainty (never having done it) I'm relatively sure that the client won't handle anything beyond 65535 (and maybe even smaller than that) and it sends the location packets as two bytes, so it certainly wouldn't be able to communicate properly beyond that. Thus if you put in a -1 it would just wrap to 0xFFFF.
Scott
xir
UOX3 Neophyte
Posts: 47
Joined: Mon Aug 23, 2004 2:59 pm
Has thanked: 0
Been thanked: 0

Post by xir »

Can you not store the pets with the actual player? You can store up to 5 simple pets I think. When you stable one, you could just save it in memory until the player claims it. You would just have to modify the save file to include this though.
giwo
Developer
Posts: 1780
Joined: Fri Jun 18, 2004 4:17 pm
Location: California
Has thanked: 0
Been thanked: 0

Post by giwo »

5 Simple pets, ehh? That sounds like a good number. Could you clarify what you mean when you say simple? Does that referr to what data is stored about the pet?

As for storing them with the character, the problem is that the pets have to be "somewhere" on the map. That is to say, any NPC must have an X and a Y value that places them within a mapregion, or the overflow region (for NPC's outside the map boundaries). Now we can hide them, we can disable them, but they will still be in that area, and to some extent, they will be adding lag. The real question is if that lag happens where the stablemaster is, if it's divided to where each individual player is (imagine 20 players on the screen each with 5 "hidden" stabled pets, that's 100 characters). Or if it is in some arbitrary off-the-map location.
Scott
Maarc
Developer
Posts: 576
Joined: Sat Mar 27, 2004 6:22 am
Location: Fleet, UK
Has thanked: 0
Been thanked: 0
Contact:

Post by Maarc »

You essentially want to try and keep it out of the core critical speed loops, and the best way for that, I'd suspect, is to keep it off map / in the overflow region somehow. Not the prettiest of things to do, especially if they keep ramping up the size of maps. The only other thing I can think of is somehow trying to store if it's forced into overflow, rather than just ising the location for it. But if 7000,7000 doesn't tickle your fancy, there's plenty of room to double it :)

If you do keep the creatures around, the stablemaster becomes a much simpler prospect. They'd just need to keep a list of NPC serials, the rest of the information could be derived from that.

One question I have, not sure, is whether our custom tag saving stuff supports saving arrays? You really do want arrays with all of this, rather than oddball tags if possible. Would simplify a big chunk of the logic, I think. Might need some additional helper API funcs though.

But I'd suggest that the solution with the most flexbility and easiest of implementation is likely to be treating them much the same as we do mounts. Those mechanisms are already in place, and don't misbehave too much I don't think.

Giwo, you know I'm a huge fan of increasing the class hierarchy. But I think that, even if we do that, it doesn't really solve the issue of what to do with the NPCs, unless we do a lot of converting between types, and you might end up at the same point (treating much the same as mounts).
User avatar
Xuri
Site Admin
Posts: 3704
Joined: Mon Jun 02, 2003 9:11 am
Location: Norway
Has thanked: 48 times
Been thanked: 8 times
Contact:

Post by Xuri »

So... I seem to be writing a stablemaster JS-script (v0.9999!) =P

So far, I have the following features:
  • *Stabling a maximum of X pets (definable in script) per player-character
    *Serial of pets saved on player character as custom tags when stabled, tags removed completely when pets are retrieved from stable
    *Pets set to stabled (true), hidden (3), wandertype 0, frozen (true), hungerstatus (false), vulnerable (false) and teleported to 8000, 8000, 0 (location definable in script)
    *Withdrawing X amount of gold (definable in script) from backpack/bank upon stabling
    *Claiming pets using a gump-menu to select from all the pets you have stabled (gump-menu resized depending on max amount of pets that can be stabled, as per defined in the script)
    *Pets not claimed after 7 real world days (definable in script) will have a 8/10 chance of being dead when the owner attempts to pick it up
Highlights:
*The stabled pets aren't removed from the game, so any custom properties unique to the pets won't vanish.
*The stabled pets are moved to a location on the map that will be inactive, since there are never any players nearby.
*The stabled pets are unable to interact with each-other as they are all invulnerable (I teleport them to 8000, 8000, 0 instead of 7000, 7000, 0 as for mounts, to avoid any problems between mounts & stabled pets), and they won't die of hunger since that should be disabled both by the .stabled = true flag and the .hungerstatus = false (if the stabled thing didn't do the trick already!).

I've also modified void CChar::SetStabled( bool newValue ) in cChar.cpp to remove the stabled pets from a player's "petlist" (shows up in status gump) when stabled flag changes to true, and add them back on the list when it changes to false:

Code: Select all

void CChar::SetStabled( bool newValue )
{
	if( IsValidNPC() )
	[color=orange]{[/color]
		mNPC->boolFlags.set( BIT_STABLED, newValue );
		[color=orange]CChar *oldOwner = GetOwnerObj();
		if( ValidateObject( oldOwner ))
		{
			if( newValue == true )
			{
				oldOwner->GetPetList()->Remove( this );
			}
			else if( newValue == false )
			{
				oldOwner->GetPetList()->Add( this );
			}
		}[/color]
	[color=orange]}[/color]
}
I would appreciate it if someone could give me some feedback on this before I throw it into UOX3 for real, and potentially poke some holes in my design and/or implementation... =P

Note #1 Do we have a way of determining (through the JS engine) whether or not an NPC is a summoned NPC or not? I'd like to disallow stabling summoned NPCs, but not sure how.

Note #2: I see Maarc brought up the question (2 1/2 years ago) whether or not the custom tag system supports saving arrays - and I need to ask the same question myself now. Does it? =P
-= Ho Eyo He Hum =-
Maarc
Developer
Posts: 576
Joined: Sat Mar 27, 2004 6:22 am
Location: Fleet, UK
Has thanked: 0
Been thanked: 0
Contact:

Post by Maarc »

Overall, your design seems pretty reasonable to me. Nothing big springs to mind as a possible problem. Our logic to only activate active areas should largely prevent any interactions anyway.
Xuri wrote:Note #1 Do we have a way of determining (through the JS engine) whether or not an NPC is a summoned NPC or not? I'd like to disallow stabling summoned NPCs, but not sure how.
Try the isDispellable property. This should be set for all summoned creatures.
Xuri wrote:Note #2: I see Maarc brought up the question (2 1/2 years ago) whether or not the custom tag system supports saving arrays - and I need to ask the same question myself now. Does it? =P
Having a look here https://developer.mozilla.org/en/Spider ... nce#Arrays shows some functions dealing with arrays on the C side of things. We don't use them :) Clicking further gives me broken links. But it sounds like it may not be too hard. It needs some experimenting but is potentially quite doable.
Mindless Automaton
UOX3 Apprentice
Posts: 189
Joined: Wed May 10, 2006 3:48 am
Has thanked: 0
Been thanked: 1 time
Contact:

Post by Mindless Automaton »

Xuri wrote:
*Pets set to stabled (true), hidden (3), wandertype 0, frozen (true), hungerstatus (false), vulnerable (false) and teleported to 8000, 8000, 0 (location definable in script)
Just to drum up some activity in the forum, let me ask:

Instead of teleporting a pet off into the ether, you make a building, lets call it a 'stable' and make rooms in it called 'stalls'. ;P

I guess this would defeat Giwo's "As a response to your edit, the benefit of the method I just described is that unless a player did get into that region, they would be "off". The benefit of how UOX3 stops checking NPC's that are not in a region near PC's."

So what if you made a new mini-region of just the building, its going to be around a long time and nothing bad will happen there, so we call it a 'stable region'. :o

Then the pets would only be active if a player was in the building?
Also, you could have some fun stuff, like the mad butcher who steals horses and makes meat pies out of them?

Is doing something like this very memory/CPU expensive?

I have no clue really, so feel free to ignore this post.

Thanks!
-Mindless Automaton
Mindless Automaton
Linux - UOX3 - 0.99.5 dev branch
Win10Pro 19042.572 - UOX3 0.99.3a; Razor 1.0.14; Client 7.0.87.11 or 4.0.11c (Patch 0)
Post Reply