Hi,
I'm using RunUO 2.4 but this seems to use the same script throughout flavours of UO servers.

When demolishing a house, only the first key (the front door key) is deleted. I've searched for help on this but the only solution I found does not seem to work for me. The one key is deleted from pack and bank but any others remain. It looked to me as if the remove instruction was outside the for loop but moving it makes no difference. I then figured that the wrong removal method was being used (the keyring one) but obviously that one would be needed or keys would not be removed from keyrings.

Does anyone have a working solution for this? Or can you point me in the right direction?

The second problem is that in houses.cs only the front door is actually keyed. There seem to be only two options for creating doors; you can either select the direction they open or you can give them a keyValue which creates a locked door. You can't have both. Now that in itself is not so much of a problem, because it is a house and you want all the doors keyed really, but like the two free shards I have played and also OSI, the internal doors have different keys, iron I think, or rusty. In RunUO they are ALL made of gold, assuming you chose to key other doors. I also want to be able to name each key on creation so the main door is called for example "a tower key" and the internal door keys are called "first floor key", "second floor key" or whatever name you choose in houses.cs - that looks pretty straight forward.
I don't want to embark on this until I get the key removal thing working but I have an idea to create a property for doors so that when you create a house from deed you can give the door the property "KeyType" for the key of either gold, iron, rusty or if you wished copper. The benefit of this comes when you change the locks or change the house from public to private. Each door will "know" what type of key it should have so that the CreateKeys method can determine what type of key to create.

So my second question is: Am I approaching that in the right way, or does someone have a better suggestion/solution for selecting different key types for different doors?

Thanks!

FB
 
Keys getting removed is not a big deal. Keys are removed by KeyValue from the demolisher's backpack or bank (it will even strip it off a keyring). If you want to fix this so that ALL keys with that KeyValue are deleted when the house is demolished, you will need to rewrite keys so that they are put into a Dictionary on creation

Code:
Dictionary<uint, List<Key>> AllKeys;
(public/private, however you decide to do it)

You'd also need to alter the methods of creating and removing keys in Key.cs to insert and removing themselves from these dictionaries, as well as update keyring to find keys in the same manner. It's such a non issue having keys that don't unlock anything that it's probably a waste of time though. The leftover keys will just be useless and no doubt trashed anyway.

Edit: On second thought, an easier solution would probably be to serialize these keys in a list inside the BaseHouse, then just delete all the keys in the list when we rekey or redeed.

The second problem is a bit more complicated and largely to do with the fact that RunUO/ServUO offer extremely secure housing with no default options for insecure housing (anything prior to UO:R). It seems it was never a concern in the development that these internal doors should have different key values.

The problem consists of multiple parts.

In Houses.cs, the first problem is that doors are being created without key values. That's easy to fix, just look for the AddSouthDoor methods (and other doors) in BaseHouse.cs that support the addition of a KeyValue, and if a relevant one doesn't exist, create it - just use the same template it's already using and add a keyvalue to it. You can even choose the itemID of the key, which was your other problem. Voila, you have keys for all your doors.

However, the problem doesn't stop there and gets a bit more complicated. m_Doors is an ArrayList (so you can tell this code is old) of all the house doors, and we know the KeyValue to these doors, so we can potentially find the key which opens it. But the key might also be deleted, which means we've lost all reference of what ItemID that key should be (assuming silver/gold keys have their own itemids). Without starting to make significant edits to Houses.cs and BaseHouse.cs, a way to get around this could be to create a dictionary (instead of an ArrayList) which tells us the ItemID of the key of each door. This would also need to be serialized (in place of the current m_Doors ArrayList), so we never lose track of the ItemIDs.

I don't have time to go through the rest of it right now (I did write up another 50 lines, but deleted them), but I will update this later if you don't have a solution by then.
 
Last edited:
Hello Jack! How is your shard coming along? I'm David :)

Looking at the key removal code it seems to roll through the doors array from which the appropriate keys should get deleted from the user's pack and bankbox by calling Key.RemoveKeys(). Is that not what I am seeing here?

Code:
public void RemoveKeys( Mobile m )
{
	if ( m_Doors != null && m_Doors.Count >= 1 )
	{
		uint keyValue = 0;
		for ( int i = 0; keyValue == 0 && i < m_Doors.Count; ++i )
		{
			BaseDoor door = m_Doors[i] as BaseDoor;
			if ( door != null )
			{
				keyValue = door.KeyValue;
				Key.RemoveKeys( m, keyValue );
			}
// Key.RemoveKeys( m, keyValue );
		}
	}
}

You can see where I moved the RemoveKeys() up into the doors != null condition

I am assuming that the doors are loaded into the array by this point, but perhaps not.
Do you know where that happens? It is behaving as if the array consists of just one element; the front door.

Thanks for your help.

David

Edit: I should have added to this that if you change the locks, all the locks are changed and the doors are locked - even doors which were not keyed before - but all doors have the same lock. That's not an issue at this point as it is simple enough to generate a new key code within the loop. So that bit of the code works which implies that it does have all the doors in your house loaded into the array here.
 
Last edited:
I have fixed the key removal issue.

Looking at the ChangeLocks function, which works, I switched around the RemoveKeys() function accordingly. So remove the code shown above (from BaseHouse.cs) and replace it with this:

Code:
public void RemoveKeys( Mobile m )
{
	if ( m_Doors != null && m_Doors.Count >= 1 )
 	{
  		for ( int i = 0; i < m_Doors.Count; ++i )
  		{
 			BaseDoor door = m_Doors[i] as BaseDoor;

			if (door != null)
  			{
   				Key.RemoveKeys( m, door.KeyValue);
  			}
 		}
 	}
}

So now that is out of the way I am not so worried about adding lots of internal door keys for towers and castles etc. that have multiple doors which should be lockable with separate keys.

Am I being sensible in adding the "KeyType" property to each door on creation in houses.cs? Or is that keyType? LoL - this C# is a blast :) Does this sound like the right way to do it? I guess I will have to change CreateKeys() a bit to accommodate that but it makes life so much easier.

I think I need to add a CommandProperty in BaseDoors.cs for KeyType based on the available options but when I try that with the definitions in Keys.cs
Code:
 public enum KeyType
 {
 Copper = 0x100E,
 Gold  = 0x100F,
 Iron  = 0x1010,
 Rusty  = 0x1013
 }

It throws an error on variable type if I use enum but is OK with string. Am I supposed to just go door.KeyType = KeyType.Gold when I create the door?

Thanks for any help

As you probably guessed I am an old school programmer not used to modern languages so C# does appear very confusing to me but the more I get into it the more amazed I am.
 
It's going good thanks!

That for loop will stop running as soon as keyValue is not 0, which will happen on the first iteration of the loop since keyValue becomes the value of the front door.

Code:
public void RemoveKeys( Mobile m )
{
   if ( m_Doors != null && m_Doors.Count >= 1 )
   {
       uint keyValue = 0;
       for ( int i = 0; i < m_Doors.Count; ++i )
       {
            BaseDoor door = m_Doors[i] as BaseDoor;
           if ( door != null )
           {
                keyValue = door.KeyValue;
                Key.RemoveKeys( m, keyValue );
           }
       }
   }
}

Try using this altered for loop and see if it deletes all the generated keys.
 
Cool, let me know if you get the rest sorted out. I didn't know there was an enum for the key item ids, yes that's sensible to use.
 
Back