/Scripts/Gumps/AProperties/APropsGump.cs
C# | 1130 lines | 939 code | 181 blank | 10 comment | 390 complexity | e86a8e8b4d447f10bcb3e83c6de24196 MD5 | raw file
- using System;
- using System.Reflection;
- using System.Collections;
- using Server;
- using Server.Network;
- using Server.Menus;
- using Server.Menus.Questions;
- using Server.Targeting;
- using CPA = Server.CommandPropertyAttribute;
- using Server.GenericCommands;
- using System.Linq;
- using System.Collections.Generic;
- using Server.Scripts.Commands;
- using Server.Scripts.Gumps;
- using Server.Guilds;
- using Server.Engines.Craft;
- using Server.Engines;
- namespace Server.Gumps
- {
- public class APropertiesGump : Gump
- {
- private ArrayList m_List;
- private int m_Page;
- private Mobile m_Mobile;
- private object m_Object;
- private Stack m_Stack;
- public static readonly bool OldStyle = PropsConfig.OldStyle;
- public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
- public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
- public static readonly int TextHue = PropsConfig.TextHue;
- public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
- public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
- public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
- public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
- public static readonly int BackGumpID = PropsConfig.BackGumpID;
- public static readonly int SetGumpID = PropsConfig.SetGumpID;
- public static readonly int SetWidth = PropsConfig.SetWidth;
- public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
- public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
- public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
- public static readonly int PrevWidth = PropsConfig.PrevWidth;
- public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
- public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
- public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
- public static readonly int NextWidth = PropsConfig.NextWidth;
- public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
- public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
- public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
- public static readonly int OffsetSize = PropsConfig.OffsetSize;
- public static readonly int EntryHeight = PropsConfig.EntryHeight;
- public static readonly int BorderSize = PropsConfig.BorderSize;
- private static bool PrevLabel = OldStyle, NextLabel = OldStyle;
- private static readonly int PrevLabelOffsetX = PrevWidth + 1;
- private static readonly int PrevLabelOffsetY = 0;
- private static readonly int NextLabelOffsetX = -29;
- private static readonly int NextLabelOffsetY = 0;
- private static readonly int NameWidth = 120; // 107;
- private static readonly int ValueWidth = 200; //190; //170;//128;
- private static readonly int EntryCount = 20;
- private static readonly int TypeWidth = NameWidth + OffsetSize + ValueWidth;
- private static readonly int TotalWidth = OffsetSize + NameWidth + OffsetSize + ValueWidth + OffsetSize + SetWidth + OffsetSize;
- private static readonly int TotalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (EntryCount + 1));
- private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
- private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
- public class StackEntry
- {
- public object m_Object;
- public PropertyInfo m_Property;
- public bool m_IsList = false;
- public StackEntry(object obj, PropertyInfo prop)
- {
- m_Object = obj;
- m_Property = prop;
- }
- public StackEntry(object obj, PropertyInfo prop, bool isList)
- {
- m_Object = obj;
- m_Property = prop;
- m_IsList = isList;
- }
- }
- public APropertiesGump( Mobile mobile, object o ) : base( GumpOffsetX, GumpOffsetY )
- {
- m_Mobile = mobile;
- m_Object = o;
- m_List = BuildList();
- Initialize( 0 );
- }
- public APropertiesGump( Mobile mobile, object o, Stack stack, APropertiesGump.StackEntry parent ) : base( GumpOffsetX, GumpOffsetY )
- {
- m_Mobile = mobile;
- m_Object = o;
- m_Stack = stack;
- m_List = BuildList();
- if ( parent != null )
- {
- if ( m_Stack == null )
- m_Stack = new Stack();
- m_Stack.Push( parent );
- }
- Initialize( 0 );
- }
- public APropertiesGump( Mobile mobile, object o, Stack stack, ArrayList list, int page ) : base( GumpOffsetX, GumpOffsetY )
- {
- m_Mobile = mobile;
- m_Object = o;
- m_List = list;
- m_Stack = stack;
- Initialize( page );
- }
- private void Initialize( int page )
- {
- m_Page = page;
- int textEntryCounter = 0;
- int count = m_List.Count - (page * EntryCount);
- if ( count < 0 )
- count = 0;
- else if ( count > EntryCount )
- count = EntryCount;
- int lastIndex = (page * EntryCount) + count - 1;
- if ( lastIndex >= 0 && lastIndex < m_List.Count && m_List[lastIndex] == null )
- --count;
- int totalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (count + 1));
- AddPage( 0 );
- AddBackground( 0, 0, BackWidth, BorderSize + totalHeight + BorderSize, BackGumpID );
- AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), totalHeight, OffsetGumpID );
- int x = BorderSize + OffsetSize;
- int y = BorderSize + OffsetSize;
- int emptyWidth = TotalWidth - PrevWidth - NextWidth - (OffsetSize * 4) - (OldStyle ? SetWidth + OffsetSize : 0);
- if ( OldStyle )
- AddImageTiled( x, y, TotalWidth - (OffsetSize * 3) - SetWidth, EntryHeight, HeaderGumpID );
- else
- AddImageTiled( x, y, PrevWidth, EntryHeight, HeaderGumpID );
- if ( page > 0 )
- {
- AddButton( x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 1, GumpButtonType.Reply, 0 );
- if ( PrevLabel )
- AddLabel( x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous" );
- }
- x += PrevWidth + OffsetSize;
- if ( !OldStyle )
- AddImageTiled( x - (OldStyle ? OffsetSize : 0), y, emptyWidth + (OldStyle ? OffsetSize * 2 : 0), EntryHeight, HeaderGumpID );
- x += emptyWidth + OffsetSize;
- if ( !OldStyle )
- AddImageTiled( x, y, NextWidth, EntryHeight, HeaderGumpID );
- if ( (page + 1) * EntryCount < m_List.Count )
- {
- AddButton( x + NextOffsetX, y + NextOffsetY, NextButtonID1, NextButtonID2, 2, GumpButtonType.Reply, 1 );
- if ( NextLabel )
- AddLabel( x + NextLabelOffsetX, y + NextLabelOffsetY, TextHue, "Next" );
- }
- for ( int i = 0, index = page * EntryCount; i < count && index < m_List.Count; ++i, ++index )
- {
- x = BorderSize + OffsetSize;
- y += EntryHeight + OffsetSize;
- object o = m_List[index];
- if ( o == null )
- {
- AddImageTiled( x - OffsetSize, y, TotalWidth, EntryHeight, BackGumpID + 4 );
- }
- else if (o is ListItemInfo)
- {
- var prop = (ListItemInfo)o;
- var propValue = prop.Object;
- var type = propValue.GetType();
- Type templateFor = Properties.GetTemplate(type);
- bool templateMismatch = CheckTemplateMismatch(templateFor);
- AddImageTiled(x, y, NameWidth, EntryHeight, EntryGumpID);
- AddLabelCropped(x + TextOffsetX, y, NameWidth - TextOffsetX - 19, EntryHeight, TextHue, type.GetDescriptedName());
- x += NameWidth + OffsetSize;
- AddImageTiled(x, y, ValueWidth, EntryHeight, EntryGumpID);
- if (templateMismatch)
- {
- AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, 140, "-impossible-");
- AddImageTiled(x + ValueWidth + OffsetSize, y, SetWidth, EntryHeight, SetGumpID);
- }
- else
- {
- AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, TextHue, ValueToString(propValue));
- x += ValueWidth + OffsetSize;
- if (SetGumpID != 0)
- AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID);
- AddButton(x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 3, GumpButtonType.Reply, 0);
- }
-
- }
- else if (o is CustomGroupInfo)
- {
- CustomGroupInfo type = (CustomGroupInfo)o;
- AddImageTiled(x, y, TypeWidth, EntryHeight, EntryGumpID);
- AddLabelCropped(x + TextOffsetX, y, TypeWidth - TextOffsetX, EntryHeight, type.TextHue, type.GroupName);
- x += TypeWidth + OffsetSize;
- if (SetGumpID != 0)
- AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID);
- }
- else if (o is Type)
- {
- Type type = (Type)o;
- AddImageTiled(x, y, TypeWidth, EntryHeight, EntryGumpID);
- AddLabelCropped(x + TextOffsetX, y, TypeWidth - TextOffsetX, EntryHeight, TextHue, type.GetDescriptedName());
- x += TypeWidth + OffsetSize;
- if (SetGumpID != 0)
- AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID);
- }
- else if (o is PropertyInfo)
- {
- PropertyInfo prop = (PropertyInfo)o;
- Type type = prop.PropertyType;
- CPA cpa = Properties.GetCPA(prop);
- Type templateFor = Properties.GetTemplate(prop);
- bool isTemplate = templateFor != null;
- bool noSetIfNull = Properties.GetNSIF(prop);
- bool templateMismatch = CheckTemplateMismatch(templateFor);
- var propValue = prop.GetValue(m_Object, null);
-
- AddImageTiled(x, y, NameWidth, EntryHeight, EntryGumpID);
- AddLabelCropped(x + TextOffsetX, y, NameWidth - TextOffsetX - 19, EntryHeight, TextHue, prop.GetDescriptedName());
- x += NameWidth + OffsetSize;
- AddImageTiled(x, y, ValueWidth, EntryHeight, EntryGumpID);
- if (templateMismatch)
- {
- AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, 140, "-impossible-");
- }
- else if (IsType(type, typeofBool))
- {
- var value = (bool)prop.GetValue(m_Object, null);
- AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, value ? 175 : 140, value ? "Oui" : "Non");
- }
- else if (IsType(type, typeofString) && prop.CanWrite && cpa != null && m_Mobile.AccessLevel >= cpa.WriteLevel)
- {
- var value = prop.GetValue(m_Object, null);
- AddTextEntry(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, TextHue, textEntryCounter, value == null ? "" : ValueToString(prop));
- if (!TextAreas.ContainsKey(index))
- TextAreas.Add(index, textEntryCounter);
- textEntryCounter++;
- }
- else
- {
- AddLabelCropped(x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, TextHue, ValueToString(prop));
- }
- x += ValueWidth + OffsetSize;
- if (SetGumpID != 0)
- AddImageTiled(x, y, SetWidth, EntryHeight, SetGumpID);
- if (prop.CanWrite && cpa != null && m_Mobile.AccessLevel >= cpa.WriteLevel && !templateMismatch && !(propValue == null && noSetIfNull))
- {
- if (prop.IsNullable() ||
- prop.PropertyType.IsNullable() ||
- IsType(prop.PropertyType, typeofMobile) ||
- IsType(prop.PropertyType, typeofItem) ||
- IsType(prop.PropertyType, typeofString))
- {
- AddButton(x - ValueWidth - 19, y + SetOffsetY, 4034, 4035, 5000 + i + 3, GumpButtonType.Reply, 0);
- }
- int actionID1 = 5538;
- int actionID2 = 5539;
- if (IsType(type, typeof(PropertyAction)) || IsType(type, typeofString))
- {
- AddButton(x + SetOffsetX - 3, y + SetOffsetY - 2, actionID1, actionID2, i + 3, GumpButtonType.Reply, 0);
- }
- else if (IsType(type, typeofBool))
- {
- var value = (bool)prop.GetValue(m_Object, null);
- AddButton(x + SetOffsetX - 2, y + SetOffsetY - 2, value ? actionID2 : actionID1, value ? actionID1 : actionID2, i + 3, GumpButtonType.Reply, 0);
- }
- else
- {
- AddButton(x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 3, GumpButtonType.Reply, 0);
- }
- }
- // Type manager links
- if (propValue != null)
- {
- var propValueType = propValue.GetType();
- if (m_Mobile.AccessLevel >= AccessLevel.GameMaster &&
- (
- (IsType(propValueType, typeofItem) && ManagerConfig.Items.ContainsKey(propValueType)) ||
- (IsType(propValueType, typeofMobile) && ManagerConfig.Creatures.ContainsKey(propValueType))
- ))
- {
- AddButton(1, y + SetOffsetY + 2, 2435, 2436, 10000 + i + 3, GumpButtonType.Reply, 0);
- }
- }
- }
-
- }
- }
- private bool CheckTemplateMismatch(Type templateFor)
- {
- bool isTemplate = templateFor != null;
- bool templateMismatch = false;
- if (!isTemplate) return false;
- if (isTemplate && IsType(m_Object.GetType(), typeof(GameItemType)))
- {
- var itemType = (m_Object as GameItemType);
- templateMismatch = !IsType(itemType.Type, templateFor);
- }
- else if (isTemplate && IsType(m_Object.GetType(), typeof(CreatureType)))
- {
- var mobileType = (m_Object as CreatureType);
- templateMismatch = !IsType(mobileType.Type, templateFor);
- }
- return templateMismatch;
- }
- private Dictionary<int, int> TextAreas = new Dictionary<int, int>();
- public static string[] m_BoolNames = new string[]{ "Vrai", "Faux" };
- public static object[] m_BoolValues = new object[]{ true, false };
- public static string[] m_PoisonNames = new string[]{ "None", "Lesser", "Regular", "Greater", "Deadly", "Lethal" };
- public static object[] m_PoisonValues = new object[]{ null, Poison.Lesser, Poison.Regular, Poison.Greater, Poison.Deadly, Poison.Lethal };
- public override void OnResponse( NetState state, RelayInfo info )
- {
- Mobile from = state.Mobile;
- if ( !Server.GenericCommands.BaseCommand.IsAccessible( from, m_Object ) )
- {
- from.SendMessage( "You may no longer access their properties." );
- return;
- }
- switch ( info.ButtonID )
- {
- case 0: // Closed
- {
- if ( m_Stack != null && m_Stack.Count > 0 )
- {
- APropertiesGump.StackEntry entry = (APropertiesGump.StackEntry)m_Stack.Pop();
- var entryType = entry.m_Object.GetType();
- if (entryType == typeof(LootPacksList) || entryType == typeof(TradesList) || entryType == typeof(CraftSystemsList))
- return;
-
- if(!entry.m_IsList)
- from.SendGump(new APropertiesGump(from, entry.m_Object, m_Stack, null));
-
- }
- break;
- }
- case 1: // Previous
- {
- if ( m_Page > 0 )
- from.SendGump( new APropertiesGump( from, m_Object, m_Stack, m_List, m_Page - 1 ) );
- break;
- }
- case 2: // Next
- {
- if ( (m_Page + 1) * EntryCount < m_List.Count )
- from.SendGump( new APropertiesGump( from, m_Object, m_Stack, m_List, m_Page + 1 ) );
- break;
- }
- default:
- {
- int index = (m_Page * EntryCount) + (info.ButtonID - 3);
- if(index >= 10000)
- {
- // Type links
- index -= 10000;
- var prop = m_List[index] as PropertyInfo;
-
- //from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- var value = prop.GetValue(m_Object, null);
- if (value != null)
- {
- var type = value.GetType();
- if (IsType(type, typeofItem) && ManagerConfig.Items.ContainsKey(type))
- {
- from.SendGump(new APropertiesGump(from, ManagerConfig.Items[type], m_Stack, new StackEntry(m_Object, prop)));
- }
- else if (IsType(type, typeofMobile) && ManagerConfig.Creatures.ContainsKey(type))
- {
- from.SendGump(new APropertiesGump(from, ManagerConfig.Creatures[type], m_Stack, new StackEntry(m_Object, prop)));
- }
- }
- }
- else if (index >= 5000)
- {
- // Nullable
- index -= 5000;
- var prop = m_List[index] as PropertyInfo;
- try
- {
- prop.SetValue(m_Object, null, null);
- APropertiesGump.OnValueChanged(m_Object, prop, m_Stack, -1);
- }
- catch { }
- from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- }
- else if (index >= 0 && index < m_List.Count)
- {
- if (m_List[index] is ListItemInfo)
- {
- var prop = m_List[index] as ListItemInfo;
- if (prop == null)
- return;
- from.SendGump(new APropertiesGump(from, prop.Object, m_Stack, new StackEntry(m_Object, prop.List) ));
- }
- else
- {
- var prop = m_List[index] as PropertyInfo;
- if (prop == null)
- return;
- CPA attr = Properties.GetCPA(prop);
- if (!prop.CanWrite || attr == null || from.AccessLevel < attr.WriteLevel)
- return;
- Type type = prop.PropertyType;
- if (IsType(type, typeofMobile) || IsType(type, typeofItem))
- from.SendGump(new ASetObjectGump(prop, from, m_Object, m_Stack, type, m_Page, m_List, -1));
- else if (IsType(type, typeofBool))
- {
- try
- {
- prop.SetValue(m_Object, !((bool)prop.GetValue(m_Object, null)), null);
- from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- APropertiesGump.OnValueChanged(m_Object, prop, m_Stack, -1);
- }
- catch { }
- }
- else if (IsType(type, typeofString))
- {
- if (TextAreas.ContainsKey(index))
- {
- var entry = info.GetTextEntry(TextAreas[index]);
- prop.SetValue(m_Object, entry.Text, null);
- APropertiesGump.OnValueChanged(m_Object, prop, m_Stack, -1);
- }
- from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- }
- else if (IsType(type, typeof(PropertyAction)))
- {
- // Is a action-type property
- from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- var action = new PropertyAction(from);
- prop.SetValue(m_Object, action, null);
- APropertiesGump.OnValueChanged(m_Object, prop, m_Stack, -1);
- }
- else if (IsType(type, typeofType))
- {
- // New via unified search
- //from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- from.SendGump(new CategorizedAddGump(from, prop, m_Object, m_Stack, m_List, m_Page));
- // Original: from object target
- // from.Target = new ASetObjectTarget(prop, from, m_Object, m_Stack, type, m_Page, m_List, -1);
- }
- else if (IsType(type, typeof(WeakChoice<>)) || type.GetInterfaces().Contains(typeof(IWeakChoice)))
- {
- var choice = prop.GetValue(m_Object, null) as IWeakChoice;
- if (choice != null)
- {
- var list = choice.GetChoiceList(m_Object);
- var values = list.Select(item => item.First).ToArray();
- var names = list.Select(item => item.Second).ToArray();
- from.SendGump(new ASetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, names, values, -1));
- }
- }
- else if (IsType(type, typeofPoint3D))
- from.SendGump(new ASetPoint3DGump(prop, from, m_Object, m_Stack, m_Page, m_List, -1));
- else if (IsType(type, typeofPoint2D))
- from.SendGump(new ASetPoint2DGump(prop, from, m_Object, m_Stack, m_Page, m_List, -1));
- else if (IsType(type, typeofTimeSpan))
- from.SendGump(new ASetTimeSpanGump(prop, from, m_Object, m_Stack, m_Page, m_List, -1));
- else if (IsType(type, typeofDateTime))
- from.SendGump(new ASetDateTimeGump(prop, from, m_Object, m_Stack, m_Page, m_List, -1));
- else if (IsCustomEnum(type))
- from.SendGump(new ASetCustomEnumGump(prop, from, m_Object, m_Stack, m_Page, m_List, GetCustomEnumNames(type), -1));
- else if (IsType(type, typeofEnum))
- from.SendGump(new ASetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, Enum.GetNames(type), GetObjects(Enum.GetValues(type)), -1));
- else if (IsType(type, typeofBool))
- from.SendGump(new ASetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, m_BoolNames, m_BoolValues, -1));
- else if (IsType(type, typeofString) || IsType(type, typeofReal) || IsType(type, typeofNumeric))
- from.SendGump(new ASetGump(prop, from, m_Object, m_Stack, m_Page, m_List, -1));
- else if (IsType(type, typeofPoison))
- from.SendGump(new ASetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, m_PoisonNames, m_PoisonValues, -1));
- else if (IsType(type, typeofMap))
- from.SendGump(new ASetListOptionGump(prop, from, m_Object, m_Stack, m_Page, m_List, Map.GetMapNames(), Map.GetMapValues(), -1));
- else if (IsType(type, typeof(List<TradeInfo>)))
- from.SendGump(new ASetListGump<TradeInfo>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<GameCraftCategory>)))
- from.SendGump(new ASetListGump<GameCraftCategory>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<GameLootItem>)))
- from.SendGump(new ASetListGump<GameLootItem>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<GameLootPack>)))
- from.SendGump(new ASetListGump<GameLootPack>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsArrayListOf(m_Object, typeof(Mobile)))
- from.SendGump(new ASetListGump<Mobile>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Mobile>)))
- from.SendGump(new ASetListGump<Mobile>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Item>)))
- from.SendGump(new ASetListGump<Item>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Single>)))
- from.SendGump(new ASetListGump<Single>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Double>)))
- from.SendGump(new ASetListGump<Double>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Byte>)))
- from.SendGump(new ASetListGump<Byte>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Int16>)))
- from.SendGump(new ASetListGump<Int16>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Int32>)))
- from.SendGump(new ASetListGump<Int32>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Int64>)))
- from.SendGump(new ASetListGump<Int64>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<SByte>)))
- from.SendGump(new ASetListGump<SByte>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<String>)))
- from.SendGump(new ASetListGump<String>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Boolean>)))
- from.SendGump(new ASetListGump<Boolean>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Type>)))
- from.SendGump(new ASetListGump<Type>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<TimeSpan>)))
- from.SendGump(new ASetListGump<TimeSpan>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<DateTime>)))
- from.SendGump(new ASetListGump<DateTime>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Point3D>)))
- from.SendGump(new ASetListGump<Point3D>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Point2D>)))
- from.SendGump(new ASetListGump<Point2D>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<GuildType>)))
- from.SendGump(new ASetListGump<GuildType>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Enum>)))
- from.SendGump(new ASetListGump<Enum>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Poison>)))
- from.SendGump(new ASetListGump<Poison>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeof(List<Map>)))
- from.SendGump(new ASetListGump<Map>(prop, from, m_Object, m_Stack, m_Page, m_List));
- else if (IsType(type, typeofSkills) && m_Object is Mobile)
- {
- from.SendGump(new APropertiesGump(from, m_Object, m_Stack, m_List, m_Page));
- from.SendGump(new SkillsGump(from, (Mobile)m_Object));
- }
- else if (HasAttribute(type, typeofPropertyObject, true))
- {
- object o = prop.GetValue(m_Object, null);
- if (o != null)
- from.SendGump(new APropertiesGump(from, o, m_Stack, new APropertiesGump.StackEntry(m_Object, prop)));
- }
- }
- }
- break;
- }
- }
- }
- public static object[] GetObjects( Array a )
- {
- object[] list = new object[a.Length];
- for ( int i = 0; i < list.Length; ++i )
- list[i] = a.GetValue( i );
- return list;
- }
- public static bool IsCustomEnum( Type type )
- {
- return type.IsDefined( typeofCustomEnum, false );
- }
- public static void OnValueChanged( object obj, PropertyInfo prop, Stack stack, int index )
- {
- if ( stack == null || stack.Count == 0 )
- return;
- if ( !prop.PropertyType.IsValueType )
- return;
- APropertiesGump.StackEntry peek = (APropertiesGump.StackEntry)stack.Peek();
- if (peek.m_Property.CanWrite)
- {
- if (index >= 0)
- {
- object[] indexes = new object[] { index };
- peek.m_Property.SetValue(peek.m_Object, obj, indexes);
- }
- else peek.m_Property.SetValue(peek.m_Object, obj, null);
- }
- }
- public static string[] GetCustomEnumNames( Type type )
- {
- object[] attrs = type.GetCustomAttributes( typeofCustomEnum, false );
- if ( attrs.Length == 0 )
- return new string[0];
- CustomEnumAttribute ce = attrs[0] as CustomEnumAttribute;
- if ( ce == null )
- return new string[0];
- return ce.Names;
- }
- public static bool HasAttribute( Type type, Type check, bool inherit )
- {
- object[] objs = type.GetCustomAttributes( check, inherit );
- return ( objs != null && objs.Length > 0 );
- }
- private static bool IsArrayListOf(object obj, Type check)
- {
- if (obj != null && obj is ArrayList && (obj as ArrayList).Count > 0)
- {
- return IsType((obj as ArrayList)[0].GetType(), check);
- }
- return false;
- }
- private static bool IsType( Type type, Type check )
- {
- return type == check || type.IsSubclassOf( check );
- }
- private static bool IsType( Type type, Type[] check )
- {
- for ( int i = 0; i < check.Length; ++i )
- if ( IsType( type, check[i] ) )
- return true;
- return false;
- }
- private static Type typeofMobile = typeof( Mobile );
- private static Type typeofItem = typeof( Item );
- private static Type typeofType = typeof( Type );
- private static Type typeofPoint3D = typeof( Point3D );
- private static Type typeofPoint2D = typeof( Point2D );
- private static Type typeofTimeSpan = typeof( TimeSpan );
- private static Type typeofDateTime = typeof(DateTime);
- private static Type typeofCustomEnum = typeof(CustomEnumAttribute);
- private static Type typeofEnum = typeof( Enum );
- private static Type typeofBool = typeof( Boolean );
- private static Type typeofString = typeof( String );
- private static Type typeofPoison = typeof( Poison );
- private static Type typeofMap = typeof( Map );
- private static Type typeofSkills = typeof( Skills );
- private static Type typeofPropertyObject = typeof( PropertyObjectAttribute );
- private static Type typeofNoSort = typeof( NoSortAttribute );
- private static Type[] typeofReal = new Type[]
- {
- typeof( Single ),
- typeof( Double )
- };
- private static Type[] typeofNumeric = new Type[]
- {
- typeof( Byte ),
- typeof( Int16 ),
- typeof( Int32 ),
- typeof( Int64 ),
- typeof( SByte ),
- typeof( UInt16 ),
- typeof( UInt32 ),
- typeof( UInt64 )
- };
- private string ValueToString( PropertyInfo prop )
- {
- return ValueToString( m_Object, prop );
- }
- public static string ValueToString( object obj, PropertyInfo prop )
- {
- try
- {
- return ValueToString( prop.GetValue( obj, null ) );
- }
- catch ( Exception e )
- {
- return String.Format( "!{0}!", e.GetType() );
- }
- }
- public static string ValueToString( object o )
- {
- if ( o == null )
- {
- return "-null-";
- }
- else if ( o is string )
- {
- return (string)o;
- //return String.Format( "\"{0}\"", (string)o );
- }
- else if ( o is bool )
- {
- return o.ToString();
- }
- else if ( o is char )
- {
- return String.Format( "0x{0:X} '{1}'", (int)(char)o, (char)o );
- }
- else if ( o is Serial )
- {
- Serial s = (Serial)o;
- if ( s.IsValid )
- {
- if ( s.IsItem )
- {
- return String.Format( "(I) 0x{0:X}", s.Value );
- }
- else if ( s.IsMobile )
- {
- return String.Format( "(M) 0x{0:X}", s.Value );
- }
- }
- return String.Format( "(?) 0x{0:X}", s.Value );
- }
- else if ( o is byte || o is sbyte || o is short || o is ushort || o is int || o is uint || o is long || o is ulong )
- {
- return String.Format( "{0} (0x{0:X})", o );
- }
- else if ( o is Mobile )
- {
- return String.Format( "(M) 0x{0:X} \"{1}\"", ((Mobile)o).Serial.Value, ((Mobile)o).Name );
- }
- else if ( o is Item )
- {
- return String.Format( "(I) 0x{0:X}", ((Item)o).Serial.Value );
- }
- else if ( o is Type )
- {
- return ((Type)o).Name;
- }
- else
- {
- return o.ToString();
- }
- }
- private ArrayList BuildList()
- {
- Type type = m_Object.GetType();
- PropertyInfo[] props = type.GetProperties( BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public );
- ArrayList groups = GetGroups( type, props );
- ArrayList list = new ArrayList();
- for ( int i = 0; i < groups.Count; ++i )
- {
- DictionaryEntry de = (DictionaryEntry)groups[i];
- ArrayList groupList = (ArrayList)de.Value;
- if (de.Key is Type && !HasAttribute( (Type)de.Key, typeofNoSort, false ) )
- groupList.Sort( PropertySorter.Instance );
- if ( i != 0 )
- list.Add( null );
- list.Add( de.Key );
- list.AddRange( groupList );
- }
- return list;
- }
- private class ListItemInfo
- {
- public ListItemInfo(PropertyInfo list, object obj)
- {
- List = list;
- Object = obj;
- }
- public PropertyInfo List { get; set; }
- public object Object { get; set; }
- }
- private class CustomGroupInfo
- {
- public CustomGroupInfo(string label, int hue)
- {
- GroupName = label;
- TextHue = hue;
- }
- public string GroupName { get; set; }
- public int TextHue { get; set; }
- }
- private static Type typeofObject = typeof(object);
- private ArrayList GetGroups( Type objectType, PropertyInfo[] props )
- {
- Hashtable groups = new Hashtable();
- bool isNoSort = objectType.GetCustomAttributes(typeof(NoSortAttribute),false).Length != 0;
- CustomGroupInfo cgi = null;
- for ( int i = 0; i < props.Length; ++i )
- {
- PropertyInfo prop = props[i];
- if ( prop.CanRead )
- {
- var attr = Properties.GetCPA( prop );
- var type = prop.DeclaringType;
- var list = cgi != null ? (ArrayList)groups[cgi] : (ArrayList)groups[type];
-
- if (Properties.IsObjectPropertyList(prop))
- {
- var listValue = prop.GetValue(m_Object, null);
- if (listValue is List<IItemTemplate>)
- {
- var l = listValue as List<IItemTemplate>;
- foreach (var item in l)
- list.Add(new ListItemInfo(prop, item));
- }
- }
- else if ( attr != null && m_Mobile.AccessLevel >= attr.ReadLevel )
- {
- while ( true )
- {
- Type baseType = type.BaseType;
- if ( baseType == null || baseType == typeofObject )
- break;
- if ( baseType.GetProperty( prop.Name, prop.PropertyType ) != null )
- type = baseType;
- else
- break;
- }
-
- if (isNoSort)
- {
- var sg = Properties.GetStartGroup(prop);
- if (sg != null)
- {
- cgi = new CustomGroupInfo(sg.GroupName, sg.TextHue);
- groups[cgi] = list = new ArrayList();
- }
- else
- {
- if (list == null)
- groups[type] = list = new ArrayList();
- }
- }
- else
- {
- if (list == null)
- groups[type] = list = new ArrayList();
- }
- list.Add(prop);
-
- }
- }
- }
- ArrayList sorted = new ArrayList( groups );
- sorted.Sort(new GroupComparer(objectType));
- return sorted;
- }
- public static object GetObjectFromString( Type t, string s )
- {
- if ( t == typeof( string ) )
- {
- return s;
- }
- else if ( t == typeof( byte ) || t == typeof( sbyte ) || t == typeof( short ) || t == typeof( ushort ) || t == typeof( int ) || t == typeof( uint ) || t == typeof( long ) || t == typeof( ulong ) )
- {
- if ( s.StartsWith( "0x" ) )
- {
- if ( t == typeof( ulong ) || t == typeof( uint ) || t == typeof( ushort ) || t == typeof( byte ) )
- {
- return Convert.ChangeType( Convert.ToUInt64( s.Substring( 2 ), 16 ), t );
- }
- else
- {
- return Convert.ChangeType( Convert.ToInt64( s.Substring( 2 ), 16 ), t );
- }
- }
- else
- {
- return Convert.ChangeType( s, t );
- }
- }
- else if ( t == typeof( double ) || t == typeof( float ) )
- {
- return Convert.ChangeType( s, t );
- }
- else if ( t.IsDefined( typeof( ParsableAttribute ), false ) )
- {
- MethodInfo parseMethod = t.GetMethod( "Parse", new Type[]{ typeof( string ) } );
- return parseMethod.Invoke( null, new object[]{ s } );
- }
- throw new Exception( "bad" );
- }
- private static string GetStringFromObject( object o )
- {
- if ( o == null )
- {
- return "-null-";
- }
- else if ( o is string )
- {
- return String.Format( "\"{0}\"", (string)o );
- }
- else if ( o is bool )
- {
- return o.ToString();
- }
- else if ( o is char )
- {
- return String.Format( "0x{0:X} '{1}'", (int)(char)o, (char)o );
- }
- else if ( o is Serial )
- {
- Serial s = (Serial)o;
- if ( s.IsValid )
- {
- if ( s.IsItem )
- {
- return String.Format( "(I) 0x{0:X}", s.Value );
- }
- else if ( s.IsMobile )
- {
- return String.Format( "(M) 0x{0:X}", s.Value );
- }
- }
- return String.Format( "(?) 0x{0:X}", s.Value );
- }
- else if ( o is byte || o is sbyte || o is short || o is ushort || o is int || o is uint || o is long || o is ulong )
- {
- return String.Format( "{0} (0x{0:X})", o );
- }
- else if ( o is Mobile )
- {
- return String.Format( "(M) 0x{0:X} \"{1}\"", ((Mobile)o).Serial.Value, ((Mobile)o).Name );
- }
- else if ( o is Item )
- {
- return String.Format( "(I) 0x{0:X}", ((Item)o).Serial.Value );
- }
- else if ( o is Type )
- {
- return ((Type)o).Name;
- }
- else
- {
- return o.ToString();
- }
- }
- private class PropertySorter : IComparer
- {
- public static readonly PropertySorter Instance = new PropertySorter();
- private PropertySorter()
- {
- }
- public int Compare( object x, object y )
- {
- if ( x == null && y == null )
- return 0;
- else if ( x == null )
- return -1;
- else if ( y == null )
- return 1;
- PropertyInfo a = x as PropertyInfo;
- PropertyInfo b = y as PropertyInfo;
- if ( a == null || b == null )
- throw new ArgumentException();
- return a.Name.CompareTo( b.Name );
- }
- }
- private class GroupComparer : IComparer
- {
- private Type m_Start;
- public GroupComparer( Type start )
- {
- m_Start = start;
- }
- private static Type typeofObject = typeof( Object );
- private int GetDistance( Type type )
- {
- Type current = m_Start;
- int dist;
- for ( dist = 0; current != null && current != typeofObject && current != type; ++dist )
- current = current.BaseType;
- return dist;
- }
- public int Compare( object x, object y )
- {
- if ( x == null && y == null )
- return 0;
- else if ( x == null )
- return -1;
- else if ( y == null )
- return 1;
- if ( !(x is DictionaryEntry) || !(y is DictionaryEntry) )
- throw new ArgumentException();
- DictionaryEntry de1 = (DictionaryEntry)x;
- DictionaryEntry de2 = (DictionaryEntry)y;
- if (de2.Key is CustomGroupInfo && de1.Key is CustomGroupInfo)
- return 0;
- if (de1.Key is CustomGroupInfo && de2.Key is Type)
- return 1;
- if (de2.Key is CustomGroupInfo && de1.Key is Type)
- return -1;
- Type a = (Type)de1.Key;
- Type b = (Type)de2.Key;
- return GetDistance( a ).CompareTo( GetDistance( b ) );
- }
- }
- }
- }