Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions BanjoBotAssets.Json/AlterationItemData.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/* Copyright 2023 Tara "Dino" Cassatt
*
* This file is part of BanjoBotAssets.
*
* BanjoBotAssets is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BanjoBotAssets is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BanjoBotAssets. If not, see <http://www.gnu.org/licenses/>.
*/
using Newtonsoft.Json;

namespace BanjoBotAssets.Json
{
[NamedItemData("Alteration")]
public sealed class AlterationItemData : NamedItemData
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, int>? AdditionalRespecCost { get; set; }
}
}
3 changes: 3 additions & 0 deletions BanjoBotAssets.Json/AlterationSlot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* You should have received a copy of the GNU General Public License
* along with BanjoBotAssets. If not, see <http://www.gnu.org/licenses/>.
*/
using Newtonsoft.Json;
using System.Diagnostics.CodeAnalysis;

namespace BanjoBotAssets.Json
Expand All @@ -24,5 +25,7 @@ public sealed class AlterationSlot
public int RequiredLevel { get; set; }
[DisallowNull]
public string[][]? Alterations { get; set; }
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public Dictionary<string, int>? BaseRespecCost { get; set; }
}
}
10 changes: 10 additions & 0 deletions BanjoBotAssets.Json/ExportedAssets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public sealed class ExportedAssets

public ItemRatingTables ItemRatings { get; } = new();

public SortedDictionary<string, int[]> ItemLevelsToXP { get; } = new();

public SortedDictionary<string, DifficultyInfo> DifficultyInfo { get; } = new(StringComparer.OrdinalIgnoreCase);

public SortedDictionary<string, string[][]> MainQuestLines { get; } = [];
Expand Down Expand Up @@ -65,6 +67,14 @@ public void Merge(ExportedAssets other)
ItemRatings.LeadSurvivor = other.ItemRatings.LeadSurvivor;
}

if(other.ItemLevelsToXP != null)
{
foreach (var (k, v) in other.ItemLevelsToXP)
{
ItemLevelsToXP[k] = v;
}
}

if (other.DifficultyInfo != null)
{
foreach (var (k, v) in other.DifficultyInfo)
Expand Down
4 changes: 2 additions & 2 deletions BanjoBotAssets.Json/HeroItemData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ namespace BanjoBotAssets.Json
[NamedItemData("Hero")]
public sealed class HeroItemData : NamedItemData
{
public string? HeroPerkName { get; set; }
public string? HeroPerkTemplate { get; set; }
[DisallowNull]
public string? HeroPerk { get; set; }
[DisallowNull]
public string? HeroPerkDescription { get; set; }
public string? CommanderPerkName { get; set; }
public string? CommanderPerkTemplate { get; set; }
[DisallowNull]
public string? CommanderPerk { get; set; }
[DisallowNull]
Expand Down
34 changes: 34 additions & 0 deletions BanjoBotAssets.Json/ItemRecipe.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/* Copyright 2023 Tara "Dino" Cassatt
*
* This file is part of BanjoBotAssets.
*
* BanjoBotAssets is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BanjoBotAssets is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BanjoBotAssets. If not, see <http://www.gnu.org/licenses/>.
*/
using Newtonsoft.Json;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace BanjoBotAssets.Json
{
public sealed class ItemRecipe
{
[DisallowNull]
public Dictionary<string, int>? Cost { get; set; }
[DisallowNull]
public string? Result { get; set; }
[DefaultValue(1)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public int? Amount { get; set; }
}
}
6 changes: 6 additions & 0 deletions BanjoBotAssets.Json/NamedItemData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ public class NamedItemData
[JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
public bool IsInventoryLimitExempt { get; set; }
public int? Tier { get; set; }

public ItemRecipe? TierUpRecipe { get; set; }
public ItemRecipe? RarityUpRecipe { get; set; }
public ItemRecipe? RecycleRecipe { get; set; }
public string? LevelToXPRow { get; set; }

[JsonProperty(Order = OrderedPropertiesContractResolver.DefaultOrder + 2)]
public SortedDictionary<ImageType, string>? ImagePaths { get; set; }

Expand Down
9 changes: 9 additions & 0 deletions BanjoBotAssets.Json/SchematicItemData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* along with BanjoBotAssets. If not, see <http://www.gnu.org/licenses/>.
*/
using Newtonsoft.Json;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

namespace BanjoBotAssets.Json
Expand All @@ -34,7 +35,15 @@ public sealed class SchematicItemData : NamedItemData
public MeleeWeaponStats? MeleeWeaponStats { get; set; }
public TrapStats? TrapStats { get; set; }

[DisallowNull]
public Dictionary<string, int>? CraftingCost { get; set; }
[DisallowNull]
public string? CraftingResult { get; set; }
[DefaultValue(1)]
[JsonProperty(DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate)]
public int? CraftingAmount { get; set; }

public ItemRecipe? AlternateTierUpRecipe { get; set; }
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
*/
namespace BanjoBotAssets.Exporters.Groups
{
internal sealed partial class DefenderExporter(IExporterContext services) : GroupExporter<UFortHeroType>(services)
internal sealed partial class DefenderExporterOld(IExporterContext services) : GroupExporter<UFortHeroType>(services)
{
protected override string Type => "Defender";

protected override bool InterestedInAsset(string name) =>
name.Contains("Defenders/DID_", StringComparison.OrdinalIgnoreCase);
protected override bool InterestedInAsset(string name) => false;
//name.Contains("Defenders/DID_", StringComparison.OrdinalIgnoreCase);

private static readonly Regex defenderAssetNameRegex = DefenderAssetNameRegex();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ internal sealed record HeroItemGroupFields(string DisplayName, string? Descripti
public HeroItemGroupFields() : this("", null, null, null, "", "", null, "", "", null, []) { }
}

internal sealed partial class HeroExporter(IExporterContext services) : GroupExporter<UFortHeroType, BaseParsedItemName, HeroItemGroupFields, HeroItemData>(services)
internal sealed partial class HeroExporterOld(IExporterContext services) : GroupExporter<UFortHeroType, BaseParsedItemName, HeroItemGroupFields, HeroItemData>(services)
{
private string? itemToQuestPath, questRewardsPath;
private readonly Dictionary<string, string> heroToTeamPerk = new(StringComparer.OrdinalIgnoreCase);
Expand All @@ -37,6 +37,7 @@ internal sealed partial class HeroExporter(IExporterContext services) : GroupExp

protected override bool InterestedInAsset(string name)
{
return false;
if (name.EndsWith("/ItemToQuestTable.uasset", StringComparison.OrdinalIgnoreCase))
{
itemToQuestPath = name;
Expand Down Expand Up @@ -203,10 +204,10 @@ private void InitHeroToTeamPerkMapping(UDataTable itemToQuestTable, UDataTable q

protected override Task<bool> ExportAssetAsync(BaseParsedItemName parsed, UFortHeroType primaryAsset, HeroItemGroupFields fields, string path, HeroItemData itemData)
{
itemData.HeroPerkName = fields.HeroPerkName;
itemData.HeroPerkTemplate = fields.HeroPerkName;
itemData.HeroPerk = fields.HeroPerk;
itemData.HeroPerkDescription = fields.HeroPerkDescription;
itemData.CommanderPerkName = fields.CommanderPerkName;
itemData.CommanderPerkTemplate = fields.CommanderPerkName;
itemData.CommanderPerk = fields.CommanderPerk;
itemData.CommanderPerkDescription = fields.CommanderPerkDescription;
itemData.HeroAbilities = fields.HeroAbilities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal sealed record SchematicItemGroupFields(string DisplayName, string? Desc
public SchematicItemGroupFields() : this("", null, null, "", "", "", "", "", "") { }
}

internal sealed partial class SchematicExporter(IExporterContext services) : GroupExporter<UObject, ParsedSchematicName, SchematicItemGroupFields, SchematicItemData>(services)
internal sealed partial class SchematicExporterOld(IExporterContext services) : GroupExporter<UObject, ParsedSchematicName, SchematicItemGroupFields, SchematicItemData>(services)
{
private readonly Dictionary<string, string> craftingResultPaths = new(StringComparer.OrdinalIgnoreCase);
private string? craftingPath, alterationGroupPath, slotDefsPath, slotLoadoutsPath, meleeWeaponsPath, rangedWeaponsPath, trapsPath, durabilityPath, namedExclusionsPath;
Expand All @@ -46,6 +46,7 @@ internal sealed partial class SchematicExporter(IExporterContext services) : Gro

protected override bool InterestedInAsset(string name)
{
return false;
// we only export SID_ assets directly, but we also want to keep track of:
// Assets that might be crafting results: WID_*, TID_*, G_*, Ingredient_*, AmmoData*
// AlterationGroups
Expand Down Expand Up @@ -249,7 +250,7 @@ protected override async Task<SchematicItemGroupFields> ExtractCommonFieldsAsync
*
* Instead, we rely on the knowledge that mythic items don't occur in any other rarities.
*
* We use a similar technique here and in <see cref="HeroExporter"/>: ensuring the primary asset has
* We use a similar technique here and in <see cref="HeroExporterOld"/>: ensuring the primary asset has
* "sr" parsed rarity in <see cref="SelectPrimaryAsset"/>, and checking the primary asset's
* display rarity in <see cref="GetRarity"/>.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ internal sealed record SurvivorItemGroupFields(string DisplayName, string? Descr
public SurvivorItemGroupFields() : this("", null, null, null) { }
}

internal sealed partial class SurvivorExporter(IExporterContext services) : GroupExporter<UFortWorkerType, BaseParsedItemName, SurvivorItemGroupFields, SurvivorItemData>(services)
internal sealed partial class SurvivorExporterOld(IExporterContext services) : GroupExporter<UFortWorkerType, BaseParsedItemName, SurvivorItemGroupFields, SurvivorItemData>(services)
{
protected override string Type => "Worker";

protected override bool InterestedInAsset(string name) =>
name.Contains("Workers/Worker", StringComparison.OrdinalIgnoreCase) || name.Contains("Managers/Manager", StringComparison.OrdinalIgnoreCase);
protected override bool InterestedInAsset(string name) => false;
//name.Contains("Workers/Worker", StringComparison.OrdinalIgnoreCase) || name.Contains("Managers/Manager", StringComparison.OrdinalIgnoreCase);

// regular survivor: WorkerBasic_SR_T02
// special survivor: Worker_Leprechaun_VR_T01, WorkerHalloween_VR_T04
Expand Down
17 changes: 17 additions & 0 deletions BanjoBotAssets/Exporters/Helpers/AssetOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ namespace BanjoBotAssets.Exporters.Helpers
internal sealed class AssetOutput : IAssetOutput
{
private ItemRatingTable? defaultItemRatings, survivorItemRatings, leadSurvivorItemRatings;
private Dictionary<string, int[]>? levelToXP;

private readonly ConcurrentDictionary<string, NamedItemData> namedItems = new(StringComparer.OrdinalIgnoreCase);
private readonly ConcurrentDictionary<ImageType, ConcurrentDictionary<string, string>> namedItemImages = new();
private readonly ConcurrentDictionary<string, DifficultyInfo> difficultyInfo = new(StringComparer.OrdinalIgnoreCase);
Expand Down Expand Up @@ -73,6 +75,11 @@ public void AddSurvivorItemRatings(ItemRatingTable itemRatings)
survivorItemRatings = itemRatings;
}

public void AddLevelToXPTable(Dictionary<string, int[]> levelToXPTable)
{
levelToXP = levelToXPTable;
}

public void CopyTo(ExportedAssets exportedAssets, IList<ExportedRecipe> exportedRecipes, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
Expand Down Expand Up @@ -112,6 +119,16 @@ public void CopyTo(ExportedAssets exportedAssets, IList<ExportedRecipe> exported

cancellationToken.ThrowIfCancellationRequested();

if (levelToXP != null)
{
foreach (var (k, v) in levelToXP)
{
exportedAssets.ItemLevelsToXP.Add(k, v);
}
}

cancellationToken.ThrowIfCancellationRequested();

foreach (var (k, v) in mainQuestLines)
{
exportedAssets.MainQuestLines.TryAdd(k, v);
Expand Down
2 changes: 2 additions & 0 deletions BanjoBotAssets/Exporters/Helpers/IAssetOutput.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ internal interface IAssetOutput
void AddSurvivorItemRatings(ItemRatingTable itemRatings);
void AddLeadSurvivorItemRatings(ItemRatingTable itemRatings);

public void AddLevelToXPTable(Dictionary<string, int[]> levelToXPTable);

void AddCraftingRecipe(string name, IReadOnlyDictionary<string, int> ingredients);
void AddDisplayNameCorrection(string schematicTemplateId, string v);

Expand Down
37 changes: 30 additions & 7 deletions BanjoBotAssets/Exporters/UObjects/AlterationExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,43 @@
* You should have received a copy of the GNU General Public License
* along with BanjoBotAssets. If not, see <http://www.gnu.org/licenses/>.
*/
using BanjoBotAssets.UExports;

namespace BanjoBotAssets.Exporters.UObjects
{
internal sealed class AlterationExporter(IExporterContext services) : UObjectExporter<UFortItemDefinition>(services)
internal sealed class AlterationExporter(IExporterContext services) : UObjectExporter<UFortItemDefinition, AlterationItemData>(services)
{
protected override string Type => "Alteration";
private string? metaPath;
protected override bool InterestedInAsset(string name)
{
if(Path.GetFileName(name).Equals("MetaRecipes.uasset", StringComparison.OrdinalIgnoreCase))
{
metaPath = name;
}

return name.Contains("/AID_", StringComparison.OrdinalIgnoreCase) &&
(name.Contains("/Alteration_v2/", StringComparison.OrdinalIgnoreCase) || name.Contains("/Defenders/", StringComparison.OrdinalIgnoreCase));
}
public override async Task ExportAssetsAsync(IProgress<ExportProgress> progress, IAssetOutput output, CancellationToken cancellationToken)
{
metaRecipeTable = (await TryLoadTableAsync(metaPath))?.ToDictionary<FRecipe>();

protected override bool InterestedInAsset(string name) =>
name.Contains("/AID_", StringComparison.OrdinalIgnoreCase) &&
(name.Contains("/Alteration_v2/", StringComparison.OrdinalIgnoreCase) || name.Contains("/Defenders/", StringComparison.OrdinalIgnoreCase));
await base.ExportAssetsAsync(progress, output, cancellationToken);
}

protected override Task<bool> ExportAssetAsync(UFortItemDefinition asset, NamedItemData namedItemData, Dictionary<ImageType, string> imagePaths)
protected override Task<bool> ExportAssetAsync(UFortItemDefinition asset, AlterationItemData itemData, Dictionary<ImageType, string> imagePaths)
{
namedItemData.DisplayName = asset.ItemDescription?.Text ?? $"<Alteration:{asset.Name}>";
namedItemData.Description = null;
itemData.DisplayName = asset.ItemDescription?.Text ?? $"<Alteration:{asset.Name}>";
itemData.Description = null;

var extraRespecCost = asset.GetOrDefault<FFortItemQuantityPair[]>("AdditionalRespecCosts")?.ToDictionary(
p => $"{p.ItemPrimaryAssetId.PrimaryAssetType.Name.Text}:{p.ItemPrimaryAssetId.PrimaryAssetName.Text}",
p => p.Quantity,
StringComparer.OrdinalIgnoreCase
);
itemData.AdditionalRespecCost = extraRespecCost?.Count == 0 ? null : extraRespecCost;

return Task.FromResult(true);
}
}
Expand Down
43 changes: 43 additions & 0 deletions BanjoBotAssets/Exporters/UObjects/DefenderExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Copyright 2023 Tara "Dino" Cassatt
*
* This file is part of BanjoBotAssets.
*
* BanjoBotAssets is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BanjoBotAssets is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BanjoBotAssets. If not, see <http://www.gnu.org/licenses/>.
*/

namespace BanjoBotAssets.Exporters.UObjects
{
internal sealed class DefenderExporter(IExporterContext services) : UObjectExporter<UFortHeroType, NamedItemData>(services)
{
protected override string Type => "Defender";
protected override bool RequireRarity => true;

protected override bool InterestedInAsset(string name) =>
name.Contains("Defenders/DID_", StringComparison.OrdinalIgnoreCase);

protected override Task<bool> ExportAssetAsync(UFortHeroType asset, NamedItemData itemData, Dictionary<ImageType, string> imagePaths)
{
var category = asset.AttributeInitKey?.AttributeInitCategory.Text;

if (category != null)
{
string[] splitCategory = category.Split('_');
itemData.SubType = $"{splitCategory[1]} {splitCategory[0]}";
itemData.DisplayName = asset.ItemName?.Text ?? $"{itemData.Rarity} {itemData.SubType}";
}

return Task.FromResult(true);
}
}
}
Loading