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 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; } 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: 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: 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: 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; } 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.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]; tables[refTable][refId].ReferencedBy.Add(value.Parent); } }