Initial commit

This commit is contained in:
2025-09-24 00:56:17 -05:00
commit 7e5e7aad40
35 changed files with 3091 additions and 0 deletions

428
.gitignore vendored Normal file
View File

@@ -0,0 +1,428 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
*.env
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
[Dd]ebug/x64/
[Dd]ebugPublic/x64/
[Rr]elease/x64/
[Rr]eleases/x64/
bin/x64/
obj/x64/
[Dd]ebug/x86/
[Dd]ebugPublic/x86/
[Rr]elease/x86/
[Rr]eleases/x86/
bin/x86/
obj/x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
[Aa][Rr][Mm]64[Ee][Cc]/
bld/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Build results on 'Bin' directories
**/[Bb]in/*
# Uncomment if you have tasks that rely on *.refresh files to move binaries
# (https://github.com/github/gitignore/pull/3736)
#!**/[Bb]in/*.refresh
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*.trx
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Approval Tests result files
*.received.*
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.idb
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
# but not Directory.Build.rsp, as it configures directory-level build defaults
!Directory.Build.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
**/.paket/paket.exe
paket-files/
# FAKE - F# Make
**/.fake/
# CodeRush personal settings
**/.cr/personal
# Python Tools for Visual Studio (PTVS)
**/__pycache__/
*.pyc
# Cake - Uncomment if you are using it
#tools/**
#!tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
MSBuild_Logs/
# AWS SAM Build and Temporary Artifacts folder
.aws-sam
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
**/.mfractor/
# Local History for Visual Studio
**/.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
**/.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp

25
NethackHelper.sln Normal file
View File

@@ -0,0 +1,25 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.5.33516.290
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NethackHelper", "NethackHelper\NethackHelper.csproj", "{551E16E7-B2D3-4143-AF0E-BE4691712B60}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{551E16E7-B2D3-4143-AF0E-BE4691712B60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{551E16E7-B2D3-4143-AF0E-BE4691712B60}.Debug|Any CPU.Build.0 = Debug|Any CPU
{551E16E7-B2D3-4143-AF0E-BE4691712B60}.Release|Any CPU.ActiveCfg = Release|Any CPU
{551E16E7-B2D3-4143-AF0E-BE4691712B60}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0CE91709-1817-4270-943D-93170193950A}
EndGlobalSection
EndGlobal

50
NethackHelper/Charisma.cs Normal file
View File

@@ -0,0 +1,50 @@
namespace NethackHelper {
using System.Collections.Generic;
using System.Windows.Forms;
public struct CharismaClass {
public string DisplayName { get; private set; } = string.Empty;
public double Multiplier { get; private set; }
public CharismaClass() { }
public static List<CharismaClass> Classes = [
new() {
DisplayName = "CHA 5-",
Multiplier = 2.0,
},
new() {
DisplayName = "CHA 6 - 7",
Multiplier = 1.5,
},
new() {
DisplayName = "CHA 8 - 10",
Multiplier = 1.3333,
},
new() {
DisplayName = "CHA 11 - 15",
Multiplier = 1.0,
},
new() {
DisplayName = "CHA 16 - 17",
Multiplier = 0.75,
},
new() {
DisplayName = "CHA 18",
Multiplier = 0.6667,
},
new() {
DisplayName = "CHA 19+",
Multiplier = 0.5,
},
];
public static readonly CharismaClass DefaultClass = Classes[3];
}
public class CharismaSource : BindingSource {
public CharismaSource() {
this.DataSource = CharismaClass.Classes;
}
}
}

21
NethackHelper/Item.cs Normal file
View File

@@ -0,0 +1,21 @@
namespace NethackHelper {
using System.Collections.Generic;
public class Item {
public string Name { get; set; } = string.Empty;
public int Cost { get; set; }
public int Ink { get; set; }
public string? Appearance { get; set; }
}
public class ItemList {
public List<Item> Items { get; set; } = new();
}
public enum ItemAttribute {
Name,
Cost,
Ink,
Appearance,
}
}

72
NethackHelper/ItemDisplay.Designer.cs generated Normal file
View File

@@ -0,0 +1,72 @@
namespace NethackHelper {
partial class ItemDisplay {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
itemListView = new System.Windows.Forms.ListView();
nameColumn = new System.Windows.Forms.ColumnHeader();
appearanceColumn = new System.Windows.Forms.ColumnHeader();
SuspendLayout();
//
// itemListView
//
itemListView.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
itemListView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { nameColumn, appearanceColumn });
itemListView.FullRowSelect = true;
itemListView.Location = new System.Drawing.Point(0, 0);
itemListView.MultiSelect = false;
itemListView.Name = "itemListView";
itemListView.Size = new System.Drawing.Size(610, 568);
itemListView.Sorting = System.Windows.Forms.SortOrder.Ascending;
itemListView.TabIndex = 0;
itemListView.UseCompatibleStateImageBehavior = false;
itemListView.View = System.Windows.Forms.View.Details;
itemListView.MouseDoubleClick += itemListView_MouseDoubleClick;
//
// nameColumn
//
nameColumn.Text = "Name";
nameColumn.Width = 144;
//
// appearanceColumn
//
appearanceColumn.Text = "Appearance";
appearanceColumn.Width = 144;
//
// ItemDisplay
//
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
Controls.Add(itemListView);
Name = "ItemDisplay";
Size = new System.Drawing.Size(613, 568);
ResumeLayout(false);
}
#endregion
private System.Windows.Forms.ListView itemListView;
private System.Windows.Forms.ColumnHeader nameColumn;
private System.Windows.Forms.ColumnHeader appearanceColumn;
}
}

View File

