feat: 完善双版本门控、状态名单分类搜索与YesNo对话自动确认
This commit is contained in:
@@ -64,6 +64,8 @@ public sealed class Plugin : IDalamudPlugin
|
||||
private long lastRetainerActionTime;
|
||||
private long lastAutoEventFinishTime;
|
||||
private long lastTalkAdvanceTime;
|
||||
private long lastYesnoTime;
|
||||
private string statusFilterText = "";
|
||||
private uint pendingEventFinishId;
|
||||
private readonly IDisposable eventSubscription;
|
||||
|
||||
@@ -206,7 +208,11 @@ public sealed class Plugin : IDalamudPlugin
|
||||
case "retainer" or "reventure":
|
||||
ProcessRetainerAutomation();
|
||||
chat.Print("[IC Rebuild] 已尝试一键处理当前雇员探险窗口"); break;
|
||||
default: Open(); notice="用法:/icr on|off 编号;stop;pos X Y Z;ground 技能ID [target|self];finish [事件ID];retainer"; break;
|
||||
case "yes":
|
||||
ConfirmYesno(true); break;
|
||||
case "no":
|
||||
ConfirmYesno(false); break;
|
||||
default: Open(); notice="用法:/icr on|off 编号;stop;pos X Y Z;ground 技能ID [target|self];finish [事件ID];retainer;yes;no"; break;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -236,6 +242,13 @@ public sealed class Plugin : IDalamudPlugin
|
||||
var value=config.Value(feature.Id);
|
||||
if(sliders.Float(feature.Id==9 ? "预设高度偏移" : "参数",ref value,feature.Min,feature.Max)) { config.Values[feature.Id]=value; Try(Save); }
|
||||
}
|
||||
if(feature.Id==4)
|
||||
{
|
||||
if(ImGui.SmallButton("一键完全防击退 (距离与持续时间归零)##antiKnockZero"))
|
||||
{
|
||||
config.Values[4]=0; config.KnockSeconds=0; Try(Save);
|
||||
}
|
||||
}
|
||||
if(feature.Id==8) DrawStatusBlock();
|
||||
if(feature.Id==9)
|
||||
{
|
||||
@@ -254,6 +267,19 @@ public sealed class Plugin : IDalamudPlugin
|
||||
: "等待当前目标的原生半径读取。");
|
||||
ImGui.TextWrapped($"目标修改 {combat.TargetRadiusChanges} · 原生圈补偿 {combat.NativeRingBonuses} · 距离检查命中 {combat.RadiusBonuses}");
|
||||
}
|
||||
if(feature.Id==18)
|
||||
{
|
||||
ImGui.TextWrapped("结印技能(天之印、地之印、人之印)复唱归零,结印无需等待 GCD。依赖模块 17。");
|
||||
}
|
||||
if(feature.Id==20)
|
||||
{
|
||||
ImGui.Text("快速预设:"); ImGui.SameLine();
|
||||
if(ImGui.SmallButton("极限 0.5s")) { config.Values[20]=0.5f; Try(Save); }
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("平滑 0.6s")) { config.Values[20]=0.6f; Try(Save); }
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("默认 0.7s")) { config.Values[20]=0.7f; Try(Save); }
|
||||
}
|
||||
ImGui.PopID();
|
||||
}
|
||||
switch(group.Key)
|
||||
@@ -278,13 +304,58 @@ public sealed class Plugin : IDalamudPlugin
|
||||
ImGui.TextWrapped($"已选 {config.BlockedStatuses.Count} 项 · 本次启用拦截 {statusBlock.Blocked} 次 · 最近状态 ID {statusBlock.LastStatus}");
|
||||
ImGui.TextWrapped("仅屏蔽本地角色后续收到的已选状态更新;开启前已有状态须等下一次更新。默认选择 1257 强制移动,空名单不屏蔽。录像回放暂停处理。");
|
||||
ImGui.TextWrapped("关闭后恢复正常接收,已屏蔽状态须等服务端再次同步。本地处理不代表服务端状态被删除;实际移动或机制效果待实测。");
|
||||
if(!ImGui.CollapsingHeader("状态名单(已审计候选,效果待逐项确认)")) return;
|
||||
if(!ImGui.CollapsingHeader("状态名单管理(分类预设与搜索)")) return;
|
||||
|
||||
ImGui.Text("快捷预设:");
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("全选滑冰##selSlippery"))
|
||||
{
|
||||
foreach(var id in StatusCatalog.LegacySlipperyCandidates.Where(StatusCatalog.AuditedBlockCandidates.Contains))
|
||||
config.BlockedStatuses.Add(id);
|
||||
Try(Save);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("全选强制移动##selMarch"))
|
||||
{
|
||||
foreach(var id in StatusCatalog.ForcedMarch.Where(StatusCatalog.AuditedBlockCandidates.Contains))
|
||||
config.BlockedStatuses.Add(id);
|
||||
Try(Save);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("全选混乱##selConf"))
|
||||
{
|
||||
foreach(var id in StatusCatalog.Confusion.Where(StatusCatalog.AuditedBlockCandidates.Contains))
|
||||
config.BlockedStatuses.Add(id);
|
||||
Try(Save);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("全选全部候选##selAll"))
|
||||
{
|
||||
foreach(var id in StatusCatalog.AuditedBlockCandidates)
|
||||
config.BlockedStatuses.Add(id);
|
||||
Try(Save);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
if(ImGui.SmallButton("清空已选##clearStatus"))
|
||||
{
|
||||
config.BlockedStatuses.Clear();
|
||||
Try(Save);
|
||||
}
|
||||
|
||||
ImGui.InputText("搜索状态名称或 ID##statusSearch",ref statusFilterText,64);
|
||||
|
||||
var sheet=game.Data.GetExcelSheet<Lumina.Excel.Sheets.Status>();
|
||||
foreach(var id in StatusCatalog.AuditedBlockCandidates.Order())
|
||||
{
|
||||
var selected=config.BlockedStatuses.Contains(id);
|
||||
var name=sheet?.GetRowOrDefault(id)?.Name.ToString() ?? "未知状态";
|
||||
if(ImGui.Checkbox($"{id} · {name}",ref selected))
|
||||
if(!string.IsNullOrWhiteSpace(statusFilterText))
|
||||
{
|
||||
if(!id.ToString().Contains(statusFilterText,StringComparison.OrdinalIgnoreCase) &&
|
||||
!name.Contains(statusFilterText,StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
}
|
||||
var selected=config.BlockedStatuses.Contains(id);
|
||||
if(ImGui.Checkbox($"{id} · {name}##status{id}",ref selected))
|
||||
{
|
||||
if(selected) config.BlockedStatuses.Add(id); else config.BlockedStatuses.Remove(id);
|
||||
Try(Save);
|
||||
@@ -454,6 +525,13 @@ public sealed class Plugin : IDalamudPlugin
|
||||
config.FastEventFinish = fastEv;
|
||||
Try(Save);
|
||||
}
|
||||
ImGui.SameLine();
|
||||
var fastYes = config.FastSelectYesno;
|
||||
if (ImGui.Checkbox("自动确认 Yes/No 提示框 (FastSelectYesno)##fastYesno", ref fastYes))
|
||||
{
|
||||
config.FastSelectYesno = fastYes;
|
||||
Try(Save);
|
||||
}
|
||||
var evTimeStr = lastEventTime > 0 ? $"{(Environment.TickCount64 - lastEventTime) / 1000} 秒前" : "无";
|
||||
ImGui.TextWrapped($"最近捕获事件:ID 0x{lastEventId:X8} · 目标 0x{lastEventTargetId:X8} · 参数 0x{lastEventParam:X8} · 时间 {evTimeStr}");
|
||||
if (ImGui.Button("立即完成当前事件 (UP_EventFinish)")) Try(() => ExecuteEventFinish());
|
||||
@@ -579,15 +657,43 @@ public sealed class Plugin : IDalamudPlugin
|
||||
var mgr=FFXIVClientStructs.FFXIV.Client.UI.RaptureAtkUnitManager.Instance();
|
||||
if(mgr==null) return;
|
||||
var now=Environment.TickCount64;
|
||||
if(now-lastTalkAdvanceTime<250) return;
|
||||
var talk=mgr->GetAddonByName("Talk",1);
|
||||
if(talk!=null && talk->IsVisible && talk->IsReady)
|
||||
if(now-lastTalkAdvanceTime>=200)
|
||||
{
|
||||
var talk=mgr->GetAddonByName("Talk",1);
|
||||
if(talk!=null && talk->IsVisible && talk->IsReady)
|
||||
{
|
||||
var val=stackalloc FFXIVClientStructs.FFXIV.Component.GUI.AtkValue[1];
|
||||
val[0].SetInt(0);
|
||||
talk->FireCallback(1,val,true);
|
||||
lastTalkAdvanceTime=now;
|
||||
}
|
||||
}
|
||||
if(config.FastSelectYesno && now-lastYesnoTime>=300)
|
||||
{
|
||||
var yesno=mgr->GetAddonByName("SelectYesno",1);
|
||||
if(yesno!=null && yesno->IsVisible && yesno->IsReady)
|
||||
{
|
||||
var val=stackalloc FFXIVClientStructs.FFXIV.Component.GUI.AtkValue[1];
|
||||
val[0].SetInt(0);
|
||||
yesno->FireCallback(1,val,true);
|
||||
lastYesnoTime=now;
|
||||
notice="已自动确认【SelectYesno】提示框";
|
||||
}
|
||||
}
|
||||
}
|
||||
private unsafe void ConfirmYesno(bool yes)
|
||||
{
|
||||
var mgr=FFXIVClientStructs.FFXIV.Client.UI.RaptureAtkUnitManager.Instance();
|
||||
if(mgr==null) return;
|
||||
var yesno=mgr->GetAddonByName("SelectYesno",1);
|
||||
if(yesno!=null && yesno->IsVisible && yesno->IsReady)
|
||||
{
|
||||
var val=stackalloc FFXIVClientStructs.FFXIV.Component.GUI.AtkValue[1];
|
||||
val[0].SetInt(0);
|
||||
talk->FireCallback(1,val,true);
|
||||
lastTalkAdvanceTime=now;
|
||||
val[0].SetInt(yes ? 0 : 1);
|
||||
yesno->FireCallback(1,val,true);
|
||||
chat.Print($"[IC Rebuild] 已手动{(yes ? "确认(Yes)" : "取消(No)")}当前提示框");
|
||||
}
|
||||
else chat.Print("[IC Rebuild] 当前无可见的 Yes/No 提示框");
|
||||
}
|
||||
private unsafe void ProcessRetainerAutomation()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user