diff --git a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Reliquary/ReliquaryWeightConfigurationGenerator.cs b/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Reliquary/ReliquaryWeightConfigurationGenerator.cs deleted file mode 100644 index 8009c9c5..00000000 --- a/src/Snap.Hutao/Snap.Hutao.SourceGeneration/Reliquary/ReliquaryWeightConfigurationGenerator.cs +++ /dev/null @@ -1,133 +0,0 @@ -using Microsoft.CodeAnalysis; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.IO; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; - -namespace Snap.Hutao.SourceGeneration.Reliquary; - -[Generator(LanguageNames.CSharp)] -internal sealed class ReliquaryWeightConfigurationGenerator : IIncrementalGenerator -{ - private const string FileName = "ReliquaryWeightConfiguration.json"; - - public void Initialize(IncrementalGeneratorInitializationContext context) - { - IncrementalValueProvider> provider = context.AdditionalTextsProvider.Where(MatchFileName).Collect(); - - context.RegisterSourceOutput(provider, GenerateReliquaryWeightConfiguration); - } - - private static bool MatchFileName(AdditionalText text) - { - return Path.GetFileName(text.Path) == FileName; - } - - private static void GenerateReliquaryWeightConfiguration(SourceProductionContext context, ImmutableArray texts) - { - AdditionalText jsonFile = texts.Single(); - - string configurationJson = jsonFile.GetText(context.CancellationToken)!.ToString(); - Dictionary metadataMap = - configurationJson.FromJson>()!; - - StringBuilder sourceBuilder = new StringBuilder().Append($$""" - // Copyright (c) DGP Studio. All rights reserved. - // Licensed under the MIT license. - - namespace Snap.Hutao.Service.AvatarInfo.Factory; - - /// - /// 圣遗物评分权重配置 - /// - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("{{nameof(ReliquaryWeightConfigurationGenerator)}}","1.0.0.0")] - internal static class ReliquaryWeightConfiguration - { - /// - /// 默认 - /// - public static readonly AffixWeight Default = new(0, 100, 75, 0, 100, 100, 0, 55, 0); - - /// - /// 词条权重 - /// - public static readonly List AffixWeights = new() - { - - """); - - foreach (KeyValuePair kvp in metadataMap.OrderBy(kvp => kvp.Key)) - { - AppendAffixWeight(sourceBuilder, kvp.Key, kvp.Value); - } - - sourceBuilder.Append($$""" - }; - } - """); - - context.AddSource("ReliquaryWeightConfiguration.g.cs", sourceBuilder.ToString()); - } - - private static void AppendAffixWeight(StringBuilder builder, string id, ReliquaryWeightConfigurationMetadata metadata) - { - StringBuilder lineBuilder = new StringBuilder() - .Append(" new AffixWeight(").Append(id).Append(',') - .Append(' ').Append(metadata.Hp).Append(',') - .Append(' ').Append(metadata.Attack).Append(',') - .Append(' ').Append(metadata.Defense).Append(',') - .Append(' ').Append(metadata.CritRate).Append(',') - .Append(' ').Append(metadata.CritHurt).Append(',') - .Append(' ').Append(metadata.Mastery).Append(',') - .Append(' ').Append(metadata.Recharge).Append(',') - .Append(' ').Append(metadata.Healing).Append(')') - .Append('.').Append(metadata.ElementType).Append("(").Append(metadata.ElementHurt).Append(')'); - - if (metadata.PhysicialHurt != 0) - { - lineBuilder.Append(".Physical(").Append(metadata.PhysicialHurt).Append(')'); - } - - lineBuilder.Append(','); - - builder.AppendLine(lineBuilder.ToString()); - } - - private sealed class ReliquaryWeightConfigurationMetadata - { - [DataMember(Name = "hp")] - public int Hp { get; set; } - - [DataMember(Name = "atk")] - public int Attack { get; set; } - - [DataMember(Name = "def")] - public int Defense { get; set; } - - [DataMember(Name = "cpct")] - public int CritRate { get; set; } - - [DataMember(Name = "cdmg")] - public int CritHurt { get; set; } - - [DataMember(Name = "mastery")] - public int Mastery { get; set; } - - [DataMember(Name = "recharge")] - public int Recharge { get; set; } - - [DataMember(Name = "heal")] - public int Healing { get; set; } - - [DataMember(Name = "element")] - public string ElementType { get; set; } = default!; - - [DataMember(Name = "dmg")] - public int ElementHurt { get; set; } - - [DataMember(Name = "phy")] - public int PhysicialHurt { get; set; } - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs index f1212ee9..2a0ac8fa 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Reliquary/ReliquaryAffixWeight.cs @@ -11,6 +11,29 @@ namespace Snap.Hutao.Model.Metadata.Reliquary; /// internal sealed class ReliquaryAffixWeight { + private static ReliquaryAffixWeight? defaultValue; + + /// + /// 默认权重 + /// + public static ReliquaryAffixWeight Default + { + get + { + return defaultValue ??= new() + { + HpPercent = 0, + AttackPercent = 75, + DefensePercent = 0, + Critical = 100, + CriticalHurt = 100, + ElementMastery = 0, + ChargeEfficiency = 55, + HealAdd = 0, + }; + } + } + /// /// 角色 Id /// diff --git a/src/Snap.Hutao/Snap.Hutao/ReliquaryWeightConfiguration.json b/src/Snap.Hutao/Snap.Hutao/ReliquaryWeightConfiguration.json deleted file mode 100644 index e2f09951..00000000 --- a/src/Snap.Hutao/Snap.Hutao/ReliquaryWeightConfiguration.json +++ /dev/null @@ -1,820 +0,0 @@ -{ - "10000066": { - "hp": 50, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Hydro" - }, - "10000058": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Electro" - }, - "10000063": { - "hp": 0, - "atk": 100, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Cryo" - }, - "10000064": { - "hp": 0, - "atk": 75, - "def": 100, - "cpct": 80, - "cdmg": 80, - "mastery": 0, - "dmg": 80, - "phy": 0, - "recharge": 80, - "heal": 0, - "element": "Geo" - }, - "10000057": { - "hp": 0, - "atk": 50, - "def": 100, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Geo" - }, - "10000055": { - "hp": 0, - "atk": 75, - "def": 100, - "cpct": 50, - "cdmg": 50, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 0, - "element": "Geo" - }, - "10000032": { - "hp": 100, - "atk": 50, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 80, - "phy": 0, - "recharge": 55, - "heal": 100, - "element": "Pyro" - }, - "10000047": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 100, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Anemo" - }, - "10000025": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 0, - "element": "Hydro" - }, - "10000030": { - "hp": 80, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 50, - "recharge": 55, - "heal": 0, - "element": "Geo" - }, - "10000002": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Cryo" - }, - "10000023": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Pyro" - }, - "10000046": { - "hp": 80, - "atk": 50, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 0, - "heal": 0, - "element": "Pyro" - }, - "10000022": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Anemo" - }, - "10000054": { - "hp": 100, - "atk": 50, - "def": 0, - "cpct": 0, - "cdmg": 0, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 100, - "element": "Hydro" - }, - "10000041": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 0, - "element": "Hydro" - }, - "10000038": { - "hp": 0, - "atk": 0, - "def": 100, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 0, - "heal": 0, - "element": "Geo" - }, - "10000039": { - "hp": 100, - "atk": 50, - "def": 0, - "cpct": 50, - "cdmg": 50, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 90, - "heal": 100, - "element": "Cryo" - }, - "10000051": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 40, - "phy": 100, - "recharge": 55, - "heal": 0, - "element": "Cryo" - }, - "10000033": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Hydro" - }, - "10000026": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Anemo" - }, - "10000049": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 0, - "heal": 0, - "element": "Pyro" - }, - "10000056": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Electro" - }, - "10000003": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 100, - "recharge": 55, - "heal": 100, - "element": "Anemo" - }, - "10000031": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 60, - "recharge": 0, - "heal": 0, - "element": "Electro" - }, - "10000045": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 70, - "phy": 80, - "recharge": 30, - "heal": 0, - "element": "Cryo" - }, - "10000029": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Pyro" - }, - "10000027": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Geo" - }, - "10000024": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Electro" - }, - "10000042": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 100, - "recharge": 0, - "heal": 0, - "element": "Electro" - }, - "10000050": { - "hp": 90, - "atk": 55, - "def": 0, - "cpct": 90, - "cdmg": 90, - "mastery": 75, - "dmg": 90, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Pyro" - }, - "10000016": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 0, - "heal": 0, - "element": "Pyro" - }, - "10000034": { - "hp": 0, - "atk": 50, - "def": 90, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 70, - "heal": 0, - "element": "Geo" - }, - "10000036": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Cryo" - }, - "10000035": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 100, - "recharge": 55, - "heal": 100, - "element": "Cryo" - }, - "10000015": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 100, - "recharge": 30, - "heal": 0, - "element": "Cryo" - }, - "10000048": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Pyro" - }, - "10000053": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 100, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 100, - "element": "Anemo" - }, - "10000021": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 100, - "recharge": 0, - "heal": 0, - "element": "Pyro" - }, - "10000006": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 0, - "heal": 0, - "element": "Electro" - }, - "10000062": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 0, - "heal": 0, - "element": "Cryo" - }, - "10000044": { - "hp": 0, - "atk": 75, - "def": 75, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 100, - "recharge": 0, - "heal": 0, - "element": "Pyro" - }, - "10000043": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 100, - "dmg": 75, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Anemo" - }, - "10000020": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 100, - "recharge": 0, - "heal": 0, - "element": "Electro" - }, - "10000060": { - "hp": 80, - "atk": 0, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Hydro" - }, - "10000065": { - "hp": 100, - "atk": 50, - "def": 0, - "cpct": 50, - "cdmg": 50, - "mastery": 100, - "dmg": 75, - "phy": 0, - "recharge": 55, - "heal": 100, - "element": "Electro" - }, - "10000059": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Anemo" - }, - "10000069": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 90, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Dendro" - }, - "10000067": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Dendro" - }, - "10000071": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Electro" - }, - "10000072": { - "hp": 75, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Hydro" - }, - "10000070": { - "hp": 100, - "atk": 0, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 80, - "dmg": 100, - "phy": 0, - "recharge": 30, - "heal": 0, - "element": "Hydro" - }, - "10000073": { - "hp": 0, - "atk": 55, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 100, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Dendro" - }, - "10000068": { - "hp": 75, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 75, - "phy": 0, - "recharge": 55, - "heal": 100, - "element": "Electro" - }, - "10000074": { - "hp": 100, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 35, - "element": "Cryo" - }, - "10000075": { - "hp": 0, - "atk": 80, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 35, - "heal": 0, - "element": "Anemo" - }, - "10000076": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 0, - "element": "Anemo" - }, - "10000077": { - "hp": 100, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 100, - "element": "Dendro" - }, - "10000078": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 100, - "dmg": 100, - "phy": 0, - "recharge": 35, - "heal": 0, - "element": "Dendro" - }, - "10000079": { - "hp": 75, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 100, - "dmg": 100, - "phy": 0, - "recharge": 55, - "heal": 0, - "element": "Pyro" - }, - "10000080": { - "hp": 75, - "atk": 55, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 0, - "dmg": 75, - "phy": 75, - "recharge": 55, - "heal": 100, - "element": "Cryo" - }, - "10000082": { - "hp": 100, - "atk": 0, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 100, - "element": "Dendro" - }, - "10000081": { - "hp": 0, - "atk": 75, - "def": 0, - "cpct": 100, - "cdmg": 100, - "mastery": 75, - "dmg": 100, - "phy": 0, - "recharge": 75, - "heal": 0, - "element": "Dendro" - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs deleted file mode 100644 index 66904676..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/AffixWeight.cs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -using Snap.Hutao.Model.Intrinsic; -using Snap.Hutao.Model.Primitive; - -namespace Snap.Hutao.Service.AvatarInfo.Factory; - -/// -/// 词条权重 -/// -[HighQuality] -internal sealed class AffixWeight : Dictionary -{ - /// - /// 构造一个新的词条权重 - /// - /// 角色Id - /// 大生命 - /// 大攻击 - /// 大防御 - /// 暴击率 - /// 暴击伤害 - /// 元素精通 - /// 充能效率 - /// 治疗加成 - /// 名称 - public AffixWeight( - uint avatarId, - float hp, - float atk, - float def, - float crit, - float critHurt, - float mastery, - float charge, - float heal, - string name = "通用") - { - AvatarId = avatarId; - Name = name; - - this[FightProperty.FIGHT_PROP_HP_PERCENT] = hp; - this[FightProperty.FIGHT_PROP_ATTACK_PERCENT] = atk; - this[FightProperty.FIGHT_PROP_DEFENSE_PERCENT] = def; - this[FightProperty.FIGHT_PROP_CRITICAL] = crit; - this[FightProperty.FIGHT_PROP_CRITICAL_HURT] = critHurt; - this[FightProperty.FIGHT_PROP_ELEMENT_MASTERY] = mastery; - this[FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY] = charge; - this[FightProperty.FIGHT_PROP_HEAL_ADD] = heal; - } - - /// - /// 角色Id - /// - public AvatarId AvatarId { get; } - - /// - /// 名称 - /// - public string Name { get; } - - /// - /// 风元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Anemo(float value = 100) - { - this[FightProperty.FIGHT_PROP_WIND_ADD_HURT] = value; - return this; - } - - /// - /// 冰元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Cryo(float value = 100) - { - this[FightProperty.FIGHT_PROP_ICE_ADD_HURT] = value; - return this; - } - - /// - /// 草元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Dendro(float value = 100) - { - this[FightProperty.FIGHT_PROP_GRASS_ADD_HURT] = value; - return this; - } - - /// - /// 雷元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Electro(float value = 100) - { - this[FightProperty.FIGHT_PROP_ELEC_ADD_HURT] = value; - return this; - } - - /// - /// 岩元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Geo(float value = 100) - { - this[FightProperty.FIGHT_PROP_ROCK_ADD_HURT] = value; - return this; - } - - /// - /// 水元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Hydro(float value = 100) - { - this[FightProperty.FIGHT_PROP_WATER_ADD_HURT] = value; - return this; - } - - /// - /// 火元素伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Pyro(float value = 100) - { - this[FightProperty.FIGHT_PROP_FIRE_ADD_HURT] = value; - return this; - } - - /// - /// 物理伤害伤害加成 - /// - /// 值 - /// 链式调用对象 - public AffixWeight Physical(float value = 100) - { - this[FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT] = value; - return this; - } -} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs index 856c6b6d..3fe27c9c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryAvatarFactory.cs @@ -58,10 +58,10 @@ internal sealed class SummaryAvatarFactory Skills = SummaryHelper.CreateSkills(avatarInfo.SkillLevelMap, avatarInfo.ProudSkillExtraLevelMap, avatar.SkillDepot.CompositeSkillsNoInherents()), // webinfo part - FetterLevel = avatarInfo.FetterInfo?.ExpLevel ?? 0, + FetterLevel = avatarInfo.FetterInfo?.ExpLevel ?? 0U, Properties = SummaryAvatarProperties.Create(avatarInfo.FightPropMap), CritScore = $"{SummaryHelper.ScoreCrit(avatarInfo.FightPropMap):F2}", - LevelNumber = avatarInfo.PropMap?[PlayerProperty.PROP_LEVEL].Value ?? 0, + LevelNumber = avatarInfo.PropMap?[PlayerProperty.PROP_LEVEL].Value ?? 0U, // processed webinfo part Weapon = reliquaryAndWeapon.Weapon, diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs index c06ed801..cda31d4e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryFactory.cs @@ -25,7 +25,8 @@ internal sealed partial class SummaryFactory : ISummaryFactory { IdAvatarMap = await metadataService.GetIdToAvatarMapAsync(token).ConfigureAwait(false), IdWeaponMap = await metadataService.GetIdToWeaponMapAsync(token).ConfigureAwait(false), - IdRelicMainPropMap = await metadataService.GetIdToReliquaryMainPropertyMapAsync(token).ConfigureAwait(false), + IdReliquaryAffixWeightMap = await metadataService.GetIdToReliquaryAffixWeightMapAsync(token).ConfigureAwait(false), + IdReliquaryMainAffixMap = await metadataService.GetIdToReliquaryMainPropertyMapAsync(token).ConfigureAwait(false), IdReliquarySubAffixMap = await metadataService.GetIdToReliquarySubAffixMapAsync(token).ConfigureAwait(false), ReliqueryLevels = await metadataService.GetReliquaryLevelsAsync(token).ConfigureAwait(false), Reliquaries = await metadataService.GetReliquariesAsync(token).ConfigureAwait(false), diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs index 612c3448..6fe88a6e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryMetadataContext.cs @@ -26,10 +26,15 @@ internal sealed class SummaryMetadataContext /// public Dictionary IdWeaponMap { get; set; } = default!; + /// + /// 权重映射 + /// + public Dictionary IdReliquaryAffixWeightMap { get; set; } = default!; + /// /// 圣遗物主属性映射 /// - public Dictionary IdRelicMainPropMap { get; set; } = default!; + public Dictionary IdReliquaryMainAffixMap { get; set; } = default!; /// /// 圣遗物副属性映射 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs index 90c248bc..79899e43 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AvatarInfo/Factory/SummaryReliquaryFactory.cs @@ -10,9 +10,7 @@ using Snap.Hutao.ViewModel.AvatarProperty; using Snap.Hutao.Web.Enka.Model; using System.Runtime.InteropServices; using MetadataReliquary = Snap.Hutao.Model.Metadata.Reliquary.Reliquary; -using MetadataReliquaryAffix = Snap.Hutao.Model.Metadata.Reliquary.ReliquarySubAffix; using ModelAvatarInfo = Snap.Hutao.Web.Enka.Model.AvatarInfo; -using PropertyReliquary = Snap.Hutao.ViewModel.AvatarProperty.ReliquaryView; namespace Snap.Hutao.Service.AvatarInfo.Factory; @@ -43,14 +41,14 @@ internal sealed class SummaryReliquaryFactory /// 构造圣遗物 /// /// 圣遗物 - public PropertyReliquary CreateReliquary() + public ReliquaryView CreateReliquary() { MetadataReliquary reliquary = metadataContext.Reliquaries.Single(r => r.Ids.Contains(equip.ItemId)); List subProperty = equip.Reliquary!.AppendPropIdList.EmptyIfNull().SelectList(CreateSubProperty); int affixCount = GetSecondaryAffixCount(reliquary); - PropertyReliquary result = new() + ReliquaryView result = new() { // NameIconDescription Name = reliquary.Name, @@ -69,7 +67,7 @@ internal sealed class SummaryReliquaryFactory result.SecondarySubProperties = new(span[^affixCount..].ToArray()); result.ComposedSubProperties = equip.Flat.ReliquarySubstats!.SelectList(CreateComposedSubProperty); ReliquaryMainAffixLevel relicLevel = metadataContext.ReliqueryLevels.Single(r => r.Level == equip.Reliquary!.Level && r.Rank == reliquary.RankLevel); - FightProperty property = metadataContext.IdRelicMainPropMap[equip.Reliquary.MainPropId]; + FightProperty property = metadataContext.IdReliquaryMainAffixMap[equip.Reliquary.MainPropId]; result.MainProperty = FightPropertyFormat.ToNameValue(property, relicLevel.PropertyMap[property]); result.Score = ScoreReliquary(property, reliquary, relicLevel, subProperty); @@ -115,13 +113,18 @@ internal sealed class SummaryReliquaryFactory { // 沙 杯 头 // equip.Flat.EquipType is EquipType.EQUIP_SHOES or EquipType.EQUIP_RING or EquipType.EQUIP_DRESS - if ((int)equip.Flat.EquipType > 3) + if (equip.Flat.EquipType > EquipType.EQUIP_SHOES) { - AffixWeight weightConfig = GetAffixWeightForAvatarId(); + ReliquaryAffixWeight affixWeight = metadataContext.IdReliquaryAffixWeightMap.GetValueOrDefault(avatarInfo.AvatarId, ReliquaryAffixWeight.Default); ReliquaryMainAffixLevel maxRelicLevel = metadataContext.ReliqueryLevels.Where(r => r.Rank == reliquary.RankLevel).MaxBy(r => r.Level)!; + if (property == FightProperty.FIGHT_PROP_ELEC_ADD_HURT) + { + System.Diagnostics.Debugger.Break(); + } + float percent = relicLevel.PropertyMap[property] / maxRelicLevel.PropertyMap[property]; - float baseScore = 8 * percent * weightConfig.GetValueOrDefault(property); + float baseScore = 8 * percent * affixWeight[property]; float score = subProperties.Sum(p => p.Score); return ((score + baseScore) / 1700) * 66; @@ -133,11 +136,6 @@ internal sealed class SummaryReliquaryFactory } } - private AffixWeight GetAffixWeightForAvatarId() - { - return ReliquaryWeightConfiguration.AffixWeights.FirstOrDefault(w => w.AvatarId == avatarInfo.AvatarId, ReliquaryWeightConfiguration.Default); - } - private ReliquarySubProperty CreateComposedSubProperty(ReliquarySubstat substat) { FormatMethod method = substat.AppendPropId.GetFormatMethod(); @@ -154,7 +152,7 @@ internal sealed class SummaryReliquaryFactory [SuppressMessage("", "SH002")] private ReliquarySubProperty CreateSubProperty(ReliquarySubAffixId appendPropId) { - MetadataReliquaryAffix affix = metadataContext.IdReliquarySubAffixMap[appendPropId]; + ReliquarySubAffix affix = metadataContext.IdReliquarySubAffixMap[appendPropId]; FightProperty property = affix.Type; return new( @@ -165,10 +163,10 @@ internal sealed class SummaryReliquaryFactory private float ScoreSubAffix(in ReliquarySubAffixId appendId) { - MetadataReliquaryAffix affix = metadataContext.IdReliquarySubAffixMap[appendId]; + ReliquarySubAffix affix = metadataContext.IdReliquarySubAffixMap[appendId]; - AffixWeight weightConfig = GetAffixWeightForAvatarId(); - float weight = weightConfig.GetValueOrDefault(affix.Type) / 100F; + ReliquaryAffixWeight affixWeight = metadataContext.IdReliquaryAffixWeightMap.GetValueOrDefault(avatarInfo.AvatarId, ReliquaryAffixWeight.Default); + float weight = affixWeight[affix.Type] / 100F; // 小字词条,转换到等效百分比计算 if (affix.Type is FightProperty.FIGHT_PROP_HP or FightProperty.FIGHT_PROP_ATTACK or FightProperty.FIGHT_PROP_DEFENSE) @@ -177,10 +175,10 @@ internal sealed class SummaryReliquaryFactory float equalPercent = affix.Value / avatarInfo.FightPropMap[affix.Type - 1]; // 获取对应百分比词条权重 - weight = weightConfig.GetValueOrDefault(affix.Type + 1) / 100F; + weight = affixWeight[affix.Type + 1] / 100F; // 最大同属性百分比数值 最大同属性百分比Id 第四五位是战斗属性位 - MetadataReliquaryAffix maxPercentAffix = metadataContext.IdReliquarySubAffixMap[SummaryHelper.GetAffixMaxId(appendId + 10U)]; + ReliquarySubAffix maxPercentAffix = metadataContext.IdReliquarySubAffixMap[SummaryHelper.GetAffixMaxId(appendId + 10U)]; float equalScore = equalPercent / maxPercentAffix.Value; return weight * equalScore * 100; diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs index 20a7dbb5..e08dde9a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs @@ -156,7 +156,7 @@ internal interface IMetadataService : ICastableService /// /// 取消令牌 /// 显示与材料映射 - ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default); + ValueTask> GetIdToDisplayItemAndMaterialMapAsync(CancellationToken token = default); /// /// 异步获取Id到材料的字典 @@ -165,6 +165,13 @@ internal interface IMetadataService : ICastableService /// Id到材料的字典 ValueTask> GetIdToMaterialMapAsync(CancellationToken token = default(CancellationToken)); + /// + /// 异步获取Id到圣遗物权重的映射 + /// + /// 取消令牌 + /// Id到圣遗物权重的字典 + ValueTask> GetIdToReliquaryAffixWeightMapAsync(CancellationToken token = default); + /// /// 异步获取ID到圣遗物副词条的字典 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs index f1f6f1e2..79e3d840 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.Indexing.cs @@ -37,7 +37,7 @@ internal sealed partial class MetadataService } /// - public async ValueTask> GetIdToDisplayAndMaterialMapAsync(CancellationToken token = default) + public async ValueTask> GetIdToDisplayItemAndMaterialMapAsync(CancellationToken token = default) { string cacheKey = $"{nameof(MetadataService)}.Cache.DisplayAndMaterial.Map.{typeof(MaterialId).Name}"; @@ -66,6 +66,12 @@ internal sealed partial class MetadataService return FromCacheAsDictionaryAsync(FileNameMaterial, a => a.Id, token); } + /// + public ValueTask> GetIdToReliquaryAffixWeightMapAsync(CancellationToken token = default) + { + return FromCacheAsDictionaryAsync(FileNameReliquaryAffixWeight, r => r.AvatarId, token); + } + /// public ValueTask> GetIdToReliquarySubAffixMapAsync(CancellationToken token = default) { diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs index f06b1d65..6c6abf3b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs @@ -50,13 +50,11 @@ internal sealed partial class MetadataService : IMetadataService, IMetadataServi return; } - ValueStopwatch stopwatch = ValueStopwatch.StartNew(); - logger.LogInformation("Metadata initialization begin"); - - isInitialized = await TryUpdateMetadataAsync(token).ConfigureAwait(false); - initializeCompletionSource.TrySetResult(); - - logger.LogInformation("Metadata initialization completed in {time}ms", stopwatch.GetElapsedTime().TotalMilliseconds); + using (ValueStopwatch.MeasureExecution(logger)) + { + isInitialized = await TryUpdateMetadataAsync(token).ConfigureAwait(false); + initializeCompletionSource.TrySetResult(); + } } private async Task TryUpdateMetadataAsync(CancellationToken token) diff --git a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj index 0a198dd6..326b6754 100644 --- a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj +++ b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj @@ -77,7 +77,6 @@ - @@ -166,7 +165,6 @@ - diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs index bae18d11..9912e1ab 100644 --- a/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs +++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/Wiki/WikiMonsterViewModel.cs @@ -58,7 +58,7 @@ internal sealed partial class WikiMonsterViewModel : Abstraction.ViewModel levelMonsterCurveMap = await metadataService.GetLevelToMonsterCurveMapAsync().ConfigureAwait(false); List monsters = await metadataService.GetMonstersAsync().ConfigureAwait(false); - Dictionary idDisplayMap = await metadataService.GetIdToDisplayAndMaterialMapAsync().ConfigureAwait(false); + Dictionary idDisplayMap = await metadataService.GetIdToDisplayItemAndMaterialMapAsync().ConfigureAwait(false); foreach (Monster monster in monsters) { monster.DropsView ??= monster.Drops?.SelectList(i => idDisplayMap.GetValueOrDefault(i)!);