Allow changing other flags for Recipe List

Closes #276
This commit is contained in:
Kurt
2020-05-31 15:22:12 -07:00
parent 453cee1e49
commit 2dca9f283b
4 changed files with 232 additions and 43 deletions

View File

@@ -106,8 +106,8 @@ public AchievementList Achievements
set => value.ToBytes().CopyTo(Data, Offsets.CountAchievement);
}
public bool[] GetRecipeList() => ArrayUtil.GitBitFlagArray(Data, Offsets.Recipes, Offsets.MaxRecipeID + 1);
public void SetRecipeList(bool[] value) => ArrayUtil.SetBitFlagArray(Data, Offsets.Recipes, value);
public RecipeBook GetRecipeBook() => new RecipeBook(Data.Slice(Offsets.Recipes, RecipeBook.SIZE));
public void SetRecipeBook(RecipeBook book) => book.Save(Data, Offsets.Recipes);
public short[] GetEventFlagsPlayer()
{

View File

@@ -0,0 +1,55 @@
using System.Collections.Generic;
namespace NHSE.Core
{
public class RecipeBook
{
private const int BitFlagArraySize = 0x100;
private const int BitFlagArrayCount = 4;
public const int SIZE = BitFlagArraySize * BitFlagArrayCount;
public const ushort RecipeCount = BitFlagArraySize * 8;
private readonly byte[] Data;
public RecipeBook(byte[] data) => Data = data;
public void Save(byte[] data, int offset) => Data.CopyTo(data, offset);
public bool GetIsKnown(int recipe) => FlagUtil.GetFlag(Data, 0 * BitFlagArraySize, recipe);
public void SetIsKnown(int recipe, bool value = true) => FlagUtil.SetFlag(Data, 0 * BitFlagArraySize, recipe, value);
public bool GetIsMade(int recipe) => FlagUtil.GetFlag(Data, 1 * BitFlagArraySize, recipe);
public void SetIsMade(int recipe, bool value = true) => FlagUtil.SetFlag(Data, 1 * BitFlagArraySize, recipe, value);
public bool GetIsNew(int recipe) => FlagUtil.GetFlag(Data, 2 * BitFlagArraySize, recipe);
public void SetIsNew(int recipe, bool value = true) => FlagUtil.SetFlag(Data, 2 * BitFlagArraySize, recipe, value);
public bool GetIsFavorite(int recipe) => FlagUtil.GetFlag(Data, 3 * BitFlagArraySize, recipe);
public void SetIsFavorite(int recipe, bool value = true) => FlagUtil.SetFlag(Data, 3 * BitFlagArraySize, recipe, value);
public void GiveAll(IReadOnlyDictionary<ushort,ushort> recipes)
{
foreach (var entry in recipes)
{
var index = entry.Key;
bool alreadyHave = GetIsKnown(index);
if (alreadyHave)
continue;
SetIsKnown(index);
SetIsNew(index);
}
}
public void ClearAll()
{
for (int i = 0; i < RecipeCount; i++)
{
SetIsKnown(i, false);
SetIsNew(i, false);
SetIsFavorite(i, false);
SetIsFavorite(i, false);
}
}
}
}

View File

@@ -30,16 +30,20 @@ private void InitializeComponent()
{
this.B_Cancel = new System.Windows.Forms.Button();
this.B_Save = new System.Windows.Forms.Button();
this.CLB_Recipes = new System.Windows.Forms.CheckedListBox();
this.B_All = new System.Windows.Forms.Button();
this.CB_Goto = new System.Windows.Forms.ComboBox();
this.L_Goto = new System.Windows.Forms.Label();
this.LB_Recipes = new System.Windows.Forms.ListBox();
this.CHK_Known = new System.Windows.Forms.CheckBox();
this.CHK_Made = new System.Windows.Forms.CheckBox();
this.CHK_Favorite = new System.Windows.Forms.CheckBox();
this.CHK_New = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// B_Cancel
//
this.B_Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.B_Cancel.Location = new System.Drawing.Point(130, 326);
this.B_Cancel.Location = new System.Drawing.Point(242, 346);
this.B_Cancel.Name = "B_Cancel";
this.B_Cancel.Size = new System.Drawing.Size(72, 23);
this.B_Cancel.TabIndex = 7;
@@ -50,7 +54,7 @@ private void InitializeComponent()
// B_Save
//
this.B_Save.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.B_Save.Location = new System.Drawing.Point(208, 326);
this.B_Save.Location = new System.Drawing.Point(320, 346);
this.B_Save.Name = "B_Save";
this.B_Save.Size = new System.Drawing.Size(72, 23);
this.B_Save.TabIndex = 6;
@@ -58,22 +62,10 @@ private void InitializeComponent()
this.B_Save.UseVisualStyleBackColor = true;
this.B_Save.Click += new System.EventHandler(this.B_Save_Click);
//
// CLB_Recipes
//
this.CLB_Recipes.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.CLB_Recipes.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.CLB_Recipes.FormattingEnabled = true;
this.CLB_Recipes.Location = new System.Drawing.Point(12, 39);
this.CLB_Recipes.Name = "CLB_Recipes";
this.CLB_Recipes.Size = new System.Drawing.Size(268, 274);
this.CLB_Recipes.TabIndex = 8;
//
// B_All
//
this.B_All.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.B_All.Location = new System.Drawing.Point(12, 327);
this.B_All.Location = new System.Drawing.Point(12, 347);
this.B_All.Name = "B_All";
this.B_All.Size = new System.Drawing.Size(82, 23);
this.B_All.TabIndex = 10;
@@ -90,7 +82,7 @@ private void InitializeComponent()
this.CB_Goto.FormattingEnabled = true;
this.CB_Goto.Location = new System.Drawing.Point(78, 12);
this.CB_Goto.Name = "CB_Goto";
this.CB_Goto.Size = new System.Drawing.Size(202, 21);
this.CB_Goto.Size = new System.Drawing.Size(206, 21);
this.CB_Goto.TabIndex = 11;
this.CB_Goto.SelectedValueChanged += new System.EventHandler(this.CB_Goto_SelectedValueChanged);
//
@@ -103,15 +95,74 @@ private void InitializeComponent()
this.L_Goto.Text = "goto:";
this.L_Goto.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// LB_Recipes
//
this.LB_Recipes.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.LB_Recipes.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.LB_Recipes.FormattingEnabled = true;
this.LB_Recipes.ItemHeight = 14;
this.LB_Recipes.Location = new System.Drawing.Point(12, 39);
this.LB_Recipes.Name = "LB_Recipes";
this.LB_Recipes.Size = new System.Drawing.Size(272, 298);
this.LB_Recipes.TabIndex = 13;
this.LB_Recipes.SelectedIndexChanged += new System.EventHandler(this.LB_Recipes_SelectedIndexChanged);
//
// CHK_Known
//
this.CHK_Known.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CHK_Known.Location = new System.Drawing.Point(290, 39);
this.CHK_Known.Name = "CHK_Known";
this.CHK_Known.Size = new System.Drawing.Size(102, 17);
this.CHK_Known.TabIndex = 14;
this.CHK_Known.Text = "Known";
this.CHK_Known.UseVisualStyleBackColor = true;
this.CHK_Known.CheckedChanged += new System.EventHandler(this.CHK_Known_CheckedChanged);
//
// CHK_Made
//
this.CHK_Made.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CHK_Made.Location = new System.Drawing.Point(290, 62);
this.CHK_Made.Name = "CHK_Made";
this.CHK_Made.Size = new System.Drawing.Size(102, 17);
this.CHK_Made.TabIndex = 15;
this.CHK_Made.Text = "Crafted";
this.CHK_Made.UseVisualStyleBackColor = true;
//
// CHK_Favorite
//
this.CHK_Favorite.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CHK_Favorite.Location = new System.Drawing.Point(290, 85);
this.CHK_Favorite.Name = "CHK_Favorite";
this.CHK_Favorite.Size = new System.Drawing.Size(102, 17);
this.CHK_Favorite.TabIndex = 16;
this.CHK_Favorite.Text = "Favorite";
this.CHK_Favorite.UseVisualStyleBackColor = true;
//
// CHK_New
//
this.CHK_New.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.CHK_New.Location = new System.Drawing.Point(290, 108);
this.CHK_New.Name = "CHK_New";
this.CHK_New.Size = new System.Drawing.Size(102, 17);
this.CHK_New.TabIndex = 17;
this.CHK_New.Text = "New";
this.CHK_New.UseVisualStyleBackColor = true;
//
// RecipeListEditor
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 361);
this.ClientSize = new System.Drawing.Size(404, 381);
this.Controls.Add(this.CHK_New);
this.Controls.Add(this.CHK_Favorite);
this.Controls.Add(this.CHK_Made);
this.Controls.Add(this.CHK_Known);
this.Controls.Add(this.LB_Recipes);
this.Controls.Add(this.L_Goto);
this.Controls.Add(this.CB_Goto);
this.Controls.Add(this.B_All);
this.Controls.Add(this.CLB_Recipes);
this.Controls.Add(this.B_Cancel);
this.Controls.Add(this.B_Save);
this.Icon = global::NHSE.WinForms.Properties.Resources.icon;
@@ -128,9 +179,13 @@ private void InitializeComponent()
private System.Windows.Forms.Button B_Cancel;
private System.Windows.Forms.Button B_Save;
private System.Windows.Forms.CheckedListBox CLB_Recipes;
private System.Windows.Forms.Button B_All;
private System.Windows.Forms.ComboBox CB_Goto;
private System.Windows.Forms.Label L_Goto;
private System.Windows.Forms.ListBox LB_Recipes;
private System.Windows.Forms.CheckBox CHK_Known;
private System.Windows.Forms.CheckBox CHK_Made;
private System.Windows.Forms.CheckBox CHK_Favorite;
private System.Windows.Forms.CheckBox CHK_New;
}
}

