public IActionResult DisplaySheetWithID(string id) { string username = HttpContext.Session.GetString("username"); if (username != null && username != "") { //sheetService.CreateDnDSheet(username, "PlaceHolder"); ModularSheet sheet = sheetService.Get(id); currentSheet = sheet; return(View("DisplaySheet", sheet)); } return(RedirectToAction("Login", "Home")); }
public async Task ChangeHP(int value, [Remainder] string args = null) { Character c; args = args.ToLower(); if (args.Contains("-c")) { c = GetCompanion(); args = args.Replace("-c", "").Trim(); if (c == null) { await ReplyAsync("You have no active companion."); return; } } else { c = GetCharacter(); if (c == null) { await ReplyAsync("You have no active character."); return; } } int CurrentHp = 0; int MaxHp = 0; int TempHP = 0; int Damage = 0; JArray Json1 = await SheetService.Get(c, "damage+hptemp/"); Damage = (string)Json1["damage"] == "null" ? 0 : (int)Json1["damage"]; TempHP = (string)Json1["hptemp"] == "null" ? 0 : (int)Json1["hptemp"]; JObject values = await SheetService.GetValues(c); MaxHp = (int)values["hp"]["value"]; CurrentHp = MaxHp - Damage; }
public async Task Attack([Remainder] string args = "") { Character c; args = args.ToLower(); if (args.Contains("-c")) { c = GetCompanion(); args = args.Replace("-c", ""); if (c == null) { await ReplyAsync("You have no active companion."); return; } } else { c = GetCharacter(); if (c == null) { await ReplyAsync("You have no active character."); return; } } if (args.NullorEmpty()) { var strikes = await SheetService.Get(c, "strikes"); var embed = new EmbedBuilder() .WithTitle(c.Name + "'s strikes") .WithThumbnailUrl(c.ImageUrl); if (strikes.Count() == 0) { await ReplyAsync(c.Name + " has no strikes."); return; } var sb = new StringBuilder(); foreach (var s in strikes) { string act = Icons.Actions["1"]; if (!((string)s["actions"]).NullorEmpty()) { if (Icons.Actions.TryGetValue((string)s["actions"], out string ic)) { act = ic; } else { act = "[" + s["actions"] + "]"; } } sb.AppendLine(Icons.Strike[(string)s["attack"]] + " " + (((string)s["name"]).NullorEmpty() ? "Unnamed Strike" : (string)s["name"]) + " " + act); } embed.WithDescription(sb.ToString()); if (c.Color != null) { embed.WithColor(new Color(c.Color[0], c.Color[1], c.Color[2])); } else { Random randonGen = new Random(); Color randomColor = new Color(randonGen.Next(255), randonGen.Next(255), randonGen.Next(255)); embed.WithColor(randomColor); } await ReplyAsync("", embed.Build()); return; } else { string[] Bonuses = new string[0]; if (BonusRegex.IsMatch(args)) { Bonuses = BonusRegex.Matches(args).Select(x => x.Value).ToArray(); foreach (var b in Bonuses) { args = args.Replace(b, ""); } args = args.Trim(); } var Jstrikes = await SheetService.Get(c, "strikes"); var values = await SheetService.GetValues(c); if (values == null || Jstrikes == null) { var err = new EmbedBuilder() .WithTitle("Click here") .WithUrl("https://character.pf2.tools/?" + c.RemoteId) .WithDescription("Seems like we cannot fetch " + c.Name + "'s values. This is due to the fact values are only updated when you open the sheet in pf2.tools. To fix this, click the link above to generate those values."); await ReplyAsync("", err.Build()); return; } var strikes = from sk in Jstrikes where ((string)sk["name"]).ToLower().StartsWith(args) orderby sk["name"] select sk; if (strikes.Count() == 0) { await ReplyAsync("You have no strikes whose name starts with '" + args + "'."); return; } var s = strikes.FirstOrDefault(); var embed = new EmbedBuilder() .WithTitle(c.Name + " strikes with a " + (((string)s["name"]).NullorEmpty() ? "Unnamed Strike" : (string)s["name"]) + "!") .WithThumbnailUrl(c.ImageUrl); if (c.Color != null) { embed.WithColor(new Color(c.Color[0], c.Color[1], c.Color[2])); } else { Random randonGen = new Random(); Color randomColor = new Color(randonGen.Next(255), randonGen.Next(255), randonGen.Next(255)); embed.WithColor(randomColor); } await ReplyAsync("Rolling..."); string hit = ""; string dmg = ""; string penalties = ""; string damagebonus = ""; string dmgtype = "Untyped"; if ((string)s["attack"] == "spell") { dmgtype = "Spell"; var classes = await SheetService.Get(c, "classes"); JToken cl = null; if (((string)s["class"]).NullorEmpty()) { cl = classes.FirstOrDefault(); } else { cl = classes.First(x => (string)x["id"] == (string)s["class"]); } if (classes == null || classes.Count == 0) { await ReplyAsync("You don't seem to have a class. Without one you can't make spell attacks."); return; } if (!values.ContainsKey(((string)cl["name"]).ToLower())) { await ReplyAsync("Sorry! It seems we cannot retrieve the data for this strike! This issue is outside of the bot's control and will likely be solved later."); return; } hit = (string)values[((string)cl["name"]).ToLower()]["bonus"]; int dc = int.Parse(hit ?? "0") + 10; dmg = (string)s["overridedamage"]; if (!dmg.NullorEmpty() && AttributeRegex.IsMatch(dmg)) { dmg = await ParseValues(dmg, c, values); } string summary = ""; var result = Roller.Roll("d20 + " + hit + (Bonuses.Length > 0?string.Join(" ", Bonuses):"")); summary += "Spell Attack roll: " + result.ParseResult() + " = `" + result.Value + "`" + "\nDC: `" + dc + "`"; if (!((string)s["spell"]).NullorEmpty()) { var spells = await SheetService.Get(c, "spells"); var sp = spells.First(x => (string)x["id"] == (string)s["spell"]); if (!((string)sp["body"]).NullorEmpty()) { embed.AddField("Spell description", sp["body"]); } if (!((string)sp["savingthrow"]).NullorEmpty()) { summary += "\nSaving Throw: " + sp["savingthrow"]; } embed.WithTitle(c.Name + " casts " + (sp["name"] ?? "Unnamed Spell") + "!"); } if (!dmg.NullorEmpty()) { try { RollResult result2 = Roller.Roll(dmg + damagebonus); summary += "\n" + dmgtype.Uppercase() + " damage: " + result2.ParseResult() + " = `" + result2.Value + "` "; if (!((string)s["extradamage"]).NullorEmpty()) { RollResult result3 = Roller.Roll((string)s["extradamage"]); summary += "\n" + ((string)s["overridedamage"]).Uppercase() + " damage: " + result3.ParseResult() + " = `" + result3.Value + "`"; } } catch { await ReplyAsync("It seems like this strike doesn't have a valid dice roll on its damage or additional damage fields. If this is a spell make sure you have a valid dice expression on the damage fields."); return; } } embed.WithDescription(summary) .WithFooter((c.ValuesLastUpdated.Outdated() ? "⚠️ Couldn't retrieve updated values. Roll might not be accurate" : DateTime.Now.ToString())); await ReplyAsync(" ", embed.Build()); } else { if (!((string)s["weapon"]).NullorEmpty()) { var items = await SheetService.Get(c, "items"); var i = items.First(x => (string)x["id"] == (string)s["weapon"]); dmgtype = (string)i["damagetype"] ?? "Untyped"; } else { dmgtype = "Bludgeoning"; } if ((string)s["attack"] == "melee" || ((string)s["attack"]).NullorEmpty()) { hit = (string)values["melee " + (string)s["name"]]["bonus"]; penalties = (string)values["melee " + (string)s["name"]]["penalty"]; } else { hit = (string)values["ranged " + (string)s["name"]]["bonus"]; penalties = (string)values["ranged " + (string)s["name"]]["penalty"]; } damagebonus = (string)values["damage " + (string)s["name"]]["value"]; dmg = (string)values["damagedice " + (string)s["name"]]["value"] + GetDie((int)values["damagedie " + (string)s["name"]]["value"]); string summary = ""; var result = Roller.Roll("d20 + " + hit + (penalties != "0"? "-" + penalties:"") + (Bonuses.Length > 0 ? string.Join(" ", Bonuses) : "")); summary += "Attack roll: " + result.ParseResult() + " = `" + result.Value + "`"; if (!dmg.NullorEmpty()) { try { RollResult result2 = Roller.Roll(dmg + "+" + damagebonus); summary += "\n" + dmgtype.Uppercase() + " damage: " + result2.ParseResult() + " = `" + result2.Value + "` "; if (!((string)s["extradamage"]).NullorEmpty()) { RollResult result3 = Roller.Roll((string)s["extradamage"]); summary += "\n" + ((string)s["overridedamage"]).Uppercase() + " damage: " + result3.ParseResult() + " = `" + result3.Value + "`"; } } catch { await ReplyAsync("It seems like this strike doesn't have a valid dice roll on its damage or additional damage fields. If this is a spell make sure you have a valid dice expression on the damage fields."); return; } } embed.WithDescription(summary) .WithFooter((c.ValuesLastUpdated.Outdated() ? "⚠️ Couldn't retrieve updated values. Roll might not be accurate" : DateTime.Now.ToString())); await ReplyAsync(" ", embed.Build()); } } }
public ActionResult <List <ModularSheet> > Get() { return(sheetService.Get()); }
public async Task Attack([Remainder] string args = "") { Character c; args = args.ToLower(); if (args.Contains("-c")) { c = GetCompanion(); args = args.Replace("-c", "").Trim(); if (c == null) { await ReplyAsync("You have no active companion."); return; } } else { c = GetCharacter(); if (c == null) { await ReplyAsync("You have no active character."); return; } } if (args.NullorEmpty()) { var strikes = await SheetService.Get(c, "strikes"); var embed = new EmbedBuilder() .WithTitle(c.Name + "'s strikes") .WithThumbnailUrl(c.ImageUrl); if (strikes.Count() == 0) { await ReplyAsync(c.Name + " has no strikes."); return; } var sb = new StringBuilder(); foreach (var s in strikes) { string act = Icons.Actions["1"]; if (!((string)s["actions"]).NullorEmpty()) { if (Icons.Actions.TryGetValue((string)s["actions"], out string ic)) { act = ic; } else { act = "[" + s["actions"] + "]"; } } sb.AppendLine(Icons.Strike[(string)s["attack"]] + " " + (((string)s["name"]).NullorEmpty() ? "Unnamed Strike" : (string)s["name"]) + " " + act); } embed.WithDescription(sb.ToString()); if (c.Color != null) { embed.WithColor(new Color(c.Color[0], c.Color[1], c.Color[2])); } else { Random randonGen = new Random(); Color randomColor = new Color(randonGen.Next(255), randonGen.Next(255), randonGen.Next(255)); embed.WithColor(randomColor); } await ReplyAsync("", embed.Build()); return; } else { string[] Bonuses = new string[0]; if (BonusRegex.IsMatch(args)) { Bonuses = BonusRegex.Matches(args).Select(x => x.Value).ToArray(); foreach (var b in Bonuses) { args = args.Replace(b, ""); } args = args.Trim(); } List <string> Toggles = new List <string>(); if (ToggleableRegex.IsMatch(args)) { MatchCollection RawToggles = ToggleableRegex.Matches(args); foreach (Match m in RawToggles) { args = args.Replace(m.Value, ""); Toggles.Add(m.Groups[2].Value.Trim()); } args = args.Trim(); } var Jstrikes = await SheetService.Get(c, "strikes"); var values = await SheetService.GetValues(c); if (values == null || Jstrikes == null) { var err = new EmbedBuilder() .WithTitle("Click here") .WithUrl("https://character.pf2.tools/?" + c.RemoteId) .WithDescription("Seems like we cannot fetch " + c.Name + "'s values. This is due to the fact values are only updated when you open the sheet in pf2.tools. To fix this, click the link above to generate those values."); await ReplyAsync("", err.Build()); return; } var strikes = from sk in Jstrikes where ((string)sk["name"]).ToLower().StartsWith(args) orderby sk["name"] select sk; if (strikes.Count() == 0) { await ReplyAsync("You have no strikes whose name starts with '" + args + "'."); return; } string strikename = ""; var s = strikes.FirstOrDefault(); var embed = new EmbedBuilder() .WithTitle(c.Name + " strikes with a " + (((string)s["name"]).NullorEmpty() ? "Unnamed Strike" : (string)s["name"]) + "!") .WithThumbnailUrl(c.ImageUrl); if (c.Color != null) { embed.WithColor(new Color(c.Color[0], c.Color[1], c.Color[2])); } else { Random randonGen = new Random(); Color randomColor = new Color(randonGen.Next(255), randonGen.Next(255), randonGen.Next(255)); embed.WithColor(randomColor); } await ReplyAsync("Rolling..."); string hit = ""; string dmg = ""; string penalties = ""; string damagebonus = ""; string dmgtype = "Untyped"; if ((string)s["attack"] == "spell") { JToken cl = null; var classes = await SheetService.Get(c, "classes"); var traditions = await SheetService.Get(c, "traditions"); classes.Merge(traditions); if (classes == null || classes.Count == 0) { await ReplyAsync("You don't seem to have a class. Without one you can't make spell attacks."); return; } if (((string)s["class"]).NullorEmpty()) { cl = classes.FirstOrDefault(); } else { cl = classes.First(x => (string)x["id"] == (string)s["class"]); } if (!values.ContainsKey(((string)cl["name"]).ToLower())) { await ReplyAsync("Sorry! It seems we cannot retrieve the data for this strike! This issue is outside of the bot's control and will likely be solved later."); return; } hit = (string)values[((string)cl["name"]).ToLower()]["bonus"]; int dc = int.Parse(hit ?? "0") + 10; string summary = ""; if (!((string)s["spell"]).NullorEmpty()) { var spells = await SheetService.Get(c, "spells"); var sp = spells.First(x => (string)x["id"] == (string)s["spell"]); if (!((string)sp["body"]).NullorEmpty()) { var sb = new StringBuilder(); sb.AppendLine((string)sp["body"]); if (sb.Length <= 1024) { embed.AddField("Spell Description", sb.ToString()); } else { var segments = sb.ToString().Split(1000).ToArray(); for (int i = 0; i < segments.Length; i++) { embed.AddField("Spell Description (" + (i + 1) + "/" + (segments.Length) + ")", segments[i]); } } } if (!((string)sp["attackroll"]).NullorEmpty() && (bool)sp["attackroll"]) { var result = Roller.Roll("d20 + " + hit + (Bonuses.Length > 0 ? string.Join(" ", Bonuses) : "")); summary += "**Spell Attack roll**: " + result.ParseResult() + " = `" + result.Value + "`"; } if (!((string)sp["savingthrow"]).NullorEmpty()) { summary += "\n**Saving Throw**: " + sp["savingthrow"] + " (DC: `" + dc + "`)"; } embed.WithTitle(c.Name + " casts " + (sp["name"] ?? "Unnamed Spell") + "!"); } dmg = (string)s["extradamage"]; if (!dmg.NullorEmpty() && AttributeRegex.IsMatch(dmg)) { dmg = await ParseValues(dmg, c, values); } if (DmgRegex.IsMatch(dmg)) { foreach (var m in DmgRegex.Matches(dmg).ToList()) { try { RollResult dmgroll = Roller.Roll(m.Groups[2].Value.ToLower()); summary += "\n**" + m.Groups[1].Value + " damage**: " + dmgroll.ParseResult() + " = `" + dmgroll.Value + "` "; } catch { continue; } } } JToken details = s["details"]; if (details != null && details.HasValues) { foreach (var value in details.Where(x => (bool)x["active"] == true || Toggles.Contains(((string)x["name"]).ToLower()))) { try { RollResult Eresult = Roller.Roll(((string)value["comment"]).ToLower()); summary += "\n**" + (((string)value["name"]).NullorEmpty() ? "Extra Damage (" + (((string)value["type"]).NullorEmpty() ? "Untyped" : (string)value["type"]) + ") " : (string)value["name"] + " (" + (((string)value["type"]).NullorEmpty() ? "Untyped" : (string)value["type"]) + ") ") + "**: " + Eresult.ParseResult() + " = `" + Eresult.Value + "`"; } catch { continue; } } } embed.WithDescription(summary) .WithFooter((c.ValuesLastUpdated.Outdated() ? "⚠️ Couldn't retrieve updated values. Roll might not be accurate" : DateTime.Now.ToString())); await ReplyAsync(" ", embed.Build()); } else if ((string)s["attack"] == "custom") { string summary = ""; if (!((string)s["weaponcustom"]).NullorEmpty()) { embed.WithTitle(c.Name + " strikes with a " + s["weaponcustom"]); } if (!((string)s["damagetypecustom"]).NullorEmpty()) { dmgtype = (string)s["damagetypecustom"]; } if (!((string)s["traitscustom"]).NullorEmpty()) { string[] traits = ((string)s["traitscustom"]).Split(','); foreach (var x in traits) { summary += "[" + x.ToUpper() + "] "; } summary += "\n"; } int range = 0; if (!((string)s["range"]).NullorEmpty()) { range += int.Parse((string)s["range"]); } if (!((string)s["modrange"]).NullorEmpty()) { range += int.Parse((string)s["modrange"]); } summary += "**Range** " + range + "ft.\n"; if ((string)s["attackcustom"] == "ranged" || ((string)s["attack"]).NullorEmpty()) { hit = (string)values["ranged " + (string)s["name"]]["bonus"]; penalties = (string)values["ranged " + (string)s["name"]]["penalty"]; var result = Roller.Roll("d20 + " + hit + (penalties != "0" ? "-" + penalties : "") + (Bonuses.Length > 0 ? string.Join(" ", Bonuses) : "")); summary += "**Attack roll**: " + result.ParseResult() + " = `" + result.Value + "`"; } else if ((string)s["attackcustom"] == "melee" || ((string)s["attack"]).NullorEmpty()) { hit = (string)values["melee " + (string)s["name"]]["bonus"]; penalties = (string)values["melee " + (string)s["name"]]["penalty"]; var result = Roller.Roll("d20 + " + hit + (penalties != "0" ? "-" + penalties : "") + (Bonuses.Length > 0 ? string.Join(" ", Bonuses) : "")); summary += "**Attack roll**: " + result.ParseResult() + " = `" + result.Value + "`"; } damagebonus = (string)values["damage " + (string)s["name"]]["value"]; dmg = (string)values["damagedice " + (string)s["name"]]["value"] + GetDie((int)values["damagedie " + (string)s["name"]]["value"]); if (!dmg.NullorEmpty()) { try { RollResult result2 = Roller.Roll(dmg + "+" + damagebonus); summary += "\n**" + dmgtype.Uppercase() + " damage**: " + result2.ParseResult() + " = `" + result2.Value + "` "; if (!((string)s["extradamage"]).NullorEmpty()) { string extradmg = (string)s["extradamage"]; if (!extradmg.NullorEmpty() && AttributeRegex.IsMatch(extradmg)) { extradmg = await ParseValues(extradmg, c, values); } if (DmgRegex.IsMatch(extradmg)) { foreach (var m in DmgRegex.Matches(extradmg).ToList()) { try { RollResult dmgroll = Roller.Roll(m.Groups[2].Value); summary += "\n**" + m.Groups[1].Value + " damage**: " + dmgroll.ParseResult() + " = `" + dmgroll.Value + "` "; } catch { continue; } } } } } catch { await ReplyAsync("It seems like this strike doesn't have a valid dice roll on its damage or additional damage fields. If this is a spell make sure you have a valid dice expression on the damage fields."); return; } } JToken details = s["details"]; if (details != null && details.HasValues) { foreach (var value in details.Where(x => (bool)x["active"] == true || Toggles.Contains(((string)x["name"]).ToLower()))) { try { RollResult Eresult = Roller.Roll((string)value["comment"]); summary += "\n**" + (((string)value["name"]).NullorEmpty() ? "Extra Damage (" + (((string)value["type"]).NullorEmpty() ? "Untyped" : (string)value["type"]) + ") " : (string)value["name"] + " (" + (((string)value["type"]).NullorEmpty() ? "Untyped" : (string)value["type"]) + ") ") + "**: " + Eresult.ParseResult() + " = `" + Eresult.Value + "`"; } catch { continue; } } } embed.WithDescription(summary) .WithFooter((c.ValuesLastUpdated.Outdated() ? "⚠️ Couldn't retrieve updated values. Roll might not be accurate" : DateTime.Now.ToString())); await ReplyAsync(" ", embed.Build()); } else { string summary = ""; if (!((string)s["weapon"]).NullorEmpty()) { var items = await SheetService.Get(c, "items"); var i = items.First(x => (string)x["id"] == (string)s["weapon"]); dmgtype = (string)i["damagetype"] ?? "Untyped"; if (!((string)i["traits"]).NullorEmpty()) { string[] traits = ((string)i["traits"]).Split(','); foreach (var x in traits) { summary += "[" + x.ToUpper() + "] "; } summary += "\n"; } int range = 0; if (!((string)i["range"]).NullorEmpty() && int.TryParse((string)i["range"], out int r)) { range += r; } if (!((string)s["modrange"]).NullorEmpty() && int.TryParse((string)s["modrange"], out int r2)) { range += r2; } summary += "**Range**: " + range + "ft.\n"; if ((string)i["attack"] == "melee") { hit = (string)values["melee " + (string)s["name"]]["bonus"]; penalties = (string)values["melee " + (string)s["name"]]["penalty"]; } else if ((string)i["attack"] == "ranged") { hit = (string)values["ranged " + (string)s["name"]]["bonus"]; penalties = (string)values["ranged " + (string)s["name"]]["penalty"]; } if (!((string)i["name"]).NullorEmpty()) { embed.WithTitle(c.Name + " strikes with a " + (string)i["name"] + "!"); } } if ((string)s["attack"] == "melee") { hit = (string)values["melee " + (string)s["name"]]["bonus"]; penalties = (string)values["melee " + (string)s["name"]]["penalty"]; } else if ((string)s["attack"] == "ranged") { hit = (string)values["ranged " + (string)s["name"]]["bonus"]; penalties = (string)values["ranged " + (string)s["name"]]["penalty"]; } damagebonus = (string)values["damage " + (string)s["name"]]["value"]; dmg = (string)values["damagedice " + (string)s["name"]]["value"] + GetDie((int)values["damagedie " + (string)s["name"]]["value"]); var result = Roller.Roll("d20 + " + hit + (penalties != "0"? "-" + penalties:"") + (Bonuses.Length > 0 ? string.Join(" ", Bonuses) : "")); summary += "**Attack roll**: " + result.ParseResult() + " = `" + result.Value + "`"; if (!dmg.NullorEmpty()) { try { RollResult result2 = Roller.Roll(dmg + "+" + damagebonus); summary += "\n**" + dmgtype.Uppercase() + " damage**: " + result2.ParseResult() + " = `" + result2.Value + "` "; if (!((string)s["extradamage"]).NullorEmpty()) { string extradmg = (string)s["extradamage"]; if (!extradmg.NullorEmpty() && AttributeRegex.IsMatch(extradmg)) { extradmg = await ParseValues(extradmg, c, values); } if (DmgRegex.IsMatch(extradmg)) { foreach (var m in DmgRegex.Matches(extradmg).ToList()) { try { RollResult dmgroll = Roller.Roll(m.Groups[2].Value); summary += "\n**" + m.Groups[1].Value + " damage**: " + dmgroll.ParseResult() + " = `" + dmgroll.Value + "` "; } catch { continue; } } } } } catch { await ReplyAsync("It seems like this strike doesn't have a valid dice roll on its damage or additional damage fields. If this is a spell make sure you have a valid dice expression on the damage fields."); return; } } JToken details = s["details"]; if (details != null && details.HasValues) { foreach (var value in details.Where(x => (bool)x["active"] == true || Toggles.Contains(((string)x["name"]).ToLower()))) { try { RollResult Eresult = Roller.Roll((string)value["comment"]); summary += "\n**" + (((string)value["name"]).NullorEmpty() ? "Extra Damage (" + (((string)value["type"]).NullorEmpty() ? "Untyped" : (string)value["type"]) + ") " : (string)value["name"] + " (" + (((string)value["type"]).NullorEmpty() ? "Untyped" : (string)value["type"]) + ") ") + "**: " + Eresult.ParseResult() + " = `" + Eresult.Value + "`"; } catch { continue; } } } embed.WithDescription(summary) .WithFooter((c.ValuesLastUpdated.Outdated() ? "⚠️ Couldn't retrieve updated values. Roll might not be accurate" : DateTime.Now.ToString())); await ReplyAsync(" ", embed.Build()); } } }