116 lines
4.3 KiB
C#
116 lines
4.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster.Config
|
|
{
|
|
/// <summary>One row of skill_state_action.txt: skill id, visible state id, be-hit action, optional stay-down action.</summary>
|
|
[Serializable]
|
|
public struct SkillStateActionRow
|
|
{
|
|
public int skill;
|
|
public int state;
|
|
public string beHitAction;
|
|
public string stayDownAction;
|
|
}
|
|
|
|
/// <summary>Parses the classic comma-separated skill_state_action table (same rules as legacy client / CECAttacksMan TextAsset loader).</summary>
|
|
public static class SkillStateActionTextParser
|
|
{
|
|
/// <summary>
|
|
/// Strip CSV-style wrapping quotes (Excel export often writes "2244","117",...).
|
|
/// Handles doubled-quote escapes inside a quoted field.
|
|
/// </summary>
|
|
private static string UnquoteCsvField(string raw)
|
|
{
|
|
if (string.IsNullOrEmpty(raw))
|
|
return string.Empty;
|
|
|
|
string s = raw.Trim().TrimStart('\uFEFF');
|
|
|
|
while (s.Length >= 2 && s[0] == '"' && s[s.Length - 1] == '"')
|
|
{
|
|
s = s.Substring(1, s.Length - 2).Replace("\"\"", "\"").Trim();
|
|
}
|
|
|
|
// Odd exports / naive splits can leave stray " on one side.
|
|
s = s.Trim('"').Trim();
|
|
return s;
|
|
}
|
|
|
|
public static List<SkillStateActionRow> Parse(string text, ICollection<string> warnings = null)
|
|
{
|
|
var rows = new List<SkillStateActionRow>();
|
|
if (string.IsNullOrEmpty(text))
|
|
return rows;
|
|
|
|
// Saved-as-UTF-8-with-BOM breaks int.TryParse on the first column of line 1 (\ufeff123,...).
|
|
text = text.TrimStart('\uFEFF');
|
|
|
|
using (var reader = new StringReader(text))
|
|
{
|
|
string line;
|
|
int lineNum = 0;
|
|
while ((line = reader.ReadLine()) != null)
|
|
{
|
|
lineNum++;
|
|
string trimmed = line.TrimStart('\uFEFF').Trim();
|
|
if (trimmed.Length == 0 || trimmed.StartsWith("//") || trimmed.StartsWith("#"))
|
|
continue;
|
|
|
|
string[] v = trimmed.Split(',');
|
|
// Some configs use tabs instead of commas.
|
|
if (v.Length < 3)
|
|
v = trimmed.Split('\t');
|
|
if (v.Length < 3)
|
|
{
|
|
warnings?.Add($"Line {lineNum}: need at least 3 comma-separated fields");
|
|
continue;
|
|
}
|
|
|
|
string s0 = UnquoteCsvField(v[0]);
|
|
string s1 = UnquoteCsvField(v[1]);
|
|
if (!int.TryParse(s0, System.Globalization.NumberStyles.Integer,
|
|
System.Globalization.CultureInfo.InvariantCulture, out int skillId) ||
|
|
!int.TryParse(s1, System.Globalization.NumberStyles.Integer,
|
|
System.Globalization.CultureInfo.InvariantCulture, out int stateId))
|
|
{
|
|
warnings?.Add($"Line {lineNum}: invalid skill or state id (got \"{s0}\", \"{s1}\")");
|
|
continue;
|
|
}
|
|
|
|
string beHit = UnquoteCsvField(v[2]);
|
|
string stayDown = v.Length > 3 ? UnquoteCsvField(v[3]) : string.Empty;
|
|
|
|
rows.Add(new SkillStateActionRow
|
|
{
|
|
skill = skillId,
|
|
state = stateId,
|
|
beHitAction = beHit,
|
|
stayDownAction = stayDown
|
|
});
|
|
}
|
|
}
|
|
|
|
return rows;
|
|
}
|
|
}
|
|
|
|
[CreateAssetMenu(fileName = "skill_state_action", menuName = "PerfectWorld/Skill State Action Config")]
|
|
public class SkillStateActionConfig : ScriptableObject
|
|
{
|
|
[SerializeField] private List<SkillStateActionRow> entries = new List<SkillStateActionRow>();
|
|
|
|
public IReadOnlyList<SkillStateActionRow> Entries => entries;
|
|
|
|
#if UNITY_EDITOR
|
|
/// <summary>Editor / tools: replace serialized rows after import.</summary>
|
|
public void SetEntries(List<SkillStateActionRow> newEntries)
|
|
{
|
|
entries = newEntries ?? new List<SkillStateActionRow>();
|
|
}
|
|
#endif
|
|
}
|
|
}
|