@@ -0,0 +1,177 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using static System.Windows.Forms.ListViewItem;
using System.ComponentModel;
namespace NethackHelper {
public partial class ItemDisplay : UserControl {
public const string UNIDENTIFIED = "[randomized]";
public static readonly Color SELECTED_COLOR = Color.Black;
public static readonly Color UNSELECTED_COLOR = Color.Gray;
private static readonly Dictionary<ItemAttribute, Func<Item, string>> COLUMN_MAP = new() {
[ItemAttribute.Name] = item => item.Name,
[ItemAttribute.Cost] = item => item.Cost.ToString(),
[ItemAttribute.Ink] = item => item.Ink.ToString(),
[ItemAttribute.Appearance] = item => item.Appearance ?? UNIDENTIFIED,
};
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Func<int, string> CostFormatter { get; set; } = cost => cost.ToString();
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public List<ItemDisplayColumn> Columns { get; set; } = new();
private int[] GroupCosts { get; set; } = [];
private Dictionary<string, string?> AppearanceMap { get; set; } = new();
public ItemDisplay() {
InitializeComponent();
this.itemListView.ListViewItemSorter = Comparer<ListViewItem>.Create(CompareItems);
}
protected override void OnLoad(EventArgs e) {
base.OnLoad(e);
if (this.Columns != null) {
this.itemListView.Columns.Clear();
foreach (var column in this.Columns) {
this.itemListView.Columns.Add(column.Attribute.ToString(), column.Width);
}
}
}
public void DisplayItemList(ItemList itemList, IdentificationRecord? idRecord) {
this.itemListView.Groups.Clear();
this.itemListView.Items.Clear();
this.AppearanceMap.Clear();
this.GroupCosts = itemList.Items.Select(item => item.Cost).Distinct().Order().ToArray();
var costDictionary = new Dictionary<int, ListViewGroup>();
foreach (var cost in this.GroupCosts) {
var group = new ListViewGroup(this.CostFormatter.Invoke(cost), HorizontalAlignment.Center);
this.itemListView.Groups.Add(group);
costDictionary.Add(cost, group);
}
foreach (var item in itemList.Items) {
bool identified = false;
ItemRecord record = default;
if (idRecord != null) {
if (idRecord.TryGetValue(item.Name, out var identity)) {
record = identity;
identified = true;
}
} else if (item.Appearance != null) {
record = new ItemRecord() {
Name = item.Name,
Appearance = item.Appearance,
};
identified = true;
}
AppearanceMap[item.Name] = record.Appearance;
var columns = this.Columns.Select(col => COLUMN_MAP[col.Attribute].Invoke(item)).ToArray();
var listViewItem = new ListViewItem(columns, costDictionary[item.Cost]);
listViewItem.UseItemStyleForSubItems = false;
var baseFont = new Font(this.itemListView.Font, FontStyle.Regular);
var baseColor = UNSELECTED_COLOR;
if (!identified) {
baseFont = new Font(baseFont, FontStyle.Bold);
baseColor = SELECTED_COLOR;
}
listViewItem.Checked = identified;
listViewItem.Font = baseFont;
listViewItem.ForeColor = baseColor;
foreach (ListViewSubItem subItem in listViewItem.SubItems) {
subItem.Font = baseFont;
subItem.ForeColor = baseColor;
}
if (record.Appearance == null) {
var fontStyle = FontStyle.Italic;
if (!identified) {
fontStyle |= FontStyle.Bold;
}
for (var i = 0; i < this.Columns.Count; i++) {
if (this.Columns[i].Attribute == ItemAttribute.Appearance) {
listViewItem.SubItems[i].Font = new Font(baseFont, fontStyle);
}
}
}
this.itemListView.Items.Add(listViewItem);
}
}
public IdentificationRecord Export() {
List<ItemRecord> records = [];
foreach (ListViewItem item in this.itemListView.Items) {
if (item.Checked) {
string? appearance = this.AppearanceMap[item.Text];
records.Add(new() {
Name = item.Text,
Appearance = appearance,
});
}
}
return new(records);
}
public void UpdateCostHeaders() {
for (int i = 0; i < this.GroupCosts.Length; i++) {
this.itemListView.Groups[i].Header = this.CostFormatter.Invoke(this.GroupCosts[i]);
}
}
private void itemListView_MouseDoubleClick(object sender, MouseEventArgs e) {
if (this.itemListView.SelectedItems.Count == 1) {
var item = this.itemListView.SelectedItems[0];
item.Checked = !item.Checked;
var baseFont = item.Font;
foreach (ListViewSubItem subItem in item.SubItems) {
if (item.Checked) {
if (subItem.Font.Italic) {
subItem.Font = new Font(baseFont, FontStyle.Italic);
} else {
subItem.Font = new Font(baseFont, FontStyle.Regular);
}
subItem.ForeColor = UNSELECTED_COLOR;
} else {
if (subItem.Font.Italic) {
subItem.Font = new Font(baseFont, FontStyle.Bold | FontStyle.Italic);
} else {
subItem.Font = new Font(baseFont, FontStyle.Bold | FontStyle.Regular);
}
subItem.ForeColor = SELECTED_COLOR;
}
}
this.itemListView.Sort();
}
}
private static int CompareItems(ListViewItem a, ListViewItem b) {
if (a.Checked != b.Checked) {
return a.Checked.CompareTo(b.Checked);
} else {
return a.Text.CompareTo(b.Text);
}
}
}
[Serializable]
public class ItemDisplayColumn {
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ItemAttribute Attribute { get; set; }
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public int Width { get; set; }
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

656
NethackHelper/MainForm.Designer.cs generated Normal file
View File

@@ -0,0 +1,656 @@
using System.Drawing;
using System.Windows.Forms;
namespace NethackHelper {
partial class MainForm : Form {
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing) {
if (disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent() {
components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
CharismaClass charismaClass8 = new CharismaClass();
CharismaClass charismaClass9 = new CharismaClass();
CharismaClass charismaClass10 = new CharismaClass();
CharismaClass charismaClass11 = new CharismaClass();
CharismaClass charismaClass12 = new CharismaClass();
CharismaClass charismaClass13 = new CharismaClass();
CharismaClass charismaClass14 = new CharismaClass();
mainTabControl = new TabControl();
itemsTab = new TabPage();
suckerBox = new CheckBox();
saveSourceBindingSource = new BindingSource(components);
shoppingTabControl = new TabControl();
scrollPotionTab = new TabPage();
potionDisplay = new ItemDisplay();
scrollDisplay = new ItemDisplay();
wandRingTab = new TabPage();
ringDisplay = new ItemDisplay();
wandDisplay = new ItemDisplay();
charismaSelector = new ComboBox();
charismaSourceBindingSource = new BindingSource(components);
intrinsicsTab = new TabPage();
label2 = new Label();
lastPrayerPicker = new NumericUpDown();
intrinsicsBindingSource = new BindingSource(components);
label1 = new Label();
protectionPicker = new NumericUpDown();
warningCheckbox = new CheckBox();
teleportitisCheckbox = new CheckBox();
teleportControlCheckbox = new CheckBox();
telepathyCheckbox = new CheckBox();
stealthCheckbox = new CheckBox();
speedCheckbox = new CheckBox();
sleepResistanceCheckbox = new CheckBox();
shockResistanceCheckbox = new CheckBox();
seeInvisibleCheckbox = new CheckBox();
searchingCheckbox = new CheckBox();
poisonResistanceCheckbox = new CheckBox();
invisibleCheckbox = new CheckBox();
fireResistanceCheckbox = new CheckBox();
disintegrationResistanceCheckbox = new CheckBox();
coldResistanceCheckbox = new CheckBox();
sokobanTab = new TabPage();
sokobanVertical = new CheckBox();
sokobanHorizontal = new CheckBox();
sokobanPrev = new Button();
sokobanNext = new Button();
sokobanSolution = new Label();
sokobanLevelList = new ListBox();
mainMenu = new MenuStrip();
fileToolStripMenuItem = new ToolStripMenuItem();
resetToolStripMenuItem = new ToolStripMenuItem();
mainTabControl.SuspendLayout();
itemsTab.SuspendLayout();
((System.ComponentModel.ISupportInitialize) saveSourceBindingSource).BeginInit();
shoppingTabControl.SuspendLayout();
scrollPotionTab.SuspendLayout();
wandRingTab.SuspendLayout();
((System.ComponentModel.ISupportInitialize) charismaSourceBindingSource).BeginInit();
intrinsicsTab.SuspendLayout();
((System.ComponentModel.ISupportInitialize) lastPrayerPicker).BeginInit();
((System.ComponentModel.ISupportInitialize) intrinsicsBindingSource).BeginInit();
((System.ComponentModel.ISupportInitialize) protectionPicker).BeginInit();
sokobanTab.SuspendLayout();
mainMenu.SuspendLayout();
SuspendLayout();
//
// mainTabControl
//
mainTabControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
mainTabControl.Controls.Add(itemsTab);
mainTabControl.Controls.Add(intrinsicsTab);
mainTabControl.Controls.Add(sokobanTab);
mainTabControl.Location = new Point(12, 27);
mainTabControl.Name = "mainTabControl";
mainTabControl.SelectedIndex = 0;
mainTabControl.Size = new Size(672, 621);
mainTabControl.TabIndex = 0;
//
// itemsTab
//
itemsTab.Controls.Add(suckerBox);
itemsTab.Controls.Add(shoppingTabControl);
itemsTab.Controls.Add(charismaSelector);
itemsTab.Location = new Point(4, 24);
itemsTab.Name = "itemsTab";
itemsTab.Padding = new Padding(3);
itemsTab.Size = new Size(664, 593);
itemsTab.TabIndex = 1;
itemsTab.Text = "Items";
itemsTab.UseVisualStyleBackColor = true;
//
// suckerBox
//
suckerBox.AutoSize = true;
suckerBox.DataBindings.Add(new Binding("Checked", saveSourceBindingSource, "Sucker", true));
suckerBox.Location = new Point(133, 8);
suckerBox.Name = "suckerBox";
suckerBox.Size = new Size(61, 19);
suckerBox.TabIndex = 2;
suckerBox.Text = "Sucker";
suckerBox.UseVisualStyleBackColor = true;
suckerBox.CheckedChanged += suckerBox_CheckedChanged;
//
// saveSourceBindingSource
//
saveSourceBindingSource.DataSource = typeof(SaveSource);
saveSourceBindingSource.Position = 0;
//
// shoppingTabControl
//
shoppingTabControl.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
shoppingTabControl.Controls.Add(scrollPotionTab);
shoppingTabControl.Controls.Add(wandRingTab);
shoppingTabControl.Location = new Point(6, 35);
shoppingTabControl.Name = "shoppingTabControl";
shoppingTabControl.SelectedIndex = 0;
shoppingTabControl.Size = new Size(652, 555);
shoppingTabControl.TabIndex = 1;
//
// scrollPotionTab
//
scrollPotionTab.Controls.Add(potionDisplay);
scrollPotionTab.Controls.Add(scrollDisplay);
scrollPotionTab.Location = new Point(4, 24);
scrollPotionTab.Name = "scrollPotionTab";
scrollPotionTab.Padding = new Padding(3);
scrollPotionTab.Size = new Size(644, 527);
scrollPotionTab.TabIndex = 1;
scrollPotionTab.Text = "Scrolls / Potions";
scrollPotionTab.UseVisualStyleBackColor = true;
//
// potionDisplay
//
potionDisplay.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
potionDisplay.Columns = (System.Collections.Generic.List<ItemDisplayColumn>) resources.GetObject("potionDisplay.Columns");
potionDisplay.Location = new Point(325, 6);
potionDisplay.Name = "potionDisplay";
potionDisplay.Size = new Size(313, 515);
potionDisplay.TabIndex = 1;
//
// scrollDisplay
//
scrollDisplay.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
scrollDisplay.Columns = (System.Collections.Generic.List<ItemDisplayColumn>) resources.GetObject("scrollDisplay.Columns");
scrollDisplay.Location = new Point(6, 6);
scrollDisplay.Name = "scrollDisplay";
scrollDisplay.Size = new Size(313, 515);
scrollDisplay.TabIndex = 0;
//
// wandRingTab
//
wandRingTab.Controls.Add(ringDisplay);
wandRingTab.Controls.Add(wandDisplay);
wandRingTab.Location = new Point(4, 24);
wandRingTab.Name = "wandRingTab";
wandRingTab.Padding = new Padding(3);
wandRingTab.Size = new Size(644, 527);
wandRingTab.TabIndex = 2;
wandRingTab.Text = "Wands / Rings";
wandRingTab.UseVisualStyleBackColor = true;
//
// ringDisplay
//
ringDisplay.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right;
ringDisplay.Columns = (System.Collections.Generic.List<ItemDisplayColumn>) resources.GetObject("ringDisplay.Columns");
ringDisplay.Location = new Point(325, 6);
ringDisplay.Name = "ringDisplay";
ringDisplay.Size = new Size(313, 515);
ringDisplay.TabIndex = 2;
//
// wandDisplay
//
wandDisplay.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left;
wandDisplay.Columns = (System.Collections.Generic.List<ItemDisplayColumn>) resources.GetObject("wandDisplay.Columns");
wandDisplay.Location = new Point(6, 6);
wandDisplay.Name = "wandDisplay";
wandDisplay.Size = new Size(313, 515);
wandDisplay.TabIndex = 1;
//
// charismaSelector
//
charismaSelector.DataBindings.Add(new Binding("SelectedItem", saveSourceBindingSource, "CharismaClass", true));
charismaSelector.DataSource = charismaSourceBindingSource;
charismaSelector.DisplayMember = "DisplayName";
charismaSelector.FormattingEnabled = true;
charismaSelector.Items.AddRange(new object[] { charismaClass8, charismaClass9, charismaClass10, charismaClass11, charismaClass12, charismaClass13, charismaClass14 });
charismaSelector.Location = new Point(6, 6);
charismaSelector.Name = "charismaSelector";
charismaSelector.Size = new Size(121, 23);
charismaSelector.TabIndex = 0;
charismaSelector.ValueMember = "Multiplier";
charismaSelector.SelectedIndexChanged += charismaSelector_SelectedIndexChanged;
//
// charismaSourceBindingSource
//
charismaSourceBindingSource.DataSource = typeof(CharismaSource);
charismaSourceBindingSource.Position = 0;
//
// intrinsicsTab
//
intrinsicsTab.Controls.Add(label2);
intrinsicsTab.Controls.Add(lastPrayerPicker);
intrinsicsTab.Controls.Add(label1);
intrinsicsTab.Controls.Add(protectionPicker);
intrinsicsTab.Controls.Add(warningCheckbox);
intrinsicsTab.Controls.Add(teleportitisCheckbox);
intrinsicsTab.Controls.Add(teleportControlCheckbox);
intrinsicsTab.Controls.Add(telepathyCheckbox);
intrinsicsTab.Controls.Add(stealthCheckbox);
intrinsicsTab.Controls.Add(speedCheckbox);
intrinsicsTab.Controls.Add(sleepResistanceCheckbox);
intrinsicsTab.Controls.Add(shockResistanceCheckbox);
intrinsicsTab.Controls.Add(seeInvisibleCheckbox);
intrinsicsTab.Controls.Add(searchingCheckbox);
intrinsicsTab.Controls.Add(poisonResistanceCheckbox);
intrinsicsTab.Controls.Add(invisibleCheckbox);
intrinsicsTab.Controls.Add(fireResistanceCheckbox);
intrinsicsTab.Controls.Add(disintegrationResistanceCheckbox);
intrinsicsTab.Controls.Add(coldResistanceCheckbox);
intrinsicsTab.Location = new Point(4, 24);
intrinsicsTab.Name = "intrinsicsTab";
intrinsicsTab.Padding = new Padding(3);
intrinsicsTab.Size = new Size(664, 593);
intrinsicsTab.TabIndex = 2;
intrinsicsTab.Text = "Intrinsics";
intrinsicsTab.UseVisualStyleBackColor = true;
//
// label2
//
label2.AutoSize = true;
label2.Location = new Point(6, 411);
label2.Name = "label2";
label2.Size = new Size(64, 15);
label2.TabIndex = 18;
label2.Text = "Last Prayer";
//
// lastPrayerPicker
//
lastPrayerPicker.DataBindings.Add(new Binding("Value", intrinsicsBindingSource, "LastPrayer", true));
lastPrayerPicker.Increment = new decimal(new int[] { 1000, 0, 0, 0 });
lastPrayerPicker.Location = new Point(76, 409);
lastPrayerPicker.Maximum = new decimal(new int[] { 100000, 0, 0, 0 });
lastPrayerPicker.Name = "lastPrayerPicker";
lastPrayerPicker.Size = new Size(61, 23);
lastPrayerPicker.TabIndex = 17;
lastPrayerPicker.ThousandsSeparator = true;
//
// intrinsicsBindingSource
//
intrinsicsBindingSource.DataSource = typeof(IntrinsicsSource);
intrinsicsBindingSource.Position = 0;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(6, 382);
label1.Name = "label1";
label1.Size = new Size(62, 15);
label1.TabIndex = 16;
label1.Text = "Protection";
//
// protectionPicker
//
protectionPicker.DataBindings.Add(new Binding("Value", intrinsicsBindingSource, "Protection", true));
protectionPicker.Location = new Point(74, 380);
protectionPicker.Maximum = new decimal(new int[] { 30, 0, 0, 0 });
protectionPicker.Name = "protectionPicker";
protectionPicker.Size = new Size(41, 23);
protectionPicker.TabIndex = 15;
//
// warningCheckbox
//
warningCheckbox.AutoSize = true;
warningCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Warning", true));
warningCheckbox.Location = new Point(6, 355);
warningCheckbox.Name = "warningCheckbox";
warningCheckbox.Size = new Size(71, 19);
warningCheckbox.TabIndex = 14;
warningCheckbox.Text = "Warning";
warningCheckbox.UseVisualStyleBackColor = true;
//
// teleportitisCheckbox
//
teleportitisCheckbox.AutoSize = true;
teleportitisCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Teleportitis", true));
teleportitisCheckbox.Location = new Point(6, 330);
teleportitisCheckbox.Name = "teleportitisCheckbox";
teleportitisCheckbox.Size = new Size(83, 19);
teleportitisCheckbox.TabIndex = 13;
teleportitisCheckbox.Text = "Teleportitis";
teleportitisCheckbox.UseVisualStyleBackColor = true;
//
// teleportControlCheckbox
//
teleportControlCheckbox.AutoSize = true;
teleportControlCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "TeleportControl", true));
teleportControlCheckbox.Location = new Point(6, 305);
teleportControlCheckbox.Name = "teleportControlCheckbox";
teleportControlCheckbox.Size = new Size(111, 19);
teleportControlCheckbox.TabIndex = 12;
teleportControlCheckbox.Text = "Teleport Control";
teleportControlCheckbox.UseVisualStyleBackColor = true;
//
// telepathyCheckbox
//
telepathyCheckbox.AutoSize = true;
telepathyCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Telepathy", true));
telepathyCheckbox.Location = new Point(6, 280);
telepathyCheckbox.Name = "telepathyCheckbox";
telepathyCheckbox.Size = new Size(76, 19);
telepathyCheckbox.TabIndex = 11;
telepathyCheckbox.Text = "Telepathy";
telepathyCheckbox.UseVisualStyleBackColor = true;
//
// stealthCheckbox
//
stealthCheckbox.AutoSize = true;
stealthCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Stealth", true));
stealthCheckbox.Location = new Point(6, 255);
stealthCheckbox.Name = "stealthCheckbox";
stealthCheckbox.Size = new Size(62, 19);
stealthCheckbox.TabIndex = 10;
stealthCheckbox.Text = "Stealth";
stealthCheckbox.UseVisualStyleBackColor = true;
//
// speedCheckbox
//
speedCheckbox.AutoSize = true;
speedCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Speed", true));
speedCheckbox.Location = new Point(6, 230);
speedCheckbox.Name = "speedCheckbox";
speedCheckbox.Size = new Size(58, 19);
speedCheckbox.TabIndex = 9;
speedCheckbox.Text = "Speed";
speedCheckbox.UseVisualStyleBackColor = true;
//
// sleepResistanceCheckbox
//
sleepResistanceCheckbox.AutoSize = true;
sleepResistanceCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "SleepResistance", true));
sleepResistanceCheckbox.Location = new Point(6, 207);
sleepResistanceCheckbox.Name = "sleepResistanceCheckbox";
sleepResistanceCheckbox.Size = new Size(112, 19);
sleepResistanceCheckbox.TabIndex = 8;
sleepResistanceCheckbox.Text = "Sleep Resistance";
sleepResistanceCheckbox.UseVisualStyleBackColor = true;
//
// shockResistanceCheckbox
//
shockResistanceCheckbox.AutoSize = true;
shockResistanceCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "ShockResistance", true));
shockResistanceCheckbox.Location = new Point(6, 182);
shockResistanceCheckbox.Name = "shockResistanceCheckbox";
shockResistanceCheckbox.Size = new Size(116, 19);
shockResistanceCheckbox.TabIndex = 7;
shockResistanceCheckbox.Text = "Shock Resistance";
shockResistanceCheckbox.UseVisualStyleBackColor = true;
//
// seeInvisibleCheckbox
//
seeInvisibleCheckbox.AutoSize = true;
seeInvisibleCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "SeeInvisible", true));
seeInvisibleCheckbox.Location = new Point(6, 157);
seeInvisibleCheckbox.Name = "seeInvisibleCheckbox";
seeInvisibleCheckbox.Size = new Size(90, 19);
seeInvisibleCheckbox.TabIndex = 6;
seeInvisibleCheckbox.Text = "See Invisible";
seeInvisibleCheckbox.UseVisualStyleBackColor = true;
//
// searchingCheckbox
//
searchingCheckbox.AutoSize = true;
searchingCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Searching", true));
searchingCheckbox.Location = new Point(6, 131);
searchingCheckbox.Name = "searchingCheckbox";
searchingCheckbox.Size = new Size(78, 19);
searchingCheckbox.TabIndex = 5;
searchingCheckbox.Text = "Searching";
searchingCheckbox.UseVisualStyleBackColor = true;
//
// poisonResistanceCheckbox
//
poisonResistanceCheckbox.AutoSize = true;
poisonResistanceCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "PoisonResistance", true));
poisonResistanceCheckbox.Location = new Point(6, 106);
poisonResistanceCheckbox.Name = "poisonResistanceCheckbox";
poisonResistanceCheckbox.Size = new Size(120, 19);
poisonResistanceCheckbox.TabIndex = 4;
poisonResistanceCheckbox.Text = "Poison Resistance";
poisonResistanceCheckbox.UseVisualStyleBackColor = true;
//
// invisibleCheckbox
//
invisibleCheckbox.AutoSize = true;
invisibleCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "Invisible", true));
invisibleCheckbox.Location = new Point(6, 81);
invisibleCheckbox.Name = "invisibleCheckbox";
invisibleCheckbox.Size = new Size(69, 19);
invisibleCheckbox.TabIndex = 3;
invisibleCheckbox.Text = "Inivisble";
invisibleCheckbox.UseVisualStyleBackColor = true;
//
// fireResistanceCheckbox
//
fireResistanceCheckbox.AutoSize = true;
fireResistanceCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "FireResistance", true));
fireResistanceCheckbox.Location = new Point(6, 56);
fireResistanceCheckbox.Name = "fireResistanceCheckbox";
fireResistanceCheckbox.Size = new Size(103, 19);
fireResistanceCheckbox.TabIndex = 2;
fireResistanceCheckbox.Text = "Fire Resistance";
fireResistanceCheckbox.UseVisualStyleBackColor = true;
//
// disintegrationResistanceCheckbox
//
disintegrationResistanceCheckbox.AutoSize = true;
disintegrationResistanceCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "DisintegrationResistance", true));
disintegrationResistanceCheckbox.Location = new Point(6, 31);
disintegrationResistanceCheckbox.Name = "disintegrationResistanceCheckbox";
disintegrationResistanceCheckbox.Size = new Size(158, 19);
disintegrationResistanceCheckbox.TabIndex = 1;
disintegrationResistanceCheckbox.Text = "Disintegration Resistance";
disintegrationResistanceCheckbox.UseVisualStyleBackColor = true;
//
// coldResistanceCheckbox
//
coldResistanceCheckbox.AutoSize = true;
coldResistanceCheckbox.DataBindings.Add(new Binding("Checked", intrinsicsBindingSource, "ColdResistance", true));
coldResistanceCheckbox.Location = new Point(6, 6);
coldResistanceCheckbox.Name = "coldResistanceCheckbox";
coldResistanceCheckbox.Size = new Size(109, 19);
coldResistanceCheckbox.TabIndex = 0;
coldResistanceCheckbox.Text = "Cold Resistance";
coldResistanceCheckbox.UseVisualStyleBackColor = true;
//
// sokobanTab
//
sokobanTab.Controls.Add(sokobanVertical);
sokobanTab.Controls.Add(sokobanHorizontal);
sokobanTab.Controls.Add(sokobanPrev);
sokobanTab.Controls.Add(sokobanNext);
sokobanTab.Controls.Add(sokobanSolution);
sokobanTab.Controls.Add(sokobanLevelList);
sokobanTab.Location = new Point(4, 24);
sokobanTab.Name = "sokobanTab";
sokobanTab.Padding = new Padding(3);
sokobanTab.Size = new Size(664, 593);
sokobanTab.TabIndex = 0;
sokobanTab.Text = "Sokoban";
sokobanTab.UseVisualStyleBackColor = true;
//
// sokobanVertical
//
sokobanVertical.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
sokobanVertical.Location = new Point(151, 564);
sokobanVertical.Name = "sokobanVertical";
sokobanVertical.Size = new Size(123, 23);
sokobanVertical.TabIndex = 3;
sokobanVertical.Text = "Vertical Reflection";
sokobanVertical.UseVisualStyleBackColor = true;
sokobanVertical.CheckedChanged += sokobanReflection_CheckedChanged;
sokobanVertical.KeyDown += sokobanLevelList_KeyDown;
//
// sokobanHorizontal
//
sokobanHorizontal.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
sokobanHorizontal.Location = new Point(6, 564);
sokobanHorizontal.Name = "sokobanHorizontal";
sokobanHorizontal.Size = new Size(139, 23);
sokobanHorizontal.TabIndex = 2;
sokobanHorizontal.Text = "Horizontal Reflection";
sokobanHorizontal.UseVisualStyleBackColor = true;
sokobanHorizontal.CheckedChanged += sokobanReflection_CheckedChanged;
sokobanHorizontal.KeyDown += sokobanLevelList_KeyDown;
//
// sokobanPrev
//
sokobanPrev.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
sokobanPrev.Location = new Point(438, 563);
sokobanPrev.Name = "sokobanPrev";
sokobanPrev.Size = new Size(24, 23);
sokobanPrev.TabIndex = 4;
sokobanPrev.Text = "<";
sokobanPrev.UseVisualStyleBackColor = true;
sokobanPrev.Click += sokobanPrev_Click;
sokobanPrev.KeyDown += sokobanLevelList_KeyDown;
//
// sokobanNext
//
sokobanNext.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
sokobanNext.Location = new Point(468, 563);
sokobanNext.Name = "sokobanNext";
sokobanNext.Size = new Size(24, 23);
sokobanNext.TabIndex = 5;
sokobanNext.Text = ">";
sokobanNext.UseVisualStyleBackColor = true;
sokobanNext.Click += sokobanNext_Click;
sokobanNext.KeyDown += sokobanLevelList_KeyDown;
//
// sokobanSolution
//
sokobanSolution.Font = new Font("Consolas", 18F);
sokobanSolution.Location = new Point(6, 6);
sokobanSolution.Name = "sokobanSolution";
sokobanSolution.Size = new Size(486, 554);
sokobanSolution.TabIndex = 1;
//
// sokobanLevelList
//
sokobanLevelList.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right;
sokobanLevelList.FormattingEnabled = true;
sokobanLevelList.IntegralHeight = false;
sokobanLevelList.Location = new Point(498, 6);
sokobanLevelList.Name = "sokobanLevelList";
sokobanLevelList.Size = new Size(160, 581);
sokobanLevelList.TabIndex = 1;
sokobanLevelList.SelectedIndexChanged += sokobanLevelList_SelectedIndexChanged;
sokobanLevelList.KeyDown += sokobanLevelList_KeyDown;
//
// mainMenu
//
mainMenu.Items.AddRange(new ToolStripItem[] { fileToolStripMenuItem });
mainMenu.Location = new Point(0, 0);
mainMenu.Name = "mainMenu";
mainMenu.Size = new Size(696, 24);
mainMenu.TabIndex = 1;
//
// fileToolStripMenuItem
//
fileToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { resetToolStripMenuItem });
fileToolStripMenuItem.Name = "fileToolStripMenuItem";
fileToolStripMenuItem.Size = new Size(37, 20);
fileToolStripMenuItem.Text = "File";
//
// resetToolStripMenuItem
//
resetToolStripMenuItem.Name = "resetToolStripMenuItem";
resetToolStripMenuItem.Size = new Size(102, 22);
resetToolStripMenuItem.Text = "Reset";
//
// MainForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(696, 660);
Controls.Add(mainTabControl);
Controls.Add(mainMenu);
Icon = (Icon) resources.GetObject("$this.Icon");
MainMenuStrip = mainMenu;
MaximizeBox = false;
MaximumSize = new Size(712, 1200);
MinimumSize = new Size(712, 500);
Name = "MainForm";
SizeGripStyle = SizeGripStyle.Hide;
StartPosition = FormStartPosition.CenterScreen;
Text = "NethackHelper";
FormClosing += Form1_FormClosing;
mainTabControl.ResumeLayout(false);
itemsTab.ResumeLayout(false);
itemsTab.PerformLayout();
((System.ComponentModel.ISupportInitialize) saveSourceBindingSource).EndInit();
shoppingTabControl.ResumeLayout(false);
scrollPotionTab.ResumeLayout(false);
wandRingTab.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize) charismaSourceBindingSource).EndInit();
intrinsicsTab.ResumeLayout(false);
intrinsicsTab.PerformLayout();
((System.ComponentModel.ISupportInitialize) lastPrayerPicker).EndInit();
((System.ComponentModel.ISupportInitialize) intrinsicsBindingSource).EndInit();
((System.ComponentModel.ISupportInitialize) protectionPicker).EndInit();
sokobanTab.ResumeLayout(false);
mainMenu.ResumeLayout(false);
mainMenu.PerformLayout();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TabControl mainTabControl;
private TabPage sokobanTab;
private Label sokobanSolution;
private ListBox sokobanLevelList;
private Button sokobanPrev;
private Button sokobanNext;
private CheckBox sokobanVertical;
private CheckBox sokobanHorizontal;
private TabPage itemsTab;
private ComboBox charismaSelector;
private TabControl shoppingTabControl;
private TabPage potionsTab;
private TabPage scrollPotionTab;
private ItemDisplay scrollDisplay;
private ItemDisplay potionDisplay;
private TabPage wandRingTab;
private ItemDisplay ringDisplay;
private ItemDisplay wandDisplay;
private CheckBox suckerBox;
private TabPage intrinsicsTab;
private CheckBox warningCheckbox;
private CheckBox teleportitisCheckbox;
private CheckBox teleportControlCheckbox;
private CheckBox telepathyCheckbox;
private CheckBox stealthCheckbox;
private CheckBox speedCheckbox;
private CheckBox sleepResistanceCheckbox;
private CheckBox shockResistanceCheckbox;
private CheckBox seeInvisibleCheckbox;
private CheckBox searchingCheckbox;
private CheckBox poisonResistanceCheckbox;
private CheckBox invisibleCheckbox;
private CheckBox fireResistanceCheckbox;
private CheckBox disintegrationResistanceCheckbox;
private CheckBox coldResistanceCheckbox;
private Label label2;
private NumericUpDown lastPrayerPicker;
private Label label1;
private NumericUpDown protectionPicker;
private BindingSource intrinsicsBindingSource;
private BindingSource saveSourceBindingSource;
private BindingSource charismaSourceBindingSource;
private MenuStrip mainMenu;
private ToolStripMenuItem fileToolStripMenuItem;
private ToolStripMenuItem resetToolStripMenuItem;
}
}

