first commit
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.Data.Hotkeys;
|
||||
using ClassicAssist.Misc;
|
||||
using ClassicAssist.UO.Network;
|
||||
using ClassicAssist.UO.Objects;
|
||||
using UOC = ClassicAssist.Shared.UO.Commands;
|
||||
|
||||
namespace ClassicAssist.Data.Dress
|
||||
{
|
||||
/*
|
||||
* Future tip to self, this is HotkeyEntry so it doesn't try to add it to hotkey commands
|
||||
*/
|
||||
public class DressAgentEntry : HotkeyEntry
|
||||
{
|
||||
private List<DressAgentItem> _items;
|
||||
private int _undressContainer;
|
||||
|
||||
public List<DressAgentItem> Items
|
||||
{
|
||||
get => _items;
|
||||
set => SetProperty( ref _items, value );
|
||||
}
|
||||
|
||||
public int UndressContainer
|
||||
{
|
||||
get => _undressContainer;
|
||||
set => SetProperty( ref _undressContainer, value );
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
public void AddOrReplaceDressItem( Item item )
|
||||
{
|
||||
List<DressAgentItem> list = Items.ToList();
|
||||
|
||||
DressAgentItem existingItem = Items.FirstOrDefault( i => i.Layer == item.Layer );
|
||||
|
||||
if ( existingItem != null )
|
||||
{
|
||||
list.Remove( existingItem );
|
||||
}
|
||||
|
||||
list.Add( new DressAgentItem
|
||||
{
|
||||
Serial = item.Serial, Layer = item.Layer, Type = DressAgentItemType.Serial, ID = item.ID
|
||||
} );
|
||||
|
||||
Items = list;
|
||||
}
|
||||
|
||||
public async Task Dress( bool moveConflicting = true )
|
||||
{
|
||||
PlayerMobile player = Engine.Player;
|
||||
|
||||
if ( player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int container = DressManager.GetInstance().GetUndressContainer( UndressContainer );
|
||||
|
||||
if ( container == 0 || container == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( DressManager.GetInstance().UseUO3DPackets )
|
||||
{
|
||||
//TODO DressAgentItemType.ID
|
||||
|
||||
if ( moveConflicting )
|
||||
{
|
||||
int[] conflictingLayers = Engine.Player.GetEquippedItems()
|
||||
.Where( i => Items.Any( ii => i.Layer == ii.Layer && i.Serial != ii.Serial ) )
|
||||
.Select( l => (int) l.Layer ).ToArray();
|
||||
|
||||
if ( conflictingLayers.Length > 0 )
|
||||
{
|
||||
UOC.UO3DUnequipItems( conflictingLayers );
|
||||
Thread.Sleep( Options.CurrentOptions.ActionDelayMS );
|
||||
}
|
||||
}
|
||||
|
||||
int[] dressItems = Items.Select( i => i.Serial ).ToArray();
|
||||
|
||||
UOC.UO3DEquipItems( dressItems );
|
||||
}
|
||||
else
|
||||
{
|
||||
await Task.Run( async () =>
|
||||
{
|
||||
foreach ( DressAgentItem dai in Items )
|
||||
{
|
||||
Item item = Engine.Items.GetItem( dai.Serial );
|
||||
|
||||
if ( item == null && dai.Type == DressAgentItemType.Serial )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int currentInLayer = Engine.Player?.GetLayer( dai.Layer ) ?? 0;
|
||||
|
||||
if ( currentInLayer == item?.Serial )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( currentInLayer != 0 && moveConflicting && container != -1 )
|
||||
{
|
||||
await ActionPacketQueue.EnqueueDragDrop( currentInLayer, 1, container,
|
||||
QueuePriority.Medium );
|
||||
|
||||
currentInLayer = 0;
|
||||
}
|
||||
|
||||
if ( currentInLayer != 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ( dai.Type )
|
||||
{
|
||||
case DressAgentItemType.Serial:
|
||||
await UOC.EquipItem( item, dai.Layer );
|
||||
break;
|
||||
case DressAgentItemType.ID:
|
||||
await UOC.EquipType( dai.ID, dai.Layer );
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Undress()
|
||||
{
|
||||
if ( Engine.Player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int container = DressManager.GetInstance().GetUndressContainer( UndressContainer );
|
||||
|
||||
if ( container == 0 || container == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<int> serials = Items.Select( dai => dai.Serial );
|
||||
|
||||
if ( DressManager.GetInstance().UseUO3DPackets )
|
||||
{
|
||||
int[] layers = Engine.Player.GetEquippedItems().Where( i => serials.Contains( i.Serial ) )
|
||||
.Select( i => (int) i.Layer ).ToArray();
|
||||
|
||||
UOC.UO3DUnequipItems( layers );
|
||||
}
|
||||
else
|
||||
{
|
||||
IEnumerable<Item> itemsToUnequip =
|
||||
Engine.Player.GetEquippedItems().Where( i => serials.Contains( i.Serial ) );
|
||||
|
||||
foreach ( Item item in itemsToUnequip )
|
||||
{
|
||||
await ActionPacketQueue.EnqueueDragDrop( item.Serial, 1, container, QueuePriority.Medium );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using ClassicAssist.Annotations;
|
||||
using ClassicAssist.Shared.Resources;
|
||||
using ClassicAssist.UO.Data;
|
||||
|
||||
namespace ClassicAssist.Data.Dress
|
||||
{
|
||||
public class DressAgentItem : INotifyPropertyChanged
|
||||
{
|
||||
private int _id = -1;
|
||||
private Layer _layer;
|
||||
private string _name;
|
||||
private int _serial;
|
||||
private DressAgentItemType _type = DressAgentItemType.Serial;
|
||||
|
||||
public DressAgentItem()
|
||||
{
|
||||
PropertyChanged += ( sender, args ) =>
|
||||
{
|
||||
// Set the name when the Type changes...
|
||||
if ( args.PropertyName == nameof( Type ) )
|
||||
{
|
||||
Name = Type == DressAgentItemType.ID
|
||||
? $"{Layer}: {Strings.Type}: 0x{ID:x4}"
|
||||
: $"{Layer}: 0x{Serial:x8}";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int ID
|
||||
{
|
||||
get => _id;
|
||||
set => SetProperty( ref _id, value );
|
||||
}
|
||||
|
||||
public Layer Layer
|
||||
{
|
||||
get => _layer;
|
||||
set => SetProperty( ref _layer, value );
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get => _name;
|
||||
set => SetProperty( ref _name, value );
|
||||
}
|
||||
|
||||
public int Serial
|
||||
{
|
||||
get => _serial;
|
||||
set => SetProperty( ref _serial, value );
|
||||
}
|
||||
|
||||
public DressAgentItemType Type
|
||||
{
|
||||
get => _type;
|
||||
set => SetProperty( ref _type, value );
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
// ReSharper disable once RedundantAssignment
|
||||
public void SetProperty<T>( ref T field, T value, [CallerMemberName] string propertyName = null )
|
||||
{
|
||||
field = value;
|
||||
OnPropertyChanged( propertyName );
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Name;
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
|
||||
{
|
||||
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#region License
|
||||
|
||||
// Copyright (C) 2020 Reetus
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#endregion
|
||||
|
||||
namespace ClassicAssist.Data.Dress
|
||||
{
|
||||
public enum DressAgentItemType
|
||||
{
|
||||
Serial,
|
||||
ID
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using ClassicAssist.Annotations;
|
||||
using ClassicAssist.Misc;
|
||||
using ClassicAssist.Shared;
|
||||
using ClassicAssist.UI.Misc;
|
||||
using ClassicAssist.UO.Data;
|
||||
using ClassicAssist.UO.Network;
|
||||
using ClassicAssist.UO.Objects;
|
||||
|
||||
namespace ClassicAssist.Data.Dress
|
||||
{
|
||||
public class DressManager : INotifyPropertyChanged
|
||||
{
|
||||
private static DressManager _instance;
|
||||
private static readonly object _instanceLock = new object();
|
||||
|
||||
private readonly Layer[] _validLayers =
|
||||
{
|
||||
Layer.Arms, Layer.Bracelet, Layer.Cloak, Layer.Earrings, Layer.Gloves, Layer.Helm, Layer.InnerLegs,
|
||||
Layer.InnerTorso, Layer.MiddleTorso, Layer.Neck, Layer.OneHanded, Layer.OuterLegs, Layer.OuterTorso,
|
||||
Layer.Pants, Layer.Ring, Layer.Shirt, Layer.Shoes, Layer.Talisman, Layer.TwoHanded, Layer.Waist
|
||||
};
|
||||
|
||||
private ObservableCollectionEx<DressAgentEntry> _items = new ObservableCollectionEx<DressAgentEntry>();
|
||||
private DressAgentEntry _temporaryDress;
|
||||
private bool _useUo3DPackets;
|
||||
|
||||
private DressManager()
|
||||
{
|
||||
Items.CollectionChanged += OnCollectionChanged;
|
||||
}
|
||||
|
||||
public bool IsDressing { get; set; }
|
||||
|
||||
public ObservableCollectionEx<DressAgentEntry> Items
|
||||
{
|
||||
get => _items;
|
||||
set => SetProperty( ref _items, value );
|
||||
}
|
||||
|
||||
public DressAgentEntry TemporaryDress
|
||||
{
|
||||
get => _temporaryDress;
|
||||
set => SetProperty( ref _temporaryDress, value );
|
||||
}
|
||||
|
||||
public bool UseUO3DPackets
|
||||
{
|
||||
get => _useUo3DPackets;
|
||||
set => SetProperty( ref _useUo3DPackets, value );
|
||||
}
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
private void OnCollectionChanged( object sender, NotifyCollectionChangedEventArgs e )
|
||||
{
|
||||
OnPropertyChanged( nameof( Items ) );
|
||||
}
|
||||
|
||||
public static DressManager GetInstance()
|
||||
{
|
||||
// ReSharper disable once InvertIf
|
||||
if ( _instance == null )
|
||||
{
|
||||
lock ( _instanceLock )
|
||||
{
|
||||
if ( _instance == null )
|
||||
{
|
||||
_instance = new DressManager();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return _instance;
|
||||
}
|
||||
|
||||
// ReSharper disable once RedundantAssignment
|
||||
public void SetProperty<T>( ref T obj, T value, [CallerMemberName] string propertyName = "" )
|
||||
{
|
||||
obj = value;
|
||||
OnPropertyChanged( propertyName );
|
||||
}
|
||||
|
||||
[NotifyPropertyChangedInvocator]
|
||||
protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
|
||||
{
|
||||
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
|
||||
}
|
||||
|
||||
public async Task UndressAll( CancellationToken cancellationToken = default )
|
||||
{
|
||||
try
|
||||
{
|
||||
IsDressing = true;
|
||||
|
||||
PlayerMobile player = Engine.Player;
|
||||
|
||||
if ( player == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int backpack = player.Backpack.Serial;
|
||||
|
||||
if ( backpack == 0 || backpack == -1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( _useUo3DPackets )
|
||||
{
|
||||
int[] layers = player.GetEquippedItems().Where( i => IsValidLayer( i.Layer ) )
|
||||
.Select( i => (int) i.Layer ).ToArray();
|
||||
|
||||
Shared.UO.Commands.UO3DUnequipItems( layers );
|
||||
}
|
||||
else
|
||||
{
|
||||
int[] items = player.GetEquippedItems().Where( i => IsValidLayer( i.Layer ) )
|
||||
.Select( i => i.Serial ).ToArray();
|
||||
|
||||
foreach ( int item in items )
|
||||
{
|
||||
if ( cancellationToken.IsCancellationRequested )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await ActionPacketQueue.EnqueueDragDrop( item, 1, backpack, QueuePriority.Medium );
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsDressing = false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsValidLayer( Layer layer )
|
||||
{
|
||||
return _validLayers.Any( l => l == layer );
|
||||
}
|
||||
|
||||
public int GetUndressContainer( int undressContainer )
|
||||
{
|
||||
int container = undressContainer;
|
||||
|
||||
if ( container != 0 && ( Engine.Items.GetItem( container )?.Distance ?? byte.MaxValue ) > 3 ||
|
||||
container == 0 )
|
||||
{
|
||||
container = Engine.Player?.Backpack?.Serial ?? 0;
|
||||
}
|
||||
|
||||
return container;
|
||||
}
|
||||
|
||||
public void ImportItems( DressAgentEntry dae )
|
||||
{
|
||||
PlayerMobile player = Engine.Player;
|
||||
|
||||
List<DressAgentItem> items = player.GetEquippedItems().Where( i => IsValidLayer( i.Layer ) ).Select( i =>
|
||||
new DressAgentItem
|
||||
{
|
||||
Serial = i.Serial, Layer = i.Layer, ID = i.ID, Type = DressAgentItemType.Serial
|
||||
} )
|
||||
.ToList();
|
||||
|
||||
dae.Items = items;
|
||||
}
|
||||
|
||||
public async Task DressAllItems( DressAgentEntry dae, bool moveConflictingItems )
|
||||
{
|
||||
try
|
||||
{
|
||||
IsDressing = true;
|
||||
|
||||
await dae.Dress( moveConflictingItems );
|
||||
}
|
||||
finally
|
||||
{
|
||||
IsDressing = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user