1138 lines
38 KiB
C#
1138 lines
38 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using Decal.Interop.Core;
|
|
|
|
namespace Decal.Adapter.Wrappers;
|
|
|
|
/// <summary>
|
|
/// Provides direct access to functions and properties in the AC client.
|
|
/// </summary>
|
|
[CLSCompliant(true)]
|
|
public sealed class HooksWrapper : MarshalByRefObject, IIndexedValueProvider, IDisposable
|
|
{
|
|
private IACHooks myHooks;
|
|
|
|
private bool isDisposed;
|
|
|
|
[CLSCompliant(false)]
|
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
public IACHooks Underlying => myHooks;
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating how the player is moving an item, or 0
|
|
/// if the player is not moving an item. There are different values
|
|
/// for moving an item, combining/splitting a stack, picking
|
|
/// up/dropping an item, etc.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Here are some known values for <c>BusyState</c>:
|
|
/// <para><c>0</c>: Idle.</para>
|
|
/// <para><c>1</c>: Combining a stack.</para>
|
|
/// <para><c>2</c>: Splitting a stack.</para>
|
|
/// <para><c>3</c>: ???</para>
|
|
/// <para><c>4</c>: Picking up an item from the ground.</para>
|
|
/// <para><c>5</c>: Moving or unequipping an item.</para>
|
|
/// <para><c>6</c>: Dropping an item to the ground.</para>
|
|
/// <para><c>7</c>: Equipping an item.</para>
|
|
/// </remarks>
|
|
public int BusyState => myHooks.BusyState;
|
|
|
|
/// <summary>
|
|
/// Gets the GUID of the object that the player is moving, or 0 if the
|
|
/// player is not currently moving any object.
|
|
/// </summary>
|
|
public int BusyStateId => myHooks.BusyStateID;
|
|
|
|
/// <summary>
|
|
/// Returns <c>true</c> if the chat bar at the bottom of the screen
|
|
/// currently has keyboard focus. Doesn't apply to floating chat
|
|
/// windows.
|
|
/// </summary>
|
|
public bool ChatState => myHooks.ChatState;
|
|
|
|
/// <summary>
|
|
/// Gets a value indicating the player's combat stance.
|
|
/// <para>1 is out of combat mode;
|
|
/// 2 is melee attack mode;
|
|
/// 4 is missile attack mode;
|
|
/// 8 is magic casting mode.</para>
|
|
/// </summary>
|
|
public CombatState CombatMode => (CombatState)myHooks.CombatMode;
|
|
|
|
/// <summary>
|
|
/// Returns a pointer to the CommandInterpreter object
|
|
/// </summary>
|
|
public int CommandInterpreter => myHooks.CommandInterpreter;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the GUID of the selected item. A GUID of 0 indicates
|
|
/// no item selected.
|
|
/// </summary>
|
|
public int CurrentSelection
|
|
{
|
|
get
|
|
{
|
|
return myHooks.CurrentSelection;
|
|
}
|
|
set
|
|
{
|
|
myHooks.CurrentSelection = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the compass heading of the player (in degrees).
|
|
/// North is 0, East is 90, etc. Setting the heading will cause the
|
|
/// player to turn.
|
|
/// </summary>
|
|
public double Heading
|
|
{
|
|
get
|
|
{
|
|
return myHooks.HeadingDegrees;
|
|
}
|
|
set
|
|
{
|
|
FaceHeading(value, bUnknown: true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the compass heading of the player (in radians).
|
|
/// North is 0, East is pi/2, etc. Setting the heading will cause the
|
|
/// player to turn.
|
|
/// </summary>
|
|
public double HeadingRadians
|
|
{
|
|
get
|
|
{
|
|
return myHooks.HeadingRadians;
|
|
}
|
|
set
|
|
{
|
|
RadianFaceHeading(value, bUnknown: true);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the ID of the player's current landcell (a.k.a. landblock).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Here is a description of landblocks from
|
|
/// <a href="http://www.ugcs.caltech.edu/~dsimpson/">David Simpson's
|
|
/// Dereth Cartography</a>, from the header comment in his mapac.c
|
|
/// <blockquote>
|
|
/// The map in Asheron's Call is 254 by 254 landblocks. Each landblock contains
|
|
/// a 9 by 9 grid of data points which makes for an 8 by 8 group of land squares
|
|
/// in game. Each landblock has a unique id, which is a word in length, and
|
|
/// has the format xxyyFFFF. In game, xx is the east-west position, and yy is the
|
|
/// north-south position. Landblock 0000FFFF is located in the southwest corner of
|
|
/// the map. Use /loc to find out which landblock you are on. Each square in a
|
|
/// landblock is 0.1 wide and tall, making each landblock 0.8 by 0.8. Although
|
|
/// each landblock contains 9 by 9 points, the points on the edges are redundant
|
|
/// with adjacent landblocks. The entire map is 2041 by 2041 data points, making
|
|
/// 2040 by 2040 squares. Lastly, each square is 24.0 by 24.0 units, whatever
|
|
/// they may be.
|
|
/// </blockquote>
|
|
/// </remarks>
|
|
/// <example>
|
|
/// This example shows how to calculate coordinates from
|
|
/// <see cref="P:Decal.Adapter.Wrappers.HooksWrapper.Landcell" />, <see cref="P:Decal.Adapter.Wrappers.HooksWrapper.LocationX" />, and
|
|
/// <see cref="P:Decal.Adapter.Wrappers.HooksWrapper.LocationY" />. North and east are positive, south and
|
|
/// west are negative. Round the result to one decimal place to get
|
|
/// identical coordinates to the ones AC reports.
|
|
/// <code><![CDATA[
|
|
/// double NS = ((uint)((Host.Actions.Landcell & 0x00FF0000) / 0x2000) + Host.Actions.LocationY / 24.0 - 1019.5) / 10.0;
|
|
/// double EW = ((uint)((Host.Actions.Landcell & 0xFF000000) / 0x200000) + Host.Actions.LocationX / 24.0 - 1019.5) / 10.0;
|
|
///
|
|
/// string coords = Math.Abs(NS).ToString("0.0") + (NS >= 0 ? "N" : "S") + ", " + Math.Abs(EW).ToString("0.0") + (EW >= 0 ? "E" : "W");
|
|
/// ]]>
|
|
/// </code>
|
|
/// </example>
|
|
public int Landcell => myHooks.Landcell;
|
|
|
|
/// <summary>
|
|
/// Gets the player's X-offset within the current landcell, measured in
|
|
/// meters. On the landscape, values range from 0 (west side of
|
|
/// landcell) to 192 (east side). In dungeons, values are unbounded.
|
|
/// </summary>
|
|
public double LocationX => myHooks.LocationX;
|
|
|
|
/// <summary>
|
|
/// Gets the player's Y-offset within the current landcell, measured in
|
|
/// meters. On the landscape, values range from 0 (south side of
|
|
/// landcell) to 192 (north side). In dungeons, values are unbounded.
|
|
/// </summary>
|
|
public double LocationY => myHooks.LocationY;
|
|
|
|
/// <summary>
|
|
/// Gets the player's altitude, measured in meters. 0 is sea-level.
|
|
/// </summary>
|
|
public double LocationZ => myHooks.LocationZ;
|
|
|
|
/// <summary>
|
|
/// Gets the total number of items in the currently selected stack.
|
|
/// </summary>
|
|
public int MaxSelectedStackCount => myHooks.MaxSelectedStackCount;
|
|
|
|
/// <summary>
|
|
/// Gets the GUID of the currently opened container, such as a chest or
|
|
/// corpse. Returns 0 if no container is currently opened.
|
|
/// </summary>
|
|
public int OpenedContainer => myHooks.OpenedContainer;
|
|
|
|
/// <summary>
|
|
/// Gets the ID of the current mouse pointer graphics. This number
|
|
/// corresponds to an image in client_portal.dat.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Here are some known values of <c>PointerState</c>:
|
|
/// <para><c>0x6004D68</c>: Brown idle cursor.</para>
|
|
/// <para><c>0x6004D69</c>: Brown idle cursor with yellow outline.</para>
|
|
/// <para><c>0x6004D6A</c>: Red combat mode cursor.</para>
|
|
/// <para><c>0x6004D6B</c>: Red combat mode cursor with yellow outline.</para>
|
|
/// <para><c>0x6004D6C</c>: Blue magic mode cursor.</para>
|
|
/// <para><c>0x6004D6D</c>: Blue magic mode cursor with yellow outline.</para>
|
|
/// <para><c>0x6004D71</c>: Magnifying glass cursor.</para>
|
|
/// <para><c>0x6004D72</c>: Hand cursor.</para>
|
|
/// <para><c>0x6004D74</c>: Hour glass cursor.</para>
|
|
/// <para><c>0x6004D75</c>: Hour glass cursor with yellow outline.</para>
|
|
/// </remarks>
|
|
public int PointerState => myHooks.PointerState;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the GUID of the previously-selected item. Setting
|
|
/// this will cause the given GUID to be selected when the user
|
|
/// presses the "select previous item" key.
|
|
/// </summary>
|
|
public int PreviousSelection
|
|
{
|
|
get
|
|
{
|
|
return myHooks.PreviousSelection;
|
|
}
|
|
set
|
|
{
|
|
myHooks.PreviousSelection = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the bounding box of the 3D region in the AC window. The 3D
|
|
/// region is the area of the window where landscape and characters
|
|
/// are visible.
|
|
/// </summary>
|
|
public Rectangle Region3D
|
|
{
|
|
get
|
|
{
|
|
tagRECT aC3DRegionRect = myHooks.AC3DRegionRect;
|
|
return new Rectangle(aC3DRegionRect.left, aC3DRegionRect.top, aC3DRegionRect.right, aC3DRegionRect.bottom);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the bounding box of the entire AC window, including the 2D
|
|
/// parts of the GUI. This is the resolution set on the settings tab
|
|
/// in AC.
|
|
/// </summary>
|
|
public Rectangle RegionWindow
|
|
{
|
|
get
|
|
{
|
|
tagRECT aCWindowRect = myHooks.ACWindowRect;
|
|
return new Rectangle(aCWindowRect.left, aCWindowRect.top, aCWindowRect.right, aCWindowRect.bottom);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the number of items in the currently selected stack.
|
|
/// Must be between 1 and <see cref="P:Decal.Adapter.Wrappers.HooksWrapper.MaxSelectedStackCount" />. If
|
|
/// this is less than <see cref="P:Decal.Adapter.Wrappers.HooksWrapper.MaxSelectedStackCount" />, then
|
|
/// moving the current selection will split the stack.
|
|
/// </summary>
|
|
public int SelectedStackCount
|
|
{
|
|
get
|
|
{
|
|
return myHooks.SelectedStackCount;
|
|
}
|
|
set
|
|
{
|
|
myHooks.SelectedStackCount = value;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the GUID of the currently open vendor, or 0 if no vendor is
|
|
/// open.
|
|
/// </summary>
|
|
public int VendorId => myHooks.VendorID;
|
|
|
|
/// <summary>
|
|
/// Gets the level an attribute. "Current" values include buffs,
|
|
/// vitae, etc.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<AttributeType> Attribute => new HookIndexer<AttributeType>(this, hookIndexType.Attribute);
|
|
|
|
/// <summary>
|
|
/// Gets the number of times a attribute has been raised above its
|
|
/// starting (innate) level.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<AttributeType> AttributeClicks => new HookIndexer<AttributeType>(this, hookIndexType.AttributeClicks);
|
|
|
|
/// <summary>
|
|
/// Gets the starting (innate) level of an attribute.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<AttributeType> AttributeStart => new HookIndexer<AttributeType>(this, hookIndexType.AttributeStart);
|
|
|
|
/// <summary>
|
|
/// Gets the total amount of XP spent on an attribute.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<AttributeType> AttributeTotalXP => new HookIndexer<AttributeType>(this, hookIndexType.AttributeTotalXP);
|
|
|
|
/// <summary>
|
|
/// Gets the value of a hook by its ID.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<int> Misc => new HookIndexer<int>(this, hookIndexType.Misc);
|
|
|
|
/// <summary>
|
|
/// Gets the level a skill. "Current" values include buffs, vitae, etc.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<SkillType> Skill => new HookIndexer<SkillType>(this, hookIndexType.Skill);
|
|
|
|
/// <summary>
|
|
/// Gets the number of times a skill has been raised above the level
|
|
/// calculated from the skill's attribute formula plus free points.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<SkillType> SkillClicks => new HookIndexer<SkillType>(this, hookIndexType.SkillClicks);
|
|
|
|
/// <summary>
|
|
/// Gets the number of free points for a skill. Specialized skills
|
|
/// have 10 free points.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<SkillType> SkillFreePoints => new HookIndexer<SkillType>(this, hookIndexType.SkillFreePoints);
|
|
|
|
/// <summary>
|
|
/// Gets the total amount of XP spent on a skill.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<SkillType> SkillTotalXP => new HookIndexer<SkillType>(this, hookIndexType.SkillTotalXP);
|
|
|
|
/// <summary>
|
|
/// Gets the level to which a skill is trained.
|
|
/// <para>0 is untrained; 1 is trained; 2 is specialized.</para>
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<SkillType> SkillTrainLevel => new HookIndexer<SkillType>(this, hookIndexType.SkillTrainLevel);
|
|
|
|
/// <summary>
|
|
/// Gets the level a vital. "Current" values include buffs, vitae, etc.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<VitalType> Vital => new HookIndexer<VitalType>(this, hookIndexType.Vital);
|
|
|
|
/// <summary>
|
|
/// Gets the number of times a vital has been raised above the level
|
|
/// calculated from the vital's attribute formula.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<VitalType> VitalClicks => new HookIndexer<VitalType>(this, hookIndexType.VitalClicks);
|
|
|
|
/// <summary>
|
|
/// Gets the total amount of XP spent on a vital.
|
|
/// </summary>
|
|
[CLSCompliant(false)]
|
|
public HookIndexer<VitalType> VitalTotalXP => new HookIndexer<VitalType>(this, hookIndexType.VitalTotalXP);
|
|
|
|
internal HooksWrapper(ACHooks hooks)
|
|
{
|
|
myHooks = hooks;
|
|
}
|
|
|
|
~HooksWrapper()
|
|
{
|
|
Dispose(disposing: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Releases the resources used by this HooksWrapper. <b>No plugin or
|
|
/// filter should use this function!</b>
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Dispose(disposing: true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private void Dispose(bool disposing)
|
|
{
|
|
if (!isDisposed)
|
|
{
|
|
}
|
|
if (myHooks != null)
|
|
{
|
|
Marshal.ReleaseComObject(myHooks);
|
|
myHooks = null;
|
|
}
|
|
isDisposed = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a line of text to the default chat window for the specified
|
|
/// text color.
|
|
/// </summary>
|
|
/// <param name="text">The text to add to the chat window.</param>
|
|
/// <param name="color">The color ID of the text to add. This also
|
|
/// determines in which chat window the text will appear, as per the
|
|
/// user's chat settings.</param>
|
|
public void AddChatText(string text, int color)
|
|
{
|
|
AddChatText(text, color, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a line of text to the specified chat window.
|
|
/// </summary>
|
|
/// <param name="text">The text to add to the chat window.</param>
|
|
/// <param name="color">The color ID of the text to add.</param>
|
|
/// <param name="target">The chat window where the text will appear.
|
|
/// <para>0 is the default chat window for the given color, 1 is main
|
|
/// chat, and 2-5 are chat tabs #1-4, respectively.</para></param>
|
|
public void AddChatText(string text, int color, int target)
|
|
{
|
|
myHooks.AddChatText(text, color, target);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds text to the default chat window for the specified text color.
|
|
/// </summary>
|
|
/// <param name="text">The text to add to the chat window.</param>
|
|
/// <param name="color">The color ID of the text to add. This also
|
|
/// determines in which chat window the text will appear, as per the
|
|
/// user's chat settings.</param>
|
|
public void AddChatTextRaw(string text, int color)
|
|
{
|
|
AddChatTextRaw(text, color, 0);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds text to the specified chat window.
|
|
/// </summary>
|
|
/// <param name="text">The text to add to the chat window.</param>
|
|
/// <param name="color">The color ID of the text to add.</param>
|
|
/// <param name="target">The chat window where the text will appear.
|
|
/// <para>0 is the default chat window for the given color, 1 is main
|
|
/// chat, and 2-5 are chat tabs #1-4, respectively.</para></param>
|
|
public void AddChatTextRaw(string text, int color, int target)
|
|
{
|
|
myHooks.AddChatTextRaw(text, color, target);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a red status message to the status area at the top of the
|
|
/// screen.
|
|
/// </summary>
|
|
/// <param name="text">The status message.</param>
|
|
public void AddStatusText(string text)
|
|
{
|
|
myHooks.AddStatusText(text);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Uses one item on another (for crafting, etc.)
|
|
/// <para>This command will fail if the player is busy using an item,
|
|
/// casting a spell, etc. If you are using multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// use the next item.</para>
|
|
/// </summary>
|
|
/// <param name="useThis">The GUID of the item to use.</param>
|
|
/// <param name="onThis">The GUID of the target.</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.UseItem(System.Int32,System.Int32,System.Int32)" />
|
|
public void ApplyItem(int useThis, int onThis)
|
|
{
|
|
myHooks.ApplyItem(useThis, onThis);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts to wield an item
|
|
/// <para>This command will fail if the player is busy using an item,
|
|
/// casting a spell, etc. If you are using multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// use the next item.</para>
|
|
/// </summary>
|
|
/// <param name="item">The GUID of the item to use.</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.UseItem(System.Int32,System.Int32,System.Int32)" />
|
|
public void AutoWield(int item)
|
|
{
|
|
myHooks.AutoWield(item);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts to wield an item
|
|
/// <para>This command will fail if the player is busy using an item,
|
|
/// casting a spell, etc. If you are using multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// use the next item.</para>
|
|
/// </summary>
|
|
/// <param name="item">The GUID of the item to use.</param>
|
|
/// <param name="slot">The slot to use</param>
|
|
/// <param name="explic">1 if explicit placement, 0 if automatic placement</param>
|
|
/// <param name="notexplic">0 if explic is 1, 1 if explic is 0</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.UseItem(System.Int32,System.Int32,System.Int32)" />
|
|
public void AutoWield(int item, int slot, int explic, int notexplic)
|
|
{
|
|
myHooks.AutoWieldEx(item, slot, explic, notexplic);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts to wield an item
|
|
/// <para>This command will fail if the player is busy using an item,
|
|
/// casting a spell, etc. If you are using multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// use the next item.</para>
|
|
/// </summary>
|
|
/// <param name="item">The GUID of the item to use.</param>
|
|
/// <param name="slot">The slot to use</param>
|
|
/// <param name="explic">1 if explicit placement, 0 if automatic placement</param>
|
|
/// <param name="notexplic">0 if explic is 1, 1 if explic is 0</param>
|
|
/// <param name="zero1">Zero</param>
|
|
/// <param name="zero2">Zero</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.UseItem(System.Int32,System.Int32,System.Int32)" />
|
|
public void AutoWield(int item, int slot, int explic, int notexplic, int zero1, int zero2)
|
|
{
|
|
myHooks.AutoWieldRaw(item, slot, explic, notexplic, zero1, zero2);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Causes the player to attempt to cast a spell. The player must be
|
|
/// in spellcasting mode and the spell must be in his spellbook.
|
|
/// </summary>
|
|
/// <param name="spellId">The ID of the spell to cast.</param>
|
|
/// <param name="objectId">The GUID of the target. This is ignored for
|
|
/// non-targeted spells, such as self spells and ring spells.</param>
|
|
public void CastSpell(int spellId, int objectId)
|
|
{
|
|
myHooks.CastSpell(spellId, objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Drop an item from the player's inventory onto the ground.
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the item to drop.</param>
|
|
public void DropItem(int objectId)
|
|
{
|
|
myHooks.DropItem(objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Causes the player to turn to the specified heading.
|
|
/// </summary>
|
|
/// <param name="heading">The desired heading (in degrees).</param>
|
|
/// <param name="bUnknown">Unknown.</param>
|
|
/// <returns>Always returns <c>true</c>.</returns>
|
|
public bool FaceHeading(double heading, bool bUnknown)
|
|
{
|
|
return myHooks.FaceHeading((float)heading, bUnknown);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Causes the player to turn to the specified heading.
|
|
/// </summary>
|
|
/// <param name="heading">The desired heading (in radians).</param>
|
|
/// <param name="bUnknown">Unknown</param>
|
|
/// <returns></returns>
|
|
public bool RadianFaceHeading(double heading, bool bUnknown)
|
|
{
|
|
if (heading < 0.0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("heading");
|
|
}
|
|
if (heading > Math.PI * 10.0)
|
|
{
|
|
throw new ArgumentOutOfRangeException("heading");
|
|
}
|
|
double num = heading * 180.0 / Math.PI;
|
|
return myHooks.FaceHeading((float)num, bUnknown);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Recruit someone to your fellowship.
|
|
/// </summary>
|
|
/// <param name="lObjectID">The GUID of the character to recruit.</param>
|
|
public void FellowshipRecruit(int lObjectID)
|
|
{
|
|
myHooks.FellowshipRecruit(lObjectID);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Give fellowship leadership to a player.
|
|
/// </summary>
|
|
/// <param name="lObjectID">The GUID of the character to become the leader.</param>
|
|
public void FellowshipGrantLeader(int lObjectID)
|
|
{
|
|
myHooks.FellowshipGrantLeader(lObjectID);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Opens or closes the fellowship.
|
|
/// </summary>
|
|
/// <param name="IsOpen">True if the fellowship should be made open, false if it should be made closed.</param>
|
|
public void FellowshipSetOpen(bool IsOpen)
|
|
{
|
|
myHooks.FellowshipSetOpen(IsOpen);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Quits the current fellowship.
|
|
/// </summary>
|
|
public void FellowshipQuit()
|
|
{
|
|
myHooks.FellowshipQuit();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disbands the current fellowship.
|
|
/// </summary>
|
|
public void FellowshipDisband()
|
|
{
|
|
myHooks.FellowshipDisband();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Dismisses another player from the fellowship.
|
|
/// </summary>
|
|
/// <param name="lObjectID">The GUID of the character to remove from the fellowship.</param>
|
|
public void FellowshipDismiss(int lObjectID)
|
|
{
|
|
myHooks.FellowshipDismiss(lObjectID);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gives an object from the player's inventory to another player or
|
|
/// NPC.
|
|
/// </summary>
|
|
/// <param name="lObject">The GUID of the object to give.</param>
|
|
/// <param name="lDestination">The GUID of the player or NPC to receive
|
|
/// the object.</param>
|
|
public void GiveItem(int lObject, int lDestination)
|
|
{
|
|
myHooks.GiveItem(lObject, lDestination);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an identify-request to the end of the request queue.
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to request an ID for.</param>
|
|
public void RequestId(int objectId)
|
|
{
|
|
CoreManager.Current.IDQueue.AddToQueueForCaller(objectId, Assembly.GetCallingAssembly(), DateTime.MaxValue);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sends text to AC's chat parser as if the user had typed the text
|
|
/// into the chat bar. This text will <i>not</i> be sent to other
|
|
/// plugins via the
|
|
/// <see cref="E:Decal.Adapter.Extension.CommandLineText" /> event, so
|
|
/// this function cannot be used to send chat commands to other plugins.
|
|
/// </summary>
|
|
/// <param name="text">The text to send.</param>
|
|
public void InvokeChatParser(string text)
|
|
{
|
|
myHooks.InvokeChatParser(text);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if the AC client knows about an object GUID. The client
|
|
/// must know about an object for it to be used in other HooksWrapper
|
|
/// functions.
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to check.</param>
|
|
/// <returns><c>true</c> if the client knows about an object, or
|
|
/// <c>false</c> if not.</returns>
|
|
public bool IsValidObject(int objectId)
|
|
{
|
|
return myHooks.IsValidObject(objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Logs out the current character and returns to the character
|
|
/// selection screen.
|
|
/// </summary>
|
|
public void Logout()
|
|
{
|
|
myHooks.Logout();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Moves an item to the specified pack in the player's inventory.
|
|
/// <para>This command will fail if the player is busy moving an item,
|
|
/// casting a spell, etc. If you are moving multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// move the next item.</para>
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to move.</param>
|
|
/// <param name="packId">The GUID of the destination container.</param>
|
|
/// <param name="slot">The slot within the pack, where 0 is the first
|
|
/// slot. If this number is greater than the number of items in the
|
|
/// pack, the object will be placed in the first unused slot in the
|
|
/// pack.</param>
|
|
/// <param name="stack">A flag indicating whether to add the object to
|
|
/// a stack in the pack, if one exists.</param>
|
|
public void MoveItem(int objectId, int packId, int slot, bool stack)
|
|
{
|
|
myHooks.MoveItem(objectId, packId, slot, stack);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Moves an item to the front of the specified container. If the item
|
|
/// is not in the player's inventory, the destination must be the
|
|
/// player's main pack (the GUID of the player), or one of his side
|
|
/// packs.
|
|
/// <para>This command will fail if the player is busy moving an item,
|
|
/// casting a spell, etc. If you are moving multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// move the next item.</para>
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the item to move.</param>
|
|
/// <param name="destinationId">The GUID of the destination container.</param>
|
|
public void MoveItem(int objectId, int destinationId)
|
|
{
|
|
myHooks.MoveItemEx(objectId, destinationId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Moves an item to the specified container, with flags indicating
|
|
/// how the move should be performed.
|
|
/// <para>This command will fail if the player is busy moving an item,
|
|
/// casting a spell, etc. If you are moving multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// move the next item.</para>
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to move.</param>
|
|
/// <param name="destinationId">The GUID of the destination container.</param>
|
|
/// <param name="moveFlags">Flags indicating how the move should be
|
|
/// performed.</param>
|
|
public void MoveItem(int objectId, int destinationId, int moveFlags)
|
|
{
|
|
myHooks.MoveItemExRaw(objectId, destinationId, moveFlags);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a salvagable item to the salvage panel.
|
|
/// <para>The salvage panel does not need to be open for this command,
|
|
/// but it <i>does</i> need to be open for
|
|
/// <see cref="M:Decal.Adapter.Wrappers.HooksWrapper.SalvagePanelSalvage" />, and opening the salvage panel
|
|
/// after adding items to it will clear the panel.</para>
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to add.</param>
|
|
public void SalvagePanelAdd(int objectId)
|
|
{
|
|
myHooks.SalvagePanelAdd(objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Salvages the items in the salvage panel. The salvage panel must
|
|
/// be open.
|
|
/// </summary>
|
|
public void SalvagePanelSalvage()
|
|
{
|
|
myHooks.SalvagePanelSalvage();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Selects an item.
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to select, or 0 to
|
|
/// clear the current selection.</param>
|
|
public void SelectItem(int objectId)
|
|
{
|
|
myHooks.SelectItem(objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Turns player's autorun on or off.
|
|
/// </summary>
|
|
/// <param name="on"><c>true</c> to turn on autorun;
|
|
/// <c>false</c> to turn it off.</param>
|
|
public void SetAutorun(bool on)
|
|
{
|
|
myHooks.SetAutorun(on);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Attempts to put the player in the specified combat stance. The
|
|
/// player must be wielding the proper weapon type (melee, bow,
|
|
/// magic caster) for the given combat stance.
|
|
/// </summary>
|
|
/// <param name="newMode">The desired combat stance.
|
|
/// <para>1 is out of combat mode;
|
|
/// 2 is melee attack mode;
|
|
/// 4 is missile attack mode;
|
|
/// 8 is magic casting mode.</para></param>
|
|
public void SetCombatMode(CombatState newMode)
|
|
{
|
|
myHooks.SetCombatMode((int)newMode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Moves the mouse cursor to the given coordinates, relative to the
|
|
/// AC window.
|
|
/// </summary>
|
|
/// <param name="x">The X-coordinate.</param>
|
|
/// <param name="y">The Y-coordinate.</param>
|
|
public void SetCursorPosition(int x, int y)
|
|
{
|
|
myHooks.SetCursorPosition(x, y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the amount of time that the player can be idle (no mouse or
|
|
/// keyboard input) before AC automatically logs out. The default
|
|
/// value is 1200 seconds (20 minutes).
|
|
/// </summary>
|
|
/// <param name="timeout">The idle timeout (in seconds).</param>
|
|
public void SetIdleTime(double timeout)
|
|
{
|
|
myHooks.SetIdleTime(timeout);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds a spell to the specified tab on the player's spell bar. The
|
|
/// spell must be in the player's spell book. Each spell tab can
|
|
/// contain only one copy of each spell. Putting a spell onto a tab
|
|
/// that already contains that spell will just move the spell to the
|
|
/// new index.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This function does not always work if you call it multiple times
|
|
/// in a loop. Consider putting the loop in the
|
|
/// <see cref="E:System.Windows.Forms.Timer.Tick" /> event of a
|
|
/// <see cref="T:System.Windows.Forms.Timer" />, and then running the
|
|
/// timer for one tick.
|
|
/// </remarks>
|
|
/// <param name="tab">The zero-based tab index to add the spell.</param>
|
|
/// <param name="index">The zero-based slot on the tab to add the spell.
|
|
/// If this index is greater than the number of spells on the tab, the
|
|
/// spell will be added to the first unused slot.</param>
|
|
/// <param name="spellId">The ID of the spell to be added.</param>
|
|
public void SpellTabAdd(int tab, int index, int spellId)
|
|
{
|
|
myHooks.SpellTabAdd(tab, index, spellId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Removes a spell from the specified tab on the player's spell bar.
|
|
/// This function can safely be called multiple times in a row with no
|
|
/// time delay between calls.
|
|
/// </summary>
|
|
/// <param name="tab">The tab from which to remove the spell.</param>
|
|
/// <param name="spellId">The ID of the spell to be removed.</param>
|
|
public void SpellTabDelete(int tab, int spellId)
|
|
{
|
|
myHooks.SpellTabDelete(tab, spellId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Accepts a trade with another player.
|
|
/// </summary>
|
|
public void TradeAccept()
|
|
{
|
|
myHooks.TradeAccept();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an object to the trade window with another player. The object
|
|
/// must be in the player's inventory.
|
|
/// </summary>
|
|
/// <param name="objectId">The GUID of the object to add.</param>
|
|
public void TradeAdd(int objectId)
|
|
{
|
|
myHooks.TradeAdd(objectId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a physics object.
|
|
/// </summary>
|
|
/// <param name="objectId">The ID of the physics object.</param>
|
|
/// <returns>A pointer to a physics object.</returns>
|
|
public IntPtr PhysicsObject(int objectId)
|
|
{
|
|
return new IntPtr(myHooks.GetPhysicsObjectPtr(objectId));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a weenie object.
|
|
/// </summary>
|
|
/// <param name="objectId">The ID of the weenie object.</param>
|
|
/// <returns>A pointer to the weenie object.</returns>
|
|
public IntPtr WeenieObject(int objectId)
|
|
{
|
|
return new IntPtr(myHooks.GetWeenieObjectPtr(objectId));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Declines (un-accepts) a trade with another player.
|
|
/// </summary>
|
|
public void TradeDecline()
|
|
{
|
|
myHooks.TradeDecline();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the contents of the trade window.
|
|
/// </summary>
|
|
public void TradeReset()
|
|
{
|
|
myHooks.TradeReset();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Ends the current trade, leaving the trade window open.
|
|
/// </summary>
|
|
public void TradeEnd()
|
|
{
|
|
myHooks.TradeEnd();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a UIElement instance.
|
|
/// </summary>
|
|
/// <param name="TypeID">The TypeID of the UIElement instance.</param>
|
|
/// <returns>A pointer to the UIElement instance.</returns>
|
|
public IntPtr UIElementLookup(UIElementType pUIElementType)
|
|
{
|
|
return new IntPtr(myHooks.UIElementLookup((int)pUIElementType));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the position of a UIElement region in the AC window.
|
|
/// </summary>
|
|
/// <param name="TypeID">The TypeID of the UIElement instance.</param>
|
|
/// <param name="x">The x-axis position the UIElement instance.</param>
|
|
/// <param name="y">The y-axis position of the UIElement instance.</param>
|
|
public void UIElementMove(UIElementType pUIElementType, int x, int y)
|
|
{
|
|
myHooks.UIElementMove((int)pUIElementType, x, y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the position of a UIElement region in the AC window.
|
|
/// </summary>
|
|
/// <param name="TypeID">The TypeID of the UIElement instance.</param>
|
|
/// <param name="width">The width of the UIElement instance.</param>
|
|
/// <param name="height">The height of the UIElement instance.</param>
|
|
public void UIElementResize(UIElementType pUIElementType, int width, int height)
|
|
{
|
|
myHooks.UIElementResize((int)pUIElementType, width, height);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the bounding box of a UIElement region in the AC window.
|
|
/// </summary>
|
|
public Rectangle UIElementRegion(UIElementType pUIElementType)
|
|
{
|
|
tagRECT tagRECT = myHooks.UIElementRegionRect((int)pUIElementType);
|
|
return new Rectangle(tagRECT.left, tagRECT.top, 1 + tagRECT.right - tagRECT.left, 1 + tagRECT.bottom - tagRECT.top);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Uses an item, such as a potion, healing kit, etc.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This command will fail if the player is busy using an item,
|
|
/// casting a spell, etc. If you are using multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// use the next item.
|
|
/// </remarks>
|
|
/// <param name="objectId">The GUID of the item to use.</param>
|
|
/// <param name="useState">The purpose of this argument is not
|
|
/// entirely known. Valid values appear to be 0 and 1: 0 uses
|
|
/// an item by itself (like a potion); 1 uses an item on the current
|
|
/// selection.</param>
|
|
public void UseItem(int objectId, int useState)
|
|
{
|
|
myHooks.UseItem(objectId, useState);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Uses an item, such as a potion, healing kit, casts the spell on a
|
|
/// wand/orb, etc.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// This command will fail if the player is busy using an item,
|
|
/// casting a spell, etc. If you are using multiple items, you must
|
|
/// wait until the previous action is complete before attempting to
|
|
/// use the next item.
|
|
/// </remarks>
|
|
/// <param name="objectId">The GUID of the item to use.</param>
|
|
/// <param name="useState">The purpose of this argument is not
|
|
/// entirely known. Valid values appear to be 0 and 1: 0 uses
|
|
/// an item by itself (like a potion); 1 uses an item on the current
|
|
/// selection.</param>
|
|
/// <param name="useMethod">The purpose of this argument is not
|
|
/// entirely known. It may be a target GUID for wand/orb spells, or
|
|
/// some other flag</param>
|
|
public void UseItem(int objectId, int useState, int useMethod)
|
|
{
|
|
myHooks.UseItemRaw(objectId, useState, useMethod);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Buys all of the items in the buy-list. The player must have
|
|
/// enough pyreals and slots in the main pack to hold all of the items
|
|
/// being bought.
|
|
/// </summary>
|
|
public void VendorBuyAll()
|
|
{
|
|
myHooks.VendorBuyAll();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an item to the list of things to buy from a vendor. A vendor
|
|
/// window must be open to use this command.
|
|
/// </summary>
|
|
/// <param name="templateId">The GUID of the item template or item in
|
|
/// the vendor's inventory. Templates are the generic items sold by
|
|
/// vendors, such as spell components or trade notes.</param>
|
|
/// <param name="count">The number of the specified item to add to the
|
|
/// buy-list.</param>
|
|
public void VendorAddBuyList(int templateId, int count)
|
|
{
|
|
myHooks.VendorBuyListAdd(templateId, count);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the buy-list.
|
|
/// </summary>
|
|
public void VendorClearBuyList()
|
|
{
|
|
myHooks.VendorBuyListClear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sells all of the items in the sell-list. The player must have
|
|
/// enough slots in the main pack to hold all of the stacks of pyreals
|
|
/// obtained from the sale.
|
|
/// </summary>
|
|
public void VendorSellAll()
|
|
{
|
|
myHooks.VendorSellAll();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds an item to the list of things to sell to a vendor. A vendor
|
|
/// window must be open, and the item must be in the player's inventory.
|
|
/// </summary>
|
|
/// <param name="itemId">The GUID of the item to add to the sell-list.</param>
|
|
public void VendorAddSellList(int itemId)
|
|
{
|
|
myHooks.VendorSellListAdd(itemId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Clears the sell-list.
|
|
/// </summary>
|
|
public void VendorClearSellList()
|
|
{
|
|
myHooks.VendorSellListClear();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spends experience points on a skill.
|
|
/// </summary>
|
|
/// <param name="skill">The skill to raise.</param>
|
|
/// <param name="experience">The number of experience points to spend.
|
|
/// Cannot be more than the player's unspent experience.</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.AddAttributeExperience(Decal.Adapter.Wrappers.AttributeType,System.Int32)" />
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.AddVitalExperience(Decal.Adapter.Wrappers.VitalType,System.Int32)" />
|
|
public void AddSkillExperience(SkillType skill, int experience)
|
|
{
|
|
myHooks.AddSkillExp((eSkill)skill, experience);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spends experience points on an attribute.
|
|
/// </summary>
|
|
/// <param name="attrib">The attribute to raise.</param>
|
|
/// <param name="experience">The number of experience points to spend.
|
|
/// Cannot be more than the player's unspent experience.</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.AddSkillExperience(Decal.Adapter.Wrappers.SkillType,System.Int32)" />
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.AddVitalExperience(Decal.Adapter.Wrappers.VitalType,System.Int32)" />
|
|
public void AddAttributeExperience(AttributeType attrib, int experience)
|
|
{
|
|
myHooks.AddAttributeExp((eAttribute)attrib, experience);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Spends experience points on a vital.
|
|
/// </summary>
|
|
/// <param name="vital">The vital to raise.</param>
|
|
/// <param name="experience">The number of experience points to spend.
|
|
/// Cannot be more than the player's unspent experience.</param>
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.AddAttributeExperience(Decal.Adapter.Wrappers.AttributeType,System.Int32)" />
|
|
/// <seealso cref="M:Decal.Adapter.Wrappers.HooksWrapper.AddSkillExperience(Decal.Adapter.Wrappers.SkillType,System.Int32)" />
|
|
public void AddVitalExperience(VitalType vital, int experience)
|
|
{
|
|
myHooks.AddVitalExp((eVital)vital, experience);
|
|
}
|
|
|
|
int IIndexedValueProvider.GetIndexedObject(hookIndexType index, int item)
|
|
{
|
|
int result = 0;
|
|
switch (index)
|
|
{
|
|
case hookIndexType.Attribute:
|
|
result = myHooks.get_Attribute(item);
|
|
break;
|
|
case hookIndexType.AttributeClicks:
|
|
result = myHooks.get_AttributeClicks((eAttribute)item);
|
|
break;
|
|
case hookIndexType.AttributeStart:
|
|
result = myHooks.get_AttributeStart((eAttribute)item);
|
|
break;
|
|
case hookIndexType.AttributeTotalXP:
|
|
result = myHooks.get_AttributeTotalXP((eAttribute)item);
|
|
break;
|
|
case hookIndexType.Skill:
|
|
result = myHooks.get_Skill(item);
|
|
break;
|
|
case hookIndexType.SkillClicks:
|
|
result = myHooks.get_SkillClicks((eSkill)item);
|
|
break;
|
|
case hookIndexType.SkillFreePoints:
|
|
result = myHooks.get_SkillFreePoints((eSkill)item);
|
|
break;
|
|
case hookIndexType.SkillTotalXP:
|
|
result = myHooks.get_SkillTotalXP((eSkill)item);
|
|
break;
|
|
case hookIndexType.SkillTrainLevel:
|
|
result = (int)myHooks.get_SkillTrainLevel((eSkill)item);
|
|
break;
|
|
case hookIndexType.Vital:
|
|
result = myHooks.get_Vital(item);
|
|
break;
|
|
case hookIndexType.VitalClicks:
|
|
result = myHooks.get_VitalClicks((eVital)item);
|
|
break;
|
|
case hookIndexType.VitalTotalXP:
|
|
result = myHooks.get_VitalTotalXP((eVital)item);
|
|
break;
|
|
case hookIndexType.Misc:
|
|
result = myHooks.get_Misc(item);
|
|
break;
|
|
}
|
|
return result;
|
|
}
|
|
}
|