180
NethackHelper/MainForm.cs Normal file
View File

@@ -0,0 +1,180 @@
namespace NethackHelper {
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
public partial class MainForm : Form {
private readonly List<SokobanSolution> sokobans = new();
private int sokobanStepIndex = 0;
private Dictionary<string, Version> versionMap = new();
private Version defaultVersion;
public MainForm() {
InitializeComponent();
this.scrollDisplay.CostFormatter = GetCostString;
this.potionDisplay.CostFormatter = GetCostString;
this.wandDisplay.CostFormatter = GetCostString;
this.ringDisplay.CostFormatter = GetCostString;
foreach (var filename in Directory.EnumerateFiles("sokoban", "*.yaml")) {
var sokoban = new SokobanSolution(YamlOptions.DeserializeFile<SokobanFile>(filename));
this.sokobans.Add(sokoban);
this.sokobanLevelList.Items.Add(sokoban.Name);
}
var versions = YamlOptions.DeserializeFile<List<Version>>("items/versions.yaml");
defaultVersion = versions[0];
foreach (var version in versions) {
ToolStripMenuItem toolStripItem = new(version.Name);
toolStripItem.Click += (sender, e) => Reset(version);
resetToolStripMenuItem.DropDownItems.Add(toolStripItem);
versionMap[version.Name] = version;
}
this.LoadSave();
}
private void Reset(Version version) {
SaveData.Instance.Reset(version.Name);
this.LoadSave();
}
private void LoadSave() {
var save = SaveData.Instance;
if (!versionMap.TryGetValue(save.Version, out Version version)) {
version = defaultVersion;
save.Version = version.Name;
}
this.Text = "NethackHelper - " + version.Name;
intrinsicsBindingSource.DataSource = save.Intrinsics;
saveSourceBindingSource.ResetItem(0);
var scrolls = YamlOptions.DeserializeFile<ItemList>(Path.Join("items", version.Scrolls));
this.scrollDisplay.DisplayItemList(scrolls, save.Scrolls);
var potions = YamlOptions.DeserializeFile<ItemList>(Path.Join("items", version.Potions));
this.potionDisplay.DisplayItemList(potions, save.Potions);
var wands = YamlOptions.DeserializeFile<ItemList>(Path.Join("items", version.Wands));
this.wandDisplay.DisplayItemList(wands, save.Wands);
var rings = YamlOptions.DeserializeFile<ItemList>(Path.Join("items", version.Rings));
this.ringDisplay.DisplayItemList(rings, save.Rings);
}
private string GetCostString(int cost) {
double buyModifier = (double) (charismaSelector.SelectedValue ?? 1.0);
double sellModifier = 0.5;
if (suckerBox.Checked) {
sellModifier = 0.3333;
buyModifier *= 1.3333;
}
if (cost == 0) {
return string.Format(
"{0} - Buy: {1}/{2}",
cost,
Math.Round(5 * buyModifier),
Math.Round(5 * buyModifier * 1.3333));
}
return string.Format(
"{0} - Buy: {1}/{2}, Sell: {3}/{4}",
cost,
Math.Round(cost * buyModifier),
Math.Round(cost * buyModifier * 1.3333),
Math.Round(cost * sellModifier),
Math.Round(cost * sellModifier * 0.75));
}
private void NextStep() {
if (sokobanLevelList.SelectedIndex >= 0) {
if (sokobanStepIndex < sokobans[sokobanLevelList.SelectedIndex].States.Count - 1) {
sokobanStepIndex++;
DisplaySokoban();
}
}
}
private void PrevStep() {
if (sokobanLevelList.SelectedIndex >= 0) {
if (sokobanStepIndex > 0) {
sokobanStepIndex--;
DisplaySokoban();
}
}
}
private void sokobanNext_Click(object sender, EventArgs e) {
this.NextStep();
}
private void sokobanPrev_Click(object sender, EventArgs e) {
this.PrevStep();
}
private void DisplaySokoban() {
if (sokobanLevelList.SelectedIndex >= 0) {
Reflection reflection = 0;
if (sokobanHorizontal.Checked) {
reflection |= Reflection.HORIZONTAL;
}
if (sokobanVertical.Checked) {
reflection |= Reflection.VERTICAL;
}
sokobanSolution.Text = sokobans[sokobanLevelList.SelectedIndex].States[sokobanStepIndex].GetArrowString(reflection);
} else {
sokobanSolution.Text = "";
}
}
private void sokobanReflection_CheckedChanged(object sender, EventArgs e) {
DisplaySokoban();
}
private void sokobanLevelList_SelectedIndexChanged(object sender, EventArgs e) {
this.sokobanStepIndex = 0;
DisplaySokoban();
}
private void UpdatePrices() {
this.scrollDisplay.UpdateCostHeaders();
this.potionDisplay.UpdateCostHeaders();
this.wandDisplay.UpdateCostHeaders();
this.ringDisplay.UpdateCostHeaders();
}
private void charismaSelector_SelectedIndexChanged(object sender, EventArgs e) {
this.UpdatePrices();
}
private void suckerBox_CheckedChanged(object sender, EventArgs e) {
this.UpdatePrices();
}
private void sokobanLevelList_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Right) {
this.NextStep();
e.Handled = true;
} else if (e.KeyCode == Keys.Left) {
this.PrevStep();
e.Handled = true;
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e) {
var save = SaveData.Instance;
save.Potions = this.potionDisplay.Export();
save.Rings = this.ringDisplay.Export();
save.Scrolls = this.scrollDisplay.Export();
save.Wands = this.wandDisplay.Export();
save.Save();
}
}
}

