Implement d6 wild dice/fumble skills and die-state rolls
This commit is contained in:
@@ -79,6 +79,7 @@ public partial class Home
|
||||
private SkillSummary? SelectedSkill => SelectedCampaign?.Skills.FirstOrDefault(s => s.Id == SelectedSkillId);
|
||||
private string? ActiveCharacterName => SelectedCampaign?.Characters.FirstOrDefault(c => c.Id == ActiveCharacterId)?.Name;
|
||||
private bool IsCurrentUserGm => SelectedCampaign is not null && User is not null && SelectedCampaign.Gm.Id == User.Id;
|
||||
private bool IsSelectedCampaignD6 => string.Equals(SelectedCampaign?.RulesetId, "d6", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
private List<SkillSummary> SelectedCharacterSkills =>
|
||||
SelectedCampaign is null || !SelectedCharacterId.HasValue
|
||||
@@ -640,6 +641,8 @@ public partial class Home
|
||||
{
|
||||
SkillForm.Name = string.Empty;
|
||||
SkillForm.DiceRollDefinition = string.Empty;
|
||||
SkillForm.WildDice = IsSelectedCampaignD6 ? 1 : 0;
|
||||
SkillForm.AllowFumble = IsSelectedCampaignD6;
|
||||
SkillErrors.Clear();
|
||||
SkillFormError = null;
|
||||
ShowCreateSkillModal = true;
|
||||
@@ -655,6 +658,8 @@ public partial class Home
|
||||
EditingSkillId = SelectedSkill.Id;
|
||||
EditSkillForm.Name = SelectedSkill.Name;
|
||||
EditSkillForm.DiceRollDefinition = SelectedSkill.DiceRollDefinition;
|
||||
EditSkillForm.WildDice = SelectedSkill.WildDice;
|
||||
EditSkillForm.AllowFumble = SelectedSkill.AllowFumble;
|
||||
EditSkillErrors.Clear();
|
||||
EditSkillFormError = null;
|
||||
ShowEditSkillModal = true;
|
||||
@@ -688,6 +693,11 @@ public partial class Home
|
||||
SkillErrors["diceRollDefinition"] = "Expression is required.";
|
||||
}
|
||||
|
||||
if (IsSelectedCampaignD6 && SkillForm.WildDice < 1)
|
||||
{
|
||||
SkillErrors["wildDice"] = "D6 skills require at least one wild die.";
|
||||
}
|
||||
|
||||
if (SkillErrors.Count > 0)
|
||||
{
|
||||
SkillFormError = "Resolve validation issues before submitting.";
|
||||
@@ -697,7 +707,10 @@ public partial class Home
|
||||
IsMutating = true;
|
||||
try
|
||||
{
|
||||
_ = await RequestAsync<SkillSummary>("POST", $"/api/characters/{SelectedCharacter.Id}/skills", new CreateSkillRequest(SkillForm.Name.Trim(), SkillForm.DiceRollDefinition.Trim()));
|
||||
_ = await RequestAsync<SkillSummary>(
|
||||
"POST",
|
||||
$"/api/characters/{SelectedCharacter.Id}/skills",
|
||||
new CreateSkillRequest(SkillForm.Name.Trim(), SkillForm.DiceRollDefinition.Trim(), SkillForm.WildDice, SkillForm.AllowFumble));
|
||||
CloseSkillModals();
|
||||
await RefreshCampaignScopeAsync();
|
||||
SetStatus("Skill created.", false);
|
||||
@@ -733,6 +746,11 @@ public partial class Home
|
||||
EditSkillErrors["diceRollDefinition"] = "Expression is required.";
|
||||
}
|
||||
|
||||
if (IsSelectedCampaignD6 && EditSkillForm.WildDice < 1)
|
||||
{
|
||||
EditSkillErrors["wildDice"] = "D6 skills require at least one wild die.";
|
||||
}
|
||||
|
||||
if (EditSkillErrors.Count > 0)
|
||||
{
|
||||
EditSkillFormError = "Resolve validation issues before submitting.";
|
||||
@@ -742,7 +760,10 @@ public partial class Home
|
||||
IsMutating = true;
|
||||
try
|
||||
{
|
||||
var updatedSkill = await RequestAsync<SkillSummary>("PUT", $"/api/skills/{EditingSkillId.Value}", new UpdateSkillRequest(EditSkillForm.Name.Trim(), EditSkillForm.DiceRollDefinition.Trim()));
|
||||
var updatedSkill = await RequestAsync<SkillSummary>(
|
||||
"PUT",
|
||||
$"/api/skills/{EditingSkillId.Value}",
|
||||
new UpdateSkillRequest(EditSkillForm.Name.Trim(), EditSkillForm.DiceRollDefinition.Trim(), EditSkillForm.WildDice, EditSkillForm.AllowFumble));
|
||||
SelectedSkillId = updatedSkill.Id;
|
||||
CloseSkillModals();
|
||||
await RefreshCampaignScopeAsync();
|
||||
@@ -985,6 +1006,93 @@ public partial class Home
|
||||
return SelectedCampaign?.Skills.FirstOrDefault(s => s.Id == skillId)?.Name ?? "Hidden skill";
|
||||
}
|
||||
|
||||
private string SkillDefinitionLabel(SkillSummary skill)
|
||||
{
|
||||
if (!string.Equals(SelectedCampaign?.RulesetId, "d6", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return skill.DiceRollDefinition;
|
||||
}
|
||||
|
||||
var fumble = skill.AllowFumble ? "fumble on" : "fumble off";
|
||||
return $"{skill.DiceRollDefinition} | wild {skill.WildDice}, {fumble}";
|
||||
}
|
||||
|
||||
private static string RollDieGlyph(int roll)
|
||||
{
|
||||
return roll switch
|
||||
{
|
||||
1 => "\u2680",
|
||||
2 => "\u2681",
|
||||
3 => "\u2682",
|
||||
4 => "\u2683",
|
||||
5 => "\u2684",
|
||||
6 => "\u2685",
|
||||
_ => roll.ToString()
|
||||
};
|
||||
}
|
||||
|
||||
private static string RollDieCssClass(RollDieResult die)
|
||||
{
|
||||
var classes = new List<string> { "die-chip" };
|
||||
if (die.Wild)
|
||||
{
|
||||
classes.Add("wild");
|
||||
}
|
||||
|
||||
if (die.Crit)
|
||||
{
|
||||
classes.Add("crit");
|
||||
}
|
||||
|
||||
if (die.Fumble)
|
||||
{
|
||||
classes.Add("fumble");
|
||||
}
|
||||
|
||||
if (die.Removed)
|
||||
{
|
||||
classes.Add("removed");
|
||||
}
|
||||
|
||||
if (die.Added)
|
||||
{
|
||||
classes.Add("added");
|
||||
}
|
||||
|
||||
return string.Join(" ", classes);
|
||||
}
|
||||
|
||||
private static string RollDieTitle(RollDieResult die)
|
||||
{
|
||||
var labels = new List<string> { $"Roll {die.Roll}" };
|
||||
if (die.Wild)
|
||||
{
|
||||
labels.Add("wild");
|
||||
}
|
||||
|
||||
if (die.Crit)
|
||||
{
|
||||
labels.Add("critical");
|
||||
}
|
||||
|
||||
if (die.Fumble)
|
||||
{
|
||||
labels.Add("fumble");
|
||||
}
|
||||
|
||||
if (die.Removed)
|
||||
{
|
||||
labels.Add("removed");
|
||||
}
|
||||
|
||||
if (die.Added)
|
||||
{
|
||||
labels.Add("added");
|
||||
}
|
||||
|
||||
return string.Join(", ", labels);
|
||||
}
|
||||
|
||||
private string RollerLabel(CampaignLogEntry entry)
|
||||
{
|
||||
if (User is not null && entry.RollerUserId == User.Id)
|
||||
@@ -1134,6 +1242,8 @@ public partial class Home
|
||||
{
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string DiceRollDefinition { get; set; } = string.Empty;
|
||||
public int WildDice { get; set; }
|
||||
public bool AllowFumble { get; set; }
|
||||
}
|
||||
|
||||
private sealed class JsApiResponse
|
||||
|
||||
Reference in New Issue
Block a user