using Lumina; using System.Text.Json; if(args.Length is <2 or >3) throw new ArgumentException("ActionAudit sqpack-path name-fragment|--movement [output-json]"); using var game=new GameData(args[0]); var rows=new List(); var timelines=new HashSet(); var ids=args[1].StartsWith("--ids:") ? args[1][6..].Split(',').Select(uint.Parse).ToHashSet() : null; foreach(var action in game.GetExcelSheet() ?? throw new InvalidDataException("Action sheet unavailable")) if(ids!=null ? ids.Contains(action.RowId) : args[1]=="--movement" ? action.IsPlayerAction && action.AffectsPosition : action.Name.ToString().Contains(args[1],StringComparison.OrdinalIgnoreCase)) { Console.WriteLine($"{action.RowId} {action.Name}: AffectsPosition={action.AffectsPosition}, Hostile={action.CanTargetHostile}, AnimationEnd={action.AnimationEnd.RowId}"); rows.Add(new { ActionId=action.RowId,Name=action.Name.ToString(),Timeline=action.AnimationEnd.RowId,PvP=action.IsPvP,PlayerAction=action.IsPlayerAction,AffectsPosition=action.AffectsPosition }); if(action.AnimationEnd.RowId is >0 and <=ushort.MaxValue) timelines.Add(action.AnimationEnd.RowId); } Console.WriteLine($"Skills={rows.Count}, Timelines={timelines.Count}"); if(args.Length==3) File.WriteAllText(args[2],JsonSerializer.Serialize(rows,new JsonSerializerOptions { WriteIndented=true }));