299
NethackHelper/MainForm.resx Normal file
View File

@@ -0,0 +1,299 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="saveSourceBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>410, 17</value>
</metadata>
<metadata name="saveSourceBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>410, 17</value>
</metadata>
<data name="potionDisplay.Columns" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEROZXRoYWNrSGVscGVyLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAeVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
cmljLkxpc3RgMVtbTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbiwgTmV0aGFja0hlbHBlciwg
Q3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVy
c2lvbgQAACFOZXRoYWNrSGVscGVyLkl0ZW1EaXNwbGF5Q29sdW1uW10CAAAACAgJAwAAAAIAAAAIAAAA
DAQAAAAzTmV0aGFja0hlbHBlciwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMA
AAAAAQAAAAQAAAAEH05ldGhhY2tIZWxwZXIuSXRlbURpc3BsYXlDb2x1bW4EAAAACQUAAAAJBgAAAA0C
BQUAAAAfTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbgIAAAAaPEF0dHJpYnV0ZT5rX19CYWNr
aW5nRmllbGQWPFdpZHRoPmtfX0JhY2tpbmdGaWVsZAQAG05ldGhhY2tIZWxwZXIuSXRlbUF0dHJpYnV0
ZQQAAAAIBAAAAAX5////G05ldGhhY2tIZWxwZXIuSXRlbUF0dHJpYnV0ZQEAAAAHdmFsdWVfXwAIBAAA
AAAAAACQAAAAAQYAAAAFAAAAAfj////5////AwAAAJAAAAAL
</value>
</data>
<data name="scrollDisplay.Columns" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEROZXRoYWNrSGVscGVyLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAeVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
cmljLkxpc3RgMVtbTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbiwgTmV0aGFja0hlbHBlciwg
Q3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVy
c2lvbgQAACFOZXRoYWNrSGVscGVyLkl0ZW1EaXNwbGF5Q29sdW1uW10CAAAACAgJAwAAAAMAAAAmAAAA
DAQAAAAzTmV0aGFja0hlbHBlciwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMA
AAAAAQAAAAQAAAAEH05ldGhhY2tIZWxwZXIuSXRlbURpc3BsYXlDb2x1bW4EAAAACQUAAAAJBgAAAAkH
AAAACgUFAAAAH05ldGhhY2tIZWxwZXIuSXRlbURpc3BsYXlDb2x1bW4CAAAAGjxBdHRyaWJ1dGU+a19f
QmFja2luZ0ZpZWxkFjxXaWR0aD5rX19CYWNraW5nRmllbGQEABtOZXRoYWNrSGVscGVyLkl0ZW1BdHRy
aWJ1dGUEAAAACAQAAAAF+P///xtOZXRoYWNrSGVscGVyLkl0ZW1BdHRyaWJ1dGUBAAAAB3ZhbHVlX18A
CAQAAAAAAAAAcgAAAAEGAAAABQAAAAH3////+P///wIAAAAoAAAAAQcAAAAFAAAAAfb////4////AwAA
AIYAAAAL
</value>
</data>
<data name="ringDisplay.Columns" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEROZXRoYWNrSGVscGVyLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAeVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
cmljLkxpc3RgMVtbTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbiwgTmV0aGFja0hlbHBlciwg
Q3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVy
c2lvbgQAACFOZXRoYWNrSGVscGVyLkl0ZW1EaXNwbGF5Q29sdW1uW10CAAAACAgJAwAAAAIAAAAIAAAA
DAQAAAAzTmV0aGFja0hlbHBlciwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMA
AAAAAQAAAAQAAAAEH05ldGhhY2tIZWxwZXIuSXRlbURpc3BsYXlDb2x1bW4EAAAACQUAAAAJBgAAAA0C
BQUAAAAfTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbgIAAAAaPEF0dHJpYnV0ZT5rX19CYWNr
aW5nRmllbGQWPFdpZHRoPmtfX0JhY2tpbmdGaWVsZAQAG05ldGhhY2tIZWxwZXIuSXRlbUF0dHJpYnV0
ZQQAAAAIBAAAAAX5////G05ldGhhY2tIZWxwZXIuSXRlbUF0dHJpYnV0ZQEAAAAHdmFsdWVfXwAIBAAA
AAAAAACQAAAAAQYAAAAFAAAAAfj////5////AwAAAJAAAAAL
</value>
</data>
<data name="wandDisplay.Columns" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAEROZXRoYWNrSGVscGVyLCBWZXJzaW9uPTEuMC4wLjAsIEN1bHR1
cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49bnVsbAQBAAAAeVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5l
cmljLkxpc3RgMVtbTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbiwgTmV0aGFja0hlbHBlciwg
Q3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsXV0DAAAABl9pdGVtcwVfc2l6ZQhfdmVy
c2lvbgQAACFOZXRoYWNrSGVscGVyLkl0ZW1EaXNwbGF5Q29sdW1uW10CAAAACAgJAwAAAAIAAAAIAAAA
DAQAAAAzTmV0aGFja0hlbHBlciwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1udWxsBwMA
AAAAAQAAAAQAAAAEH05ldGhhY2tIZWxwZXIuSXRlbURpc3BsYXlDb2x1bW4EAAAACQUAAAAJBgAAAA0C
BQUAAAAfTmV0aGFja0hlbHBlci5JdGVtRGlzcGxheUNvbHVtbgIAAAAaPEF0dHJpYnV0ZT5rX19CYWNr
aW5nRmllbGQWPFdpZHRoPmtfX0JhY2tpbmdGaWVsZAQAG05ldGhhY2tIZWxwZXIuSXRlbUF0dHJpYnV0
ZQQAAAAIBAAAAAX5////G05ldGhhY2tIZWxwZXIuSXRlbUF0dHJpYnV0ZQEAAAAHdmFsdWVfXwAIBAAA
AAAAAACQAAAAAQYAAAAFAAAAAfj////5////AwAAAJAAAAAL
</value>
</data>
<metadata name="charismaSourceBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="intrinsicsBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>232, 17</value>
</metadata>
<metadata name="intrinsicsBindingSource.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>232, 17</value>
</metadata>
<metadata name="mainMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>600, 17</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
AAABAAEAQEAAAAEACAAoFgAAFgAAACgAAABAAAAAgAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAADQ0NABYWFgAcHBwAIiIiACYmJgAqKioALi4uADIyMgA1NTUAODg4AEJCQgBFRUUAR0dHAElJ
SQBLS0sAT09PAFFRUQBTU1MAWFhYAF1dXQBgYGAAYmJiAGNjYwBlZWUAZmZmAGhoaABpaWkAampqAGxs
bABubm4AcXFxAHJycgBzc3MAdXV1AHZ2dgB3d3cAeXl5AHp6egB/f38AgICAAIODgwCFhYUAh4eHAImJ
iQCLi4sAjo6OAJGRkQCSkpIAk5OTAJSUlACWlpYAl5eXAJmZmQCbm5sAnJycAJ2dnQCenp4An5+fAKGh
oQCioqIAo6OjAKWlpQCmpqYAp6enAKioqACpqakAqqqqAK2trQCurq4Ar6+vALCwsACysrIAtLS0ALW1
tQC2trYAt7e3ALi4uAC5ubkAurq6ALu7uwC8vLwAvb29AL+/vwDAwMAAwsLCAMTExADFxcUAx8fHAMjI
yADJyckAysrKAMzMzADNzc0Az8/PANDQ0ADR0dEA0tLSANPT0wDU1NQA1dXVANbW1gDX19cA2NjYANnZ
2QDa2toA29vbANzc3ADd3d0A3t7eAN/f3wDg4OAA4eHhAOLi4gDj4+MA5OTkAOXl5QDm5uYA5+fnAOnp
6QDq6uoA6+vrAOzs7ADt7e0A7u7uAO/v7wDx8fEA8vLyAPPz8wD09PQA9fX1APb29gD39/cA+Pj4APn5
+QD6+voA+/v7APz8/AD9/f0A/v7+AP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAdUnGCiomDeGNGGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAABFhjIyMjIyMjIyMjIx1PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAB9+jIyMjIh7c3mEjIyMjH4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAABOAjIyMdjYDAAAAABY+a4t+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAABrjIyMXQYAAAAAAAAAAAAYTQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyjIyMZgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc4yMgQ4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIIyMjEkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFGMjIYMAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABzjIxlAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHioyMRAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJoyMjB8AAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADuMjIsFAAAAJWyH
g2UbAAAjbYOEcDUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOjIx+AAAA
H4eMjIyMghoQhYyMjIyMVwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWoyM
bwAAAGeMjIyMjIxzRoyMjIyMjIxDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AGOMjGYAAAqJjIyEOluMjH2MjGc1b4yMhA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAABrjIxgAAAojIyMVgAAZoyMjIwdAAuBjIxKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAb4yMXAAAN4yMjEIAABeKjIyMCwAAT4yMeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAHGMjFgAAECMjIw3AAAAZoyMjBIAAB6MjIwTAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAABujIxbAABAjIyMNQAAAFKMjIwhAAAAg4yMNgAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAaoyMXgAAOYyMjDoAAAA7jIyMMQAAAG6MjFMAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaMjGMAADKMjIxCAAAAJ4yMjEcAAABajIxlAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABejIxuAAAkjIyMUgAAAA2MjIxaAAAAS4yMdgAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU4yMegAACIuMjGAAAAAAg4yMbQAAAECMjIAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAESMjIUAAAB8jIx6AAAAAHOMjH4AAAA0
jIyIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAzjIyMEAAAXoyMjA4AAABfjIyM
CAAAL4yMjAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAG4yMjCwAADOMjIw9AAAA
TYyMjCIAAC2MjIwJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGjIxFAAAIh4yM
bwAAADeMjIw2AAArjIyMCwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcoyMYQAA
AFuMjIwwAAAkjIyMTAAALoyMjAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFWM
jH8AAAAVh4yMhkY2aYyMjF4AADOMjIoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAujIyMGQAAAEOMjIyMjIyMjIxzAAA4jIyGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAACIiMjEgAAAAAS4uMjIyMjIyMgwAARoyMgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAABnjIxzAAAAAAAoZIGIe15LaYQOAFWMjHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAANYyMjB0AAAAAAAAAAAAAAAABAgBijIxfAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAaDjIxYAAAAAAAAAAAAAAAAAAAAe4yMTwAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUYyMhhAAAAAAAAAAAAAAAAAADYyMjDIAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+GjIxYAAAAAAAAAAAAAAAAADaMjIsOAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUIyMiiMAAAAAAAAAAAAAAABpjIxwAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAd7jIx5CAAAAAAAAAAAAAAcioyMPwAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKoqMjGcEAAAAAAAAAAAAboyM
gAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDjIyMaA4AAAAAAAAB
WYyMjD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFKMjIx/QQkA
AAAla4yMjGcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQoqM
jIyIeXSBjIyMjG4KAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAicIyMjIyMjIyMiVQFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAApWXeDioNxTxQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
</value>
</data>
</root>

