Skip to content

Commit

Permalink
Add summoning odds calculation (#699)
Browse files Browse the repository at this point in the history
Adds the logic to calculate the summoning odds distribution. Initially
only used for `/summon/get_odds_data` - i.e. the 'Appearance Rates' menu
- however the code has been designed to hopefully be easily reusable for
calculating summoning results with FluentRandomPicker.
  • Loading branch information
SapiensAnatis authored Mar 7, 2024
1 parent 034e52d commit 3f55034
Show file tree
Hide file tree
Showing 18 changed files with 2,131 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Diagnostics.CodeAnalysis;
using DragaliaAPI.Database.Entities.Abstract;
using DragaliaAPI.Shared.Definitions.Enums;
using DragaliaAPI.Shared.Features.Summoning;
using DragaliaAPI.Shared.MasterAsset;
using DragaliaAPI.Shared.MasterAsset.Models;
using Microsoft.EntityFrameworkCore;
Expand Down Expand Up @@ -202,6 +203,6 @@ public DbPlayerCharaData(long viewerId, Charas id)
this.Ability1Level = (byte)data.DefaultAbility1Level;
this.Ability2Level = (byte)data.DefaultAbility2Level;
this.Ability3Level = (byte)data.DefaultAbility3Level;
this.IsUnlockEditSkill = data.Availability == CharaAvailabilities.Story;
this.IsUnlockEditSkill = data.GetAvailability() == UnitAvailability.Story;
}
}
112 changes: 109 additions & 3 deletions DragaliaAPI/DragaliaAPI.Integration.Test/Dragalia/SummonTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,122 @@ await this.Client.PostMsgpack<SummonExcludeGetListResponse>(
}

[Fact]
public async Task SummonGetOddsData_ReturnsAnyData()
public async Task SummonGetOddsData_ReturnsExpectedData()
{
SummonGetOddsDataResponse response = (
await this.Client.PostMsgpack<SummonGetOddsDataResponse>(
"summon/get_odds_data",
new SummonGetOddsDataRequest(1020203)
new SummonGetOddsDataRequest(1020010)
)
).Data;

response.Should().NotBeNull();
OddsRate normalOdds = response.OddsRateList.Normal;
OddsRate guaranteeOdds = response.OddsRateList.Guarantee;

normalOdds
.RarityList.Should()
.BeEquivalentTo(
[
new AtgenRarityList { Rarity = 5, TotalRate = "4.00%" },
new AtgenRarityList { Rarity = 4, TotalRate = "16.00%" },
new AtgenRarityList { Rarity = 3, TotalRate = "80.00%" },
]
);

guaranteeOdds
.RarityList.Should()
.BeEquivalentTo(
[
new AtgenRarityList { Rarity = 5, TotalRate = "4.00%" },
new AtgenRarityList { Rarity = 4, TotalRate = "96.00%" },
]
);

normalOdds
.RarityGroupList.Should()
.BeEquivalentTo(
[
new AtgenRarityGroupList
{
Rarity = 5,
CharaRate = "1.00%",
DragonRate = "0.80%",
Pickup = true,
TotalRate = "1.80%"
},
new AtgenRarityGroupList
{
Rarity = 5,
CharaRate = "1.10%",
DragonRate = "1.10%",
Pickup = false,
TotalRate = "2.20%"
},
new AtgenRarityGroupList
{
Rarity = 4,
CharaRate = "8.55%",
DragonRate = "7.45%",
Pickup = false,
TotalRate = "16.00%"
},
new AtgenRarityGroupList
{
Rarity = 3,
CharaRate = "48.00%",
DragonRate = "32.00%",
Pickup = false,
TotalRate = "80.00%"
}
]
);

guaranteeOdds
.RarityGroupList.Should()
.BeEquivalentTo(
[
new AtgenRarityGroupList
{
Rarity = 5,
CharaRate = "1.00%",
DragonRate = "0.80%",
Pickup = true,
TotalRate = "1.80%"
},
new AtgenRarityGroupList
{
Rarity = 5,
CharaRate = "1.10%",
DragonRate = "1.10%",
Pickup = false,
TotalRate = "2.20%"
},
new AtgenRarityGroupList
{
Rarity = 4,
CharaRate = "51.30%",
DragonRate = "44.70%",
Pickup = false,
TotalRate = "96.00%"
}
]
);

normalOdds.Unit.CharaOddsList.Should().HaveCount(4);

normalOdds
.Unit.CharaOddsList.ElementAt(0)
.UnitList.Should()
.BeEquivalentTo(
[
new AtgenUnitList { Id = (int)Charas.Joker, Rate = "0.500%" },
new AtgenUnitList { Id = (int)Charas.Mona, Rate = "0.500%" }
]
);
normalOdds
.Unit.DragonOddsList.ElementAt(0)
.UnitList.Should()
.BeEquivalentTo([new AtgenUnitList { Id = (int)Dragons.Arsene, Rate = "0.800%" }]);
}

[Fact]
Expand Down
14 changes: 6 additions & 8 deletions DragaliaAPI/DragaliaAPI.Shared.Test/Unit/MasterAssetTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Frozen;
using DragaliaAPI.Photon.Shared.Enums;
using DragaliaAPI.Shared.Definitions.Enums;
using DragaliaAPI.Shared.Features.Summoning;
using DragaliaAPI.Shared.MasterAsset;
using DragaliaAPI.Shared.MasterAsset.Models;
using DragaliaAPI.Shared.MasterAsset.Models.ManaCircle;
Expand Down Expand Up @@ -157,17 +158,14 @@ int expectedAbility3Level
}

[Theory]
[InlineData(Charas.Elisanne, CharaAvailabilities.Story)]
[InlineData(Charas.Annelie, CharaAvailabilities.Default)]
[InlineData(Charas.Chelle, CharaAvailabilities.Story)]
public void CharaData_Availability_ReturnsExpectedResult(
Charas id,
CharaAvailabilities expected
)
[InlineData(Charas.Elisanne, UnitAvailability.Story)]
[InlineData(Charas.Annelie, UnitAvailability.Permanent)]
[InlineData(Charas.Chelle, UnitAvailability.Story)]
public void CharaData_Availability_ReturnsExpectedResult(Charas id, UnitAvailability expected)
{
CharaData chara = MasterAsset.MasterAsset.CharaData.Get(id);

chara.Availability.Should().Be(expected);
chara.GetAvailability().Should().Be(expected);
}

[Fact]
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace DragaliaAPI.Shared.Definitions.Enums;

/// <summary>
/// Represents a unit's availability from a summoning perspective.
/// </summary>
public enum UnitAvailability
{
/// <summary>
/// The unit is always able to be summoned.
/// </summary>
Permanent,

/// <summary>
/// The unit can only be summoned on Gala banners.
/// </summary>
Gala,

/// <summary>
/// The unit can only be summoned on particular limited banners.
/// </summary>
Limited,

/// <summary>
/// The unit can never be summoned, but is available from completing a main story quest.
/// </summary>
Story,

/// <summary>
/// The unit can never be summoned.
/// </summary>
Other
}
Loading

0 comments on commit 3f55034

Please sign in to comment.