cheat UI
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:47ff1377fe87865c1bdada70b8f6fee638a20879f70b84b40d62fb978aee203e
|
||||
size 325051
|
||||
oid sha256:efc3059b491e93ff0a1f6d4d6cdc8546e4f81e520c63c1a4ee38b7ccfb0dfa70
|
||||
size 330783
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public class DebugCmdHistoryListItem : MonoBehaviour
|
||||
{
|
||||
[SerializeField] TMP_Text _label;
|
||||
[SerializeField] Button _btnUse;
|
||||
[SerializeField] Button _btnDelete;
|
||||
|
||||
private DlgConsole _console;
|
||||
private DebugCmdHistoryStore.Entry _entry;
|
||||
|
||||
public void Bind(DlgConsole console, DebugCmdHistoryStore.Entry entry)
|
||||
{
|
||||
_console = console;
|
||||
_entry = entry;
|
||||
|
||||
if (_label == null)
|
||||
_label = GetComponentInChildren<TMP_Text>(true);
|
||||
|
||||
if (_btnUse == null)
|
||||
_btnUse = GetComponentInChildren<Button>(true);
|
||||
|
||||
if (_btnDelete == null)
|
||||
{
|
||||
// Optional: if you have multiple buttons, assign _btnDelete in inspector.
|
||||
// Auto-find by name as best-effort.
|
||||
var buttons = GetComponentsInChildren<Button>(true);
|
||||
for (int i = 0; i < buttons.Length; i++)
|
||||
{
|
||||
var b = buttons[i];
|
||||
if (b != null && b.gameObject.name.IndexOf("delete", System.StringComparison.OrdinalIgnoreCase) >= 0)
|
||||
{
|
||||
_btnDelete = b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_label != null)
|
||||
{
|
||||
string cmd = entry.hasParam ? $"{entry.header} {entry.param}" : $"{entry.header}";
|
||||
if (!string.IsNullOrWhiteSpace(entry.describe))
|
||||
_label.text = $"{entry.describe} ({cmd})";
|
||||
else
|
||||
_label.text = cmd;
|
||||
}
|
||||
|
||||
if (_btnUse != null)
|
||||
{
|
||||
_btnUse.onClick.RemoveListener(OnUseClicked);
|
||||
_btnUse.onClick.AddListener(OnUseClicked);
|
||||
}
|
||||
|
||||
if (_btnDelete != null)
|
||||
{
|
||||
_btnDelete.onClick.RemoveListener(OnDeleteClicked);
|
||||
_btnDelete.onClick.AddListener(OnDeleteClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnUseClicked()
|
||||
{
|
||||
if (_console == null || _entry == null)
|
||||
return;
|
||||
|
||||
_console.ApplyHistoryItemToInputs(_entry.header, _entry.param, _entry.hasParam, _entry.describe);
|
||||
}
|
||||
|
||||
private void OnDeleteClicked()
|
||||
{
|
||||
if (_console == null || _entry == null)
|
||||
return;
|
||||
|
||||
_console.RemoveHistoryItem(_entry.header, _entry.param, _entry.hasParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7aa769352164e6f4aa858fb9136ffa67
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public class DebugCmdHistoryListView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] DlgConsole _console;
|
||||
[SerializeField] Transform _content;
|
||||
[SerializeField] DebugCmdHistoryListItem _itemPrefab;
|
||||
[SerializeField] TMP_Text _emptyText;
|
||||
[SerializeField] Button _btnClear;
|
||||
|
||||
private readonly List<DebugCmdHistoryListItem> _items = new List<DebugCmdHistoryListItem>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (_btnClear != null)
|
||||
_btnClear.onClick.AddListener(OnClearClicked);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_console != null)
|
||||
_console.HistoryChanged += Rebuild;
|
||||
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_console != null)
|
||||
_console.HistoryChanged -= Rebuild;
|
||||
}
|
||||
|
||||
public void Rebuild()
|
||||
{
|
||||
if (_content == null || _itemPrefab == null || _console == null)
|
||||
{
|
||||
SetEmptyTextVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ClearItems();
|
||||
|
||||
var history = _console.GetHistory();
|
||||
if (history == null || history.Count == 0)
|
||||
{
|
||||
SetEmptyTextVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
SetEmptyTextVisible(false);
|
||||
for (int i = 0; i < history.Count; i++)
|
||||
{
|
||||
var item = Instantiate(_itemPrefab, _content);
|
||||
item.gameObject.SetActive(true);
|
||||
item.Bind(_console, history[i]);
|
||||
_items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnClearClicked()
|
||||
{
|
||||
if (_console != null)
|
||||
_console.ClearHistory();
|
||||
}
|
||||
|
||||
private void ClearItems()
|
||||
{
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
if (_items[i] != null)
|
||||
Destroy(_items[i].gameObject);
|
||||
}
|
||||
_items.Clear();
|
||||
}
|
||||
|
||||
private void SetEmptyTextVisible(bool visible)
|
||||
{
|
||||
if (_emptyText != null)
|
||||
_emptyText.gameObject.SetActive(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2602b8c962e1b824ba3016d81b470617
|
||||
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public static class DebugCmdHistoryStore
|
||||
{
|
||||
private const string PlayerPrefsKey = "DebugCmdHistory_v1";
|
||||
private const int MaxEntries = 200;
|
||||
|
||||
[Serializable]
|
||||
public class Entry
|
||||
{
|
||||
public int header;
|
||||
public int param;
|
||||
public bool hasParam;
|
||||
public string describe;
|
||||
public long lastUsedUtcTicks;
|
||||
|
||||
public string KeyString => hasParam ? $"{header}:{param}" : $"{header}:";
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class EntryListWrapper
|
||||
{
|
||||
public List<Entry> items = new List<Entry>();
|
||||
}
|
||||
|
||||
public static List<Entry> Load()
|
||||
{
|
||||
string json = PlayerPrefs.GetString(PlayerPrefsKey, string.Empty);
|
||||
if (string.IsNullOrWhiteSpace(json))
|
||||
return new List<Entry>();
|
||||
|
||||
try
|
||||
{
|
||||
var wrapper = JsonUtility.FromJson<EntryListWrapper>(json);
|
||||
if (wrapper == null || wrapper.items == null)
|
||||
return new List<Entry>();
|
||||
|
||||
wrapper.items.RemoveAll(e => e == null);
|
||||
return wrapper.items;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return new List<Entry>();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Save(List<Entry> entries)
|
||||
{
|
||||
var wrapper = new EntryListWrapper { items = entries ?? new List<Entry>() };
|
||||
string json = JsonUtility.ToJson(wrapper);
|
||||
PlayerPrefs.SetString(PlayerPrefsKey, json);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
public static bool Upsert(List<Entry> entries, int header, int param, bool hasParam, string describe)
|
||||
{
|
||||
if (entries == null)
|
||||
throw new ArgumentNullException(nameof(entries));
|
||||
|
||||
describe = (describe ?? string.Empty).Trim();
|
||||
|
||||
int idx = FindIndex(entries, header, param, hasParam);
|
||||
if (idx >= 0)
|
||||
{
|
||||
var e = entries[idx];
|
||||
bool changed = false;
|
||||
|
||||
// Overwrite describe whenever it differs (supports updating from empty -> non-empty).
|
||||
if (!string.Equals((e.describe ?? string.Empty).Trim(), describe, StringComparison.Ordinal))
|
||||
{
|
||||
e.describe = describe;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
e.lastUsedUtcTicks = DateTime.UtcNow.Ticks;
|
||||
if (idx != 0)
|
||||
{
|
||||
entries.RemoveAt(idx);
|
||||
entries.Insert(0, e);
|
||||
changed = true;
|
||||
}
|
||||
else if (!changed)
|
||||
{
|
||||
// still considered "used"; keep order
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
else
|
||||
{
|
||||
var e = new Entry
|
||||
{
|
||||
header = header,
|
||||
param = param,
|
||||
hasParam = hasParam,
|
||||
describe = describe,
|
||||
lastUsedUtcTicks = DateTime.UtcNow.Ticks
|
||||
};
|
||||
entries.Insert(0, e);
|
||||
|
||||
if (entries.Count > MaxEntries)
|
||||
entries.RemoveRange(MaxEntries, entries.Count - MaxEntries);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
PlayerPrefs.DeleteKey(PlayerPrefsKey);
|
||||
PlayerPrefs.Save();
|
||||
}
|
||||
|
||||
public static bool Remove(List<Entry> entries, int header, int param, bool hasParam)
|
||||
{
|
||||
if (entries == null)
|
||||
throw new ArgumentNullException(nameof(entries));
|
||||
|
||||
int idx = FindIndex(entries, header, param, hasParam);
|
||||
if (idx < 0)
|
||||
return false;
|
||||
|
||||
entries.RemoveAt(idx);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static int FindIndex(List<Entry> entries, int header, int param, bool hasParam)
|
||||
{
|
||||
for (int i = 0; i < entries.Count; i++)
|
||||
{
|
||||
var e = entries[i];
|
||||
if (e == null) continue;
|
||||
if (e.header != header) continue;
|
||||
if (e.hasParam != hasParam) continue;
|
||||
if (hasParam && e.param != param) continue;
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9d8c1a000a99b140aa0ecff6bba4bbc
|
||||
@@ -1,5 +1,7 @@
|
||||
using BrewMonster.Network;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using EditorAttributes;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
@@ -11,9 +13,19 @@ namespace BrewMonster.Scripts
|
||||
{
|
||||
[SerializeField] GameObject _panelConsole;
|
||||
|
||||
[Header("Debug Cmd Input (new UI)")]
|
||||
[SerializeField] TMP_InputField _inputHeader;
|
||||
[SerializeField] TMP_InputField _inputParam;
|
||||
[SerializeField] TMP_InputField _inputTime;
|
||||
[SerializeField] Toggle _toggleLoop;
|
||||
[SerializeField] TMP_InputField _inputDescribe;
|
||||
|
||||
[Space(6)]
|
||||
[Header("Legacy Console Input")]
|
||||
[SerializeField] TMP_InputField _consoleInput;
|
||||
//send button
|
||||
[SerializeField] Button _btnSend;
|
||||
[SerializeField] Button _btnCancelAllLoops;
|
||||
[SerializeField] Button _btnOpen;
|
||||
[SerializeField] Button _btnClose;
|
||||
|
||||
@@ -25,11 +37,20 @@ namespace BrewMonster.Scripts
|
||||
private bool _isAutoAddWrathEnabled = false;
|
||||
private Coroutine _autoAddWrathCoroutine;
|
||||
|
||||
private readonly Dictionary<LoopCmdKey, LoopCmdInfo> _loopCmds = new Dictionary<LoopCmdKey, LoopCmdInfo>();
|
||||
|
||||
public event Action LoopCommandsChanged;
|
||||
public event Action HistoryChanged;
|
||||
|
||||
private List<DebugCmdHistoryStore.Entry> _history;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_history = DebugCmdHistoryStore.Load();
|
||||
_btnSend?.onClick.AddListener(OnBtnSendClicked);
|
||||
_btnCancelAllLoops?.onClick.AddListener(CancelAllLoopCommands);
|
||||
_btnOpen?.onClick.AddListener(OnBtnOpenClicked);
|
||||
_btnClose?.onClick.AddListener(OnBtnCloseClicked);
|
||||
//_btnClose?.onClick.AddListener(OnBtnCloseClicked);
|
||||
_btnNoCooldown?.onClick.AddListener(OnBtnNoCooldownClicked);
|
||||
_btnToggleAutoWrath?.onClick.AddListener(OnBtnToggleAutoWrathClicked);
|
||||
|
||||
@@ -38,6 +59,7 @@ namespace BrewMonster.Scripts
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
CancelAllLoopCommands();
|
||||
// Stop coroutine if running when object is destroyed
|
||||
// 对象销毁时如果协程正在运行则停止它
|
||||
if (_autoAddWrathCoroutine != null)
|
||||
@@ -50,28 +72,36 @@ namespace BrewMonster.Scripts
|
||||
#region button events
|
||||
private void OnBtnSendClicked()
|
||||
{
|
||||
string input = _consoleInput.text;
|
||||
if (string.IsNullOrEmpty(input))
|
||||
if (TryReadCmdFromNewInputs(out int header, out int param, out bool hasParam, out float intervalSeconds, out bool loopEnabled))
|
||||
{
|
||||
UpsertHistoryFromInputs(header, param, hasParam);
|
||||
SendCmdDebug(header, param, hasParam);
|
||||
|
||||
if (loopEnabled)
|
||||
{
|
||||
string describe = _inputDescribe != null ? _inputDescribe.text : string.Empty;
|
||||
StartOrRestartLoopCommand(header, param, hasParam, intervalSeconds, describe);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!input.StartsWith("d "))
|
||||
return;
|
||||
|
||||
input = input.Substring(2);
|
||||
string[] cmdParams = input.Split(' ');
|
||||
|
||||
// Fallback: legacy console style: "d <header> [param]"
|
||||
if (TryReadCmdFromLegacyConsole(out header, out param, out hasParam))
|
||||
{
|
||||
UpsertHistory(header, param, hasParam, string.Empty);
|
||||
SendCmdDebug(header, param, hasParam);
|
||||
}
|
||||
}
|
||||
|
||||
bool isOpen = false;
|
||||
private void OnBtnOpenClicked()
|
||||
{
|
||||
_panelConsole.SetActive(true);
|
||||
isOpen = !isOpen;
|
||||
_panelConsole.SetActive(isOpen);
|
||||
}
|
||||
private void OnBtnCloseClicked()
|
||||
/* private void OnBtnCloseClicked()
|
||||
{
|
||||
_panelConsole.SetActive(false);
|
||||
}
|
||||
}*/
|
||||
public void OnBtnNoCooldownClicked()
|
||||
{
|
||||
UnityGameSession.c2s_CmdDebug(8903, 73125);
|
||||
@@ -122,6 +152,288 @@ namespace BrewMonster.Scripts
|
||||
}
|
||||
_autoAddWrathCoroutine = null;
|
||||
}
|
||||
|
||||
private void SendCmdDebug(int header, int param, bool hasParam)
|
||||
{
|
||||
if (hasParam)
|
||||
UnityGameSession.c2s_CmdDebug((ushort)header, param);
|
||||
else
|
||||
UnityGameSession.c2s_CmdDebug((ushort)header);
|
||||
}
|
||||
|
||||
private void UpsertHistoryFromInputs(int header, int param, bool hasParam)
|
||||
{
|
||||
string describe = _inputDescribe != null ? _inputDescribe.text : string.Empty;
|
||||
UpsertHistory(header, param, hasParam, describe);
|
||||
}
|
||||
|
||||
private void UpsertHistory(int header, int param, bool hasParam, string describe)
|
||||
{
|
||||
_history ??= new List<DebugCmdHistoryStore.Entry>();
|
||||
bool changed = DebugCmdHistoryStore.Upsert(_history, header, param, hasParam, describe);
|
||||
if (changed)
|
||||
{
|
||||
DebugCmdHistoryStore.Save(_history);
|
||||
HistoryChanged?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Still persist last-used ordering (Upsert may have moved it) even if describe unchanged.
|
||||
DebugCmdHistoryStore.Save(_history);
|
||||
HistoryChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public IReadOnlyList<DebugCmdHistoryStore.Entry> GetHistory()
|
||||
{
|
||||
_history ??= DebugCmdHistoryStore.Load();
|
||||
return _history;
|
||||
}
|
||||
|
||||
public void ClearHistory()
|
||||
{
|
||||
DebugCmdHistoryStore.Clear();
|
||||
_history = new List<DebugCmdHistoryStore.Entry>();
|
||||
HistoryChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void RemoveHistoryItem(int header, int param, bool hasParam)
|
||||
{
|
||||
_history ??= DebugCmdHistoryStore.Load();
|
||||
bool removed = DebugCmdHistoryStore.Remove(_history, header, param, hasParam);
|
||||
if (!removed)
|
||||
return;
|
||||
|
||||
DebugCmdHistoryStore.Save(_history);
|
||||
HistoryChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void ApplyHistoryItemToInputs(int header, int param, bool hasParam, string describe)
|
||||
{
|
||||
if (_inputHeader != null) _inputHeader.text = header.ToString();
|
||||
if (_inputParam != null) _inputParam.text = hasParam ? param.ToString() : string.Empty;
|
||||
if (_inputDescribe != null) _inputDescribe.text = describe ?? string.Empty;
|
||||
}
|
||||
|
||||
private bool TryReadCmdFromNewInputs(out int header, out int param, out bool hasParam, out float intervalSeconds, out bool loopEnabled)
|
||||
{
|
||||
header = 0;
|
||||
param = 0;
|
||||
hasParam = false;
|
||||
intervalSeconds = 1f;
|
||||
loopEnabled = _toggleLoop != null && _toggleLoop.isOn;
|
||||
|
||||
// If these inputs aren't wired up in inspector, bail to legacy mode.
|
||||
if (_inputHeader == null && _inputParam == null && _inputTime == null && _toggleLoop == null && _inputDescribe == null)
|
||||
return false;
|
||||
|
||||
var headerText = _inputHeader != null ? _inputHeader.text : string.Empty;
|
||||
var paramText = _inputParam != null ? _inputParam.text : string.Empty;
|
||||
var timeText = _inputTime != null ? _inputTime.text : string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(headerText))
|
||||
return false;
|
||||
|
||||
if (!int.TryParse(headerText.Trim(), out header))
|
||||
return false;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(paramText) && int.TryParse(paramText.Trim(), out param))
|
||||
hasParam = true;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(timeText) && float.TryParse(timeText.Trim(), out float parsed))
|
||||
intervalSeconds = Mathf.Max(0.05f, parsed);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryReadCmdFromLegacyConsole(out int header, out int param, out bool hasParam)
|
||||
{
|
||||
header = 0;
|
||||
param = 0;
|
||||
hasParam = false;
|
||||
|
||||
if (_consoleInput == null)
|
||||
return false;
|
||||
|
||||
string input = _consoleInput.text;
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return false;
|
||||
|
||||
input = input.Trim();
|
||||
if (!input.StartsWith("d ", StringComparison.OrdinalIgnoreCase))
|
||||
return false;
|
||||
|
||||
input = input.Substring(2).Trim();
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
return false;
|
||||
|
||||
string[] cmdParams = input.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (cmdParams.Length < 1)
|
||||
return false;
|
||||
|
||||
if (!int.TryParse(cmdParams[0], out header))
|
||||
return false;
|
||||
|
||||
if (cmdParams.Length >= 2 && int.TryParse(cmdParams[1], out param))
|
||||
hasParam = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void StartOrRestartLoopCommand(int header, int param, bool hasParam, float intervalSeconds, string describe)
|
||||
{
|
||||
var key = new LoopCmdKey(header, param, hasParam);
|
||||
if (_loopCmds.TryGetValue(key, out var existing) && existing.Coroutine != null)
|
||||
{
|
||||
StopCoroutine(existing.Coroutine);
|
||||
_loopCmds.Remove(key);
|
||||
}
|
||||
|
||||
var co = StartCoroutine(LoopSendCoroutine(key, intervalSeconds));
|
||||
_loopCmds[key] = new LoopCmdInfo(co, intervalSeconds, describe);
|
||||
|
||||
Debug.Log($"[DlgConsole] Loop ON: {key} every {intervalSeconds:0.###}s");
|
||||
LoopCommandsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public void CancelLoopCommand(int header, int param, bool hasParam)
|
||||
{
|
||||
var key = new LoopCmdKey(header, param, hasParam);
|
||||
if (_loopCmds.TryGetValue(key, out var info) && info.Coroutine != null)
|
||||
{
|
||||
StopCoroutine(info.Coroutine);
|
||||
_loopCmds.Remove(key);
|
||||
Debug.Log($"[DlgConsole] Loop OFF: {key}");
|
||||
LoopCommandsChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelAllLoopCommands()
|
||||
{
|
||||
if (_loopCmds.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var kv in _loopCmds)
|
||||
{
|
||||
if (kv.Value.Coroutine != null)
|
||||
StopCoroutine(kv.Value.Coroutine);
|
||||
}
|
||||
_loopCmds.Clear();
|
||||
Debug.Log("[DlgConsole] Loop OFF: ALL");
|
||||
LoopCommandsChanged?.Invoke();
|
||||
}
|
||||
|
||||
public string GetActiveLoopCommandsDebugString()
|
||||
{
|
||||
if (_loopCmds.Count == 0)
|
||||
return "(none)";
|
||||
|
||||
var parts = new List<string>(_loopCmds.Count);
|
||||
foreach (var key in _loopCmds.Keys)
|
||||
parts.Add(key.ToString());
|
||||
|
||||
return string.Join(", ", parts);
|
||||
}
|
||||
|
||||
public IReadOnlyList<ActiveLoopCommand> GetActiveLoopCommands()
|
||||
{
|
||||
if (_loopCmds.Count == 0)
|
||||
return Array.Empty<ActiveLoopCommand>();
|
||||
|
||||
var list = new List<ActiveLoopCommand>(_loopCmds.Count);
|
||||
foreach (var kv in _loopCmds)
|
||||
{
|
||||
list.Add(new ActiveLoopCommand(
|
||||
kv.Key.Header,
|
||||
kv.Key.Param,
|
||||
kv.Key.HasParam,
|
||||
kv.Value.IntervalSeconds,
|
||||
kv.Value.Describe
|
||||
));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private IEnumerator LoopSendCoroutine(LoopCmdKey key, float intervalSeconds)
|
||||
{
|
||||
// Send immediately already happened in OnBtnSendClicked; wait interval then keep sending.
|
||||
var wait = new WaitForSeconds(intervalSeconds);
|
||||
while (true)
|
||||
{
|
||||
yield return wait;
|
||||
SendCmdDebug(key.Header, key.Param, key.HasParam);
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct LoopCmdInfo
|
||||
{
|
||||
public readonly Coroutine Coroutine;
|
||||
public readonly float IntervalSeconds;
|
||||
public readonly string Describe;
|
||||
|
||||
public LoopCmdInfo(Coroutine coroutine, float intervalSeconds, string describe)
|
||||
{
|
||||
Coroutine = coroutine;
|
||||
IntervalSeconds = intervalSeconds;
|
||||
Describe = describe ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly struct ActiveLoopCommand
|
||||
{
|
||||
public readonly int Header;
|
||||
public readonly int Param;
|
||||
public readonly bool HasParam;
|
||||
public readonly float IntervalSeconds;
|
||||
public readonly string Describe;
|
||||
|
||||
public ActiveLoopCommand(int header, int param, bool hasParam, float intervalSeconds, string describe)
|
||||
{
|
||||
Header = header;
|
||||
Param = param;
|
||||
HasParam = hasParam;
|
||||
IntervalSeconds = intervalSeconds;
|
||||
Describe = describe ?? string.Empty;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var cmd = HasParam ? $"{Header} {Param}" : $"{Header}";
|
||||
if (!string.IsNullOrWhiteSpace(Describe))
|
||||
return $"{Describe} ({cmd}) @ {IntervalSeconds:0.###}s";
|
||||
return $"{cmd} @ {IntervalSeconds:0.###}s";
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct LoopCmdKey : IEquatable<LoopCmdKey>
|
||||
{
|
||||
public readonly int Header;
|
||||
public readonly int Param;
|
||||
public readonly bool HasParam;
|
||||
|
||||
public LoopCmdKey(int header, int param, bool hasParam)
|
||||
{
|
||||
Header = header;
|
||||
Param = param;
|
||||
HasParam = hasParam;
|
||||
}
|
||||
|
||||
public bool Equals(LoopCmdKey other) => Header == other.Header && Param == other.Param && HasParam == other.HasParam;
|
||||
public override bool Equals(object obj) => obj is LoopCmdKey other && Equals(other);
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
int hash = 17;
|
||||
hash = (hash * 31) + Header;
|
||||
hash = (hash * 31) + Param;
|
||||
hash = (hash * 31) + (HasParam ? 1 : 0);
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString() => HasParam ? $"{Header} {Param}" : $"{Header}";
|
||||
}
|
||||
}
|
||||
}
|
||||
/// d 2000 la kn
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public class LoopCommandListItem : MonoBehaviour
|
||||
{
|
||||
[SerializeField] TMP_Text _label;
|
||||
[SerializeField] Button _btnCancel;
|
||||
|
||||
private DlgConsole _console;
|
||||
private int _header;
|
||||
private int _param;
|
||||
private bool _hasParam;
|
||||
|
||||
public void Bind(DlgConsole console, DlgConsole.ActiveLoopCommand cmd)
|
||||
{
|
||||
_console = console;
|
||||
_header = cmd.Header;
|
||||
_param = cmd.Param;
|
||||
_hasParam = cmd.HasParam;
|
||||
|
||||
if (_label != null)
|
||||
_label.text = cmd.ToString();
|
||||
|
||||
if (_btnCancel != null)
|
||||
{
|
||||
_btnCancel.onClick.RemoveListener(OnCancelClicked);
|
||||
_btnCancel.onClick.AddListener(OnCancelClicked);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCancelClicked()
|
||||
{
|
||||
if (_console == null)
|
||||
return;
|
||||
|
||||
_console.CancelLoopCommand(_header, _param, _hasParam);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93b9ee106facc74418927a432923ce72
|
||||
@@ -0,0 +1,74 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace BrewMonster.Scripts
|
||||
{
|
||||
public class LoopCommandListView : MonoBehaviour
|
||||
{
|
||||
[SerializeField] DlgConsole _console;
|
||||
[SerializeField] Transform _content;
|
||||
[SerializeField] LoopCommandListItem _itemPrefab;
|
||||
[SerializeField] TMP_Text _emptyText;
|
||||
|
||||
private readonly List<LoopCommandListItem> _items = new List<LoopCommandListItem>();
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (_console != null)
|
||||
_console.LoopCommandsChanged += Rebuild;
|
||||
|
||||
Rebuild();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
if (_console != null)
|
||||
_console.LoopCommandsChanged -= Rebuild;
|
||||
}
|
||||
|
||||
public void Rebuild()
|
||||
{
|
||||
if (_content == null || _itemPrefab == null || _console == null)
|
||||
{
|
||||
SetEmptyTextVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
ClearItems();
|
||||
|
||||
var active = _console.GetActiveLoopCommands();
|
||||
if (active == null || active.Count == 0)
|
||||
{
|
||||
SetEmptyTextVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
SetEmptyTextVisible(false);
|
||||
for (int i = 0; i < active.Count; i++)
|
||||
{
|
||||
var item = Instantiate(_itemPrefab, _content);
|
||||
item.gameObject.SetActive(true);
|
||||
item.Bind(_console, active[i]);
|
||||
_items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearItems()
|
||||
{
|
||||
for (int i = 0; i < _items.Count; i++)
|
||||
{
|
||||
if (_items[i] != null)
|
||||
Destroy(_items[i].gameObject);
|
||||
}
|
||||
_items.Clear();
|
||||
}
|
||||
|
||||
private void SetEmptyTextVisible(bool visible)
|
||||
{
|
||||
if (_emptyText != null)
|
||||
_emptyText.gameObject.SetActive(visible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f379675ccc2c2fa41be2bcda18cbca48
|
||||
@@ -105,7 +105,18 @@ namespace BrewMonster
|
||||
// OnClickedYes = () => UnityGameSession.c2s_SendCmdNPCSevLearnSkill(m_skillID)
|
||||
// });
|
||||
var messagebox = uiManager.ShowMessageBoxYes("Game_LearnSkill", str, this,
|
||||
() => UnityGameSession.c2s_SendCmdNPCSevLearnSkill(m_skillID));
|
||||
() => {
|
||||
UnityGameSession.c2s_SendCmdNPCSevLearnSkill(m_skillID);
|
||||
int skillID = (int)GetData();
|
||||
int nCondition = EC_Game.GetGameRun().GetHostPlayer().CheckSkillLearnCondition(skillID, true);
|
||||
BMLogger.LogError("HoangDev: CDlgSkillSubListItem OnCommand_Upgrade clicked yes for nCondition " + nCondition);
|
||||
|
||||
if (0 == nCondition)
|
||||
{
|
||||
UnityGameSession.c2s_SendCmdNPCSevLearnSkill(skillID);
|
||||
}
|
||||
|
||||
});
|
||||
messagebox.SetData((uint)m_skillID);
|
||||
//GetGameUIMan()->MessageBox("Game_LearnSkill", str, //GetGameUIMan()->GetStringFromTable(231),
|
||||
// MB_OKCANCEL, A3DCOLORRGBA(255, 255, 255, 160), &pMsgBox);
|
||||
|
||||
@@ -479,13 +479,13 @@ public class CECUIManager : MonoSingleton<CECUIManager>
|
||||
|
||||
else if (string.Equals(pDlg.GetName(), "Game_LearnSkill", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
int skillID = (int)pDlg.GetData();
|
||||
/* int skillID = (int)pDlg.GetData();
|
||||
int nCondition = pHost.CheckSkillLearnCondition(skillID, true);
|
||||
|
||||
if (0 == nCondition)
|
||||
{
|
||||
UnityGameSession.c2s_SendCmdNPCSevLearnSkill(skillID);
|
||||
}
|
||||
}*/
|
||||
/*else if (1 == nCondition)
|
||||
AddChatMessage(GetStringFromTable(270), GP_CHAT_MISC);
|
||||
else if (6 == nCondition)
|
||||
|
||||
+336
-31
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user