View Single Post
Old 05-20-2005, 09:28 PM   #1 (permalink)
uburz
Forum Novice
 
Join Date: Mar 2003
Posts: 304
Default Items Management System

What is this?
This is what I called Groups Handler, a powerful items management system for RunUO. It has been used (and is still in use) in UODreams for more than a year, by admins, GMs and especially questers, and it's now tracking near 100.000 items in about 50 different groups.

Have you ever had the need to keep track of some items, or to prevent decorations to be accidentally deleted by staff members, or to execute commands on a group of items without the risks of committing bad mistakes (ie: global delete where...), or to mass move a group of decoration items, or to search for items without the pain of loading a save locally because you don't even remember their serial? Also, questers will like the ability to track, move and remove temporary decorations and special items with a few mouse clicks. This script can help you doing all this, and more.

You no longer write serials on pieces of paper, you see them in a handy gump.
You no longer need to remember what items (and decorations) you added and where, you just know they are there.

Note 1: this script supports both Italian and English languages.
Note 2: this script supports, without bad consequences, concurrent gump use by more than one GM at a time.
Note 3: this script fully supports RunUO 1.0.0 and RunUO 1.0.1 pre-releases.
New: version 2 supports RunUO 2.0 RC1.
Note 4: all commands done through the gump are logged.

Click Here to see a few images and hints to use the gump.

