Files
Beyhan Oğur d5f52cc3d3 first commit
2026-09-03 04:45:36 +03:00

603 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using ClassicAssist.Shared;
using ClassicAssist.Data.Regions;
using ClassicAssist.Data.Targeting;
using ClassicAssist.Misc;
using ClassicAssist.Shared.Resources;
using ClassicAssist.UO;
using ClassicAssist.UO.Data;
using ClassicAssist.UO.Network.Packets;
using ClassicAssist.UO.Objects;
using TargetTypeEnum = ClassicAssist.UO.Data.TargetType;
using UOC = ClassicAssist.Shared.UO.Commands;
namespace ClassicAssist.Data.Macros.Commands
{
public static class TargetCommands
{
public enum TargetExistsType
{
Any,
Beneficial,
Harmful,
Neutral
}
public enum TargetResourceType
{
Ore,
Sand,
Wood,
Graves,
Red_Mushrooms
}
private static readonly ushort[] _treeTiles =
{
0x0CCA, 0x0CCB, 0x0CCC, 0x0CCD, 0x0CD0, 0x0CD3, 0x0CD6, 0x0CD8, 0x0CDA, 0x0CDD, 0x0CE0, 0x0CE3, 0x0CE6,
0x0D41, 0x0D42, 0x0D43, 0x0D44, 0x0D57, 0x0D58, 0x0D59, 0x0D5A, 0x0D5B, 0x0D6E, 0x0D6F, 0x0D70, 0x0D71,
0x0D72, 0x0D84, 0x0D85, 0x0D86, 0x0D94, 0x0D98, 0x0D9C, 0x0DA0, 0x0DA4, 0x0DA8, 0x0C9E, 0x0CA8, 0x0CAA,
0x0CAB, 0x0CC9, 0x0CF8, 0x0CFB, 0x0CFE, 0x0D01, 0x12B6, 0x12B7, 0x12B8, 0x12B9, 0x12BA, 0x12BB, 0x12BC,
0x12BD
};
private static readonly ushort[] _caveTiles =
{
1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355,
1356, 1357, 1358, 1359, 1361, 1362, 1363
};
[CommandsDisplay( Category = nameof( Strings.Target ) )]
public static void CancelTarget()
{
Engine.SendPacketToServer( new Target( TargetTypeEnum.Object, -1, TargetFlags.Cancel, -1, -1, -1, 0, 0,
true ) );
}
[CommandsDisplay( Category = nameof( Strings.Target ), Parameters = new[] { nameof( ParameterType.Timeout ) } )]
public static bool WaitForTarget( int timeout = 5000 )
{
return UOC.WaitForTarget( timeout );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[] { nameof( ParameterType.SerialOrAlias ) } )]
public static void Target( object obj, bool checkRange = false, bool useQueue = false )
{
int serial = AliasCommands.ResolveSerial( obj );
if ( serial == 0 )
{
return;
}
if ( checkRange && UOMath.IsMobile( serial ) && Engine.TargetExists )
{
Mobile mobile = Engine.Mobiles.GetMobile( serial );
if ( mobile != null )
{
if ( mobile.Distance > Options.CurrentOptions.RangeCheckLastTargetAmount )
{
UOC.SystemMessage( Strings.Target_out_of_range__try_again___ );
UOC.ResendTargetToClient();
return;
}
}
else
{
UOC.SystemMessage( Strings.Target_out_of_range__try_again___ );
UOC.ResendTargetToClient();
return;
}
}
if ( Options.CurrentOptions.PreventTargetingInnocentsInGuardzone && Engine.TargetExists )
{
Mobile mobile = Engine.Mobiles.GetMobile( serial );
if ( mobile != null && mobile.Notoriety == Notoriety.Innocent &&
mobile.Serial != Engine.Player?.Serial && Engine.TargetFlags == TargetFlags.Harmful &&
mobile.GetRegion().Attributes.HasFlag( RegionAttributes.Guarded ) )
{
UOC.SystemMessage( Strings.Target_blocked____try_again___ );
UOC.ResendTargetToClient();
return;
}
}
if ( useQueue && !Engine.TargetExists )
{
MsgCommands.HeadMsg( Strings.Target_Queued, Engine.Player?.Serial );
Engine.LastTargetQueue.Enqueue( obj );
return;
}
Engine.SendPacketToServer( new Target( TargetTypeEnum.Object, -1, TargetFlags.None, serial, -1, -1, -1, 0,
true ) );
Engine.TargetExists = false;
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[] { nameof( ParameterType.SerialOrAlias ), nameof( ParameterType.String ) } )]
[CommandsDisplayStringSeeAlso( new[] { null, nameof( TargetResourceType ) } )]
public static void TargetByResource( object toolObj, string resourceType )
{
int serial = AliasCommands.ResolveSerial( toolObj );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
try
{
TargetResourceType resourceEnum = Utility.GetEnumValueByName<TargetResourceType>( resourceType );
Engine.SendPacketToServer( new TargetByResource( serial, (int) resourceEnum ) );
}
catch ( InvalidOperationException )
{
}
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.SerialOrAlias ), nameof( ParameterType.IntegerValue ),
nameof( ParameterType.Boolean ), nameof( ParameterType.ItemID )
} )]
public static void TargetTileRelative( object obj, int distance, bool reverse = false, int itemID = 0 )
{
int serial = AliasCommands.ResolveSerial( obj );
if ( serial == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Entity entity = Engine.Mobiles.GetMobile( serial );
if ( entity == null )
{
UOC.SystemMessage( Strings.Mobile_not_found___ );
return;
}
int x = entity.X;
int y = entity.Y;
int offsetX = 0;
int offsetY = 0;
// TODO
Direction direction = (Direction) ( (int) entity.Direction & ~0x80 );
switch ( direction )
{
case Direction.North:
offsetY = -1;
break;
case Direction.Northeast:
offsetY = -1;
offsetX = 1;
break;
case Direction.East:
offsetX = 1;
break;
case Direction.Southeast:
offsetX = 1;
offsetY = 1;
break;
case Direction.South:
offsetY = 1;
break;
case Direction.Southwest:
offsetY = 1;
offsetX = -1;
break;
case Direction.West:
offsetX = -1;
break;
case Direction.Northwest:
offsetX = -1;
offsetY = -1;
break;
case Direction.Invalid:
break;
default:
throw new ArgumentOutOfRangeException();
}
int totalOffsetX = offsetX * distance;
int totalOffsetY = offsetY * distance;
if ( reverse )
{
totalOffsetX = -totalOffsetX;
totalOffsetY = -totalOffsetY;
}
int destinationX = x + totalOffsetX;
int destinationY = y + totalOffsetY;
( int surfaceZ, int surfaceID ) =
MapInfo.GetMapSurface( (int) Engine.Player.Map, destinationX, destinationY );
if ( itemID == 0 )
{
itemID = surfaceID;
}
TargetXYZ( destinationX, destinationY, surfaceZ, itemID );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.XCoordinateOffset ), nameof( ParameterType.YCoordinateOffset ),
nameof( ParameterType.YCoordinateOffset ), nameof( ParameterType.ItemID )
} )]
public static void TargetTileOffset( int xOffset, int yOffset, int zOffset, int itemID = 0 )
{
TargetXYZ( Engine.Player.X + xOffset, Engine.Player.Y + yOffset, Engine.Player.Z + zOffset, itemID );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.XCoordinateOffset ), nameof( ParameterType.YCoordinateOffset ),
nameof( ParameterType.YCoordinateOffset ), nameof( ParameterType.ItemID )
} )]
public static void TargetTileOffsetResource( int xOffset, int yOffset, int zOffset, int itemID = 0 )
{
int x = Engine.Player.X + xOffset;
int y = Engine.Player.Y + yOffset;
int z = Engine.Player.Z + zOffset;
if ( itemID == 0 )
{
StaticTile[] staticTiles = Statics.GetStatics( (int) Engine.Player.Map, x, y );
if ( staticTiles != null )
{
StaticTile selectedStatic = staticTiles.FirstOrDefault( i =>
_treeTiles.Contains( i.ID ) || _caveTiles.Contains( i.ID ) ||
i.Flags.HasFlag( TileFlags.Wet ) );
if ( selectedStatic.ID == 0 )
{
selectedStatic = staticTiles.FirstOrDefault();
}
itemID = selectedStatic.ID;
z = selectedStatic.Z;
}
}
TargetXYZ( x, y, z, itemID );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.Empty ), nameof( ParameterType.Empty ), nameof( ParameterType.Empty ),
nameof( ParameterType.Empty )
} )]
[CommandsDisplayStringSeeAlso( new[]
{
nameof( TargetNotoriety ), nameof( TargetBodyType ), nameof( TargetDistance ),
nameof( TargetInfliction )
} )]
public static bool GetEnemy( IEnumerable<string> notorieties, string bodyType = "Any", string distance = "Next",
string infliction = "Any" )
{
TargetNotoriety notoFlags = TargetNotoriety.None;
foreach ( string noto in notorieties )
{
if ( Enum.TryParse( noto, true, out TargetNotoriety flag ) )
{
notoFlags |= flag;
}
}
if ( !Enum.TryParse( bodyType, true, out TargetBodyType bt ) )
{
bt = TargetBodyType.Any;
}
if ( !Enum.TryParse( distance, true, out TargetDistance td ) )
{
td = TargetDistance.Next;
}
if ( !Enum.TryParse( infliction, true, out TargetInfliction ti ) )
{
ti = TargetInfliction.Any;
}
return TargetManager.GetInstance().GetEnemy( notoFlags, bt, td, TargetFriendType.None, ti );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.Empty ), nameof( ParameterType.Empty ), nameof( ParameterType.Empty )
} )]
[CommandsDisplayStringSeeAlso( new[]
{
nameof( TargetDistance ), nameof( TargetInfliction ), nameof( TargetBodyType )
} )]
public static bool GetFriendListOnly( string distance = "Next", string targetInfliction = "Any",
string bodyType = "Any" )
{
if ( !Enum.TryParse( distance, true, out TargetDistance td ) )
{
td = TargetDistance.Next;
}
if ( !Enum.TryParse( targetInfliction, true, out TargetInfliction ti ) )
{
ti = TargetInfliction.Any;
}
if ( !Enum.TryParse( bodyType, true, out TargetBodyType bt ) )
{
bt = TargetBodyType.Any;
}
return TargetManager.GetInstance().GetFriend( TargetNotoriety.Any, bt, td, TargetFriendType.Only, ti );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.Empty ), nameof( ParameterType.Empty ), nameof( ParameterType.Empty ),
nameof( ParameterType.Empty )
} )]
[CommandsDisplayStringSeeAlso( new[]
{
nameof( TargetNotoriety ), nameof( TargetBodyType ), nameof( TargetDistance ),
nameof( TargetInfliction )
} )]
public static bool GetFriend( IEnumerable<string> notorieties, string bodyType = "Any",
string distance = "Next", string infliction = "Any" )
{
TargetNotoriety notoFlags = TargetNotoriety.None;
foreach ( string noto in notorieties )
{
if ( Enum.TryParse( noto, true, out TargetNotoriety flag ) )
{
notoFlags |= flag;
}
}
if ( !Enum.TryParse( bodyType, true, out TargetBodyType bt ) )
{
bt = TargetBodyType.Any;
}
if ( !Enum.TryParse( distance, true, out TargetDistance td ) )
{
td = TargetDistance.Next;
}
if ( !Enum.TryParse( infliction, true, out TargetInfliction ti ) )
{
ti = TargetInfliction.Any;
}
return TargetManager.GetInstance().GetFriend( notoFlags, bt, td, TargetFriendType.Include, ti );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[] { nameof( ParameterType.BeneficialHarmfulNeutral ) } )]
[CommandsDisplayStringSeeAlso( new[] { nameof( TargetExistsType ) } )]
public static bool TargetExists( string targetExistsType = "Any" )
{
if ( !Enum.TryParse( targetExistsType, out TargetExistsType enumValue ) )
{
enumValue = TargetExistsType.Any;
}
switch ( enumValue )
{
case TargetExistsType.Any:
return Engine.TargetExists;
case TargetExistsType.Beneficial:
return Engine.TargetExists && Engine.TargetFlags == TargetFlags.Beneficial;
case TargetExistsType.Harmful:
return Engine.TargetExists && Engine.TargetFlags == TargetFlags.Harmful;
case TargetExistsType.Neutral:
return Engine.TargetExists && Engine.TargetFlags == TargetFlags.None;
default:
throw new ArgumentOutOfRangeException();
}
}
[CommandsDisplay( Category = nameof( Strings.Target ) )]
public static bool WaitingForTarget()
{
return Engine.WaitingForTarget;
}
[CommandsDisplay( Category = nameof( Strings.Target ) )]
public static void ClearTargetQueue()
{
Engine.LastTargetQueue?.Clear();
UOC.SystemMessage( Strings.Target_queue_cleared___ );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.SerialOrAlias ), nameof( ParameterType.Hue ), nameof( ParameterType.Range )
} )]
public static void TargetType( object obj, int hue = -1, int range = -1 )
{
int id = AliasCommands.ResolveSerial( obj );
if ( id == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
if ( Engine.Player?.Backpack == null )
{
UOC.SystemMessage( Strings.Error__Cannot_find_player_backpack );
return;
}
Item item = Engine.Items.SelectEntity( i =>
i.ID == id && ( hue == -1 || i.Hue == hue ) &&
i.IsDescendantOf( Engine.Player.Backpack.Serial, range ) );
if ( item == null )
{
UOC.SystemMessage( Strings.Cannot_find_item___ );
return;
}
Target( item.Serial, false, Options.CurrentOptions.QueueLastTarget );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.SerialOrAlias ), nameof( ParameterType.Hue ), nameof( ParameterType.Range )
} )]
public static void TargetGround( object obj, int hue = -1, int range = -1 )
{
int id = AliasCommands.ResolveSerial( obj );
if ( id == 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Entity entity =
(Entity) Engine.Items.SelectEntity( i =>
i.ID == id && ( hue == -1 || i.Hue == hue ) && ( range == -1 || i.Distance < range ) ) ??
Engine.Mobiles.SelectEntity( m =>
m.ID == id && ( hue == -1 || m.Hue == hue ) && ( range == -1 || m.Distance < range ) );
if ( entity == null )
{
UOC.SystemMessage( Strings.Cannot_find_item___ );
return;
}
Target( entity.Serial, false, Options.CurrentOptions.QueueLastTarget );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[] { nameof( ParameterType.SerialOrAlias ) } )]
public static void SetEnemy( object obj )
{
int serial = AliasCommands.ResolveSerial( obj );
if ( serial <= 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Entity entity = Engine.Items.GetItem( serial ) ?? (Entity) Engine.Mobiles.GetMobile( serial );
if ( entity == null )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
TargetManager.GetInstance().SetEnemy( entity );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[] { nameof( ParameterType.SerialOrAlias ) } )]
public static void SetFriend( object obj )
{
int serial = AliasCommands.ResolveSerial( obj );
if ( serial <= 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Entity entity = Engine.Items.GetItem( serial ) ?? (Entity) Engine.Mobiles.GetMobile( serial );
if ( entity == null )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
TargetManager.GetInstance().SetFriend( entity );
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[] { nameof( ParameterType.SerialOrAlias ) } )]
public static void SetLastTarget( object obj )
{
int serial = AliasCommands.ResolveSerial( obj );
if ( serial <= 0 )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
Entity entity = Engine.Items.GetItem( serial ) ?? (Entity) Engine.Mobiles.GetMobile( serial );
if ( entity == null )
{
UOC.SystemMessage( Strings.Invalid_or_unknown_object_id );
return;
}
TargetManager.GetInstance().SetLastTarget( entity );
}
[CommandsDisplay( Category = nameof( Strings.Target ), Parameters = new[] { nameof( ParameterType.Timeout ) } )]
public static bool WaitForTargetOrFizzle( int timeout )
{
( _, bool result ) = UOC.WaitForTargetOrFizzle( timeout );
return result;
}
[CommandsDisplay( Category = nameof( Strings.Target ),
Parameters = new[]
{
nameof( ParameterType.XCoordinate ), nameof( ParameterType.YCoordinate ),
nameof( ParameterType.ZCoordinate ), nameof( ParameterType.ItemID )
} )]
public static void TargetXYZ( int x, int y, int z, int itemID = 0 )
{
Engine.SendPacketToServer( new Target( TargetTypeEnum.Tile, -1, Engine.TargetFlags, 0, x, y, z, itemID,
true ) );
Engine.TargetExists = false;
}
}
}