Browse Source

Merge branch 'develop' into main

main
Jonathan McCaffrey 4 years ago
parent
commit
8c06fdd120
  1. 11
      .vscode/launch.json
  2. 41
      .vscode/tasks.json
  3. 2
      Components/Display/CodeComponent.razor
  4. 10
      Components/Display/DevOnlyComponent.razor
  5. 4
      Components/Display/EntityDisplayComponent.razor
  6. 5
      Components/Display/InfoTooltipComponent.razor
  7. 10
      Components/Display/MakingOfComponent.razor
  8. 4
      Components/Display/MakingOfSectionComponent.razor
  9. 10
      Components/Display/PaperComponent.razor
  10. 4
      Components/Form/FormDisplayComponent.razor
  11. 4
      Components/Form/FormEscapeCodeComponent.razor
  12. 12
      Components/Form/FormGuessComponent.razor
  13. 6
      Components/Inputs/ButtonComponent.razor
  14. 4
      Components/Inputs/ButtonGroupComponent.razor
  15. 6
      Components/Inputs/EntityLabelComponent.razor
  16. 58
      Components/Layout/LayoutWithSidebarComponent.razor
  17. 2
      Components/Layout/PageContainerComponent.razor
  18. 17
      Components/MarkdownContent/MarkdownContent.razor
  19. 8
      Components/Navigation/DesktopNavComponent.razor
  20. 36
      Components/Navigation/MobileNavComponent.razor
  21. 11
      Components/Navigation/NavLinkComponent.razor
  22. 4
      Components/Navigation/NavSectionComponent.razor
  23. 16
      Components/Navigation/TabletNavComponent.razor
  24. 6
      Components/Shared/DisplayableContent.razor
  25. 4
      Components/Shared/DisplayableRoute.razor
  26. 4
      Components/Shared/MathDivisionComponent.razor
  27. 6
      Components/Shared/MathLoopSumComponent.razor
  28. 2
      Components/Shared/SpoilerTextComponent.razor
  29. 34
      Contexts/DatabaseContext.cs
  30. 33
      IGP/App.razor
  31. BIN
      IGP/Database.db
  32. 52
      IGP/Dialog/EntityDialogComponent.razor
  33. 27
      IGP/IGP.csproj
  34. 4
      IGP/Index.razor
  35. 53
      IGP/PageLayout.razor
  36. 77
      IGP/Pages/Agile/AgilePage.razor
  37. 2
      IGP/Pages/Agile/AgilePage.razor.css
  38. 29
      IGP/Pages/Agile/Parts/BacklogComponent.razor
  39. 46
      IGP/Pages/Agile/Parts/SprintComponent.razor
  40. 106
      IGP/Pages/BuildCalculator/BuildCalculatorPage.razor
  41. 37
      IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor
  42. 16
      IGP/Pages/BuildCalculator/Parts/BankComponent.razor
  43. 19
      IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor
  44. 61
      IGP/Pages/BuildCalculator/Parts/ChartComponent.razor
  45. 28
      IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor
  46. 18
      IGP/Pages/BuildCalculator/Parts/FilterComponent.razor
  47. 30
      IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor
  48. 131
      IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor
  49. 10
      IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor
  50. 16
      IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor
  51. 27
      IGP/Pages/BuildCalculator/Parts/TimingComponent.razor
  52. 54
      IGP/Pages/ChangeLogPage.razor
  53. 31
      IGP/Pages/Comparision/ComparisionPage.razor
  54. 11
      IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor
  55. 8
      IGP/Pages/Comparision/Parts/SandComponent.razor
  56. 2
      IGP/Pages/ContactPage.razor
  57. 108
      IGP/Pages/Database/DatabasePage.razor
  58. 39
      IGP/Pages/Database/DatabaseSinglePage.razor
  59. 7
      IGP/Pages/Database/Entity/EntityViewComponent.razor
  60. 64
      IGP/Pages/Database/Entity/Parts/EntityAbilitiesComponent.razor
  61. 19
      IGP/Pages/Database/Entity/Parts/EntityHeaderComponent.razor
  62. 41
      IGP/Pages/Database/Entity/Parts/EntityInfoComponent.razor
  63. 10
      IGP/Pages/Database/Entity/Parts/EntityMechanicsComponent.razor
  64. 72
      IGP/Pages/Database/Entity/Parts/EntityPassivesComponent.razor
  65. 249
      IGP/Pages/Database/Entity/Parts/EntityProductionComponent.razor
  66. 40
      IGP/Pages/Database/Entity/Parts/EntityPyreSpellsComponent.razor
  67. 149
      IGP/Pages/Database/Entity/Parts/EntityStatsComponent.razor
  68. 21
      IGP/Pages/Database/Entity/Parts/EntityUpgradesComponent.razor
  69. 30
      IGP/Pages/Database/Entity/Parts/EntityVanguardAddedComponent.razor
  70. 23
      IGP/Pages/Database/Entity/Parts/EntityVanguardsComponent.razor
  71. 322
      IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor
  72. 57
      IGP/Pages/Database/Parts/EntityFilterComponent.razor
  73. 115
      IGP/Pages/Documentation/DocumentationIndexPage.razor
  74. 112
      IGP/Pages/Documentation/DocumentationPage.razor
  75. 35
      IGP/Pages/Documentation/Parts/DocumentComponent.razor
  76. 70
      IGP/Pages/Documentation/Parts/DocumentInnerNavComponent.razor
  77. 46
      IGP/Pages/Documentation/Parts/DocumentNavComponent.razor
  78. 33
      IGP/Pages/HarassCalculatorPage.razor
  79. 82
      IGP/Pages/Home/HomePage.razor
  80. 76
      IGP/Pages/Home/Parts/ContentHighlightComponent.razor
  81. 149
      IGP/Pages/HomePage.razor
  82. 26
      IGP/Pages/MakingOf/Parts/MakingOfColours.razor
  83. 2
      IGP/Pages/MakingOf/Parts/MakingOfDialogs.razor
  84. 9
      IGP/Pages/MakingOf/Parts/MakingOfDisplays.razor
  85. 2
      IGP/Pages/MakingOf/Parts/MakingOfFeedback.razor
  86. 40
      IGP/Pages/MemoryTester/Parts/UnitMemory.razor
  87. 31
      IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor
  88. 140
      IGP/Pages/Notes/NotesIndexPage.razor
  89. 126
      IGP/Pages/Notes/NotesPage.razor
  90. 35
      IGP/Pages/Notes/Parts/NoteComponent.razor
  91. 75
      IGP/Pages/Notes/Parts/NoteInnerNavComponent.razor
  92. 43
      IGP/Pages/Notes/Parts/NoteNavComponent.razor
  93. 3
      IGP/Pages/RoadMap/Parts/RoadMapComponent.razor
  94. 3
      IGP/Pages/RoadMap/RoadMapPage.razor
  95. 229
      IGP/Pages/SandboxPage.razor
  96. 9
      IGP/Portals/EntityDialogPortal.razor
  97. 15
      IGP/Program.cs
  98. 44
      IGP/_Imports.razor
  99. 6
      IGP/wwwroot/css/app.css
  100. 1
      IGP/wwwroot/generated/AgileSprintModels.json
  101. Some files were not shown because too many files have changed in this diff Show More

11
.vscode/launch.json vendored

@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch and Debug Standalone Blazor WebAssembly App",
"type": "blazorwasm",
"request": "launch",
"cwd": "${workspaceFolder}/IGP"
}
]
}

41
.vscode/tasks.json vendored

@ -0,0 +1,41 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "process",
"args": [
"build",
"${workspaceFolder}/IGP/IGP.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/IGP/IGP.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/IGP/IGP.csproj"
],
"problemMatcher": "$msCompile"
}
]
}

2
Components/Display/CodeComponent.razor

@ -22,6 +22,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
}

10
Components/Display/DevOnlyComponent.razor

