first commit
This commit is contained in:
@@ -0,0 +1,438 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Windows.Input;
|
||||
using ClassicAssist.Misc;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.UI.Models;
|
||||
using ClassicAssist.UO;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Objects;
|
||||
using Microsoft.Scripting.Utils;
|
||||
|
||||
namespace ClassicAssist.UI.ViewModels
|
||||
{
|
||||
public class ObjectInspectorViewModel : BaseViewModel
|
||||
{
|
||||
private ICommand _copyToClipboardCommand;
|
||||
private ObservableCollection<ObjectInspectorData> _items = new ObservableCollection<ObjectInspectorData>();
|
||||
private ObjectInspectorData _selectedItem;
|
||||
|
||||
public ObjectInspectorViewModel()
|
||||
{
|
||||
Items.AddRange( new List<ObjectInspectorData>
|
||||
{
|
||||
new ObjectInspectorData { Name = "Name", Value = "Value", Category = "Category" }
|
||||
} );
|
||||
}
|
||||
|
||||
public ObjectInspectorViewModel( Entity entity )
|
||||
{
|
||||
AddEntityProperties( entity );
|
||||
|
||||
if ( entity is Mobile mobile )
|
||||
{
|
||||
AddMobileProperties( mobile );
|
||||
}
|
||||
|
||||
//AddPublicProperties( entity );
|
||||
}
|
||||
|
||||
public ObjectInspectorViewModel( StaticTile staticTile )
|
||||
{
|
||||
AddStaticProperties( staticTile );
|
||||
}
|
||||
|
||||
public ObjectInspectorViewModel( LandTile landTile )
|
||||
{
|
||||
AddLandProperties( landTile );
|
||||
}
|
||||
|
||||
public ICommand CopyToClipboardCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
return _copyToClipboardCommand ?? ( _copyToClipboardCommand =
|
||||
new RelayCommand( o => CopyToClipboard(), o => _selectedItem != null ) );
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<ObjectInspectorData> Items
|
||||
{
|
||||
get => _items;
|
||||
set => SetProperty( ref _items, value );
|
||||
}
|
||||
|
||||
public ObjectInspectorData SelectedItem
|
||||
{
|
||||
get => _selectedItem;
|
||||
set => SetProperty( ref _selectedItem, value );
|
||||
}
|
||||
|
||||
private void AddLandProperties( LandTile landTile )
|
||||
{
|
||||
AddData( typeof( Entity ), nameof( Entity.Name ), landTile.Name, Strings.Entity );
|
||||
AddData( "Flags", landTile.Flags.ToString(), Strings.Entity );
|
||||
AddData( typeof( Entity ), nameof( Entity.ID ), landTile.ID, Strings.Entity, Strings.Graphic );
|
||||
AddData( "Position", $"{landTile.X}, {landTile.Y}, {landTile.Z}", Strings.Entity );
|
||||
}
|
||||
|
||||
private void AddStaticProperties( StaticTile staticTile )
|
||||
{
|
||||
AddData( typeof( Entity ), nameof( Entity.Name ), staticTile.Name, Strings.Entity );
|
||||
AddData( "Flags", staticTile.Flags.ToString(), Strings.Entity );
|
||||
AddData( typeof( Entity ), nameof( Entity.ID ), staticTile.ID, Strings.Entity, Strings.Graphic );
|
||||
AddData( typeof( Entity ), nameof( Entity.Hue ), staticTile.Hue, Strings.Entity, Strings.Color );
|
||||
AddData( "Position", $"{staticTile.X}, {staticTile.Y}, {staticTile.Z}", Strings.Entity );
|
||||
AddData( "Weight", staticTile.Weight.ToString(), Strings.Entity );
|
||||
AddData( "Height", staticTile.Height.ToString(), Strings.Entity );
|
||||
AddData( "Quality", staticTile.Quality.ToString(), Strings.Entity );
|
||||
AddData( "Quantity", staticTile.Quantity.ToString(), Strings.Entity );
|
||||
}
|
||||
|
||||
private void AddEntityProperties( Entity entity )
|
||||
{
|
||||
AddData( typeof( Entity ), nameof( Entity.Name ), entity.Name, Strings.Entity );
|
||||
AddData( typeof( Entity ), nameof( Entity.Serial ), entity.Serial, Strings.Entity );
|
||||
AddData( typeof( Entity ), nameof( Entity.ID ), entity.ID, Strings.Entity, Strings.Graphic );
|
||||
AddData( typeof( Entity ), nameof( Entity.Hue ), entity.Hue, Strings.Entity, Strings.Color );
|
||||
AddData( "Position", $"{entity.X}, {entity.Y}, {entity.Z}", Strings.Entity );
|
||||
}
|
||||
|
||||
private void AddMobileProperties( Mobile mobile )
|
||||
{
|
||||
AddData( typeof( Mobile ), nameof( Mobile.Name ), mobile.Name, Strings.Mobile );
|
||||
AddData( "Sex", mobile.Status.HasFlag( MobileStatus.Female ) ? "Female" : "Male", Strings.Mobile );
|
||||
|
||||
if ( mobile is PlayerMobile player )
|
||||
{
|
||||
AddData( typeof( Mobile ), nameof( Mobile.Hits ), player.Hits, Strings.Mobile );
|
||||
AddData( typeof( Mobile ), nameof( Mobile.HitsMax ), player.HitsMax, Strings.Mobile, "Max Health" );
|
||||
}
|
||||
else
|
||||
{
|
||||
float health = mobile.Hits;
|
||||
float maxHealth = mobile.HitsMax;
|
||||
float per = health / maxHealth * 100;
|
||||
AddData( "Hits", ( (uint) per ).ToString() + '%', Strings.Mobile );
|
||||
}
|
||||
|
||||
AddData( typeof( Mobile ), nameof( Mobile.Notoriety ), mobile.Notoriety, Strings.Mobile );
|
||||
AddData( typeof( Mobile ), nameof( Mobile.Status ), mobile.Status, Strings.Mobile, "Flags" );
|
||||
|
||||
#region Equipment Properties
|
||||
|
||||
Item[] equipment = GetEquipmentItems( mobile );
|
||||
|
||||
if ( equipment == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AddEquipmentProperty( equipment, new[] { 1060448, 1153735 }, new[] { 0, 0 }, "Physical Resist",
|
||||
Strings.Resistances );
|
||||
AddEquipmentProperty( equipment, new[] { 1060447, 1153737 }, new[] { 0, 0 }, "Fire Resist",
|
||||
Strings.Resistances );
|
||||
AddEquipmentProperty( equipment, new[] { 1060445, 1153739 }, new[] { 0, 0 }, "Cold Resist",
|
||||
Strings.Resistances );
|
||||
AddEquipmentProperty( equipment, new[] { 1060449, 1153736 }, new[] { 0, 0 }, "Poison Resist",
|
||||
Strings.Resistances );
|
||||
AddEquipmentProperty( equipment, new[] { 1060446, 1153738 }, new[] { 0, 0 }, "Energy Resist",
|
||||
Strings.Resistances );
|
||||
|
||||
AddEquipmentProperty( equipment, 1060413, 0, "Faster Casting", Strings.Magical );
|
||||
AddEquipmentProperty( equipment, 1060412, 0, "Faster Cast Recovery", Strings.Magical );
|
||||
AddEquipmentProperty( equipment, 1060434, 0, "Lower Reagent Cost", Strings.Magical );
|
||||
AddEquipmentProperty( equipment, 1060433, 0, "Lower Mana Cost", Strings.Magical );
|
||||
AddEquipmentProperty( equipment, 1060483, 0, "Spell Damage Increase", Strings.Magical );
|
||||
|
||||
AddEquipmentProperty( equipment, 1060408, 0, "Defense Chance Increase", Strings.Combat );
|
||||
AddEquipmentProperty( equipment, 1060415, 0, "Hit Chance Increase", Strings.Combat );
|
||||
AddEquipmentProperty( equipment, 1060401, 0, "Damage Increase", Strings.Combat );
|
||||
AddEquipmentProperty( equipment, 1060402, 0, "Damage Increase", Strings.Combat );
|
||||
AddEquipmentProperty( equipment, 1060486, 0, "Swing Speed Increase", Strings.Combat );
|
||||
|
||||
AddEquipmentProperty( equipment, 1060485, 0, "Strength Bonus", Strings.Stats );
|
||||
AddEquipmentProperty( equipment, 1060432, 0, "Intelligence Bonus", Strings.Stats );
|
||||
AddEquipmentProperty( equipment, 1060409, 0, "Dexterity Bonus", Strings.Stats );
|
||||
|
||||
AddEquipmentProperty( equipment, 1060431, 0, "Hit Point Increase", Strings.Stats );
|
||||
AddEquipmentProperty( equipment, 1060439, 0, "Mana Increase", Strings.Stats );
|
||||
AddEquipmentProperty( equipment, 1060484, 0, "Stamina Increase", Strings.Stats );
|
||||
|
||||
AddEquipmentProperty( equipment, 1060444, 0, "Hit Point Regeneration", Strings.Regeneration );
|
||||
AddEquipmentProperty( equipment, 1060440, 0, "Mana Regeneration", Strings.Regeneration );
|
||||
AddEquipmentProperty( equipment, 1060443, 0, "Stamina Regeneration", Strings.Regeneration );
|
||||
|
||||
AddEquipmentProperty( equipment, 1060436, 0, "Luck", "Misc" );
|
||||
|
||||
AddEquipmentPropertyWithSymbol( equipment, 1153733, 0, 1, "Max Defense Chance Increase",
|
||||
Strings.Buffs___Penalties );
|
||||
AddEquipmentPropertyWithSymbol( equipment, 1153735, 1, 2, "Physical Resist", Strings.Buffs___Penalties );
|
||||
AddEquipmentPropertyWithSymbol( equipment, 1153737, 1, 2, "Fire Resist", Strings.Buffs___Penalties );
|
||||
AddEquipmentPropertyWithSymbol( equipment, 1153739, 1, 2, "Cold Resist", Strings.Buffs___Penalties );
|
||||
AddEquipmentPropertyWithSymbol( equipment, 1153736, 1, 2, "Poison Resist", Strings.Buffs___Penalties );
|
||||
AddEquipmentPropertyWithSymbol( equipment, 1153738, 1, 2, "Energy Resist", Strings.Buffs___Penalties );
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
private static Item[] GetEquipmentItems( Mobile mobile )
|
||||
{
|
||||
List<Item> items = new List<Item>();
|
||||
|
||||
foreach ( Item item in mobile.GetEquippedItems() )
|
||||
{
|
||||
items.Add( item );
|
||||
}
|
||||
|
||||
return items.ToArray();
|
||||
}
|
||||
|
||||
private void AddEquipmentProperty( Item[] items, int cliloc, int argumentIndex, string name, string category )
|
||||
{
|
||||
AddEquipmentProperty( items, new[] { cliloc }, new[] { argumentIndex }, name, category );
|
||||
}
|
||||
|
||||
private void AddEquipmentProperty( Item[] items, IReadOnlyList<int> clilocs, IReadOnlyList<int> argumentIndexs,
|
||||
string name, string category )
|
||||
{
|
||||
int amount = clilocs.Select( ( t, i ) => CountPropertyList( items.ToArray(), t, argumentIndexs[i] ) ).Sum();
|
||||
|
||||
if ( amount > 0 )
|
||||
{
|
||||
AddData( new ObjectInspectorData
|
||||
{
|
||||
Name = name, Value = amount.ToString(), Category = category, IsExpanded = false
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private void AddEquipmentPropertyWithSymbol( Item[] items, int cliloc, int symbolIndex, int argumentIndex,
|
||||
string name, string category )
|
||||
{
|
||||
int amount = CountPropertyListWithSymbol( items.ToArray(), cliloc, symbolIndex, argumentIndex );
|
||||
|
||||
if ( amount != 0 )
|
||||
{
|
||||
AddData( new ObjectInspectorData
|
||||
{
|
||||
Name = name, Value = amount.ToString(), Category = category, IsExpanded = false
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
private static int CountProperty( int serial, int cliloc, int argumentIndex )
|
||||
{
|
||||
Item item = Engine.Items.GetItem( serial );
|
||||
|
||||
Property[] properties = item?.Properties;
|
||||
|
||||
if ( properties == null )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return properties.Where( p => p.Cliloc == cliloc ).Select( p => int.Parse( p.Arguments[argumentIndex] ) )
|
||||
.FirstOrDefault();
|
||||
}
|
||||
|
||||
private static int CountPropertyList( IEnumerable<Item> items, int cliloc, int argumentIndex )
|
||||
{
|
||||
return items.Sum( t => CountProperty( t.Serial, cliloc, argumentIndex ) );
|
||||
}
|
||||
|
||||
private static int CountPropertyListWithSymbol( IReadOnlyList<Item> items, int cliloc, int symbolIndex,
|
||||
int argumentIndex )
|
||||
{
|
||||
int total = 0;
|
||||
|
||||
foreach ( Item t in items )
|
||||
{
|
||||
int count = CountProperty( t.Serial, cliloc, argumentIndex );
|
||||
|
||||
Property[] properties = t.Properties;
|
||||
|
||||
if ( properties == null )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( Property p in properties )
|
||||
{
|
||||
if ( p.Cliloc != cliloc )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
string symbol = p.Arguments[symbolIndex];
|
||||
|
||||
if ( symbol == "-" )
|
||||
{
|
||||
total -= count;
|
||||
}
|
||||
else
|
||||
{
|
||||
total += count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
private static string GetDisplayFormat( Type type, string propertyName, object value )
|
||||
{
|
||||
if ( propertyName == null )
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
|
||||
DisplayFormatAttribute attr = type.GetPropertyAttribute<DisplayFormatAttribute>( propertyName );
|
||||
|
||||
return attr != null ? attr.ToString( value ) : value?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
private void AddData( Type type, string propertyName, object value, string category, string nameOverride = "",
|
||||
Action<object> action = null )
|
||||
{
|
||||
AddData( new ObjectInspectorData
|
||||
{
|
||||
Name = string.IsNullOrEmpty( nameOverride ) ? propertyName : nameOverride,
|
||||
Value = GetDisplayFormat( type, propertyName, value ),
|
||||
Category = category,
|
||||
OnDoubleClick = action
|
||||
} );
|
||||
}
|
||||
|
||||
private void AddData( string name, string value, string category )
|
||||
{
|
||||
AddData( new ObjectInspectorData { Name = name, Value = value, Category = category } );
|
||||
}
|
||||
|
||||
private void AddData( ObjectInspectorData data )
|
||||
{
|
||||
_dispatcher.Invoke( () => { Items.Add( data ); } );
|
||||
}
|
||||
|
||||
private void CopyToClipboard()
|
||||
{
|
||||
try
|
||||
{
|
||||
//TODO
|
||||
//Clipboard.SetData( DataFormats.Text, _selectedItem.Value );
|
||||
}
|
||||
catch ( Exception )
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
private void AddPublicProperties( Entity entity )
|
||||
{
|
||||
List<ObjectInspectorData> data = new List<ObjectInspectorData>();
|
||||
|
||||
IOrderedEnumerable<PropertyInfo> properties = entity.GetType().GetProperties().OrderBy( p => p.Name );
|
||||
|
||||
foreach ( PropertyInfo p in properties )
|
||||
{
|
||||
object value = p.GetValue( entity );
|
||||
string valueString = "null";
|
||||
|
||||
if ( value != null )
|
||||
{
|
||||
valueString = value.ToString();
|
||||
}
|
||||
|
||||
DisplayFormatAttribute attr = entity.GetType().GetPropertyAttribute<DisplayFormatAttribute>( p.Name );
|
||||
|
||||
if ( attr != null )
|
||||
{
|
||||
valueString = attr.ToString( value );
|
||||
}
|
||||
|
||||
data.Add( new ObjectInspectorData
|
||||
{
|
||||
Name = p.Name,
|
||||
Value = valueString,
|
||||
Category = Strings.Public_Properties,
|
||||
IsExpanded = true,
|
||||
OnDoubleClick = GetDoubleClickAction( value )
|
||||
} );
|
||||
}
|
||||
|
||||
Items.AddRange( data );
|
||||
}
|
||||
|
||||
private static Action<object> GetDoubleClickAction( object value )
|
||||
{
|
||||
if ( value == null )
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( value is IObjectInspectorDoubleClick )
|
||||
{
|
||||
return o => ( (IObjectInspectorDoubleClick) value ).OnDoubleClick( o );
|
||||
}
|
||||
|
||||
if ( value is ItemCollection collection )
|
||||
{
|
||||
return o => ShowItemCollection( collection );
|
||||
}
|
||||
|
||||
if ( value is Item item )
|
||||
{
|
||||
return o => InspectObject( item.Serial );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void InspectObject( int serial )
|
||||
{
|
||||
Entity entity;
|
||||
|
||||
if ( UOMath.IsMobile( serial ) )
|
||||
{
|
||||
entity = Engine.Mobiles.GetMobile( serial );
|
||||
}
|
||||
else
|
||||
{
|
||||
entity = Engine.Items.GetItem( serial );
|
||||
}
|
||||
|
||||
if ( entity == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Engine.UIInvoker.Invoke( "ObjectInspectorWindow", null, typeof( ObjectInspectorViewModel ),
|
||||
new object[] { entity } );
|
||||
}
|
||||
|
||||
private static void ShowItemCollection( ItemCollection collection )
|
||||
{
|
||||
if ( collection == null )
|
||||
{
|
||||
}
|
||||
|
||||
//TODO
|
||||
//EntityCollectionViewer window = new EntityCollectionViewer
|
||||
//{
|
||||
// DataContext = new EntityCollectionViewerViewModel( collection ),
|
||||
// Topmost = true
|
||||
//};
|
||||
|
||||
//window.ShowDialog();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IObjectInspectorDoubleClick
|
||||
{
|
||||
void OnDoubleClick( object o );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user