Italian gump use description here (actually it's a page specifically written for UODreams staff).
You can also download the script here and here (version 2).

What are the main features?
  • Items categorization into different user defined groups
  • Support for secure groups
  • Search for items by type, serial and itemid
  • Easy and graphical property summary panel
  • Options for basic GMs interact with items, like Interface command (move, delete, props, bring...)
  • Ability to perform commands on selected items, including conditions
  • Support for multiple "Contained" commands implementor (ie: to perform a "contained" command for a large amount of containers with just a click)
  • Mass move command (ie: to move many items at a time to a different location, by keeping their relative position
  • World decorations finder
Note: all the operations provided by the gump can be performed regarding the items belong to a group or not (ie: you do not need to categorize a group of items to mass move them).

What does this tool do and how can I use it?
Groups Handler is a tool built up with a series of commands and a gump for groups management and items classification. This way, specifically created items (which perhaps need to be deleted or moved in a near future) can be found with no effort at all. You don't even need to remember which items they were, where you placed them or whom you gave them to. This system also grants very easy decorations management.
Each item can be assigned to a group, and groups can all be easily seen and searched for in the main gump.

Let's talk about the gump. Admins will see a few orange groups: these are intended as protected groups. If you installed scripts correctly, these items will not be visible from the gump to non-Admins. Also, commands like delete, move, set, wipe (this one for Admins too), etcetera, will be prohibited. This ensures a GM or Seer can decorate an area without paying attention for already existing items (ie: default decoration items): a wipe command will not erase these ones (as long as they are categorized into an orange group).

Yellow groups, on the contrary, are public: items here categorized can be viewd by all Councelors and upper (but Counselors cannot edit them nor use advanced gump options).

Admins can, also, change the security level of a group, making it yellow or orange respectively, with the only exception of default groups.

GMs and upper can create new groups, by specifying name and description. If a group name already exists, it won't be added again (only description will be changed). An item can be assinged to one group only, but a group can contain all items you want.

Here the commands list:
  • SetGroup <group name>: adds an item to the specified group (unless the item already belongs to another group). This commands supports implementors Single and Multi.
  • ToggleGroup: opens the main gump listing the item(s) targeted and showing if they belongs to a groups or not. From the gump, you can add items to a group, move them to another group, remove them from their own group, showing properties, etcetera. If you need to find an item with a specific serial, you can type ToggleGroup <serial>. Councelors can only view items list and groups, but cannot perform other actions. The "add/remove" button, adds uncategorized items to the group "(default)" or the one imposed by current filter, or remove items from their own groups if they have one. In this case, the item is only removed from GroupsHandler gump, but NOT deleted. This command supports implementors Single, Contained, Area, Global. It also has an alias: TG.
  • HandleGroups: opens the main gump (like TG), showing all categorized items. This commands has an alias: HG.
  • FindDecorations: this commands find all non movable, not in a house, not in green acres, etc, items in the word, and adds them to the group "orphans". Useful if your staff forgets temporary decorations throughout the world and you wish to find them.
How can I install these scripts?
Unzip the file in your desktop, then copy the "Custom" folder inside your RunUO "Scripts" folder. Those are the main engine files for GroupsHandler.
Then, compare other files with those already present in your RunUO folder, and merge changes. Or, if you did not edit default RunUO scripts, just overwrite them all.
On first run, you will be warned about no groups list found: just ignore the message and press enter key. This is a security feature to prevent accidentally groups list removing while reverting from a previous save. BTW: groups list is saved into RunUO "Saves" folder.

My scripts are heavily customized and I can't overwrite them with your version, and/or I have no time to compare them all. Can you please tell me how and where to apply all changes?
Here they are, all distro scripts changes (at least those I could remember, hope they are all).

- Commands\Decorate.cs, ~line 967 (~986 for version 2), add red line:
Code:
                    if ( FindItem( loc.X, loc.Y, loc.Z, maps[j], item ) )
                    {
                    }
                    else
                    {
                        item.MoveToWorld( loc, maps[j] );
                   GroupsHandler.DecorationGroup.AddItem( item, true );
                        ++count;
 
                        if ( item is BaseDoor )
                        {
- Commands\GenTeleporter, CreateTeleporter method, add red lines:
Code:
using Server.Scripts.Commands; // ignore this line for version 2
...
            public void CreateTeleporter( Point3D pointLocation, Point3D pointDestination, Map mapLocation, Map mapDestination, bool back )
            {
                if ( !FindTeleporter( mapLocation, pointLocation ) )
                {
                    m_Count++;
 
                    Teleporter tel = new Teleporter( pointDestination, mapDestination );
 
                    tel.MoveToWorld( pointLocation, mapLocation );
               GroupsHandler.TelGenGroup.AddItem( tel, true );
                }
 
                if ( back && !FindTeleporter( mapDestination, pointDestination ) )
                {
                    m_Count++;
 
                    Teleporter telBack = new Teleporter( pointLocation, mapLocation );
 
                    telBack.MoveToWorld( pointDestination, mapDestination );
               GroupsHandler.TelGenGroup.AddItem( telBack, true );
                }
            }
- Commands\SignParser.cs, ~line 137, add red line:
Code:
            sign.MoveToWorld( location, map );
       GroupsHandler.SignGenGroup.AddItem( sign, true );
- Commands\Wipe.cs, ~line 92, edit line as shown in red:
Code:
            foreach ( object obj in eable )
            {
                if ( items && (obj is Item) && !((obj is BaseMulti) || (obj is HouseSign)) && !GroupsHandler.InSecureGroup( obj as Item ) )
                    toDelete.Add( obj );
- Misc\DoorGenerator.cs, ~line 480 (~485 for version 2), add red lines:
Code:
using Server.Scripts.Commands; // ignore this line for version 2
...
            BaseDoor door = new DarkWoodDoor( facing );
            door.MoveToWorld( new Point3D( x, y, z ), m_Map );
       GroupsHandler.DoorGenGroup.AddItem( door, true );
 
            ++m_Count;
- Misc\uoamVendors.cs, ~line 341, add red lines:
Code:
using Server.Scripts.Commands; // ignore this line for version 2
...
                sp.MoveToWorld( new Point3D( x, y, z ), map );
           GroupsHandler.UOAMVendorsGroup.AddItem( sp, true );
- Items\Misc\PublicMoongate.cs, ~line 128 (~146 for version 2), add red lines:
Code:
using Server.Scripts.Commands; // ignore this line for version 2
...
                Item item = new PublicMoongate();
 
                item.MoveToWorld( entry.Location, list.Map );
           GroupsHandler.MoonGenGroup.AddItem( item, true );
Add similar lines to other decorationg scripts, if you wish decorating items to be automatically categorized (i.e.: factions generator, gauntlet generator, khaldun generator, solen hives teleporters, etc.).
If you wish to add items to a new custom group, be sure to create the group first in scripts: see notes above for this.

Note: for all the following paths, change "Abstracted" with "Generic" for version 2.

- Commands\Abstracted\Commands\BaseCommand.cs, edit method IsAccessible, and add red lines as follows:
Code:
        public virtual bool UseGroupsSecurity{ get{ return false; } }
 
        public static bool IsAccessible( Mobile from, object obj )
   {
            return IsAccessible( from, obj, false );
        }
 
        public static bool IsAccessible( Mobile from, object obj, BaseCommand command )
        {
            return IsAccessible( from, obj, command != null && command.UseGroupsSecurity );
        }
 
        public static bool IsAccessible( Mobile from, object obj, bool checkSecurity )
        {
            if ( from.AccessLevel >= AccessLevel.Administrator || obj == null )
                return true;
 
            Mobile mob;
 
            if ( obj is Mobile )
                mob = (Mobile)obj;
            else if ( obj is Item )
                mob = ((Item)obj).RootParent as Mobile;
            else
                mob = null;
 
       if ( checkSecurity && obj is Item && !GroupsHandler.IsAccessible( from, obj as Item ) )
                return false;
 
            if ( mob == null || mob == from || from.AccessLevel > mob.AccessLevel )
                return true;
 
            return false;
        }
- Commands\Abstracted\Commands\Commands.cs, add red lines:
Code:
// line 55 (59 for version 2)
       Register( new GroupsHandler.SetGroupCommand() );
            Register( new GroupsHandler.ToggleGroupCommand() );
 
// BringToPackCommand, line 112 (120 for version 2)
   public override bool UseGroupsSecurity{ get{ return true; } }
 
// IncreaseCommand, line 261 (271 for version 2)
   public override bool UseGroupsSecurity{ get{ return true; } }
 
// AliasedSetCommand, line 643 (665 for version 2)
   public override bool UseGroupsSecurity{ get{ return true; } }
 
// SetCommand, line 676 (690 for version 2)
   public override bool UseGroupsSecurity{ get{ return true; } }
 
// DeleteCommand, line 709 (725 for version 2)
   public override bool UseGroupsSecurity{ get{ return true; } }
Add similar lines to all other command you wish to protect.

- Commands\Abstracted\Commands\Interface.cs, add or edit lines in red as follows:
Code:
// line 12 (15 for version 2)
    public class InterfaceCommand : BaseCommand
    {
   public override bool UseGroupsSecurity{ get{ return true; } }
 
// line 128 (229 for version 2)
                        if ( !BaseCommand.IsAccessible( m_From, obj, true ) )
 
// line 209 (318 for version 2)
            else if ( !BaseCommand.IsAccessible( m_From, m_Item, true ) )
 
// line 231 (341 for version 2)
               if ( GroupsHandler.IsAccessible( m_From, m_Item ) )
                    {
                        CommandLogging.WriteLine( m_From, "{0} {1} deleting {2}", m_From.AccessLevel, CommandLogging.Format( m_From ), CommandLogging.Format( m_Item ) );
                        m_Item.Delete();
               }
 
// line 260 (373 for version 2)
                        m_From.SendMessage( "You can not get what you can not see." );
                    }
               else if ( !GroupsHandler.IsAccessible( m_From, m_Item ) )
                    {
                        m_From.SendMessage( "You can not get what you can not access." );
                    }
- Commands\Abstracted\Implementors\AreaCommandImplem entor.cs, line 57, edit as follows:
Code:
                    if ( !BaseCommand.IsAccessible( from, obj, command ) )
- Commands\Abstracted\Implementors\BaseCommandImplem entor.cs, line 41 (43 for version 2), add line:
Code:
            Register( GroupsHandler.CommandImplementor );
- Commands\Abstracted\Implementors\ContainedCommandI mplementor.cs, edit OnTarget method as follows:
Code:
        public void OnTarget( Mobile from, object targeted, object state )
        {
 
       object[] states = (object[])state;
            BaseCommand command = (BaseCommand)states[0];
            string[] args = (string[])states[1];
 
            if ( !BaseCommand.IsAccessible( from, targeted, command ) )
            {
                from.SendMessage( "That is not accessible." );
                return;
            }
 
            if ( command.ObjectTypes == ObjectTypes.Mobiles )
                return; // sanity check
- Commands\Abstracted\Implementors\GlobalCommandImpl ementor.cs, edit lines 36 and 45 as follows:
Code:
                        if ( cond.CheckCondition( item ) && BaseCommand.IsAccessible( from, item, command ) )
...
                        if ( cond.CheckCondition( mob ) && BaseCommand.IsAccessible( from, mob, command ) )
- Commands\Abstracted\Implementors\MultiCommandImple mentor.cs, edit line 31 as follows:
Code:
            if ( !BaseCommand.IsAccessible( from, targeted, command ) )
- Commands\Abstracted\Implementors\SingleCommandImpl ementor.cs, edit OnTarget method as follows:
Code:
        public void OnTarget( Mobile from, object targeted, object state )
        {
       object[] states = (object[])state;
            BaseCommand command = (BaseCommand)states[0];
            string[] args = (string[])states[1];
 
            if ( !BaseCommand.IsAccessible( from, targeted, command ) )
            {
                from.SendMessage( "That is not accessible." );
                return;
            }
 
            switch ( command.ObjectTypes )
            {
For version 2 only:
- Commands\Generic\Implementors\SerialCommandImpleme ntor.cs, line 44:
Code:
     else if ( e.Mobile.AccessLevel < command.AccessLevel )
     {
      e.Mobile.SendMessage( "You do not have access to that command." );
     }
     else if ( !BaseCommand.IsAccessible( e.Mobile, obj, command ) )
     {
      e.Mobile.SendMessage( "That is not accessible." );
     }
    else


I have a custom script which generates items. How can I make my script to automatically add those items to a group, so that I can easily track them in game?
Pretty simple. Locate the line where your script creates the item, then add these lines just after that:
Code:
ItemsGroup g = GroupsHandler.AddGroup( "mygroup", "This is a description", false );
g.AddItem( item, true );
The first line will create the group only if it does not exist. Otherwise, it simply returns the group instance.
The parameters of AddGroup methods are: group name (case unsensitive), group description (case sensitive) and secure flag (true = orange group; false = yellow group).
The parameters of AddItem are: the item just created and the ability to add it in a secure group (keep this always true if the item is added by a script).
That's all ;)

I selected all decorations, then clicked the button "delete marked", but it seems the operation is very slow. Why?
If you delete items that way, each single delete is logged, thus the slowness and the high times required to perform all the deletes. Instead of deleting large amounts of items that way, click on the "Execute commands" button, type "delete" on the command text box, then press the apply button. The log will only show how many items you deleted instead of a full list of all them.

I don't want counselors to be able to see grouped items, even if they cannot edit nothing. How can I do this?
Just change the required accesslevel for HandleGroups command from Counselor to GM.

I don't need all security features, accidental delete prevention for non-admins, etcetera. How can I ignore them?
Just copy only the engine and the gump (folder "Custom\GroupsHandler" into my zip) to the RunUO scripts folder, and ignore all other scripts.
Attached Files
File Type: zip Scripts.zip (58.8 KB, 287 views)
File Type: zip Scripts (version 2).zip (61.6 KB, 93 views)

Last edited by uburz; 06-16-2006 at 01:09 PM.
uburz is offline