@ -1,4 +1,4 @@
@if (IsOnDev) {
@if (isOnDev) {
<div class="devOnlyContainer">
<div class="devOnlyTitleContainer">
<div class="devOnlyTitle">
@ -58,15 +58,15 @@
@code {
[Inject]
NavigationManager NavigationManager { get; set; }
NavigationManager NavigationManager { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
bool IsOnDev;
bool isOnDev;
protected override void OnInitialized() {
IsOnDev = NavigationManager.BaseUri.Contains("https://localhost");
isOnDev = NavigationManager.BaseUri.Contains("https://localhost");
}
}

4
Components/Display/EntityDisplayComponent.razor

@ -70,9 +70,9 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Title { get; set; }
public string Title { get; set; } = default!;
}

5
Components/Display/InfoTooltipComponent.razor

@ -50,15 +50,16 @@
margin-bottom: 20px;
position: absolute;
}
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string InfoText { get; set; }
public string InfoText { get; set; } = default!;
[Parameter]
public int? Margin { get; set; }

10
Components/Display/MakingOfComponent.razor

@ -98,19 +98,19 @@
@code {
[Parameter]
public RenderFragment Title { get; set; }
public RenderFragment Title { get; set; } = default!;
[Parameter]
public RenderFragment Description { get; set; }
public RenderFragment Description { get; set; } = default!;
[Parameter]
public RenderFragment Example { get; set; }
public RenderFragment Example { get; set; } = default!;
[Parameter]
public RenderFragment Usage { get; set; }
public RenderFragment Usage { get; set; } = default!;
[Parameter]
public RenderFragment Code { get; set; }
public RenderFragment Code { get; set; } = default!;
}

4
Components/Display/MakingOfSectionComponent.razor

@ -23,10 +23,10 @@
@code {
[Parameter]
public string Title { get; set; }
public string Title { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
}

10
Components/Display/PaperComponent.razor

@ -1,29 +1,27 @@
<div class="paper">
<div class="paperDisplay">
@ChildContent
</div>
<style>
.paper {
.paperDisplay {
padding-top: 24px;
padding-left: 24px;
padding-right: 24px;
padding-bottom: 24px;
margin: auto;
overflow-y: auto;
overflow-x: hidden;
border: 4px solid var(--paper-border);
background-color: var(--paper);
box-shadow: 0px 6px var(--paper-border);
width: 100%;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Title { get; set; }
public string Title { get; set; } = default!;
}

4
Components/Form/FormDisplayComponent.razor

@ -35,10 +35,10 @@
@code {
//TODO Clean up
[Parameter]
public string Label { get; set; }
public string Label { get; set; } = default!;
[Parameter]
public string Info { get; set; }
public string Info { get; set; } = default!;
[Parameter]
public RenderFragment? Display { get; set; }

4
Components/Form/FormEscapeCodeComponent.razor

@ -21,8 +21,8 @@
string Output = "";
public void OnChange(ChangeEventArgs changeEventArgs) {
var encoded = HttpUtility.HtmlEncode(changeEventArgs.Value.ToString());
Output = encoded.Replace("@", "@@");
var encoded = HttpUtility.HtmlEncode(changeEventArgs.Value!.ToString());
Output = encoded?.Replace("@", "@@")!;
Output = Output.Replace("\n", "<br />");
}

12
Components/Form/FormGuessComponent.razor

@ -1,6 +1,6 @@
@using Services
@using Services.Immortal
@using Model.Immortal.MemoryTester
@using Model.MemoryTester
@implements IDisposable
@inject IMemoryTesterService MemoryTesterService
@ -13,7 +13,7 @@
}
<div>
<input readonly="@MemoryQuestion.IsRevealed"
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess) == MemoryQuestion.Answer ? "correct" : "wrong")"
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess ?? string.Empty) == MemoryQuestion.Answer ? "correct" : "wrong")"
placeholder="guess..."
type="number"
value="@guess"
@ -80,16 +80,16 @@
public string Info { get; set; } = "";
[Parameter]
public EventCallback<AnswerEventArgs> OnChange { get; set; }
public EventCallback<AnswerEventArgs> OnChange { get; set; } = default!;
[Parameter]
public MemoryQuestionModel MemoryQuestion { get; set; }
public MemoryQuestionModel MemoryQuestion { get; set; } = default!;
[Parameter]
public bool IsSubmitted { get; set; }
private string guess { get; set; } = "";
private string? guess = "";
private string labelId = "";
@ -142,7 +142,7 @@
}
void OnGuessChanged(ChangeEventArgs changeEventArgs) {
guess = changeEventArgs.Value.ToString();
guess = changeEventArgs.Value!.ToString()!;
OnChange.InvokeAsync(new AnswerEventArgs {
Name = MemoryQuestion.Name,

6
Components/Inputs/ButtonComponent.razor

@ -37,13 +37,13 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public EventCallback<EventArgs> OnClick { get; set; }
public EventCallback<EventArgs> OnClick { get; set; } = default!;
[Parameter]
public ButtonType ButtonType { get; set; }
public ButtonType ButtonType { get; set; } = default!;
private void ButtonClicked(EventArgs eventArgs) {
OnClick.InvokeAsync(eventArgs);

4
Components/Inputs/ButtonGroupComponent.razor

@ -68,10 +68,10 @@
@code {
[Parameter]
public string Choice { get; set; }
public string Choice { get; set; } = default!;
[Parameter]
public List<string> Choices { get; set; }
public List<string> Choices { get; set; } = default!;
[Parameter]
public EventCallback<string> OnClick { get; set; }

6
Components/Inputs/EntityLabelComponent.razor

@ -1,7 +1,7 @@
@using Model.Immortal.Entity
@using Model.Entity
@using Services.Website
@using System.ComponentModel.DataAnnotations
@using Model.Immortal.Entity.Data
@using Model.Entity.Data
@using Services
@inject IEntityDialogService entityDialogService
@ -18,7 +18,7 @@ else
@code {
[Parameter] public string EntityId { get; set; }
[Parameter] public string EntityId { get; set; } = default!;
private EntityModel Entity => DATA.Get()[EntityId];

58
Components/Layout/LayoutWithSidebarComponent.razor

@ -0,0 +1,58 @@

<div class="layoutWithSidebar">
<div class="layoutSidebar">
@Sidebar
</div>
<div class="layoutContent">
@Content
</div>
</div>
<style scoped>
.layoutWithSidebar {
display: grid;
gap: 16px;
width: 65%;
min-width: 1000px;
margin-left: auto;
margin-right: auto;
padding-top: 10px;
padding-bottom: 30px;
grid-template-columns: 412px 1fr;
}
.layoutSidebar {
background: var(--paper);
padding: 16px;
}
.layoutContent {
}
@@media only screen and (max-width: 1025px) {
.layoutWithSidebar {
flex-direction: column-reverse;
width: 100%;
min-width: 350px;
}
}
@@media only screen and (min-width: 1024px) {
.layoutWithSidebar {
margin-top: 50px;
}
}
</style>
@code {
[Parameter]
public RenderFragment Sidebar { get; set; } = default!;
[Parameter]
public RenderFragment Content { get; set; } = default!;
}

2
Components/Layout/PageContainerComponent.razor

@ -25,6 +25,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
}

17
Components/MarkdownContent/MarkdownContent.razor

@ -1,22 +1,15 @@
@if (Markdown == null) {
<div>Loading...</div>
}
else {
@((MarkupString)Markdown)
}
@((MarkupString)MarkdownText)
@code {
[Inject]
protected HttpClient Http { get; set; }
protected HttpClient Http { get; set; } = default!;
[Parameter]
public string MarkdownFileName { get; set; }
public string MarkdownFileName { get; set; } = default!;
public string Markdown { get; set; }
private string MarkdownText { get; set; } = "";
protected override async Task OnInitializedAsync() {
Markdown = Markdig.Markdown.ToHtml(await Http.GetStringAsync($"markdown/{MarkdownFileName}.md"));
MarkdownText = Markdig.Markdown.ToHtml(await Http.GetStringAsync($"markdown/{MarkdownFileName}.md"));
}
}

8
Components/Navigation/DesktopNavComponent.razor

@ -100,17 +100,17 @@
#if NO_SQL
[Parameter]
public List<WebSectionModel> WebSections { get; set; }
public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; }
public List<WebPageModel> WebPages { get; set; } = default!;
#else
[Parameter]
public DbSet<WebSectionModel> WebSections { get; set; }
public DbSet<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public DbSet<WebPageModel> WebPages { get; set; }
public DbSet<WebPageModel> WebPages { get; set; } = default!;
#endif
protected override void OnInitialized() {

36
Components/Navigation/MobileNavComponent.razor

@ -4,10 +4,10 @@
@using Microsoft.EntityFrameworkCore
<div class="mobileFooter">
<div class="mobileNavSectionsContainer">
@foreach (var _section in WebSections) {
<div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(_section)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
@foreach (var webSection in WebSections) {
<div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(webSection)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavSectionButtonText">
@_section.Name
@webSection?.Name
</div>
</div>
}
@ -17,18 +17,18 @@
</div>
@if (selectedSection != null) {
var pages = (from page in WebPages
List<WebPageModel?> webPages = (from page in WebPages
where page.WebSectionModelId == selectedSection.Id
select page).ToList();
select page).ToList()!;
<div class="mobileNavPagesContainer">
@foreach (var _page in pages) {
if (_page.IsPrivate.Equals("True")) {
@foreach (var webPage in webPages) {
if (webPage!.IsPrivate.Equals("True")) {
continue;
}
<div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(_page)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(webPage)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavPageButtonText">
@_page.Name
@webPage.Name
</div>
</div>
}
@ -38,7 +38,7 @@
<style>
fullPageButton {
.fullPageButton {
position: fixed;
width: 100vw;
height: 100vh;
@ -140,10 +140,10 @@
@code {
#if NO_SQL
[Parameter]
public List<WebSectionModel> WebSections { get; set; }
public List<WebSectionModel?> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; }
public List<WebPageModel> WebPages { get; set; } = default!;
#else
[Parameter]
@ -154,22 +154,22 @@
#endif
[Inject]
public NavigationManager NavigationManager { get; set; }
public NavigationManager NavigationManager { get; set; } = default!;
public WebSectionModel selectedSection;
public WebPageModel selectedPage;
private WebSectionModel? selectedSection;
private WebPageModel? selectedPage;
void OnSectionClicked(WebSectionModel webSection) {
void OnSectionClicked(WebSectionModel? webSection) {
selectedSection = webSection;
}
void OnPageLinkClicked(WebPageModel webPage) {
void OnPageLinkClicked(WebPageModel? webPage) {
selectedPage = webPage;
selectedSection = null;
NavigationManager.NavigateTo(webPage.Href);
NavigationManager.NavigateTo(webPage?.Href!);
}
void OnPageClicked(EventArgs eventArgs) {

11
Components/Navigation/NavLinkComponent.razor

@ -5,7 +5,7 @@
@inject NavigationManager NavigationManager;
@if (IsOnPage) {
@if (isOnPage) {
<NavLink href="@Page.Href" class="navContainer navLink navSelected">
<div class="navName">
@Page.Name
@ -62,14 +62,15 @@ else {
@code {
[Parameter]
public WebPageModel Page { get; set; }
public WebPageModel Page { get; set; } = default!;
bool IsOnPage = false;
bool isOnPage = false;
protected override async Task OnParametersSetAsync() {
protected override Task OnParametersSetAsync() {
var uri = NavigationManager.Uri.Remove(0, NavigationManager.BaseUri.Count()).ToLower();
IsOnPage = Page.Href.ToLower().Equals(uri);
isOnPage = Page.Href.ToLower().Equals(uri);
return Task.CompletedTask;
}

4
Components/Navigation/NavSectionComponent.razor

@ -50,9 +50,9 @@
@code {
[Parameter]
public WebSectionModel? Section { get; set; }
public WebSectionModel Section { get; set; } = default!;
[Parameter]
public List<WebPageModel>? Children { get; set; }
public List<WebPageModel> Children { get; set; } = default!;
}

16
Components/Navigation/TabletNavComponent.razor

@ -16,11 +16,11 @@
</div>
<div class="fullPageButton @NavOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
<div class="fullPageButton @navOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
</div>
<div class="tabletNav @NavOpen">
<div class="tabletNav @navOpen">
@foreach (var _section in WebSections) {
var pages = (from page in WebPages
where page.WebSectionModelId == _section.Id
@ -144,11 +144,11 @@
#if NO_SQL
[Parameter]
public List<WebSectionModel> WebSections { get; set; }
public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; }
public List<WebPageModel> WebPages { get; set; } = default!;
#else
[Parameter]
public DbSet<WebSectionModel> WebSections { get; set; }
@ -159,15 +159,15 @@
bool NavOpen = true;
bool navOpen = true;
void OnNavClicked(EventArgs eventArgs) {
NavOpen = !NavOpen;
navOpen = !navOpen;
}
void OnPageClicked(EventArgs eventArgs) {
NavOpen = false;
navOpen = false;
}
}

6
Components/Shared/DisplayableContent.razor

@ -7,13 +7,13 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public WebDeploymentType DeploymentType { get; set; }
public WebDeploymentType DeploymentType { get; set; } = default!;
[Inject]
public NavigationManager MyNavigationManager { get; set; }
public NavigationManager MyNavigationManager { get; set; } = default!;
bool isDisplayable;

4
Components/Shared/DisplayableRoute.razor

@ -11,10 +11,10 @@ else {
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Inject]
public NavigationManager MyNavigationManager { get; set; }
public NavigationManager MyNavigationManager { get; set; } = default!;
bool isDisplayable;

4
Components/Shared/MathDivisionComponent.razor

@ -11,9 +11,9 @@
@code {
[Parameter]
public RenderFragment Dividee { get; set; }
public RenderFragment Dividee { get; set; } = default!;
[Parameter]
public RenderFragment Divider { get; set; }
public RenderFragment Divider { get; set; } = default!;
}

6
Components/Shared/MathLoopSumComponent.razor

@ -13,12 +13,12 @@
@code {
[Parameter]
public RenderFragment LoopEnd { get; set; }
public RenderFragment LoopEnd { get; set; } = default!;
[Parameter]
public RenderFragment LoopStart { get; set; }
public RenderFragment LoopStart { get; set; } = default!;
[Parameter]
public RenderFragment IndexSymbol { get; set; }
public RenderFragment IndexSymbol { get; set; } = default!;
}

2
Components/Shared/SpoilerTextComponent.razor

@ -23,6 +23,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
}

34
Contexts/DatabaseContext.cs

@ -3,10 +3,10 @@
#else
using Microsoft.EntityFrameworkCore;
using Model.Documentation;
using Model.Immortal.Notes;
using Model.Doc;
using Model.Notes;
using Model.Website;
using Model.Work.Git;
using Model.Development.Git;
using Model.Work.Tasks;
namespace Contexts;
@ -16,22 +16,18 @@ public class DatabaseContext : DbContext {
Database.EnsureCreated();
}
public DbSet<SprintModel> SprintModels { get; set; }
public DbSet<TaskModel> TaskModels { get; set; }
public DbSet<ChangeModel> ChangeModels { get; set; }
public DbSet<PatchModel> PatchModels { get; set; }
public DbSet<WebPageModel> WebPageModels { get; set; }
public DbSet<WebSectionModel> WebSectionModels { get; set; }
public DbSet<DocumentationModel> DocumentationModels { get; set; }
public DbSet<NoteModel> NoteModels { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder) {
modelBuilder.Entity<PatchModel>();
modelBuilder.Entity<TaskModel>();
base.OnModelCreating(modelBuilder);
}
public DbSet<AgileSprintModel> AgileSprintModels { get; set; } = default!;
public DbSet<AgileTaskModel> AgileTaskModels { get; set; } = default!;
public DbSet<GitChangeModel> GitChangeModels { get; set; } = default!;
public DbSet<GitPatchModel> GitPatchModels { get; set; } = default!;
public DbSet<WebPageModel> WebPageModels { get; set; } = default!;
public DbSet<WebSectionModel> WebSectionModels { get; set; } = default!;
public DbSet<DocContentModel> DocContentModels { get; set; } = default!;
public DbSet<DocConnectionModel> DocConnectionModels { get; set; } = default!;
public DbSet<DocSectionModel> DocSectionModels { get; set; } = default!;
public DbSet<NoteContentModel> NoteContentModels { get; set; } = default!;
public DbSet<NoteConnectionModel> NoteConnectionModels { get; set; } = default!;
public DbSet<NoteSectionModel> NoteSectionModels { get; set; } = default!;
}
#endif

33
IGP/App.razor

@ -17,21 +17,48 @@
<style>
a {
color: #8fc5ff;
color: white;
font-weight: 700;
}
a:hover {
color: #d2f0ff;
color: white;
text-decoration: underline;
text-decoration-color: #8fc5ff;
text-decoration-thickness: 3px;
}
:root {
/* Duplicate Code, to deal with cache issues. See wwwroot/css/app.css for proper :root */
--accent: #432462;
--primary: #4308a3;
--primary-border: #2c0b62;
--primary-hover: #5e00f7;
--primary-border-hover: #a168ff;
--background: #161618;
--secondary: #23133e;
--secondary-hover: #2a0070;
--secondary-border-hover: #a168ff;
--paper: #252526;
--paper-border: #151516;
--paper-hover: #52366f;
--paper-border-hover: #653497;
--info: #451376;
--info-border: #210b36;
--dialog-border-color: black;
--dialog-border-width: 2px;
--dialog-radius: 6px;
}
</style>
@code {
#if NO_SQL
#if NO_SQL
#else
[Inject]

BIN
IGP/Database.db

Binary file not shown.

52
IGP/Dialog/EntityDialogComponent.razor

@ -3,9 +3,9 @@
<div class="dialogBackground" onclick="@CloseDialog">
<div class="dialogContainer"
@onclick:preventDefault="true"
@onclick:stopPropagation="true">
<div class="dialogContainer"
@onclick:preventDefault="true"
@onclick:stopPropagation="true">
@if (entity == null)
{
<div>Entity is null</div>
@ -26,26 +26,26 @@
</div>
<div class="dialogContent">
<CascadingValue Value="@entity">
<EntityVanguardAddedComponent />
<EntityInfoComponent />
<EntityVanguardsComponent />
<EntityProductionComponent />
<EntityStatsComponent />
<EntityMechanicsComponent />
<EntityPassivesComponent />
<EntityPyreSpellsComponent />
<EntityUpgradesComponent />
<EntityWeaponsComponent />
<EntityAbilitiesComponent />
</CascadingValue>
<CascadingValue Value="@entity">
<EntityVanguardAddedComponent/>
<EntityInfoComponent/>
<EntityVanguardsComponent/>
<EntityProductionComponent/>
<EntityStatsComponent/>
<EntityMechanicsComponent/>
<EntityPassivesComponent/>
<EntityPyreSpellsComponent/>
<EntityUpgradesComponent/>
<EntityWeaponsComponent/>
<EntityAbilitiesComponent/>
</CascadingValue>
</div>
<div class="dialogFooter"></div>
}
</div>
</div>
<style>
@ -133,19 +133,20 @@
</style>
@code {
EntityModel entity = null;
EntityModel entity = default!;
private int refresh = 0;
protected override void OnInitialized()
{
entity = DATA.Get()[entityDialogService.GetEntityId()];
entity = DATA.Get()[entityDialogService.GetEntityId() ?? string.Empty];
entityDialogService.Subscribe(OnUpdate);
}
public void Dispose() {
public void Dispose()
{
entityDialogService.Unsubscribe(OnUpdate);
}
@ -157,11 +158,10 @@
Console.WriteLine("OnUpdate()");
StateHasChanged();
}
public void CloseDialog()
{
entityDialogService.CloseDialog();
}
}
}

27
IGP/IGP.csproj

@ -8,32 +8,37 @@
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;NO_SQL</DefineConstants>
<DefineConstants>TRACE;NO_SQL</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>TRACE;NO_SQL</DefineConstants>
<DefineConstants>TRACE;NO_SQL</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.28.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.0-preview.2.22153.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.0-preview.2.22153.2" PrivateAssets="all" />
<PackageReference Include="Markdig" Version="0.28.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="7.0.0-preview.2.22153.2"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="7.0.0-preview.2.22153.2" PrivateAssets="all"/>
<!--
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0-preview.2.22153.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="7.0.0-preview.2.22153.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.0-preview.2.22153.1" />
<NativeFileReference Include="e_sqlite3.o" /> -->
<NativeFileReference Include="e_sqlite3.o" /> -->
</ItemGroup>
<ItemGroup>
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js" />
<ServiceWorker Include="wwwroot\service-worker.js" PublishedContent="wwwroot\service-worker.published.js"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Components\Components.csproj" />
<ProjectReference Include="..\Contexts\Contexts.csproj" />
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Services\Services.csproj" />
<ProjectReference Include="..\Components\Components.csproj"/>
<ProjectReference Include="..\Contexts\Contexts.csproj"/>
<ProjectReference Include="..\Model\Model.csproj"/>
<ProjectReference Include="..\Services\Services.csproj"/>
</ItemGroup>
<ItemGroup>
<Folder Include="wwwroot\generated"/>
</ItemGroup>
</Project>

4
IGP/Index.razor

@ -2,4 +2,8 @@
@layout PageLayout
<DevOnlyComponent>
<DocumentationIndexPage></DocumentationIndexPage>
</DevOnlyComponent>
<HomePage></HomePage>

53
IGP/PageLayout.razor

@ -1,26 +1,26 @@
@inherits LayoutComponentBase;
@inject IWebsiteService WebService;
@inject IWebsiteService webService;
@implements IDisposable;
<div class="layoutContainer" @onclick="OnPageClicked">
@if (!WebService.IsLoaded()) {
<LoadingComponent></LoadingComponent>
} else {
<div class="layoutContainer">
@if (!webService.IsLoaded())
{
<LoadingComponent/>
}
else
{
<div class="content">
@Body
</div>
<DesktopNavComponent WebSections=WebService.WebSectionModels
WebPages=WebService.WebPageModels />
<TabletNavComponent WebSections=WebService.WebSectionModels
WebPages=WebService.WebPageModels />
<MobileNavComponent WebSections=WebService.WebSectionModels
WebPages=WebService.WebPageModels />
<DesktopNavComponent WebSections=webService.WebSectionModels
WebPages=webService.WebPageModels/>
<TabletNavComponent WebSections=webService.WebSectionModels
WebPages=webService.WebPageModels/>
<MobileNavComponent WebSections=webService.WebSectionModels
WebPages=webService.WebPageModels/>
}
</div>
@ -32,32 +32,29 @@
[Inject]
DatabaseContext Database { get; set; }
#endif
bool NavOpen = true;
void OnPageClicked(EventArgs eventArgs) {
NavOpen = false;
}
protected override void OnInitialized() {
WebService.Subscribe(HasChanged);
protected override void OnInitialized()
{
webService.Subscribe(HasChanged);
}
protected override async Task OnInitializedAsync() {
protected override async Task OnInitializedAsync()
{
#if NO_SQL
await WebService.Load();
await webService.Load();
#else
await WebService.Load(Database);
#endif
}
void IDisposable.Dispose() {
WebService.Unsubscribe(HasChanged);
void IDisposable.Dispose()
{
webService.Unsubscribe(HasChanged);
}
void HasChanged() {
void HasChanged()
{
StateHasChanged();
}

77
IGP/Pages/Agile/AgilePage.razor

@ -5,34 +5,39 @@
@page "/agile"
@if (AgileService.IsLoaded()) {
@if (AgileService.IsLoaded())
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Agile</WebsiteTitleComponent>
<div class="agileViewContainer">
@foreach (var sprint in AgileService.SprintModels.OrderBy(e => e.EndDate).Reverse()) {
@foreach (var sprint in AgileService.AgileSprintModels!.OrderBy(e => e.EndDate).Reverse())
{
<details class="sprintDisplayContainer @sprint.GetSprintType().ToLower()" open="@(sprint.GetSprintType() == SprintType.Current)">
<summary class="sprintSummary">
<div class="sprintTitle">@sprint.Name</div>
<div style="flex: 1; flex-grow: 1;"></div>
<div class="sprintDates">
<div class="sprintStartDate">
@if (sprint.StartDate != null)
{
<b>Start: </b>@sprint.StartDate.Value.ToString("dd/MM/yyyy")
}
@if (sprint.StartDate != null)
{
<b>Start: </b>
@sprint.StartDate.Value.ToString("dd/MM/yyyy")
}
</div>
<div class="sprintEndDate">
@if (sprint.EndDate != null)
{
<b>End: </b>@sprint.EndDate.Value.ToString("dd/MM/yyyy")
}
{
<b>End: </b>
@sprint.EndDate.Value.ToString("dd/MM/yyyy")
}
</div>
</div>
</summary>
<SprintComponent Sprint=sprint Tasks=AgileService.TaskModels></SprintComponent>
<SprintComponent AgileSprint="sprint"></SprintComponent>
</details>
}
@ -49,29 +54,31 @@
<ContentDividerComponent></ContentDividerComponent>
<InfoBodyComponent>
<InfoQuestionComponent>What is Agile?</InfoQuestionComponent>
<InfoAnswerComponent>
Agile is a work methodology for determing task assignment and release deadlines.
<br/><br/>
My agile practice will be creating tasks in a backlog. Assigning them to weekly sprints. And completing all tasks in the allotted time frame.
<br/><br/>
Any unfinished tasks are moved into the next sprint, or the sprint will be extended by a week.
</InfoAnswerComponent>
</InfoBodyComponent>
<PaperComponent>
<InfoBodyComponent>
<InfoQuestionComponent>What is Agile?</InfoQuestionComponent>
<InfoAnswerComponent>
Agile is a work methodology for determing task assignment and release deadlines.
<br/><br/>
My agile practice will be creating tasks in a backlog. Assigning them to weekly sprints. And completing all tasks in the allotted time frame.
<br/><br/>
Any unfinished tasks are moved into the next sprint, or the sprint will be extended by a week.
</InfoAnswerComponent>
</InfoBodyComponent>
</PaperComponent>
</LayoutMediumContentComponent>
}
else {
<LoadingComponent></LoadingComponent>
else
{
<LoadingComponent/>
}
@code {
#if NO_SQL
public List<TaskModel> Tasks => AgileService.TaskModels;
public List<SprintModel> Sprints => AgileService.SprintModels;
#else
[Inject]
DatabaseContext Database { get; set; }
@ -83,21 +90,26 @@ else {
public DbSet<SprintModel> Sprints { get; set; }
#endif
private readonly List<TaskModel> backlog = new();
private readonly List<AgileTaskModel> backlog = new();
protected override void OnInitialized() {
protected override void OnInitialized()
{
AgileService.Subscribe(HasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
AgileService.Unsubscribe(HasChanged);
}
void HasChanged() {
void HasChanged()
{
backlog.Clear();
foreach (var task in Tasks) {
if (task.SprintModelId == null) {
foreach (var task in AgileService.AgileTaskModels!)
{
if (task.AgileSprintModelId == null)
{
backlog.Add(task);
}
}
@ -105,7 +117,8 @@ else {
StateHasChanged();
}
protected override async Task OnInitializedAsync() {
protected override async Task OnInitializedAsync()
{
#if NO_SQL
await AgileService.Load();
#else

2
IGP/Pages/Agile/AgilePage.razor.css

@ -7,7 +7,7 @@
.sprintDisplayContainer {
border: 4px solid var(--paper);
box-shadow: 0px 2px 12px rgba(0,0,0,0.2);
box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.2);
border-radius: 2px;
padding: 25px;
margin: auto;

29
IGP/Pages/Agile/Parts/BacklogComponent.razor

@ -1,6 +1,7 @@
<div class="sprintContainer">
<div class="tasksContainer">
@foreach (var task in Backlog) {
@foreach (var task in Backlog)
{
<div class="taskContainer @task.Status.ToLower()">
<div class="taskName">@task.Name</div>
<div class="taskDetails">
@ -17,7 +18,8 @@
</div>
</LayoutColumnComponent>
<LayoutColumnComponent>
@if (task.Finished != null) {
@if (task.Finished != null)
{
<div class="taskFinished">
<b>Finished: </b>@task.Finished
</div>
@ -49,19 +51,6 @@
padding-top: 16px;
}
.sprintDescription {
grid-area: description;
}
.sprintStartDate {
}
.sprintEndDate {
}
.sprintNotes {
}
@@media only screen and (max-width: 1025px) {
.sprintContainer {
@ -73,14 +62,6 @@
box-shadow: none;
padding: 8px;
}
.sprintStartDate {
text-align: left;
}
.sprintEndDate {
text-align: left;
}
}
.tasksContainer {
@ -197,6 +178,6 @@
@code {
[Parameter]
public List<TaskModel> Backlog { get; set; }
public List<AgileTaskModel> Backlog { get; set; } = default!;
}

46
IGP/Pages/Agile/Parts/SprintComponent.razor

@ -1,16 +1,18 @@
<div class="sprintContainer">
<div class="sprintStatus">
<b>Status: </b>@Sprint.GetSprintType()
<b>Status: </b>@AgileSprint.GetSprintType()
</div>
<div class="sprintDescription">
<b>Description: </b>@Sprint.Description
<b>Description: </b>@AgileSprint.Description
</div>
<div class="sprintNotes">
<b>Notes: </b>@Sprint.Notes
<b>Notes: </b>@AgileSprint.Notes
</div>
<div class="tasksContainer">
@if (selectedTasks.Count > 0) {
@foreach (var task in selectedTasks) {
@if (AgileSprint.AgileTaskModels.Count > 0)
{
@foreach (var task in AgileSprint.AgileTaskModels)
{
<div class="taskContainer @task.Status.ToLower() @task.Task.ToLower()">
<div class="taskName">@task.Name</div>
<div class="taskDetails">
@ -28,13 +30,14 @@
</LayoutColumnComponent>
<LayoutColumnComponent>
@if (task.Finished != null) {
@if (task.Finished != null)
{
<div class="taskFinished">
<b>Finished: </b>@task.Finished.Value.ToString("dd/MM/yyyy")
</div>
}
<div class="taskCreated">
<b>Created: </b>@task.Created.Value.ToString("dd/MM/yyyy")
<b>Created: </b>@task.Created!.Value.ToString("dd/MM/yyyy")
</div>
</LayoutColumnComponent>
</LayoutRowComponent>
@ -48,7 +51,8 @@
</div>
}
}
else {
else
{
<div>Add Tasks...</div>
}
</div>
@ -66,14 +70,6 @@
grid-area: description;
}
.sprintStartDate {
}
.sprintEndDate {
}
.sprintNotes {
}
@@media only screen and (max-width: 1025px) {
@ -221,23 +217,7 @@
@code {
#if NO_SQL
[Parameter]
public List<TaskModel> Tasks { get; set; }
#else
[Parameter]
public DbSet<TaskModel> Tasks { get; set; }
#endif
[Parameter]
public SprintModel Sprint { get; set; }
private List<TaskModel> selectedTasks { get; set; }
protected override void OnInitialized() {
selectedTasks = (from task in Tasks
where task.SprintModelId == Sprint.Id
select task).OrderBy(x => x.Created).OrderBy(x => x.Finished).Reverse().OrderBy(x => x.Status).ToList();
}
public AgileSprintModel AgileSprint { get; set; } = default!;
}

106
IGP/Pages/BuildCalculator/BuildCalculatorPage.razor

@ -2,6 +2,12 @@
@layout PageLayout
@inject IKeyService keyService
@inject IImmortalSelectionService filterService
@inject IBuildOrderService buildOrderService
@inject IEconomyService economyService
@inject ITimingService timingService
@page "/build-calculator"
<LayoutLargeContentComponent>
@ -20,19 +26,15 @@
<div class="calculatorGrid">
<div style="grid-area: timing;" class="gridItem">
<InfoTooltipComponent InfoText="Enter build details.
<b>Timing Interval:</b> set the max interval length for the build. <i>Ex. 240 (seconds) is 4 minutes, a possible timing for Thrum build order.</i>
<b>Name:</b> the name of the build for saving purposes. <i>Ex. 'Safe Thrum Opener'</i>
<b>Notes:</b> additional notes of the build for saving purposes. <i>Ex. 'Thrums are for harassing and defending against a ground Q'Rath army.'</i>
<b>Color:</b> value to color charts when comparing builds. Not currently implemented.">
<InfoTooltipComponent InfoText="">
<TimingComponent></TimingComponent>
</InfoTooltipComponent>
</div>
@if (true) {
@if (true)
{
<div style="grid-area: chart;" class="gridItem">
<InfoTooltipComponent InfoText="Shows economy at each game interval. Use to determine if spending additional resourcses on harvesters will help or hinder overall timing attack.">
<ChartComponent></ChartComponent>
@ -70,18 +72,15 @@
<div class="gridItem gridKeys">
<InfoTooltipComponent InfoText="Click on the desired entity to build it. <i>You cannot build entities you cannot afford, construct an ether extractor before spending ether.</i>
You can also use the default Immortal hotkeys, but the above hotkey UI must have focus for this to work. <i>I.e. click on it if hotkeys aren't working, and a white border should appear after key input to indicate focus.</i>
Additionally, more entities will appear as you build the required technology. You can click or press ` to remove the last made entity. <i>But you cannot remove the starting entities at interval 0.</i>">
<InfoTooltipComponent InfoText="">
<HotkeyViewerComponent Size="80"></HotkeyViewerComponent>
</InfoTooltipComponent>
</div>
@if (false) {
@if (false)
{
<div style="grid-area: timeline;" class="gridItem">
<TimelineComponent></TimelineComponent>
</div>
@ -216,72 +215,59 @@ Additionally, more entities will appear as you build the required technology. Yo
@code {
[Inject]
IKeyService KeyService { get; set; }
[Inject]
IImmortalSelectionService FilterService { get; set; }
[Inject]
IBuildOrderService BuildOrderService { get; set; }
[Inject]
IEconomyService EconomyService { get; set; }
[Inject]
ITimingService TimingService { get; set; }
Dictionary<int, List<EntityModel>> completedEntities = new();
List<EntityModel> entities = EntityModel.GetListOnlyHotkey();
protected override void OnInitialized() {
KeyService.Subscribe(HandleClick);
FilterService.Subscribe(StateHasChanged);
EconomyService.Subscribe(StateHasChanged);
TimingService.Subscribe(HandleTimingChanged);
EconomyService.Calculate(BuildOrderService, TimingService, 0);
protected override void OnInitialized()
{
keyService.Subscribe(HandleClick);
filterService.Subscribe(StateHasChanged);
economyService.Subscribe(StateHasChanged);
timingService.Subscribe(HandleTimingChanged);
economyService.Calculate(buildOrderService, timingService, 0);
}
void IDisposable.Dispose() {
KeyService.Unsubscribe(HandleClick);
FilterService.Unsubscribe(StateHasChanged);
TimingService.Unsubscribe(StateHasChanged);
EconomyService.Unsubscribe(StateHasChanged);
void IDisposable.Dispose()
{
keyService.Unsubscribe(HandleClick);
filterService.Unsubscribe(StateHasChanged);
timingService.Unsubscribe(StateHasChanged);
economyService.Unsubscribe(StateHasChanged);
}
protected void HandleTimingChanged() {
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
private void HandleTimingChanged()
{
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
}
protected void HandleClick() {
var hotkey = KeyService.GetHotkey();
private void HandleClick()
{
var hotkey = keyService.GetHotkey();
if (hotkey == "") {
if (hotkey == "")
{
return;
}
if (hotkey == "`") {
BuildOrderService.RemoveLast();
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
if (hotkey == "`")
{
buildOrderService.RemoveLast();
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
StateHasChanged();
return;
}
var hotkeyGroup = KeyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace();
var faction = FilterService.GetFactionType();
var immortal = FilterService.GetImmortalType();
var hotkeyGroup = keyService.GetHotkeyGroup();
var isHoldSpace = keyService.IsHoldingSpace();
var faction = filterService.GetFactionType();
var immortal = filterService.GetImmortalType();
var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (entity == null) {
if (entity == null)
{
return;
}
if (BuildOrderService.Add(entity, EconomyService)) {
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
if (buildOrderService.Add(entity, economyService))
{
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
}
}

37
IGP/Pages/BuildCalculator/Parts/ArmyComponent.razor

@ -2,12 +2,13 @@
<FormLayoutComponent>
<FormDisplayComponent Label="Army ready at">
<Display>@LastInterval | T @Interval.ToTime(LastInterval)</Display>
<Display>@lastInterval | T @Interval.ToTime(lastInterval)</Display>
</FormDisplayComponent>
<FormDisplayComponent Label="Army units built">
<Display>
<div style="display: flex; width: 100%; gap: 12px; flex-wrap: wrap;">
@foreach (var unit in armyCount) {
@foreach (var unit in armyCount)
{
<div style="width:90px; height: 60px; border: 1px solid gray; padding: 8px;">
<div>@unit.Value.ToString()x</div>
<div>@unit.Key</div>
@ -22,38 +23,46 @@
@code {
[Inject]
public IBuildOrderService BuildOrder { get; set; }
public IBuildOrderService BuildOrder { get; set; } = default!;
int LastInterval;
private int lastInterval;
readonly Dictionary<string, int> armyCount = new();
List<EntityModel> army = new();
protected override void OnInitialized() {
protected override void OnInitialized()
{
BuildOrder.Subscribe(OnBuildOrderChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
BuildOrder.Unsubscribe(OnBuildOrderChanged);
}
void OnBuildOrderChanged() {
void OnBuildOrderChanged()
{
armyCount.Clear();
LastInterval = 0;
lastInterval = 0;
var entitiesOverTime = BuildOrder.GetOrders();
foreach (var entitiesAtTime in entitiesOverTime) {
foreach (var entity in entitiesAtTime.Value) {
if (entity.EntityType == EntityType.Army) {
if (!armyCount.TryAdd(entity.Info().Name, 1)) {
foreach (var entitiesAtTime in entitiesOverTime)
{
foreach (var entity in entitiesAtTime.Value)
{
if (entity.EntityType == EntityType.Army)
{
if (!armyCount.TryAdd(entity.Info().Name, 1))
{
armyCount[entity.Info().Name]++;
}
if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > LastInterval) {
LastInterval = entity.Production().BuildTime + entitiesAtTime.Key;
if (entity.Production() != null && entity.Production().BuildTime + entitiesAtTime.Key > lastInterval)
{
lastInterval = entity.Production().BuildTime + entitiesAtTime.Key;
}
}
}

16
IGP/Pages/BuildCalculator/Parts/BankComponent.razor

@ -23,27 +23,30 @@
@code {
[Inject]
IBuildOrderService BuildOrderService { get; set; }
IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject]
IEconomyService EconomyService { get; set; }
IEconomyService EconomyService { get; set; } = default!;
EconomyModel economy = new();
int supplyGranted;
int supplyTaken;
int extraBuildings;
protected override void OnInitialized() {
protected override void OnInitialized()
{
BuildOrderService.Subscribe(OnBuildOrderChanged);
EconomyService.Subscribe(OnBuildOrderChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
BuildOrderService.Unsubscribe(OnBuildOrderChanged);
EconomyService.Subscribe(OnBuildOrderChanged);
}
void OnBuildOrderChanged() {
void OnBuildOrderChanged()
{
economy = EconomyService.GetEconomy(BuildOrderService.GetLastRequestInterval());
var ordersOverTime = BuildOrderService.GetOrders();
@ -61,7 +64,8 @@
select order.Supply().Grants).Sum();
extraBuildings = 0;
if (supplyGranted > 160) {
if (supplyGranted > 160)
{
extraBuildings = (supplyGranted - 160) / 16;
supplyGranted = 160;
}

19
IGP/Pages/BuildCalculator/Parts/BuildOrderComponent.razor

@ -1,23 +1,24 @@
@implements IDisposable
@inject IBuildOrderService buildOrderService
@implements IDisposable
<FormLayoutComponent>
<FormTextAreaComponent Label="JSON Data"
Rows="14"
Value="@BuildOrderService.AsJson()">
Value="@buildOrderService.AsJson()">
</FormTextAreaComponent>
</FormLayoutComponent>
@code {
[Inject]
IBuildOrderService BuildOrderService { get; set; }
protected override void OnInitialized() {
BuildOrderService.Subscribe(StateHasChanged);
protected override void OnInitialized()
{
buildOrderService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
BuildOrderService.Unsubscribe(StateHasChanged);
void IDisposable.Dispose()
{
buildOrderService.Unsubscribe(StateHasChanged);
}
}

61
IGP/Pages/BuildCalculator/Parts/ChartComponent.razor

@ -1,10 +1,12 @@
@implements IDisposable
<div class="chartsContainer">
@foreach (var chart in charts) {
@foreach (var chart in charts)
{
<div style="width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
<div style="position: relative; border: 2px solid gray; border-radius:2px; width: @chart.IntervalDisplayMax.ToString()px; height: @chart.ValueDisplayMax.ToString()px">
@foreach (var point in chart.Points) {
@foreach (var point in chart.Points)
{
<div style="position: absolute;
bottom:@point.GetValue(chart.HighestValuePoint, chart.ValueDisplayMax)px;
left:@point.GetInterval(chart.HighestIntervalPoint, chart.IntervalDisplayMax)px;
@ -51,10 +53,10 @@
@code {
[Inject]
IEconomyService EconomyService { get; set; }
IEconomyService EconomyService { get; set; } = default!;
[Inject]
IBuildOrderService BuildOrderService { get; set; }
IBuildOrderService BuildOrderService { get; set; } = default!;
int height = 100;
@ -70,43 +72,50 @@
float highestPyrePoint;
float highestArmyPoint;
protected override void OnInitialized() {
protected override void OnInitialized()
{
EconomyService.Subscribe(GenerateChart);
BuildOrderService.Subscribe(GenerateChart);
GenerateChart();
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
EconomyService.Unsubscribe(GenerateChart);
BuildOrderService.Unsubscribe(GenerateChart);
}
void GenerateChart() {
void GenerateChart()
{
var economyOverTime = EconomyService.GetOverTime();
charts.Clear();
var alloyChart = new ChartModel {
var alloyChart = new ChartModel
{
IntervalDisplayMax = width,
ValueDisplayMax = 100,
ChartColor = "Cyan"
};
var etherChart = new ChartModel {
var etherChart = new ChartModel
{
Offset = width,
IntervalDisplayMax = width,
ValueDisplayMax = 100,
ChartColor = "LightGreen"
};
var pyreChart = new ChartModel {
var pyreChart = new ChartModel
{
Offset = width * 2,
IntervalDisplayMax = width,
ValueDisplayMax = 100,
ChartColor = "Red"
};
var armyChart = new ChartModel {
var armyChart = new ChartModel
{
Offset = width * 3,
IntervalDisplayMax = width,
ValueDisplayMax = 100,
@ -118,13 +127,15 @@
highestPyrePoint = 0;
highestArmyPoint = 0;
for (var interval = 0; interval < economyOverTime.Count(); interval++) {
for (var interval = 0; interval < economyOverTime.Count(); interval++)
{
var army = from unit in BuildOrderService.GetCompletedBefore(interval)
where unit.EntityType == EntityType.Army
select unit;
var armyValue = 0;
foreach (var unit in army) {
foreach (var unit in army)
{
armyValue += unit.Production().Alloy + unit.Production().Ether;
}
@ -135,7 +146,8 @@
}
for (var interval = 0; interval < economyOverTime.Count(); interval++) {
for (var interval = 0; interval < economyOverTime.Count(); interval++)
{
var alloyPoint = new PointModel { Interval = interval };
var etherPoint = new PointModel { Interval = interval };
var pyrePoint = new PointModel { Interval = interval };
@ -167,26 +179,32 @@
float economySpending = 0;
foreach (var alloyAutoHarvester in alloyAutomaticHarvesters) {
foreach (var alloyAutoHarvester in alloyAutomaticHarvesters)
{
autoAlloy += alloyAutoHarvester.Harvest().Slots * alloyAutoHarvester.Harvest().HarvestedPerInterval;
var production = alloyAutoHarvester.Production();
if (production != null) {
if (production != null)
{
economySpending += production.Alloy;
}
}
foreach (var alloyWorkerHarvester in alloyWorkerHarvesters) {
foreach (var alloyWorkerHarvester in alloyWorkerHarvesters)
{
workerSlots += alloyWorkerHarvester.Harvest().Slots;
var production = alloyWorkerHarvester.Production();
if (production != null) {
if (production != null)
{
economySpending += production.Alloy;
}
}
foreach (var etherWorkerHarvester in etherAutomaticHarvesters) {
foreach (var etherWorkerHarvester in etherAutomaticHarvesters)
{
autoEther += etherWorkerHarvester.Harvest().Slots * etherWorkerHarvester.Harvest().HarvestedPerInterval;
var production = etherWorkerHarvester.Production();
if (production != null) {
if (production != null)
{
economySpending += production.Alloy;
}
}
@ -200,7 +218,8 @@
etherPoint.Value = autoEther;
if (interval > 0) {
if (interval > 0)
{
alloyPoint.TempValue += alloyChart.Points.Last().TempValue;
etherPoint.Value += etherChart.Points.Last().Value;
pyrePoint.Value = pyreChart.Points.Last().Value + 1;

28
IGP/Pages/BuildCalculator/Parts/EntityClickViewComponent.razor

@ -1,35 +1,39 @@
@implements IDisposable
<div style="overflow-y: scroll; width: 100%; overflow-x: hidden; height: 550px;">
@if (Entity != null) {
@if (entity != null)
{
<EntityViewComponent Entity=Entity></EntityViewComponent>
}
</div>
@code {
EntityModel Entity;
private EntityModel entity = default!;
[Inject]
IKeyService KeyService { get; set; }
IKeyService KeyService { get; set; } = default!;
[Inject]
IImmortalSelectionService FilterService { get; set; }
IImmortalSelectionService FilterService { get; set; } = default!;
[Inject]
IBuildOrderService BuildOrderService { get; set; }
IBuildOrderService BuildOrderService { get; set; } = default!;
protected override void OnInitialized() {
protected override void OnInitialized()
{
KeyService.Subscribe(HandleClick);
BuildOrderService.Subscribe(OnBuildOrderChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
KeyService.Unsubscribe(HandleClick);
BuildOrderService.Unsubscribe(OnBuildOrderChanged);
}
protected void HandleClick() {
protected void HandleClick()
{
var hotkey = KeyService.GetHotkey();
var hotkeyGroup = KeyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace();
@ -38,13 +42,15 @@
var foundEntity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (foundEntity != null) {
Entity = foundEntity;
if (foundEntity != null)
{
entity = foundEntity;
StateHasChanged();
}
}
void OnBuildOrderChanged() {
void OnBuildOrderChanged()
{
StateHasChanged();
}

18
IGP/Pages/BuildCalculator/Parts/FilterComponent.razor

@ -10,11 +10,13 @@
<FormSelectComponent OnChange="@OnImmortalChanged">
<FormLabelComponent>Immortal</FormLabelComponent>
<ChildContent>
@if (FilterService.GetFactionType() == FactionType.QRath) {
@if (FilterService.GetFactionType() == FactionType.QRath)
{
<option value="@ImmortalType.Orzum" selected>Orzum</option>
<option value="@ImmortalType.Ajari">Ajari</option>
}
@if (FilterService.GetFactionType() == FactionType.Aru) {
@if (FilterService.GetFactionType() == FactionType.Aru)
{
<option value="@ImmortalType.Mala" selected>Mala</option>
<option value="@ImmortalType.Xol">Xol</option>
}
@ -25,14 +27,16 @@
@code {
[Inject]
public IImmortalSelectionService FilterService { get; set; }
public IImmortalSelectionService FilterService { get; set; } = default!;
void OnFactionChanged(ChangeEventArgs e) {
FilterService.SelectFactionType(e.Value.ToString());
void OnFactionChanged(ChangeEventArgs e)
{
FilterService.SelectFactionType(e.Value!.ToString()!);
}
void OnImmortalChanged(ChangeEventArgs e) {
FilterService.SelectImmortalType(e.Value.ToString());
void OnImmortalChanged(ChangeEventArgs e)
{
FilterService.SelectImmortalType(e.Value!.ToString()!);
}
}

30
IGP/Pages/BuildCalculator/Parts/HighlightsComponent.razor

@ -4,9 +4,12 @@
<div>
<div>Requested</div>
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--) {
@foreach (var order in BuildOrderService.GetOrdersAt(i)) {
if (order.EntityType == EntityType.Worker) {
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--)
{
@foreach (var order in BuildOrderService.GetOrdersAt(i))
{
if (order.EntityType == EntityType.Worker)
{
continue;
}
<div>
@ -22,9 +25,12 @@
<div>
<div>Finished</div>
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--) {
@foreach (var order in BuildOrderService.GetCompletedAt(i)) {
if (order.EntityType == EntityType.Worker) {
@for (var i = TimingService.GetTiming() - 1; i >= 0; i--)
{
@foreach (var order in BuildOrderService.GetCompletedAt(i))
{
if (order.EntityType == EntityType.Worker)
{
continue;
}
<div>
@ -54,20 +60,22 @@
@code {
[Inject]
IEconomyService EconomyService { get; set; }
IEconomyService EconomyService { get; set; } = default!;
[Inject]
IBuildOrderService BuildOrderService { get; set; }
IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject]
ITimingService TimingService { get; set; }
ITimingService TimingService { get; set; } = default!;
protected override void OnInitialized() {
protected override void OnInitialized()
{
EconomyService.Subscribe(StateHasChanged);
BuildOrderService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
EconomyService.Unsubscribe(StateHasChanged);
BuildOrderService.Unsubscribe(StateHasChanged);
}

131
IGP/Pages/BuildCalculator/Parts/HotkeyViewerComponent.razor

@ -2,8 +2,10 @@
<InputPanelComponent>
<div class="keyContainer">
@foreach (var hotkey in hotkeys) {
if (hotkey.IsHidden) {
@foreach (var hotkey in hotkeys)
{
if (hotkey.IsHidden)
{
continue;
}
@ -14,14 +16,17 @@
var y = hotkey.PositionY * Size;
var border = "1px solid black";
if (hotkey.KeyText.Equals(_key)) {
if (hotkey.KeyText.Equals(_key))
{
border = "5px solid black";
}
if (hotkey.KeyText.Equals(_controlGroup)) {
if (hotkey.KeyText.Equals(_controlGroup))
{
border = "5px solid green";
}
if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace()) {
if (hotkey.KeyText.Equals("SPACE") && KeyService.IsHoldingSpace())
{
border = "5px solid green";
}
@ -39,16 +44,20 @@
overflow: hidden;
padding: 4px;">
@hotkey.KeyText
@foreach (var entity in data.Values) {
if (!BuildOrderService.MeetsRequirements(entity, 9000)) {
@foreach (var entity in data.Values)
{
if (!BuildOrderService.MeetsRequirements(entity, 9000))
{
continue;
}
if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity)) {
if (InvalidKey(entity, hotkey) || InvalidKeyGroup(entity, hotkey) || InvalidHoldSpace(entity))
{
continue;
}
if (InvalidFaction(entity) || InvalidVanguard(entity) || InvalidNonVanguard(entity)) {
if (InvalidFaction(entity) || InvalidVanguard(entity) || InvalidNonVanguard(entity))
{
continue;
}
@ -77,7 +86,7 @@
@@media only screen and (max-width: 1025px) {
.keyContainer {
transform: scale(0.85) translateX(-20px);
background-color: none;
background-color: transparent;
outline: none;
}
}
@ -89,13 +98,13 @@
public int Size { get; set; } = 100;
[Inject]
public IKeyService KeyService { get; set; }
public IKeyService KeyService { get; set; } = default!;
[Inject]
public IBuildOrderService BuildOrderService { get; set; }
public IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject]
public IImmortalSelectionService FilterService { get; set; }
public IImmortalSelectionService FilterService { get; set; } = default!;
readonly Dictionary<string, EntityModel> data = EntityModel.GetDictionary();
readonly List<HotkeyModel> hotkeys = HotkeyModel.GetAll();
@ -103,21 +112,25 @@
public string _controlGroup = "C";
public string _key = "";
protected override void OnInitialized() {
protected override void OnInitialized()
{
base.OnInitialized();
KeyService.Subscribe(OnKeyPressed);
FilterService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
KeyService.Unsubscribe(OnKeyPressed);
FilterService.Unsubscribe(StateHasChanged);
}
// Move to Filter Service
bool InvalidFaction(EntityModel entity) {
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFactionType() && FilterService.GetFactionType() != FactionType.Any) {
bool InvalidFaction(EntityModel entity)
{
if (entity.Faction() != null && entity.Faction()?.Faction != FilterService.GetFactionType() && FilterService.GetFactionType() != FactionType.Any)
{
return true;
}
@ -125,8 +138,10 @@
}
// Move to Filter Service
bool InvalidVanguard(EntityModel entity) {
if (entity.VanguardAdded() != null && entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortalType() && FilterService.GetImmortalType() != ImmortalType.Any) {
bool InvalidVanguard(EntityModel entity)
{
if (entity.VanguardAdded() != null && entity.VanguardAdded()?.ImmortalId != FilterService.GetImmortalType() && FilterService.GetImmortalType() != ImmortalType.Any)
{
return true;
}
@ -134,16 +149,21 @@
}
// Move to Filter Service
bool InvalidNonVanguard(EntityModel entity) {
if (entity.Replaceds().Count > 0) {
bool InvalidNonVanguard(EntityModel entity)
{
if (entity.Replaceds().Count > 0)
{
var isReplaced = false;
foreach (var replaced in entity.Replaceds()) {
if (FilterService.GetImmortalType() == replaced.ImmortalId) {
foreach (var replaced in entity.Replaceds())
{
if (FilterService.GetImmortalType() == replaced.ImmortalId)
{
isReplaced = true;
break;
}
}
if (isReplaced) {
if (isReplaced)
{
return true;
}
}
@ -151,75 +171,96 @@
return false;
}
bool InvalidRequirements(EntityModel entity) {
bool InvalidRequirements(EntityModel entity)
{
return !BuildOrderService.MeetsRequirements(entity, 9000);
}
bool InvalidKey(EntityModel entity, HotkeyModel key) {
if (entity.Hotkey()?.Hotkey == key.KeyText) {
bool InvalidKey(EntityModel entity, HotkeyModel key)
{
if (entity.Hotkey()?.Hotkey == key.KeyText)
{
return false;
}
return true;
}
bool InvalidKeyGroup(EntityModel entity, HotkeyModel key) {
if (entity.Hotkey()?.HotkeyGroup == _controlGroup) {
bool InvalidKeyGroup(EntityModel entity, HotkeyModel key)
{
if (entity.Hotkey()?.HotkeyGroup == _controlGroup)
{
return false;
}
return true;
}
bool InvalidKey(EntityModel entity) {
if (entity.Hotkey()?.Hotkey == _key) {
bool InvalidKey(EntityModel entity)
{
if (entity.Hotkey()?.Hotkey == _key)
{
return false;
}
return true;
}
bool InvalidKeyGroup(EntityModel entity) {
if (entity.Hotkey()?.HotkeyGroup == _controlGroup) {
bool InvalidKeyGroup(EntityModel entity)
{
if (entity.Hotkey()?.HotkeyGroup == _controlGroup)
{
return false;
}
return true;
}
bool InvalidHoldSpace(EntityModel entity) {
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace()) {
bool InvalidHoldSpace(EntityModel entity)
{
if (entity.Hotkey()?.HoldSpace == KeyService.IsHoldingSpace())
{
return false;
}
return true;
}
void OnKeyPressed() {
if (KeyService.GetAllPressedKeys().Contains("Z")) {
void OnKeyPressed()
{
if (KeyService.GetAllPressedKeys().Contains("Z"))
{
_controlGroup = "Z";
}
if (KeyService.GetAllPressedKeys().Contains("TAB")) {
if (KeyService.GetAllPressedKeys().Contains("TAB"))
{
_controlGroup = "TAB";
}
if (KeyService.GetAllPressedKeys().Contains("C")) {
if (KeyService.GetAllPressedKeys().Contains("C"))
{
_controlGroup = "C";
}
if (KeyService.GetAllPressedKeys().Contains("D")) {
if (KeyService.GetAllPressedKeys().Contains("D"))
{
_controlGroup = "D";
}
if (KeyService.GetAllPressedKeys().Contains("1")) {
if (KeyService.GetAllPressedKeys().Contains("1"))
{
_controlGroup = "1";
}
//TODO This could be better. Duplicated code
if (KeyService.GetAllPressedKeys().Contains("2")) {
if (KeyService.GetAllPressedKeys().Contains("2"))
{
_controlGroup = "2";
}
if (KeyService.GetAllPressedKeys().Contains("SHIFT")) {
if (KeyService.GetAllPressedKeys().Contains("SHIFT"))
{
_controlGroup = "SHIFT";
}
if (KeyService.GetAllPressedKeys().Contains("CONTROL")) {
if (KeyService.GetAllPressedKeys().Contains("CONTROL"))
{
_controlGroup = "CONTROL";
}
if (KeyService.GetAllPressedKeys().Count > 0) {
if (KeyService.GetAllPressedKeys().Count > 0)
{
_key = KeyService.GetAllPressedKeys().First();
}

10
IGP/Pages/BuildCalculator/Parts/InputPanelComponent.razor

@ -10,16 +10,18 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
public RenderFragment ChildContent { get; set; } = default!;
[Inject]
public IKeyService KeyService { get; set; }
public IKeyService KeyService { get; set; } = default!;
private void HandleKeyDown(KeyboardEventArgs e) {
private void HandleKeyDown(KeyboardEventArgs e)
{
KeyService.AddPressedKey(e.Key);
}
private void HandleKeyUp(KeyboardEventArgs e) {
private void HandleKeyUp(KeyboardEventArgs e)
{
KeyService.RemovePressedKey(e.Key);
}

16
IGP/Pages/BuildCalculator/Parts/TimelineComponent.razor

@ -24,12 +24,14 @@
<br/>
</div>
<div>
@foreach (var order in BuildOrderService.GetOrdersAt(economyAtSecond.Interval)) {
@foreach (var order in BuildOrderService.GetOrdersAt(economyAtSecond.Interval))
{
<div>
Requested: @order.Info().Name
</div>
}
@foreach (var order in BuildOrderService.GetCompletedAt(economyAtSecond.Interval)) {
@foreach (var order in BuildOrderService.GetCompletedAt(economyAtSecond.Interval))
{
<div>
New: @order.Info().Name
</div>
@ -42,17 +44,19 @@
@code {
[Inject]
IEconomyService EconomyService { get; set; }
IEconomyService EconomyService { get; set; } = default!;
[Inject]
IBuildOrderService BuildOrderService { get; set; }
IBuildOrderService BuildOrderService { get; set; } = default!;
protected override void OnInitialized() {
protected override void OnInitialized()
{
EconomyService.Subscribe(StateHasChanged);
BuildOrderService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
EconomyService.Unsubscribe(StateHasChanged);
BuildOrderService.Unsubscribe(StateHasChanged);
}

27
IGP/Pages/BuildCalculator/Parts/TimingComponent.razor

@ -20,31 +20,36 @@
@code {
[Inject]
public ITimingService TimingService { get; set; }
public ITimingService TimingService { get; set; } = default!;
[Inject]
public IBuildOrderService BuildOrderService { get; set; }
public IBuildOrderService BuildOrderService { get; set; } = default!;
void OnTimingChanged(ChangeEventArgs changeEventArgs) {
TimingService.SetTiming(int.Parse(changeEventArgs.Value.ToString()));
void OnTimingChanged(ChangeEventArgs changeEventArgs)
{
TimingService.SetTiming(int.Parse(changeEventArgs.Value!.ToString()!));
}
void OnTimingChanged(int value) {
void OnTimingChanged(int value)
{
TimingService.SetTiming(value);
}
void OnNameChanged(ChangeEventArgs changeEventArgs) {
BuildOrderService.SetName(changeEventArgs.Value.ToString());
void OnNameChanged(ChangeEventArgs changeEventArgs)
{
BuildOrderService.SetName(changeEventArgs.Value!.ToString()!);
}
void OnColorChanged(ChangeEventArgs changeEventArgs) {
BuildOrderService.SetColor(changeEventArgs.Value.ToString());
void OnColorChanged(ChangeEventArgs changeEventArgs)
{
BuildOrderService.SetColor(changeEventArgs.Value!.ToString()!);
}
void OnNotesChanged(ChangeEventArgs changeEventArgs) {
BuildOrderService.SetNotes(changeEventArgs.Value.ToString());
void OnNotesChanged(ChangeEventArgs changeEventArgs)
{
BuildOrderService.SetNotes(changeEventArgs.Value!.ToString()!);
}
}

54
IGP/Pages/ChangeLogPage.razor

@ -5,7 +5,8 @@
@layout PageLayout
@if (GitService.IsLoaded()) {
@if (GitService.IsLoaded())
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Change Log</WebsiteTitleComponent>
@ -20,8 +21,10 @@
</PaperComponent>
<PaperComponent>
@foreach (var patch in Patches.OrderBy(x => x.Date).Reverse()) {
@if (!patch.Important.Equals("True") && isViewImportant) {
@foreach (var patch in Patches.OrderBy(x => x.Date).Reverse())
{
@if (!patch.Important.Equals("True") && isViewImportant)
{
continue;
}
@ -33,21 +36,26 @@
@patch.Name
</div>
<div>
@if (daysAgo == 0) {
@if (daysAgo == 0)
{
<i>Today</i>
}
else if (daysAgo < 8) {
else if (daysAgo < 8)
{
<i>@daysAgo days ago</i>
}
else {
else
{
<i>@patch.Date.ToString("dd/MM/yyyy")</i>
}
</div>
</div>
<div>
@foreach (var change in Changes.FindAll(e => e.PatchModelId == patch.Id)) {
@if (!change.Important.Equals("True") && isViewImportant) {
@foreach (var change in Changes.FindAll(e => e.GitPatchModelId == patch.Id))
{
@if (!change.Important.Equals("True") && isViewImportant)
{
continue;
}
@ -57,7 +65,8 @@
<b>
<span>- @change.Name </span>
@if (change.Commit != CommitType.None) {
@if (change.Commit != CommitType.None)
{
<span>(@change.Commit)</span>
}
<span>: </span>
@ -68,23 +77,23 @@
}
</div>
</div>
}
</PaperComponent>
</LayoutMediumContentComponent>
}
else {
<LoadingComponent></LoadingComponent>
else
{
<LoadingComponent/>
}
@code {
#if NO_SQL
public List<PatchModel> Patches => GitService.PatchModels;
public List<GitPatchModel> Patches => GitService.GitPatchModels;
public List<ChangeModel> Changes => GitService.ChangeModels;
public List<GitChangeModel> Changes => GitService.GitChangeModels;
#else
[Inject]
DatabaseContext Database { get; set; }
@ -99,24 +108,29 @@ else {
private bool isViewImportant = true;
protected override void OnInitialized() {
protected override void OnInitialized()
{
GitService.Subscribe(HasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
GitService.Unsubscribe(HasChanged);
}
void OnChangeClicked(ChangeEventArgs changeEventArgs) {
isViewImportant = (bool)changeEventArgs.Value;
void OnChangeClicked(ChangeEventArgs changeEventArgs)
{
isViewImportant = (bool)changeEventArgs.Value!;
}
void HasChanged() {
void HasChanged()
{
StateHasChanged();
}
protected override async Task OnInitializedAsync() {
protected override async Task OnInitializedAsync()
{
#if NO_SQL
GitService.Load();
#else

31
IGP/Pages/Comparision/ComparisionPage.razor

@ -28,19 +28,19 @@ grid-template-areas: 'loader sand compare compare' ;">
@code {
[Inject]
IKeyService KeyService { get; set; }
IKeyService KeyService { get; set; } = default!;
[Inject]
IImmortalSelectionService FilterService { get; set; }
IImmortalSelectionService FilterService { get; set; } = default!;
[Inject]
IBuildOrderService BuildOrderService { get; set; }
IBuildOrderService BuildOrderService { get; set; } = default!;
[Inject]
IEconomyService EconomyService { get; set; }
IEconomyService EconomyService { get; set; } = default!;
[Inject]
ITimingService TimingService { get; set; }
ITimingService TimingService { get; set; } = default!;
Dictionary<int, List<EntityModel>> completedEntities = new();
@ -48,7 +48,8 @@ grid-template-areas: 'loader sand compare compare' ;">
List<EntityModel> entities = EntityModel.GetListOnlyHotkey();
protected override void OnInitialized() {
protected override void OnInitialized()
{
KeyService.Subscribe(HandleClick);
FilterService.Subscribe(StateHasChanged);
EconomyService.Subscribe(StateHasChanged);
@ -56,7 +57,8 @@ grid-template-areas: 'loader sand compare compare' ;">
EconomyService.Calculate(BuildOrderService, TimingService, 0);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
KeyService.Unsubscribe(HandleClick);
FilterService.Unsubscribe(StateHasChanged);
TimingService.Unsubscribe(StateHasChanged);
@ -64,18 +66,21 @@ grid-template-areas: 'loader sand compare compare' ;">
}
protected void HandleTimingChanged() {
protected void HandleTimingChanged()
{
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
}
protected void HandleClick() {
protected void HandleClick()
{
var hotkey = KeyService.GetHotkey();
var hotkeyGroup = KeyService.GetHotkeyGroup();
var isHoldSpace = KeyService.IsHoldingSpace();
var faction = FilterService.GetFactionType();
var immortal = FilterService.GetImmortalType();
if (hotkey == "`") {
if (hotkey == "`")
{
BuildOrderService.RemoveLast();
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
StateHasChanged();
@ -83,10 +88,12 @@ grid-template-areas: 'loader sand compare compare' ;">
}
var entity = EntityModel.GetFrom(hotkey, hotkeyGroup, isHoldSpace, faction, immortal);
if (entity == null) {
if (entity == null)
{
return;
}
if (BuildOrderService.Add(entity, EconomyService)) {
if (BuildOrderService.Add(entity, EconomyService))
{
EconomyService.Calculate(BuildOrderService, TimingService, BuildOrderService.GetLastRequestInterval());
}
}

11
IGP/Pages/Comparision/Parts/BuildLoaderComponent.razor

@ -16,17 +16,20 @@
string buildData = "";
[Inject]
IBuildComparisonService BuildComparisionService { get; set; }
IBuildComparisonService BuildComparisionService { get; set; } = default!;
protected override void OnInitialized() {
protected override void OnInitialized()
{
BuildComparisionService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
BuildComparisionService.Unsubscribe(StateHasChanged);
}
void OnLoad() {
void OnLoad()
{
BuildComparisionService.LoadJson(buildData);
}

8
IGP/Pages/Comparision/Parts/SandComponent.razor

@ -9,13 +9,15 @@
@code {
[Inject]
IBuildComparisonService BuildComparisonService { get; set; }
IBuildComparisonService BuildComparisonService { get; set; } = default!;
protected override void OnInitialized() {
protected override void OnInitialized()
{
BuildComparisonService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
BuildComparisonService.Unsubscribe(StateHasChanged);
}

2
IGP/Pages/ContactPage.razor

@ -11,7 +11,7 @@
How do I contact you for feature requests and bug reports?
</InfoQuestionComponent>
<InfoAnswerComponent>
You can direct message me at <b>Iremirror#3544</b> on the <a href="https://discord.gg/uMq8bMGeeN" target="_blank">IGP Fan Reference</a> discord.
You can message me at <b>JonathanMcCaffrey#3544</b> on my <a href="https://discord.gg/uMq8bMGeeN" target="_blank">Discord</a> channel.
</InfoAnswerComponent>
</InfoBodyComponent>
</PaperComponent>

108
IGP/Pages/Database/DatabasePage.razor

@ -10,27 +10,29 @@
<WebsiteTitleComponent>Database</WebsiteTitleComponent>
<PaperComponent>
<FormDisplayComponent Label="Patch">
<Display>
Game Patch: @EntityModel.GameVersion
</Display>
</FormDisplayComponent>
<FormDisplayComponent Label="Patch">
<Display>
Game Patch: @EntityModel.GameVersion
</Display>
</FormDisplayComponent>
</PaperComponent>
<div style="margin-left: 8px">
<ButtonGroupComponent OnClick="((choice => { entityDisplayService.SetDisplayType(choice); }))" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent>
</div>
<ButtonGroupComponent OnClick="choice => { entityDisplayService.SetDisplayType(choice); }" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent>
</div>
<PaperComponent>
<EntityFilterComponent></EntityFilterComponent>
@if (searches != null) {
@if (searches != null)
{
<div class="databaseItems">
@foreach (var entity in searches) {
@foreach (var entity in searches)
{
<CascadingValue Value="entity">
<CascadingValue Value="@entityDisplayService.GetDisplayType()">
<EntityViewComponent></EntityViewComponent>
</CascadingValue>
</CascadingValue>
</CascadingValue>
}
</div>
@ -112,16 +114,16 @@
@code {
[Inject]
public IEntityFilterService EntityFilterService { get; set; }
public IEntityFilterService EntityFilterService { get; set; } = default!;
readonly List<EntityModel> defaults = (from entity in EntityModel.GetList()
where entity.IsSpeculative == false
select entity).ToList();
List<EntityModel> factions;
List<EntityModel> immortals;
List<EntityModel> entities;
List<EntityModel> searches;
List<EntityModel> factions = default!;
List<EntityModel> immortals = default!;
List<EntityModel> entities = default!;
List<EntityModel> searches = default!;
string selectedFactionType = FactionType.Any;
@ -129,44 +131,54 @@
string selectedEntityType = EntityType.Army;
string searchText = "";
protected override void OnInitialized() {
protected override void OnInitialized()
{
RefreshFactionSearch();
EntityFilterService.Subscribe(OnChange);
entityDisplayService.Subscribe(StateHasChanged);
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
EntityFilterService.Unsubscribe(OnChange);
entityDisplayService.Unsubscribe(StateHasChanged);
}
void OnChange(EntityFilterEvent filterEntityEvent) {
if (filterEntityEvent == EntityFilterEvent.OnRefreshFaction) {
void OnChange(EntityFilterEvent filterEntityEvent)
{
if (filterEntityEvent == EntityFilterEvent.OnRefreshFaction)
{
RefreshFactionSearch();
}
if (filterEntityEvent == EntityFilterEvent.OnRefreshImmortal) {
if (filterEntityEvent == EntityFilterEvent.OnRefreshImmortal)
{
RefreshImmortalSearch();
}
if (filterEntityEvent == EntityFilterEvent.OnRefreshEntity) {
if (filterEntityEvent == EntityFilterEvent.OnRefreshEntity)
{
RefreshEntitySearch();
}
if (filterEntityEvent == EntityFilterEvent.OnRefreshSearch) {
if (filterEntityEvent == EntityFilterEvent.OnRefreshSearch)
{
RefreshTextSearch();
}
}
void RefreshFactionSearch() {
void RefreshFactionSearch()
{
selectedFactionType = EntityFilterService.GetFactionType();
if (selectedFactionType == FactionType.Any) {
if (selectedFactionType == FactionType.Any)
{
factions = defaults.ToList();
}
else {
else
{
factions = (from entity in defaults
where entity.Faction() != null && entity.Faction().Faction == selectedFactionType
select entity).ToList();
@ -176,18 +188,22 @@
}
void OnImmortalChanged(ChangeEventArgs e) {
selectedImmortalType = e.Value.ToString();
void OnImmortalChanged(ChangeEventArgs e)
{
selectedImmortalType = e.Value!.ToString()!;
RefreshImmortalSearch();
}
void RefreshImmortalSearch() {
void RefreshImmortalSearch()
{
selectedImmortalType = EntityFilterService.GetImmortalType();
if (selectedImmortalType == ImmortalType.Any) {
if (selectedImmortalType == ImmortalType.Any)
{
immortals = factions.ToList();
}
else {
else
{
immortals = (from entity in factions
where entity.VanguardAdded() == null || entity.VanguardAdded().ImmortalId == selectedImmortalType
select entity).ToList();
@ -196,18 +212,22 @@
RefreshEntitySearch();
}
void OnEntityChanged(ChangeEventArgs e) {
selectedEntityType = e.Value.ToString();
void OnEntityChanged(ChangeEventArgs e)
{
selectedEntityType = e.Value!.ToString()!;
RefreshEntitySearch();
}
void RefreshEntitySearch() {
void RefreshEntitySearch()
{
selectedEntityType = EntityFilterService.GetEntityType();
if (selectedEntityType == EntityType.Any) {
if (selectedEntityType == EntityType.Any)
{
entities = immortals.ToList();
}
else {
else
{
entities = (from entity in immortals
where entity.EntityType == selectedEntityType
select entity).ToList();
@ -216,18 +236,22 @@
RefreshTextSearch();
}
void OnSearchTextChanged(ChangeEventArgs e) {
searchText = e.Value.ToString();
void OnSearchTextChanged(ChangeEventArgs e)
{
searchText = e.Value!.ToString()!;
RefreshTextSearch();
}
void RefreshTextSearch() {
void RefreshTextSearch()
{
searchText = EntityFilterService.GetSearchText();
if (searchText.Trim() == "") {
if (searchText.Trim() == "")
{
searches = entities.ToList();
}
else {
else
{
searches = (from entity in entities
where entity.Info().Name.ToLower().Contains(searchText.ToLower())
select entity).ToList();

39
IGP/Pages/Database/DatabaseSinglePage.razor

@ -7,7 +7,7 @@
@implements IDisposable
<LayoutLargeContentComponent>
<PaperComponent>
<FormDisplayComponent Label="Patch">
<Display>
@ -15,18 +15,19 @@
</Display>
</FormDisplayComponent>
</PaperComponent>
<div style="margin-left: 8px">
<ButtonGroupComponent OnClick="((choice => { entityDisplayService.SetDisplayType(choice); }))" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent>
<ButtonGroupComponent OnClick="choice => { entityDisplayService.SetDisplayType(choice); }" Choice="@entityDisplayService.GetDisplayType()" Choices="@entityDisplayService.DefaultChoices()"></ButtonGroupComponent>
</div>
@if(Text.Trim().ToLower().Equals("walter"))
@if (Text!.Trim().ToLower().Equals("walter"))
{
<PaperComponent>
<CodeComponent>Unhandled Exception: EXCEPTION_MEMORY_SIZE_VIOLATION
<CodeComponent>
Unhandled Exception: EXCEPTION_MEMORY_SIZE_VIOLATION
UNIT_WALTER too powerful to be displayed.
This SHOULD NEVER HAPPEN!
</CodeComponent>
</PaperComponent>
@ -37,36 +38,35 @@
<div>Invalid entity name entered: @Text</div>
<div>No such entity. Did you mean <b>"Throne"</b>?</div>
</PaperComponent>
}
}
else
{
<PaperComponent>
<CascadingValue Value="entity">
<CascadingValue Value="@entityDisplayService.GetDisplayType()">
<EntityViewComponent></EntityViewComponent>
</CascadingValue>
</CascadingValue>
</PaperComponent>
</PaperComponent>
}
</LayoutLargeContentComponent>
</LayoutLargeContentComponent>
@code {
[Parameter]
public string? Text { get; set; }
private EntityModel? entity = null;
private EntityModel? entity;
protected override void OnInitialized()
{
entityDisplayService.Subscribe(StateHasChanged);
foreach (var e in DATA.Get().Values)
{
if (e.Info().Name.Equals(Text))
@ -76,8 +76,9 @@
}
}
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
entityDisplayService.Unsubscribe(StateHasChanged);
}

7
IGP/Pages/Database/Entity/EntityViewComponent.razor

@ -1,4 +1,5 @@
@if (Entity != null) {
@if (Entity != null)
{
var isVanguard = Entity.VanguardAdded() != null ? " vanguard" : "";
<div class="enititiesContainer @isVanguard">
@ -47,9 +48,11 @@
</style>
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
[CascadingParameter]
public string? StyleType { get; set; }
}

64
IGP/Pages/Database/Entity/Parts/EntityAbilitiesComponent.razor

@ -1,7 +1,9 @@
@if (Entity.IdAbilities().Count > 0) {
@if (Entity!.IdAbilities().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@foreach (var idAbility in Entity.IdAbilities()) {
@foreach (var idAbility in Entity.IdAbilities())
{
var spell = EntityModel.Get(idAbility.Id);
var info = spell.Info();
@ -14,26 +16,31 @@
<div>
<b>- Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>- Notes:</b> @((MarkupString)info.Notes)
</div>
</div>
}
<div>
@if (production != null) {
if (production.Energy != 0) {
@if (production != null)
{
if (production.Energy != 0)
{
<div>
<b>- Energy: </b> @production.Energy
</div>
}
if (production.BuildTime != 0) {
if (production.BuildTime != 0)
{
<div>
<b>- BuildTime: </b> @production.BuildTime
<b>- BuildTime: </b> @production.BuildTime
</div>
}
if (production.Cooldown != 0) {
if (production.Cooldown != 0)
{
<div>
<b>- Cooldown: </b> @production.Cooldown
</div>
@ -42,13 +49,12 @@
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Abilities">
@foreach (var idAbility in Entity.IdAbilities()) {
@foreach (var idAbility in Entity.IdAbilities())
{
var spell = EntityModel.Get(idAbility.Id);
var info = spell.Info();
@ -61,26 +67,31 @@
<div>
<b>Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>Notes:</b> @((MarkupString)info.Notes)
</div>
</div>
}
<div>
@if (production != null) {
if (production.Energy != 0) {
@if (production != null)
{
if (production.Energy != 0)
{
<div>
<b> Energy: </b> @production.Energy
</div>
}
if (production.BuildTime != 0) {
if (production.BuildTime != 0)
{
<div>
<b> BuildTime: </b> @production.BuildTime
<b> BuildTime: </b> @production.BuildTime
</div>
}
if (production.Cooldown != 0) {
if (production.Cooldown != 0)
{
<div>
<b> Cooldown: </b> @production.Cooldown
</div>
@ -89,19 +100,18 @@
</div>
</div>
}
</EntityDisplayComponent>
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";
}

19
IGP/Pages/Database/Entity/Parts/EntityHeaderComponent.razor

@ -1,11 +1,12 @@
@if (StyleType.Equals("Plain"))
{
<div><b>@Entity?.Info().Name</b>
@if (Entity?.Info().Descriptive != DescriptiveType.None)
{
<span>, @Entity?.Info().Descriptive.Replace("_", " ")</span>
}
</div>
<div>
<b>@Entity?.Info().Name</b>
@if (Entity?.Info().Descriptive != DescriptiveType.None)
{
<span>, @Entity?.Info().Descriptive.Replace("_", " ")</span>
}
</div>
}
else
{
@ -18,7 +19,7 @@ else
@if (Entity?.Info().Descriptive != DescriptiveType.None)
{
<span>
<b>:</b> @Entity.Info().Descriptive.Replace("_", " ")
<b>:</b> @Entity!.Info().Descriptive.Replace("_", " ")
</span>
}
</div>
@ -53,9 +54,9 @@ else
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

41
IGP/Pages/Database/Entity/Parts/EntityInfoComponent.razor

@ -1,34 +1,38 @@

@if (StyleType.Equals("Plain"))
@if (StyleType.Equals("Plain"))
{
@if (Entity.Info().Description != "") {
@if (Entity!.Info().Description != "")
{
<div>
<b>Description:</b> @((MarkupString)Entity.Info().Description)
</div>
}
@if (Entity.Info().Notes != "") {
@if (Entity.Info().Notes != "")
{
<div>
<b>Notes:</b> @((MarkupString)Entity.Info().Notes)
</div>
}
<div class="infoDisplayContainer">
<div>
@if (Entity.Faction() != null) {
@if (Entity.Faction() != null)
{
<div>
<b>Faction:</b> @Entity.Faction().Faction
</div>
}
@if (Entity.Tier() != null) {
@if (Entity.Tier() != null)
{
<div>
<b>Tier:</b> @Entity.Tier().Tier
</div>
}
</div>
@if (Entity.Hotkey() != null) {
@if (Entity.Hotkey() != null)
{
<div>
<div>
<b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup
@ -46,34 +50,39 @@
else
{
<EntityDisplayComponent Title="Info">
@if (Entity.Info().Description != "") {
@if (Entity!.Info().Description != "")
{
<div>
<b>Description:</b> @((MarkupString)Entity.Info().Description)
</div>
}
@if (Entity.Info().Notes != "") {
@if (Entity.Info().Notes != "")
{
<div>
<b>Notes:</b> @((MarkupString)Entity.Info().Notes)
</div>
}
<div class="infoDisplayContainer">
<div>
@if (Entity.Faction() != null) {
@if (Entity.Faction() != null)
{
<div>
<b>Faction:</b> @Entity.Faction().Faction
</div>
}
@if (Entity.Tier() != null) {
@if (Entity.Tier() != null)
{
<div>
<b>Tier:</b> @Entity.Tier().Tier
</div>
}
</div>
@if (Entity.Hotkey() != null) {
@if (Entity.Hotkey() != null)
{
<div>
<div>
<b>Hotkey Group:</b> @Entity.Hotkey().HotkeyGroup
@ -101,7 +110,7 @@ else
gap: 4px;
}
}
</style>
</style>
}
@ -109,7 +118,7 @@ else
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

10
IGP/Pages/Database/Entity/Parts/EntityMechanicsComponent.razor

@ -1,7 +1,9 @@
@if (Entity.Mechanics().Count > 0) {
@if (Entity!.Mechanics().Count > 0)
{
<EntityDisplayComponent Title="Mechanics">
<div>
@foreach (var data in Entity.Mechanics()) {
@foreach (var data in Entity.Mechanics())
{
<div>
<div>
<span>
@ -22,8 +24,8 @@
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

72
IGP/Pages/Database/Entity/Parts/EntityPassivesComponent.razor

@ -1,100 +1,106 @@
@if (Entity.IdPassives().Count > 0) {
@if (Entity!.IdPassives().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@foreach (var idPassive in Entity.IdPassives()) {
@foreach (var idPassive in Entity.IdPassives())
{
var passive = EntityModel.Get(idPassive.Id);
var info = passive.Info();
var production = passive.Production();
<div>
<div>
<b>Name:</b> @info.Name
<b>Name:</b> @info.Name
</div>
<div>
<b>- Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>- Description:</b> @((MarkupString)info.Notes)
</div>
</div>
}
</div>
@if (production != null) {
@if (production != null)
{
<div>
@if (production.Pyre != 0) {
@if (production.Pyre != 0)
{
<div>
<b>- Pyre:</b> @production.Pyre
</div>
</div>
}
@if (production.Cooldown != 0) {
@if (production.Cooldown != 0)
{
<div>
<b>- Cooldown:</b> @production.Cooldown.ToString()s
</div>
</div>
}
</div>
}
}
}
else
{
<EntityDisplayComponent Title="Passives">
@foreach (var idPassive in Entity.IdPassives()) {
@foreach (var idPassive in Entity.IdPassives())
{
var passive = EntityModel.Get(idPassive.Id);
var info = passive.Info();
var production = passive.Production();
<div>
<div>
<b>Name:</b> <EntityLabelComponent EntityId="@passive.DataType"/>
<b>Name:</b> <EntityLabelComponent EntityId="@passive.DataType"/>
</div>
<div>
<b>Description:</b> @((MarkupString)info.Description)
</div>
@if (!info.Notes.Trim().Equals("")) {
@if (!info.Notes.Trim().Equals(""))
{
<div>
<b>Description:</b> @((MarkupString)info.Notes)
</div>
</div>
}
</div>
@if (production != null) {
@if (production != null)
{
<div>
@if (production.Pyre != 0) {
@if (production.Pyre != 0)
{
<div>
<b>Pyre:</b> @production.Pyre
</div>
</div>
}
@if (production.Cooldown != 0) {
@if (production.Cooldown != 0)
{
<div>
<b>Cooldown:</b> @production.Cooldown.ToString()s
</div>
</div>
}
</div>
}
}
</EntityDisplayComponent>
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

249
IGP/Pages/Database/Entity/Parts/EntityProductionComponent.razor

@ -1,16 +1,103 @@
@if (Production != null || Supply != null || Requirements.Count > 0) {
@if (Production != null || Supply != null || Requirements.Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@if (Requirements.Count() > 0) {
@if (Requirements.Count() > 0)
{
<div>
@foreach (var requirement in Requirements)
{
var replaced = DATA.Get()[requirement.DataType];
<div>
<span>
<b>@requirement.Requirement.Replace("_", " "):</b> @replaced.Info().Name
</span>
</div>
}
</div>
}
@if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0)))
{
<div>
@if (!Production.Alloy.Equals(0))
{
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0))
{
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0))
{
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0))
{
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0))
{
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null)
{
<div>
@if (!Supply.Grants.Equals(0))
{
<div>
<b>Grants:</b> @Supply.Grants
</div>
}
@if (!Supply.Takes.Equals(0))
{
<div>
<b>Takes:</b> @Supply.Takes Supply
</div>
}
</div>
}
}
else
{
<EntityDisplayComponent Title="Production">
<div class="ProductionContainer">
@if (Requirements.Count() > 0)
{
<div>
@foreach (var requirement in Requirements)
{
var replaced = DATA.Get()[requirement.DataType];
<div>
<span>
<b>@requirement.Requirement.Replace("_", " "):</b> @replaced.Info().Name
<b>@requirement.Requirement.Replace("_", " "):</b> <EntityLabelComponent EntityId="@requirement.DataType"/>
</span>
</div>
}
@ -20,127 +107,62 @@
@if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0))) {
<div>
@if (!Production.Alloy.Equals(0)) {
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0)) {
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0)) {
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0)) {
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0)) {
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0)) {
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null) {
|| !Production.Cooldown.Equals(0)))
{
<div>
@if (!Supply.Grants.Equals(0)) {
@if (!Production.Alloy.Equals(0))
{
<div>
<b>Grants:</b> @Supply.Grants
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Supply.Takes.Equals(0)) {
@if (!Production.Ether.Equals(0))
{
<div>
<b>Takes:</b> @Supply.Takes Supply
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0))
{
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
</div>
}
}
else
{
<EntityDisplayComponent Title="Production">
<div class="ProductionContainer">
@if (Requirements.Count() > 0) {
<div>
@foreach (var requirement in Requirements) {
@if (!Production.BuildTime.Equals(0))
{
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
<span>
<b>@requirement.Requirement.Replace("_", " "):</b> <EntityLabelComponent EntityId="@requirement.DataType"/>
</span>
@if (!Production.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0))
{
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Production != null && (!Production.Alloy.Equals(0)
|| !Production.Ether.Equals(0)
|| !Production.BuildTime.Equals(0)
|| !Production.Cooldown.Equals(0))) {
<div>
@if (!Production.Alloy.Equals(0)) {
<div>
<b>Alloy:</b> @Production.Alloy
</div>
}
@if (!Production.Ether.Equals(0)) {
<div>
<b>Ether:</b> @Production.Ether
</div>
}
@if (!Production.Pyre.Equals(0)) {
<div>
<b>Pyre:</b> @Production.Pyre
</div>
}
@if (!Production.BuildTime.Equals(0)) {
<div>
<b>Build Time:</b> @Production.BuildTime.ToString()s
</div>
}
@if (!Production.Energy.Equals(0)) {
<div>
<b>Energy:</b> @Production.Energy
</div>
}
@if (!Production.Cooldown.Equals(0)) {
<div>
<b>Cooldown:</b> @Production.Cooldown.ToString()s
</div>
}
</div>
}
@if (Supply != null) {
@if (Supply != null)
{
<div>
@if (!Supply.Grants.Equals(0)) {
@if (!Supply.Grants.Equals(0))
{
<div>
<b>Grants:</b> @Supply.Grants
</div>
}
@if (!Supply.Takes.Equals(0)) {
@if (!Supply.Takes.Equals(0))
{
<div>
<b>Takes:</b> @Supply.Takes Supply
</div>
@ -149,8 +171,8 @@
}
</div>
</EntityDisplayComponent>
<style>
.ProductionContainer {
display: flex;
@ -164,7 +186,6 @@
}
}
</style>
}
}
@ -173,14 +194,14 @@
[CascadingParameter]
public EntityModel? Entity { get; set; }
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";
private EntityProductionModel Production => Entity.Production();
private List<EntityRequirementModel> Requirements => Entity.Requirements();
private EntitySupplyModel Supply => Entity.Supply();
private EntityProductionModel Production => Entity!.Production();
private List<EntityRequirementModel> Requirements => Entity!.Requirements();
private EntitySupplyModel Supply => Entity!.Supply();
protected override void OnParametersSet()

40
IGP/Pages/Database/Entity/Parts/EntityPyreSpellsComponent.razor

@ -1,8 +1,9 @@
@if (Entity.IdPyreSpells().Count > 0)
@if (Entity!.IdPyreSpells().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@foreach (var pyreSpell in Entity.IdPyreSpells()) {
@foreach (var pyreSpell in Entity.IdPyreSpells())
{
var spell = EntityModel.Get(pyreSpell.Id);
var info = spell.Info();
@ -16,16 +17,20 @@
<b>- Description:</b> @((MarkupString)info.Description)
</div>
<div>
@if (production != null) {
if (production.Pyre != 0) {
@if (production != null)
{
if (production.Pyre != 0)
{
<b>- Pyre: </b>
@production.Pyre
}
if (production.BuildTime != 0) {
if (production.BuildTime != 0)
{
<b>- BuildTime: </b>
@production.BuildTime
}
if (production.Cooldown != 0) {
if (production.Cooldown != 0)
{
<b>- Cooldown: </b>
@production.Cooldown
}
@ -33,12 +38,12 @@
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Pyre Spells">
@foreach (var pyreSpell in Entity.IdPyreSpells()) {
@foreach (var pyreSpell in Entity.IdPyreSpells())
{
var spell = EntityModel.Get(pyreSpell.Id);
var info = spell.Info();
@ -52,16 +57,20 @@
<b>Description:</b> @((MarkupString)info.Description)
</div>
<div>
@if (production != null) {
if (production.Pyre != 0) {
@if (production != null)
{
if (production.Pyre != 0)
{
<b> Pyre: </b>
@production.Pyre
}
if (production.BuildTime != 0) {
if (production.BuildTime != 0)
{
<b> BuildTime: </b>
@production.BuildTime
}
if (production.Cooldown != 0) {
if (production.Cooldown != 0)
{
<b> Cooldown: </b>
@production.Cooldown
}
@ -70,7 +79,6 @@
</div>
}
</EntityDisplayComponent>
}
}
@ -78,9 +86,9 @@
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

149
IGP/Pages/Database/Entity/Parts/EntityStatsComponent.razor

@ -1,97 +1,112 @@

@if (Vitality != null || Movement != null) {
@if (Vitality != null || Movement != null)
{
@if (StyleType.Equals("Plain"))
{
@if (Vitality != null) {
@if (Vitality != null)
{
<div>
@if (!Vitality.DefenseLayer.Equals(0))
{
<div>
@if (!Vitality.DefenseLayer.Equals(0)) {
<div>
<b>Shield:</b> @Vitality.DefenseLayer
</div>
}
@if (!Vitality.Health.Equals(0)) {
<div>
<b>Health:</b> @Vitality.Health
</div>
}
@if (!Vitality.Energy.Equals(0)) {
<div>
<b>Energy:</b> @Vitality.Energy
</div>
}
@if (Vitality.Armor != "") {
<div>
<b>Armor:</b> @Vitality.Armor
</div>
}
<b>Shield:</b> @Vitality.DefenseLayer
</div>
}
@if (!Vitality.Health.Equals(0))
{
<div>
<b>Health:</b> @Vitality.Health
</div>
}
@if (!Vitality.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Vitality.Energy
</div>
}
@if (Vitality.Armor != "")
{
<div>
<b>Armor:</b> @Vitality.Armor
</div>
}
@if (Vitality.IsEtheric) {
<div>
<b> + Etheric</b>
</div>
}
@if (Vitality.IsStructure) {
<div>
<b> + Structure</b>
</div>
}
@if (Vitality.IsEtheric)
{
<div>
<b> + Etheric</b>
</div>
}
@if (Vitality.IsStructure)
{
<div>
<b> + Structure</b>
</div>
}
</div>
}
@if (Movement != null) {
@if (Movement != null)
{
<div>
@if (!Movement.Speed.Equals(0))
{
<div>
@if (!Movement.Speed.Equals(0)) {
<div>
<b>Speed:</b> @Movement.Speed
</div>
}
else {
<div>
<b>Speed:</b> Immobile
</div>
}
<div>
<b>Move Type:</b> @Movement.Movement
</div>
<b>Speed:</b> @Movement.Speed
</div>
}
else
{
<div>
<b>Speed:</b> Immobile
</div>
}
<div>
<b>Move Type:</b> @Movement.Movement
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Stats">
<div class="statContainer">
@if (Vitality != null) {
@if (Vitality != null)
{
<div>
@if (!Vitality.DefenseLayer.Equals(0)) {
@if (!Vitality.DefenseLayer.Equals(0))
{
<div>
<b>Shield:</b> @Vitality.DefenseLayer
</div>
}
@if (!Vitality.Health.Equals(0)) {
@if (!Vitality.Health.Equals(0))
{
<div>
<b>Health:</b> @Vitality.Health
</div>
}
@if (!Vitality.Energy.Equals(0)) {
@if (!Vitality.Energy.Equals(0))
{
<div>
<b>Energy:</b> @Vitality.Energy
</div>
}
@if (Vitality.Armor != "") {
@if (Vitality.Armor != "")
{
<div>
<b>Armor:</b> @Vitality.Armor
</div>
}
@if (Vitality.IsEtheric) {
@if (Vitality.IsEtheric)
{
<div>
<b> + Etheric</b>
</div>
}
@if (Vitality.IsStructure) {
@if (Vitality.IsStructure)
{
<div>
<b> + Structure</b>
</div>
@ -100,14 +115,17 @@
}
@if (Movement != null) {
@if (Movement != null)
{
<div>
@if (!Movement.Speed.Equals(0)) {
@if (!Movement.Speed.Equals(0))
{
<div>
<b>Speed:</b> @Movement.Speed
</div>
}
else {
else
{
<div>
<b>Speed:</b> Immobile
</div>
@ -132,21 +150,20 @@
}
}
</style>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";
private EntityVitalityModel Vitality => Entity.Vitality();
private EntityMovementModel Movement => Entity.Movement();
private EntityVitalityModel Vitality => Entity!.Vitality();
private EntityMovementModel Movement => Entity!.Movement();
}

21
IGP/Pages/Database/Entity/Parts/EntityUpgradesComponent.razor

@ -1,7 +1,9 @@
@if (Entity.IdUpgrades().Count > 0) {
@if (Entity!.IdUpgrades().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@foreach (var upgradeId in Entity.IdUpgrades()) {
@foreach (var upgradeId in Entity.IdUpgrades())
{
var entity = EntityModel.Get(upgradeId.Id);
<div>
<div>
@ -12,13 +14,13 @@
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Upgrades">
<div class="upgradesContainer">
@foreach (var upgradeId in Entity.IdUpgrades()) {
@foreach (var upgradeId in Entity.IdUpgrades())
{
var entity = EntityModel.Get(upgradeId.Id);
<div>
<div>
@ -30,9 +32,9 @@
</div>
}
</div>
</EntityDisplayComponent>
</EntityDisplayComponent>
<style>
.upgradesContainer {
display: flex;
@ -47,16 +49,15 @@
}
</style>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

30
IGP/Pages/Database/Entity/Parts/EntityVanguardAddedComponent.razor

@ -1,17 +1,19 @@
@if (Vanguard != null) {
@if (Vanguard != null)
{
var immortalId = Vanguard.ImmortalId;
var immortal = DATA.Get()[immortalId];
var replaced = DATA.Get()[Vanguard.ReplaceId];
@if (StyleType.Equals("Plain"))
{
<div>
<b>Immortal:</b> @immortal.Info().Name
</div>
@if (!Vanguard.ReplaceId.Equals("")) {
@if (!Vanguard.ReplaceId.Equals(""))
{
<div>
<b>Replaces:</b> @replaced.Info().Name
<b>Replaces:</b> @replaced.Info().Name
</div>
}
}
@ -22,25 +24,27 @@
<div>
<b>Immortal:</b> <EntityLabelComponent EntityId="@immortal.DataType"/>
</div>
@if (!Vanguard.ReplaceId.Equals("")) {
@if (!Vanguard.ReplaceId.Equals(""))
{
<div>
<b>Replaces:</b> <EntityLabelComponent EntityId="@Vanguard.ReplaceId"></EntityLabelComponent>
<b>Replaces:</b> <EntityLabelComponent EntityId="@Vanguard.ReplaceId"></EntityLabelComponent>
</div>
}
</div>
</EntityDisplayComponent>
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
private EntityVanguardAddedModel? Vanguard => Entity?.VanguardAdded();
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";
}

23
IGP/Pages/Database/Entity/Parts/EntityVanguardsComponent.razor

@ -1,7 +1,9 @@
@if (Entity.IdVanguards().Count > 0) {
@if (Entity!.IdVanguards().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
@foreach (var data in Entity.IdVanguards()) {
@foreach (var data in Entity.IdVanguards())
{
var entity = EntityModel.Get(data.Id);
var requirements = entity.Requirements();
@ -9,7 +11,7 @@
var replaced = DATA.Get()[vanguardAdded.ReplaceId];
var immortal = DATA.Get()[vanguardAdded.ImmortalId];
var productionBuilding = (from building in requirements
where building.Requirement == RequirementType.Production_Building
select building).First().DataType;
@ -22,7 +24,7 @@
<b>- Replaces:</b> @replaced.Info().Name
</div>
<div>
<b>- Built From:</b> @immortal.Info().Name
<b>- Built From:</b> @immortal.Info().Name
</div>
</div>
}
@ -30,7 +32,8 @@
else
{
<EntityDisplayComponent Title="Vanguards">
@foreach (var data in Entity.IdVanguards()) {
@foreach (var data in Entity.IdVanguards())
{
var entity = EntityModel.Get(data.Id);
var requirements = entity.Requirements();
@ -44,7 +47,7 @@
<b>Name:</b> <EntityLabelComponent EntityId="@entity.DataType"/>
</div>
<div>
<b>Replaces:</b> <EntityLabelComponent EntityId="@vanguard.ReplaceId"/>
<b>Replaces:</b> <EntityLabelComponent EntityId="@vanguard.ReplaceId"/>
</div>
<div>
<b>Built From:</b> <EntityLabelComponent EntityId="@productionBuilding"/>
@ -52,17 +55,15 @@
</div>
}
</EntityDisplayComponent>
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

322
IGP/Pages/Database/Entity/Parts/EntityWeaponsComponent.razor

@ -1,205 +1,204 @@
@if (Entity.Weapons().Count > 0)
@if (Entity!.Weapons().Count > 0)
{
@if (StyleType.Equals("Plain"))
{
int index = 0;
var index = 0;
foreach (var data in Entity.Weapons())
{
index++;
<div>
<div>
<div>
<div class="damageContainer">
<div>
<b>Weapon @index</b>
</div>
<div>
<b>- Damage:</b> @data.Damage
</div>
@if (data.LightDamage != 0)
{
<div class="alternateDamage">
<i>- vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div class="alternateDamage">
<i>- vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div class="alternateDamage">
<i>- vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div>
<div>
<b>- Range:</b> @data.Range
</div>
@if (data.SecondsBetweenAttacks > 0)
{
<div>
<b>- AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
</div>
<div class="damageContainer">
<div>
- (or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
</div>
}
else if (data.AttacksPerSecond > 0)
{
<div>
<b>- AttacksPerSecond:</b> @data.AttacksPerSecond
<b>Weapon @index</b>
</div>
<div>
- (or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
<b>- Damage:</b> @data.Damage
</div>
}
<div>
<b>- Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{
<span>
<b>- DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
</span>
@if (data.LightDamage != 0)
{
<span>
<i>- Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
<div class="alternateDamage">
<i>- vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<span>
<i>- Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
<div class="alternateDamage">
<i>- vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<span>
<i>- Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
<div class="alternateDamage">
<i>- vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>- vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div>
}
}
else
{
<EntityDisplayComponent Title="Weapons">
<div class="weaponsContainer">
@foreach (var data in Entity.Weapons())
{
<div>
<b>- Range:</b> @data.Range
</div>
@if (data.SecondsBetweenAttacks > 0)
{
<div>
<div class="damageContainer">
<div>
<b>Damage:</b> @data.Damage
</div>
@if (data.LightDamage != 0)
{
<div class="alternateDamage">
<i>vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div class="alternateDamage">
<i>vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div class="alternateDamage">
<i>vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
<b>- AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
</div>
<div>
- (or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
</div>
}
else if (data.AttacksPerSecond > 0)
{
<div>
<b>Range:</b> @data.Range
<b>- AttacksPerSecond:</b> @data.AttacksPerSecond
</div>
@if (data.SecondsBetweenAttacks > 0)
<div>
- (or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
</div>
}
<div>
<b>- Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{
<span>
<b>- DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
</span>
@if (data.LightDamage != 0)
{
<div>
<b>AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
</div>
<div>
(or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
</div>
<span>
<i>- Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
}
else if (data.AttacksPerSecond > 0)
@if (data.MediumDamage != 0)
{
<div>
<b>AttacksPerSecond:</b> @data.AttacksPerSecond
</div>
<div>
(or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
</div>
<span>
<i>- Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
}
<div>
<b>Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
@if (data.HeavyDamage != 0)
{
<span>
<i>- Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp;
</span>
}
}
</div>
}
}
else
{
<EntityDisplayComponent Title="Weapons">
<div class="weaponsContainer">
@foreach (var data in Entity.Weapons())
{
<div>
<div>
<b>DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
<div class="damageContainer">
<div>
<b>Damage:</b> @data.Damage
</div>
@if (data.LightDamage != 0)
{
<div class="alternateDamage">
<i>vs Light: @data.LightDamage</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div class="alternateDamage">
<i>vs Medium: @data.MediumDamage</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div class="alternateDamage">
<i>vs Heavy: @data.HeavyDamage</i>&nbsp;
</div>
}
@if (data.EthericDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Etheric +@data.EthericDamageBonus</i>&nbsp;
</div>
}
@if (data.StructureDamageBonus != 0)
{
<div class="alternateDamage">
<i>vs Structure: +@data.StructureDamageBonus</i>&nbsp;
</div>
}
</div>
</div>
@if (data.LightDamage != 0)
<div>
<b>Range:</b> @data.Range
</div>
@if (data.SecondsBetweenAttacks > 0)
{
<div>
<i>Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp;
<b>AttacksPerSecond:</b> @(1 / data.SecondsBetweenAttacks)
</div>
<div>
(or <b>SecondsBetweenAttacks:</b> @data.SecondsBetweenAttacks)
</div>
}
@if (data.MediumDamage != 0)
else if (data.AttacksPerSecond > 0)
{
<div>
<i>Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp;
<b>AttacksPerSecond:</b> @data.AttacksPerSecond
</div>
<div>
(or <b>SecondsBetweenAttacks:</b> @(1 / data.AttacksPerSecond))
</div>
}
@if (data.HeavyDamage != 0)
<div>
<b>Targets:</b> @data.Targets
</div>
@if (data.AttacksPerSecond != 0)
{
<div>
<i>Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp;
<b>DPS:</b> @(Math.Round(data.Damage * data.AttacksPerSecond))&nbsp;
</div>
@if (data.LightDamage != 0)
{
<div>
<i>Light DPS: @(Math.Round(data.LightDamage * data.AttacksPerSecond))</i>&nbsp;
</div>
}
@if (data.MediumDamage != 0)
{
<div>
<i>Medium DPS: @(Math.Round(data.MediumDamage * data.AttacksPerSecond))</i>&nbsp;
</div>
}
@if (data.HeavyDamage != 0)
{
<div>
<i>Heavy DPS: @(Math.Round(data.HeavyDamage * data.AttacksPerSecond))</i>&nbsp;
</div>
}
}
}
</div>
}
</div>
</EntityDisplayComponent>
</div>
}
</div>
</EntityDisplayComponent>
<style>
.weaponsContainer {
@ -222,16 +221,15 @@
margin-bottom: 6px;
}
</style>
}
}
}
@code {
[CascadingParameter]
public EntityModel? Entity { get; set; }
public EntityModel? Entity { get; set; } = default!;
[CascadingParameter]
public string StyleType { get; set; } = "Detailed";

57
IGP/Pages/Database/Parts/EntityFilterComponent.razor

@ -2,23 +2,27 @@
<div class="desktopFiltersContainer">
<div class="filtersContainer">
<div class="filterContainer">
@foreach (var choice in EntityFilterService.GetFactionChoices()) {
@foreach (var choice in EntityFilterService.GetFactionChoices())
{
var styleClass = "";
if (choice.Equals(EntityFilterService.GetFactionType())) {
if (choice.Equals(EntityFilterService.GetFactionType()))
{
styleClass = "selected";
}
<button @onclick="@(e => OnChangeFaction(choice))" class="choiceButton @styleClass">@choice</button>
}
</div>
@if (EntityFilterService.GetFactionType() != "Any" && EntityFilterService.GetFactionType() != "None") {
@if (EntityFilterService.GetFactionType() != "Any" && EntityFilterService.GetFactionType() != "None")
{
<div class="filterContainer">
@foreach (var choice in EntityFilterService.GetImmortalChoices())
{
var name = DATA.Get()[choice].Info().Name;
var styleClass = "";
if (choice.Equals(EntityFilterService.GetImmortalType())) {
if (choice.Equals(EntityFilterService.GetImmortalType()))
{
styleClass = "selected";
}
<button class="choiceButton @styleClass" @onclick="@(e => OnChangeImmortal(choice))">@name</button>
@ -27,16 +31,18 @@
}
</div>
<div class="filterContainer">
@foreach (var choice in EntityFilterService.GetEntityChoices()) {
@foreach (var choice in EntityFilterService.GetEntityChoices())
{
var styleClass = "";
if (choice.Equals(EntityFilterService.GetEntityType())) {
if (choice.Equals(EntityFilterService.GetEntityType()))
{
styleClass = "selected";
}
<button class="choiceButton @styleClass" @onclick="@(e => OnChangeEntity(choice))">@choice.Replace("_", " ")</button>
}
</div>
<FormTextComponent Label="Search Label" Placeholder="Throne..." OnChange="@(e => EntityFilterService.EnterSearchText(e.Value.ToString()))"/>
<FormTextComponent Label="Search Label" Placeholder="Throne..." OnChange="@(e => EntityFilterService.EnterSearchText(e.Value!.ToString()!))"/>
</div>
</div>
@ -199,40 +205,49 @@
@code {
[Inject]
public IEntityFilterService EntityFilterService { get; set; }
public IEntityFilterService EntityFilterService { get; set; } = default!;
protected override void OnInitialized() { }
protected override void OnInitialized()
{
}
void OnChangeFaction(string clickedFaction) {
void OnChangeFaction(string clickedFaction)
{
EntityFilterService.SelectFactionType(clickedFaction);
StateHasChanged();
}
void OnChangeImmortal(string clickedImmortal) {
void OnChangeImmortal(string clickedImmortal)
{
EntityFilterService.SelectImmortalType(clickedImmortal);
}
void OnChangeEntity(string clickedEntity) {
void OnChangeEntity(string clickedEntity)
{
EntityFilterService.SelectEntityType(clickedEntity);
}
void OnFactionChanged(ChangeEventArgs e) {
EntityFilterService.SelectFactionType(e.Value.ToString());
void OnFactionChanged(ChangeEventArgs e)
{
EntityFilterService.SelectFactionType(e.Value!.ToString()!);
}
void OnImmortalChanged(ChangeEventArgs e) {
EntityFilterService.SelectImmortalType(e.Value.ToString());
void OnImmortalChanged(ChangeEventArgs e)
{
EntityFilterService.SelectImmortalType(e.Value!.ToString()!);
}
void OnEntityChanged(ChangeEventArgs e) {
EntityFilterService.SelectEntityType(e.Value.ToString());
void OnEntityChanged(ChangeEventArgs e)
{
EntityFilterService.SelectEntityType(e.Value!.ToString()!);
}
void OnSearchTextChanged(ChangeEventArgs e) {
EntityFilterService.EnterSearchText(e.Value.ToString());
void OnSearchTextChanged(ChangeEventArgs e)
{
EntityFilterService.EnterSearchText(e.Value!.ToString()!);
}
}

115
IGP/Pages/Documentation/DocumentationIndexPage.razor

@ -0,0 +1,115 @@
@layout PageLayout
@inject IDocumentationService documentationService
@implements IDisposable
@page "/docs"
@if (!documentationService.IsLoaded())
{
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<PaperComponent>
@foreach (var docSection in documentationService.DocSectionModels)
{
<div class="docSectionContainer">
<div class="docSectionTitle">@docSection.Name</div>
<div class="docContentContainer">
@foreach (var docContent in docSection.DocumentationModels)
{
<NavLink class="docContentLink" href="@docContent.GetDocLink()">
<div class="docContentName">@docContent.Name</div>
<div class="docContentDescription">@docContent.Description</div>
</NavLink>
}
</div>
</div>
}
</PaperComponent>
</LayoutMediumContentComponent>
}
<style>
.docSectionContainer {
width: 100%;
padding: 8px;
}
.docSectionTitle {
font-size: 3rem;
font-weight: bold;
text-align: center;
margin-bottom: 32px;
}
.docContentContainer {
display: grid;
gap: 12px;
grid-template-columns: 1fr 1fr;
}
@@media only screen and (max-width: 1025px) {
.docContentContainer {
grid-template-columns: 1fr;
}
}
.docContentName {
font-weight: bold;
font-size: 1.6rem;
}
.docContentDescription {
font-weight: normal;
}
.docContentLink {
background-color: var(--paper);
border: 1px solid var(--paper-border);
border-radius: 2px;
padding-left: 12px;
padding-right: 12px;
padding-top: 24px;
padding-bottom: 24px;
color: white;
display: flex;
flex-direction: column;
gap: 12px;
text-align: center;
margin-left: 12px;
margin-right: 12px;
}
.docContentLink:hover {
background-color: var(--paper-hover);
border-color: var(--paper-border-hover);
text-decoration: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.6);
transform: translateY(-2px) scale(1.01);
}
</style>
@code {
[Parameter]
public string? Text { get; set; }
protected override void OnInitialized()
{
documentationService.Subscribe(StateHasChanged);
documentationService.Load();
}
public void Dispose()
{
documentationService.Unsubscribe(StateHasChanged);
}
}

112
IGP/Pages/Documentation/DocumentationPage.razor

@ -1,69 +1,40 @@
@layout PageLayout
@inject IDocumentationService DocumentationService
@using Markdig
@implements IDisposable
@inject IDocumentationService documentationService
@page "/docs/{text?}"
@implements IDisposable
@page "/docs/{href1}/{href2?}/{href3?}/{href4?}/{href5?}"
@if (!DocumentationService.IsLoaded())
@if (!documentationService.IsLoaded())
{
<LoadingComponent></LoadingComponent>
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Documentation</WebsiteTitleComponent>
<div class="section">
<div for="docSection">Section: </div>
<div style="flex: 1"></div>
<select @oninput="OnSectionChanged" style="background-color: #36393F; width: 250px; margin-right: 16px;" name="docSection">
<option value="All">All</option>
</select>
</div>
<div class="docsContainer">
@foreach (var doc in DocumentationService.DocumentationModels) {
if (selectedSection != "All" && doc.Section != selectedSection) {
continue;
<LayoutWithSidebarComponent>
<Sidebar>
<DocumentNavComponent
Connections="documentationService.DocConnectionModels"
Documents="documentationService.DocContentModels"/>
</Sidebar>
<Content>
<PaperComponent>
@foreach (var doc in documentationService.DocContentModels)
{
if (!doc.Href.Equals(Href))
{
continue;
}
<DocumentComponent DocContentModel="doc"/>
}
<PaperComponent>
<div style="display: flex; flex-direction: row;">
<span style="font-weight: bold; font-style:italic;">@doc.Section</span>
<div style="flex: 1"></div>
<span style="font-weight: bold; font-style:italic;">Last Updated on @doc.UpdatedDate.ToString("MM/dd/yyyy")</span>
</div>
<div>
<div id="@doc.Id" style="font-weight: bold; font-size: 1.4rem;">@doc.Name</div>
<div>@((MarkupString)Markdown.ToHtml(doc.Description))</div>
</div>
</PaperComponent>
}
</div>
</LayoutMediumContentComponent>
</PaperComponent>
</Content>
</LayoutWithSidebarComponent>
}
<style>
.section {
display: flex;
width: 500px;
flex-direction: row;
background-color: var(--paper);
justify-content: center;
padding: 24px;
border: 4px solid var(--paper-border);
box-shadow: 0px 6px var(--paper-border);
}
.docsContainer {
display: flex;
flex-direction: column;
gap: 16px;
}
pre code {
color: white;
@ -121,25 +92,32 @@ else
@code {
[Parameter]
public string? Text { get; set; }
string selectedSection = "All";
public string? Href1 { get; set; }
[Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
protected override void OnInitialized()
{
DocumentationService.Subscribe(StateHasChanged);
DocumentationService.Load();
documentationService.Subscribe(StateHasChanged);
documentationService.Load();
}
public void Dispose()
{
DocumentationService.Unsubscribe(StateHasChanged);
}
void OnSectionChanged(ChangeEventArgs e) {
selectedSection = e.Value.ToString();
StateHasChanged();
documentationService.Unsubscribe(StateHasChanged);
}
}

35
IGP/Pages/Documentation/Parts/DocumentComponent.razor

@ -0,0 +1,35 @@
<div class="doc">
<div class="docHeader">
<div class="docTitle">@DocContentModel.Name</div>
<div class="docDates">
<div class="docDateUpdated"><b>Updated</b>: @DocContentModel.UpdatedDate.ToString("MM/dd/yyyy")</div>
<div class="docDateCreated"><b>Created</b>: @DocContentModel.CreatedDate.ToString("MM/dd/yyyy")</div>
</div>
</div>
<div class="docContent">@((MarkupString)Markdown.ToHtml(DocContentModel.Content))</div>
</div>
<style>
.docTitle {
font-weight: bold;
}
.docHeader {
display: flex;
justify-content: space-between;
}
.docDates {
display: flex;
flex-direction: column;
}
</style>
@code {
[Parameter]
public DocContentModel DocContentModel { get; set; } = default!;
}

70
IGP/Pages/Documentation/Parts/DocumentInnerNavComponent.razor

@ -0,0 +1,70 @@
@if (Document!.DocumentationModels.Count > 0)
{
<div class="docInnerNavContainer">
@foreach (var innerDoc in Document.DocumentationModels)
{
var linkStyle = $"docInnerNavButton inner_{Layers}";
<NavLink class="@linkStyle" href="@innerDoc.GetDocLink()">@innerDoc.Name</NavLink>
<DocumentInnerNavComponent Document="@innerDoc" Layers="@IncrementLayers()"/>
}
</div>
}
<style>
.docInnerNavContainer {
display: flex;
flex-direction: column;
}
.docInnerNavButton a {
color: white;
}
.docInnerNavButton a:hover {
color: white;
}
.docInnerNavButton {
padding: 8px;
margin-left: 8px;
color: white;
}
.inner_1 {
margin-left: 8px;
}
.inner_2 {
margin-left: 16px;
}
.inner_3 {
margin-left: 24px;
}
</style>
@code {
[Parameter]
public DocContentModel? Document { get; set; } = default!;
[Parameter]
public int Layers { get; set; } = 1;
public int IncrementLayers()
{
return Layers + 1;
}
private string GetLink(DocContentModel doc)
{
return $"docs/{doc.Href}";
}
}

46
IGP/Pages/Documentation/Parts/DocumentNavComponent.razor

@ -0,0 +1,46 @@
<div class="docNavContainer">
@foreach (var doc in Documents)
{
if (doc.Parent == null)
{
<NavLink class="docNavButton" href="@doc.GetDocLink()">@doc.Name</NavLink>
<DocumentInnerNavComponent Document="@doc"/>
}
}
</div>
<style>
.docNavContainer {
display: flex;
flex-direction: column;
}
.docNavButton a {
color: white;
}
.docNavButton a:hover {
color: white;
}
.docNavButton {
padding: 8px;
color: white;
}
</style>
@code {
[Parameter]
public List<DocContentModel> Documents { get; set; } = default!;
[Parameter]
public List<DocConnectionModel> Connections { get; set; } = default!;
private string GetLink(DocContentModel doc)
{
return $"docs/{doc.Href}";
}
}

33
IGP/Pages/HarassCalculatorPage.razor

@ -31,19 +31,19 @@
<FormLayoutComponent>
<FormNumberComponent Min="0"
Value="@((int)NumberOfWorkersLostToHarass)"
OnChange="@(e => { NumberOfWorkersLostToHarass = int.Parse(e.Value.ToString()); Calculate();})">
OnChange="@(e => { NumberOfWorkersLostToHarass = int.Parse(e.Value!.ToString()!); Calculate();})">
<FormLabelComponent>Number of workers lost to harass</FormLabelComponent>
</FormNumberComponent>
<FormNumberComponent Min="0"
Value="@((int)NumberOfTownHallsExisting)"
OnChange="@(e => { NumberOfTownHallsExisting = int.Parse(e.Value.ToString()); Calculate();})">
OnChange="@(e => { NumberOfTownHallsExisting = int.Parse(e.Value!.ToString()!); Calculate();})">
<FormLabelComponent>Number of townhalls existing</FormLabelComponent>
</FormNumberComponent>
<FormNumberComponent Min="0"
Value="@((int)TravelTime)"
OnChange="@(e => { TravelTime = int.Parse(e.Value.ToString()); Calculate();})">
OnChange="@(e => { TravelTime = int.Parse(e.Value!.ToString()!); Calculate();})">
<FormLabelComponent>Travel time</FormLabelComponent>
</FormNumberComponent>
@ -230,42 +230,51 @@
float NumberOfWorkersLostToHarass = 1;
float NumberOfTownHallsExisting = 1;
float SimultaneousProductionFloor() {
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0) {
float SimultaneousProductionFloor()
{
if (NumberOfTownHallsExisting <= 0 || NumberOfWorkersLostToHarass <= 0)
{
return 0;
}
return (float)Math.Floor(NumberOfWorkersLostToHarass / Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass));
}
float LeftOverWorkersToProduceCount() {
float LeftOverWorkersToProduceCount()
{
return NumberOfWorkersLostToHarass % Math.Min(NumberOfTownHallsExisting, NumberOfWorkersLostToHarass);
}
float WorkerReplacementCost() {
float WorkerReplacementCost()
{
return CostOfWorker * NumberOfWorkersLostToHarass;
}
float DelayedMiningCost() {
float DelayedMiningCost()
{
return TotalAlloyHarassment - WorkerReplacementCost();
}
void Calculate() {
void Calculate()
{
TotalAlloyHarassment = WorkerReplacementCost();
for (var workerProductionIndex = 0; workerProductionIndex < SimultaneousProductionFloor(); workerProductionIndex++) {
for (var workerProductionIndex = 0; workerProductionIndex < SimultaneousProductionFloor(); workerProductionIndex++)
{
TotalAlloyHarassment += AlloyMinedPerSecondByWorker * (TimeToProduceWorker + TravelTime) * (workerProductionIndex + 1);
}
TotalAlloyHarassment += LeftOverWorkersToProduceCount() * (TimeToProduceWorker + TravelTime) * AlloyMinedPerSecondByWorker;
}
protected override void OnInitialized() {
protected override void OnInitialized()
{
Calculate();
}
void ValueChanged(float test) {
void ValueChanged(float test)
{
Calculate();
}

82
IGP/Pages/Home/HomePage.razor

@ -0,0 +1,82 @@
@layout PageLayout;
@page "/immortal-home"
<LayoutMediumContentComponent>
<PaperComponent>
<div class="mainContainer">
<div class="mainTitle">
Fan Reference
</div>
<div>
Refer to various aspects of "IMMORTAL: Gates of Pyre" from this external reference!
</div>
</div>
</PaperComponent>
<ContentDividerComponent></ContentDividerComponent>
<PaperComponent>
<div class="heroesContainer">
<ContentHighlightComponent
Title="Database"
Description="Review the units!"
Href="/database"
ImageHref="image/hero/Database.png"/>
<ContentHighlightComponent
Title="Build Calculator"
Description="Make a build!"
Href="/build-calculator"
ImageHref="image/hero/Build.png"/>
<ContentHighlightComponent
Title="Notes"
Description="Read some notes!"
Href="/notes"
ImageHref="image/hero/Notes.png"/>
<ContentHighlightComponent
Title="Streams"
Description="Watch live development!"
Href="/streams"
ImageHref="image/hero/Streams.png"/>
</div>
</PaperComponent>
<ContentDividerComponent></ContentDividerComponent>
<AlertComponent>
<Title>Under Construction</Title>
<Message>Website is still being made. Check out <NavLink Href="/immortal-roadmap">Road Map</NavLink> for future plans, <NavLink Href="/immortal-agile">Agile</NavLink> for present tasks, and <NavLink Href="/immortal-changelog">Change Log</NavLink> for past changes.</Message>
</AlertComponent>
</LayoutMediumContentComponent>
<style>
.mainContainer {
padding-bottom: 32px;
}
.mainTitle {
font-size: 2.2rem;
font-weight: bold;
}
.heroesContainer {
display: grid;
gap: 64px;
justify-content: center;
margin: auto;
grid-template-columns: 1fr 1fr;
}
@@media only screen and (max-width: 1025px) {
.heroesContainer {
grid-template-columns: 1fr; }
}
</style>

76
IGP/Pages/Home/Parts/ContentHighlightComponent.razor

@ -0,0 +1,76 @@
<NavLink Href="@Href" class="contentHighlight">
<div class="contentHighlightTitle">
@Title
</div>
<img src="@ImageHref" class="contentHighlightImage" alt="@Title"/>
<div class="contentHighlightCallToAction">
@Description
</div>
</NavLink>
<style>
.contentHighlight {
background-color: var(--paper);
border: 1px solid var(--paper-border);
border-radius: 2px;
padding-left: 12px;
padding-right: 12px;
padding-top: 24px;
padding-bottom: 24px;
color: white;
display: flex;
flex-direction: column;
gap: 12px;
text-align: center;
margin-left: 12px;
margin-right: 12px;
}
.contentHighlight:hover {
background-color: var(--paper-hover);
border-color: var(--paper-border-hover);
text-decoration: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.6);
transform: translateY(-2px) scale(1.01);
}
.contentHighlightTitle {
font-weight: 800;
font-size: 1.3rem;
margin: auto;
}
.contentHighlightImage {
border: 1px solid rgba(0,0,0,0.5);
box-shadow: 2px 2px 2px rgba(0,0,0,0.5);
height: 400px;
width: 400px;
margin: auto;
}
.contentHighlightCallToAction {
font-weight: 700;
font-size: 1.1rem;
margin: auto;
padding: 16px;
}
</style>
@code {
[Parameter]
public string Href { get; set; } = default!;
[Parameter]
public string Title { get; set; } = default!;
[Parameter]
public string Description { get; set; } = default!;
[Parameter]
public string ImageHref { get; set; } = default!;
}

149
IGP/Pages/HomePage.razor

@ -1,149 +0,0 @@
@layout PageLayout;
@page "/immortal-home"
<LayoutMediumContentComponent>
<div class="mainContainer">
<div class="mainTitle">
Fan Reference
</div>
<div>
Refer to various aspects of "IMMORTAL: Gates of Pyre" from this external reference!
</div>
</div>
<ContentDividerComponent></ContentDividerComponent>
<div class="herosContainer">
<div class="hero">
<div class="heroTitle">
Database
</div>
<img src="image/hero/Database.png" class="heroImage"/>
<NavLink Href="/database" class="heroCallToAction">
Review the units!
</NavLink>
</div>
<div class="hero">
<div class="heroTitle">
Build Calculator
</div>
<img src="image/hero/Build.png" class="heroImage"/>
<NavLink Href="/build-calculator" class="heroCallToAction">
Make a build!
</NavLink>
</div>
<div class="hero">
<div class="heroTitle">
Notes
</div>
<img src="image/hero/Notes.png" class="heroImage"/>
<NavLink Href="/notes" class="heroCallToAction">
Read some notes!
</NavLink>
</div>
<div class="hero">
<div class="heroTitle">
Streams
</div>
<img src="image/hero/Streams.png" class="heroImage"/>
<NavLink Href="/streams" class="heroCallToAction">
Watch live development!
</NavLink>
</div>
</div>
<ContentDividerComponent></ContentDividerComponent>
<AlertComponent>
<Title>Under Construction</Title>
<Message>Website is still being made. Check out <NavLink Href="/immortal-roadmap">Road Map</NavLink> for future plans, <NavLink Href="/immortal-agile">Agile</NavLink> for present tasks, and <NavLink Href="/immortal-changelog">Change Log</NavLink> for past changes.</Message>
</AlertComponent>
</LayoutMediumContentComponent>
<style>
.mainContainer {
padding-bottom: 32px;
}
.mainTitle {
font-size: 2.2rem;
font-weight: bold;
}
.quoteContainer {
display: flex;
flex-direction: column;
gap: 8px;
max-width: 600px;
margin: auto;
}
.quoteTitle {
font-weight: 800;
margin-bottom: 8px;
}
.quoteText {
margin: auto;
font-style: italic;
}
.herosContainer {
display: flex;
flex-wrap: wrap;
gap: 64px;
justify-content: center;
}
.hero {
padding: 32px;
display: flex;
flex-direction: column;
gap: 32px;
}
.heroTitle {
font-weight: 800;
font-size: 1.3rem;
margin: auto;
}
.heroImage {
border: 1px solid rgba(0,0,0,0.5);
box-shadow: 2px 2px 2px rgba(0,0,0,0.5);
height: 400px;
width: 400px;
margin: auto;
}
.heroCallToAction {
font-weight: 700;
font-size: 1.1rem;
margin: auto;
background-color: var(--primary);
border: 1px solid var(--primary);
padding: 16px;
cursor: pointer;
color: white;
}
.heroCallToAction:hover {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
</style>

26
IGP/Pages/MakingOf/Parts/MakingOfColours.razor

@ -16,60 +16,60 @@
--info: @info;
--info-border: @info_border;
</CodeComponent>
<br />
<br/>
<div class="color accent">
<div>Accent</div>
<div>
Base: <input type="color" value="@accent" @onchange="e => accent = e.Value.ToString()" />
Base: <input type="color" value="@accent" @onchange="e => accent = e.Value!.ToString()!"/>
</div>
</div>
<div class="color primary">
<div>Primary</div>
<div>
Base: <input type="color" value="@primary" @onchange="e => primary = e.Value.ToString()" />
Base: <input type="color" value="@primary" @onchange="e => primary = e.Value!.ToString()!"/>
</div>
<div>
Border: <input type="color" value="@primary_border" @onchange="e => primary_border = e.Value.ToString()" />
Border: <input type="color" value="@primary_border" @onchange="e => primary_border = e.Value!.ToString()!"/>
</div>
<div>
Hover Base: <input type="color" value="@primary_hover" @onchange="e => primary_hover = e.Value.ToString()" />
Hover Base: <input type="color" value="@primary_hover" @onchange="e => primary_hover = e.Value!.ToString()!"/>
</div>
<div>
Hover Border: <input type="color" value="@primary_border_hover" @onchange="e => primary_border_hover = e.Value.ToString()" />
Hover Border: <input type="color" value="@primary_border_hover" @onchange="e => primary_border_hover = e.Value!.ToString()!"/>
</div>
</div>
<div class="color secondary">
<div>Secondary</div>
<div>
Base: <input type="color" value="@secondary" @onchange="e => secondary = e.Value.ToString()" />
Base: <input type="color" value="@secondary" @onchange="e => secondary = e.Value!.ToString()!"/>
</div>
<div>
Hover Base: <input type="color" value="@secondary_hover" @onchange="e => secondary_hover = e.Value.ToString()" />
Hover Base: <input type="color" value="@secondary_hover" @onchange="e => secondary_hover = e.Value!.ToString()!"/>
</div>
<div>
Hover Border: <input type="color" value="@secondary_border_hover" @onchange="e => secondary_border_hover = e.Value.ToString()" />
Hover Border: <input type="color" value="@secondary_border_hover" @onchange="e => secondary_border_hover = e.Value!.ToString()!"/>
</div>
</div>
<div class="color paper">
<div>Paper</div>
<div>
Base: <input type="color" value="@paper" @onchange="e => paper = e.Value.ToString()" />
Base: <input type="color" value="@paper" @onchange="e => paper = e.Value!.ToString()!"/>
</div>
<div>
Border: <input type="color" value="@paper_border" @onchange="e => paper_border = e.Value.ToString()" />
Border: <input type="color" value="@paper_border" @onchange="e => paper_border = e.Value!.ToString()!"/>
</div>
</div>
<div class="color background">
<div>Background</div>
<div>
Base: <input type="color" value="@background" @onchange="e => background = e.Value.ToString()" />
Base: <input type="color" value="@background" @onchange="e => background = e.Value!.ToString()!"/>
</div>
</div>
<div class="color info">
<div>Info</div>
<div>
Base: <input type="color" value="@info" @onchange="e => info = e.Value.ToString()" />
Base: <input type="color" value="@info" @onchange="e => info = e.Value!.ToString()!"/>
</div>
</div>
</div>

2
IGP/Pages/MakingOf/Parts/MakingOfDialogs.razor

@ -2,7 +2,6 @@
<Title>Dialog</Title>
<Description>...</Description>
<Example>
<DialogComponent></DialogComponent>
</Example>
<Usage>
//TODO
@ -12,7 +11,6 @@
</Code>
</MakingOfComponent>
@code {
}

9
IGP/Pages/MakingOf/Parts/MakingOfDisplays.razor

@ -12,7 +12,8 @@
Example Entity Content
</div>
@for (var i = 0; i < 1; i++) {
@for (var i = 0; i < 1; i++)
{
<div>
-@i Example Entity Content
</div>
@ -27,7 +28,8 @@
Example Entity Content
</div>
@for (var i = 0; i < 2; i++) {
@for (var i = 0; i < 2; i++)
{
<div>
-@i Example Entity Content
</div>
@ -42,7 +44,8 @@
Example Entity Content
</div>
@for (var i = 0; i < 1; i++) {
@for (var i = 0; i < 1; i++)
{
<div>
-@i Example Entity Content
</div>

2
IGP/Pages/MakingOf/Parts/MakingOfFeedback.razor

@ -12,7 +12,7 @@
<Example>
<div style="width: 300px; height: 450px;">
<LoadingComponent></LoadingComponent>
<LoadingComponent/>
</div>
</Example>
<Usage>

40
IGP/Pages/MemoryTester/Parts/UnitMemory.razor

@ -7,14 +7,16 @@
<Display>@EntityMemory.Name</Display>
</FormDisplayComponent>
@foreach (var question in questions) {
@foreach (var question in questions)
{
var questionWrong = hasBeenSubmitted && !question.IsRevealed && question.Guess != question.Answer;
<FormGuessComponent IsSubmitted="hasBeenSubmitted"
OnChange="answerEventArgs => OnAnswerEntered(answerEventArgs, question)"
MemoryQuestion="question"/>
@if (questionWrong) {
@if (questionWrong)
{
<div class="wrongAnswer">The correct answer was @question.Answer</div>
}
}
@ -48,9 +50,9 @@
@code {
[Parameter]
public MemoryEntityModel EntityMemory { get; set; }
public MemoryEntityModel EntityMemory { get; set; } = default!;
private List<MemoryQuestionModel> questions { get; set; }
private List<MemoryQuestionModel> questions { get; set; } = default!;
private bool hasBeenSubmitted = false;
private bool isCorrect = false;
@ -58,40 +60,49 @@
public int Guess { get; set; }
protected override void OnInitialized() {
protected override void OnInitialized()
{
MemoryTesterService.Subscribe(OnMemoryEvent);
OnRefresh();
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
MemoryTesterService.Unsubscribe(OnMemoryEvent);
}
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent) {
if (memoryTesterEvent == MemoryTesterEvent.OnVerify) {
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent)
{
if (memoryTesterEvent == MemoryTesterEvent.OnVerify)
{
OnVerify();
}
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh) {
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh)
{
OnRefresh();
}
}
public void OnAnswerEntered(AnswerEventArgs answerEventArgs, MemoryQuestionModel question) {
public void OnAnswerEntered(AnswerEventArgs answerEventArgs, MemoryQuestionModel question)
{
question.Guess = answerEventArgs.Guess;
MemoryTesterService.Update(question);
}
void OnVerify() {
void OnVerify()
{
hasBeenSubmitted = true;
isCorrect = true;
foreach (var question in questions) {
if (question.Answer != question.Guess) {
foreach (var question in questions)
{
if (question.Answer != question.Guess)
{
isCorrect = false;
isWrong = true;
return;
@ -101,7 +112,8 @@
StateHasChanged();
}
void OnRefresh() {
void OnRefresh()
{
hasBeenSubmitted = false;
isCorrect = false;
isWrong = false;

31
IGP/Pages/MemoryTester/Parts/UnitMemoryManager.razor

@ -4,8 +4,10 @@
<div class="quizContainer">
<div class="quizListContainer">
@if (entities != null && questions != null) {
@foreach (var entityMemory in entities) {
@if (entities != null && questions != null)
{
@foreach (var entityMemory in entities)
{
<UnitMemory EntityMemory="entityMemory"></UnitMemory>
}
}
@ -57,25 +59,30 @@
@code {
private List<MemoryEntityModel> entities;
private List<MemoryQuestionModel> questions;
private List<MemoryEntityModel> entities = null!;
private List<MemoryQuestionModel> questions = null!;
protected override void OnInitialized() {
protected override void OnInitialized()
{
MemoryTesterService.Subscribe(OnMemoryEvent);
MemoryTesterService.GenerateQuiz();
}
void IDisposable.Dispose() {
void IDisposable.Dispose()
{
MemoryTesterService.Unsubscribe(OnMemoryEvent);
}
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent) {
if (memoryTesterEvent == MemoryTesterEvent.OnVerify) {
void OnMemoryEvent(MemoryTesterEvent memoryTesterEvent)
{
if (memoryTesterEvent == MemoryTesterEvent.OnVerify)
{
StateHasChanged();
}
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh) {
if (memoryTesterEvent == MemoryTesterEvent.OnRefresh)
{
entities = MemoryTesterService.GetEntities();
questions = MemoryTesterService.GetQuestions();
@ -83,11 +90,13 @@
}
}
void OnSubmitQuiz(EventArgs eventArgs) {
void OnSubmitQuiz(EventArgs eventArgs)
{
MemoryTesterService.Verify();
}
void OnRefreshQuiz(EventArgs eventArgs) {
void OnRefreshQuiz(EventArgs eventArgs)
{
MemoryTesterService.GenerateQuiz();
}

140
IGP/Pages/Notes/NotesIndexPage.razor

@ -0,0 +1,140 @@
@layout PageLayout
@inject INoteService noteService
@implements IDisposable
@page "/notes"
@if (!noteService.IsLoaded())
{
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<PaperComponent>
@foreach (var noteSection in noteService.NoteSectionModels)
{
<div class="noteSectionContainer">
<div class="noteSectionTitle">@noteSection.Name</div>
<div class="noteContentContainer">
@foreach (var noteContent in noteSection.NoteContentModels)
{
<NavLink class="noteContentLink" href="@noteContent.GetNoteLink()">
<div class="noteContentName">@noteContent.Name</div>
<div class="noteContentDescription">@noteContent.Description</div>
</NavLink>
}
</div>
</div>
}
</PaperComponent>
</LayoutMediumContentComponent>
}
<style>
.noteSectionContainer {
width: 100%;
padding: 8px;
}
.noteSectionTitle {
font-size: 3rem;
font-weight: bold;
text-align: center;
margin-bottom: 32px;
}
.noteContentContainer {
display: grid;
gap: 12px;
grid-template-columns: 1fr 1fr;
}
@@media only screen and (max-width: 1025px) {
.noteContentContainer {
grid-template-columns: 1fr;
}
}
.noteContentName {
font-weight: bold;
font-size: 1.6rem;
}
.noteContentDescription {
font-weight: normal;
}
.noteContentLink {
background-color: var(--paper);
border: 1px solid var(--paper-border);
border-radius: 2px;
padding-left: 12px;
padding-right: 12px;
padding-top: 24px;
padding-bottom: 24px;
color: white;
display: flex;
flex-direction: column;
gap: 12px;
text-align: center;
margin-left: 12px;
margin-right: 12px;
}
.noteContentLink:hover {
background-color: var(--paper-hover);
border-color: var(--paper-border-hover);
text-decoration: none;
box-shadow: 0 4px 6px rgba(0,0,0,0.6);
transform: translateY(-2px) scale(1.01);
}
</style>
@code {
[Parameter]
public string? Href1 { get; set; }
[Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
string selectedSection = "All";
protected override void OnInitialized()
{
noteService.Subscribe(StateHasChanged);
noteService.Load();
}
public void Dispose()
{
noteService.Unsubscribe(StateHasChanged);
}
void OnSectionChanged(ChangeEventArgs e)
{
selectedSection = e.Value!.ToString()!;
StateHasChanged();
}
}

126
IGP/Pages/Notes/NotesPage.razor

@ -1,109 +1,71 @@
@layout PageLayout
@inject INoteService NoteService
@inject INoteService noteService
@implements IDisposable
@page "/notes"
@page "/notes/{href1}/{href2?}/{href3?}/{href4?}/{href5?}"
@if (!NoteService.IsLoaded())
@if (!noteService.IsLoaded())
{
<LoadingComponent></LoadingComponent>
<LoadingComponent/>
}
else
{
<LayoutMediumContentComponent>
<WebsiteTitleComponent>Notes</WebsiteTitleComponent>
<div class="section">
<div for="noteSection">Section: </div>
<div style="flex: 1"></div>
<select @oninput="OnSectionChanged" style="background-color: #36393F; width: 250px; margin-right: 16px;" name="noteSection">
<option value="All">All</option>
</select>
</div>
<div class="notesContainer">
@foreach (var note in NoteService.NoteModels) {
if (note.IsHidden) {
continue;
<LayoutWithSidebarComponent>
<Sidebar>
<NoteNavComponent
Connections="noteService.NoteConnectionModels"
Notes="noteService.NoteContentModels"/>
</Sidebar>
<Content>
<PaperComponent>
@foreach (var note in noteService.NoteContentModels)
{
if (!note.Href.Equals(Href))
{
continue;
}
<NoteComponent NoteContentModel="note"/>
}
if (selectedSection != "All" && note.Section != selectedSection) {
continue;
}
@if (note.IsPreAlpha) {
<AlertComponent Type=SeverityType.Warning>
<Title>Pre Alpha</Title>
<Message>This note refers to content that is in pre-alpha. It won't be accurate in future updates to IGP.</Message>
</AlertComponent>
}
<PaperComponent>
<div style="display: flex; flex-direction: row;">
<span style="font-weight: bold; font-style:italic;">@note.Section</span>
<div style="flex: 1"></div>
<span style="font-weight: bold; font-style:italic;">Last Updated on @note.LastUpdated</span>
</div>
<div>
<div id="@note.DEPRECATED_Id()" style="font-weight: bold; font-size: 1.4rem;">@note.Name</div>
<div style="white-space:break-spaces;">@((MarkupString)note.Description)</div>
</div>
</PaperComponent>
}
</div>
</LayoutMediumContentComponent>
</PaperComponent>
</Content>
</LayoutWithSidebarComponent>
}
<style>
.section {
display: flex;
width: 500px;
flex-direction: row;
background-color: var(--paper);
justify-content: center;
padding: 24px;
border: 4px solid var(--paper-border);
box-shadow: 0px 6px var(--paper-border);
}
.notesContainer {
display: flex;
flex-direction: column;
gap: 16px;
}
<style>
.noteContainer {
padding: 24px;
border: 2px solid black;
margin: auto;
overflow-y: auto;
overflow-x: hidden;
background-color: var(--paper);
}
</style>
@code {
string selectedSection = "All";
[Parameter]
public string? Href1 { get; set; }
[Parameter]
public string? Href2 { get; set; }
[Parameter]
public string? Href3 { get; set; }
[Parameter]
public string? Href4 { get; set; }
[Parameter]
public string? Href5 { get; set; }
private string Href => Href5 ?? Href4 ?? Href3 ?? Href2 ?? Href1 ?? "";
protected override void OnInitialized()
{
NoteService.Subscribe(StateHasChanged);
NoteService.Load();
noteService.Subscribe(StateHasChanged);
noteService.Load();
}
public void Dispose()
{
NoteService.Unsubscribe(StateHasChanged);
noteService.Unsubscribe(StateHasChanged);
}
void OnSectionChanged(ChangeEventArgs e) {
selectedSection = e.Value.ToString();
StateHasChanged();
}
}

35
IGP/Pages/Notes/Parts/NoteComponent.razor

@ -0,0 +1,35 @@
<div class="note">
<div class="noteHeader">
<div class="noteTitle">@NoteContentModel.Name</div>
<div class="noteDates">
<div class="noteDateUpdated"><b>Updated</b>: @NoteContentModel.UpdatedDate.ToString("MM/dd/yyyy")</div>
<div class="noteDateCreated"><b>Created</b>: @NoteContentModel.CreatedDate.ToString("MM/dd/yyyy")</div>
</div>
</div>
<div class="noteContent">@((MarkupString)Markdown.ToHtml(NoteContentModel.Content))</div>
</div>
<style>
.noteTitle {
font-weight: bold;
}
.noteHeader {
display: flex;
justify-content: space-between;
}
.noteDates {
display: flex;
flex-direction: column;
}
</style>
@code {
[Parameter]
public NoteContentModel NoteContentModel { get; set; } = default!;
}

75
IGP/Pages/Notes/Parts/NoteInnerNavComponent.razor

@ -0,0 +1,75 @@
@if (Note!.NoteContentModels.Count > 0)
{
<div class="noteInnerNavContainer">
@foreach (var innerNote in Note.NoteContentModels)
{
var linkStyle = $"noteInnerNavButton inner_{Layers}";
<NavLink class="@linkStyle" href="@innerNote.GetNoteLink()">@innerNote.Name</NavLink>
<NoteInnerNavComponent Note="@innerNote" Layers="@IncrementLayers()"/>
}
</div>
}
<style>
.noteInnerNavContainer {
display: flex;
flex-direction: column;
}
.noteInnerNavButton a {
color: white;
}
.noteInnerNavButton a:hover {
color: white;
}
.noteInnerNavButton {
padding: 8px;
margin-left: 8px;
color: white;
}
.noteInnerNavButton:hover {
}
.inner_1 {
margin-left: 8px;
}
.inner_2 {
margin-left: 16px;
}
.inner_3 {
margin-left: 24px;
}
</style>
@code {
[Parameter]
public NoteContentModel? Note { get; set; } = default!;
[Parameter]
public int Layers { get; set; } = 1;
public int IncrementLayers()
{
return Layers + 1;
}
private string GetLink(NoteContentModel note)
{
return $"notes/{note.Href}";
}
}

43
IGP/Pages/Notes/Parts/NoteNavComponent.razor

@ -0,0 +1,43 @@
<div class="noteNavContainer">
@foreach (var note in Notes)
{
if (note.Parent == null)
{
<NavLink class="noteNavButton" href="@note.GetNoteLink()">@note.Name</NavLink>
<NoteInnerNavComponent Note="@note"/>
}
}
</div>
<style>
.noteNavContainer {
display: flex;
flex-direction: column;
}
.noteNavButton a {
color: white;
}
.noteNavButton a:hover {
color: white;
background-color: var(--primary-hover);
}
.noteNavButton {
padding: 8px;
color: white;
}
</style>
@code {
[Parameter]
public List<NoteContentModel> Notes { get; set; } = default!;
[Parameter]
public List<NoteConnectionModel> Connections { get; set; } = default!;
}

3
IGP/Pages/RoadMap/Parts/RoadMapComponent.razor

@ -1,4 +1,4 @@
<div class="roadMapContainer @RoadMap.Status.ToLower()">
<div class="roadMapContainer @RoadMap!.Status.ToLower()">
<div class="roadMapTitle">@RoadMap.Name</div>
<div>
<b>Priority:</b> @RoadMap.Priority.Replace("_", " ")
@ -53,6 +53,7 @@
</style>
@code {
[Parameter]
public ImmortalRoadMapModel? RoadMap { get; set; }

3
IGP/Pages/RoadMap/RoadMapPage.razor

@ -6,7 +6,8 @@
<WebsiteTitleComponent>Road Map</WebsiteTitleComponent>
<div class="roadMapsContainer">
@foreach (var roadMap in data) {
@foreach (var roadMap in data)
{
<RoadMapComponent RoadMap=roadMap/>
}
</div>

229
IGP/Pages/SandboxPage.razor

@ -1,229 +0,0 @@
@layout PageLayout
@page "/sandbox"
@inject IJSRuntime JS
<LayoutLargeContentComponent>
<WebsiteTitleComponent>Sandbox</WebsiteTitleComponent>
<div>
Generic Page of Testing In Progress code
</div>
<button @onclick="() => DownloadFile(typeof(WebPageModel))">
WebPageModel
</button>
<button @onclick="() => DownloadFile(typeof(WebSectionModel))">
WebSectionModel
</button>
<button @onclick="() => DownloadFile(typeof(PatchModel))">
PatchModel
</button>
<button @onclick="() => DownloadFile(typeof(ChangeModel))">
ChangeModel
</button>
<button @onclick="() => DownloadFile(typeof(SprintModel))">
SprintModel
</button>
<button @onclick="() => DownloadFile(typeof(TaskModel))">
TaskModel
</button>
<FormLayoutComponent>
<FormTextAreaComponent Value="@infoText"></FormTextAreaComponent>
</FormLayoutComponent>
</LayoutLargeContentComponent>
@code {
readonly List<EntityModel> entities = EntityModel.GetList();
List<EntityInfoModel> infos = new();
string infoText = "";
string weaponText = "";
readonly List<ChangeModel> changes = new();
readonly List<PatchModel> patches = new();
private async Task DownloadFile(Type type) {
var fileName = $"{type.ToString().Split(".").Last()}s.csv";
var objectData =
type == typeof(PatchModel) ? new List<object>(patches)
: type == typeof(ChangeModel) ? new List<object>(changes)
: new List<object>();
await JS.InvokeVoidAsync("download", fileName, Generate(type, objectData));
}
void GenerateEntityModels() {
var properties = typeof(EntityInfoModel).GetProperties();
infoText += "Id,Name,Descriptive,Description,Notes\n";
var id = 1;
foreach (var entity in entities) {
infoText += $"{id++},{entity.Info().Name},{entity.Info().Descriptive},{entity.Info().Description},{entity.Info().Notes}\n";
}
}
string Generate(Type type, List<object> dataList) {
var properties = type.GetProperties();
var generatedText = "";
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>();
if (attributes.Count() > 0) {
continue;
}
generatedText += property.Name;
if (index != properties.Count() - 1) {
generatedText += ",";
}
}
generatedText = generatedText.Trim();
if (generatedText.EndsWith(",")) {
generatedText = generatedText.Remove(generatedText.Length - 1);
}
generatedText += "\n";
foreach (var data in dataList) {
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>();
if (attributes.Count() > 0) {
continue;
}
if (property.GetValue(data) != null) {
generatedText += "\"" + property.GetValue(data).ToString().Replace("\"", "\"\"") + "\"";
if (index != properties.Count() - 1) {
generatedText += ",";
}
}
else {
generatedText += "\"" + " " + "\"";
if (index != properties.Count() - 1) {
generatedText += ",";
}
}
}
generatedText = generatedText.Trim();
if (generatedText.EndsWith(",")) {
generatedText = generatedText.Remove(generatedText.Length - 1);
}
generatedText += "\n";
}
return generatedText;
}
void GenerateWeapons() {
var properties = typeof(EntityWeaponModel).GetProperties();
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>
();
if (attributes.Count() > 0) {
continue;
}
weaponText += property.Name;
if (index != properties.Count() - 1) {
weaponText += ",";
}
}
weaponText += "\n";
foreach (var entity in entities) {
foreach (var weapon in entity.Weapons()) {
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
if (property.GetAccessors().First().IsVirtual) {
continue;
}
var attributes = property.GetCustomAttributes().OfType<ObsoleteAttribute>
();
if (attributes.Count() > 0) {
continue;
}
weaponText += property.GetValue(weapon);
if (index != properties.Count() - 1) {
weaponText += ",";
}
}
weaponText += "\n";
}
}
}
void GenerateExample() {
var properties = typeof(EntityInfoModel).GetProperties();
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
infoText += property.Name;
if (index != properties.Count() - 1) {
infoText += ",";
}
}
infoText += "\n";
foreach (var entity in entities) {
if (entity.Info() != null) {
for (var index = 0; index < properties.Count(); index++) {
var property = properties[index];
infoText += property.GetValue(entity.Info());
if (index != properties.Count() - 1) {
infoText += ",";
}
}
infoText += "\n";
}
}
}
}

9
IGP/Portals/EntityDialogPortal.razor

@ -9,12 +9,14 @@
@code {
protected override void OnInitialized()
{
entityDialogService.Subscribe(OnUpdate);
}
public void Dispose() {
public void Dispose()
{
entityDialogService.Unsubscribe(OnUpdate);
}
@ -23,5 +25,4 @@
StateHasChanged();
}
}
}

15
IGP/Program.cs

@ -1,20 +1,16 @@
using IGP;
using Microsoft.AspNetCore.Components.Web;
using Services;
using Services.Development;
using Services.Immortal;
using Services.Website;
#if NO_SQL
#else
using Contexts;
using Microsoft.EntityFrameworkCore;
#endif
using Services;
using Services.Immortal;
using Services.Website;
using Services.Development;
using IEntityDisplayService = Services.IEntityDisplayService;
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.Logging.SetMinimumLevel(LogLevel.Warning);
@ -37,7 +33,8 @@ builder.Services.AddSingleton<IEntityFilterService, EntityFilterService>();
builder.Services.AddSingleton<IEntityDisplayService, EntityDisplayService>();
builder.Services.AddSingleton(new HttpClient {
builder.Services.AddSingleton(new HttpClient
{
BaseAddress = new Uri(builder.HostEnvironment.BaseAddress)
});

44
IGP/_Imports.razor

@ -1,6 +1,4 @@

@using Components.Display
@using Components.Display
@using Components.Feedback
@using Components.Form
@using Components.Info
@ -9,17 +7,26 @@
@using Components.Navigation
@using Components.Shared
@using Components.Utils
@using IGP.Portals
@using IGP.Pages
@using IGP.Dialog
@using IGP.Pages
@using IGP.Pages.Agile.Parts
@using IGP.Pages.BuildCalculator.Parts
@using IGP.Pages.Comparision
@using IGP.Pages.Comparision.Parts
@using IGP.Pages.Database.Entity
@using IGP.Pages.Database.Entity.Parts
@using IGP.Pages.Database.Parts
@using IGP.Pages.Documentation
@using IGP.Pages.Documentation.Parts
@using IGP.Pages.Home
@using IGP.Pages.Home.Parts
@using IGP.Pages.MakingOf.Parts
@using IGP.Pages.MemoryTester.Parts
@using IGP.Pages.RoadMap.Parts
@using IGP.Pages.Notes
@using IGP.Pages.Notes.Parts
@using IGP.Portals
@using Markdig
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@ -27,21 +34,20 @@
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.EntityFrameworkCore
@using Microsoft.JSInterop
@using Model.Immortal.Chart
@using Model.Immortal.Economy
@using Model.Immortal.Entity
@using Model.Immortal.Entity.Data
@using Model.Immortal.Entity.Parts
@using Model.Immortal.Hotkeys
@using Model.Immortal.MemoryTester
@using Model.Immortal.MemoryTester
@using Model.Immortal.Notes
@using Model.Immortal.RoadMap
@using Model.Immortal.RoadMap
@using Model.Immortal.RoadMap.Enums
@using Model.Immortal.Types
@using Model.Chart
@using Model.Development.Git
@using Model.Doc
@using Model.Economy
@using Model.Entity
@using Model.Entity.Data
@using Model.Entity.Parts
@using Model.Hotkeys
@using Model.MemoryTester
@using Model.Notes
@using Model.RoadMap
@using Model.RoadMap.Enums
@using Model.Types
@using Model.Website
@using Model.Work.Git
@using Model.Work.Tasks
@using Model.Work.Tasks.Enums
@using Services

6
IGP/wwwroot/css/app.css

@ -15,9 +15,13 @@
--secondary-border-hover: #a168ff;
--paper: #252526;
--paper-border: #151516;
--paper-hover: #52366f;
--paper-border-hover: #653497;
--info: #451376;
--info-border: #210b36;
--dialog-border-color: black;
--dialog-border-width: 2px;
--dialog-radius: 6px;

1
IGP/wwwroot/generated/AgileSprintModels.json

@ -0,0 +1 @@
[{"Id":1,"Name":"Agile Sprint","Description":"Changelogs and sprint views were going to be pushed till later, but I am feeling inspired by the IGP Content Creators\u0027 minimum weekly lifecycle requirement. So I am going to focus on agile-related tasks, and handle roadmap tasks after this initial sprint. All weekly sprints will release on Sunday, starting next Sunday.","StartDate":"2022-02-14T00:00:00","EndDate":"2022-02-20T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":2,"Name":"SQL Update","Description":"The SQL update is big enough to be a full sprint in of itself, and I spent less time this week for development. Will just extend sprint by 2 week, and remove all non SQL tasks from the sprint.","StartDate":"2022-02-20T00:00:00","EndDate":"2022-03-27T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":3,"Name":"Database Page","Description":"Improvements to the Database page","StartDate":"2022-03-27T00:00:00","EndDate":"2022-04-03T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":4,"Name":"Branding","Description":"Improve streaming branding around the website","StartDate":"2022-04-03T00:00:00","EndDate":"2022-04-10T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":5,"Name":"Calculators","Description":"Improve Calculators","StartDate":"2022-04-10T00:00:00","EndDate":"2022-04-24T00:00:00","Notes":null,"AgileTaskModels":[]},{"Id":6,"Name":"Infrastructure","Description":"Localization, Analytics, and Test Automation","StartDate":"2022-04-24T00:00:00","EndDate":"2022-05-08T00:00:00","Notes":null,"AgileTaskModels":[]}]

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save