private static string GetReader(BdatMember member) { string name = GetIdentifier(member.Name); string memberPos = member.MemberPos > 0 ? $" + {member.MemberPos}" : string.Empty; switch (member.ValType) { case BdatValueType.UInt8: return($"item.{name} = file[itemOffset{memberPos}];"); case BdatValueType.UInt16: return($"item.{name} = BitConverter.ToUInt16(file, itemOffset{memberPos});"); case BdatValueType.UInt32: return($"item.{name} = BitConverter.ToUInt32(file, itemOffset{memberPos});"); case BdatValueType.Int8: return($"item.{name} = (sbyte)file[itemOffset{memberPos}];"); case BdatValueType.Int16: return($"item.{name} = BitConverter.ToInt16(file, itemOffset{memberPos});"); case BdatValueType.Int32: return($"item.{name} = BitConverter.ToInt32(file, itemOffset{memberPos});"); case BdatValueType.String: return($"item.{name} = Stuff.GetUTF8Z(file, tableOffset + BitConverter.ToInt32(file, itemOffset{memberPos}));"); case BdatValueType.FP32: return($"item.{name} = BitConverter.ToSingle(file, itemOffset{memberPos});"); } throw new ArgumentOutOfRangeException(); }
private static BdatStringItem ReadItem(BdatTable table, int itemIndex) { int itemOffset = table.ItemTableOffset + itemIndex * table.ItemSize; var item = new BdatStringItem(); foreach (BdatMember member in table.Members) { switch (member.Type) { case BdatMemberType.Scalar: string v = ReadValue(table.Data, itemOffset + member.MemberPos, member.ValType); item.AddMember(member.Name, new BdatStringValue(v, item, member)); break; case BdatMemberType.Array: string[] a = ReadArray(table.Data, itemOffset + member.MemberPos, member); item.AddMember(member.Name, new BdatStringValue(a, item, member)); break; case BdatMemberType.Flag: BdatMember flagsMember = table.Members[member.FlagVarIndex]; string f = ReadFlag(table.Data, itemOffset, member, flagsMember); item.AddMember(member.Name, new BdatStringValue(f, item, member)); break; } } return(item); }
private static string[] ReadArray(DataBuffer table, int arrayOffset, BdatMember member) { var values = new string[member.ArrayCount]; int typeSize = GetTypeSize(member.ValType); for (int i = 0, offset = arrayOffset; i < member.ArrayCount; i++, offset += typeSize) { values[i] = ReadValue(table, offset, member.ValType); } return(values); }
public static void SetXb2EffectCaptions(BdatStringCollection tables) { if (!tables.Tables.ContainsKey("BTL_Enhance") || !tables.Tables.ContainsKey("BTL_EnhanceEff")) { return; } BdatStringTable enhances = tables["BTL_Enhance"]; BdatStringTable effects = tables["BTL_EnhanceEff"]; List <BdatMember> newMembers = effects.Members.ToList(); var captionMember = new BdatMember("Caption", BdatMemberType.Scalar, BdatValueType.String); newMembers.Add(captionMember); effects.Members = newMembers.ToArray(); foreach (BdatStringItem effect in effects.Items) { effect.AddMember("Caption", new BdatStringValue("0", effect, captionMember)); effect["Caption"].Display = ""; } foreach (BdatStringItem enhance in enhances.Items) { int captionId = int.Parse(enhance["Caption"].ValueString); if (captionId == 0) { continue; } BdatStringValue effect = effects[int.Parse(enhance["EnhanceEffect"].ValueString)]["Caption"]; string caption = tables["btl_enhance_cap"][captionId]?["name"].ValueString; effect.Value = captionId.ToString(); effect.Display = caption; } foreach (BdatStringItem enhance in enhances.Items) { int effectCaptionId = int.Parse(enhance["EnhanceEffect"].ValueString); int enhanceCaptionId = int.Parse(enhance["Caption"].ValueString); if (enhanceCaptionId != 0 || effectCaptionId == 0) { continue; } BdatStringValue effect = effects[effectCaptionId]["Caption"]; enhance["Caption"].Value = effect.ValueString; } }
private static void GetArrayReader(BdatMember member, Indenter sb) { string name = GetIdentifier(member.Name); int itemSize = GetSize(member.ValType); string memberPos = member.MemberPos > 0 ? $" + {member.MemberPos}" : string.Empty; sb.AppendLine($"for (int i = 0, offset = itemOffset{memberPos}; i < {member.ArrayCount}; i++, offset += {itemSize})"); sb.AppendLineAndIncrease("{"); switch (member.ValType) { case BdatValueType.UInt8: sb.AppendLine($"item.{name}[i] = file[offset];"); break; case BdatValueType.UInt16: sb.AppendLine($"item.{name}[i] = BitConverter.ToUInt16(file, offset);"); break; case BdatValueType.UInt32: sb.AppendLine($"item.{name}[i] = BitConverter.ToUInt32(file, offset);"); break; case BdatValueType.Int8: sb.AppendLine($"item.{name}[i] = (sbyte)file[offset];"); break; case BdatValueType.Int16: sb.AppendLine($"item.{name}[i] = BitConverter.ToInt16(file, offset);"); break; case BdatValueType.Int32: sb.AppendLine($"item.{name}[i] = BitConverter.ToInt32(file, offset);"); break; case BdatValueType.String: sb.AppendLine($"item.{name}[i] = Stuff.GetUTF8Z(file, tableOffset + BitConverter.ToInt32(file, offset));"); break; case BdatValueType.FP32: sb.AppendLine($"item.{name}[i] = BitConverter.ToSingle(file, offset);"); break; } sb.DecreaseAndAppendLine("}"); }
private static string ReadFlag(DataBuffer table, int itemOffset, BdatMember member, BdatMember flagsMember) { uint flags = uint.Parse(ReadValue(table, itemOffset + flagsMember.MemberPos, flagsMember.ValType)); return(((flags & member.FlagMask) != 0).ToString()); }
public static void ResolveItemRef(BdatStringValue value) { if (value.Resolved) { return; } BdatStringItem item = value.Parent; BdatStringTable table = item.Table; BdatStringCollection tables = table.Collection; BdatMember member = value.Member; BdatFieldInfo field = member.Metadata; if (value.Array != null) { foreach (BdatStringValue element in value.Array) { ResolveItemRef(element); } value.Resolved = true; return; } if (field == null) { value.Resolved = true; return; } if (!int.TryParse(value.ValueString, out int refId)) { value.Resolved = true; return; } refId += field.Adjust; switch (field.Type) { case BdatFieldType.Message: value.Display = tables[field.RefTable][refId]?["name"].DisplayString; if (string.IsNullOrWhiteSpace(value.DisplayString) && refId > 0) { value.Display = refId.ToString(); } break; case BdatFieldType.Reference: ApplyRef(field.RefTable); break; case BdatFieldType.OneWayReference: ApplyRef(field.RefTable, false); break; case BdatFieldType.Item: if (tables.Game == Game.XB2) { ApplyRef(BdatStringTools.GetItemTableXb2(refId)); } if (tables.Game == Game.XB1 || tables.Game == Game.XB1DE) { var itemType = (ItemTypeXb1)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetItemTableXb1(itemType)); } if (tables.Game == Game.XBX) { var itemType = (ItemTypeXbx)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetItemTableXbx(itemType)); } break; case BdatFieldType.Event: ApplyRef(BdatStringTools.GetEventTable(refId)); break; case BdatFieldType.EventSetup: ApplyRef(BdatStringTools.GetEventSetupTable(refId)); break; case BdatFieldType.Quest when tables.Game == Game.XB1DE: ApplyRef(BdatStringTools.GetQuestJournalTableXb1(refId)); break; case BdatFieldType.QuestMenu when tables.Game == Game.XB1DE: ApplyRef(BdatStringTools.GetQuestMenuTableXb1(refId)); break; case BdatFieldType.Quest: throw new InvalidDataException(); case BdatFieldType.QuestFlag: ApplyRef(BdatStringTools.GetQuestListTable(refId)); break; case BdatFieldType.QuestFlagIra: ApplyRef(BdatStringTools.GetQuestListIraTable(refId)); break; case BdatFieldType.Condition: if (tables.Game == Game.XB2) { var conditionType = (ConditionType)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetConditionTable(conditionType)); } if (tables.Game == Game.XBX) { var conditionType = (ConditionTypeXbx)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetConditionTableXbx(conditionType)); } break; case BdatFieldType.Task when tables.Game == Game.XB2: var taskType = (TaskType)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetTaskTable(taskType)); break; case BdatFieldType.Task when tables.Game == Game.XB1 || tables.Game == Game.XB1DE: var taskTypeXb1 = (TaskTypeXb1)int.Parse(item[field.RefField].ValueString); int itemId = int.Parse(item[field.Field].ValueString); ApplyRef(BdatStringTools.GetTaskTableXb1(taskTypeXb1, itemId)); break; case BdatFieldType.ShopTable: var shopType = (ShopType)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetShopTable(shopType)); break; case BdatFieldType.Character: ApplyRef(BdatStringTools.GetCharacterTable(refId)); break; case BdatFieldType.Enhance: if (tables.Game == Game.XB2) { value.Display = BdatStringTools.GetEnhanceCaption(value); } if (tables.Game == Game.XBX) { value.Display = BdatStringTools.GetEnhanceCaptionXbx(value); } break; case BdatFieldType.WeatherIdMap: value.Display = BdatStringTools.PrintWeatherIdMap(refId, 13, tables); break; case BdatFieldType.PouchBuff: value.Display = GetPouchBuffCaption(value); break; case BdatFieldType.Flag: AddFlag(tables, field.RefTable, refId, value); break; case BdatFieldType.GameFlag: string flagType = item[field.RefField].ValueString; AddFlag(tables, flagType + "bit", refId, value); break; case BdatFieldType.Change: var changeType = (ChangeType)int.Parse(item[field.RefField].ValueString); if (changeType == ChangeType.scenario) { AddFlag(tables, "Scenario", refId, value); } break; case BdatFieldType.ItemComment: ApplyRef(item.Id >= 1852 ? "MNU_item_mes_b" : "MNU_item_mes_a"); break; case BdatFieldType.Layer: ApplyRef(BdatStringTools.GetLayerTable(refId)); break; case BdatFieldType.Place: var placeCat = (PlaceCategory)int.Parse(item[field.RefField].ValueString); string placeTable = GimmickData.GetPlaceTable(placeCat, refId); if (placeTable != null) { ApplyRef(placeTable); } break; case BdatFieldType.Enemy when tables.Game == Game.XB1DE: ApplyRef(BdatStringTools.GetEnemyTableXb1(refId), member.Type != BdatMemberType.None); break; case BdatFieldType.ArmorStyle when tables.Game == Game.XB1DE: { int characterId = int.Parse(item[field.RefField].ValueString); int equipItemId = int.Parse(item[field.Field].ValueString); if (equipItemId != 0) { ApplyRef(BdatStringTools.GetArmorStyleTableXb1(characterId)); } break; } case BdatFieldType.WeaponStyle when tables.Game == Game.XB1DE: { int characterId = 0; int equipItemId = int.Parse(item[field.Field].ValueString); for (int i = 0; i <= 16; i++) { string fieldName = $"equip_pc{i}"; if (item.Values.TryGetValue(fieldName, out BdatStringValue equipPcValue)) { if (equipPcValue.ValueString == "1") { characterId = i; break; } } } if (equipItemId != 0 && characterId != 0) { ApplyRef(BdatStringTools.GetWeaponStyleTableXb1(characterId)); } break; } } if (field.EnumType != null) { if (field.EnumType.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0) { value.Display = BdatStringTools.PrintEnumFlags(field.EnumType, refId); } else { value.Display = Enum.GetName(field.EnumType, refId); } } value.Resolved = true; void ApplyRef(string refTable, bool addReverseRef = true) { if (refTable == null || !tables.Tables.ContainsKey(refTable) || !tables[refTable].ContainsId(refId)) { value.Display = refId == 0 ? null : refId.ToString(); return; } BdatStringValue reft = tables[refTable][refId].Display; if (reft != null) { if (!reft.Resolved) { ResolveItemRef(reft); } if (!string.IsNullOrWhiteSpace(reft.DisplayString)) { value.Display = reft.Display; } } value.Reference = tables[refTable][refId]; if (addReverseRef) { tables[refTable][refId].ReferencedBy.Add(value.Parent); } } }
public static void PrintTable(BdatStringTable table, Indenter sb) { sb.AppendLineAndIncrease("<table class=\"sortable\">"); sb.AppendLineAndIncrease("<thead>"); sb.AppendLineAndIncrease("<tr id=\"header\">"); sb.AppendLine("<th class=\" dir-d \">ID</th>"); sb.AppendLine("<th>Referenced By</th>"); foreach (BdatMember member in table.Members) { if (member.Metadata?.Type == BdatFieldType.Hide) { continue; } bool sticky = table.DisplayMember == member.Name; string cellTag = $"<th{(sticky ? " class=\"side\"" : "")}"; switch (member.Type) { case BdatMemberType.Scalar: case BdatMemberType.Flag: sb.AppendLine($"{cellTag}>{member.Name}</th>"); break; case BdatMemberType.Array: sb.AppendLine($"{cellTag} colspan=\"{member.ArrayCount}\">{member.Name}</th>"); break; } } sb.DecreaseAndAppendLine("</tr>"); sb.DecreaseAndAppendLine("</thead>"); foreach (BdatStringItem item in table.Items.Where(x => x != null)) { sb.AppendLineAndIncrease($"<tr id=\"{item.Id}\">"); sb.AppendLine($"<td>{item.Id}</td>"); sb.AppendLineAndIncrease("<td>"); if (item.ReferencedBy.Count > 0) { sb.AppendLineAndIncrease("<details>"); sb.AppendLine($"<summary>{item.ReferencedBy.Count} refs</summary>"); foreach (BdatStringItem a in item.ReferencedBy.OrderBy(x => x.Table.Name).ThenBy(x => x.Id)) { string link = GetLink(table, a.Table, a.Id.ToString()); string display = (string)a.Display?.Display ?? a.Id.ToString(); if (string.IsNullOrWhiteSpace(display)) { display = a.Id.ToString(); } sb.AppendLine($"<a href=\"{link}\">{a.Table.Name}#{display}</a>"); } sb.DecreaseAndAppendLine("</details>"); } sb.DecreaseAndAppendLine("</td>"); foreach (BdatStringValue value in item.Values.Values) { BdatMember member = value.Member; if (member.Metadata?.Type == BdatFieldType.Hide) { continue; } bool sticky = value.Parent.Display == value; string cellTag = $"<td{(sticky ? " class=\"side\"" : "")}>"; switch (member.Type) { case BdatMemberType.Scalar: case BdatMemberType.Flag: PrintValue(value, cellTag); break; case BdatMemberType.Array: foreach (BdatStringValue arrValue in value.Array) { PrintValue(arrValue, cellTag); } break; } } sb.DecreaseAndAppendLine("</tr>"); } sb.DecreaseAndAppendLine("</table>"); void PrintValue(BdatStringValue value, string cellTag) { BdatStringItem child = value.Reference; if (child != null) { string display = child.Display?.DisplayString; if (string.IsNullOrWhiteSpace(display)) { display = child.Id.ToString(); } string link = GetLink(table, child.Table, child.Id.ToString()); sb.AppendLine($"{cellTag}<a href=\"{link}\">{WebUtility.HtmlEncode(display)}</td></a>"); } else { sb.AppendLine($"{cellTag}{WebUtility.HtmlEncode(value.DisplayString)}</td>"); } } }
public static void ResolveItemRef(BdatStringValue value) { if (value.Resolved) return; BdatStringItem item = value.Parent; BdatStringTable table = item.Table; BdatStringCollection tables = table.Collection; BdatMember member = value.Member; BdatFieldInfo field = member.Metadata; if (value.Array != null) { foreach (var element in value.Array) { ResolveItemRef(element); } value.Resolved = true; return; } if (field == null) { value.Resolved = true; return; } int refId = int.Parse(value.ValueString) + field.Adjust; switch (field.Type) { case BdatFieldType.Message: value.Display = tables[field.RefTable][refId]?["name"].DisplayString; if (string.IsNullOrWhiteSpace(value.DisplayString) && refId > 0) { value.Display = refId.ToString(); } break; case BdatFieldType.Reference: ApplyRef(field.RefTable); break; case BdatFieldType.Item: if (tables.Game == Game.XB2) ApplyRef(BdatStringTools.GetItemTableXb2(refId)); if (tables.Game == Game.XB1) { var itemType = (ItemTypeXb1)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetItemTableXb1(itemType)); } if (tables.Game == Game.XBX) { var itemType = (ItemTypeXbx)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetItemTableXbx(itemType)); } break; case BdatFieldType.Event: ApplyRef(BdatStringTools.GetEventTable(refId)); break; case BdatFieldType.EventSetup: ApplyRef(BdatStringTools.GetEventSetupTable(refId)); break; case BdatFieldType.QuestFlag: ApplyRef(BdatStringTools.GetQuestListTable(refId)); break; case BdatFieldType.QuestFlagIra: ApplyRef(BdatStringTools.GetQuestListIraTable(refId)); break; case BdatFieldType.Condition: var conditionType = (ConditionType)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetConditionTable(conditionType)); break; case BdatFieldType.Task: var taskType = (TaskType)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetTaskTable(taskType)); break; case BdatFieldType.ShopTable: var shopType = (ShopType)int.Parse(item[field.RefField].ValueString); ApplyRef(BdatStringTools.GetShopTable(shopType)); break; case BdatFieldType.Character: ApplyRef(BdatStringTools.GetCharacterTable(refId)); break; case BdatFieldType.Enhance: value.Display = BdatStringTools.GetEnhanceCaption(value); break; case BdatFieldType.WeatherIdMap: value.Display = BdatStringTools.PrintWeatherIdMap(refId, 13, tables); break; case BdatFieldType.PouchBuff: value.Display = GetPouchBuffCaption(value); break; case BdatFieldType.Flag: AddFlag(tables, field.RefTable, refId, value); break; case BdatFieldType.GameFlag: var flagType = item[field.RefField].ValueString; AddFlag(tables, flagType + "bit", refId, value); break; case BdatFieldType.Change: var changeType = (ChangeType)int.Parse(item[field.RefField].ValueString); if (changeType == ChangeType.scenario) { AddFlag(tables, "Scenario", refId, value); } break; case BdatFieldType.ItemComment: ApplyRef(item.Id >= 1852 ? "MNU_item_mes_b" : "MNU_item_mes_a"); break; case BdatFieldType.Layer: ApplyRef(BdatStringTools.GetLayerTable(refId)); break; } if (field.EnumType != null) { if (field.EnumType.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0) { value.Display = BdatStringTools.PrintEnumFlags(field.EnumType, refId); } else { value.Display = Enum.GetName(field.EnumType, refId); } } value.Resolved = true; void ApplyRef(string refTable) { if (refTable == null || !tables[refTable].ContainsId(refId)) { value.Display = refId == 0 ? null : refId.ToString(); return; } var reft = tables[refTable][refId].Display; if (reft != null) { if (!reft.Resolved) { ResolveItemRef(reft); } if (!string.IsNullOrWhiteSpace(reft.DisplayString)) { value.Display = reft.Display; } } value.Reference = tables[refTable][refId]; tables[refTable][refId].ReferencedBy.Add(value.Parent); } }