View File

@@ -0,0 +1,35 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>disable</ImplicitUsings>
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Content Include="icon.ico" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="YamlDotNet" Version="15.1.6" />
</ItemGroup>
<ItemGroup>
<None Update="items\*.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="sokoban\*.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Form1.resx">
<Generator></Generator>
</EmbeddedResource>
</ItemGroup>
</Project>

17
NethackHelper/Program.cs Normal file
View File

@@ -0,0 +1,17 @@
using System;
using System.Windows.Forms;
namespace NethackHelper {
internal static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="CharismaSource" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>NethackHelper.CharismaSource, NethackHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="Intrinsics" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>NethackHelper.Intrinsics, NethackHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="SaveSource" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>NethackHelper.SaveSource, NethackHelper, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,9 @@
using System;
namespace NethackHelper {
[Flags]
internal enum Reflection {
HORIZONTAL = 0x1,
VERTICAL = 0x2,
}
}

149
NethackHelper/SaveData.cs Normal file
View File

@@ -0,0 +1,149 @@
namespace NethackHelper {
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Forms;
public class SaveData {
private const string SAVE_NAME = "savedata.yaml";
private static SaveData? _instance;
public static SaveData Instance {
get {
_instance ??= new();
return _instance;
}
}
private SaveData() {
var fileName = Path.Combine(Application.UserAppDataPath, SAVE_NAME);
var save = YamlOptions.DeserializeFileOrDefault<SaveFile>(fileName);
if (save != null) {
this.Version = save.Version;
this.CharismaClass = save.CharismaClass;
this.Sucker = save.Sucker;
this.Intrinsics = save.Intrinsics;
if (save.Potions != null && save.Potions.Count > 0) {
this.Potions = new(save.Potions);
}
if (save.Rings != null && save.Rings.Count > 0) {
this.Rings = new(save.Rings);
}
if (save.Scrolls != null && save.Scrolls.Count > 0) {
this.Scrolls = new(save.Scrolls);
}
if (save.Wands != null && save.Wands.Count > 0) {
this.Wands = new(save.Wands);
}
}
}
public void Save() {
var fileName = Path.Combine(Application.UserAppDataPath, SAVE_NAME);
var save = new SaveFile() {
Version = this.Version,
CharismaClass = this.CharismaClass,
Sucker = this.Sucker,
Intrinsics = this.Intrinsics,
Potions = this.Potions?.Export() ?? [],
Rings = this.Rings?.Export() ?? [],
Scrolls = this.Scrolls?.Export() ?? [],
Wands = this.Wands?.Export() ?? [],
};
YamlOptions.SerializeToFile(fileName, save);
}
public void Reset(string version) {
this.Version = version;
this.CharismaClass = CharismaClass.DefaultClass;
this.Sucker = false;
this.Potions = null;
this.Rings = null;
this.Scrolls = null;
this.Wands = null;
this.Intrinsics = new();
}
public string Version { get; set; } = string.Empty;
public CharismaClass CharismaClass { get; set; } = CharismaClass.DefaultClass;
public bool Sucker { get; set; }
public Intrinsics Intrinsics { get; set; } = new();
public IdentificationRecord? Potions { get; set; }
public IdentificationRecord? Rings { get; set; }
public IdentificationRecord? Scrolls { get; set; }
public IdentificationRecord? Wands { get; set; }
}
public struct ItemRecord {
public string Name { get; set; }
public string? Appearance { get; set; }
}
public class IdentificationRecord {
private readonly Dictionary<string, ItemRecord> identifications = new();
public IdentificationRecord(List<ItemRecord> records) {
this.identifications = records.ToDictionary(record => record.Name);
}
public bool HasIdentified(string name) {
return identifications.ContainsKey(name);
}
public bool TryGetValue(string name, out ItemRecord record) {
return identifications.TryGetValue(name, out record);
}
public List<ItemRecord> Export() {
return identifications.Values.ToList();
}
}
public class SaveFile {
public string Version { get; set; } = string.Empty;
public CharismaClass CharismaClass { get; set; } = CharismaClass.DefaultClass;
public bool Sucker { get; set; }
public Intrinsics Intrinsics { get; set; } = new();
public List<ItemRecord> Potions { get; set; } = new();
public List<ItemRecord> Rings { get; set; } = new();
public List<ItemRecord> Scrolls { get; set; } = new();
public List<ItemRecord> Wands { get; set; } = new();
}
public class Intrinsics {
public bool ColdResistance { get; set; }
public bool DisintegrationResistance { get; set; }
public bool FireResistance { get; set; }
public bool Invisible { get; set; }
public bool PoisonResistance { get; set; }
public bool Searching { get; set; }
public bool SeeInvisible { get; set; }
public bool ShockResistance { get; set; }
public bool SleepResistance { get; set; }
public bool Speed { get; set; }
public bool Stealth { get; set; }
public bool Telepathy { get; set; }
public bool TeleportControl { get; set; }
public bool Teleportitis { get; set; }
public bool Warning { get; set; }
public int Protection { get; set; }
public int LastPrayer { get; set; }
}
public class IntrinsicsSource : BindingSource {
public IntrinsicsSource() {
this.DataSource = SaveData.Instance.Intrinsics;
}
}
public class SaveSource : BindingSource {
public SaveSource() {
this.DataSource = SaveData.Instance;
}
}
}

View File

@@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace NethackHelper {
internal class SokobanFile {
public string Name { get; set; } = "";
public string Map { get; set; } = "";
public List<string> Solution { get; set; } = new();
}
}

View File

@@ -0,0 +1,196 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace NethackHelper {
internal class SokobanSolution {
public string Name { get; }
public List<SokobanState> States { get; }
public SokobanSolution(SokobanFile file) {
Name = file.Name;
States = new();
SokobanState current = new(file.Map);
States.Add(current);
foreach (string step in file.Solution) {
current = new SokobanState(current, step);
States.Add(current);
}
}
}
internal class SokobanState {
private static readonly Dictionary<char, char> horizSubstitute = new() {
['←'] = '→',
['→'] = '←',
['┌'] = '┐',
['┐'] = '┌',
['└'] = '┘',
['┘'] = '└',
['├'] = '┤',
['┤'] = '├',
};
private static readonly Dictionary<char, char> vertSubstitute = new() {
['↑'] = '↓',
['↓'] = '↑',
['┌'] = '└',
['┐'] = '┘',
['└'] = '┌',
['┘'] = '┐',
['┬'] = '┴',
['┴'] = '┬',
};
private char[,] Start { get; }
private char[,] Arrows { get; }
private char[,] End { get; }
public SokobanState(string map) {
List<string> lines = new();
int maxLen = 0;
using (StringReader reader = new(map)) {
string? line;
while ((line = reader.ReadLine()) is not null) {
lines.Add(line);
maxLen = Math.Max(maxLen, line.Length);
}
}
Start = new char[lines.Count, maxLen];
for (int y = 0; y < lines.Count; y++) {
for (int x = 0; x < lines[y].Length; x++) {
Start[y, x] = lines[y][x];
}
for (int x = lines[y].Length; x < maxLen; x++) {
Start[y, x] = ' ';
}
}
Arrows = Start;
End = Start;
}
public SokobanState(SokobanState prior, string step) {
Start = prior.End;
Arrows = (char[,]) Start.Clone();
End = (char[,]) Start.Clone();
int height = Start.GetLength(0);
int width = Start.GetLength(1);
int x = 0;
int y = 0;
char boulder = step[0];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (Start[i, j] == boulder) {
x = j;
y = i;
}
}
}
foreach (char c in step[1..]) {
switch (c) {
case ' ':
continue;
case 'u':
if (y == 0) { throw new SokobanError(); }
SetEnd(y - 1, x, boulder);
SetEmpty(y, x);
Arrows[y, x] = '↑';
y--;
break;
case 'd':
if (y >= height - 1) { throw new SokobanError(); }
SetEnd(y + 1, x, boulder);
SetEmpty(y, x);
Arrows[y, x] = '↓';
y++;
break;
case 'l':
if (x == 0) { throw new SokobanError(); }
SetEnd(y, x - 1, boulder);
SetEmpty(y, x);
Arrows[y, x] = '←';
x--;
break;
case 'r':
if (x >= width - 1) { throw new SokobanError(); }
SetEnd(y, x + 1, boulder);
SetEmpty(y, x);
Arrows[y, x] = '→';
x++;
break;
default:
throw new SokobanError();
}
}
}
private void SetEmpty(int y, int x) {
switch (Start[y, x]) {
case '>':
End[y, x] = '>';
break;
default:
End[y, x] = '.';
break;
}
}
private void SetEnd(int y, int x, char boulder) {
switch (Start[y, x]) {
case '.':
case '>':
End[y, x] = boulder;
Arrows[y, x] = boulder;
break;
case '^':
End[y, x] = '.';
Arrows[y, x] = '*';
break;
default:
throw new SokobanError();
}
}
public string GetArrowString(Reflection reflection) {
return GetString(Arrows, reflection);
}
public string GetEndString(Reflection reflection) {
return GetString(End, reflection);
}
private static string GetString(char[,] map, Reflection reflection) {
StringBuilder sb = new();
int height = map.GetLength(0);
int width = map.GetLength(1);
char c;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int mappedI = reflection.HasFlag(Reflection.VERTICAL) ? height - 1 - i : i;
int mappedJ = reflection.HasFlag(Reflection.HORIZONTAL) ? width - 1 - j : j;
c = map[mappedI, mappedJ];
if (reflection.HasFlag(Reflection.HORIZONTAL)) {
c = horizSubstitute.GetValueOrDefault(c, c);
}
if (reflection.HasFlag(Reflection.VERTICAL)) {
c = vertSubstitute.GetValueOrDefault(c, c);
}
sb.Append(c);
}
sb.AppendLine();
}
return sb.ToString();
}
}
public class SokobanError : Exception { }
}