View File

@@ -8,16 +8,16 @@ namespace NHSE.WinForms
public partial class RecipeListEditor : Form
{
private readonly Player Player;
private readonly bool[] Known;
private readonly RecipeBook Book;
private const string Unknown = "???";
public RecipeListEditor(Player player)
{
Player = player;
Known = Player.Personal.GetRecipeList();
InitializeComponent();
this.TranslateInterface(GameInfo.CurrentLanguage);
Book = player.Personal.GetRecipeBook();
var gotoSource = FillCheckBoxes();
gotoSource.SortByText();
CB_Goto.DisplayMember = nameof(ComboItem.Text);
@@ -27,45 +27,124 @@ public RecipeListEditor(Player player)
private List<ComboItem> FillCheckBoxes()
{
var book = Book;
var recipes = RecipeList.Recipes;
var max = (ushort)Known.Length - 1;
var strings = GameInfo.Strings.itemlist;
const ushort max = RecipeBook.RecipeCount;
FillListBox(max, recipes, strings, book);
var gotoSource = new List<ComboItem>();
return GetJumpList(max, recipes, strings, gotoSource);
}
private void FillListBox(ushort max, IReadOnlyDictionary<ushort, ushort> recipes, string[] strings, RecipeBook book)
{
for (ushort i = 0; i <= max; i++)
{
bool exists = recipes.TryGetValue(i, out var value);
string item = exists ? strings[value] : Unknown;
if (string.IsNullOrEmpty(item))
item = value.ToString();
string name = $"0x{i:X3} - {item}";
CLB_Recipes.Items.Add(name, Known[i]);
if (exists)
gotoSource.Add(new ComboItem(item, i));
var name = GetItemName(i, recipes, strings);
var text = GetEntryText(book, i, name);
LB_Recipes.Items.Add(text);
}
}
private static List<ComboItem> GetJumpList(ushort max, IReadOnlyDictionary<ushort, ushort> recipes, string[] strings, List<ComboItem> gotoSource)
{
for (ushort i = 0; i <= max; i++)
{
var name = GetItemName(i, recipes, strings);
if (recipes.ContainsKey(i))
gotoSource.Add(new ComboItem(name, i));
}
return gotoSource;
}
private static string GetItemName(ushort index, IReadOnlyDictionary<ushort, ushort> recipes, string[] itemNames)
{
bool exists = recipes.TryGetValue(index, out var value);
string item = exists ? itemNames[value] : Unknown;
if (string.IsNullOrEmpty(item))
item = value.ToString();
return item;
}
private static object GetEntryText(RecipeBook recipeBook, ushort index, string item)
{
var known = recipeBook.GetIsKnown(index) ? "✅" : "❌";
return $"0x{index:X3} - {known} {item}";
}
private void B_All_Click(object sender, EventArgs e)
{
var index = LB_Recipes.SelectedIndex;
var book = Book;
var recipes = RecipeList.Recipes;
for (ushort i = 0; i < CLB_Recipes.Items.Count; i++)
{
bool exists = recipes.ContainsKey(i);
CLB_Recipes.SetItemChecked(i, exists);
}
var strings = GameInfo.Strings.itemlist;
const ushort max = RecipeBook.RecipeCount;
book.GiveAll(recipes);
LB_Recipes.Items.Clear();
FillListBox(max, recipes, strings, book);
LB_Recipes.SelectedIndex = index;
}
private void B_Cancel_Click(object sender, EventArgs e) => Close();
private void B_Save_Click(object sender, EventArgs e)
{
for (int i = 0; i < Known.Length; i++)
Known[i] = CLB_Recipes.GetItemChecked(i);
Player.Personal.SetRecipeList(Known);
Player.Personal.SetRecipeBook(Book);
Close();
}
private void CB_Goto_SelectedValueChanged(object sender, EventArgs e) => CLB_Recipes.SelectedIndex = WinFormsUtil.GetIndex(CB_Goto);
private void CB_Goto_SelectedValueChanged(object sender, EventArgs e) => LB_Recipes.SelectedIndex = WinFormsUtil.GetIndex(CB_Goto);
private int Index = -1;
private bool Loading;
private void LB_Recipes_SelectedIndexChanged(object sender, EventArgs e)
{
if (Loading)
return;
SaveIndex(Index);
Index = LB_Recipes.SelectedIndex;
Loading = true;
LoadIndex(Index);
Loading = false;
}
private void LoadIndex(in int index)
{
if (index < 0)
return;
var book = Book;
CHK_Known.Checked = book.GetIsKnown(index);
CHK_New.Checked = book.GetIsNew(index);
CHK_Made.Checked = book.GetIsMade(index);
CHK_Favorite.Checked = book.GetIsFavorite(index);
}
private void SaveIndex(in int index)
{
if (index < 0)
return;
var book = Book;
book.SetIsKnown(index, CHK_Known.Checked);
book.SetIsNew(index, CHK_New.Checked);
book.SetIsMade(index, CHK_Made.Checked);
book.SetIsFavorite(index, CHK_Favorite.Checked);
}
private void CHK_Known_CheckedChanged(object sender, EventArgs e)
{
if (Loading)
return;
Loading = true;
var book = Book;
book.SetIsKnown(Index, CHK_Known.Checked);
var recipes = RecipeList.Recipes;
var strings = GameInfo.Strings.itemlist;
var name = GetItemName((ushort)Index, recipes, strings);
LB_Recipes.Items[Index] = GetEntryText(book, (ushort)Index, name);
Loading = false;
}
}
}