first commit

This commit is contained in:
Beyhan Oğur
2026-09-03 04:45:36 +03:00
commit d5f52cc3d3
1038 changed files with 169579 additions and 0 deletions
@@ -0,0 +1,52 @@
using System.Linq;
using ClassicAssist.Shared;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UO.Network.Packets;
using ClassicAssist.UO.Objects;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Bandage Self" )]
public class BandageSelf : HotkeyCommand
{
private const int TIMEOUT = 5000;
private readonly int[] _bandageTypes = { 0xe21 };
public override void Execute()
{
PlayerMobile player = Engine.Player;
if ( player == null )
{
UOC.SystemMessage( Strings.Error__No_Player );
return;
}
Item backpack = player.Backpack;
if ( backpack == null )
{
UOC.SystemMessage( Strings.Error__Cannot_find_player_backpack );
return;
}
Item bandage = backpack.Container?.SelectEntity( i => _bandageTypes.Contains( i.ID ) );
if ( bandage == null )
{
UOC.SystemMessage( Strings.Error__Cannot_find_type );
return;
}
ObjectCommands.UseObject( bandage.Serial );
bool result = UOC.WaitForTarget( TIMEOUT );
if ( result )
{
Engine.SendPacketToServer( new Target( -1, player, true ) );
}
}
}
}
@@ -0,0 +1,36 @@
#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
using ClassicAssist.Shared;
using ClassicAssist.UO.Network.Packets;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Cast Last Spell" )]
public class CastLastSpell : HotkeyCommand
{
public override void Execute()
{
if ( Engine.LastSpellID != 0 )
{
Engine.SendPacketToServer( new CastSpell( Engine.LastSpellID ) );
}
}
}
}
@@ -0,0 +1,13 @@
using ClassicAssist.UO.Network;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Clear Object Queue" )]
public class ClearObjectQueue : HotkeyCommand
{
public override void Execute()
{
ActionPacketQueue.Clear();
}
}
}
@@ -0,0 +1,150 @@
using ClassicAssist.Shared;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.UO.Data;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Category = "Consume", Name = "Cure Potion" )]
public class UseCurePotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf07, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Heal Potion" )]
public class UseHealPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf0c, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Refresh Potion" )]
public class UseRefreshPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf0b, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Strength Potion" )]
public class UseStrengthPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf09, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Agility Potion" )]
public class UseAgilityPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf08, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Explosion Potion" )]
public class UseExplosionPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf0d, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Invisibility Potion" )]
public class UseInvisibilityPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf06, 306, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Confusion Blast Potion" )]
public class UseConfusionBlastPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf06, 1165, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Conflagration Potion" )]
public class UseConflagPotion : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0xf06, 1161, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Smoke Bomb" )]
public class UseSmokeBomb : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x2808, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Grapes of Wrath" )]
public class UseGrapesOfWrath : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x2fd7, 1154, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Fruit Bowl" )]
public class UseFruitBowl : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x2d4f, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Enchanted Apple" )]
public class UseEnchantedApple : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x2fd8, 1160, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Trinsic Rose Petal" )]
public class UseTrinsicPetal : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x1021, 14, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Orange Petal" )]
public class UseOrangePetal : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x1021, 43, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
[HotkeyCommand( Category = "Consume", Name = "Bola" )]
public class UseBolaCommand : HotkeyCommand
{
public override void Execute()
{
ObjectCommands.UseType( 0x26ac, 0, Engine.Player.GetLayer( Layer.Backpack ) );
}
}
}
@@ -0,0 +1,37 @@
#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
using ClassicAssist.Shared;
using ClassicAssist.UO.Network.Packets;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Drop Holding Object" )]
public class DropHoldingObject : HotkeyCommand
{
public override void Execute()
{
if ( Engine.Player != null && Engine.Player.Holding != 0 )
{
Engine.SendPacketToServer( new DropItem( Engine.Player.Holding, Engine.Player.Backpack.Serial, -1, -1,
0 ) );
}
}
}
}
@@ -0,0 +1,13 @@
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Equip Last Weapon (Quick Weapon Switch)", Tooltip = "Requires Server Support" )]
public class EquipLastWeapon : HotkeyCommand
{
public override void Execute()
{
ActionCommands.EquipLastWeapon();
}
}
}
@@ -0,0 +1,22 @@
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Add Friend", Category = "Friends" )]
public class AddFriend : HotkeyCommand
{
public override void Execute()
{
MobileCommands.AddFriend();
}
}
[HotkeyCommand( Name = "Remove Friend", Category = "Friends" )]
public class RemoveFriend : HotkeyCommand
{
public override void Execute()
{
MobileCommands.RemoveFriend();
}
}
}
@@ -0,0 +1,68 @@
using System;
using System.Threading.Tasks;
using ClassicAssist.Shared.Resources;
namespace ClassicAssist.Data.Hotkeys.Commands
{
public class HotkeyCommand : HotkeyEntry, IComparable<HotkeyCommand>
{
private string _tooltip;
public HotkeyCommand()
{
HotkeyCommandAttribute a =
(HotkeyCommandAttribute) Attribute.GetCustomAttribute( GetType(), typeof( HotkeyCommandAttribute ) );
if ( a != null )
{
// if the attribute exists, the Name must be localizable.
string hotkeyName = Strings.ResourceManager.GetString(
a.Name ?? throw new ArgumentNullException( $"No localizable string for {a.Name}" ) );
string tooltipName = Strings.ResourceManager.GetString(
a.Tooltip ?? throw new ArgumentNullException( $"No localizable string for {a.Tooltip}" ) );
base.Name = string.IsNullOrEmpty( hotkeyName ) ? a.Name : hotkeyName;
Tooltip = string.IsNullOrEmpty( tooltipName ) ? a.Tooltip : tooltipName;
}
Action = hs => Task.Run( Execute );
}
public string Tooltip
{
get => _tooltip;
set => SetProperty( ref _tooltip, value );
}
public int CompareTo( HotkeyCommand other )
{
return string.Compare( Name, other.Name, StringComparison.Ordinal );
}
public virtual void Execute()
{
throw new NotImplementedException();
}
public override string ToString()
{
return Name;
}
public override bool Equals( object obj )
{
if ( !( obj is HotkeyCommand hkc ) )
{
return false;
}
return Name == hkc.Name;
}
public override int GetHashCode()
{
return Name.GetHashCode();
}
}
}
@@ -0,0 +1,11 @@
using System;
namespace ClassicAssist.Data.Hotkeys.Commands
{
public class HotkeyCommandAttribute : Attribute
{
public string Category { get; set; } = "";
public string Name { get; set; }
public string Tooltip { get; set; } = "";
}
}
@@ -0,0 +1,57 @@
using ClassicAssist.Shared;
using ClassicAssist.Misc;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network;
using ClassicAssist.UO.Network.Packets;
using ClassicAssist.UO.Objects;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Interrupt Spell" )]
public class InterruptSpellCommand : HotkeyCommand
{
public override void Execute()
{
PlayerMobile player = Engine.Player;
if ( player == null )
{
return;
}
Layer[] layerPriority =
{
Layer.Shirt, Layer.Shoes, Layer.Pants, Layer.Helm, Layer.Gloves, Layer.Ring, Layer.Neck,
Layer.Waist, Layer.InnerTorso, Layer.Bracelet, Layer.MiddleTorso, Layer.Earrings, Layer.Arms,
Layer.Cloak, Layer.OuterTorso, Layer.OuterLegs, Layer.InnerLegs, Layer.TwoHanded, Layer.OneHanded
};
Layer selectedLayer = Layer.Invalid;
int serial = 0;
foreach ( Layer layer in layerPriority )
{
serial = player.GetLayer( layer );
if ( serial == 0 )
{
continue;
}
selectedLayer = layer;
break;
}
if ( selectedLayer == Layer.Invalid )
{
return;
}
ActionPacketQueue.EnqueueActionPackets(
new BasePacket[]
{
new DragItem( serial, 1 ), new EquipRequest( serial, selectedLayer, player.Serial )
}, QueuePriority.High );
}
}
}
@@ -0,0 +1,31 @@
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Category = "Movement", Name = "Toggle Force Walk" )]
public class ToggleForceWalk : HotkeyCommand
{
public override void Execute()
{
MovementCommands.ToggleForceWalk();
}
}
[HotkeyCommand( Category = "Movement", Name = "Force Walk On" )]
public class SetForceWalkOn : HotkeyCommand
{
public override void Execute()
{
MovementCommands.SetForceWalk( true );
}
}
[HotkeyCommand( Category = "Movement", Name = "Force Walk Off" )]
public class SetForceWalkOff : HotkeyCommand
{
public override void Execute()
{
MovementCommands.SetForceWalk( false );
}
}
}
@@ -0,0 +1,13 @@
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Resync" )]
public class Resync : HotkeyCommand
{
public override void Execute()
{
UOC.Resync();
}
}
}
@@ -0,0 +1,15 @@
using ClassicAssist.Data.Macros;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Stop All Macros",
Tooltip = "Stops all running macros including background and autostart macros." )]
public class StopAllMacros : HotkeyCommand
{
public override void Execute()
{
MacroManager manager = MacroManager.GetInstance();
manager.StopAll();
}
}
}
@@ -0,0 +1,14 @@
using ClassicAssist.Data.Macros;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Stop Current Macro" )]
public class StopCurrentMacro : HotkeyCommand
{
public override void Execute()
{
MacroManager manager = MacroManager.GetInstance();
manager.Stop();
}
}
}
@@ -0,0 +1,102 @@
#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
using ClassicAssist.Data.Targeting;
namespace ClassicAssist.Data.Hotkeys.Commands
{
public class TargetAcquisitionEnemy
{
[HotkeyCommand( Name = "Get Next Friend", Category = "Target Acquisition - Enemy" )]
public class GetNextFriend : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetEnemy( TargetNotoriety.Friend, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Innocent", Category = "Target Acquisition - Enemy" )]
public class GetNextInnocent : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetEnemy( TargetNotoriety.Innocent, TargetBodyType.Any, TargetDistance.Closest );
}
}
[HotkeyCommand( Name = "Get Next Gray", Category = "Target Acquisition - Enemy" )]
public class GetNextGray : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetEnemy( TargetNotoriety.Gray, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Criminal", Category = "Target Acquisition - Enemy" )]
public class GetNextCriminal : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetEnemy( TargetNotoriety.Criminal, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Gray / Criminal", Category = "Target Acquisition - Enemy" )]
public class GetNextGrayCriminal : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetEnemy( TargetNotoriety.Gray | TargetNotoriety.Criminal,
TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Enemy", Category = "Target Acquisition - Enemy" )]
public class GetNextEnemy : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetEnemy( TargetNotoriety.Enemy, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Murderer", Category = "Target Acquisition - Enemy" )]
public class GetNextMurderer : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetEnemy( TargetNotoriety.Murderer, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Any", Category = "Target Acquisition - Enemy" )]
public class GetNextAny : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetEnemy( TargetNotoriety.Any, TargetBodyType.Any, TargetDistance.Next );
}
}
}
}
@@ -0,0 +1,103 @@
#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
using ClassicAssist.Data.Targeting;
namespace ClassicAssist.Data.Hotkeys.Commands
{
public class TargetAcquisitionFriend
{
[HotkeyCommand( Name = "Get Next Friend", Category = "Target Acquisition - Friend" )]
public class GetNextFriend : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetFriend( TargetNotoriety.Friend, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Innocent", Category = "Target Acquisition - Friend" )]
public class GetNextInnocent : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetFriend( TargetNotoriety.Innocent, TargetBodyType.Any, TargetDistance.Closest );
}
}
[HotkeyCommand( Name = "Get Next Gray", Category = "Target Acquisition - Friend" )]
public class GetNextGray : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetFriend( TargetNotoriety.Gray, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Criminal", Category = "Target Acquisition - Friend" )]
public class GetNextCriminal : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetFriend( TargetNotoriety.Criminal, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Gray / Criminal", Category = "Target Acquisition - Friend" )]
public class GetNextGrayCriminal : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetFriend( TargetNotoriety.Gray | TargetNotoriety.Criminal,
TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Enemy", Category = "Target Acquisition - Friend" )]
public class GetNextEnemy : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetFriend( TargetNotoriety.Enemy, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Murderer", Category = "Target Acquisition - Friend" )]
public class GetNextMurderer : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance()
.GetFriend( TargetNotoriety.Murderer, TargetBodyType.Any, TargetDistance.Next );
}
}
[HotkeyCommand( Name = "Get Next Any", Category = "Target Acquisition - Friend" )]
public class GetNextAny : HotkeyCommand
{
public override void Execute()
{
TargetManager.GetInstance().GetFriend( TargetNotoriety.Any, TargetBodyType.Any, TargetDistance.Next );
}
}
}
}
@@ -0,0 +1,202 @@
using ClassicAssist.Shared;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.Data.Targeting;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UO;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network.Packets;
using ClassicAssist.UO.Objects;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
public class Targeting
{
[HotkeyCommand( Name = "Set Enemy", Category = "Targeting" )]
public class SetEnemyCommand : HotkeyCommand
{
public override void Execute()
{
TargetManager manager = TargetManager.GetInstance();
Entity mobile = manager.PromptTarget();
if ( mobile == null )
{
return;
}
manager.SetEnemy( mobile );
Engine.SendPacketToServer( new LookRequest( mobile.Serial ) );
}
}
[HotkeyCommand( Name = "Set Friend", Category = "Targeting" )]
public class SetFriendCommand : HotkeyCommand
{
public override void Execute()
{
TargetManager manager = TargetManager.GetInstance();
Entity mobile = manager.PromptTarget();
if ( mobile == null )
{
return;
}
manager.SetFriend( mobile );
Engine.SendPacketToServer( new LookRequest( mobile.Serial ) );
}
}
[HotkeyCommand( Name = "Set Last Target", Category = "Targeting" )]
public class SetLastTargetCommand : HotkeyCommand
{
public override void Execute()
{
TargetManager manager = TargetManager.GetInstance();
Entity entity = manager.PromptTarget();
if ( entity == null )
{
return;
}
manager.SetLastTarget( entity );
if ( UOMath.IsMobile( entity.Serial ) )
{
Engine.SendPacketToServer( new LookRequest( entity.Serial ) );
}
}
}
[HotkeyCommand( Name = "Target Enemy", Category = "Targeting" )]
public class TargetEnemyCommand : HotkeyCommand
{
public override void Execute()
{
TargetCommands.Target( "enemy", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
}
}
[HotkeyCommand( Name = "Target Last", Category = "Targeting" )]
public class TargetLastCommand : HotkeyCommand
{
public override void Execute()
{
if ( Options.CurrentOptions.SmartTargetOption == SmartTargetOption.None )
{
TargetCommands.Target( "last", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
}
else
{
if ( Engine.TargetExists )
{
if ( Options.CurrentOptions.SmartTargetOption.HasFlag( SmartTargetOption.Friend ) &&
Engine.TargetFlags == TargetFlags.Beneficial && AliasCommands.FindAlias( "friend" ) )
{
TargetCommands.Target( "friend", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
return;
}
if ( Options.CurrentOptions.SmartTargetOption.HasFlag( SmartTargetOption.Enemy ) &&
Engine.TargetFlags == TargetFlags.Harmful && AliasCommands.FindAlias( "enemy" ) )
{
TargetCommands.Target( "enemy", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
return;
}
}
TargetCommands.Target( "last", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
}
}
}
[HotkeyCommand( Name = "Target Friend", Category = "Targeting" )]
public class TargetFriendCommand : HotkeyCommand
{
public override void Execute()
{
TargetCommands.Target( "friend", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
}
}
[HotkeyCommand( Name = "Target Self", Category = "Targeting" )]
public class TargetSelfCommand : HotkeyCommand
{
public override void Execute()
{
TargetCommands.Target( "self", Options.CurrentOptions.RangeCheckLastTarget,
Options.CurrentOptions.QueueLastTarget );
}
}
[HotkeyCommand( Name = "Clear Target Queue", Category = "Targeting" )]
public class ClearTargetQueueCommand : HotkeyCommand
{
public override void Execute()
{
TargetCommands.ClearTargetQueue();
}
}
[HotkeyCommand( Name = "Attack Last", Category = "Targeting" )]
public class AttackLastCommand : HotkeyCommand
{
public override void Execute()
{
ActionCommands.Attack( "last" );
}
}
[HotkeyCommand( Name = "Attack Enemy", Category = "Targeting" )]
public class AttackEnemyCommand : HotkeyCommand
{
public override void Execute()
{
ActionCommands.Attack( "enemy" );
}
}
[HotkeyCommand( Name = "Show Next Target In Queue", Category = "Targeting" )]
public class ShowNextTargetQueue : HotkeyCommand
{
public override void Execute()
{
if ( !Options.CurrentOptions.QueueLastTarget )
{
UOC.SystemMessage( Strings.Target_queue_is_not_enabled___ );
return;
}
object nextTarget = Engine.LastTargetQueue.Peek();
switch ( nextTarget )
{
case string targetAlias:
MsgCommands.HeadMsg( string.Format( Strings.Next_Target___0_, targetAlias ),
Engine.Player?.Serial );
break;
case int targetSerial:
{
Mobile entity = Engine.Mobiles.GetMobile( targetSerial );
MsgCommands.HeadMsg(
string.Format( Strings.Next_Target___0_,
$"0x{targetSerial:x} - {entity?.Name ?? "Unknown"}" ), Engine.Player?.Serial );
break;
}
}
}
}
}
}
@@ -0,0 +1,18 @@
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Toggle hotkeys" )]
public sealed class ToggleHotkeys : HotkeyCommand
{
public ToggleHotkeys()
{
Disableable = false;
}
public override void Execute()
{
MainCommands.Hotkeys();
}
}
}
@@ -0,0 +1,32 @@
#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
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Toggle mounted" )]
public class ToggleMounted : HotkeyCommand
{
public override void Execute()
{
ActionCommands.ToggleMounted();
}
}
}
@@ -0,0 +1,50 @@
using ClassicAssist.Shared;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Objects;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
public static class UseHands
{
public static void UseHand( Layer layer )
{
PlayerMobile player = Engine.Player;
if ( player == null )
{
return;
}
int serial = player.GetLayer( layer );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_layer_value___ );
return;
}
ObjectCommands.UseObject( serial );
}
[HotkeyCommand( Name = "Use Left Hand" )]
public class UseLeftHand : HotkeyCommand
{
public override void Execute()
{
UseHand( Layer.OneHanded );
}
}
[HotkeyCommand( Name = "Use Right Hand" )]
public class UseRightHand : HotkeyCommand
{
public override void Execute()
{
UseHand( Layer.TwoHanded );
}
}
}
}
@@ -0,0 +1,19 @@
using ClassicAssist.Shared;
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "Use Last Object" )]
public class UseLastObject : HotkeyCommand
{
public override void Execute()
{
int serial = Engine.Player?.LastObjectSerial ?? 0;
if ( serial != 0 )
{
ObjectCommands.UseObject( serial );
}
}
}
}
@@ -0,0 +1,31 @@
using ClassicAssist.Data.Macros.Commands;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Name = "WarMode On" )]
public class WarModeOnCommand : HotkeyCommand
{
public override void Execute()
{
MainCommands.WarMode( "on" );
}
}
[HotkeyCommand( Name = "WarMode Off" )]
public class WarModeOffCommand : HotkeyCommand
{
public override void Execute()
{
MainCommands.WarMode( "off" );
}
}
[HotkeyCommand( Name = "WarMode Toggle" )]
public class WarModeCommand : HotkeyCommand
{
public override void Execute()
{
MainCommands.WarMode();
}
}
}
@@ -0,0 +1,87 @@
using ClassicAssist.Shared;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.UO.Network.Packets;
namespace ClassicAssist.Data.Hotkeys.Commands
{
[HotkeyCommand( Category = "Abilities", Name = "Set Primary Ability" )]
public class SetPrimaryAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.SetAbility( "primary", "on" );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Unset Primary Ability" )]
public class UnsetPrimaryAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.SetAbility( "primary", "off" );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Set Secondary Ability" )]
public class SetSecondaryAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.SetAbility( "secondary", "on" );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Unset Secondary Ability" )]
public class UnsetSecondaryAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.SetAbility( "secondary", "off" );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Toggle Primary Ability" )]
public class TogglePrimaryAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.SetAbility( "primary" );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Toggle Secondary Ability" )]
public class ToggleSecondaryAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.SetAbility( "secondary" );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Clear Weapon Ability" )]
public class ClearWeaponAbility : HotkeyCommand
{
public override void Execute()
{
AbilitiesCommands.ClearAbility();
}
}
[HotkeyCommand( Category = "Abilities", Name = "Stun" )]
public class StunAbility : HotkeyCommand
{
public override void Execute()
{
Engine.SendPacketToServer( new StunRequest() );
}
}
[HotkeyCommand( Category = "Abilities", Name = "Disarm" )]
public class DisarmAbility : HotkeyCommand
{
public override void Execute()
{
Engine.SendPacketToServer( new DisarmRequest() );
}
}
}
@@ -0,0 +1,14 @@
namespace ClassicAssist.Data.Hotkeys
{
public class HotkeyChangedEventArgs
{
public HotkeyChangedEventArgs( ShortcutKeys oldValue, ShortcutKeys newValue )
{
OldValue = oldValue;
NewValue = newValue;
}
public ShortcutKeys NewValue { get; set; }
public ShortcutKeys OldValue { get; set; }
}
}
@@ -0,0 +1,134 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using ClassicAssist.Annotations;
using ClassicAssist.UI.Misc;
using Newtonsoft.Json;
namespace ClassicAssist.Data.Hotkeys
{
public abstract class HotkeyEntry : INotifyPropertyChanged, IComparable<HotkeyEntry>
{
public delegate void HotkeyChangedEventHandler( object sender, HotkeyChangedEventArgs e );
private readonly object _childrenLock = new object();
private ObservableCollectionEx<HotkeyEntry> _children = new ObservableCollectionEx<HotkeyEntry>();
private ShortcutKeys _hotkey = new ShortcutKeys();
private bool _isCategory;
private string _name;
private bool _passToUo = true;
[JsonIgnore]
public Action<HotkeyEntry> Action { get; set; }
[JsonIgnore]
public ObservableCollectionEx<HotkeyEntry> Children
{
get
{
lock ( _childrenLock )
{
return _children;
}
}
set
{
lock ( _childrenLock )
{
SetProperty( ref _children, value );
}
}
}
public virtual bool Disableable { get; set; } = true;
public ShortcutKeys Hotkey
{
get => _hotkey;
set
{
if ( !Equals( value, ShortcutKeys.Default ) )
{
HotkeyManager manager = HotkeyManager.GetInstance();
manager.ClearPreviousHotkey( value );
}
SetProperty( ref _hotkey, value );
OnPropertyChanged( nameof(Image) );
HotkeyChanged?.Invoke( this, new HotkeyChangedEventArgs( _hotkey, value ) );
}
}
[JsonIgnore]
public string Image => Equals( Hotkey, ShortcutKeys.Default ) ? "red-circle.png" : "green-circle.png";
public bool IsCategory
{
get => _isCategory;
set => SetProperty( ref _isCategory, value );
}
public virtual string Name
{
get => _name;
set => SetProperty( ref _name, value );
}
public bool PassToUO
{
get => _passToUo;
set => SetProperty( ref _passToUo, value );
}
public int CompareTo( HotkeyEntry other )
{
if ( ReferenceEquals( this, other ) )
{
return 0;
}
if ( ReferenceEquals( null, other ) )
{
return 1;
}
int isCategoryComparison = _isCategory.CompareTo( other._isCategory );
if ( isCategoryComparison != 0 )
{
return isCategoryComparison;
}
return string.Compare( _name, other._name, StringComparison.Ordinal );
}
public event HotkeyChangedEventHandler HotkeyChanged;
public override string ToString()
{
return Name;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
}
// ReSharper disable once RedundantAssignment
public void SetProperty<T>( ref T field, T value, [CallerMemberName] string propertyName = null )
{
field = value;
OnPropertyChanged( propertyName );
}
#endregion
}
}
@@ -0,0 +1,303 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using ClassicAssist.Annotations;
using ClassicAssist.Data.Hotkeys.Commands;
using ClassicAssist.Data.Macros.Commands;
using ClassicAssist.Misc;
using ClassicAssist.UI.Misc;
using static ClassicAssist.Misc.SDLKeys;
namespace ClassicAssist.Data.Hotkeys
{
public class KeyState
{
[DllImport("SDL2.dll", EntryPoint = "SDL_GetKeyboardState", CallingConvention = CallingConvention.Cdecl)]
private static unsafe extern byte* GetKeyboardState(out int numKeys);
public static unsafe bool GetKeyState(SDL_Scancode scanCode)
{
var result = GetKeyboardState(out int numKeys);
int code = (int) scanCode;
return code < numKeys && result[(int)code] == 1;
}
}
public class HotkeyManager : INotifyPropertyChanged
{
private static HotkeyManager _instance;
private static readonly object _instanceLock = new object();
private readonly object _lock = new object();
private readonly Key[] _modifierKeys =
{
Key.LeftCtrl, Key.RightCtrl, Key.LeftShift, Key.RightShift, Key.LeftAlt, Key.RightAlt
};
private readonly List<Key> _modifiers = new List<Key>();
private bool _enabled = true;
private ObservableCollectionEx<HotkeyCommand> _items = new ObservableCollectionEx<HotkeyCommand>();
private HotkeyManager()
{
}
public Action ClearAllHotkeys { get; set; }
public bool Enabled
{
get => _enabled;
set => SetProperty( ref _enabled, value );
}
public ObservableCollectionEx<HotkeyCommand> Items
{
get => _items;
set => SetProperty( ref _items, value );
}
public event PropertyChangedEventHandler PropertyChanged;
public void AddCategory( HotkeyCommand item, IComparer<HotkeyEntry> comparer = null )
{
if ( Items.Contains( item ) )
{
Items.Remove( item );
}
if ( comparer == null )
{
comparer = Comparer<HotkeyEntry>.Default;
}
int i = 0;
while ( i < Items.Count && comparer.Compare( Items[i], item ) < 0 )
{
i++;
}
Items.Insert( i, item );
}
public void ClearPreviousHotkey( ShortcutKeys keys )
{
foreach ( HotkeyCommand hotkeyEntry in Items )
{
if ( hotkeyEntry.Children == null )
{
continue;
}
foreach ( HotkeyEntry hotkeyEntryChild in hotkeyEntry.Children )
{
if ( Equals( hotkeyEntryChild.Hotkey, keys ) )
{
hotkeyEntryChild.Hotkey = ShortcutKeys.Default;
}
}
}
}
public static HotkeyManager GetInstance()
{
// ReSharper disable once InvertIf
if ( _instance == null )
{
lock ( _instanceLock )
{
if ( _instance == null )
{
_instance = new HotkeyManager();
}
}
}
return _instance;
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged( [CallerMemberName] string propertyName = null )
{
PropertyChanged?.Invoke( this, new PropertyChangedEventArgs( propertyName ) );
}
// ReSharper disable once RedundantAssignment
public void SetProperty<T>( ref T obj, T value, [CallerMemberName] string propertyName = "" )
{
obj = value;
OnPropertyChanged( propertyName );
}
public bool OnHotkeyPressed( Key keys )
{
lock ( _lock )
{
bool filter = false;
if ( _modifierKeys.Contains( keys ) )
{
_modifiers.Clear();
_modifiers.Add( keys );
return false;
}
Key modifier = Key.None;
if ( _modifiers.Count > 0 )
{
modifier = _modifiers[0];
}
bool down = KeyState.GetKeyState(KeysToSDLScancode(modifier));
if ( !down )
{
modifier = Key.None;
}
// Sanity check
if ( keys == Key.None )
{
return false;
}
foreach ( HotkeyCommand hke in Items )
{
if ( hke.Children == null )
{
continue;
}
try
{
IEnumerable<HotkeyEntry> hotkeyEntries = hke.Children.Where( t =>
t.Hotkey.Modifier == modifier && t.Hotkey.Key == keys &&
t.Hotkey.Mouse == MouseOptions.None );
foreach ( HotkeyEntry hks in hotkeyEntries )
{
if ( hks.Disableable && !Enabled )
{
continue;
}
filter = !hks.PassToUO;
AliasCommands.SetDefaultAliases();
Task.Run( () => hks.Action.Invoke( hks ) );
break;
}
}
catch ( InvalidOperationException )
{
// When spamming keys
}
}
return filter;
}
}
private SDL_Scancode KeysToSDLScancode(Key modifier )
{
//TODO Enter keys / find better way
switch ( modifier )
{
case Key.LeftAlt:
return SDL_Scancode.SDL_SCANCODE_LALT;
case Key.Right:
return SDL_Scancode.SDL_SCANCODE_RIGHT;
case Key.LeftCtrl:
return SDL_Scancode.SDL_SCANCODE_LCTRL;
case Key.RightCtrl:
return SDL_Scancode.SDL_SCANCODE_RCTRL;
case Key.LeftShift:
return SDL_Scancode.SDL_SCANCODE_LSHIFT;
case Key.RightShift:
return SDL_Scancode.SDL_SCANCODE_RSHIFT;
}
return 0;
}
public void OnMouseAction( MouseOptions mouse )
{
// Sanity check
if ( mouse == MouseOptions.None )
{
return;
}
lock ( _lock )
{
foreach ( HotkeyCommand hke in Items )
{
if ( hke.Children == null )
{
continue;
}
try
{
Key modifier = Key.None;
//Key modifier = _modifierKeys.FirstOrDefault( key =>
// Engine.Dispatcher.Invoke( () => Keyboard.IsKeyDown( key ) ) );
IEnumerable<HotkeyEntry> hotkeyEntries = hke.Children.Where( t =>
t.Hotkey.Modifier == modifier && t.Hotkey.Key == Key.None && t.Hotkey.Mouse == mouse );
foreach ( HotkeyEntry hks in hotkeyEntries )
{
if ( hks.Disableable && !Enabled )
{
continue;
}
AliasCommands.SetDefaultAliases();
Task.Run( () => hks.Action.Invoke( hks ) );
break;
}
}
catch ( InvalidOperationException )
{
// When spamming wheel
}
}
}
}
public void ClearItems()
{
foreach ( HotkeyEntry entry in Items )
{
ClearHotkeys( entry );
}
Items.Clear();
}
private void ClearHotkeys( HotkeyEntry entry )
{
entry.Hotkey = ShortcutKeys.Default;
if ( !entry.IsCategory )
{
return;
}
foreach ( HotkeyEntry hotkeyEntry in entry.Children )
{
ClearHotkeys( hotkeyEntry );
}
}
}
}
@@ -0,0 +1,97 @@
using System;
using ClassicAssist.Misc;
using Newtonsoft.Json.Linq;
namespace ClassicAssist.Data.Hotkeys
{
public enum MouseOptions
{
LeftButton,
MiddleButton,
RightButton,
XButton1,
XButton2,
MouseWheelDown,
MouseWheelUp,
None
}
public class ShortcutKeys
{
public ShortcutKeys()
{
}
public ShortcutKeys( Key modifier, Key key )
{
Modifier = modifier;
Key = key;
}
public ShortcutKeys( JToken token )
{
if ( token == null )
{
return;
}
Key = token["Keys"]?.ToObject<Key>() ?? Key.None;
Modifier = token["Modifier"]?.ToObject<Key>() ?? Key.None;
Mouse = token["Mouse"]?.ToObject<MouseOptions>() ?? MouseOptions.None;
}
public static ShortcutKeys Default => new ShortcutKeys( Key.None, Key.None ) { Mouse = MouseOptions.None };
public Key Key { get; set; } = Key.None;
public Key Modifier { get; set; } = Key.None;
public MouseOptions Mouse { get; set; } = MouseOptions.None;
public Keys[] ToArray()
{
//TODO
//Keys modifier = (Keys) KeyInterop.VirtualKeyFromKey( Modifier );
//Keys key = (Keys) KeyInterop.VirtualKeyFromKey( Key );
//if ( modifier == Keys.LControlKey || modifier == Keys.RControlKey )
//{
// modifier = Keys.ControlKey;
//}
//return modifier == Keys.None ? new[] { key } : new[] { modifier, key };
throw new NotImplementedException();
}
public override string ToString()
{
if ( Mouse != MouseOptions.None )
{
return Modifier != Key.None ? $"{Modifier} + {Mouse}" : Mouse.ToString();
}
return Modifier != Key.None ? $"{Modifier} + {Key}" : Key.ToString();
}
public override bool Equals( object obj )
{
return obj is ShortcutKeys keys && Key == keys.Key && Modifier == keys.Modifier && Mouse == keys.Mouse;
}
public override int GetHashCode()
{
int hashCode = 572187996;
hashCode = hashCode * -1521134295 + Key.GetHashCode();
hashCode = hashCode * -1521134295 + Modifier.GetHashCode();
hashCode = hashCode * -1521134295 + Mouse.GetHashCode();
return hashCode;
}
public JObject ToJObject()
{
JObject keys = new JObject
{
{ "Keys", (int) Key }, { "Modifier", (int) Modifier }, { "Mouse", (int) Mouse }
};
return keys;
}
}
}