View File

@@ -0,0 +1,9 @@
namespace NethackHelper {
internal struct Version {
public string Name { get; set; }
public string Scrolls { get; set; }
public string Potions { get; set; }
public string Wands { get; set; }
public string Rings { get; set; }
}
}

View File

@@ -0,0 +1,28 @@
namespace NethackHelper {
using System.IO;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
internal class YamlOptions {
private static readonly IDeserializer deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
private static readonly ISerializer serializer = new SerializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();
public static T DeserializeFile<T>(string filename) {
using var reader = new StreamReader(filename);
return deserializer.Deserialize<T>(reader);
}
public static T? DeserializeFileOrDefault<T>(string filename) {
if (File.Exists(filename)) {
using var reader = new StreamReader(filename);
return deserializer.Deserialize<T>(reader);
}
return default;
}
public static void SerializeToFile<T>(string filename, T value) {
using var writer = new StreamWriter(filename);
serializer.Serialize(writer, value);
}
}
}

BIN
NethackHelper/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@@ -0,0 +1,57 @@
items:
- name: Water
cost: 0
appearance: clear
- name: Booze
cost: 50
- name: Fruit Juice
cost: 50
- name: See Invisible
cost: 50
- name: Sickness
cost: 50
- name: Confusion
cost: 100
- name: Extra Healing
cost: 100
- name: Hallucination
cost: 100
- name: Healing
cost: 100
- name: Restore Ability
cost: 100
- name: Sleeping
cost: 100
- name: (Un)Holy Water
cost: 100
appearance: clear
- name: Blindness
cost: 150
- name: Gain Energy
cost: 150
- name: Invisibility
cost: 150
- name: Monster Detection
cost: 150
- name: Object Detection
cost: 150
- name: Enlightenment
cost: 200
- name: Full Healing
cost: 200
- name: Levitation
cost: 200
- name: Polymorph
cost: 200
- name: Speed
cost: 200
- name: Acid
cost: 250
- name: Oil
cost: 250
- name: Gain Ability
cost: 300
- name: Gain Level
cost: 300
- name: Paralysis
cost: 300

