Compare commits
No commits in common. "7ea7c9aab19d1c3a2a06b29b087d6818f26aa387" and "0278218756f9c95ae34234f9af046a9b38d237d0" have entirely different histories.
7ea7c9aab1
...
0278218756
|
|
@ -11,7 +11,7 @@
|
||||||
1. [普通副本](https://github.com/RedAsteroid/FFXIV_Triggers/blob/main/demo/img1.md)
|
1. [普通副本](https://github.com/RedAsteroid/FFXIV_Triggers/blob/main/demo/img1.md)
|
||||||
2. [亚历山大绝境战(暂缺)](https://github.com/RedAsteroid/FFXIV_Triggers/blob/main/demo/img2.md)
|
2. [亚历山大绝境战(暂缺)](https://github.com/RedAsteroid/FFXIV_Triggers/blob/main/demo/img2.md)
|
||||||
|
|
||||||
### 零式万魔殿天狱篇施工中,预设参考请访问 [**此处**](https://github.com/RedAsteroid/FFXIV_Triggers/blob/main/src/Endwalker/9-12savage.md)
|
- 零式万魔殿天狱篇施工中,预设参考请访问 [**此处**](https://github.com/RedAsteroid/FFXIV_Triggers/blob/main/src/Endwalker/9-12savage.md)
|
||||||
|
|
||||||
## 请注意:
|
## 请注意:
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1,143 +0,0 @@
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
|
||||||
using ECommons;
|
|
||||||
using ECommons.Configuration;
|
|
||||||
using ECommons.GameHelpers;
|
|
||||||
using ECommons.Hooks;
|
|
||||||
using ECommons.ImGuiMethods;
|
|
||||||
using ECommons.Logging;
|
|
||||||
using ECommons.MathHelpers;
|
|
||||||
using ImGuiNET;
|
|
||||||
using Splatoon.SplatoonScripting;
|
|
||||||
using Splatoon.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SplatoonScriptsOfficial.Duties.Endwalker
|
|
||||||
{
|
|
||||||
public class P10S_Tethers_扇形连线 : SplatoonScript
|
|
||||||
{
|
|
||||||
public override HashSet<uint> ValidTerritories => new() { 1150 };
|
|
||||||
public override Metadata? Metadata => new(2, "NightmareXIV, RedAsteroid 修改");
|
|
||||||
List<TetherData> Tethers = new();
|
|
||||||
|
|
||||||
public class TetherData
|
|
||||||
{
|
|
||||||
public uint source;
|
|
||||||
public uint target;
|
|
||||||
public long time = Environment.TickCount64;
|
|
||||||
public float Age => (float)(Environment.TickCount64 - time) / 1000f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnSetup()
|
|
||||||
{
|
|
||||||
var code = "{\"Name\":\"\",\"type\":5,\"refX\":103.03228,\"refY\":99.94743,\"radius\":20.0,\"coneAngleMin\":-61,\"coneAngleMax\":61,\"color\":3355506687,\"FillStep\":2.0,\"includeRotation\":true,\"AdditionalRotation\":3.1415927,\"Filled\":true}";
|
|
||||||
Controller.RegisterElementFromCode("Cone1", code);
|
|
||||||
Controller.RegisterElementFromCode("Cone2", code);
|
|
||||||
Controller.RegisterElementFromCode("Tether", "{\"Name\":\"\",\"Enabled\":false,\"radius\":0.0,\"thicc\":5.0,\"tether\":true}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnEnable()
|
|
||||||
{
|
|
||||||
ActionEffect.ActionEffectEvent += ActionEffect_ActionEffectEvent;
|
|
||||||
Off();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ActionEffect_ActionEffectEvent(ECommons.Hooks.ActionEffectTypes.ActionEffectSet set)
|
|
||||||
{
|
|
||||||
if (set.Action.RowId == 33432)
|
|
||||||
{
|
|
||||||
Off();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDisable()
|
|
||||||
{
|
|
||||||
ActionEffect.ActionEffectEvent -= ActionEffect_ActionEffectEvent;
|
|
||||||
Off();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnTetherCreate(uint source, uint target, uint data2, uint data3, uint data5)
|
|
||||||
{
|
|
||||||
Tethers.Add(new() { source = source, target = target });
|
|
||||||
Tethers.RemoveAll(x => x.Age > 30f);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Off()
|
|
||||||
{
|
|
||||||
Tethers.Clear();
|
|
||||||
Controller.GetRegisteredElements().Each(x => x.Value.Enabled = false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDirectorUpdate(DirectorUpdateCategory category)
|
|
||||||
{
|
|
||||||
if (category.EqualsAny(DirectorUpdateCategory.Commence, DirectorUpdateCategory.Recommence, DirectorUpdateCategory.Wipe))
|
|
||||||
{
|
|
||||||
Off();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnSettingsDraw()
|
|
||||||
{
|
|
||||||
ImGui.ColorEdit4("自身连线 颜色", ref C.ColorSelf, ImGuiColorEditFlags.NoInputs); // Self color
|
|
||||||
ImGui.Checkbox("高亮显示自己的连线", ref C.TetherSelf); // Highlight own tether
|
|
||||||
ImGui.ColorEdit4("其他玩家连线 颜色", ref C.Color, ImGuiColorEditFlags.NoInputs); // Other player color
|
|
||||||
ImGui.SetNextItemWidth(150f);
|
|
||||||
ImGui.SliderFloat("扇形线条粗细", ref C.Thick, 1f, 10f); // Cone line thickness
|
|
||||||
ImGui.SetNextItemWidth(150f);
|
|
||||||
ImGui.SliderFloat("扇形填充步骤", ref C.Interval, 1f, 20f); // Cone fill step
|
|
||||||
ImGui.SetNextItemWidth(150f);
|
|
||||||
ImGui.SliderFloat("扇形线条长度", ref C.radius, 5f, 40f); // Cone length
|
|
||||||
if (ImGui.CollapsingHeader("debug"))
|
|
||||||
{
|
|
||||||
foreach (var x in Tethers)
|
|
||||||
{
|
|
||||||
ImGuiEx.Text($"{x.source.GetObject()}->{x.target.GetObject()}, {x.Age}s");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnUpdate()
|
|
||||||
{
|
|
||||||
int num = 1;
|
|
||||||
foreach (var x in Tethers)
|
|
||||||
{
|
|
||||||
if (x.source.TryGetObject(out var pillar) && pillar is BattleChara p && p.NameId == 12354 && x.target.TryGetObject(out var player) && player is PlayerCharacter pc && Controller.TryGetElementByName($"Cone{num}", out var e))
|
|
||||||
{
|
|
||||||
num++;
|
|
||||||
e.Enabled = true;
|
|
||||||
e.AdditionalRotation = (180 + MathHelper.GetRelativeAngle(p.Position, pc.Position)).DegreesToRadians();
|
|
||||||
e.SetRefPosition(p.Position);
|
|
||||||
e.color = C.Color.ToUint();
|
|
||||||
e.thicc = C.Thick;
|
|
||||||
e.FillStep = C.Interval;
|
|
||||||
e.radius = C.radius;
|
|
||||||
if (pc.Address == Player.Object.Address)
|
|
||||||
{
|
|
||||||
e.color = C.ColorSelf.ToUint();
|
|
||||||
if (C.TetherSelf && Controller.TryGetElementByName("Tether", out var t))
|
|
||||||
{
|
|
||||||
t.Enabled = true;
|
|
||||||
t.SetRefPosition(p.Position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Config C => Controller.GetConfig<Config>();
|
|
||||||
public class Config : IEzConfig
|
|
||||||
{
|
|
||||||
public Vector4 Color = 0xFFF700C8.SwapBytes().ToVector4();
|
|
||||||
public Vector4 ColorSelf = 0xFFAD00C8.SwapBytes().ToVector4();
|
|
||||||
public float Thick = 4f;
|
|
||||||
public float Interval = 10f;
|
|
||||||
public bool TetherSelf = true;
|
|
||||||
public float radius = 10f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,258 +0,0 @@
|
||||||
using Dalamud.Interface.Colors;
|
|
||||||
using ECommons;
|
|
||||||
using ECommons.Configuration;
|
|
||||||
using ECommons.DalamudServices;
|
|
||||||
using ECommons.GameFunctions;
|
|
||||||
using ECommons.Hooks;
|
|
||||||
using ECommons.MathHelpers;
|
|
||||||
using ECommons.Schedulers;
|
|
||||||
using Splatoon;
|
|
||||||
using ImGuiNET;
|
|
||||||
using Splatoon.SplatoonScripting;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
|
||||||
using PluginLog = ECommons.Logging.PluginLog;
|
|
||||||
|
|
||||||
namespace SplatoonScriptsOfficial.Duties.Endwalker
|
|
||||||
{
|
|
||||||
public class P12S_Caloric_Theory_热质说 : SplatoonScript
|
|
||||||
{
|
|
||||||
public override HashSet<uint> ValidTerritories => new() { 1154 };
|
|
||||||
public override Metadata? Metadata => new(1, "tatad2, RedAsteroid 修改");
|
|
||||||
|
|
||||||
private string ElementNamePrefix = "P12SCaloricTheory123";
|
|
||||||
|
|
||||||
private int closeCaloricStatusId = 3589;
|
|
||||||
private int spreadStatusId = 3591; // atmosfaction
|
|
||||||
private int stackStatusId = 3590; // entropifaction
|
|
||||||
|
|
||||||
private bool lastHasBuff = false;
|
|
||||||
|
|
||||||
// the distance player can move in one layer of close caloric buff.
|
|
||||||
// may not very accurate. 9.2 meters has been tested to be safe and 9.4 meters are unsafe, but the data may affected by server latency.
|
|
||||||
private float maxDistancePerBuff = 9.2f;
|
|
||||||
|
|
||||||
// change the color of Indicator when the remaining distance is less than this value.
|
|
||||||
// better stop moving when the color is changed.
|
|
||||||
private float changeColorDistance = 0.5f;
|
|
||||||
|
|
||||||
private float spreadRadius = 7.0f;
|
|
||||||
private float stackRadius = 4.0f;
|
|
||||||
private float distancePassed = 0;
|
|
||||||
|
|
||||||
private Vector2 lastPosition;
|
|
||||||
private int caloricTheoryCount = 0;
|
|
||||||
|
|
||||||
private Element? Indicator1;
|
|
||||||
private Element? Indicator2;
|
|
||||||
HashSet<uint> StackSpreadRecord = new HashSet<uint>();
|
|
||||||
|
|
||||||
List<TickScheduler> Sch = new List<TickScheduler>();
|
|
||||||
|
|
||||||
private bool debug = false;
|
|
||||||
Dictionary<uint, float> distanceDebug = new Dictionary<uint, float>();
|
|
||||||
Dictionary<uint, Vector2> positionDebug = new Dictionary<uint, Vector2>();
|
|
||||||
|
|
||||||
private void AddStackSpreadElement(uint objectId, bool isStack)
|
|
||||||
{
|
|
||||||
// {"Name":"","type":1,"Enabled":false,"radius":5.0,"refActorObjectID":291,"refActorComparisonType":2}
|
|
||||||
|
|
||||||
StackSpreadRecord.Add(objectId);
|
|
||||||
Element e = new Element(1);
|
|
||||||
e.refActorObjectID = objectId;
|
|
||||||
e.refActorComparisonType = 2;
|
|
||||||
e.radius = isStack ? stackRadius : spreadRadius;
|
|
||||||
e.color = isStack ? ImGuiColors.DPSRed.ToUint() : ImGuiColors.TankBlue.ToUint();
|
|
||||||
Controller.RegisterElement(ElementNamePrefix + objectId.ToString(), e, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ClearStackSpreadElements()
|
|
||||||
{
|
|
||||||
foreach(uint objectId in StackSpreadRecord)
|
|
||||||
Controller.TryUnregisterElement(ElementNamePrefix + objectId.ToString());
|
|
||||||
StackSpreadRecord.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
PluginLog.Debug("caloric theory RESET");
|
|
||||||
Sch.Each(x => x.Dispose());
|
|
||||||
Indicator1.Enabled = false;
|
|
||||||
Indicator2.Enabled = false;
|
|
||||||
lastHasBuff = false;
|
|
||||||
caloricTheoryCount = 0;
|
|
||||||
ClearStackSpreadElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnEnable()
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnSetup()
|
|
||||||
{
|
|
||||||
// {"Name":"","type":1,"radius":5.0,"refActorType":1}
|
|
||||||
|
|
||||||
Element e1 = new Element(1);
|
|
||||||
e1.refActorType = 1;
|
|
||||||
e1.Enabled = false;
|
|
||||||
Controller.RegisterElement(ElementNamePrefix + "Indicator1", e1, true);
|
|
||||||
Indicator1 = Controller.GetElementByName(ElementNamePrefix + "Indicator1");
|
|
||||||
|
|
||||||
|
|
||||||
Element e2 = new Element(1);
|
|
||||||
e2.refActorType = 1;
|
|
||||||
e2.Enabled = false;
|
|
||||||
Controller.RegisterElement(ElementNamePrefix + "Indicator2", e2, true);
|
|
||||||
Indicator2 = Controller.GetElementByName(ElementNamePrefix + "Indicator2");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnMessage(string Message)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDirectorUpdate(DirectorUpdateCategory category)
|
|
||||||
{
|
|
||||||
if (category == DirectorUpdateCategory.Commence || category == DirectorUpdateCategory.Recommence || category == DirectorUpdateCategory.Wipe)
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Init(bool isPhaseTwo)
|
|
||||||
{
|
|
||||||
Indicator1.radius = maxDistancePerBuff;
|
|
||||||
Indicator2.radius = maxDistancePerBuff * 2;
|
|
||||||
Indicator1.Enabled = true;
|
|
||||||
Indicator2.Enabled = isPhaseTwo;
|
|
||||||
Indicator1.color = ImGuiColors.HealerGreen.ToUint();
|
|
||||||
Indicator2.color = ImGuiColors.HealerGreen.ToUint();
|
|
||||||
distancePassed = 0;
|
|
||||||
//lastPosition = FakeParty.Get().First(x => x.ObjectId == 0x1017913F).Position.ToVector2();
|
|
||||||
lastPosition = Svc.ClientState.LocalPlayer.Position.ToVector2();
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
foreach (var player in FakeParty.Get())
|
|
||||||
{
|
|
||||||
distanceDebug[player.ObjectId] = 0;
|
|
||||||
positionDebug[player.ObjectId] = player.Position.ToVector2();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnUpdate()
|
|
||||||
{
|
|
||||||
bool hasBuff = Svc.ClientState.LocalPlayer.StatusList.Any(x => x.StatusId == closeCaloricStatusId);
|
|
||||||
if (hasBuff)
|
|
||||||
{
|
|
||||||
if (!lastHasBuff)
|
|
||||||
{
|
|
||||||
caloricTheoryCount++;
|
|
||||||
Init(caloricTheoryCount >= 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Vector2 Position = FakeParty.Get().First(x => x.ObjectId == 0x1017913F).Position.ToVector2();
|
|
||||||
Vector2 Position = Svc.ClientState.LocalPlayer.Position.ToVector2();
|
|
||||||
float distance = Vector2.Distance(Position, lastPosition);
|
|
||||||
//PluginLog.Information($"pos:{Position}, lastPos:{lastPosition}, dis: {distance}");
|
|
||||||
lastPosition = Position;
|
|
||||||
distancePassed += distance;
|
|
||||||
Indicator1.radius -= distance;
|
|
||||||
Indicator2.radius -= distance;
|
|
||||||
if (distancePassed >= maxDistancePerBuff - changeColorDistance)
|
|
||||||
Indicator1.color = ImGuiColors.DalamudRed.ToUint();
|
|
||||||
if (distancePassed >= maxDistancePerBuff * 2 - changeColorDistance)
|
|
||||||
Indicator2.color = ImGuiColors.DalamudRed.ToUint();
|
|
||||||
|
|
||||||
if(debug)
|
|
||||||
{
|
|
||||||
foreach (var player in FakeParty.Get())
|
|
||||||
{
|
|
||||||
Position = player.Position.ToVector2();
|
|
||||||
distance = Vector2.Distance(Position, positionDebug[player.ObjectId]);
|
|
||||||
positionDebug[player.ObjectId] = Position;
|
|
||||||
distanceDebug[player.ObjectId] += distance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastHasBuff = hasBuff;
|
|
||||||
|
|
||||||
if (Conf.StakcSpreadShowTime > 0 && Conf.StakcSpreadShowTime < 7)
|
|
||||||
{
|
|
||||||
if (Conf.DrawStack)
|
|
||||||
{
|
|
||||||
// display stack/spread range
|
|
||||||
var stackers = FakeParty.Get().Where(x => x.StatusList.Any(x => x.StatusId == stackStatusId && x.RemainingTime <= Conf.StakcSpreadShowTime));
|
|
||||||
foreach (var stacker in stackers)
|
|
||||||
{
|
|
||||||
uint objectId = stacker.ObjectId;
|
|
||||||
if (StackSpreadRecord.Contains(objectId)) continue;
|
|
||||||
AddStackSpreadElement(objectId, true);
|
|
||||||
if (StackSpreadRecord.Count == 1)
|
|
||||||
Sch.Add(new TickScheduler(ClearStackSpreadElements, Conf.StakcSpreadShowTime * 1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var spreaders = FakeParty.Get().Where(x => x.StatusList.Any(x => x.StatusId == spreadStatusId && x.RemainingTime <= Conf.StakcSpreadShowTime));
|
|
||||||
|
|
||||||
if (Conf.DrawSpread)
|
|
||||||
{
|
|
||||||
foreach (var spreader in spreaders)
|
|
||||||
{
|
|
||||||
uint objectId = spreader.ObjectId;
|
|
||||||
if (StackSpreadRecord.Contains(objectId)) continue;
|
|
||||||
AddStackSpreadElement(objectId, false);
|
|
||||||
if (StackSpreadRecord.Count == 1)
|
|
||||||
Sch.Add(new TickScheduler(ClearStackSpreadElements, Conf.StakcSpreadShowTime * 1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasBuff && lastHasBuff)
|
|
||||||
{
|
|
||||||
lastHasBuff = false;
|
|
||||||
Indicator1.Enabled = false;
|
|
||||||
Indicator2.Enabled = false;
|
|
||||||
ClearStackSpreadElements();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class Config : IEzConfig
|
|
||||||
{
|
|
||||||
public int StakcSpreadShowTime = 2;
|
|
||||||
public bool DrawStack = false;
|
|
||||||
public bool DrawSpread = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config Conf => Controller.GetConfig<Config>();
|
|
||||||
public override void OnSettingsDraw()
|
|
||||||
{
|
|
||||||
ImGui.InputInt("显示分摊/分散 AoE 范围(单位:秒,最长6秒)", ref Conf.StakcSpreadShowTime); // the time to show stack/spread aoe(seconds, max=6)
|
|
||||||
ImGui.Checkbox("启用 分摊绘制", ref Conf.DrawStack);
|
|
||||||
ImGui.Checkbox("启用 分散绘制", ref Conf.DrawSpread);
|
|
||||||
ImGui.Text("预设已有分散分摊绘制,可以不启用脚本的分散分摊绘制。");
|
|
||||||
ImGui.Text("随移动缩小的绿色圆形线为移动距离提醒,存在误差请不要卡极限距离移动。");
|
|
||||||
|
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader("Debug"))
|
|
||||||
{
|
|
||||||
ImGui.Checkbox("debug", ref debug);
|
|
||||||
ImGui.Text($"Position: {lastPosition}, distance: {distancePassed}");
|
|
||||||
ImGui.Text($"hasBuff: {lastHasBuff}");
|
|
||||||
ImGui.Text($"StackSpread buff count: {StackSpreadRecord.Count()}");
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
foreach (var player in FakeParty.Get())
|
|
||||||
{
|
|
||||||
if(distanceDebug.ContainsKey(player.ObjectId))
|
|
||||||
{
|
|
||||||
ImGui.Text($"{player.Name}, dis: {distanceDebug[player.ObjectId]}, pos: {player.Position}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,263 +0,0 @@
|
||||||
using ECommons;
|
|
||||||
using ECommons.MathHelpers;
|
|
||||||
using ECommons.DalamudServices;
|
|
||||||
using ECommons.Logging;
|
|
||||||
using Splatoon.SplatoonScripting;
|
|
||||||
using Splatoon;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
|
||||||
using ECommons.Hooks;
|
|
||||||
using ECommons.Schedulers;
|
|
||||||
using Dalamud.Interface.Colors;
|
|
||||||
using ECommons.GameFunctions;
|
|
||||||
using ECommons.Configuration;
|
|
||||||
using ECommons.ImGuiMethods;
|
|
||||||
using ImGuiNET;
|
|
||||||
|
|
||||||
namespace SplatoonScriptsOfficial.Duties.Endwalker
|
|
||||||
{
|
|
||||||
public class P12S_Classical_Concepts_元素理念 : SplatoonScript
|
|
||||||
{
|
|
||||||
public override HashSet<uint> ValidTerritories => new() { 1154 };
|
|
||||||
public override Metadata? Metadata => new(5, "tatad2");
|
|
||||||
|
|
||||||
private string ElementNamePrefix = "P12SSC";
|
|
||||||
|
|
||||||
private int cubeCount = 0;
|
|
||||||
private int[,] cube = new int[4, 3];
|
|
||||||
|
|
||||||
bool isBlinking = false;
|
|
||||||
|
|
||||||
List<TickScheduler> Schedulers = new();
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
Hide();
|
|
||||||
Schedulers.Each(x => x.Dispose());
|
|
||||||
PluginLog.Debug("classical concepts RESET");
|
|
||||||
cubeCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hide()
|
|
||||||
{
|
|
||||||
Controller.ClearRegisteredElements();
|
|
||||||
isBlinking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnEnable()
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnUpdate()
|
|
||||||
{
|
|
||||||
if(Svc.ClientState.LocalPlayer.StatusList.Any(x => x.StatusId == 3588 && x.RemainingTime < 1f))
|
|
||||||
{
|
|
||||||
Hide();
|
|
||||||
}
|
|
||||||
if (isBlinking)
|
|
||||||
{
|
|
||||||
foreach(var e in Controller.GetRegisteredElements())
|
|
||||||
{
|
|
||||||
if (e.Key.StartsWith("Red"))
|
|
||||||
{
|
|
||||||
e.Value.color = (GradientColor.Get(ImGuiColors.DalamudRed, ImGuiColors.DalamudRed / 2, 333) with { W = Conf.Trans }).ToUint();
|
|
||||||
}
|
|
||||||
if (e.Key.StartsWith("Yellow"))
|
|
||||||
{
|
|
||||||
e.Value.color = (GradientColor.Get(ImGuiColors.DalamudYellow, ImGuiColors.DalamudYellow / 2, 333) with { W = Conf.Trans }).ToUint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnMessage(string Message)
|
|
||||||
{
|
|
||||||
if (Message.EqualsAny(">33574)"))
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnDirectorUpdate(DirectorUpdateCategory category)
|
|
||||||
{
|
|
||||||
if (category == DirectorUpdateCategory.Commence || category == DirectorUpdateCategory.Recommence || category == DirectorUpdateCategory.Wipe)
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
List<(int, int)> bias = new List<(int, int)> { (1, 0), (-1, 0), (0, 1), (0, -1) };
|
|
||||||
private void DrawLines(bool swap)
|
|
||||||
{
|
|
||||||
PluginLog.Debug($"swap: {swap}");
|
|
||||||
if (swap)
|
|
||||||
{
|
|
||||||
for(int x = 0; x < 4; x ++)
|
|
||||||
{
|
|
||||||
(cube[x, 0], cube[3-x, 2]) = (cube[3-x, 2], cube[x, 0]);
|
|
||||||
if (x < 2)
|
|
||||||
(cube[x, 1], cube[3 - x, 1]) = (cube[3 - x, 1], cube[x, 1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < 3; y++)
|
|
||||||
PluginLog.Debug($"{cube[0, y]}, {cube[1, y]}, {cube[2, y]}, {cube[3, y]}");
|
|
||||||
for (int x = 0; x < 4; x++)
|
|
||||||
for (int y = 0; y < 3; y++)
|
|
||||||
{
|
|
||||||
if (cube[x, y] != 2) continue;
|
|
||||||
// blue
|
|
||||||
List<(int, int)> Red = new List<(int, int)>();
|
|
||||||
List<(int, int)> Yellow = new List<(int, int)>();
|
|
||||||
|
|
||||||
foreach((int, int) b in bias)
|
|
||||||
{
|
|
||||||
int xx = x + b.Item1;
|
|
||||||
int yy = y + b.Item2;
|
|
||||||
if (xx < 0 || xx > 3 || yy < 0 || yy > 2) continue;
|
|
||||||
if (cube[xx, yy] == 1) Red.Add((xx, yy));
|
|
||||||
if (cube[xx, yy] == 3) Yellow.Add((xx, yy));
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginLog.Debug($"(x, y): {x}, {y} redcount:{Red.Count}, yellowcount:{Yellow.Count}");
|
|
||||||
|
|
||||||
if (Red.Count == 1)
|
|
||||||
DrawLine(x, y, Red[0].Item1, Red[0].Item2, true);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int blueCount = 0;
|
|
||||||
foreach ((int, int) b in bias)
|
|
||||||
{
|
|
||||||
int xx = Red[0].Item1 + b.Item1;
|
|
||||||
int yy = Red[0].Item2 + b.Item2;
|
|
||||||
if (xx < 0 || xx > 3 || yy < 0 || yy > 2) continue;
|
|
||||||
if (cube[xx, yy] == 2) blueCount++;
|
|
||||||
}
|
|
||||||
int index = blueCount == 2 ? 1 : 0;
|
|
||||||
DrawLine(x, y, Red[index].Item1, Red[index].Item2, true);
|
|
||||||
}
|
|
||||||
if (Yellow.Count == 1)
|
|
||||||
DrawLine(x, y, Yellow[0].Item1, Yellow[0].Item2, false);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int blueCount = 0;
|
|
||||||
foreach ((int, int) b in bias)
|
|
||||||
{
|
|
||||||
int xx = Yellow[0].Item1 + b.Item1;
|
|
||||||
int yy = Yellow[0].Item2 + b.Item2;
|
|
||||||
if (xx < 0 || xx > 3 || yy < 0 || yy > 2) continue;
|
|
||||||
if (cube[xx, yy] == 2) blueCount++;
|
|
||||||
}
|
|
||||||
int index = blueCount == 2 ? 1 : 0;
|
|
||||||
DrawLine(x, y, Yellow[index].Item1, Yellow[index].Item2, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DrawLine(int x1, int y1, int x2, int y2, bool isRed)
|
|
||||||
{
|
|
||||||
//{"Name":"","type":2,"refX":88.0,"refY":92.0,"offX":96.0,"offY":92.0,"offZ":-3.8146973E-06,"radius":0.5,"refActorRequireCast":true,"refActorComparisonType":3,"includeRotation":true,"Filled":true}
|
|
||||||
|
|
||||||
PluginLog.Debug($"draw: ({x1}, {y1}) => ({x2}, {y2})");
|
|
||||||
x1 = x1 * 8 + 88;
|
|
||||||
y1 = y1 * 8 + 84;
|
|
||||||
x2 = x2 * 8 + 88;
|
|
||||||
y2 = y2 * 8 + 84;
|
|
||||||
|
|
||||||
Element e = new(2)
|
|
||||||
{
|
|
||||||
refX = x1,
|
|
||||||
refY = y1,
|
|
||||||
offX = x2,
|
|
||||||
offY = y2,
|
|
||||||
radius = Conf.LineWidth,
|
|
||||||
color = ((isRed?ImGuiColors.DalamudRed:ImGuiColors.DalamudYellow) with { W = Conf.Trans }).ToUint(),
|
|
||||||
thicc = Conf.LineThickness
|
|
||||||
};
|
|
||||||
|
|
||||||
string elementName = x1.ToString() + y1.ToString() + x2.ToString() + y2.ToString();
|
|
||||||
Controller.RegisterElement((isRed?"Red":"Yellow") + elementName, e, true);
|
|
||||||
|
|
||||||
Schedulers.Add(new TickScheduler(() =>
|
|
||||||
{
|
|
||||||
e.Enabled = false;
|
|
||||||
}, 20000));
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnObjectCreation(nint newObjectPtr)
|
|
||||||
{
|
|
||||||
Schedulers.Add(new TickScheduler(() =>
|
|
||||||
{
|
|
||||||
GameObject? obj = Svc.Objects.FirstOrDefault(x => x.Address == newObjectPtr);
|
|
||||||
if (!(obj?.DataId == 0x3F37 || obj?.DataId == 0x3F38 || obj?.DataId == 0x3F39))
|
|
||||||
return;
|
|
||||||
|
|
||||||
string color = obj.DataId == 0x3F37 ? "red" : obj.DataId == 0x3F38 ? "blue" : "yellow";
|
|
||||||
Vector2 position = obj.Position.ToVector2();
|
|
||||||
PluginLog.Debug($"cube color:{color}, position:{position.ToString()}");
|
|
||||||
|
|
||||||
int xIndex = ((int)position.X - 88) / 8;
|
|
||||||
int yIndex = ((int)position.Y - 84) / 8;
|
|
||||||
cube[xIndex, yIndex] = (int)obj.DataId - 0x3F36;
|
|
||||||
cubeCount++;
|
|
||||||
if (cubeCount == 12)
|
|
||||||
DrawLines(false);
|
|
||||||
if (cubeCount == 24)
|
|
||||||
{
|
|
||||||
if (Conf.SwapSecond)
|
|
||||||
{
|
|
||||||
if (Conf.SwapSecondDelay == 0)
|
|
||||||
{
|
|
||||||
DrawLines(true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawLines(false);
|
|
||||||
isBlinking = true;
|
|
||||||
Schedulers.Add(new TickScheduler(() =>
|
|
||||||
{
|
|
||||||
Hide();
|
|
||||||
DrawLines(true);
|
|
||||||
}, Conf.SwapSecondDelay * 1000));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DrawLines(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 100 ));
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Config : IEzConfig
|
|
||||||
{
|
|
||||||
public bool SwapSecond = true;
|
|
||||||
public int SwapSecondDelay = 0;
|
|
||||||
public float LineWidth = 0.5f;
|
|
||||||
public float LineThickness = 2f;
|
|
||||||
public float Trans = 0.3f;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config Conf => Controller.GetConfig<Config>();
|
|
||||||
|
|
||||||
public override void OnSettingsDraw()
|
|
||||||
{
|
|
||||||
ImGui.Checkbox($"第 2 次元素理念交换线条", ref Conf.SwapSecond); // Swap lines for second classical concepts
|
|
||||||
ImGui.SetNextItemWidth(100);
|
|
||||||
ImGui.InputInt("交换延迟,单位(秒)", ref Conf.SwapSecondDelay.ValidateRange(0, 15)); // Swap delay, seconds
|
|
||||||
ImGui.Separator();
|
|
||||||
ImGui.SetNextItemWidth(100);
|
|
||||||
ImGui.DragFloat("线条宽度", ref Conf.LineWidth.ValidateRange(0f, 5f), 0.01f); // Line width
|
|
||||||
ImGui.SetNextItemWidth(100);
|
|
||||||
ImGui.DragFloat("线条粗细", ref Conf.LineThickness.ValidateRange(1, 20f), 0.01f); // Line thickness
|
|
||||||
ImGui.SetNextItemWidth(100);
|
|
||||||
ImGui.DragFloat("透明度", ref Conf.Trans.ValidateRange(0.1f, 1f), 0.01f); // Transparency
|
|
||||||
if (ImGui.CollapsingHeader("Debug"))
|
|
||||||
{
|
|
||||||
ImGui.InputInt("num cubes", ref cubeCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,488 +0,0 @@
|
||||||
using System;
|
|
||||||
using Dalamud.Game.ClientState.Objects.SubKinds;
|
|
||||||
using Dalamud.Game.ClientState.Objects.Types;
|
|
||||||
using Dalamud.Game.ClientState.Statuses;
|
|
||||||
using Dalamud.Interface.Components;
|
|
||||||
using ECommons.Configuration;
|
|
||||||
using ECommons.DalamudServices;
|
|
||||||
using ECommons.GameFunctions;
|
|
||||||
using ECommons.Hooks;
|
|
||||||
using ECommons.ImGuiMethods;
|
|
||||||
using ECommons.MathHelpers;
|
|
||||||
using ECommons.Schedulers;
|
|
||||||
using ImGuiNET;
|
|
||||||
using Splatoon;
|
|
||||||
using Splatoon.SplatoonScripting;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Numerics;
|
|
||||||
using ECommons;
|
|
||||||
using ECommons.Logging;
|
|
||||||
using PluginLog = ECommons.Logging.PluginLog;
|
|
||||||
|
|
||||||
namespace SplatoonScriptsOfficial.Duties.Endwalker
|
|
||||||
{
|
|
||||||
public class P12S_Pangenesis_泛生论 : SplatoonScript
|
|
||||||
{
|
|
||||||
public enum DebuffType { None, Short_2, Long_2, One }
|
|
||||||
DebuffType MyDebuff = DebuffType.None;
|
|
||||||
|
|
||||||
public override HashSet<uint> ValidTerritories => new() { 1154 };
|
|
||||||
public override Metadata? Metadata => new(4, "tatad2-fra, RedAsteroid 修改");
|
|
||||||
|
|
||||||
private string ElementNamePrefix = "P12SSC";
|
|
||||||
private int towerCount = 0;
|
|
||||||
|
|
||||||
private int whiteTowerCast = 33603;
|
|
||||||
private int blackTowerCast = 33604;
|
|
||||||
|
|
||||||
private int whiteDebuff = 3576;
|
|
||||||
private int blackDebuff = 3577;
|
|
||||||
private int DNABuff = 3593;
|
|
||||||
|
|
||||||
private Element? Indicator;
|
|
||||||
private Element? Indicator1;
|
|
||||||
|
|
||||||
private bool directionRight = false; // 0=>left, 1=>right
|
|
||||||
private bool lastTowerBlack = false; // 0=>white, 1=>black
|
|
||||||
|
|
||||||
string TestOverride = "";
|
|
||||||
|
|
||||||
PlayerCharacter PC => TestOverride != "" && FakeParty.Get().FirstOrDefault(x => x.Name.ToString() == TestOverride) is PlayerCharacter pc ? pc : Svc.ClientState.LocalPlayer!;
|
|
||||||
|
|
||||||
public override void OnEnable()
|
|
||||||
{
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Reset()
|
|
||||||
{
|
|
||||||
PluginLog.Information("pangenesis RESET");
|
|
||||||
towerCount = 0;
|
|
||||||
Indicator.Enabled = false;
|
|
||||||
Indicator1.Enabled = false;
|
|
||||||
MyDebuff = DebuffType.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnSetup()
|
|
||||||
{
|
|
||||||
// {"Name":"","refX":100.0,"refY":95.0,"refActorDataID":16182,"refActorComparisonType":3,"tether":true}
|
|
||||||
|
|
||||||
Element e = new Element(0);
|
|
||||||
e.tether = true;
|
|
||||||
e.Enabled = false;
|
|
||||||
e.thicc = 5.0f;
|
|
||||||
e.color = 4294967295;
|
|
||||||
Controller.RegisterElement(ElementNamePrefix + "Indicator", e, true);
|
|
||||||
Indicator = Controller.GetElementByName(ElementNamePrefix + "Indicator");
|
|
||||||
|
|
||||||
Element e1 = new Element(0);
|
|
||||||
e1.tether = true;
|
|
||||||
e1.Enabled = false;
|
|
||||||
e1.thicc = 2.0f;
|
|
||||||
e1.color = 4294907904;
|
|
||||||
Controller.RegisterElement(ElementNamePrefix + "Indicator1", e1, true);
|
|
||||||
Indicator1 = Controller.GetElementByName(ElementNamePrefix + "Indicator1");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FirstTower()
|
|
||||||
{
|
|
||||||
BattleChara whiteTower = (BattleChara)Svc.Objects.First(x => x is BattleChara o && o.IsCasting == true && o.CastActionId == whiteTowerCast && o.CurrentCastTime < 1);
|
|
||||||
BattleChara blackTower = (BattleChara)Svc.Objects.First(x => x is BattleChara o && o.IsCasting == true && o.CastActionId == blackTowerCast && o.CurrentCastTime < 1);
|
|
||||||
|
|
||||||
PluginLog.Information($"tower casting time: {blackTower.CurrentCastTime}");
|
|
||||||
|
|
||||||
Vector2 whitePos = whiteTower.Position.ToVector2();
|
|
||||||
Vector2 blackPos = blackTower.Position.ToVector2();
|
|
||||||
|
|
||||||
PluginLog.Information($"wtower: {whiteTower.ObjectId}, blacktower: {blackTower.ObjectId}, casttime: {whiteTower.CurrentCastTime}, {blackTower.CurrentCastTime}, position: {whiteTower.Position.ToVector2().ToString()}, {blackTower.Position.ToVector2().ToString()}");
|
|
||||||
PluginLog.Information($"白塔: {whiteTower.ObjectId}, 黑塔: {blackTower.ObjectId}, 咏唱时间: {whiteTower.CurrentCastTime}, {blackTower.CurrentCastTime}, 位置: {whiteTower.Position.ToVector2().ToString()}, {blackTower.Position.ToVector2().ToString()}");
|
|
||||||
|
|
||||||
StatusList statusList = PC.StatusList;
|
|
||||||
if (statusList.Any(x => x.StatusId == whiteDebuff && x.RemainingTime <= 8) && !(C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// short white, go black tower
|
|
||||||
Indicator.refX = blackPos.X;
|
|
||||||
Indicator.refY = blackPos.Y;
|
|
||||||
Indicator1.refX = blackPos.X;
|
|
||||||
Indicator1.refY = blackPos.Y;
|
|
||||||
lastTowerBlack = true;
|
|
||||||
MyDebuff = DebuffType.Short_2;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == whiteDebuff && x.RemainingTime > 8) && !(C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// long white, wait
|
|
||||||
int biasX = blackPos.X < 100 ? 5 : -5;
|
|
||||||
Indicator.refX = blackPos.X + biasX;
|
|
||||||
Indicator.refY = blackPos.Y;
|
|
||||||
Indicator1.refX = blackPos.X + biasX;
|
|
||||||
Indicator1.refY = blackPos.Y;
|
|
||||||
lastTowerBlack = true;
|
|
||||||
MyDebuff = DebuffType.Long_2;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == blackDebuff && x.RemainingTime <= 8) && !(C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// short black, go white tower
|
|
||||||
Indicator.refX = whitePos.X;
|
|
||||||
Indicator.refY = whitePos.Y;
|
|
||||||
Indicator1.refX = whitePos.X;
|
|
||||||
Indicator1.refY = whitePos.Y;
|
|
||||||
lastTowerBlack = false;
|
|
||||||
MyDebuff = DebuffType.Short_2;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == blackDebuff && x.RemainingTime > 8) && !(C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// long black, wait
|
|
||||||
int biasX = whitePos.X < 100 ? 5 : -5;
|
|
||||||
Indicator.refX = whitePos.X + biasX;
|
|
||||||
Indicator.refY = whitePos.Y;
|
|
||||||
Indicator1.refX = whitePos.X + biasX;
|
|
||||||
Indicator1.refY = whitePos.Y;
|
|
||||||
lastTowerBlack = false;
|
|
||||||
MyDebuff = DebuffType.Long_2;
|
|
||||||
}
|
|
||||||
// 菓子2+0魔改
|
|
||||||
if (statusList.Any(x => x.StatusId == whiteDebuff && x.RemainingTime <= 8) && (C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// short white, go black tower
|
|
||||||
Indicator.refX = blackPos.X;
|
|
||||||
Indicator.refY = blackPos.Y - 2;
|
|
||||||
Indicator1.refX = blackPos.X;
|
|
||||||
Indicator1.refY = blackPos.Y - 2;
|
|
||||||
lastTowerBlack = true;
|
|
||||||
MyDebuff = DebuffType.Short_2;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == whiteDebuff && x.RemainingTime > 8) && (C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// long white, wait
|
|
||||||
int biasX = blackPos.X < 100 ? 5 : -5;
|
|
||||||
Indicator.refX = blackPos.X + biasX;
|
|
||||||
Indicator.refY = blackPos.Y;
|
|
||||||
Indicator1.refX = blackPos.X + biasX;
|
|
||||||
Indicator1.refY = blackPos.Y;
|
|
||||||
lastTowerBlack = true;
|
|
||||||
MyDebuff = DebuffType.Long_2;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == blackDebuff && x.RemainingTime <= 8) && (C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// short black, go white tower
|
|
||||||
Indicator.refX = whitePos.X;
|
|
||||||
Indicator.refY = whitePos.Y - 2;
|
|
||||||
Indicator1.refX = whitePos.X;
|
|
||||||
Indicator1.refY = whitePos.Y - 2;
|
|
||||||
lastTowerBlack = false;
|
|
||||||
MyDebuff = DebuffType.Short_2;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == blackDebuff && x.RemainingTime > 8) && (C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
// long black, wait
|
|
||||||
int biasX = whitePos.X < 100 ? 5 : -5;
|
|
||||||
Indicator.refX = whitePos.X + biasX;
|
|
||||||
Indicator.refY = whitePos.Y;
|
|
||||||
Indicator1.refX = whitePos.X + biasX;
|
|
||||||
Indicator1.refY = whitePos.Y;
|
|
||||||
lastTowerBlack = false;
|
|
||||||
MyDebuff = DebuffType.Long_2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (C.Strat == Strat.First_2_1)
|
|
||||||
{
|
|
||||||
if (statusList.Any(x => x.StatusId == DNABuff))
|
|
||||||
{
|
|
||||||
// 1 buff, go first tower
|
|
||||||
Indicator.refX = debuff1.IndexOf(PC) < 1 ? 85 : 115;
|
|
||||||
Indicator.refY = 91;
|
|
||||||
Indicator1.refX = debuff1.IndexOf(PC) < 1 ? 85 : 115;
|
|
||||||
Indicator1.refY = 91;
|
|
||||||
lastTowerBlack = (Indicator.refX < 100) == (blackPos.X < 100);
|
|
||||||
MyDebuff = DebuffType.One;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 0 buff, wait;
|
|
||||||
Indicator.refX = debuff0.IndexOf(PC) < 1 ? 90 : 110;
|
|
||||||
Indicator.refY = 91;
|
|
||||||
Indicator1.refX = debuff0.IndexOf(PC) < 1 ? 90 : 110;
|
|
||||||
Indicator1.refY = 91;
|
|
||||||
lastTowerBlack = (Indicator.refX < 100) != (blackPos.X < 100);
|
|
||||||
MyDebuff = DebuffType.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (C.Strat == Strat.First_2_0)
|
|
||||||
{
|
|
||||||
if (statusList.Any(x => x.StatusId == DNABuff))
|
|
||||||
{
|
|
||||||
// 1 buff, wait
|
|
||||||
Indicator.refX = PC.Position.ToVector2().X < 100 ? 90 : 110;
|
|
||||||
Indicator.refY = 91;
|
|
||||||
Indicator1.refX = PC.Position.ToVector2().X < 100 ? 90 : 110;
|
|
||||||
Indicator1.refY = 91;
|
|
||||||
lastTowerBlack = (Indicator.refX < 100) == (blackPos.X < 100);
|
|
||||||
MyDebuff = DebuffType.One;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 0 buff, go first tower;
|
|
||||||
Indicator.refX = PC.Position.ToVector2().X < 100 ? 85 : 115;
|
|
||||||
Indicator.refY = 91;
|
|
||||||
Indicator1.refX = PC.Position.ToVector2().X < 100 ? 85 : 115;
|
|
||||||
Indicator1.refY = 91;
|
|
||||||
lastTowerBlack = (Indicator.refX < 100) != (blackPos.X < 100);
|
|
||||||
MyDebuff = DebuffType.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (C.Strat == Strat.First_2_0_菓子)
|
|
||||||
{
|
|
||||||
if (statusList.Any(x => x.StatusId == DNABuff))
|
|
||||||
{
|
|
||||||
// 1 buff, go first tower
|
|
||||||
Indicator.refX = debuff1.IndexOf(PC) < 1 ? 85 : 115;
|
|
||||||
Indicator.refY = 93.5f;
|
|
||||||
Indicator1.refX = debuff1.IndexOf(PC) < 1 ? 85 : 115;
|
|
||||||
Indicator1.refY = 93.5f;
|
|
||||||
lastTowerBlack = (Indicator.refX < 100) == (blackPos.X < 100);
|
|
||||||
MyDebuff = DebuffType.One;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 0 buff, wait;
|
|
||||||
Indicator.refX = debuff0.IndexOf(PC) < 1 ? 85 : 115;
|
|
||||||
Indicator.refY = 94.5f;
|
|
||||||
Indicator1.refX = debuff0.IndexOf(PC) < 1 ? 85 : 115;
|
|
||||||
Indicator1.refY = 94.5f;
|
|
||||||
lastTowerBlack = (Indicator.refX < 100) != (blackPos.X < 100);
|
|
||||||
MyDebuff = DebuffType.None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (C.Strat == Strat.First_2_0 && MyDebuff == DebuffType.Short_2)
|
|
||||||
{
|
|
||||||
lastTowerBlack = !lastTowerBlack;
|
|
||||||
}
|
|
||||||
|
|
||||||
directionRight = (int)Indicator.refX < 100 ? false : true;
|
|
||||||
Indicator.Enabled = true;
|
|
||||||
Indicator1.Enabled = true;
|
|
||||||
|
|
||||||
PluginLog.Information($"first tower, {Indicator.refX}, {Indicator.refY}, colorBlack?: {lastTowerBlack}");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void SecondTower()
|
|
||||||
{
|
|
||||||
BattleChara whiteTower;
|
|
||||||
BattleChara blackTower;
|
|
||||||
if (directionRight)
|
|
||||||
{
|
|
||||||
// right
|
|
||||||
whiteTower = (BattleChara)Svc.Objects.First(x => x is BattleChara o && o.IsCasting == true && o.CastActionId == whiteTowerCast && o.Position.ToVector2().X > 100 && o.CurrentCastTime < 1);
|
|
||||||
blackTower = (BattleChara)Svc.Objects.First(x => x is BattleChara o && o.IsCasting == true && o.CastActionId == blackTowerCast && o.Position.ToVector2().X > 100 && o.CurrentCastTime < 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// left
|
|
||||||
whiteTower = (BattleChara)Svc.Objects.First(x => x is BattleChara o && o.IsCasting == true && o.CastActionId == whiteTowerCast && o.Position.ToVector2().X < 100 && o.CurrentCastTime < 1);
|
|
||||||
blackTower = (BattleChara)Svc.Objects.First(x => x is BattleChara o && o.IsCasting == true && o.CastActionId == blackTowerCast && o.Position.ToVector2().X < 100 && o.CurrentCastTime < 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 whitePos = whiteTower.Position.ToVector2();
|
|
||||||
Vector2 blackPos = blackTower.Position.ToVector2();
|
|
||||||
|
|
||||||
new TickScheduler(() =>
|
|
||||||
{
|
|
||||||
StatusList statusList = PC.StatusList;
|
|
||||||
if (statusList.Any(x => x.StatusId == whiteDebuff))
|
|
||||||
{
|
|
||||||
// white, go black
|
|
||||||
Indicator.refX = blackPos.X;
|
|
||||||
Indicator.refY = blackPos.Y;
|
|
||||||
Indicator1.refX = blackPos.X;
|
|
||||||
Indicator1.refY = blackPos.Y;
|
|
||||||
lastTowerBlack = true;
|
|
||||||
}
|
|
||||||
else if (statusList.Any(x => x.StatusId == blackDebuff))
|
|
||||||
{
|
|
||||||
// black, go white
|
|
||||||
Indicator.refX = whitePos.X;
|
|
||||||
Indicator.refY = whitePos.Y;
|
|
||||||
Indicator1.refX = whitePos.X;
|
|
||||||
Indicator1.refY = whitePos.Y;
|
|
||||||
lastTowerBlack = false;
|
|
||||||
}
|
|
||||||
else if (C.Strat == Strat.First_2_0_菓子)
|
|
||||||
{
|
|
||||||
Indicator.refX = lastTowerBlack ? whitePos.X : blackPos.X;
|
|
||||||
Indicator.refY = lastTowerBlack ? whitePos.Y : blackPos.Y;
|
|
||||||
Indicator1.refX = lastTowerBlack ? whitePos.X : blackPos.X;
|
|
||||||
Indicator1.refY = lastTowerBlack ? whitePos.Y : blackPos.Y;
|
|
||||||
}
|
|
||||||
else if (!(C.Strat == Strat.First_2_0_菓子))
|
|
||||||
{
|
|
||||||
Indicator.refX = lastTowerBlack ? blackPos.X : whitePos.X;
|
|
||||||
Indicator.refY = lastTowerBlack ? blackPos.Y : whitePos.Y;
|
|
||||||
Indicator1.refX = lastTowerBlack ? blackPos.X : whitePos.X;
|
|
||||||
Indicator1.refY = lastTowerBlack ? blackPos.Y : whitePos.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginLog.Information($"second/third tower, {Indicator.refX}, {Indicator.refY}");
|
|
||||||
PluginLog.Information($"第2/3次塔, {Indicator.refX}, {Indicator.refY}");
|
|
||||||
}, 1500);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThirdTower()
|
|
||||||
{
|
|
||||||
SecondTower();
|
|
||||||
new TickScheduler(() =>
|
|
||||||
{
|
|
||||||
Indicator.Enabled = false;
|
|
||||||
Indicator1.Enabled = false;
|
|
||||||
}, 6000);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnMessage(string Message)
|
|
||||||
{
|
|
||||||
if (Message.Contains("(12383>33603)") || Message.Contains("(12383>33604)"))
|
|
||||||
{
|
|
||||||
// tower appear
|
|
||||||
PluginLog.Information($"tower appear!");
|
|
||||||
towerCount++;
|
|
||||||
if (towerCount == 2)
|
|
||||||
FirstTower();
|
|
||||||
if (towerCount == 6)
|
|
||||||
SecondTower();
|
|
||||||
if (towerCount == 10)
|
|
||||||
ThirdTower();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Message.Contains("(12382>33602)"))
|
|
||||||
{
|
|
||||||
debuff1.Clear();
|
|
||||||
debuff0.Clear();
|
|
||||||
CheckBuff();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CheckBuff()
|
|
||||||
{
|
|
||||||
var Party = FakeParty.Get();
|
|
||||||
foreach (var pc in Party)
|
|
||||||
{
|
|
||||||
if (pc.StatusList.Any(x => x.StatusId == DNABuff))
|
|
||||||
{
|
|
||||||
if (pc.StatusList.Any(x => x.StatusId == DNABuff && x.StackCount == 1))
|
|
||||||
{
|
|
||||||
debuff1.Add(pc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debuff0.Add(pc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<string> order = new List<string> { C.MT, C.ST, C.H1, C.H2, C.D1, C.D2, C.D3, C.D4 };
|
|
||||||
debuff0 = debuff0.OrderBy(p => order.IndexOf(p.Name.ToString())).ToList();
|
|
||||||
debuff1 = debuff1.OrderBy(p => order.IndexOf(p.Name.ToString())).ToList();
|
|
||||||
}
|
|
||||||
public override void OnDirectorUpdate(DirectorUpdateCategory category)
|
|
||||||
{
|
|
||||||
if (category == DirectorUpdateCategory.Commence || category == DirectorUpdateCategory.Recommence)
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public override void OnSettingsDraw()
|
|
||||||
{
|
|
||||||
ImGui.SetNextItemWidth(200f);
|
|
||||||
ImGuiEx.EnumCombo("选择打法", ref C.Strat); // Select strat
|
|
||||||
ImGui.Text("使用前请在Debug2中初始化队伍,调整小队成员为正确的职能");
|
|
||||||
ImGui.Text("如果您使用菓子攻略泛生论踩塔,请务必在 \"选择打法\" 中切换!!!");
|
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader("Debug"))
|
|
||||||
{
|
|
||||||
ImGuiEx.Text($"LastTowerBlack: {lastTowerBlack}");
|
|
||||||
ImGuiEx.Text($"towerCount: {towerCount}");
|
|
||||||
ImGuiEx.Text($"MyDebuff: {MyDebuff}");
|
|
||||||
if (ImGui.Button("Reset")) Reset();
|
|
||||||
ImGui.SetNextItemWidth(200f);
|
|
||||||
ImGui.InputText("TestOverride", ref TestOverride, 50);
|
|
||||||
ImGuiEx.Text($"{PC}");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui.CollapsingHeader("Debug2"))
|
|
||||||
{
|
|
||||||
ImGui.Text("=====无debuff=====");
|
|
||||||
if (debuff0.Count >= 2)
|
|
||||||
{
|
|
||||||
ImGui.Text($"高优先级:{debuff0[0].Name}");
|
|
||||||
ImGui.Text($"低优先级:{debuff0[1].Name}");
|
|
||||||
}
|
|
||||||
ImGui.Text("=====1debuff=====");
|
|
||||||
if (debuff1.Count >= 2)
|
|
||||||
{
|
|
||||||
ImGui.Text($"高优先级:{debuff1[0].Name}");
|
|
||||||
ImGui.Text($"低优先级:{debuff1[1].Name}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DrawPartySelection("MT", ref C.MT);
|
|
||||||
DrawPartySelection("ST", ref C.ST);
|
|
||||||
DrawPartySelection("H1", ref C.H1);
|
|
||||||
DrawPartySelection("H2", ref C.H2);
|
|
||||||
DrawPartySelection("D1", ref C.D1);
|
|
||||||
DrawPartySelection("D2", ref C.D2);
|
|
||||||
DrawPartySelection("D3", ref C.D3);
|
|
||||||
DrawPartySelection("D4", ref C.D4);
|
|
||||||
if (ImGui.Button("初始化"))
|
|
||||||
{
|
|
||||||
var orderlist = FakeParty.Get();
|
|
||||||
orderlist = orderlist.OrderBy(p => desiredOrder.IndexOf(p.ClassJob.Id)).ToList();
|
|
||||||
foreach (var pc in orderlist)
|
|
||||||
{
|
|
||||||
DuoLog.Information($"{pc.ClassJob.Id}-{pc.ClassJob.GameData.Name}");
|
|
||||||
}
|
|
||||||
C.MT = orderlist.ToList()[0].Name.ToString();
|
|
||||||
C.ST = orderlist.ToList()[1].Name.ToString();
|
|
||||||
C.H1 = orderlist.ToList()[2].Name.ToString();
|
|
||||||
C.H2 = orderlist.ToList()[3].Name.ToString();
|
|
||||||
C.D1 = orderlist.ToList()[4].Name.ToString();
|
|
||||||
C.D2 = orderlist.ToList()[5].Name.ToString();
|
|
||||||
C.D3 = orderlist.ToList()[6].Name.ToString();
|
|
||||||
C.D4 = orderlist.ToList()[7].Name.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void DrawPartySelection(string label, ref string selectedParty)
|
|
||||||
{
|
|
||||||
string tempSelectedParty = selectedParty;
|
|
||||||
|
|
||||||
ImGui.Text(label);
|
|
||||||
ImGui.SameLine();
|
|
||||||
ImGui.SetNextItemWidth(120f);
|
|
||||||
if (ImGui.BeginCombo($"##partysel+{label}", tempSelectedParty))
|
|
||||||
{
|
|
||||||
FakeParty.Get().Each((x) => { if (ImGui.Selectable(x.Name.ToString())) tempSelectedParty = x.Name.ToString(); });
|
|
||||||
ImGui.EndCombo();
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedParty = tempSelectedParty;
|
|
||||||
}
|
|
||||||
public enum Strat { First_2_1, First_2_0, First_2_0_菓子 }
|
|
||||||
List<uint> desiredOrder = new List<uint> { 21, 32, 37, 19, 24, 33, 40, 28, 34, 20, 30, 22, 39, 23, 38, 31, 25, 27, 35 };
|
|
||||||
List<PlayerCharacter> debuff0 = new List<PlayerCharacter>();
|
|
||||||
List<PlayerCharacter> debuff1 = new List<PlayerCharacter>();
|
|
||||||
Config C => Controller.GetConfig<Config>();
|
|
||||||
public class Config : IEzConfig
|
|
||||||
{
|
|
||||||
public Strat Strat = Strat.First_2_1;
|
|
||||||
public string MT = String.Empty;
|
|
||||||
public string ST = String.Empty;
|
|
||||||
public string H1 = String.Empty;
|
|
||||||
public string H2 = String.Empty;
|
|
||||||
public string D1 = String.Empty;
|
|
||||||
public string D2 = String.Empty;
|
|
||||||
public string D3 = String.Empty;
|
|
||||||
public string D4 = String.Empty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue