2022-09-06 07:37:03 +00:00
|
|
|
using System.Numerics;
|
2022-09-04 05:03:59 +00:00
|
|
|
using System.Text;
|
2022-09-04 22:19:16 +00:00
|
|
|
using Dalamud.Game.ClientState.Conditions;
|
2024-07-22 07:44:30 +00:00
|
|
|
using Dalamud.Game.ClientState.Objects.SubKinds;
|
2024-07-01 15:10:41 +00:00
|
|
|
using Dalamud.Interface.Textures;
|
2024-07-22 09:49:51 +00:00
|
|
|
using Dalamud.Interface.Utility;
|
2024-07-22 07:44:30 +00:00
|
|
|
using Dalamud.Utility;
|
|
|
|
using FFXIVClientStructs.FFXIV.Client.Game.Character;
|
|
|
|
using FFXIVClientStructs.FFXIV.Client.Game.Object;
|
|
|
|
using FFXIVClientStructs.FFXIV.Client.Game.UI;
|
2022-09-04 05:03:59 +00:00
|
|
|
using ImGuiNET;
|
2024-07-22 07:44:30 +00:00
|
|
|
using Lumina.Excel.GeneratedSheets;
|
2022-09-04 05:03:59 +00:00
|
|
|
using Newtonsoft.Json;
|
|
|
|
using OrangeGuidanceTomestone.Helpers;
|
2024-06-16 19:28:34 +00:00
|
|
|
using OrangeGuidanceTomestone.Util;
|
2022-09-04 05:03:59 +00:00
|
|
|
|
|
|
|
namespace OrangeGuidanceTomestone.Ui.MainWindowTabs;
|
|
|
|
|
|
|
|
internal class Write : ITab {
|
|
|
|
public string Name => "Write";
|
|
|
|
|
|
|
|
private Plugin Plugin { get; }
|
|
|
|
|
|
|
|
private int _pack;
|
|
|
|
private int _part1 = -1;
|
|
|
|
private (int, int) _word1 = (-1, -1);
|
|
|
|
private int _conj = -1;
|
|
|
|
private int _part2 = -1;
|
|
|
|
private (int, int) _word2 = (-1, -1);
|
2022-09-06 04:24:32 +00:00
|
|
|
private int _glyph;
|
2024-07-22 07:44:30 +00:00
|
|
|
private int _emoteIdx = -1;
|
2024-07-22 17:31:44 +00:00
|
|
|
|
|
|
|
private string _word1Search = string.Empty;
|
|
|
|
private string _word2Search = string.Empty;
|
2024-07-22 09:49:51 +00:00
|
|
|
private string _emoteSearch = string.Empty;
|
2022-09-04 05:03:59 +00:00
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
private const string Placeholder = "****";
|
|
|
|
private Pack? Pack => Pack.All.Get(this._pack);
|
|
|
|
private Template? Template1 => this.Pack?.Templates.Get(this._part1);
|
|
|
|
private Template? Template2 => this.Pack?.Templates.Get(this._part2);
|
|
|
|
private string? Word1 => this.GetWord(this._word1, this.Template1);
|
|
|
|
private string? Word2 => this.GetWord(this._word2, this.Template2);
|
|
|
|
private string? Conjunction => this.Pack?.Conjunctions?.Get(this._conj);
|
|
|
|
|
2024-07-22 07:44:30 +00:00
|
|
|
private List<Emote> Emotes { get; }
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
private string? GetWord((int, int) word, Template? template) {
|
|
|
|
if (word.Item2 == -1) {
|
|
|
|
return Placeholder;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (template == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (template.Words == null) {
|
|
|
|
if (word.Item1 == -1) {
|
|
|
|
return Placeholder;
|
|
|
|
}
|
|
|
|
|
|
|
|
var pack = this.Pack;
|
|
|
|
if (pack?.Words == null) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pack.Words.Get(word.Item1)?.Words.Get(word.Item2);
|
|
|
|
}
|
|
|
|
|
|
|
|
return template.Words.Get(word.Item2);
|
|
|
|
}
|
|
|
|
|
2022-09-04 05:03:59 +00:00
|
|
|
internal Write(Plugin plugin) {
|
|
|
|
this.Plugin = plugin;
|
2022-09-06 07:57:38 +00:00
|
|
|
|
2024-07-22 17:31:44 +00:00
|
|
|
this.Emotes = [
|
|
|
|
.. this.Plugin.DataManager.GetExcelSheet<Emote>()!
|
|
|
|
.Skip(1)
|
|
|
|
.Where(emote => emote.TextCommand.Row != 0)
|
|
|
|
.OrderBy(emote => emote.Order)
|
|
|
|
];
|
2024-07-22 07:44:30 +00:00
|
|
|
|
2022-09-06 07:57:38 +00:00
|
|
|
this._glyph = this.Plugin.Config.DefaultGlyph;
|
2022-09-08 03:13:55 +00:00
|
|
|
Pack.UpdatePacks();
|
2022-09-06 07:37:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Dispose() {
|
2024-07-01 15:10:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private ISharedImmediateTexture GetGlyphImage(int i) {
|
|
|
|
return this.Plugin.TextureProvider.GetFromManifestResource(
|
|
|
|
typeof(Plugin).Assembly,
|
|
|
|
$"OrangeGuidanceTomestone.img.sign_{i}.jpg"
|
|
|
|
);
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Draw() {
|
2022-09-08 03:13:55 +00:00
|
|
|
Pack.AllMutex.Wait();
|
|
|
|
|
|
|
|
try {
|
|
|
|
this.DrawInner();
|
|
|
|
} finally {
|
|
|
|
Pack.AllMutex.Release();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void DrawInner() {
|
|
|
|
if (Pack.All.Length == 0) {
|
|
|
|
ImGui.TextUnformatted("Please refresh the packs from the settings.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._pack < 0 || this._pack >= Pack.All.Length) {
|
|
|
|
this._pack = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
var packPrev = Pack.All[this._pack].Name;
|
2022-09-04 05:03:59 +00:00
|
|
|
if (ImGui.BeginCombo("Pack", packPrev)) {
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endCombo = new OnDispose(ImGui.EndCombo);
|
|
|
|
|
2022-09-08 03:13:55 +00:00
|
|
|
for (var i = 0; i < Pack.All.Length; i++) {
|
|
|
|
var selPack = Pack.All[i];
|
2022-09-04 05:03:59 +00:00
|
|
|
if (!ImGui.Selectable(selPack.Name)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
this._pack = i;
|
|
|
|
this.ResetWriter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const string placeholder = "****";
|
|
|
|
|
2024-06-16 19:38:43 +00:00
|
|
|
bool DrawPicker(string id, IReadOnlyList<string> items, ref int x) {
|
2022-09-04 05:03:59 +00:00
|
|
|
var preview = x == -1 ? "" : items[x].Replace("{0}", placeholder);
|
|
|
|
if (!ImGui.BeginCombo(id, preview)) {
|
2024-06-16 19:38:43 +00:00
|
|
|
return false;
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endCombo = new OnDispose(ImGui.EndCombo);
|
|
|
|
|
2024-06-16 19:38:43 +00:00
|
|
|
var changed = false;
|
2022-09-04 05:03:59 +00:00
|
|
|
if (ImGui.Selectable("<none>")) {
|
|
|
|
x = -1;
|
2024-06-16 19:38:43 +00:00
|
|
|
changed = true;
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < items.Count; i++) {
|
|
|
|
var template = items[i].Replace("{0}", placeholder);
|
2024-06-16 19:38:43 +00:00
|
|
|
if (!ImGui.Selectable(template, i == x)) {
|
|
|
|
continue;
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
2024-06-16 19:38:43 +00:00
|
|
|
|
|
|
|
x = i;
|
|
|
|
changed = true;
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
2024-06-16 19:38:43 +00:00
|
|
|
|
|
|
|
return changed;
|
2024-06-16 19:28:34 +00:00
|
|
|
}
|
2022-09-04 05:03:59 +00:00
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
void DrawTemplatePicker(string id, IReadOnlyList<string> items, ref int x, ref (int, int) word) {
|
2024-06-16 19:38:43 +00:00
|
|
|
var wasAdvanced = this.Pack?.Templates.Get(x)?.Words != null;
|
|
|
|
|
|
|
|
var changed = DrawPicker(id, items, ref x);
|
|
|
|
if (changed && wasAdvanced) {
|
2024-06-16 19:28:34 +00:00
|
|
|
word = (-1, -1);
|
|
|
|
}
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
|
2024-07-22 17:31:44 +00:00
|
|
|
void DrawSpecificWordPicker(string id, Template template, ref (int, int) x, ref string search) {
|
2024-06-16 19:28:34 +00:00
|
|
|
if (template.Words == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-06-15 22:42:22 +00:00
|
|
|
var preview = x == (-1, -1) ? "" : template.Words[x.Item2];
|
|
|
|
if (!ImGui.BeginCombo(id, preview)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-07-22 17:31:44 +00:00
|
|
|
using var endCombo = new OnDispose(ImGui.EndCombo);
|
|
|
|
|
2024-06-15 22:42:22 +00:00
|
|
|
for (var wordIdx = 0; wordIdx < template.Words.Length; wordIdx++) {
|
2024-07-22 17:31:44 +00:00
|
|
|
var word = template.Words[wordIdx];
|
|
|
|
if (!string.IsNullOrEmpty(search) && !word.Contains(search, StringComparison.InvariantCultureIgnoreCase)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui.Selectable(word, x == (-1, wordIdx))) {
|
2024-06-15 22:42:22 +00:00
|
|
|
x = (-1, wordIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-22 17:31:44 +00:00
|
|
|
void DrawWordPicker(string id, IReadOnlyList<WordList> words, ref (int, int) x, ref string search) {
|
2022-09-04 05:03:59 +00:00
|
|
|
var preview = x == (-1, -1) ? "" : words[x.Item1].Words[x.Item2];
|
|
|
|
if (!ImGui.BeginCombo(id, preview)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endCombo = new OnDispose(ImGui.EndCombo);
|
|
|
|
|
2022-09-04 05:03:59 +00:00
|
|
|
for (var listIdx = 0; listIdx < words.Count; listIdx++) {
|
|
|
|
var list = words[listIdx];
|
|
|
|
if (!ImGui.BeginMenu(list.Name)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endMenu = new OnDispose(ImGui.EndMenu);
|
|
|
|
|
2024-07-22 17:31:44 +00:00
|
|
|
ImGui.InputText("###word-search", ref search, 100);
|
|
|
|
|
2022-09-04 05:03:59 +00:00
|
|
|
for (var wordIdx = 0; wordIdx < list.Words.Length; wordIdx++) {
|
2024-07-22 17:31:44 +00:00
|
|
|
var word = list.Words[wordIdx];
|
|
|
|
if (!string.IsNullOrEmpty(search) && !word.Contains(search, StringComparison.InvariantCultureIgnoreCase)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui.MenuItem(word)) {
|
2022-09-04 05:03:59 +00:00
|
|
|
x = (listIdx, wordIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-08 03:13:55 +00:00
|
|
|
var pack = Pack.All[this._pack];
|
2022-09-04 05:03:59 +00:00
|
|
|
|
2022-09-06 07:46:21 +00:00
|
|
|
var lineHeight = ImGui.CalcTextSize("A").Y;
|
|
|
|
var imageHeight = lineHeight * 4;
|
|
|
|
|
2022-09-04 05:03:59 +00:00
|
|
|
var actualText = string.Empty;
|
|
|
|
|
2022-09-06 07:49:34 +00:00
|
|
|
if (ImGui.BeginTable("##message-preview", 2)) {
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endTable = new OnDispose(ImGui.EndTable);
|
|
|
|
|
2022-09-06 07:49:34 +00:00
|
|
|
ImGui.TableSetupColumn("##image", ImGuiTableColumnFlags.WidthFixed);
|
|
|
|
ImGui.TableSetupColumn("##message", ImGuiTableColumnFlags.WidthStretch);
|
|
|
|
ImGui.TableNextRow();
|
|
|
|
|
|
|
|
if (ImGui.TableSetColumnIndex(0)) {
|
2024-07-01 15:10:41 +00:00
|
|
|
var glyphImage = this.GetGlyphImage(this._glyph);
|
|
|
|
var wrap = glyphImage.GetWrapOrEmpty();
|
|
|
|
ImGui.Image(wrap.ImGuiHandle, new Vector2(imageHeight));
|
2022-09-06 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui.TableSetColumnIndex(1) && this._part1 != -1) {
|
|
|
|
var preview = new StringBuilder();
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
var word1 = this.Word1;
|
|
|
|
if (this.Template1 is { } template1Preview && word1 != null) {
|
|
|
|
preview.Append(string.Format(template1Preview.Text, word1));
|
|
|
|
}
|
2022-09-06 07:49:34 +00:00
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
if (this.Conjunction is { } conj) {
|
|
|
|
var isPunc = conj.Length == 1 && char.IsPunctuation(conj[0]);
|
2022-09-06 07:49:34 +00:00
|
|
|
if (isPunc) {
|
|
|
|
preview.Append(conj);
|
|
|
|
preview.Append('\n');
|
|
|
|
} else {
|
|
|
|
preview.Append('\n');
|
|
|
|
preview.Append(conj);
|
|
|
|
preview.Append(' ');
|
|
|
|
}
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
var word2 = this.Word2;
|
|
|
|
if (this.Template2 is { } template2Preview && word2 != null) {
|
|
|
|
preview.Append(string.Format(template2Preview.Text, word2));
|
2022-09-06 07:49:34 +00:00
|
|
|
}
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
2022-09-06 07:49:34 +00:00
|
|
|
|
|
|
|
actualText = preview.ToString();
|
|
|
|
var actualSize = ImGui.CalcTextSize(actualText);
|
2022-09-06 07:59:39 +00:00
|
|
|
ImGui.Dummy(new Vector2(1, imageHeight / 2 - actualSize.Y / 2 - ImGui.GetStyle().ItemSpacing.Y));
|
2022-09-06 07:49:34 +00:00
|
|
|
ImGui.TextUnformatted(actualText);
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui.Separator();
|
|
|
|
|
2024-06-15 22:42:22 +00:00
|
|
|
var templateStrings = pack.Templates
|
2024-06-16 19:28:34 +00:00
|
|
|
.Select(template => template.Text)
|
2024-06-15 22:42:22 +00:00
|
|
|
.ToArray();
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
DrawTemplatePicker("Template##part-1", templateStrings, ref this._part1, ref this._word1);
|
|
|
|
if (this.Template1 is { } template1 && template1.Text.Contains("{0}")) {
|
|
|
|
if (template1.Words == null && pack.Words != null) {
|
2024-07-22 17:31:44 +00:00
|
|
|
DrawWordPicker("Word##word-1", pack.Words, ref this._word1, ref this._word1Search);
|
2024-06-16 19:28:34 +00:00
|
|
|
} else if (template1.Words != null) {
|
2024-07-22 17:31:44 +00:00
|
|
|
DrawSpecificWordPicker("Word##word-1", template1, ref this._word1, ref this._word1Search);
|
2024-06-15 22:42:22 +00:00
|
|
|
}
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
|
2024-06-15 22:42:22 +00:00
|
|
|
if (pack.Conjunctions != null) {
|
|
|
|
DrawPicker("Conjunction##conj", pack.Conjunctions, ref this._conj);
|
|
|
|
}
|
2022-09-04 05:03:59 +00:00
|
|
|
|
|
|
|
if (this._conj != -1) {
|
2024-06-16 19:28:34 +00:00
|
|
|
DrawTemplatePicker("Template##part-2", templateStrings, ref this._part2, ref this._word2);
|
|
|
|
if (this.Template1 is { } template2 && template2.Text.Contains("{0}")) {
|
|
|
|
if (template2.Words == null && pack.Words != null) {
|
2024-07-22 17:31:44 +00:00
|
|
|
DrawWordPicker("Word##word-2", pack.Words, ref this._word2, ref this._word2Search);
|
2024-06-16 19:28:34 +00:00
|
|
|
} else if (template2.Words != null) {
|
2024-07-22 17:31:44 +00:00
|
|
|
DrawSpecificWordPicker("Word##word-2", template2, ref this._word2, ref this._word2Search);
|
2024-06-15 22:42:22 +00:00
|
|
|
}
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-06 07:59:39 +00:00
|
|
|
if (ImGui.BeginCombo("Glyph", $"{this._glyph + 1}")) {
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endCombo = new OnDispose(ImGui.EndCombo);
|
2022-09-06 07:57:38 +00:00
|
|
|
var tooltipShown = false;
|
|
|
|
|
2022-09-09 09:35:10 +00:00
|
|
|
for (var i = 0; i < Messages.VfxPaths.Length; i++) {
|
2022-09-06 07:37:03 +00:00
|
|
|
if (ImGui.Selectable($"{i + 1}", this._glyph == i)) {
|
2022-09-06 04:24:32 +00:00
|
|
|
this._glyph = i;
|
|
|
|
}
|
2022-09-06 07:37:03 +00:00
|
|
|
|
2022-09-06 07:57:38 +00:00
|
|
|
if (tooltipShown || !ImGui.IsItemHovered()) {
|
2022-09-06 07:37:03 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2024-07-01 16:13:36 +00:00
|
|
|
var glyphImage = this.GetGlyphImage(i);
|
|
|
|
if (!glyphImage.TryGetWrap(out var wrap, out _)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-09-06 07:37:03 +00:00
|
|
|
ImGui.BeginTooltip();
|
2024-06-16 19:28:34 +00:00
|
|
|
using var endTooltip = new OnDispose(ImGui.EndTooltip);
|
2024-07-01 16:13:36 +00:00
|
|
|
|
2024-07-01 15:10:41 +00:00
|
|
|
ImGui.Image(wrap.ImGuiHandle, new Vector2(imageHeight));
|
2022-09-06 07:57:38 +00:00
|
|
|
tooltipShown = true;
|
2022-09-06 04:24:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-22 07:44:30 +00:00
|
|
|
var emoteLabel = this._emoteIdx == -1
|
|
|
|
? "None"
|
|
|
|
: this.Emotes[this._emoteIdx].Name.ToDalamudString().TextValue;
|
2024-07-22 09:49:51 +00:00
|
|
|
if (ImGui.BeginCombo("Emote", emoteLabel, ImGuiComboFlags.HeightLarge)) {
|
2024-07-22 07:44:30 +00:00
|
|
|
using var endCombo = new OnDispose(ImGui.EndCombo);
|
|
|
|
|
2024-07-22 09:49:51 +00:00
|
|
|
if (ImGui.IsWindowAppearing()) {
|
|
|
|
ImGui.SetKeyboardFocusHere();
|
2024-07-22 07:44:30 +00:00
|
|
|
}
|
|
|
|
|
2024-07-22 09:49:51 +00:00
|
|
|
ImGui.SetNextItemWidth(-1);
|
|
|
|
ImGui.InputTextWithHint("###emote-search", "Search...", ref this._emoteSearch, 100, ImGuiInputTextFlags.AutoSelectAll);
|
2024-07-22 07:44:30 +00:00
|
|
|
|
2024-07-22 09:49:51 +00:00
|
|
|
using var endChild = new OnDispose(ImGui.EndChild);
|
|
|
|
if (ImGui.BeginChild("##emote-search-child", new Vector2(0, 150) * ImGuiHelpers.GlobalScale)) {
|
|
|
|
if (ImGui.Selectable("None##no-emote", this._emoteIdx == -1)) {
|
|
|
|
this._emoteIdx = -1;
|
|
|
|
ImGui.CloseCurrentPopup();
|
2024-07-22 07:44:30 +00:00
|
|
|
}
|
|
|
|
|
2024-07-22 09:49:51 +00:00
|
|
|
ImGui.Separator();
|
|
|
|
|
|
|
|
for (var i = 0; i < this.Emotes.Count; i++) {
|
|
|
|
var emote = this.Emotes[i];
|
2024-07-22 17:31:44 +00:00
|
|
|
var name = emote.Name.ToDalamudString().TextValue;
|
2024-07-22 09:49:51 +00:00
|
|
|
if (!string.IsNullOrEmpty(this._emoteSearch)) {
|
2024-07-22 17:31:44 +00:00
|
|
|
if (!name.Contains(this._emoteSearch, StringComparison.InvariantCultureIgnoreCase)) {
|
2024-07-22 09:49:51 +00:00
|
|
|
if (!emote.TextCommand.Value!.Command.ToDalamudString().TextValue.Contains(this._emoteSearch, StringComparison.InvariantCultureIgnoreCase)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var unlocked = IsEmoteUnlocked(emote);
|
|
|
|
if (!unlocked) {
|
|
|
|
ImGui.BeginDisabled();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ImGui.Selectable($"{name}##emote-{emote.RowId}", this._emoteIdx == i)) {
|
|
|
|
this._emoteIdx = i;
|
|
|
|
ImGui.CloseCurrentPopup();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!unlocked) {
|
|
|
|
ImGui.EndDisabled();
|
|
|
|
}
|
2024-07-22 07:44:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-04 05:03:59 +00:00
|
|
|
this.ClearIfNecessary();
|
|
|
|
|
|
|
|
var valid = this.ValidSetup();
|
|
|
|
if (!valid) {
|
|
|
|
ImGui.BeginDisabled();
|
|
|
|
}
|
|
|
|
|
2022-09-04 22:19:16 +00:00
|
|
|
var inAir = this.Plugin.Condition[ConditionFlag.Jumping]
|
|
|
|
|| this.Plugin.Condition[ConditionFlag.Jumping61]
|
|
|
|
|| this.Plugin.Condition[ConditionFlag.InFlight];
|
|
|
|
if (ImGui.Button("Write") && valid && !inAir && this.Plugin.ClientState.LocalPlayer is { } player) {
|
2024-07-01 04:38:58 +00:00
|
|
|
var location = HousingLocation.Current();
|
2022-09-04 05:03:59 +00:00
|
|
|
var req = new MessageRequest {
|
|
|
|
Territory = this.Plugin.ClientState.TerritoryType,
|
2024-07-22 07:44:30 +00:00
|
|
|
World = player.CurrentWorld.Id,
|
2024-07-01 04:38:58 +00:00
|
|
|
Ward = location?.Ward,
|
|
|
|
Plot = location?.CombinedPlot(),
|
2022-09-04 05:03:59 +00:00
|
|
|
X = player.Position.X,
|
|
|
|
Y = player.Position.Y,
|
|
|
|
Z = player.Position.Z,
|
2022-09-04 21:02:13 +00:00
|
|
|
Yaw = player.Rotation,
|
2022-09-04 05:03:59 +00:00
|
|
|
PackId = pack.Id,
|
|
|
|
Template1 = this._part1,
|
|
|
|
Word1List = this._word1.Item1 == -1 ? null : this._word1.Item1,
|
|
|
|
Word1Word = this._word1.Item2 == -1 ? null : this._word1.Item2,
|
|
|
|
Conjunction = this._conj == -1 ? null : this._conj,
|
|
|
|
Template2 = this._part2 == -1 ? null : this._part2,
|
|
|
|
Word2List = this._word2.Item1 == -1 ? null : this._word2.Item1,
|
|
|
|
Word2Word = this._word2.Item2 == -1 ? null : this._word2.Item2,
|
2022-09-06 04:24:32 +00:00
|
|
|
Glyph = this._glyph,
|
2024-07-22 07:44:30 +00:00
|
|
|
Emote = this._emoteIdx == -1
|
|
|
|
? null
|
|
|
|
: this.GetEmoteData(this.Emotes[this._emoteIdx], player),
|
2022-09-04 05:03:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
var json = JsonConvert.SerializeObject(req);
|
|
|
|
Task.Run(async () => {
|
|
|
|
var resp = await ServerHelper.SendRequest(
|
|
|
|
this.Plugin.Config.ApiKey,
|
|
|
|
HttpMethod.Post,
|
|
|
|
"/messages",
|
|
|
|
"application/json",
|
|
|
|
new StringContent(json)
|
|
|
|
);
|
2022-09-05 08:21:45 +00:00
|
|
|
var content = await resp.Content.ReadAsStringAsync();
|
2022-09-04 05:03:59 +00:00
|
|
|
if (resp.IsSuccessStatusCode) {
|
|
|
|
var newMsg = new Message {
|
2022-09-05 08:21:45 +00:00
|
|
|
Id = Guid.Parse(content),
|
2022-09-04 05:03:59 +00:00
|
|
|
X = player.Position.X,
|
|
|
|
Y = player.Position.Y,
|
|
|
|
Z = player.Position.Z,
|
2022-09-04 21:10:03 +00:00
|
|
|
Yaw = player.Rotation,
|
2022-09-04 05:03:59 +00:00
|
|
|
Text = actualText,
|
|
|
|
NegativeVotes = 0,
|
|
|
|
PositiveVotes = 0,
|
2024-07-22 07:44:30 +00:00
|
|
|
UserVote = 0,
|
2022-09-06 04:24:32 +00:00
|
|
|
Glyph = this._glyph,
|
2024-07-22 07:44:30 +00:00
|
|
|
Emote = req.Emote,
|
2022-09-04 05:03:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
this.Plugin.Messages.Add(newMsg);
|
|
|
|
this.ResetWriter();
|
|
|
|
this.Plugin.Ui.MainWindow.Visible = false;
|
2022-09-05 08:21:45 +00:00
|
|
|
} else {
|
|
|
|
var error = JsonConvert.DeserializeObject<ErrorMessage>(content);
|
2022-09-05 08:35:28 +00:00
|
|
|
this.Plugin.Ui.ShowModal($"Error writing message.\n\nMessage from server:\n{error?.Message}");
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!valid) {
|
|
|
|
ImGui.EndDisabled();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-22 07:44:30 +00:00
|
|
|
private unsafe EmoteData GetEmoteData(Emote emote, IPlayerCharacter player) {
|
2024-07-22 09:49:51 +00:00
|
|
|
var chara = (Character*) GameObjectManager.Instance()->Objects.GetObjectByGameObjectId(player.GameObjectId);
|
2024-07-22 07:44:30 +00:00
|
|
|
|
|
|
|
return new EmoteData {
|
|
|
|
Id = emote.RowId,
|
2024-07-22 09:49:51 +00:00
|
|
|
Customise = player.Customize.ToList(),
|
2024-07-22 07:44:30 +00:00
|
|
|
Equipment = chara->DrawData.EquipmentModelIds
|
|
|
|
.ToArray()
|
|
|
|
.Select(equip => new EquipmentData {
|
|
|
|
Id = equip.Id,
|
|
|
|
Variant = equip.Variant,
|
|
|
|
Stain0 = equip.Stain0,
|
|
|
|
Stain1 = equip.Stain1,
|
|
|
|
})
|
|
|
|
.ToArray(),
|
|
|
|
Weapon = chara->DrawData.WeaponData
|
|
|
|
.ToArray()
|
|
|
|
.Select(weapon => new WeaponData {
|
|
|
|
ModelId = new WeaponModelId {
|
|
|
|
Id = weapon.ModelId.Id,
|
|
|
|
Kind = weapon.ModelId.Type,
|
|
|
|
Variant = weapon.ModelId.Variant,
|
|
|
|
Stain0 = weapon.ModelId.Stain0,
|
|
|
|
Stain1 = weapon.ModelId.Stain1,
|
|
|
|
},
|
|
|
|
Flags1 = weapon.Flags1,
|
|
|
|
Flags2 = weapon.Flags2,
|
|
|
|
State = weapon.State,
|
|
|
|
})
|
|
|
|
.ToArray(),
|
|
|
|
Glasses = chara->DrawData.GlassesIds[0],
|
|
|
|
HatHidden = chara->DrawData.IsHatHidden,
|
|
|
|
VisorToggled = chara->DrawData.IsVisorToggled,
|
|
|
|
WeaponHidden = chara->DrawData.IsWeaponHidden,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
private static unsafe bool IsEmoteUnlocked(Emote emote) {
|
|
|
|
return UIState.Instance()->IsEmoteUnlocked((ushort) emote.RowId);
|
|
|
|
}
|
|
|
|
|
2022-09-04 05:03:59 +00:00
|
|
|
private void ResetWriter() {
|
|
|
|
this._part1 = this._part2 = this._conj = -1;
|
|
|
|
this._word1 = (-1, -1);
|
|
|
|
this._word2 = (-1, -1);
|
2022-09-06 07:57:38 +00:00
|
|
|
this._glyph = this.Plugin.Config.DefaultGlyph;
|
2024-07-22 09:49:51 +00:00
|
|
|
this._emoteIdx = -1;
|
|
|
|
this._emoteSearch = string.Empty;
|
2024-07-22 17:31:44 +00:00
|
|
|
this._word1Search = string.Empty;
|
|
|
|
this._word2Search = string.Empty;
|
2022-09-04 05:03:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void ClearIfNecessary() {
|
|
|
|
if (this._pack == -1) {
|
|
|
|
this._part1 = -1;
|
|
|
|
}
|
|
|
|
|
2022-09-08 03:13:55 +00:00
|
|
|
var pack = Pack.All[this._pack];
|
2022-09-04 05:03:59 +00:00
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
if (this._part1 == -1 || !pack.Templates[this._part1].Text.Contains("{0}")) {
|
2022-09-04 05:03:59 +00:00
|
|
|
this._word1 = (-1, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._conj == -1) {
|
|
|
|
this._part2 = -1;
|
|
|
|
}
|
|
|
|
|
2024-06-16 19:28:34 +00:00
|
|
|
if (this._part2 == -1 || !pack.Templates[this._part2].Text.Contains("{0}")) {
|
2022-09-04 05:03:59 +00:00
|
|
|
this._word2 = (-1, -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private bool ValidSetup() {
|
|
|
|
if (this._pack == -1 || this._part1 == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-09-08 03:13:55 +00:00
|
|
|
var pack = Pack.All[this._pack];
|
2022-09-04 05:03:59 +00:00
|
|
|
var template1 = pack.Templates[this._part1];
|
2024-06-16 19:28:34 +00:00
|
|
|
var temp1Variable = template1.Text.Contains("{0}");
|
2022-09-04 05:03:59 +00:00
|
|
|
|
|
|
|
switch (temp1Variable) {
|
|
|
|
case true when this._word1 == (-1, -1):
|
|
|
|
case false when this._word1 != (-1, -1):
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._conj == -1 && (this._part2 != -1 || this._word2 != (-1, -1))) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this._conj != -1) {
|
|
|
|
if (this._part2 == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
var template2 = pack.Templates[this._part2];
|
2024-06-16 19:28:34 +00:00
|
|
|
var temp2Variable = template2.Text.Contains("{0}");
|
2022-09-04 05:03:59 +00:00
|
|
|
|
|
|
|
switch (temp2Variable) {
|
|
|
|
case true when this._word2 == (-1, -1):
|
|
|
|
case false when this._word2 != (-1, -1):
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|