Skip to content

Commit

Permalink
TargetFurniture 1.0.1.4 [PUSH]
Browse files Browse the repository at this point in the history
6.2 Update
  • Loading branch information
InitialDet committed Aug 24, 2022
1 parent 096aeef commit 4dbf662
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 226 deletions.
35 changes: 19 additions & 16 deletions TargetFurniture/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,30 @@
using Dalamud.Plugin;
using System;

namespace MoveFurniture {
[Serializable]
public class Configuration : IPluginConfiguration {
public int Version { get; set; } = 1;
namespace MoveFurniture;
[Serializable]
public class Configuration : IPluginConfiguration
{
public int Version { get; set; } = 1;

public void Save() {
Service.PluginInterface!.SavePluginConfig(this);
}

public bool UseAltTarget = false;
public void Save()
{
Service.PluginInterface!.SavePluginConfig(this);
}

public bool MoveToCursor = true;
public bool UseAltTarget = false;

public static Configuration Load() {
if (Service.PluginInterface.GetPluginConfig() is Configuration config) {
return config;
}
public bool MoveToCursor = true;

config = new Configuration();
config.Save();
public static Configuration Load()
{
if (Service.PluginInterface.GetPluginConfig() is Configuration config)
{
return config;
}

config = new Configuration();
config.Save();
return config;
}
}
97 changes: 58 additions & 39 deletions TargetFurniture/ContextMenuHousing.cs
Original file line number Diff line number Diff line change
@@ -1,55 +1,74 @@
using System;
using XivCommon.Functions.ContextMenu;
using Dalamud.Logging;
using System.Threading.Tasks;
using Dalamud.ContextMenu;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;

namespace MoveFurniture {
public unsafe class ContextMenuHousing : IDisposable {
ContextMenu ContextMenu = null!;
namespace MoveFurniture;
public unsafe class ContextMenuHousing : IDisposable
{
DalamudContextMenu ContextMenu = null!;

AwaitingTarget waiting = new();
GameObjectContextMenuItem? contextMenuItem;
AwaitingTarget waiting = new();

public void Toggle() {
ContextMenu = Service.Common.Functions.ContextMenu;
ContextMenu.OpenContextMenu += OnOpenContextMenu;
}
public void Toggle()
{
ContextMenu = new DalamudContextMenu();
contextMenuItem = new GameObjectContextMenuItem(new SeString(new TextPayload("Target Item")), SetFurnitureActive, false);
ContextMenu.OnOpenGameObjectContextMenu += OnOpenContextMenu;
}

public void Dispose() {
if (ContextMenu != null)
ContextMenu.OpenContextMenu -= OnOpenContextMenu;
}
public void Dispose()
{
if (ContextMenu != null)
ContextMenu.OnOpenGameObjectContextMenu -= OnOpenContextMenu;
}

private void OnOpenContextMenu(ContextMenuOpenArgs args) {
if (args.ParentAddonName is "HousingGoods" && args.Items.Count < 3) // To make sure it doenst appear in the Stored tab
args.Items.Add(new NormalContextMenuItem("Target Item", SetFurnitureActive));
}
private void OnOpenContextMenu(GameObjectContextMenuOpenArgs args)
{

private void SetFurnitureActive(ContextMenuItemSelectedArgs args) {
if (Service.Memory.HousingStructure->Mode == HousingLayoutMode.Rotate && Service.Memory.HousingStructure->State == ItemState.SoftSelect) {
Service.Memory.SelectItem((IntPtr)Service.Memory.HousingStructure, (IntPtr)Service.Memory.HousingStructure->ActiveItem);
} else if (Service.Memory.HousingStructure->Mode == HousingLayoutMode.Move && Service.Memory.HousingStructure->State == ItemState.SoftSelect) {
if (Service.Configuration.UseAltTarget) {
Service.Memory.HousingStructure->State = ItemState.Active;
Service.Memory.HousingStructure->State2 = ItemState2.Active;
} else {
// To make the item follow the cursor you need to retarget it, for reasons idk you need a small delay before the second target for it to work
TargetItem();
if (Service.Configuration.MoveToCursor)
waiting.waitingRetarget(this);
PluginLog.Debug($"Finished");
}
}
}
if (args.ParentAddonName is "HousingGoods" && contextMenuItem != null) // To make sure it doenst appear in the Stored tab
args.AddCustomItem(contextMenuItem);
}

public void TargetItem() {
private void SetFurnitureActive(GameObjectContextMenuItemSelectedArgs args)
{
if (Service.Memory.HousingStructure->Mode == HousingLayoutMode.Rotate && Service.Memory.HousingStructure->State == ItemState.SoftSelect)
{
Service.Memory.SelectItem((IntPtr)Service.Memory.HousingStructure, (IntPtr)Service.Memory.HousingStructure->ActiveItem);
}
else if (Service.Memory.HousingStructure->Mode == HousingLayoutMode.Move && Service.Memory.HousingStructure->State == ItemState.SoftSelect)
{
if (Service.Configuration.UseAltTarget)
{
Service.Memory.HousingStructure->State = ItemState.Active;
Service.Memory.HousingStructure->State2 = ItemState2.Active;
}
else
{
// To make the item follow the cursor you need to retarget it, for reasons idk you need a small delay before the second target for it to work
TargetItem();
if (Service.Configuration.MoveToCursor)
waiting.waitingRetarget(this);
PluginLog.Debug($"Finished");
}
}
}

public class AwaitingTarget {
public async void waitingRetarget(ContextMenuHousing contextMenuHousing) {
await Task.Delay(60);
contextMenuHousing.TargetItem();
}
public void TargetItem()
{
Service.Memory.SelectItem((IntPtr)Service.Memory.HousingStructure, (IntPtr)Service.Memory.HousingStructure->ActiveItem);
}
}

public class AwaitingTarget
{
public async void waitingRetarget(ContextMenuHousing contextMenuHousing)
{
await Task.Delay(60);
contextMenuHousing.TargetItem();
}
}

134 changes: 72 additions & 62 deletions TargetFurniture/PluginMemory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,79 +3,89 @@
using System.Numerics;
using System.Runtime.InteropServices;

namespace MoveFurniture {
namespace MoveFurniture;

public class PluginMemory {
// Layout and housing module pointers.
private readonly IntPtr layoutWorldPtr;
public unsafe LayoutWorld* Layout => (LayoutWorld*)layoutWorldPtr;
public unsafe HousingStructure* HousingStructure => Layout->HousingStruct;
public class PluginMemory
{
// Layout and housing module pointers.
private readonly IntPtr layoutWorldPtr;
public unsafe LayoutWorld* Layout => (LayoutWorld*)layoutWorldPtr;
public unsafe HousingStructure* HousingStructure => Layout->HousingStruct;

// Function for selecting an item, usually used when clicking on one in game.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SelectItemDelegate(IntPtr housingStruct, IntPtr item);
public SelectItemDelegate SelectItem = null!;
// Function for selecting an item, usually used when clicking on one in game.
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void SelectItemDelegate(IntPtr housingStruct, IntPtr item);
public SelectItemDelegate SelectItem = null!;

public PluginMemory() {
try {
// Pointers for housing structures.
layoutWorldPtr = Service.SigScanner.GetStaticAddressFromSig("48 8B 0D ?? ?? ?? ?? 48 85 C9 74 ?? 48 8B 49 40 E9 ?? ?? ?? ??", 2);

// Read the pointers.
layoutWorldPtr = Marshal.ReadIntPtr(layoutWorldPtr);
public PluginMemory()
{
try
{
// Pointers for housing structures.
layoutWorldPtr = Service.SigScanner.GetStaticAddressFromSig("48 8B 0D ?? ?? ?? ?? 48 85 C9 74 ?? 48 8B 49 40 E9 ?? ?? ?? ??", 2);

// Select housing item.
IntPtr selectItemAddress = Service.SigScanner.ScanText("E8 ?? ?? ?? ?? 48 8B CE E8 ?? ?? ?? ?? 48 8B 6C 24 40 48 8B CE");
SelectItem = Marshal.GetDelegateForFunctionPointer<SelectItemDelegate>(selectItemAddress);
// Read the pointers.
layoutWorldPtr = Marshal.ReadIntPtr(layoutWorldPtr);

} catch (Exception ex) {
PluginLog.LogError(ex, "Error while calling PluginMemory.ctor()");
}
// Select housing item.
IntPtr selectItemAddress = Service.SigScanner.ScanText("E8 ?? ?? ?? ?? 48 8B CE E8 ?? ?? ?? ?? 48 8B 6C 24 40 48 8B CE");
SelectItem = Marshal.GetDelegateForFunctionPointer<SelectItemDelegate>(selectItemAddress);

}
catch (Exception ex)
{
PluginLog.LogError(ex, "Error while calling PluginMemory.ctor()");
}
}
}

public enum HousingLayoutMode {
None,
Move,
Rotate,
Store,
Place,
Remove = 6
}
public enum HousingLayoutMode
{
None,
Move,
Rotate,
Store,
Place,
Remove = 6
}

public enum ItemState {
None = 0,
Hover,
SoftSelect,
Active
}
public enum ItemState
{
None = 0,
Hover,
SoftSelect,
Active
}

public enum ItemState2 {
None = 0,
SoftSelect = 3,
Active = 5
}
public enum ItemState2
{
None = 0,
SoftSelect = 3,
Active = 5
}

[StructLayout(LayoutKind.Explicit)]
public unsafe struct LayoutWorld {
[FieldOffset(0x40)] public HousingStructure* HousingStruct;
}
[StructLayout(LayoutKind.Explicit)]
public unsafe struct LayoutWorld
{
[FieldOffset(0x40)] public HousingStructure* HousingStruct;
}

[StructLayout(LayoutKind.Explicit)]
public unsafe struct HousingStructure {
[FieldOffset(0x0)] public HousingLayoutMode Mode;
[FieldOffset(0x4)] public HousingLayoutMode LastMode;
[FieldOffset(0x8)] public ItemState State;
[FieldOffset(0xC)] public ItemState2 State2;
[FieldOffset(0x10)] public HousingItem* HoverItem;
[FieldOffset(0x18)] public HousingItem* ActiveItem;
[FieldOffset(0xB8)] public bool Rotating;
}
[StructLayout(LayoutKind.Explicit)]
public unsafe struct HousingStructure
{
[FieldOffset(0x0)] public HousingLayoutMode Mode;
[FieldOffset(0x4)] public HousingLayoutMode LastMode;
[FieldOffset(0x8)] public ItemState State;
[FieldOffset(0xC)] public ItemState2 State2;
[FieldOffset(0x10)] public HousingItem* HoverItem;
[FieldOffset(0x18)] public HousingItem* ActiveItem;
[FieldOffset(0xB8)] public bool Rotating;
}

[StructLayout(LayoutKind.Explicit)]
public unsafe struct HousingItem {
[FieldOffset(0x50)] public Vector3 Position;
[FieldOffset(0x60)] public Quaternion Rotation;
// [FieldOffset(0x90)] public HousingItemUnknown1* unknown;
}
[StructLayout(LayoutKind.Explicit)]
public unsafe struct HousingItem
{
[FieldOffset(0x50)] public Vector3 Position;
[FieldOffset(0x60)] public Quaternion Rotation;
// [FieldOffset(0x90)] public HousingItemUnknown1* unknown;
}
Loading

0 comments on commit 4dbf662

Please sign in to comment.