Naviehs

Member
It seems to be a very common feature on most server.
Is it a repo ServUO feature? Or did people edit their item/basearmor/baseweapon (I hope it doesn't consist on adding a ondoubleclick on every equipables :p )
 
Its not standard with ServUO, and as far as the ondoubleclick on every equipables, you aren't far off, minus you would only have to add it to the BaseFiles, and not each item manually.
 
You have to create the double click code then add it to each of your base classes, BaseArmor, BaseWeapon, etc.
It's enough to override the Use( Item item ) method in PlayerMobile for this idea and check the items on the Layer property.
 
Can you give a more detailed example of the script and where to insert it?
Place this code in the PlayerMobile.cs script.
C#:
        public override void Use(Item item)
        {
            base.Use(item);

            if (item.IsChildOf(this.Backpack))
            {
                if (item.Movable && item is ICraftable)
                {
                    if (CanEquipItem(item))
                        EquipItem(item);
                    else
                    {
                        PlaceInBackpack(FindItemOnLayer(item.Layer));
                        EquipItem(item);
                    }
                }
            }
        }

        private bool CanEquipItem(Item item)
        {
            return !Items.Any(i => i.Layer == item.Layer);
        }
 
Place this code in the PlayerMobile.cs script.
C#:
        public override void Use(Item item)
        {
            base.Use(item);

            if (item.IsChildOf(this.Backpack))
            {
                if (item.Movable && item is ICraftable)
                {
                    if (CanEquipItem(item))
                        EquipItem(item);
                    else
                    {
                        PlaceInBackpack(FindItemOnLayer(item.Layer));
                        EquipItem(item);
                    }
                }
            }
        }

        private bool CanEquipItem(Item item)
        {
            return !Items.Any(i => i.Layer == item.Layer);
        }
Thanks, but unfortunately there is a compilation error(
 

Attachments

  • err.jpg
    err.jpg
    74.7 KB · Views: 6
  • PlayerMobile.cs
    205.1 KB · Views: 1
You need to place that a little further along in your code, where it goes further down shouldn't actually matter.. I placed it right above here:
C#:
public override bool AllowItemUse(Item item)
I have tested the code and it does work as expected, I would love for it to work both ways though..
 
You need to place that a little further along in your code, where it goes further down shouldn't actually matter.. I placed it right above here:
C#:
public override bool AllowItemUse(Item item)
I have tested the code and it does work as expected, I would love for it to work both ways though..
And can you be more precise where lower?
Or put it where you want and drop the file)
 
Writes an error, like inserted below that line(
And if above that line, then such an error(
 

Attachments

  • PlayerMobile.cs
    205.2 KB · Views: 1
  • err2.jpg
    err2.jpg
    205.1 KB · Views: 9
  • err3.jpg
    err3.jpg
    208.8 KB · Views: 8
  • PlayerMobile.cs
    205.2 KB · Views: 0
I think and someone correct me if I am wrong, but the version of .NET that server was written in might be a little outdated, I don't know if you can change the version of .NET it's compiled on without breaking a lot of things.. unfortunately this is beyond my expertise and you might have to wait for someone else to reply for further assistance.
 
Never mind it was easier than I thought, just add:
C#:
using System.Linq;
Anywhere to the top of your script with the rest of the "using" statements.
 
Hi guys, thanks for this, I wanted to do the same. It works fine with double click, but I only have one problem. If I am already wearing a weapon and I double click a new one from the backpack it says: "You can only wield one weapon at time" instead of equip the new one and put the previous one directly in the backpack. Do you know how can I change that?
Thank you in advance!
 
Hi guys, thanks for this, I wanted to do the same. It works fine with double click, but I only have one problem. If I am already wearing a weapon and I double click a new one from the backpack it says: "You can only wield one weapon at time" instead of equip the new one and put the previous one directly in the backpack. Do you know how can I change that?
Thank you in advance!
It works with replacing equipped items
 
That's because BaseWeapon needs a specific handling, due to its nature of being more particular: one handed can go only if there is nothing in 1h and nothing or not a weapon in 2h (1h works with shields, that are basearmor in twohanded layer). I'm not on a standard ServUO/RunUO and I don't know which .NET are you using (I'm on NET 7) so I tried to be as verbose and old-styled as possible, then you can prettify and modernise the code according to your necessities.

For example there is CleanHands that could be used, with the correct modifications to handle shields as well, etc. Lot of things can be done to make the code smarter, but I just wrote the most basic to make it work in "almost" any situation.

Anyway the concept is that you need to handle differently both che CanEquipItem check and the equipment itself for weapons, cause they work differently ^^.

Code:
public override void Use(Item item)
{
    base.Use(item);

    if (!item.IsChildOf(Backpack)) return;
    if (!item.Movable || item is not ICraftable) return;
   
    if (CanEquipItem(item))
        EquipItem(item);
    else
    {
        if (item is BaseWeapon wp)
        {
            switch (wp.Layer)
            {
                case Layer.TwoHanded:
                    PlaceInBackpack(FindItemOnLayer(Layer.TwoHanded));
                    PlaceInBackpack(FindItemOnLayer(Layer.OneHanded));
                    EquipItem(item);
                    return;
                case Layer.OneHanded:
                    if (FindItemOnLayer(Layer.TwoHanded) is BaseWeapon thwp) PlaceInBackpack(thwp);
                    PlaceInBackpack(FindItemOnLayer(Layer.OneHanded));
                    EquipItem(item);
                    return;
            }
        }
        else
        {
            PlaceInBackpack(FindItemOnLayer(item.Layer));
            EquipItem(item);
        }
    }
}

private bool CanEquipItem(Item item)
{
    if (!(item is BaseWeapon wp)) return Items.All(i => i.Layer != item.Layer);
    switch (wp.Layer)
    {
        case Layer.TwoHanded:
            return FindItemOnLayer(Layer.OneHanded) == null && FindItemOnLayer(Layer.TwoHanded) == null;
        case Layer.OneHanded:
            return FindItemOnLayer(Layer.OneHanded) == null && (FindItemOnLayer(Layer.TwoHanded) == null ||
            FindItemOnLayer(Layer.TwoHanded) is BaseArmor);
        default:
return Items.All(i => i.Layer != item.Layer);
    }
}
 
That's because BaseWeapon needs a specific handling, due to its nature of being more particular: one handed can go only if there is nothing in 1h and nothing or not a weapon in 2h (1h works with shields, that are basearmor in twohanded layer). I'm not on a standard ServUO/RunUO and I don't know which .NET are you using (I'm on NET 7) so I tried to be as verbose and old-styled as possible, then you can prettify and modernise the code according to your necessities.

For example there is CleanHands that could be used, with the correct modifications to handle shields as well, etc. Lot of things can be done to make the code smarter, but I just wrote the most basic to make it work in "almost" any situation.

Anyway the concept is that you need to handle differently both che CanEquipItem check and the equipment itself for weapons, cause they work differently ^^.

Code:
public override void Use(Item item)
{
    base.Use(item);

    if (!item.IsChildOf(Backpack)) return;
    if (!item.Movable || item is not ICraftable) return;
  
    if (CanEquipItem(item))
        EquipItem(item);
    else
    {
        if (item is BaseWeapon wp)
        {
            switch (wp.Layer)
            {
                case Layer.TwoHanded:
                    PlaceInBackpack(FindItemOnLayer(Layer.TwoHanded));
                    PlaceInBackpack(FindItemOnLayer(Layer.OneHanded));
                    EquipItem(item);
                    return;
                case Layer.OneHanded:
                    if (FindItemOnLayer(Layer.TwoHanded) is BaseWeapon thwp) PlaceInBackpack(thwp);
                    PlaceInBackpack(FindItemOnLayer(Layer.OneHanded));
                    EquipItem(item);
                    return;
            }
        }
        else
        {
            PlaceInBackpack(FindItemOnLayer(item.Layer));
            EquipItem(item);
        }
    }
}

private bool CanEquipItem(Item item)
{
    if (!(item is BaseWeapon wp)) return Items.All(i => i.Layer != item.Layer);
    switch (wp.Layer)
    {
        case Layer.TwoHanded:
            return FindItemOnLayer(Layer.OneHanded) == null && FindItemOnLayer(Layer.TwoHanded) == null;
        case Layer.OneHanded:
            return FindItemOnLayer(Layer.OneHanded) == null && (FindItemOnLayer(Layer.TwoHanded) == null ||
            FindItemOnLayer(Layer.TwoHanded) is BaseArmor);
        default:
return Items.All(i => i.Layer != item.Layer);
    }
}
1708508253034.png
 
Check for a typo on line 2178, you have a ; instead of || (at the end of the line)


Note : This code is causing crashes and will need gone over again by its author.

Using PlaceInBackpack with a null item is causing the crash.
 
Last edited:
Yep sorry, "is not" is not supported in your .NET platform, so as Fraz said was the fix.

Also agree with him that you should check the function of PlaceInBackpack, cause for example in my server it has a nullcheck to prevent crashes, but I'm not sure if in your ServUO it's handled or not. If it's not, you've two options: add a way to handle it in the method, or add more null checks before calling it in OnBeforeDeath.
 

Active Shards

Donations

Total amount
$0.00
Goal
$1,000.00
Back