View File

@@ -0,0 +1,57 @@
items:
- name: Water
cost: 0
appearance: clear
- name: Healing
cost: 20
- name: Booze
cost: 50
- name: Fruit Juice
cost: 50
- name: See Invisible
cost: 50
- name: Sickness
cost: 50
- name: Confusion
cost: 100
- name: Extra Healing
cost: 100
- name: Hallucination
cost: 100
- name: Restore Ability
cost: 100
- name: Sleeping
cost: 100
- name: (Un)Holy Water
cost: 100
appearance: clear
- name: Blindness
cost: 150
- name: Gain Energy
cost: 150
- name: Invisibility
cost: 150
- name: Monster Detection
cost: 150
- name: Object Detection
cost: 150
- name: Enlightenment
cost: 200
- name: Full Healing
cost: 200
- name: Levitation
cost: 200
- name: Polymorph
cost: 200
- name: Speed
cost: 200
- name: Acid
cost: 250
- name: Oil
cost: 250
- name: Gain Ability
cost: 300
- name: Gain Level
cost: 300
- name: Paralysis
cost: 300

View File

@@ -0,0 +1,57 @@
items:
- name: Adornment
cost: 100
- name: Hunger
cost: 100
- name: Protection
cost: 100
- name: Protection from Shape Changers
cost: 100
- name: Stealth
cost: 100
- name: Sustain Ability
cost: 100
- name: Warning
cost: 100
- name: Aggravate Monster
cost: 150
- name: Cold Resistance
cost: 150
- name: Gain Constitution
cost: 150
- name: Gain Strength
cost: 150
- name: Increase Accuracy
cost: 150
- name: Increase Damage
cost: 150
- name: Invisibility
cost: 150
- name: Poison Resistance
cost: 150
- name: See Invisible
cost: 150
- name: Shock Resistance
cost: 150
- name: Fire Resistance
cost: 200
- name: Free Action
cost: 200
- name: Levitation
cost: 200
- name: Regeneration
cost: 200
- name: Searching
cost: 200
- name: Slow Digestion
cost: 200
- name: Teleportation
cost: 200
- name: Conflict
cost: 300
- name: Polymorph
cost: 300
- name: Polymorph Control
cost: 300
- name: Teleport Control
cost: 300

View File

@@ -0,0 +1,68 @@
items:
- name: Identify
ink: 14
cost: 20
- name: Light
ink: 8
cost: 50
- name: Enchant Weapon
ink: 16
cost: 60
- name: Blank Paper
ink: 0
cost: 60
appearance: unlabeled
- name: Enchant Armor
ink: 16
cost: 80
- name: Remove Curse
ink: 16
cost: 80
- name: Confuse Monster
ink: 12
cost: 100
- name: Destroy Armor
ink: 10
cost: 100
- name: Fire
ink: 8
cost: 100
- name: Food Detection
ink: 8
cost: 100
- name: Gold Detection
ink: 8
cost: 100
- name: Magic Mapping
ink: 8
cost: 100
- name: Scare Monster
ink: 20
cost: 100
- name: Teleportation
ink: 20
cost: 100
- name: Amnesia
ink: 8
cost: 200
- name: Create Monster
ink: 10
cost: 200
- name: Earth
ink: 8
cost: 200
- name: Taming
ink: 20
cost: 200
- name: Charging
ink: 16
cost: 300
- name: Genocide
ink: 30
cost: 300
- name: Punishment
ink: 10
cost: 300
- name: Stinking Cloud
ink: 20
cost: 300

View File

@@ -0,0 +1,10 @@
- name: Vanilla 3.6
scrolls: scrolls.yaml
rings: rings.yaml
potions: potions-36.yaml
wands: wands.yaml
- name: Vanilla 3.7
scrolls: scrolls.yaml
rings: rings.yaml
potions: potions-37.yaml
wands: wands.yaml

View File

