Cleanup
This commit is contained in:
@@ -136,7 +136,7 @@
|
|||||||
<div class="card-shimmer"></div>
|
<div class="card-shimmer"></div>
|
||||||
<img src="@card.ImagePath" alt="@card.Name" loading="lazy"
|
<img src="@card.ImagePath" alt="@card.Name" loading="lazy"
|
||||||
onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22200%22 height=%22280%22><rect fill=%22%23222244%22 width=%22200%22 height=%22280%22/><text fill=%22%23686888%22 font-size=%2214%22 x=%22100%22 y=%22140%22 text-anchor=%22middle%22 dominant-baseline=%22middle%22>No Image</text></svg>'"/>
|
onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22200%22 height=%22280%22><rect fill=%22%23222244%22 width=%22200%22 height=%22280%22/><text fill=%22%23686888%22 font-size=%2214%22 x=%22100%22 y=%22140%22 text-anchor=%22middle%22 dominant-baseline=%22middle%22>No Image</text></svg>'"/>
|
||||||
|
|
||||||
@if (card.IsSpell && !string.IsNullOrEmpty(card.Speed))
|
@if (card.IsSpell && !string.IsNullOrEmpty(card.Speed))
|
||||||
{
|
{
|
||||||
<div class="card-speed-badge" title="Speed">
|
<div class="card-speed-badge" title="Speed">
|
||||||
|
|||||||
@@ -298,7 +298,9 @@
|
|||||||
var inDeck = deckCards.ToHashSet();
|
var inDeck = deckCards.ToHashSet();
|
||||||
var otherDiverSlot = activeDiverSlot == 0
|
var otherDiverSlot = activeDiverSlot == 0
|
||||||
? divers.Count > 1 ? divers[1] : null
|
? divers.Count > 1 ? divers[1] : null
|
||||||
: divers.Count > 0 ? divers[0] : null;
|
: divers.Count > 0
|
||||||
|
? divers[0]
|
||||||
|
: null;
|
||||||
|
|
||||||
return AllCards
|
return AllCards
|
||||||
.Where(c => c.Category is "Agent" or "Spell" or "Immortalized")
|
.Where(c => c.Category is "Agent" or "Spell" or "Immortalized")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<Router AppAssembly="@typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(Home).Assembly, typeof(Shared.Pages.Syndicates).Assembly, typeof(Shared.Pages.Agents).Assembly }">
|
<Router AppAssembly="@typeof(Program).Assembly"
|
||||||
|
AdditionalAssemblies="new[] { typeof(Home).Assembly, typeof(Syndicates).Assembly, typeof(Agents).Assembly }">
|
||||||
<Found Context="routeData">
|
<Found Context="routeData">
|
||||||
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
|
<AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)">
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
|
|||||||
@@ -20,6 +20,6 @@
|
|||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Update="..\..\chrono.docs\Faction" />
|
<Folder Update="..\..\chrono.docs\Faction"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
@using Shared.Services
|
|
||||||
@implements IDisposable
|
@implements IDisposable
|
||||||
@inject CardPreviewService PreviewService
|
@inject CardPreviewService PreviewService
|
||||||
@namespace Shared.Components
|
@namespace Shared.Components
|
||||||
@@ -7,12 +6,13 @@
|
|||||||
{
|
{
|
||||||
<div class="card-preview-popup" style="left: @(PreviewService.X + 20)px; top: @(PreviewService.Y)px;">
|
<div class="card-preview-popup" style="left: @(PreviewService.X + 20)px; top: @(PreviewService.Y)px;">
|
||||||
<div class="preview-content">
|
<div class="preview-content">
|
||||||
<img src="@PreviewService.HoveredCard.ImagePath" alt="@PreviewService.HoveredCard.Name" />
|
<img src="@PreviewService.HoveredCard.ImagePath" alt="@PreviewService.HoveredCard.Name"/>
|
||||||
<div class="preview-info">
|
<div class="preview-info">
|
||||||
<strong>@PreviewService.HoveredCard.Name</strong>
|
<strong>@PreviewService.HoveredCard.Name</strong>
|
||||||
@if (PreviewService.HoveredCard.Cost.HasValue)
|
@if (PreviewService.HoveredCard.Cost.HasValue)
|
||||||
{
|
{
|
||||||
<span class="preview-cost"><i class="bi bi-lightning-fill"></i> @PreviewService.HoveredCard.Cost</span>
|
<span class="preview-cost"><i
|
||||||
|
class="bi bi-lightning-fill"></i> @PreviewService.HoveredCard.Cost</span>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
PreviewService.OnChange += StateHasChanged;
|
PreviewService.OnChange += StateHasChanged;
|
||||||
@@ -29,4 +30,5 @@
|
|||||||
{
|
{
|
||||||
PreviewService.OnChange -= StateHasChanged;
|
PreviewService.OnChange -= StateHasChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,8 @@
|
|||||||
tableLines.Add(trimmedLine);
|
tableLines.Add(trimmedLine);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inTable)
|
|
||||||
|
if (inTable)
|
||||||
{
|
{
|
||||||
RenderTable(builder, ref seq, tableLines);
|
RenderTable(builder, ref seq, tableLines);
|
||||||
tableLines.Clear();
|
tableLines.Clear();
|
||||||
@@ -100,13 +101,15 @@
|
|||||||
builder.OpenElement(seq++, "ul");
|
builder.OpenElement(seq++, "ul");
|
||||||
inList = true;
|
inList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isCardListItem = trimmedLine.Contains("[[") && trimmedLine.Contains("]]");
|
var isCardListItem = trimmedLine.Contains("[[") && trimmedLine.Contains("]]");
|
||||||
builder.OpenElement(seq++, "li");
|
builder.OpenElement(seq++, "li");
|
||||||
RenderInlines(builder, ref seq, trimmedLine[2..], true);
|
RenderInlines(builder, ref seq, trimmedLine[2..], true);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inList)
|
|
||||||
|
if (inList)
|
||||||
{
|
{
|
||||||
builder.CloseElement(); // Close ul
|
builder.CloseElement(); // Close ul
|
||||||
inList = false;
|
inList = false;
|
||||||
@@ -167,6 +170,7 @@
|
|||||||
RenderInlines(builder, ref seq, cell.Trim(), false);
|
RenderInlines(builder, ref seq, cell.Trim(), false);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
startIdx = 2;
|
startIdx = 2;
|
||||||
@@ -184,8 +188,10 @@
|
|||||||
RenderInlines(builder, ref seq, cell.Trim(), false);
|
RenderInlines(builder, ref seq, cell.Trim(), false);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
@@ -194,7 +200,7 @@
|
|||||||
private void RenderInlines(RenderTreeBuilder builder, ref int seq, string text, bool renderAsImage)
|
private void RenderInlines(RenderTreeBuilder builder, ref int seq, string text, bool renderAsImage)
|
||||||
{
|
{
|
||||||
var remaining = text;
|
var remaining = text;
|
||||||
|
|
||||||
while (!string.IsNullOrEmpty(remaining))
|
while (!string.IsNullOrEmpty(remaining))
|
||||||
{
|
{
|
||||||
var boldMatch = Regex.Match(remaining, @"\*\*(.*?)\*\*");
|
var boldMatch = Regex.Match(remaining, @"\*\*(.*?)\*\*");
|
||||||
@@ -203,11 +209,28 @@
|
|||||||
|
|
||||||
var bestIdx = int.MaxValue;
|
var bestIdx = int.MaxValue;
|
||||||
Match? bestMatch = null;
|
Match? bestMatch = null;
|
||||||
int matchType = 0; // 1: bold, 2: italic, 3: card
|
var matchType = 0; // 1: bold, 2: italic, 3: card
|
||||||
|
|
||||||
if (boldMatch.Success && boldMatch.Index < bestIdx) { bestIdx = boldMatch.Index; bestMatch = boldMatch; matchType = 1; }
|
if (boldMatch.Success && boldMatch.Index < bestIdx)
|
||||||
if (italicMatch.Success && italicMatch.Index < bestIdx) { bestIdx = italicMatch.Index; bestMatch = italicMatch; matchType = 2; }
|
{
|
||||||
if (cardMatch.Success && cardMatch.Index < bestIdx) { bestIdx = cardMatch.Index; bestMatch = cardMatch; matchType = 3; }
|
bestIdx = boldMatch.Index;
|
||||||
|
bestMatch = boldMatch;
|
||||||
|
matchType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (italicMatch.Success && italicMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = italicMatch.Index;
|
||||||
|
bestMatch = italicMatch;
|
||||||
|
matchType = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardMatch.Success && cardMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = cardMatch.Index;
|
||||||
|
bestMatch = cardMatch;
|
||||||
|
matchType = 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (bestMatch != null)
|
if (bestMatch != null)
|
||||||
{
|
{
|
||||||
@@ -215,7 +238,7 @@
|
|||||||
builder.AddContent(seq++, remaining[..bestIdx]);
|
builder.AddContent(seq++, remaining[..bestIdx]);
|
||||||
|
|
||||||
var innerText = bestMatch.Groups[1].Value;
|
var innerText = bestMatch.Groups[1].Value;
|
||||||
|
|
||||||
if (matchType == 1) // Bold
|
if (matchType == 1) // Bold
|
||||||
{
|
{
|
||||||
builder.OpenElement(seq++, "strong");
|
builder.OpenElement(seq++, "strong");
|
||||||
@@ -255,4 +278,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
from { opacity: 0; }
|
from {
|
||||||
to { opacity: 1; }
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-detail {
|
.card-detail {
|
||||||
@@ -148,17 +152,42 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-content h2 { font-size: 1.5rem; }
|
.markdown-content h2 {
|
||||||
.markdown-content h3 { font-size: 1.3rem; }
|
font-size: 1.5rem;
|
||||||
.markdown-content h4 { font-size: 1.1rem; }
|
}
|
||||||
|
|
||||||
|
.markdown-content h3 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content h4 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Syndicate Colors */
|
/* Syndicate Colors */
|
||||||
.lifeblood { color: #4caf50; }
|
.lifeblood {
|
||||||
.phasetide { color: #2196f3; }
|
color: #4caf50;
|
||||||
.silence { color: #9c27b0; }
|
}
|
||||||
.singularity { color: #ffffff; }
|
|
||||||
.splintergleam { color: #f44336; }
|
.phasetide {
|
||||||
.sungrace { color: #ff9800; }
|
color: #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.silence {
|
||||||
|
color: #9c27b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.singularity {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splintergleam {
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sungrace {
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
.inline-card-btn {
|
.inline-card-btn {
|
||||||
background: none;
|
background: none;
|
||||||
@@ -194,6 +223,7 @@
|
|||||||
width: 95vw;
|
width: 95vw;
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-layout {
|
.detail-layout {
|
||||||
padding: 2rem 1.25rem;
|
padding: 2rem 1.25rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,8 @@
|
|||||||
tableLines.Add(trimmedLine);
|
tableLines.Add(trimmedLine);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inTable)
|
|
||||||
|
if (inTable)
|
||||||
{
|
{
|
||||||
RenderTable(builder, ref seq, tableLines);
|
RenderTable(builder, ref seq, tableLines);
|
||||||
tableLines.Clear();
|
tableLines.Clear();
|
||||||
@@ -106,13 +107,15 @@
|
|||||||
builder.OpenElement(seq++, "ul");
|
builder.OpenElement(seq++, "ul");
|
||||||
inList = true;
|
inList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isCardListItem = trimmedLine.Contains("[[") && trimmedLine.Contains("]]");
|
var isCardListItem = trimmedLine.Contains("[[") && trimmedLine.Contains("]]");
|
||||||
builder.OpenElement(seq++, "li");
|
builder.OpenElement(seq++, "li");
|
||||||
RenderInlines(builder, ref seq, trimmedLine[2..], true);
|
RenderInlines(builder, ref seq, trimmedLine[2..], true);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inList)
|
|
||||||
|
if (inList)
|
||||||
{
|
{
|
||||||
builder.CloseElement(); // Close ul
|
builder.CloseElement(); // Close ul
|
||||||
inList = false;
|
inList = false;
|
||||||
@@ -173,6 +176,7 @@
|
|||||||
RenderInlines(builder, ref seq, cell.Trim(), false);
|
RenderInlines(builder, ref seq, cell.Trim(), false);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
startIdx = 2;
|
startIdx = 2;
|
||||||
@@ -190,8 +194,10 @@
|
|||||||
RenderInlines(builder, ref seq, cell.Trim(), false);
|
RenderInlines(builder, ref seq, cell.Trim(), false);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
@@ -201,7 +207,7 @@
|
|||||||
{
|
{
|
||||||
// Simple regex-based inline parser for Bold, Italics, and [[Card Links]]
|
// Simple regex-based inline parser for Bold, Italics, and [[Card Links]]
|
||||||
var remaining = text;
|
var remaining = text;
|
||||||
|
|
||||||
while (!string.IsNullOrEmpty(remaining))
|
while (!string.IsNullOrEmpty(remaining))
|
||||||
{
|
{
|
||||||
var boldMatch = Regex.Match(remaining, @"\*\*(.*?)\*\*");
|
var boldMatch = Regex.Match(remaining, @"\*\*(.*?)\*\*");
|
||||||
@@ -210,11 +216,28 @@
|
|||||||
|
|
||||||
var bestIdx = int.MaxValue;
|
var bestIdx = int.MaxValue;
|
||||||
Match? bestMatch = null;
|
Match? bestMatch = null;
|
||||||
int matchType = 0; // 1: bold, 2: italic, 3: card
|
var matchType = 0; // 1: bold, 2: italic, 3: card
|
||||||
|
|
||||||
if (boldMatch.Success && boldMatch.Index < bestIdx) { bestIdx = boldMatch.Index; bestMatch = boldMatch; matchType = 1; }
|
if (boldMatch.Success && boldMatch.Index < bestIdx)
|
||||||
if (italicMatch.Success && italicMatch.Index < bestIdx) { bestIdx = italicMatch.Index; bestMatch = italicMatch; matchType = 2; }
|
{
|
||||||
if (cardMatch.Success && cardMatch.Index < bestIdx) { bestIdx = cardMatch.Index; bestMatch = cardMatch; matchType = 3; }
|
bestIdx = boldMatch.Index;
|
||||||
|
bestMatch = boldMatch;
|
||||||
|
matchType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (italicMatch.Success && italicMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = italicMatch.Index;
|
||||||
|
bestMatch = italicMatch;
|
||||||
|
matchType = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardMatch.Success && cardMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = cardMatch.Index;
|
||||||
|
bestMatch = cardMatch;
|
||||||
|
matchType = 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (bestMatch != null)
|
if (bestMatch != null)
|
||||||
{
|
{
|
||||||
@@ -222,7 +245,7 @@
|
|||||||
builder.AddContent(seq++, remaining[..bestIdx]);
|
builder.AddContent(seq++, remaining[..bestIdx]);
|
||||||
|
|
||||||
var innerText = bestMatch.Groups[1].Value;
|
var innerText = bestMatch.Groups[1].Value;
|
||||||
|
|
||||||
if (matchType == 1) // Bold
|
if (matchType == 1) // Bold
|
||||||
{
|
{
|
||||||
builder.OpenElement(seq++, "strong");
|
builder.OpenElement(seq++, "strong");
|
||||||
@@ -262,4 +285,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
from { opacity: 0; }
|
from {
|
||||||
to { opacity: 1; }
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-detail {
|
.card-detail {
|
||||||
@@ -189,17 +193,42 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-content h2 { font-size: 1.5rem; }
|
.markdown-content h2 {
|
||||||
.markdown-content h3 { font-size: 1.3rem; }
|
font-size: 1.5rem;
|
||||||
.markdown-content h4 { font-size: 1.1rem; }
|
}
|
||||||
|
|
||||||
|
.markdown-content h3 {
|
||||||
|
font-size: 1.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content h4 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Syndicate Colors */
|
/* Syndicate Colors */
|
||||||
.lifeblood { color: #4caf50; }
|
.lifeblood {
|
||||||
.phasetide { color: #2196f3; }
|
color: #4caf50;
|
||||||
.silence { color: #9c27b0; }
|
}
|
||||||
.singularity { color: #ffffff; }
|
|
||||||
.splintergleam { color: #f44336; }
|
.phasetide {
|
||||||
.sungrace { color: #ff9800; }
|
color: #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.silence {
|
||||||
|
color: #9c27b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.singularity {
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splintergleam {
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sungrace {
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
.inline-card-btn {
|
.inline-card-btn {
|
||||||
background: none;
|
background: none;
|
||||||
@@ -235,6 +264,7 @@
|
|||||||
width: 95vw;
|
width: 95vw;
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
.detail-layout {
|
.detail-layout {
|
||||||
padding: 2rem 1.25rem;
|
padding: 2rem 1.25rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -795,7 +795,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Lifeblood",
|
Title = "Lifeblood",
|
||||||
Category = "Syndicate",
|
Category = "Syndicate",
|
||||||
Content = "# Timelines\n\n## Deadly Fauna\n\nGives everything +1 / +1.\n\n## Abundant Growth\n\nGives everything [[Overpower]].\n\n# Mechanics\n\n## Flourish\n\nFlourish.\n## Combat\n\nCombat.\n## Evasive\n\nEvasive.\n\n## Sprout\n\nSprout.\n\n# Wolves\n\nWolves.\n\n# Key Cards\n\n## Defensive Cards:\n- [[Bloom]]\n- [[Mulch]]\n- [[Focused Adaptation]]\n- [[Symbiosis]]\n\n\n## Threats\n- [[Glade Grazers]]\n- [[Sapling Dryad]]\n- [[Spark of Bounty]]\n- [[Glasswinged Monarch]]\n- [[Zealot of the Hunt]]\n- [[Hungry Tyrannosaur]]",
|
Content = "# Timelines\n\n## Deadly Fauna\n\nGives everything +1 / +1.\n\n## Abundant Growth\n\nGives everything [[Overpower]].\n\n# Mechanics\n\n## Flourish\n\nFlourish.\n\n## Combat\n\nCombat.\n\n## Evasive\n\nEvasive.\n\n## Sprout\n\nSprout.\n\n# Wolves\n\nWolves.\n\n# Key Cards\n\n## Defensive Cards:\n\n- [[Bloom]]\n- [[Mulch]]\n- [[Focused Adaptation]]\n- [[Symbiosis]]\n\n## Threats\n\n- [[Glade Grazers]]\n- [[Sapling Dryad]]\n- [[Spark of Bounty]]\n- [[Glasswinged Monarch]]\n- [[Zealot of the Hunt]]\n- [[Hungry Tyrannosaur]]",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Syndicate" },
|
{ "category", "Syndicate" },
|
||||||
@@ -808,7 +808,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Phasetide",
|
Title = "Phasetide",
|
||||||
Category = "Syndicate",
|
Category = "Syndicate",
|
||||||
Content = "# Timelines\n\n## The One True Timeline\n\nHeals everything 1 health each turn.\n\nA lot of Phasetide agents simply immortalize in this timeline. And a lot of Phasetide agents start damage to take advantage of this healing effect.\n\nAnd some Phasetide agents will hate it when your not in the timeline. Such as [[Shattersmith]], which will flat out die if too many timelines exist in the stack that are not The One True timeline.\n\n# Mechanics\n\n## Healing\n\nHealing.\n\nCards:\n- [[Bearer of the Broth]]\n\nPayoff:\n- [[Bareknuckle Inquisitor]]\n\n## Rewind\n\nRewind.\n\nCards: \n- [[Temple Analyst]]\n\nPayoff:\n- [[Divergence Assassin]]\n\n## Phase\n\nPhase.\n\nCards:\n- [[Set in Stone]]\n\nPayoff:\n- [[Karmic Debtor]]\n\n## Reduce Cost\n\nReduce cost.\n\nCards:\n- [[Slow Convert]]\n\nPayoff:\n- [[Stern Arbiter]]\n\n# Key Cards\n\n## Defensive Cards:\n- [[Prayer of Rescue]]\n- [[Invigorating Balm]]\n- [[Set in Stone]]\n- [[Out of Line]]\n\n## Threats\n- [[Temple Analyst]]\n- [[Consummate Conspirator]]\n- [[Bareknuckle Inquisitor]]\n- [[Divergence Assassin]]\n- [[Stern Arbiter]]",
|
Content = "# Timelines\n\n## The One True Timeline\n\nHeals everything 1 health each turn.\n\nA lot of Phasetide agents simply immortalize in this timeline. And a lot of Phasetide agents start damage to take\nadvantage of this healing effect.\n\nAnd some Phasetide agents will hate it when your not in the timeline. Such as [[Shattersmith]], which will flat out die\nif too many timelines exist in the stack that are not The One True timeline.\n\n# Mechanics\n\n## Healing\n\nHealing.\n\nCards:\n\n- [[Bearer of the Broth]]\n\nPayoff:\n\n- [[Bareknuckle Inquisitor]]\n\n## Rewind\n\nRewind.\n\nCards:\n\n- [[Temple Analyst]]\n\nPayoff:\n\n- [[Divergence Assassin]]\n\n## Phase\n\nPhase.\n\nCards:\n\n- [[Set in Stone]]\n\nPayoff:\n\n- [[Karmic Debtor]]\n\n## Reduce Cost\n\nReduce cost.\n\nCards:\n\n- [[Slow Convert]]\n\nPayoff:\n\n- [[Stern Arbiter]]\n\n# Key Cards\n\n## Defensive Cards:\n\n- [[Prayer of Rescue]]\n- [[Invigorating Balm]]\n- [[Set in Stone]]\n- [[Out of Line]]\n\n## Threats\n\n- [[Temple Analyst]]\n- [[Consummate Conspirator]]\n- [[Bareknuckle Inquisitor]]\n- [[Divergence Assassin]]\n- [[Stern Arbiter]]",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Syndicate" },
|
{ "category", "Syndicate" },
|
||||||
@@ -821,7 +821,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Silence",
|
Title = "Silence",
|
||||||
Category = "Syndicate",
|
Category = "Syndicate",
|
||||||
Content = "# Timelines\n\n## Voiceless Skies\n\nCauses it so that if you have one agent in play, that agent gets +3 / +3.\nWith deplete, you can ensure the player ideally can never properly take advantage of the timeline.\n\nIt turn on some of your key board survival cards, like [[Braindead Bouncer]] and [[Nameless Spirit]].\n\nIt also notably interacts with [[Phase]]. So you can phase your [[Sensory Deprivation Pod]] to potentially activate Voiceless Skies for your other blocker, or use [[Bury the Evidence]] if you have two 1 / 1 cards and need to remove one. \n\n# Mechanics\n\n## Deplete\n\nPrevents a card from attacking and blocking if they have not already attacked or blocked. Also prevents a card from being activated, although outside of [[Mind Over Matter]] during [[Voiceless Sky]], the opposing agent can always activate in a response.\n\nCards:\n- [[Return to Stillness]]\n\nPayoff:\n- [[Telepathic Scavenger]]\n\n## Mute\n\nCan remove all keywords and effects on an agent. Note the order matters. If you mute a target, and an effect gets added on after, the agent will have the newly added effect while still being considered muted.\n\nCards: \n- [[Muffle]]\n\nPayoff:\n- [[Destiny Ripper]]\n\n## Revival\n\nCan bring cards back from the dead. Currently mostly a mechanic in practice for keeping [[Somnus, the Dreaming]] alive.\n\nCards:\n- [[The Forgotten Tale]]\n\nPayoff:\n- [[Solemn Attendant]]\n\n## Spell Duplication\n\nHas access to duplicating spells.\n\nCards:\n- [[Disciplined Student]]\n\nPayoff:\n- [[Overburdened Scribe]]\n\n## Activations\n\nCards with strong activation effects. And it's revival package also allows you to kill off and revive your own cards to activate them again in a fresh state.\n\nCards:\n- [[Death Jockey]]\n\nPayoff:\n- [[Rotting Rocker]]\n\n# Key Cards\n\n## Defensive Cards:\n- [[Hush Now]]\n- [[Spread the Sickness]]\n- [[Pressure Spike]]\n- [[Muffle]]\n\n## Threats\n- [[Rotting Rocker]]\n- [[Telepathic Scavenger]]\n- [[Sensory Deprivation Pod]]\n- [[Overburdened Scribe]]\n- [[The Forgotten Tale]]",
|
Content = "# Timelines\n\n## Voiceless Skies\n\nCauses it so that if you have one agent in play, that agent gets +3 / +3.\nWith deplete, you can ensure the player ideally can never properly take advantage of the timeline.\n\nIt turn on some of your key board survival cards, like [[Braindead Bouncer]] and [[Nameless Spirit]].\n\nIt also notably interacts with [[Phase]]. So you can phase your [[Sensory Deprivation Pod]] to potentially activate\nVoiceless Skies for your other blocker, or use [[Bury the Evidence]] if you have two 1 / 1 cards and need to remove one.\n\n# Mechanics\n\n## Deplete\n\nPrevents a card from attacking and blocking if they have not already attacked or blocked. Also prevents a card from\nbeing activated, although outside of [[Mind Over Matter]] during [[Voiceless Sky]], the opposing agent can always\nactivate in a response.\n\nCards:\n\n- [[Return to Stillness]]\n\nPayoff:\n\n- [[Telepathic Scavenger]]\n\n## Mute\n\nCan remove all keywords and effects on an agent. Note the order matters. If you mute a target, and an effect gets added\non after, the agent will have the newly added effect while still being considered muted.\n\nCards:\n\n- [[Muffle]]\n\nPayoff:\n\n- [[Destiny Ripper]]\n\n## Revival\n\nCan bring cards back from the dead. Currently mostly a mechanic in practice for keeping [[Somnus, the Dreaming]] alive.\n\nCards:\n\n- [[The Forgotten Tale]]\n\nPayoff:\n\n- [[Solemn Attendant]]\n\n## Spell Duplication\n\nHas access to duplicating spells.\n\nCards:\n\n- [[Disciplined Student]]\n\nPayoff:\n\n- [[Overburdened Scribe]]\n\n## Activations\n\nCards with strong activation effects. And it's revival package also allows you to kill off and revive your own cards to\nactivate them again in a fresh state.\n\nCards:\n\n- [[Death Jockey]]\n\nPayoff:\n\n- [[Rotting Rocker]]\n\n# Key Cards\n\n## Defensive Cards:\n\n- [[Hush Now]]\n- [[Spread the Sickness]]\n- [[Pressure Spike]]\n- [[Muffle]]\n\n## Threats\n\n- [[Rotting Rocker]]\n- [[Telepathic Scavenger]]\n- [[Sensory Deprivation Pod]]\n- [[Overburdened Scribe]]\n- [[The Forgotten Tale]]",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Syndicate" },
|
{ "category", "Syndicate" },
|
||||||
@@ -834,7 +834,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Singularity",
|
Title = "Singularity",
|
||||||
Category = "Syndicate",
|
Category = "Syndicate",
|
||||||
Content = "# Timelines\n\n## Erudite Beacon\n\nCauses you to draw a card when you shift to it, and a card every round. You will have many cards in hand, so if you play in this timeline, you need ways to spend your hand to avoid erasing cards off the top of your deck. \n\n[[Enlightened Refugee]] is the simplest way to shift to this [[Timeline]].\n\n# Mechanics\n\n## Discard\n\nHas a lot of cards that can be removed from hand for added benefits, and a lot of cards that can discard for additional card draw.\n\nCards:\n- [[Efficient Scrapbot]]\n\nPayoff:\n- [[Rapid Iteration]]\n\n## Disarm\n\nCan reduce agents attack values to zero. Way to reduce damage for a turn or win combat trades.\n\nCards:\n- [[Frontline Fellowship]]\n\nPayoff:\n- [[Traffic Conductor]]\n\n## Agent Duplication\n\nHas access to duplicating agents.\n\nCards:\n- [[Chronal Scan]]\n\nPayoff:\n- [[Springloaded Hopper]]\n\n## Pocket Scout\n\n1 / 1 token that can swarm the board or chump block.\n\nCards:\n- [[Enthusiastic Bot-Poke]]\n\nPayoff:\n- [[Scattered Helpers]]\n\n# Key Cards\n\n## Defensive Cards:\n- [[Timestop]]\n- [[Rapid Iteration]]\n- [[Frontline Fellowship]]\n\n## Threats\n- [[Roiling Amalgam]]\n- [[Rogue Amalgam]]\n- [[Quicksilver Khaela]]\n- [[Scuttling Spares]]\n- [[Springloaded Hopper]]",
|
Content = "# Timelines\n\n## Erudite Beacon\n\nCauses you to draw a card when you shift to it, and a card every round. You will have many cards in hand, so if you play\nin this timeline, you need ways to spend your hand to avoid erasing cards off the top of your deck.\n\n[[Enlightened Refugee]] is the simplest way to shift to this [[Timeline]].\n\n# Mechanics\n\n## Discard\n\nHas a lot of cards that can be removed from hand for added benefits, and a lot of cards that can discard for additional\ncard draw.\n\nCards:\n\n- [[Efficient Scrapbot]]\n\nPayoff:\n\n- [[Rapid Iteration]]\n\n## Disarm\n\nCan reduce agents attack values to zero. Way to reduce damage for a turn or win combat trades.\n\nCards:\n\n- [[Frontline Fellowship]]\n\nPayoff:\n\n- [[Traffic Conductor]]\n\n## Agent Duplication\n\nHas access to duplicating agents.\n\nCards:\n\n- [[Chronal Scan]]\n\nPayoff:\n\n- [[Springloaded Hopper]]\n\n## Pocket Scout\n\n1 / 1 token that can swarm the board or chump block.\n\nCards:\n\n- [[Enthusiastic Bot-Poke]]\n\nPayoff:\n\n- [[Scattered Helpers]]\n\n# Key Cards\n\n## Defensive Cards:\n\n- [[Timestop]]\n- [[Rapid Iteration]]\n- [[Frontline Fellowship]]\n\n## Threats\n\n- [[Roiling Amalgam]]\n- [[Rogue Amalgam]]\n- [[Quicksilver Khaela]]\n- [[Scuttling Spares]]\n- [[Springloaded Hopper]]",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Syndicate" },
|
{ "category", "Syndicate" },
|
||||||
@@ -847,7 +847,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Splintergleam",
|
Title = "Splintergleam",
|
||||||
Category = "Syndicate",
|
Category = "Syndicate",
|
||||||
Content = "# Timelines\n\n## Volcanic Rivers\n\nDeals 1 damage to each core when shifted to.\n\n## Torment\n\n# Mechanics\n\n## Bleed\n\nBleed.\n## Big Timeline Stack\n\nBig Timeline Stack\n## Fervor\n\nFervor\n\n## Self Wound\n\nSelf Wound\n\n\n# Key Cards\n\n## Defensive Cards:\n- [[Bathe in Flames]]\n- [[Circle of Strife]]\n- [[Paradox Cacophony]]\n- [[Fervor]]\n- [[Sanguine Resurgence]]\n\n\n## Threats\n- [[Pit Dog]]\n- [[Bright-Eyed Supplicant]]\n- [[Blazing Shifter]]\n- [[Toothy Pugilist]]\n- [[Devoted Bloodletter]]\n- [[Hungry Engine]]\n- [[Frontline Juggernaut]]\n- [[Brutal Reveler]]\n- [[Gilded Behemoth]]",
|
Content = "# Timelines\n\n## Volcanic Rivers\n\nDeals 1 damage to each core when shifted to.\n\n## Torment\n\n# Mechanics\n\n## Bleed\n\nBleed.\n\n## Big Timeline Stack\n\nBig Timeline Stack\n\n## Fervor\n\nFervor\n\n## Self Wound\n\nSelf Wound\n\n# Key Cards\n\n## Defensive Cards:\n\n- [[Bathe in Flames]]\n- [[Circle of Strife]]\n- [[Paradox Cacophony]]\n- [[Fervor]]\n- [[Sanguine Resurgence]]\n\n## Threats\n\n- [[Pit Dog]]\n- [[Bright-Eyed Supplicant]]\n- [[Blazing Shifter]]\n- [[Toothy Pugilist]]\n- [[Devoted Bloodletter]]\n- [[Hungry Engine]]\n- [[Frontline Juggernaut]]\n- [[Brutal Reveler]]\n- [[Gilded Behemoth]]",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Syndicate" },
|
{ "category", "Syndicate" },
|
||||||
@@ -860,7 +860,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Sungrace",
|
Title = "Sungrace",
|
||||||
Category = "Syndicate",
|
Category = "Syndicate",
|
||||||
Content = "# Timelines\n\n## Star Siphon\n\nRefill your energy reserves every turn. Not, this will not overflow your energy reserve if your energy reserve is full and you otherwise have no other energy. Now if you have 1 energy, and 0 reserves, even though you have 2 less mana, it will overflow. So your encouraged to spend all your reserves and always leave one normal mana left over a turn to trigger your overflows.\n\n# Mechanics\n\n## Overflow\n\nEnergy Reserves.\n## Energy Reserves\n\nEnergy Reserves.\n## Spend 12+ Energy\n\nSpend 12+ Energy.\n\n## Ramp\n\nRamp.\n\n# Spells\n\nSpells.\n\n## Blitz\n\nBlitz.\n\n# Key Cards\n\n## Defensive Cards:\n- [[Soothing Glow]]\n- [[Chaos Control]]\n- [[Radiant Channeling]]\n- [[Supernova]]\n- [[Throw into the Sun]]\n- [[Entropy's End]]\n\n\n## Threats\n- [[Canine Adjutant]]\n- [[Limit Breaker]]\n- [[Debris Collector]]\n- [[Jury of the Second Law]]\n- [[Lightsteel Colossus]]\n- [[APEX Starcruise]]\n- [[Devourer Spawn]]",
|
Content = "# Timelines\n\n## Star Siphon\n\nRefill your energy reserves every turn. Not, this will not overflow your energy reserve if your energy reserve is full\nand you otherwise have no other energy. Now if you have 1 energy, and 0 reserves, even though you have 2 less mana, it\nwill overflow. So your encouraged to spend all your reserves and always leave one normal mana left over a turn to\ntrigger your overflows.\n\n# Mechanics\n\n## Overflow\n\nEnergy Reserves.\n\n## Energy Reserves\n\nEnergy Reserves.\n\n## Spend 12+ Energy\n\nSpend 12+ Energy.\n\n## Ramp\n\nRamp.\n\n# Spells\n\nSpells.\n\n## Blitz\n\nBlitz.\n\n# Key Cards\n\n## Defensive Cards:\n\n- [[Soothing Glow]]\n- [[Chaos Control]]\n- [[Radiant Channeling]]\n- [[Supernova]]\n- [[Throw into the Sun]]\n- [[Entropy's End]]\n\n## Threats\n\n- [[Canine Adjutant]]\n- [[Limit Breaker]]\n- [[Debris Collector]]\n- [[Jury of the Second Law]]\n- [[Lightsteel Colossus]]\n- [[APEX Starcruise]]\n- [[Devourer Spawn]]",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "category", "Syndicate" },
|
{ "category", "Syndicate" },
|
||||||
@@ -873,7 +873,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Lifeblood - Phasetide",
|
Title = "Lifeblood - Phasetide",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "Pairing has cards that care about [[Shift]] like [[Heretic Whistleblower]] and [[Convergent Pack]] so you could go that route.\r\n\r\nBoth pairings also have access to [[Flourish]], so you could go a board route and use [[Tidal Wave]] as a finisher.",
|
Content = "Pairing has cards that care about [[Shift]] like [[Heretic Whistleblower]] and [[Convergent Pack]] so you could go that\r\nroute.\r\n\r\nBoth pairings also have access to [[Flourish]], so you could go a board route and use [[Tidal Wave]] as a finisher.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Lifeblood\n- Phasetide" },
|
{ "syndicates", "- Lifeblood\n- Phasetide" },
|
||||||
@@ -889,7 +889,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Lifeblood - Silence",
|
Title = "Lifeblood - Silence",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "Typically the [[Somnus, the Dreaming]] pairing. Access to strong cards like [[Sap Sapper]] and [[Sleepy Druid]].\r\n\r\nSuppose you could also go [[Evasive]] with removal to protect your creatures from [[Confront]], and have [[Spirit's Lament]] as a top end.",
|
Content = "Typically the [[Somnus, the Dreaming]] pairing. Access to strong cards like [[Sap Sapper]] and [[Sleepy Druid]].\r\n\r\nSuppose you could also go [[Evasive]] with removal to protect your creatures from [[Confront]], and\r\nhave [[Spirit's Lament]] as a top end.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Lifeblood\n- Silence" },
|
{ "syndicates", "- Lifeblood\n- Silence" },
|
||||||
@@ -904,7 +904,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Lifeblood - Singularity",
|
Title = "Lifeblood - Singularity",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "For this pairing, I typically go [[Sprout]]. \r\n\r\n[[P.O.G.O]] is another easy one drop to make all your tokens more lethal, and you have a lot of cheap removal like [[Rapid Iteration]] and [[Wake-Up Prod]] to remove blockers that can otherwise slow down your game plan.",
|
Content = "For this pairing, I typically go [[Sprout]].\r\n\r\n[[P.O.G.O]] is another easy one drop to make all your tokens more lethal, and you have a lot of cheap removal\r\nlike [[Rapid Iteration]] and [[Wake-Up Prod]] to remove blockers that can otherwise slow down your game plan.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Lifeblood\n- Singularity" },
|
{ "syndicates", "- Lifeblood\n- Singularity" },
|
||||||
@@ -935,7 +935,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Lifeblood - Sungrace",
|
Title = "Lifeblood - Sungrace",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "Both actually have access to [[Flourish]], given [[Limit Breaker]] and [[Soothing Glow]].\r\n\r\nSo you could wrong a flourish deck, protect your agents with the massive amount of protection Sungrace and Lifeblood provide, and get a surprise lethal with [[Symbiosis]] to pay off all your flourish triggers.",
|
Content = "Both actually have access to [[Flourish]], given [[Limit Breaker]] and [[Soothing Glow]].\r\n\r\nSo you could wrong a flourish deck, protect your agents with the massive amount of protection Sungrace and Lifeblood\r\nprovide, and get a surprise lethal with [[Symbiosis]] to pay off all your flourish triggers.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Lifeblood\n- Sungrace" },
|
{ "syndicates", "- Lifeblood\n- Sungrace" },
|
||||||
@@ -950,7 +950,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Phasetide - Silence",
|
Title = "Phasetide - Silence",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "I suppose a control heavily [[The One True Timeline]] deck. \r\n\r\n[[Boof, Ever Loyal]] will return to hand the last played spell the current round if it dies. [[Silence]] has a lot of nice removal spells to copy.\r\n\r\nAnd I suppose given how easy it is to immortalize your cards with the one true timeline, [[Solemn Attendant]] will always have a target.\r\n\r\n[[Paradox Plague]] can be a bit awkward if there are not many timelines in the timeline stack, or bulky enough paradox units on the board, and [[Phasetide]] provides both.\r\n\r\nSo mid range [[The One True Timeline]] deck with [[Silence]] utilities and removal.\r\n\r\nAnd potential [[The Firm Hand]] can be what turns on your [[Overburdened Scribe]].",
|
Content = "I suppose a control heavily [[The One True Timeline]] deck.\r\n\r\n[[Boof, Ever Loyal]] will return to hand the last played spell the current round if it dies. [[Silence]] has a lot of\r\nnice removal spells to copy.\r\n\r\nAnd I suppose given how easy it is to immortalize your cards with the one true timeline, [[Solemn Attendant]] will\r\nalways have a target.\r\n\r\n[[Paradox Plague]] can be a bit awkward if there are not many timelines in the timeline stack, or bulky enough paradox\r\nunits on the board, and [[Phasetide]] provides both.\r\n\r\nSo mid range [[The One True Timeline]] deck with [[Silence]] utilities and removal.\r\n\r\nAnd potential [[The Firm Hand]] can be what turns on your [[Overburdened Scribe]].",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Phasetide\n- Silence" },
|
{ "syndicates", "- Phasetide\n- Silence" },
|
||||||
@@ -980,7 +980,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Phasetide - Splintergleam",
|
Title = "Phasetide - Splintergleam",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "You have access to bleeding and healing. Seems kind of clear of a gameplan. Bleed everything, and keep your stuff barely alive, while everything your enemy has dies.",
|
Content = "You have access to bleeding and healing. Seems kind of clear of a gameplan. Bleed everything, and keep your stuff barely\r\nalive, while everything your enemy has dies.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Phasetide\n- Splintergleam" },
|
{ "syndicates", "- Phasetide\n- Splintergleam" },
|
||||||
@@ -995,7 +995,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Phasetide - Sungrace",
|
Title = "Phasetide - Sungrace",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "You can [[Snap Back]] your [[Supernova]] for so much mana.\r\n\r\nThis is more of the stereotypically heal faction due to all the healing in [[Phasetide]] and [[Starfueled Medics]] to turn your healing more into a win condition.",
|
Content = "You can [[Snap Back]] your [[Supernova]] for so much mana.\r\n\r\nThis is more of the stereotypically heal faction due to all the healing in [[Phasetide]] and [[Starfueled Medics]] to\r\nturn your healing more into a win condition.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Phasetide\n- Sungrace" },
|
{ "syndicates", "- Phasetide\n- Sungrace" },
|
||||||
@@ -1011,7 +1011,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Silence - Singularity",
|
Title = "Silence - Singularity",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "I like going [[Deplete]]. Singularity has good removal and [[Timestop]]. \r\n\r\nIf your deplete plan still fails, you have [[Zorp, Unrecyclable]] to continue the attacking plan forever.",
|
Content = "I like going [[Deplete]]. Singularity has good removal and [[Timestop]].\r\n\r\nIf your deplete plan still fails, you have [[Zorp, Unrecyclable]] to continue the attacking plan forever.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Silence\n- Singularity" },
|
{ "syndicates", "- Silence\n- Singularity" },
|
||||||
@@ -1026,7 +1026,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Silence - Splintergleam",
|
Title = "Silence - Splintergleam",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "The [[Precon Telekinetic Burn]] deck. And I like to go that route. So many activate triggers, with [[Telepathic Conduit]], [[Bloodline Tracker]] and [[Ylka, the Headliner]] all in play, you can just blow up your opponent.",
|
Content = "The [[Precon Telekinetic Burn]] deck. And I like to go that route. So many activate triggers,\r\nwith [[Telepathic Conduit]], [[Bloodline Tracker]] and [[Ylka, the Headliner]] all in play, you can just blow up your\r\nopponent.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Silence\n- Splintergleam" },
|
{ "syndicates", "- Silence\n- Splintergleam" },
|
||||||
@@ -1041,7 +1041,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Silence - Sungrace",
|
Title = "Silence - Sungrace",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "The typical control pairing.\r\n\r\nYou can put down one threat at a time, like [[Limit Breaker]], [[Canine Adjutant]], [[Debris Collector]] and [[Jury of the Second Law]].\r\n\r\nAll your [[Silence]] spells will kill their threats, plus you can [[Overflow]] for days.\r\n\r\n[[Redactionist]] is great graveyard hate. You also have [[Suncursed Conduit]] to shut down [[Fractal Phantasm]]s, so you can uber kill the things you kill.\r\n\r\nIf you encounter a [[Devourer Spawn]] or [[Roiling Amalgam]] you can always [[Throw into the Sun]].\r\n\r\n[[APEX Starcruise]] is another top board wipe that also has a big body to start doing damage.",
|
Content = "The typical control pairing.\r\n\r\nYou can put down one threat at a time, like [[Limit Breaker]], [[Canine Adjutant]], [[Debris Collector]]\r\nand [[Jury of the Second Law]].\r\n\r\nAll your [[Silence]] spells will kill their threats, plus you can [[Overflow]] for days.\r\n\r\n[[Redactionist]] is great graveyard hate. You also have [[Suncursed Conduit]] to shut down [[Fractal Phantasm]]s, so you\r\ncan uber kill the things you kill.\r\n\r\nIf you encounter a [[Devourer Spawn]] or [[Roiling Amalgam]] you can always [[Throw into the Sun]].\r\n\r\n[[APEX Starcruise]] is another top board wipe that also has a big body to start doing damage.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Silence\n- Sungrace" },
|
{ "syndicates", "- Silence\n- Sungrace" },
|
||||||
@@ -1056,7 +1056,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Singularity - Splintergleam",
|
Title = "Singularity - Splintergleam",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "I've seen a person go the [[Singularity]] + [[Splintergleam]] pairing just to have [[Timestop]] to protect their big [[Bleed]] troops that been heavily buffed. Using [[Nascent Clone]] to duplicate [[Fervor]] casts was also a pretty clever idea.",
|
Content = "I've seen a person go the [[Singularity]] + [[Splintergleam]] pairing just to have [[Timestop]] to protect their\r\nbig [[Bleed]] troops that been heavily buffed. Using [[Nascent Clone]] to duplicate [[Fervor]] casts was also a pretty\r\nclever idea.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Singularity\n- Splintergleam" },
|
{ "syndicates", "- Singularity\n- Splintergleam" },
|
||||||
@@ -1071,7 +1071,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Singularity - Sungrace",
|
Title = "Singularity - Sungrace",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "This pairing has the funny access to discard revive, so you can cheat out something like [[Kyln, the Dynasty]] or the classic [[Devourer Spawn]] early with [[Entropy's End]].",
|
Content = "This pairing has the funny access to discard revive, so you can cheat out something like [[Kyln, the Dynasty]] or the\r\nclassic [[Devourer Spawn]] early with [[Entropy's End]].",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Singularity\n- Sungrace" },
|
{ "syndicates", "- Singularity\n- Sungrace" },
|
||||||
@@ -1086,7 +1086,7 @@ public static class DocDatabase
|
|||||||
{
|
{
|
||||||
Title = "Splintergleam - Sungrace",
|
Title = "Splintergleam - Sungrace",
|
||||||
Category = "Syndicate Pairings",
|
Category = "Syndicate Pairings",
|
||||||
Content = "I saw someone using [[Lightsteel Engineer]] with the entire [[Volcanic Rivers]] package, and I just love it.\r\n\r\nTechnically, [[Gentle Frank]] also reduces core damage, but I feel like your going to die before 8 mana.\r\n\r\n[[Clarion, Deepest Breath]] turns your [[Volcanic Rivers]] shifts into life gain, but then you need to run the [[Overflow]] package.",
|
Content = "I saw someone using [[Lightsteel Engineer]] with the entire [[Volcanic Rivers]] package, and I just love it.\r\n\r\nTechnically, [[Gentle Frank]] also reduces core damage, but I feel like your going to die before 8 mana.\r\n\r\n[[Clarion, Deepest Breath]] turns your [[Volcanic Rivers]] shifts into life gain, but then you need to run\r\nthe [[Overflow]] package.",
|
||||||
Frontmatter = new()
|
Frontmatter = new()
|
||||||
{
|
{
|
||||||
{ "syndicates", "- Splintergleam\n- Sungrace" },
|
{ "syndicates", "- Splintergleam\n- Sungrace" },
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
@namespace Shared.Pages
|
@namespace Shared.Pages
|
||||||
@page "/agents"
|
@page "/agents"
|
||||||
@rendermode @(new InteractiveServerRenderMode(prerender: false))
|
|
||||||
@using Shared.Components
|
|
||||||
|
|
||||||
<PageTitle>Chrono CCG - Agents</PageTitle>
|
<PageTitle>Chrono CCG - Agents</PageTitle>
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,11 @@
|
|||||||
|
|
||||||
@code {
|
@code {
|
||||||
private string _countdownString = "00:00:00";
|
private string _countdownString = "00:00:00";
|
||||||
private System.Threading.Timer? _timer;
|
private Timer? _timer;
|
||||||
|
|
||||||
protected override void OnInitialized()
|
protected override void OnInitialized()
|
||||||
{
|
{
|
||||||
_timer = new System.Threading.Timer(_ =>
|
_timer = new Timer(_ =>
|
||||||
{
|
{
|
||||||
UpdateCountdown();
|
UpdateCountdown();
|
||||||
InvokeAsync(StateHasChanged);
|
InvokeAsync(StateHasChanged);
|
||||||
@@ -60,4 +60,5 @@
|
|||||||
{
|
{
|
||||||
_timer?.Dispose();
|
_timer?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
|
||||||
using Model;
|
using Model;
|
||||||
|
|
||||||
namespace Shared.Services;
|
namespace Shared.Services;
|
||||||
@@ -27,5 +26,8 @@ public class CardPreviewService
|
|||||||
NotifyStateChanged();
|
NotifyStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NotifyStateChanged() => OnChange?.Invoke();
|
private void NotifyStateChanged()
|
||||||
}
|
{
|
||||||
|
OnChange?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -257,7 +257,8 @@
|
|||||||
tableLines.Add(trimmedLine);
|
tableLines.Add(trimmedLine);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inTable)
|
|
||||||
|
if (inTable)
|
||||||
{
|
{
|
||||||
RenderTable(builder, ref seq, tableLines);
|
RenderTable(builder, ref seq, tableLines);
|
||||||
tableLines.Clear();
|
tableLines.Clear();
|
||||||
@@ -272,13 +273,15 @@
|
|||||||
builder.OpenElement(seq++, "ul");
|
builder.OpenElement(seq++, "ul");
|
||||||
inList = true;
|
inList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isCardListItem = trimmedLine.Contains("[[") && trimmedLine.Contains("]]");
|
var isCardListItem = trimmedLine.Contains("[[") && trimmedLine.Contains("]]");
|
||||||
builder.OpenElement(seq++, "li");
|
builder.OpenElement(seq++, "li");
|
||||||
RenderInlines(builder, ref seq, trimmedLine[2..], true);
|
RenderInlines(builder, ref seq, trimmedLine[2..], true);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inList)
|
|
||||||
|
if (inList)
|
||||||
{
|
{
|
||||||
builder.CloseElement(); // Close ul
|
builder.CloseElement(); // Close ul
|
||||||
inList = false;
|
inList = false;
|
||||||
@@ -339,6 +342,7 @@
|
|||||||
RenderInlines(builder, ref seq, cell.Trim(), false);
|
RenderInlines(builder, ref seq, cell.Trim(), false);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
startIdx = 2;
|
startIdx = 2;
|
||||||
@@ -356,8 +360,10 @@
|
|||||||
RenderInlines(builder, ref seq, cell.Trim(), false);
|
RenderInlines(builder, ref seq, cell.Trim(), false);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
@@ -366,7 +372,7 @@
|
|||||||
private void RenderInlines(RenderTreeBuilder builder, ref int seq, string text, bool renderAsImage)
|
private void RenderInlines(RenderTreeBuilder builder, ref int seq, string text, bool renderAsImage)
|
||||||
{
|
{
|
||||||
var remaining = text;
|
var remaining = text;
|
||||||
|
|
||||||
while (!string.IsNullOrEmpty(remaining))
|
while (!string.IsNullOrEmpty(remaining))
|
||||||
{
|
{
|
||||||
var boldMatch = Regex.Match(remaining, @"\*\*(.*?)\*\*");
|
var boldMatch = Regex.Match(remaining, @"\*\*(.*?)\*\*");
|
||||||
@@ -375,11 +381,28 @@
|
|||||||
|
|
||||||
var bestIdx = int.MaxValue;
|
var bestIdx = int.MaxValue;
|
||||||
Match? bestMatch = null;
|
Match? bestMatch = null;
|
||||||
int matchType = 0; // 1: bold, 2: italic, 3: card
|
var matchType = 0; // 1: bold, 2: italic, 3: card
|
||||||
|
|
||||||
if (boldMatch.Success && boldMatch.Index < bestIdx) { bestIdx = boldMatch.Index; bestMatch = boldMatch; matchType = 1; }
|
if (boldMatch.Success && boldMatch.Index < bestIdx)
|
||||||
if (italicMatch.Success && italicMatch.Index < bestIdx) { bestIdx = italicMatch.Index; bestMatch = italicMatch; matchType = 2; }
|
{
|
||||||
if (cardMatch.Success && cardMatch.Index < bestIdx) { bestIdx = cardMatch.Index; bestMatch = cardMatch; matchType = 3; }
|
bestIdx = boldMatch.Index;
|
||||||
|
bestMatch = boldMatch;
|
||||||
|
matchType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (italicMatch.Success && italicMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = italicMatch.Index;
|
||||||
|
bestMatch = italicMatch;
|
||||||
|
matchType = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardMatch.Success && cardMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = cardMatch.Index;
|
||||||
|
bestMatch = cardMatch;
|
||||||
|
matchType = 3;
|
||||||
|
}
|
||||||
|
|
||||||
if (bestMatch != null)
|
if (bestMatch != null)
|
||||||
{
|
{
|
||||||
@@ -387,7 +410,7 @@
|
|||||||
builder.AddContent(seq++, remaining[..bestIdx]);
|
builder.AddContent(seq++, remaining[..bestIdx]);
|
||||||
|
|
||||||
var innerText = bestMatch.Groups[1].Value;
|
var innerText = bestMatch.Groups[1].Value;
|
||||||
|
|
||||||
if (matchType == 1) // Bold
|
if (matchType == 1) // Bold
|
||||||
{
|
{
|
||||||
builder.OpenElement(seq++, "strong");
|
builder.OpenElement(seq++, "strong");
|
||||||
|
|||||||
@@ -224,9 +224,17 @@
|
|||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.markdown-content h2 { font-size: 1.3rem; }
|
.markdown-content h2 {
|
||||||
.markdown-content h3 { font-size: 1.2rem; }
|
font-size: 1.3rem;
|
||||||
.markdown-content h4 { font-size: 1rem; }
|
}
|
||||||
|
|
||||||
|
.markdown-content h3 {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.markdown-content h4 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
.table-responsive {
|
.table-responsive {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
@using Model
|
|
||||||
@using System.Text.RegularExpressions
|
@using System.Text.RegularExpressions
|
||||||
@using Microsoft.AspNetCore.Components.Rendering
|
@using Microsoft.AspNetCore.Components.Rendering
|
||||||
@namespace Chrono.Components
|
@namespace Chrono.Components
|
||||||
@@ -35,8 +34,15 @@
|
|||||||
[Parameter] public DocData? Doc { get; set; }
|
[Parameter] public DocData? Doc { get; set; }
|
||||||
[Parameter] public EventCallback OnClose { get; set; }
|
[Parameter] public EventCallback OnClose { get; set; }
|
||||||
|
|
||||||
private void HandleClose() => _ = OnClose.InvokeAsync();
|
private void HandleClose()
|
||||||
private void HandleBackdropClick() => _ = OnClose.InvokeAsync();
|
{
|
||||||
|
_ = OnClose.InvokeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleBackdropClick()
|
||||||
|
{
|
||||||
|
_ = OnClose.InvokeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
private RenderFragment RenderDescription(string content)
|
private RenderFragment RenderDescription(string content)
|
||||||
{
|
{
|
||||||
@@ -61,12 +67,14 @@
|
|||||||
builder.OpenElement(seq++, "ul");
|
builder.OpenElement(seq++, "ul");
|
||||||
inList = true;
|
inList = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.OpenElement(seq++, "li");
|
builder.OpenElement(seq++, "li");
|
||||||
RenderInlines(builder, ref seq, trimmedLine[2..]);
|
RenderInlines(builder, ref seq, trimmedLine[2..]);
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (inList)
|
|
||||||
|
if (inList)
|
||||||
{
|
{
|
||||||
builder.CloseElement();
|
builder.CloseElement();
|
||||||
inList = false;
|
inList = false;
|
||||||
@@ -94,10 +102,21 @@
|
|||||||
|
|
||||||
var bestIdx = int.MaxValue;
|
var bestIdx = int.MaxValue;
|
||||||
Match? bestMatch = null;
|
Match? bestMatch = null;
|
||||||
int matchType = 0; // 1: bold, 2: italic
|
var matchType = 0; // 1: bold, 2: italic
|
||||||
|
|
||||||
if (boldMatch.Success && boldMatch.Index < bestIdx) { bestIdx = boldMatch.Index; bestMatch = boldMatch; matchType = 1; }
|
if (boldMatch.Success && boldMatch.Index < bestIdx)
|
||||||
if (italicMatch.Success && italicMatch.Index < bestIdx) { bestIdx = italicMatch.Index; bestMatch = italicMatch; matchType = 2; }
|
{
|
||||||
|
bestIdx = boldMatch.Index;
|
||||||
|
bestMatch = boldMatch;
|
||||||
|
matchType = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (italicMatch.Success && italicMatch.Index < bestIdx)
|
||||||
|
{
|
||||||
|
bestIdx = italicMatch.Index;
|
||||||
|
bestMatch = italicMatch;
|
||||||
|
matchType = 2;
|
||||||
|
}
|
||||||
|
|
||||||
if (bestMatch != null)
|
if (bestMatch != null)
|
||||||
{
|
{
|
||||||
@@ -115,4 +134,5 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-7
@@ -1,8 +1,5 @@
|
|||||||
@page "/syndicates"
|
@page "/syndicates"
|
||||||
@rendermode @(new InteractiveServerRenderMode(prerender: false))
|
@using Chrono.Components
|
||||||
@using Model
|
|
||||||
@using Shared.Components
|
|
||||||
@inject NavigationManager Navigation
|
|
||||||
|
|
||||||
<HeadContent>
|
<HeadContent>
|
||||||
<meta name="description" content="Explore each syndicate in Chrono CCG."/>
|
<meta name="description" content="Explore each syndicate in Chrono CCG."/>
|
||||||
@@ -33,9 +30,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SyndicateDialog Doc="selectedDoc" OnClose="CloseSyndicate" OnNavigate="HandleNavigate" />
|
<SyndicateDialog Doc="selectedDoc" OnClose="CloseSyndicate" OnNavigate="HandleNavigate"/>
|
||||||
<CardDialog Card="selectedCard" OnClose="CloseCard" OnNavigate="HandleNavigate" />
|
<CardDialog Card="selectedCard" OnClose="CloseCard" OnNavigate="HandleNavigate"/>
|
||||||
<GenericDocDialog Doc="selectedGenericDoc" OnClose="CloseGenericDoc" />
|
<GenericDocDialog Doc="selectedGenericDoc" OnClose="CloseGenericDoc"/>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<DocData> syndicates = [];
|
private List<DocData> syndicates = [];
|
||||||
@@ -84,6 +81,7 @@
|
|||||||
{
|
{
|
||||||
selectedGenericDoc = new DocData { Title = card.Name, Content = card.Description ?? "", Category = card.Category };
|
selectedGenericDoc = new DocData { Title = card.Name, Content = card.Description ?? "", Category = card.Category };
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -95,4 +93,5 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+24
-7
@@ -81,18 +81,35 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Syndicate Colors */
|
/* Syndicate Colors */
|
||||||
.singularity { color: #ffffff; }
|
.singularity {
|
||||||
.phasetide { color: #2196f3; }
|
color: #ffffff;
|
||||||
.silence { color: #9c27b0; }
|
}
|
||||||
.lifeblood { color: #4caf50; }
|
|
||||||
.sungrace { color: #ff9800; }
|
.phasetide {
|
||||||
.splintergleam { color: #f44336; }
|
color: #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.silence {
|
||||||
|
color: #9c27b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lifeblood {
|
||||||
|
color: #4caf50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sungrace {
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splintergleam {
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.pairings-grid {
|
.pairings-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.syndicates-container {
|
.syndicates-container {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
<div class="card-shimmer"></div>
|
<div class="card-shimmer"></div>
|
||||||
<img src="@card.ImagePath" alt="@card.Name" loading="lazy"
|
<img src="@card.ImagePath" alt="@card.Name" loading="lazy"
|
||||||
onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22200%22 height=%22280%22><rect fill=%22%23222244%22 width=%22200%22 height=%22280%22/><text fill=%22%23686888%22 font-size=%2214%22 x=%22100%22 y=%22140%22 text-anchor=%22middle%22 dominant-baseline=%22middle%22>No Image</text></svg>'"/>
|
onerror="this.src='data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 width=%22200%22 height=%22280%22><rect fill=%22%23222244%22 width=%22200%22 height=%22280%22/><text fill=%22%23686888%22 font-size=%2214%22 x=%22100%22 y=%22140%22 text-anchor=%22middle%22 dominant-baseline=%22middle%22>No Image</text></svg>'"/>
|
||||||
|
|
||||||
@if (card.Cost.HasValue)
|
@if (card.Cost.HasValue)
|
||||||
{
|
{
|
||||||
<div class="card-cost-badge" title="Cost">@card.Cost</div>
|
<div class="card-cost-badge" title="Cost">@card.Cost</div>
|
||||||
@@ -156,7 +156,8 @@
|
|||||||
|
|
||||||
@if (card.IsImmortalized)
|
@if (card.IsImmortalized)
|
||||||
{
|
{
|
||||||
<div class="card-immortalize-badge" title="@(card.IsImmortalized ? "Immortalized" : "Immortalizes")">
|
<div class="card-immortalize-badge"
|
||||||
|
title="@(card.IsImmortalized ? "Immortalized" : "Immortalizes")">
|
||||||
<i class="bi bi-star-fill"></i>
|
<i class="bi bi-star-fill"></i>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
@@ -169,7 +170,7 @@
|
|||||||
{
|
{
|
||||||
<div class="card-description">@card.Description</div>
|
<div class="card-description">@card.Description</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@if (card.IsImmortalized && !string.IsNullOrEmpty(card.ImmortalizeFrom))
|
@if (card.IsImmortalized && !string.IsNullOrEmpty(card.ImmortalizeFrom))
|
||||||
{
|
{
|
||||||
<div class="card-immortalize-info">
|
<div class="card-immortalize-info">
|
||||||
@@ -246,7 +247,7 @@
|
|||||||
private string categoryFilter = "";
|
private string categoryFilter = "";
|
||||||
private string immortalFilter = "";
|
private string immortalFilter = "";
|
||||||
private bool agentLink = true;
|
private bool agentLink = true;
|
||||||
private HashSet<string> syndicateFilter = [];
|
private readonly HashSet<string> syndicateFilter = [];
|
||||||
private string costFilter = "";
|
private string costFilter = "";
|
||||||
private string sortBy = "Cost";
|
private string sortBy = "Cost";
|
||||||
private bool sortDescending;
|
private bool sortDescending;
|
||||||
|
|||||||
@@ -221,16 +221,39 @@
|
|||||||
background: var(--bg-elevated);
|
background: var(--bg-elevated);
|
||||||
border-color: var(--border);
|
border-color: var(--border);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Syndicate Colors */
|
/* Syndicate Colors */
|
||||||
.syndicate-btn.active.singularity { border-color: #ffffff; color: #ffffff; }
|
.syndicate-btn.active.singularity {
|
||||||
.syndicate-btn.active.phasetide { border-color: #2196f3; color: #2196f3; }
|
border-color: #ffffff;
|
||||||
.syndicate-btn.active.silence { border-color: #9c27b0; color: #9c27b0; }
|
color: #ffffff;
|
||||||
.syndicate-btn.active.lifeblood { border-color: #4caf50; color: #4caf50; }
|
}
|
||||||
.syndicate-btn.active.sungrace { border-color: #ff9800; color: #ff9800; }
|
|
||||||
.syndicate-btn.active.splintergleam { border-color: #f44336; color: #f44336; }
|
.syndicate-btn.active.phasetide {
|
||||||
|
border-color: #2196f3;
|
||||||
|
color: #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.syndicate-btn.active.silence {
|
||||||
|
border-color: #9c27b0;
|
||||||
|
color: #9c27b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.syndicate-btn.active.lifeblood {
|
||||||
|
border-color: #4caf50;
|
||||||
|
color: #4caf50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.syndicate-btn.active.sungrace {
|
||||||
|
border-color: #ff9800;
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.syndicate-btn.active.splintergleam {
|
||||||
|
border-color: #f44336;
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
.syn-icon {
|
.syn-icon {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
@@ -522,7 +545,7 @@
|
|||||||
font-size: 0.85rem;
|
font-size: 0.85rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-shadow: 0 1px 3px rgba(0,0,0,0.8);
|
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
@@ -544,7 +567,7 @@
|
|||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: 2.5rem 0.5rem 0.5rem;
|
padding: 2.5rem 0.5rem 0.5rem;
|
||||||
background: linear-gradient(to top, rgba(0,0,0,1) 0%, rgba(0,0,0,0.7) 60%, transparent 100%);
|
background: linear-gradient(to top, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0.7) 60%, transparent 100%);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 0.25rem;
|
gap: 0.25rem;
|
||||||
@@ -560,7 +583,7 @@
|
|||||||
-webkit-line-clamp: 3;
|
-webkit-line-clamp: 3;
|
||||||
-webkit-box-orient: vertical;
|
-webkit-box-orient: vertical;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-shadow: 0 1px 2px rgba(0,0,0,0.8);
|
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8);
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-immortalize-info {
|
.card-immortalize-info {
|
||||||
@@ -589,7 +612,7 @@
|
|||||||
gap: 0.25rem;
|
gap: 0.25rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
text-shadow: 0 1px 3px rgba(0,0,0,0.9);
|
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.card-stats-row .stat.attack {
|
.card-stats-row .stat.attack {
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
@page "/syndicate-pairings"
|
@page "/syndicate-pairings"
|
||||||
@using Model
|
|
||||||
@using Chrono.Components
|
@using Chrono.Components
|
||||||
@inject NavigationManager Navigation
|
|
||||||
|
|
||||||
<HeadContent>
|
<HeadContent>
|
||||||
<meta name="description" content="Explore all syndicate pairings in Chrono CCG."/>
|
<meta name="description" content="Explore all syndicate pairings in Chrono CCG."/>
|
||||||
@@ -40,9 +38,9 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<SyndicatePairDialog Doc="selectedDoc" OnClose="ClosePairing" OnNavigate="HandleNavigate" />
|
<SyndicatePairDialog Doc="selectedDoc" OnClose="ClosePairing" OnNavigate="HandleNavigate"/>
|
||||||
<CardDialog Card="selectedCard" OnClose="CloseCard" OnNavigate="HandleNavigate" />
|
<CardDialog Card="selectedCard" OnClose="CloseCard" OnNavigate="HandleNavigate"/>
|
||||||
<GenericDocDialog Doc="selectedGenericDoc" OnClose="CloseGenericDoc" />
|
<GenericDocDialog Doc="selectedGenericDoc" OnClose="CloseGenericDoc"/>
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private List<DocData> pairings = [];
|
private List<DocData> pairings = [];
|
||||||
@@ -91,6 +89,7 @@
|
|||||||
{
|
{
|
||||||
selectedGenericDoc = new DocData { Title = card.Name, Content = card.Description ?? "", Category = card.Category };
|
selectedGenericDoc = new DocData { Title = card.Name, Content = card.Description ?? "", Category = card.Category };
|
||||||
}
|
}
|
||||||
|
|
||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -102,4 +101,5 @@
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,123 +95,150 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Syndicate Colors */
|
/* Syndicate Colors */
|
||||||
.singularity { color: #ffffff; }
|
.singularity {
|
||||||
.phasetide { color: #2196f3; }
|
color: #ffffff;
|
||||||
.silence { color: #9c27b0; }
|
}
|
||||||
.lifeblood { color: #4caf50; }
|
|
||||||
.sungrace { color: #ff9800; }
|
.phasetide {
|
||||||
.splintergleam { color: #f44336; }
|
color: #2196f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.silence {
|
||||||
|
color: #9c27b0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.lifeblood {
|
||||||
|
color: #4caf50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sungrace {
|
||||||
|
color: #ff9800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.splintergleam {
|
||||||
|
color: #f44336;
|
||||||
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
.pairings-grid {
|
.pairings-grid {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
|
|
||||||
.syndicates-container {
|
.syndicates-container {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── Dialog ── */
|
/* ── Dialog ── */
|
||||||
.pairing-dialog {
|
.pairing-dialog {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
width: 92vw;
|
width: 92vw;
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
max-height: 85vh;
|
max-height: 85vh;
|
||||||
background: #1a1a1a; /* Explicit dark background */
|
background: #1a1a1a; /* Explicit dark background */
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-lg);
|
border-radius: var(--radius-lg);
|
||||||
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
|
||||||
z-index: 1050;
|
z-index: 1050;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
animation: dialog-enter 0.25s ease-out;
|
animation: dialog-enter 0.25s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes dialog-enter {
|
@keyframes dialog-enter {
|
||||||
from { opacity: 0; transform: translate(-50%, -50%) scale(0.92); }
|
from {
|
||||||
to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
|
opacity: 0;
|
||||||
|
transform: translate(-50%, -50%) scale(0.92);
|
||||||
}
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, -50%) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.dialog-close {
|
.dialog-close {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.75rem;
|
top: 0.75rem;
|
||||||
right: 0.75rem;
|
right: 0.75rem;
|
||||||
background: rgba(0, 0, 0, 0.5);
|
background: rgba(0, 0, 0, 0.5);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
transition: all var(--transition);
|
transition: all var(--transition);
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-close:hover {
|
.dialog-close:hover {
|
||||||
background: rgba(255, 255, 255, 0.15);
|
background: rgba(255, 255, 255, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-header {
|
.dialog-header {
|
||||||
padding: 2.5rem 1.5rem 1.5rem;
|
padding: 2.5rem 1.5rem 1.5rem;
|
||||||
background: #252525; /* Explicit slightly lighter dark */
|
background: #252525; /* Explicit slightly lighter dark */
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-header h2 {
|
.dialog-header h2 {
|
||||||
margin: 1.25rem 0 0;
|
margin: 1.25rem 0 0;
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: #ffffff; /* Explicit white */
|
color: #ffffff; /* Explicit white */
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-body {
|
.dialog-body {
|
||||||
padding: 1.5rem;
|
padding: 1.5rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background: #1a1a1a; /* Explicit dark */
|
background: #1a1a1a; /* Explicit dark */
|
||||||
}
|
}
|
||||||
|
|
||||||
.doc-content {
|
.doc-content {
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
color: #e0e0e0; /* Explicit light gray */
|
color: #e0e0e0; /* Explicit light gray */
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.inline-card-ref {
|
.inline-card-ref {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.doc-content p {
|
.doc-content p {
|
||||||
margin-bottom: 1.25rem;
|
margin-bottom: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 3rem 1rem;
|
padding: 3rem 1rem;
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-backdrop {
|
.modal-backdrop {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
background: rgba(0, 0, 0, 0.45);
|
background: rgba(0, 0, 0, 0.45);
|
||||||
backdrop-filter: blur(2px);
|
backdrop-filter: blur(2px);
|
||||||
z-index: 1040;
|
z-index: 1040;
|
||||||
animation: fade-in 0.2s ease-out;
|
animation: fade-in 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes fade-in {
|
@keyframes fade-in {
|
||||||
from { opacity: 0; }
|
from {
|
||||||
to { opacity: 1; }
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public abstract class AuthenticatedPageTest : PageTest
|
|||||||
public async Task SignIn()
|
public async Task SignIn()
|
||||||
{
|
{
|
||||||
// Use a browser with a UI as requested
|
// Use a browser with a UI as requested
|
||||||
await Context.Tracing.StartAsync(new()
|
await Context.Tracing.StartAsync(new TracingStartOptions
|
||||||
{
|
{
|
||||||
Title = TestContext.CurrentContext.Test.ClassName + "." + TestContext.CurrentContext.Test.Name,
|
Title = TestContext.CurrentContext.Test.ClassName + "." + TestContext.CurrentContext.Test.Name,
|
||||||
Screenshots = true,
|
Screenshots = true,
|
||||||
@@ -36,9 +36,10 @@ public abstract class AuthenticatedPageTest : PageTest
|
|||||||
[TearDown]
|
[TearDown]
|
||||||
public async Task TearDown()
|
public async Task TearDown()
|
||||||
{
|
{
|
||||||
await Context.Tracing.StopAsync(new()
|
await Context.Tracing.StopAsync(new TracingStopOptions
|
||||||
{
|
{
|
||||||
Path = Path.Combine(TestContext.CurrentContext.WorkDirectory, "playwright-traces", $"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}.zip")
|
Path = Path.Combine(TestContext.CurrentContext.WorkDirectory, "playwright-traces",
|
||||||
|
$"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}.zip")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,18 +20,23 @@ public class AgentsPage : BasePage
|
|||||||
public async Task WaitForInteractiveAsync()
|
public async Task WaitForInteractiveAsync()
|
||||||
{
|
{
|
||||||
await Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
await Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
// Wait for the grid container with a much longer timeout for Telerik initialization
|
// Wait for the grid container with a much longer timeout for Telerik initialization
|
||||||
await Page.WaitForSelectorAsync(".agents-page", new PageWaitForSelectorOptions { Timeout = 30_000, State = WaitForSelectorState.Visible });
|
await Page.WaitForSelectorAsync(".agents-page",
|
||||||
|
new PageWaitForSelectorOptions { Timeout = 30_000, State = WaitForSelectorState.Visible });
|
||||||
// Wait for the actual Telerik Grid to be rendered and populated
|
// Wait for the actual Telerik Grid to be rendered and populated
|
||||||
await Page.WaitForSelectorAsync(".k-grid", new PageWaitForSelectorOptions { Timeout = 30_000, State = WaitForSelectorState.Visible });
|
await Page.WaitForSelectorAsync(".k-grid",
|
||||||
} catch (System.Exception ex) {
|
new PageWaitForSelectorOptions { Timeout = 30_000, State = WaitForSelectorState.Visible });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
var content = await Page.ContentAsync();
|
var content = await Page.ContentAsync();
|
||||||
var title = await Page.TitleAsync();
|
var title = await Page.TitleAsync();
|
||||||
var url = Page.Url;
|
var url = Page.Url;
|
||||||
System.Console.WriteLine($"[DEBUG_LOG] FAILED to find Agents Grid. Error: {ex.Message}");
|
Console.WriteLine($"[DEBUG_LOG] FAILED to find Agents Grid. Error: {ex.Message}");
|
||||||
System.Console.WriteLine($"[DEBUG_LOG] URL: {url}, Title: {title}");
|
Console.WriteLine($"[DEBUG_LOG] URL: {url}, Title: {title}");
|
||||||
System.Console.WriteLine("[DEBUG_LOG] Page Content length: " + content.Length);
|
Console.WriteLine("[DEBUG_LOG] Page Content length: " + content.Length);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,14 +8,14 @@ public class DecksPage : BasePage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ILocator DeckCards => Page.Locator(".deck-card");
|
||||||
|
public ILocator CreateDeckButton => Page.Locator(".btn-create-deck");
|
||||||
|
|
||||||
public async Task GotoAsync()
|
public async Task GotoAsync()
|
||||||
{
|
{
|
||||||
await NavigateToAsync("/decks");
|
await NavigateToAsync("/decks");
|
||||||
}
|
}
|
||||||
|
|
||||||
public ILocator DeckCards => Page.Locator(".deck-card");
|
|
||||||
public ILocator CreateDeckButton => Page.Locator(".btn-create-deck");
|
|
||||||
|
|
||||||
public async Task WaitForInteractiveAsync()
|
public async Task WaitForInteractiveAsync()
|
||||||
{
|
{
|
||||||
await Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
await Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
||||||
|
|||||||
@@ -21,14 +21,18 @@ public class SyndicatesPage : BasePage
|
|||||||
public async Task WaitForInteractiveAsync()
|
public async Task WaitForInteractiveAsync()
|
||||||
{
|
{
|
||||||
await Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
await Page.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
await Page.WaitForSelectorAsync(".pairing-card", new PageWaitForSelectorOptions { Timeout = 15_000 });
|
await Page.WaitForSelectorAsync(".pairing-card", new PageWaitForSelectorOptions { Timeout = 15_000 });
|
||||||
} catch (System.Exception) {
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
var content = await Page.ContentAsync();
|
var content = await Page.ContentAsync();
|
||||||
var title = await Page.TitleAsync();
|
var title = await Page.TitleAsync();
|
||||||
var url = Page.Url;
|
var url = Page.Url;
|
||||||
System.Console.WriteLine($"[DEBUG_LOG] FAILED to find .pairing-card. URL: {url}, Title: {title}");
|
Console.WriteLine($"[DEBUG_LOG] FAILED to find .pairing-card. URL: {url}, Title: {title}");
|
||||||
System.Console.WriteLine("[DEBUG_LOG] Page Content snippet: " + (content.Length > 2000 ? content.Substring(0, 2000) : content));
|
Console.WriteLine("[DEBUG_LOG] Page Content snippet: " +
|
||||||
|
(content.Length > 2000 ? content.Substring(0, 2000) : content));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -41,6 +45,7 @@ public class SyndicatesPage : BasePage
|
|||||||
public async Task CloseDialogAsync()
|
public async Task CloseDialogAsync()
|
||||||
{
|
{
|
||||||
await DialogCloseButton.ClickAsync();
|
await DialogCloseButton.ClickAsync();
|
||||||
await Page.WaitForSelectorAsync(".card-detail", new PageWaitForSelectorOptions { State = WaitForSelectorState.Hidden });
|
await Page.WaitForSelectorAsync(".card-detail",
|
||||||
|
new PageWaitForSelectorOptions { State = WaitForSelectorState.Hidden });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.Playwright;
|
using Microsoft.Playwright;
|
||||||
using Microsoft.Playwright.NUnit;
|
|
||||||
using Tests.PageObjects;
|
using Tests.PageObjects;
|
||||||
|
|
||||||
namespace Tests;
|
namespace Tests;
|
||||||
@@ -9,14 +7,14 @@ namespace Tests;
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class SyndicateTests : AuthenticatedPageTest
|
public class SyndicateTests : AuthenticatedPageTest
|
||||||
{
|
{
|
||||||
private SyndicatesPage _syndicatesPage;
|
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
_syndicatesPage = new SyndicatesPage(Page);
|
_syndicatesPage = new SyndicatesPage(Page);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SyndicatesPage _syndicatesPage;
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task SyndicatesPage_ShouldOpenDialogOnPairingClick()
|
public async Task SyndicatesPage_ShouldOpenDialogOnPairingClick()
|
||||||
{
|
{
|
||||||
@@ -62,4 +60,4 @@ public class SyndicateTests : AuthenticatedPageTest
|
|||||||
await _syndicatesPage.CloseDialogAsync();
|
await _syndicatesPage.CloseDialogAsync();
|
||||||
await Expect(_syndicatesPage.SyndicateDialog).ToBeHiddenAsync();
|
await Expect(_syndicatesPage.SyndicateDialog).ToBeHiddenAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
category: Debuff
|
category: Debuff
|
||||||
---
|
---
|
||||||
|
|
||||||
Agent cannot activate or attack. If it's already attacking, it will continue to strike it's target.
|
Agent cannot activate or attack. If it's already attacking, it will continue to strike it's target.
|
||||||
@@ -6,6 +6,8 @@ category: Syndicate Pairings
|
|||||||
overlappingMechanics:
|
overlappingMechanics:
|
||||||
- "[[Shift]]"
|
- "[[Shift]]"
|
||||||
---
|
---
|
||||||
Pairing has cards that care about [[Shift]] like [[Heretic Whistleblower]] and [[Convergent Pack]] so you could go that route.
|
|
||||||
|
Pairing has cards that care about [[Shift]] like [[Heretic Whistleblower]] and [[Convergent Pack]] so you could go that
|
||||||
|
route.
|
||||||
|
|
||||||
Both pairings also have access to [[Flourish]], so you could go a board route and use [[Tidal Wave]] as a finisher.
|
Both pairings also have access to [[Flourish]], so you could go a board route and use [[Tidal Wave]] as a finisher.
|
||||||
@@ -4,7 +4,9 @@ syndicates:
|
|||||||
- Silence
|
- Silence
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
|
|
||||||
Typically the [[Somnus, the Dreaming]] pairing. Access to strong cards like [[Sap Sapper]] and [[Sleepy Druid]].
|
Typically the [[Somnus, the Dreaming]] pairing. Access to strong cards like [[Sap Sapper]] and [[Sleepy Druid]].
|
||||||
|
|
||||||
Suppose you could also go [[Evasive]] with removal to protect your creatures from [[Confront]], and have [[Spirit's Lament]] as a top end.
|
Suppose you could also go [[Evasive]] with removal to protect your creatures from [[Confront]], and
|
||||||
|
have [[Spirit's Lament]] as a top end.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ syndicates:
|
|||||||
- Singularity
|
- Singularity
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
For this pairing, I typically go [[Sprout]].
|
|
||||||
|
|
||||||
[[P.O.G.O]] is another easy one drop to make all your tokens more lethal, and you have a lot of cheap removal like [[Rapid Iteration]] and [[Wake-Up Prod]] to remove blockers that can otherwise slow down your game plan.
|
For this pairing, I typically go [[Sprout]].
|
||||||
|
|
||||||
|
[[P.O.G.O]] is another easy one drop to make all your tokens more lethal, and you have a lot of cheap removal
|
||||||
|
like [[Rapid Iteration]] and [[Wake-Up Prod]] to remove blockers that can otherwise slow down your game plan.
|
||||||
@@ -6,5 +6,6 @@ category: Syndicate Pairings
|
|||||||
overlappingMechanics:
|
overlappingMechanics:
|
||||||
- "[[Fervor]]"
|
- "[[Fervor]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
Both syndicates have access to [[Fervor]]. So you could technically go that route.
|
Both syndicates have access to [[Fervor]]. So you could technically go that route.
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ syndicates:
|
|||||||
- Sungrace
|
- Sungrace
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
|
|
||||||
Both actually have access to [[Flourish]], given [[Limit Breaker]] and [[Soothing Glow]].
|
Both actually have access to [[Flourish]], given [[Limit Breaker]] and [[Soothing Glow]].
|
||||||
|
|
||||||
So you could wrong a flourish deck, protect your agents with the massive amount of protection Sungrace and Lifeblood provide, and get a surprise lethal with [[Symbiosis]] to pay off all your flourish triggers.
|
So you could wrong a flourish deck, protect your agents with the massive amount of protection Sungrace and Lifeblood
|
||||||
|
provide, and get a surprise lethal with [[Symbiosis]] to pay off all your flourish triggers.
|
||||||
@@ -4,13 +4,17 @@ syndicates:
|
|||||||
- Silence
|
- Silence
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
I suppose a control heavily [[The One True Timeline]] deck.
|
|
||||||
|
|
||||||
[[Boof, Ever Loyal]] will return to hand the last played spell the current round if it dies. [[Silence]] has a lot of nice removal spells to copy.
|
I suppose a control heavily [[The One True Timeline]] deck.
|
||||||
|
|
||||||
And I suppose given how easy it is to immortalize your cards with the one true timeline, [[Solemn Attendant]] will always have a target.
|
[[Boof, Ever Loyal]] will return to hand the last played spell the current round if it dies. [[Silence]] has a lot of
|
||||||
|
nice removal spells to copy.
|
||||||
|
|
||||||
[[Paradox Plague]] can be a bit awkward if there are not many timelines in the timeline stack, or bulky enough paradox units on the board, and [[Phasetide]] provides both.
|
And I suppose given how easy it is to immortalize your cards with the one true timeline, [[Solemn Attendant]] will
|
||||||
|
always have a target.
|
||||||
|
|
||||||
|
[[Paradox Plague]] can be a bit awkward if there are not many timelines in the timeline stack, or bulky enough paradox
|
||||||
|
units on the board, and [[Phasetide]] provides both.
|
||||||
|
|
||||||
So mid range [[The One True Timeline]] deck with [[Silence]] utilities and removal.
|
So mid range [[The One True Timeline]] deck with [[Silence]] utilities and removal.
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ syndicates:
|
|||||||
- Singularity
|
- Singularity
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
|
|
||||||
The [[Fractal Phantasm]] pairing, given the sheer amount of access [[Phasetide]] has to [[Shift]].
|
The [[Fractal Phantasm]] pairing, given the sheer amount of access [[Phasetide]] has to [[Shift]].
|
||||||
@@ -4,4 +4,6 @@ syndicates:
|
|||||||
- Splintergleam
|
- Splintergleam
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
You have access to bleeding and healing. Seems kind of clear of a gameplan. Bleed everything, and keep your stuff barely alive, while everything your enemy has dies.
|
|
||||||
|
You have access to bleeding and healing. Seems kind of clear of a gameplan. Bleed everything, and keep your stuff barely
|
||||||
|
alive, while everything your enemy has dies.
|
||||||
@@ -6,6 +6,8 @@ category: Syndicate Pairings
|
|||||||
overlappingMechanics:
|
overlappingMechanics:
|
||||||
- "[[Heal]]"
|
- "[[Heal]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
You can [[Snap Back]] your [[Supernova]] for so much mana.
|
You can [[Snap Back]] your [[Supernova]] for so much mana.
|
||||||
|
|
||||||
This is more of the stereotypically heal faction due to all the healing in [[Phasetide]] and [[Starfueled Medics]] to turn your healing more into a win condition.
|
This is more of the stereotypically heal faction due to all the healing in [[Phasetide]] and [[Starfueled Medics]] to
|
||||||
|
turn your healing more into a win condition.
|
||||||
@@ -4,6 +4,7 @@ syndicates:
|
|||||||
- Singularity
|
- Singularity
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
I like going [[Deplete]]. Singularity has good removal and [[Timestop]].
|
|
||||||
|
I like going [[Deplete]]. Singularity has good removal and [[Timestop]].
|
||||||
|
|
||||||
If your deplete plan still fails, you have [[Zorp, Unrecyclable]] to continue the attacking plan forever.
|
If your deplete plan still fails, you have [[Zorp, Unrecyclable]] to continue the attacking plan forever.
|
||||||
@@ -4,4 +4,7 @@ syndicates:
|
|||||||
- Splintergleam
|
- Splintergleam
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
The [[Precon Telekinetic Burn]] deck. And I like to go that route. So many activate triggers, with [[Telepathic Conduit]], [[Bloodline Tracker]] and [[Ylka, the Headliner]] all in play, you can just blow up your opponent.
|
|
||||||
|
The [[Precon Telekinetic Burn]] deck. And I like to go that route. So many activate triggers,
|
||||||
|
with [[Telepathic Conduit]], [[Bloodline Tracker]] and [[Ylka, the Headliner]] all in play, you can just blow up your
|
||||||
|
opponent.
|
||||||
@@ -4,13 +4,16 @@ syndicates:
|
|||||||
- Sungrace
|
- Sungrace
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
|
|
||||||
The typical control pairing.
|
The typical control pairing.
|
||||||
|
|
||||||
You can put down one threat at a time, like [[Limit Breaker]], [[Canine Adjutant]], [[Debris Collector]] and [[Jury of the Second Law]].
|
You can put down one threat at a time, like [[Limit Breaker]], [[Canine Adjutant]], [[Debris Collector]]
|
||||||
|
and [[Jury of the Second Law]].
|
||||||
|
|
||||||
All your [[Silence]] spells will kill their threats, plus you can [[Overflow]] for days.
|
All your [[Silence]] spells will kill their threats, plus you can [[Overflow]] for days.
|
||||||
|
|
||||||
[[Redactionist]] is great graveyard hate. You also have [[Suncursed Conduit]] to shut down [[Fractal Phantasm]]s, so you can uber kill the things you kill.
|
[[Redactionist]] is great graveyard hate. You also have [[Suncursed Conduit]] to shut down [[Fractal Phantasm]]s, so you
|
||||||
|
can uber kill the things you kill.
|
||||||
|
|
||||||
If you encounter a [[Devourer Spawn]] or [[Roiling Amalgam]] you can always [[Throw into the Sun]].
|
If you encounter a [[Devourer Spawn]] or [[Roiling Amalgam]] you can always [[Throw into the Sun]].
|
||||||
|
|
||||||
|
|||||||
@@ -4,5 +4,8 @@ syndicates:
|
|||||||
- Splintergleam
|
- Splintergleam
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
I've seen a person go the [[Singularity]] + [[Splintergleam]] pairing just to have [[Timestop]] to protect their big [[Bleed]] troops that been heavily buffed. Using [[Nascent Clone]] to duplicate [[Fervor]] casts was also a pretty clever idea.
|
|
||||||
|
I've seen a person go the [[Singularity]] + [[Splintergleam]] pairing just to have [[Timestop]] to protect their
|
||||||
|
big [[Bleed]] troops that been heavily buffed. Using [[Nascent Clone]] to duplicate [[Fervor]] casts was also a pretty
|
||||||
|
clever idea.
|
||||||
|
|
||||||
|
|||||||
@@ -4,4 +4,6 @@ syndicates:
|
|||||||
- Sungrace
|
- Sungrace
|
||||||
category: Syndicate Pairings
|
category: Syndicate Pairings
|
||||||
---
|
---
|
||||||
This pairing has the funny access to discard revive, so you can cheat out something like [[Kyln, the Dynasty]] or the classic [[Devourer Spawn]] early with [[Entropy's End]].
|
|
||||||
|
This pairing has the funny access to discard revive, so you can cheat out something like [[Kyln, the Dynasty]] or the
|
||||||
|
classic [[Devourer Spawn]] early with [[Entropy's End]].
|
||||||
@@ -6,8 +6,10 @@ category: Syndicate Pairings
|
|||||||
overlappingMechanics:
|
overlappingMechanics:
|
||||||
- "[[Volcanic Rivers]]"
|
- "[[Volcanic Rivers]]"
|
||||||
---
|
---
|
||||||
|
|
||||||
I saw someone using [[Lightsteel Engineer]] with the entire [[Volcanic Rivers]] package, and I just love it.
|
I saw someone using [[Lightsteel Engineer]] with the entire [[Volcanic Rivers]] package, and I just love it.
|
||||||
|
|
||||||
Technically, [[Gentle Frank]] also reduces core damage, but I feel like your going to die before 8 mana.
|
Technically, [[Gentle Frank]] also reduces core damage, but I feel like your going to die before 8 mana.
|
||||||
|
|
||||||
[[Clarion, Deepest Breath]] turns your [[Volcanic Rivers]] shifts into life gain, but then you need to run the [[Overflow]] package.
|
[[Clarion, Deepest Breath]] turns your [[Volcanic Rivers]] shifts into life gain, but then you need to run
|
||||||
|
the [[Overflow]] package.
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
category: Syndicate
|
category: Syndicate
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timelines
|
# Timelines
|
||||||
|
|
||||||
## Deadly Fauna
|
## Deadly Fauna
|
||||||
@@ -16,9 +17,11 @@ Gives everything [[Overpower]].
|
|||||||
## Flourish
|
## Flourish
|
||||||
|
|
||||||
Flourish.
|
Flourish.
|
||||||
|
|
||||||
## Combat
|
## Combat
|
||||||
|
|
||||||
Combat.
|
Combat.
|
||||||
|
|
||||||
## Evasive
|
## Evasive
|
||||||
|
|
||||||
Evasive.
|
Evasive.
|
||||||
@@ -34,13 +37,14 @@ Wolves.
|
|||||||
# Key Cards
|
# Key Cards
|
||||||
|
|
||||||
## Defensive Cards:
|
## Defensive Cards:
|
||||||
|
|
||||||
- [[Bloom]]
|
- [[Bloom]]
|
||||||
- [[Mulch]]
|
- [[Mulch]]
|
||||||
- [[Focused Adaptation]]
|
- [[Focused Adaptation]]
|
||||||
- [[Symbiosis]]
|
- [[Symbiosis]]
|
||||||
|
|
||||||
|
|
||||||
## Threats
|
## Threats
|
||||||
|
|
||||||
- [[Glade Grazers]]
|
- [[Glade Grazers]]
|
||||||
- [[Sapling Dryad]]
|
- [[Sapling Dryad]]
|
||||||
- [[Spark of Bounty]]
|
- [[Spark of Bounty]]
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
---
|
---
|
||||||
category: Syndicate
|
category: Syndicate
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timelines
|
# Timelines
|
||||||
|
|
||||||
## The One True Timeline
|
## The One True Timeline
|
||||||
|
|
||||||
Heals everything 1 health each turn.
|
Heals everything 1 health each turn.
|
||||||
|
|
||||||
A lot of Phasetide agents simply immortalize in this timeline. And a lot of Phasetide agents start damage to take advantage of this healing effect.
|
A lot of Phasetide agents simply immortalize in this timeline. And a lot of Phasetide agents start damage to take
|
||||||
|
advantage of this healing effect.
|
||||||
|
|
||||||
And some Phasetide agents will hate it when your not in the timeline. Such as [[Shattersmith]], which will flat out die if too many timelines exist in the stack that are not The One True timeline.
|
And some Phasetide agents will hate it when your not in the timeline. Such as [[Shattersmith]], which will flat out die
|
||||||
|
if too many timelines exist in the stack that are not The One True timeline.
|
||||||
|
|
||||||
# Mechanics
|
# Mechanics
|
||||||
|
|
||||||
@@ -18,19 +21,23 @@ And some Phasetide agents will hate it when your not in the timeline. Such as [[
|
|||||||
Healing.
|
Healing.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Bearer of the Broth]]
|
- [[Bearer of the Broth]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Bareknuckle Inquisitor]]
|
- [[Bareknuckle Inquisitor]]
|
||||||
|
|
||||||
## Rewind
|
## Rewind
|
||||||
|
|
||||||
Rewind.
|
Rewind.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Temple Analyst]]
|
- [[Temple Analyst]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Divergence Assassin]]
|
- [[Divergence Assassin]]
|
||||||
|
|
||||||
## Phase
|
## Phase
|
||||||
@@ -38,9 +45,11 @@ Payoff:
|
|||||||
Phase.
|
Phase.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Set in Stone]]
|
- [[Set in Stone]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Karmic Debtor]]
|
- [[Karmic Debtor]]
|
||||||
|
|
||||||
## Reduce Cost
|
## Reduce Cost
|
||||||
@@ -48,20 +57,24 @@ Payoff:
|
|||||||
Reduce cost.
|
Reduce cost.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Slow Convert]]
|
- [[Slow Convert]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Stern Arbiter]]
|
- [[Stern Arbiter]]
|
||||||
|
|
||||||
# Key Cards
|
# Key Cards
|
||||||
|
|
||||||
## Defensive Cards:
|
## Defensive Cards:
|
||||||
|
|
||||||
- [[Prayer of Rescue]]
|
- [[Prayer of Rescue]]
|
||||||
- [[Invigorating Balm]]
|
- [[Invigorating Balm]]
|
||||||
- [[Set in Stone]]
|
- [[Set in Stone]]
|
||||||
- [[Out of Line]]
|
- [[Out of Line]]
|
||||||
|
|
||||||
## Threats
|
## Threats
|
||||||
|
|
||||||
- [[Temple Analyst]]
|
- [[Temple Analyst]]
|
||||||
- [[Consummate Conspirator]]
|
- [[Consummate Conspirator]]
|
||||||
- [[Bareknuckle Inquisitor]]
|
- [[Bareknuckle Inquisitor]]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
category: Syndicate
|
category: Syndicate
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timelines
|
# Timelines
|
||||||
|
|
||||||
## Voiceless Skies
|
## Voiceless Skies
|
||||||
@@ -10,28 +11,36 @@ With deplete, you can ensure the player ideally can never properly take advantag
|
|||||||
|
|
||||||
It turn on some of your key board survival cards, like [[Braindead Bouncer]] and [[Nameless Spirit]].
|
It turn on some of your key board survival cards, like [[Braindead Bouncer]] and [[Nameless Spirit]].
|
||||||
|
|
||||||
It also notably interacts with [[Phase]]. So you can phase your [[Sensory Deprivation Pod]] to potentially activate Voiceless Skies for your other blocker, or use [[Bury the Evidence]] if you have two 1 / 1 cards and need to remove one.
|
It also notably interacts with [[Phase]]. So you can phase your [[Sensory Deprivation Pod]] to potentially activate
|
||||||
|
Voiceless Skies for your other blocker, or use [[Bury the Evidence]] if you have two 1 / 1 cards and need to remove one.
|
||||||
|
|
||||||
# Mechanics
|
# Mechanics
|
||||||
|
|
||||||
## Deplete
|
## Deplete
|
||||||
|
|
||||||
Prevents a card from attacking and blocking if they have not already attacked or blocked. Also prevents a card from being activated, although outside of [[Mind Over Matter]] during [[Voiceless Sky]], the opposing agent can always activate in a response.
|
Prevents a card from attacking and blocking if they have not already attacked or blocked. Also prevents a card from
|
||||||
|
being activated, although outside of [[Mind Over Matter]] during [[Voiceless Sky]], the opposing agent can always
|
||||||
|
activate in a response.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Return to Stillness]]
|
- [[Return to Stillness]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Telepathic Scavenger]]
|
- [[Telepathic Scavenger]]
|
||||||
|
|
||||||
## Mute
|
## Mute
|
||||||
|
|
||||||
Can remove all keywords and effects on an agent. Note the order matters. If you mute a target, and an effect gets added on after, the agent will have the newly added effect while still being considered muted.
|
Can remove all keywords and effects on an agent. Note the order matters. If you mute a target, and an effect gets added
|
||||||
|
on after, the agent will have the newly added effect while still being considered muted.
|
||||||
|
|
||||||
|
Cards:
|
||||||
|
|
||||||
Cards:
|
|
||||||
- [[Muffle]]
|
- [[Muffle]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Destiny Ripper]]
|
- [[Destiny Ripper]]
|
||||||
|
|
||||||
## Revival
|
## Revival
|
||||||
@@ -39,9 +48,11 @@ Payoff:
|
|||||||
Can bring cards back from the dead. Currently mostly a mechanic in practice for keeping [[Somnus, the Dreaming]] alive.
|
Can bring cards back from the dead. Currently mostly a mechanic in practice for keeping [[Somnus, the Dreaming]] alive.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[The Forgotten Tale]]
|
- [[The Forgotten Tale]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Solemn Attendant]]
|
- [[Solemn Attendant]]
|
||||||
|
|
||||||
## Spell Duplication
|
## Spell Duplication
|
||||||
@@ -49,30 +60,37 @@ Payoff:
|
|||||||
Has access to duplicating spells.
|
Has access to duplicating spells.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Disciplined Student]]
|
- [[Disciplined Student]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Overburdened Scribe]]
|
- [[Overburdened Scribe]]
|
||||||
|
|
||||||
## Activations
|
## Activations
|
||||||
|
|
||||||
Cards with strong activation effects. And it's revival package also allows you to kill off and revive your own cards to activate them again in a fresh state.
|
Cards with strong activation effects. And it's revival package also allows you to kill off and revive your own cards to
|
||||||
|
activate them again in a fresh state.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Death Jockey]]
|
- [[Death Jockey]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Rotting Rocker]]
|
- [[Rotting Rocker]]
|
||||||
|
|
||||||
# Key Cards
|
# Key Cards
|
||||||
|
|
||||||
## Defensive Cards:
|
## Defensive Cards:
|
||||||
|
|
||||||
- [[Hush Now]]
|
- [[Hush Now]]
|
||||||
- [[Spread the Sickness]]
|
- [[Spread the Sickness]]
|
||||||
- [[Pressure Spike]]
|
- [[Pressure Spike]]
|
||||||
- [[Muffle]]
|
- [[Muffle]]
|
||||||
|
|
||||||
## Threats
|
## Threats
|
||||||
|
|
||||||
- [[Rotting Rocker]]
|
- [[Rotting Rocker]]
|
||||||
- [[Telepathic Scavenger]]
|
- [[Telepathic Scavenger]]
|
||||||
- [[Sensory Deprivation Pod]]
|
- [[Sensory Deprivation Pod]]
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
---
|
---
|
||||||
category: Syndicate
|
category: Syndicate
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timelines
|
# Timelines
|
||||||
|
|
||||||
## Erudite Beacon
|
## Erudite Beacon
|
||||||
|
|
||||||
Causes you to draw a card when you shift to it, and a card every round. You will have many cards in hand, so if you play in this timeline, you need ways to spend your hand to avoid erasing cards off the top of your deck.
|
Causes you to draw a card when you shift to it, and a card every round. You will have many cards in hand, so if you play
|
||||||
|
in this timeline, you need ways to spend your hand to avoid erasing cards off the top of your deck.
|
||||||
|
|
||||||
[[Enlightened Refugee]] is the simplest way to shift to this [[Timeline]].
|
[[Enlightened Refugee]] is the simplest way to shift to this [[Timeline]].
|
||||||
|
|
||||||
@@ -13,12 +15,15 @@ Causes you to draw a card when you shift to it, and a card every round. You will
|
|||||||
|
|
||||||
## Discard
|
## Discard
|
||||||
|
|
||||||
Has a lot of cards that can be removed from hand for added benefits, and a lot of cards that can discard for additional card draw.
|
Has a lot of cards that can be removed from hand for added benefits, and a lot of cards that can discard for additional
|
||||||
|
card draw.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Efficient Scrapbot]]
|
- [[Efficient Scrapbot]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Rapid Iteration]]
|
- [[Rapid Iteration]]
|
||||||
|
|
||||||
## Disarm
|
## Disarm
|
||||||
@@ -26,9 +31,11 @@ Payoff:
|
|||||||
Can reduce agents attack values to zero. Way to reduce damage for a turn or win combat trades.
|
Can reduce agents attack values to zero. Way to reduce damage for a turn or win combat trades.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Frontline Fellowship]]
|
- [[Frontline Fellowship]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Traffic Conductor]]
|
- [[Traffic Conductor]]
|
||||||
|
|
||||||
## Agent Duplication
|
## Agent Duplication
|
||||||
@@ -36,9 +43,11 @@ Payoff:
|
|||||||
Has access to duplicating agents.
|
Has access to duplicating agents.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Chronal Scan]]
|
- [[Chronal Scan]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Springloaded Hopper]]
|
- [[Springloaded Hopper]]
|
||||||
|
|
||||||
## Pocket Scout
|
## Pocket Scout
|
||||||
@@ -46,19 +55,23 @@ Payoff:
|
|||||||
1 / 1 token that can swarm the board or chump block.
|
1 / 1 token that can swarm the board or chump block.
|
||||||
|
|
||||||
Cards:
|
Cards:
|
||||||
|
|
||||||
- [[Enthusiastic Bot-Poke]]
|
- [[Enthusiastic Bot-Poke]]
|
||||||
|
|
||||||
Payoff:
|
Payoff:
|
||||||
|
|
||||||
- [[Scattered Helpers]]
|
- [[Scattered Helpers]]
|
||||||
|
|
||||||
# Key Cards
|
# Key Cards
|
||||||
|
|
||||||
## Defensive Cards:
|
## Defensive Cards:
|
||||||
|
|
||||||
- [[Timestop]]
|
- [[Timestop]]
|
||||||
- [[Rapid Iteration]]
|
- [[Rapid Iteration]]
|
||||||
- [[Frontline Fellowship]]
|
- [[Frontline Fellowship]]
|
||||||
|
|
||||||
## Threats
|
## Threats
|
||||||
|
|
||||||
- [[Roiling Amalgam]]
|
- [[Roiling Amalgam]]
|
||||||
- [[Rogue Amalgam]]
|
- [[Rogue Amalgam]]
|
||||||
- [[Quicksilver Khaela]]
|
- [[Quicksilver Khaela]]
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
---
|
---
|
||||||
category: Syndicate
|
category: Syndicate
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timelines
|
# Timelines
|
||||||
|
|
||||||
## Volcanic Rivers
|
## Volcanic Rivers
|
||||||
@@ -14,9 +15,11 @@ Deals 1 damage to each core when shifted to.
|
|||||||
## Bleed
|
## Bleed
|
||||||
|
|
||||||
Bleed.
|
Bleed.
|
||||||
|
|
||||||
## Big Timeline Stack
|
## Big Timeline Stack
|
||||||
|
|
||||||
Big Timeline Stack
|
Big Timeline Stack
|
||||||
|
|
||||||
## Fervor
|
## Fervor
|
||||||
|
|
||||||
Fervor
|
Fervor
|
||||||
@@ -25,18 +28,18 @@ Fervor
|
|||||||
|
|
||||||
Self Wound
|
Self Wound
|
||||||
|
|
||||||
|
|
||||||
# Key Cards
|
# Key Cards
|
||||||
|
|
||||||
## Defensive Cards:
|
## Defensive Cards:
|
||||||
|
|
||||||
- [[Bathe in Flames]]
|
- [[Bathe in Flames]]
|
||||||
- [[Circle of Strife]]
|
- [[Circle of Strife]]
|
||||||
- [[Paradox Cacophony]]
|
- [[Paradox Cacophony]]
|
||||||
- [[Fervor]]
|
- [[Fervor]]
|
||||||
- [[Sanguine Resurgence]]
|
- [[Sanguine Resurgence]]
|
||||||
|
|
||||||
|
|
||||||
## Threats
|
## Threats
|
||||||
|
|
||||||
- [[Pit Dog]]
|
- [[Pit Dog]]
|
||||||
- [[Bright-Eyed Supplicant]]
|
- [[Bright-Eyed Supplicant]]
|
||||||
- [[Blazing Shifter]]
|
- [[Blazing Shifter]]
|
||||||
|
|||||||
@@ -1,20 +1,26 @@
|
|||||||
---
|
---
|
||||||
category: Syndicate
|
category: Syndicate
|
||||||
---
|
---
|
||||||
|
|
||||||
# Timelines
|
# Timelines
|
||||||
|
|
||||||
## Star Siphon
|
## Star Siphon
|
||||||
|
|
||||||
Refill your energy reserves every turn. Not, this will not overflow your energy reserve if your energy reserve is full and you otherwise have no other energy. Now if you have 1 energy, and 0 reserves, even though you have 2 less mana, it will overflow. So your encouraged to spend all your reserves and always leave one normal mana left over a turn to trigger your overflows.
|
Refill your energy reserves every turn. Not, this will not overflow your energy reserve if your energy reserve is full
|
||||||
|
and you otherwise have no other energy. Now if you have 1 energy, and 0 reserves, even though you have 2 less mana, it
|
||||||
|
will overflow. So your encouraged to spend all your reserves and always leave one normal mana left over a turn to
|
||||||
|
trigger your overflows.
|
||||||
|
|
||||||
# Mechanics
|
# Mechanics
|
||||||
|
|
||||||
## Overflow
|
## Overflow
|
||||||
|
|
||||||
Energy Reserves.
|
Energy Reserves.
|
||||||
|
|
||||||
## Energy Reserves
|
## Energy Reserves
|
||||||
|
|
||||||
Energy Reserves.
|
Energy Reserves.
|
||||||
|
|
||||||
## Spend 12+ Energy
|
## Spend 12+ Energy
|
||||||
|
|
||||||
Spend 12+ Energy.
|
Spend 12+ Energy.
|
||||||
@@ -34,6 +40,7 @@ Blitz.
|
|||||||
# Key Cards
|
# Key Cards
|
||||||
|
|
||||||
## Defensive Cards:
|
## Defensive Cards:
|
||||||
|
|
||||||
- [[Soothing Glow]]
|
- [[Soothing Glow]]
|
||||||
- [[Chaos Control]]
|
- [[Chaos Control]]
|
||||||
- [[Radiant Channeling]]
|
- [[Radiant Channeling]]
|
||||||
@@ -41,8 +48,8 @@ Blitz.
|
|||||||
- [[Throw into the Sun]]
|
- [[Throw into the Sun]]
|
||||||
- [[Entropy's End]]
|
- [[Entropy's End]]
|
||||||
|
|
||||||
|
|
||||||
## Threats
|
## Threats
|
||||||
|
|
||||||
- [[Canine Adjutant]]
|
- [[Canine Adjutant]]
|
||||||
- [[Limit Breaker]]
|
- [[Limit Breaker]]
|
||||||
- [[Debris Collector]]
|
- [[Debris Collector]]
|
||||||
|
|||||||
@@ -3,24 +3,30 @@
|
|||||||
To enhance the utility of the site for the community, I suggest adding the following features:
|
To enhance the utility of the site for the community, I suggest adding the following features:
|
||||||
|
|
||||||
## 1. Advanced Deck Analytics
|
## 1. Advanced Deck Analytics
|
||||||
|
|
||||||
- **Mana Curve Visualization**: A bar chart showing the distribution of card costs in a deck.
|
- **Mana Curve Visualization**: A bar chart showing the distribution of card costs in a deck.
|
||||||
- **Type Breakdown**: A pie chart showing the ratio of Spells, Units, and Divers.
|
- **Type Breakdown**: A pie chart showing the ratio of Spells, Units, and Divers.
|
||||||
- **Syndicate Compatibility**: An indicator showing how well the deck aligns with its chosen Syndicate or Faction.
|
- **Syndicate Compatibility**: An indicator showing how well the deck aligns with its chosen Syndicate or Faction.
|
||||||
|
|
||||||
## 2. Interactive Card Browser Enhancements
|
## 2. Interactive Card Browser Enhancements
|
||||||
|
|
||||||
- **Hover Previews**: Hovering over a card name in a deck list or doc should show a popup of the card image.
|
- **Hover Previews**: Hovering over a card name in a deck list or doc should show a popup of the card image.
|
||||||
- **Advanced Filtering**: Filter by keyword (e.g., "Silence", "Phasetide"), set, rarity, and artist.
|
- **Advanced Filtering**: Filter by keyword (e.g., "Silence", "Phasetide"), set, rarity, and artist.
|
||||||
- **Related Cards**: On a card's detail page, show cards that frequently appear in decks alongside it.
|
- **Related Cards**: On a card's detail page, show cards that frequently appear in decks alongside it.
|
||||||
|
|
||||||
## 3. Social and Community Features
|
## 3. Social and Community Features
|
||||||
|
|
||||||
- **Deck Sharing**: Generate a unique URL or exportable "Deck Code" for sharing.
|
- **Deck Sharing**: Generate a unique URL or exportable "Deck Code" for sharing.
|
||||||
- **User Ratings**: Allow logged-in users to rate decks or comment on card strategies.
|
- **User Ratings**: Allow logged-in users to rate decks or comment on card strategies.
|
||||||
- **Public vs. Private Decks**: Toggle visibility for decks in "My Decks".
|
- **Public vs. Private Decks**: Toggle visibility for decks in "My Decks".
|
||||||
|
|
||||||
## 4. Agent Customization and Progression
|
## 4. Agent Customization and Progression
|
||||||
|
|
||||||
- **Agent Skill Tree**: If the game features agent progression, a visualizer for skill trees or equipment.
|
- **Agent Skill Tree**: If the game features agent progression, a visualizer for skill trees or equipment.
|
||||||
- **Win-Rate Tracking**: Integration with match history to show win rates for specific Agents or Syndicates.
|
- **Win-Rate Tracking**: Integration with match history to show win rates for specific Agents or Syndicates.
|
||||||
|
|
||||||
## 5. Game State Simulator (Sandboxing)
|
## 5. Game State Simulator (Sandboxing)
|
||||||
|
|
||||||
- **Starting Hand Simulator**: A button to "Draw 5" from a built deck to test opening hand consistency.
|
- **Starting Hand Simulator**: A button to "Draw 5" from a built deck to test opening hand consistency.
|
||||||
- **Combat Calculator**: A simple tool to calculate damage outcomes between two units with various debuffs/buffs applied.
|
- **Combat Calculator**: A simple tool to calculate damage outcomes between two units with various debuffs/buffs
|
||||||
|
applied.
|
||||||
|
|||||||
@@ -1,15 +1,26 @@
|
|||||||
# Website Opinions - Chrono CCG Reference
|
# Website Opinions - Chrono CCG Reference
|
||||||
|
|
||||||
The "Slop Game Reference" website for Chrono CCG provides a solid foundation for a digital card game companion tool. Here are my opinions on the current state of the website and its content:
|
The "Slop Game Reference" website for Chrono CCG provides a solid foundation for a digital card game companion tool.
|
||||||
|
Here are my opinions on the current state of the website and its content:
|
||||||
|
|
||||||
## Strengths
|
## Strengths
|
||||||
- **Clean Aesthetic**: The dark theme and "hero glow" effects (seen on the Home page) align well with a modern CCG aesthetic.
|
|
||||||
- **Comprehensive Data**: Integration with a Telerik Grid for Agents and a dedicated Docs section indicates a focus on data density and rule clarity.
|
- **Clean Aesthetic**: The dark theme and "hero glow" effects (seen on the Home page) align well with a modern CCG
|
||||||
|
aesthetic.
|
||||||
|
- **Comprehensive Data**: Integration with a Telerik Grid for Agents and a dedicated Docs section indicates a focus on
|
||||||
|
data density and rule clarity.
|
||||||
- **Quick Navigation**: The home page provides immediate access to core functions like browsing cards and viewing decks.
|
- **Quick Navigation**: The home page provides immediate access to core functions like browsing cards and viewing decks.
|
||||||
- **Dynamic Elements**: The "Free Pack Countdown" adds a layer of interactivity and engagement, simulating a live game environment.
|
- **Dynamic Elements**: The "Free Pack Countdown" adds a layer of interactivity and engagement, simulating a live game
|
||||||
|
environment.
|
||||||
|
|
||||||
## Areas for Improvement
|
## Areas for Improvement
|
||||||
- **"Slop Game" Branding**: The term "Slop Game Reference" in the title and hero section might be perceived as self-deprecating or confusing to new users. If "Slop" isn't a specific in-game term, a more professional name like "Chrono CCG Nexus" or "Archive" might be better.
|
|
||||||
- **Visual Feedback**: Some pages (like the Agents grid) could benefit from more visual flair beyond standard data tables, such as agent portraits or faction-themed styling.
|
- **"Slop Game" Branding**: The term "Slop Game Reference" in the title and hero section might be perceived as
|
||||||
- **Content Discoverability**: While the Docs section exists, it could be better integrated with the card browser (e.g., clicking a keyword on a card takes you to the relevant Doc entry).
|
self-deprecating or confusing to new users. If "Slop" isn't a specific in-game term, a more professional name like "
|
||||||
- **Mobile Experience**: Ensuring the heavy data tables and deck builder UI translate well to mobile devices is crucial for players who might use this as a second-screen reference during live play.
|
Chrono CCG Nexus" or "Archive" might be better.
|
||||||
|
- **Visual Feedback**: Some pages (like the Agents grid) could benefit from more visual flair beyond standard data
|
||||||
|
tables, such as agent portraits or faction-themed styling.
|
||||||
|
- **Content Discoverability**: While the Docs section exists, it could be better integrated with the card browser (e.g.,
|
||||||
|
clicking a keyword on a card takes you to the relevant Doc entry).
|
||||||
|
- **Mobile Experience**: Ensuring the heavy data tables and deck builder UI translate well to mobile devices is crucial
|
||||||
|
for players who might use this as a second-screen reference during live play.
|
||||||
|
|||||||
Reference in New Issue
Block a user