Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Daybreak.API/Services/PartyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ private unsafe bool SpawnHeroes(PartyLoadout partyLoadout)
{
var scopedLogger = this.logger.CreateScopedLogger();
scopedLogger.LogDebug("Spawning {heroCount} heroes for party loadout", partyLoadout.Entries.AsValueEnumerable().Count(c => c.HeroId != 0));
foreach (var entry in partyLoadout.Entries)
foreach (var entry in partyLoadout.Entries.AsValueEnumerable().OrderBy(e => e.Build.Primary))
{
if (entry.HeroId != 0 &&
Hero.TryParse(entry.HeroId, out var hero))
Expand Down
4 changes: 3 additions & 1 deletion Daybreak.Shared/Services/Api/ScopedApiContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Extensions.Core;
using System.Net.Http;
using System.Net.Http.Json;
using System.Text.Encodings.Web;

namespace Daybreak.Shared.Services.Api;
public sealed class ScopedApiContext(
Expand Down Expand Up @@ -74,7 +75,8 @@ public async Task<bool> SwitchCharacter(string characterName, CancellationToken

public async Task<bool> PostMainPlayerBuild(string code, CancellationToken cancellationToken)
{
var path = PostMainPlayerBuildPath.Replace(CodePlaceholder, code);
var encodedBuildCode = UrlEncoder.Default.Encode(code);
var path = PostMainPlayerBuildPath.Replace(CodePlaceholder, encodedBuildCode);
using var emptyContent = new StringContent(string.Empty);
return await this.Post(path, request => emptyContent, cancellationToken);
}
Expand Down
50 changes: 13 additions & 37 deletions Daybreak.Shared/Services/BuildTemplates/BuildTemplateManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,15 +204,6 @@ public bool CanApply(MainPlayerBuildContext mainPlayerBuildContext, TeamBuildEnt
return (build, compositionEntry, index);
});

var lockedSkill = loadoutEntryComposition
.Select(entry => entry.build.Skills.FirstOrDefault(s => s != Skill.NoSkill && !IsSkillUnlocked(s.Id, mainPlayerBuildContext.UnlockedAccountSkills)))
.OfType<Skill>()
.FirstOrDefault();
if (lockedSkill is not null)
{
scopedLogger.LogDebug("Invalid team build entry {buildName}. Skill {skillName} is not unlocked by the current account", teamBuildEntry.Name ?? string.Empty, lockedSkill.Name);
}

return loadoutEntryComposition.Any(entry => entry.compositionEntry.Type is PartyCompositionMemberType.MainPlayer && this.CanApply(mainPlayerBuildContext, entry.build));
}

Expand All @@ -232,12 +223,6 @@ public bool CanApply(MainPlayerBuildContext mainPlayerBuildContext, SingleBuildE
return false;
}

if (singleBuildEntry.Skills.FirstOrDefault(s => s != Skill.NoSkill && !IsSkillUnlocked(s.Id, mainPlayerBuildContext.UnlockedCharacterSkills)) is Skill lockedSkill)
{
scopedLogger.LogDebug("Invalid build entry {buildName}. Skill {skillName} is not unlocked by the current character", singleBuildEntry.Name ?? string.Empty, lockedSkill.Name);
return false;
}

return true;
}

Expand All @@ -257,16 +242,6 @@ public bool CanTemplateApply(BuildTemplateValidationRequest request)
return false;
}

foreach(var skill in request.BuildSkills)
{
if (skill is not 0 &&
!IsSkillUnlocked((int)skill, request.UnlockedSkills))
{
scopedLogger.LogError("Skill {skillId} is not unlocked", skill);
return false;
}
}

return true;
}

Expand Down Expand Up @@ -872,16 +847,17 @@ private static int FromBitString(string bitString)

private static bool IsProfessionUnlocked(int professionId, uint unlockedProfessions) => (unlockedProfessions & (1 << professionId)) != 0;

private static bool IsSkillUnlocked(int skillId, uint[] unlockedSkills)
{
var realIndex = skillId / 32;
if (realIndex >= unlockedSkills.Length)
{
return false;
}

var shift = skillId % 32;
var flag = 1U << shift;
return (unlockedSkills[realIndex] & flag) != 0;
}
// Not using anymore. Skills are marked as locked if they are not part of the primary/secondary of the current character. Cannot rely on this for build viability checks.
//private static bool IsSkillUnlocked(int skillId, uint[] unlockedSkills)
//{
// var realIndex = skillId / 32;
// if (realIndex >= unlockedSkills.Length)
// {
// return false;
// }

// var shift = skillId % 32;
// var flag = 1U << shift;
// return (unlockedSkills[realIndex] & flag) != 0;
//}
}
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<NoWarn>$(NoWarn);IL2104;IL3053;IL3000;IL3002;NU1701;CS0108</NoWarn>

<Version>0.9.9.76</Version>
<Version>0.9.9.77</Version>

<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
Expand Down
Loading