@@ -0,0 +1,49 @@
items:
- name: Light
cost: 100
- name: Nothing
cost: 100
- name: Digging
cost: 150
- name: Enlightenment
cost: 150
- name: Locking
cost: 150
- name: Magic Missile
cost: 150
- name: Make Invisible
cost: 150
- name: Opening
cost: 150
- name: Probing
cost: 150
- name: Secret Door Detection
cost: 150
- name: Slow Monster
cost: 150
- name: Speed Monster
cost: 150
- name: Striking
cost: 150
- name: Undead Turning
cost: 150
- name: Cold
cost: 175
- name: Fire
cost: 175
- name: Lightning
cost: 175
- name: Sleep
cost: 175
- name: Cancellation
cost: 200
- name: Create Monster
cost: 200
- name: Polymorph
cost: 200
- name: Teleportation
cost: 200
- name: Death
cost: 500
- name: Wishing
cost: 500

View File

@@ -0,0 +1,30 @@
name: Sokoban Level 1a
map: |
┌─┬────┐ ┌────┐
│<│>...└─┘....│
│^├┐.AB....C..│
│^││..DE│.F.G.│
│^││....│.....│
│^│└───┬┘H────┤
│^│ │......│
│^└────┘......│
│..^^^^IJKL...│
│??┌───┐......│
└──┘ └──────┘
solution:
- A d
- B rrrr
- H dd
- J u
- I l
- L u
- K llll
- L dlll lll
- H dlll lll
- J dlll llll u
- F r
- B ddld dddl llll lllu u
- G dlll dddd llll llll uuu
- F lldd dddl llll lllu uuu
- C ddll dddd llll llll uuuu u
- E urrr ddld dddl llll lllu uuuu u

View File

@@ -0,0 +1,49 @@
name: Sokoban Level 2a
map: |
 ┌──┐ ┌─────────┐
┌┘.>└──────┐ │.........│
│..........│ │.........│
│.A┌───┐B─.│ │.........│
│..│...│.C.│ │....<....│
│.D.E....F─┤ │.........│
│.G..H..│..│ │.........│
│.────I.└┐.│ │.........│
│..J...K.│.└┐ │.........│
│.──┐L─...M.└──┴────────+┤
│...│..N─.O.^^^^^^^^^^^^.│
│..P......┌──────────────┘
└───┐..│..│
└──┴──┘
solution:
- P rrru
- O rr
- N dlll ll
- B dd
- C l
- M l
- F u
- B ll
- K d
- M rdrr r
- N rrrr rrru urdr rrr
- K ddll lll
- K rrrr rrru urdr rrrr
- L ddll l
- L rrrr rrru urdr rrrr r
- P rdrr uurd rrrr rrr
- I drdd drru urdr rrrr rrr
- C d
- F l
- A u
- G r
- D u
- E r
- B ddd
- D d
- A d
- B rddd rruu rdrr rrrr rrr
- E rddd rddd rruu rdrr rrrr rrrr
- C lll
- C rddd rddd rruu rdrr rrrr rrrr r
- H rrdd dddr ruur drrr rrrr rrrr r
- J rrrr dddr ruur drrr rrrr rrrr rr

View File

@@ -0,0 +1,35 @@
name: Sokoban Level 2b
map: |
┌────┬────┐ ┌─────────┐
│....│....└─┐ │.........│
│..AB│CD...>│ │.........│
│.....E...┌─┘ │.........│
│....│....│ │....<....│
├─.──┼────┴┐ │.........│
│..F.│.....│ │.........│
│.GH.│I.J.K│ │.........│
│..L.....M.│ │.........│
│.NOP│Q..R.└──────┴────────+┤
│....│..S.T.^^^^^^^^^^^^^^^.│
└────┴──────────────────────┘
solution:
- E lll
- L rrrr r
- R r
- T rr
- S rrrr r
- M ddrr rrr
- R drrr rr
- K dddr rrrr r
- L rrdd rrrr rrr
- J dddr rrrr rrrr r
- O urrr rrrr ddrr rrrr rrr
- P urrr rrrd drrr rrrr rrr
- G drrr rrrr rddr rrrr rrrr rr
- H ldrr rrrr rrdd rrrr rrrr rrrr
- N urrr rrrr rddr rrrr rrrr rrrr
- Q ulll
- Q rrrr rrrd drrr rrrr rrrr rrr
- I dlll
- I rrrr rrrd drrr rrrr rrrr rrrr
- E lddd ddrr rrrr rddr rrrr rrrr rrrr rrrr

View File

@@ -0,0 +1,33 @@
name: Sokoban Level 3a
map: |
  ┌─┬────┐
┌─┘.│....│
│...A....├─┬───────┐
│.─.BC─DE│.│.......│
│.FG─......│.......│
│.─..H.│...│.......│
│....─I└─J─┤...<...│
│..KL..M...│.......│
│.──...│...│.......│
│....─N├───┤.......│
└─┐..O.└───┴──────+┤
│..P>^^^^^^^^^^^.│
└────────────────┘
solution:
- O ll
- P rr
- N ddrr
- L ddd
- O u
- L rrdr rr
- O rddr rrrr r
- K rddd drrr rrrr
- G dddr dddd rrrr rrrr
- F rddd rddd drrr rrrr rr
- M rr
- M llll lddd drrr rrrr rrr
- J uu
- I dddd drrr rrrr rr
- H rddd dddr rrrr rrrr r
- A rr
- C ddrd dddd drrr rrrr rrrr

View File

@@ -0,0 +1,32 @@
name: Sokoban Level 3b
map: |
┌────────┬───┬─────┐
│........│...│.....│
│.AB..─CD│.─.│.....│
│..│.E.F.│GH.│.....│
├─.│..─..│.─.│..<..│
│...┌─.......│.....│
│...│.I.─...┌┤.....│
│.J.│K.│...┌┘│.....│
├─L.│..└───┴─┴────+┤
│..M....^^^^^^^^^^.│
│...│.>┌───────────┘
└───┴──┘
solution:
- M l
- M rrrr rr
- J r
- L drrr rrrr
- J ddrr rrrr r
- A dddd dddr rrrr rrrr
- B lddd dddd rrrr rrrr rr
- E u
- D dd
- F lllu
- E d
- F lldd dddd drrr rrrr rrrr
- E lull dddd dddr rrrr rrrr rrr
- C dlll ulld dddd ddrr rrrr rrrr rrr
- I dddr rrrr rrrr r
- K ddll l
- K rrrr rrrr rrrr rrr

View File

@@ -0,0 +1,51 @@
name: Sokoban Level 4a
map: |
┌────────────────────────┐
│>......^^^^^^^^^^^^^^^^.│
│.......┌──────────────┐.│
└┬─────.└────┐ │.│
│...........│ │.│
│.A.B.C.D.E.│ │.│
┌┴──────.────┤ │.│
│...F.G..H.I.│ │.│
│...J........│ │.│
└┬───.──────┬┘ ┌─────┤.│
│..K.L.M...│ ┌─┤.....│.│
│.....N....│ │.+.....│.│
│.O.P...Q.┌┘ ├─┤.....│.│
┌┴─────.─┬─┘ │.+.....+.│
│..R.....│ ├─┤.....├─┘
│........│ │.+.....│
│...┌────┘ └─┤.....│
└───┘ └─────┘
solution:
- K l
- N rrr
- R rrr
- P rrdd dlll lur
- F ll
- J rddd drrd ddll lllu
- G ll
- H ll
- D lddd llld dddr
- C rddd llld dd
- H ruuu luuu r
- G rrrr uuul uuur r
- F rrrr rruu uluu urrr
- I lllu uulu uurr rr
- C uuuu rrru uulu uurr rrr
- K rruu urrr uuul uuur rrrr r
- L luuu rrru uulu uurr rrrr r
- M lllu uurr ruuu luuu rrrr rrrr
- N llll luuu urrr uuul uuur rrrr rrrr
- R ruuu ullu uurr ruuu luuu rrrr rrrr rr
- P rrru uuul luuu rrru uulu uurr rrrr rrrr r
- J rrrr ruuu ullu uurr ruuu luuu rrrr rrrr rrrr
- D rddd llll lu
- D rr rrru uuul luuu rrru uulu uurr rrrr rrrr rrr
- B rrrd ddll lddd
- B uuuu rrru uulu uurr rrrr rrrr rrrr
- A rrrr rddd llld dd
- A uu uurr ruuu luuu rrrr rrrr rrrr rrr
- E llld ddll lddd
- E uuuu rrru uulu uurr rrrr rrrr rrrr rr

View File

@@ -0,0 +1,53 @@
name: Sokoban Level 4b
map: |
  ┌──────────────────────┐
│..^^^^^^^^^^^^^^^^^^..│
│..┌─────────────────┐.│
┌─┴┐.│ ┌───┐ │.│
│..│A└┐ ┌┘...│ │.│
│.....├──┤.B..│ │.│
│.CD..│..│..E.│ │.│
└┐..FG│...HI.┌┘ │.│
│J..K...│L..│ ┌─────┤.│
│.MN.│..│..O│ ┌─┤.....│.│
│.P.Q└──┤.R.│ │.+.....│.│
│.......│..┌┘ ├─┤.....│.│
└──┐.S..│.┌┘ │.+.....+.│
└┬─.─┘.│ ├─┤.....├─┘
│.T...│ │.+.....│
│>.│..│ └─┤.....│
└──┴──┘ └─────┘
solution:
- T rrru uuu
- R u
- O uu
- I u
- H lll
- K ll
- N d
- F u
- G u
- C u
- C d
- A uuur
- F dd
- F uu uuuu urr
- C u
- D ruuu uurr r
- C rruu uurr rr
- N uuuu uuuu urrr rr
- P ruuu uuuu uurr rrrr
- M ruuu uuuu urrr rrrr
- K uuur uuuu rrrr rrrr
- J uuur ruuu urrr rrrr rr
- H dlll uuuu uuur rrrr rrrr r
- R d
- L ulll dlll uuuu uuur rrrr rrrr rr
- T uuul lldl lluu uuuu urrr rrrr rrrr r
- R luuu llld lllu uuuu uurr rrrr rrrr rrr
- B r
- I dddl uull ldll luuu uuuu rrrr rrrr rrrr rr
- E lldl lldl lluu uuuu urrr rrrr rrrr rrrr
- B dlld llld lllu uuuu uurr rrrr rrrr rrrr rr
- G ddlu uuuu uurr rrrr rrrr rrrr rrr
- Q uulu uuuu uurr rrrr rrrr rrrr rrrr