Add feature to populate max item stack (#396)

* Add event handler for count label click
This commit is contained in:
Charlie U
2020-09-29 22:55:06 -04:00
committed by GitHub
parent f49d616e9b
commit 6b2b46ec1d
6 changed files with 221 additions and 1 deletions

View File

@@ -1,4 +1,7 @@
namespace NHSE.Core
using System.Collections.Generic;
using static NHSE.Core.ItemKind;
namespace NHSE.Core
{
/// <summary>
/// Fetching metadata about an <see cref="Item"/>
@@ -40,5 +43,147 @@ public static ItemMenuIconType GetMenuIcon(ushort id)
return ItemMenuIconType.Unknown;
return (ItemMenuIconType)ItemMenuIcons[id];
}
public static bool TryGetMaxStackCount(Item item, out ushort max) => TryGetMaxStackCount(item.DisplayItemId, out max);
public static bool TryGetMaxStackCount(ushort id, out ushort max)
{
var kind = GetItemKind(id);
return MaxCountByKind.TryGetValue(kind, out max);
}
private static readonly Dictionary<ItemKind, ushort> MaxCountByKind = new Dictionary<ItemKind, ushort>
{
{Kind_Ftr, 00001},
{Kind_RoomWall, 00001},
{Kind_RoomFloor, 00001},
{Kind_Rug, 00001},
{Kind_RugMyDesign, 00001},
{Kind_Socks, 00001},
{Kind_Cap, 00001},
{Kind_Helmet, 00001},
{Kind_Accessory, 00001},
{Kind_Bag, 00001},
{Kind_Umbrella, 00001},
{Kind_FishingRod, 00001},
{Kind_Net, 00001},
{Kind_Shovel, 00001},
{Kind_Axe, 00001},
{Kind_Watering, 00001},
{Kind_Slingshot, 00001},
{Kind_ChangeStick, 00001},
{Kind_WoodenStickTool, 00001},
{Kind_Ladder, 00001},
{Kind_GroundMaker, 00001},
{Kind_RiverMaker, 00001},
{Kind_CliffMaker, 00001},
{Kind_PartyPopper, 00010},
{Kind_Ocarina, 00001},
{Kind_Panflute, 00001},
{Kind_Tambourine, 00001},
{Kind_FierworkHand, 00010},
{Kind_StickLight, 00001},
{Kind_Uchiwa, 00001},
{Kind_Windmill, 00001},
{Kind_BlowBubble, 00010},
{Kind_Partyhorn, 00001},
{Kind_Balloon, 00001},
{Kind_Timer, 00001},
{Kind_HandheldPennant, 00001},
{Kind_TreeSeedling, 00010},
{Kind_Tree, 00001},
{Kind_BushSeedling, 00010},
{Kind_Bush, 00001},
{Kind_VegeSeedling, 00010},
{Kind_VegeTree, 00001},
{Kind_Vegetable, 00010},
{Kind_Weed, 00099},
{Kind_FlowerSeed, 00010},
{Kind_FlowerBud, 00001},
{Kind_Flower, 00010},
{Kind_Fruit, 00010},
{Kind_Mushroom, 00010},
{Kind_Turnip, 00010},
{Kind_TurnipExpired, 00001},
{Kind_FishBait, 00010},
{Kind_PitFallSeed, 00010},
{Kind_Medicine, 00010},
{Kind_CraftMaterial, 00030},
{Kind_CraftRemake, 00050},
{Kind_Ore, 00030},
{Kind_CraftPhoneCase, 00001},
{Kind_Honeycomb, 00010},
{Kind_Trash, 00001},
{Kind_SnowCrystal, 00010},
{Kind_AutumnLeaf, 00010},
{Kind_Sakurapetal, 00010},
{Kind_XmasDeco, 00010},
{Kind_StarPiece, 00010},
{Kind_Insect, 00001},
{Kind_Fish, 00001},
{Kind_DiveFish, 00001},
{Kind_ShellDrift, 00010},
{Kind_ShellFish, 00001},
{Kind_FishToy, 00001},
{Kind_InsectToy, 00001},
{Kind_Fossil, 00001},
{Kind_FossilUnknown, 00001},
{Kind_Music, 00001},
{Kind_MusicMiss, 00001},
{Kind_Bromide, 00001},
{Kind_Poster, 00001},
{Kind_HousePost, 00001},
{Kind_DoorDeco, 00001},
{Kind_Fence, 00050},
{Kind_DummyRecipe, 00001},
{Kind_DummyDIYRecipe, 00001},
{Kind_DummyHowtoBook, 00001},
{Kind_LicenseItem, 00001},
{Kind_BridgeItem, 00001},
{Kind_SlopeItem, 00001},
{Kind_DIYRecipe, 00001},
{Kind_MessageBottle, 00001},
{Kind_WrappingPaper, 00010},
{Kind_HousingKit, 00001},
{Kind_HousingKitRcoQuest, 00001},
{Kind_HousingKitBirdge, 00001},
{Kind_Money, 00010},
{Kind_FireworkM, 00001},
{Kind_BdayCupcake, 00010},
{Kind_YutaroWisp, 00005},
{Kind_JohnnyQuest, 00010},
{Kind_JohnnyQuestDust, 00010},
{Kind_PirateQuest, 00010},
{Kind_QuestWrapping, 00001},
{Kind_LostQuest, 00001},
{Kind_LostQuestDust, 00001},
{Kind_TailorTicket, 00010},
{Kind_TreasureQuest, 00001},
{Kind_TreasureQuestDust, 00001},
{Kind_MilePlaneTicket, 00010},
{Kind_RollanTicket, 00005},
{Kind_EasterEgg, 00030},
{Kind_LoveCrystal, 00030},
{Kind_Candy, 00030},
{Kind_Giftbox, 00001},
{Kind_PinataStick, 00001},
{Kind_NpcOutfit, 00001},
{Kind_PlayerDemoOutfit, 00001},
{Kind_Picture, 00001},
{Kind_Sculpture, 00001},
{Kind_PictureFake, 00001},
{Kind_SculptureFake, 00001},
{Kind_SmartPhone, 00001},
{Kind_DummyFtr, 00001},
{Kind_SequenceOnly, 00001},
{Kind_MyDesignObject, 00001},
{Kind_MyDesignTexture, 00001},
{Kind_DummyWrapping, 00001},
{Kind_DummyPresentbox, 00001},
{Kind_DummyCardboard, 00001},
{Kind_EventObjFtr, 00001},
{Kind_NnpcRoomMarker, 00001},
{Kind_PhotoStudioList, 00001},
};
}
}

View File

@@ -147,6 +147,7 @@ public enum ItemKind : byte
Kind_WoodenStickTool,
Kind_WrappingPaper,
Kind_YutaroWisp,
Kind_XmasDeco,
Onepiece_Dress,
Onepiece_Long,
Onepiece_Middle,

View File

@@ -56,6 +56,14 @@ void DumpU(string fn, ushort[] ushorts, string dir = "bin")
Console.WriteLine($"Created {fn}");
}
void DumpD<T, S>(string fn, Dictionary<T, S> dict, string dir = "text")
{
Directory.CreateDirectory(Path.Combine(dest, dir));
var lines = dict.Select(z => $"{{{z.Key}, {z.Value:00000}}},");
File.WriteAllLines(Path.Combine(dest, dir, fn), lines);
Console.WriteLine($"Created {fn}");
}
DumpS("bcsv_map.txt", BCSV.EnumLookup.Dump());
DumpS("lifeSupportAchievement.txt", GetLifeSupportAchievementList(pathBCSV));
DumpS("recipeDictionary.txt", GetRecipeList(pathBCSV));
@@ -83,6 +91,8 @@ void DumpU(string fn, ushort[] ushorts, string dir = "bin")
DumpS("DoorKind.txt", GetNumberedEnumValues(pathBCSV, "StructureHouseDoorParam.bcsv", 0x39B5A93D, 0x54706054));
DumpS("WallKind.txt", GetNumberedEnumValues(pathBCSV, "StructureHouseWallParam.bcsv", 0x39B5A93D, 0x54706054));
DumpD("ItemStack.txt", GetItemStackDict(pathBCSV));
DumpB("item_kind.bin", GetItemKindArray(pathBCSV));
DumpB("item_size.bin", GetItemSizeArray(pathBCSV));
DumpU("item_menuicon.bin", GetItemMenuIconArray(pathBCSV));
@@ -227,6 +237,59 @@ public static byte[] GetItemSizeArray(string pathBCSV, string fn = "ItemParam.bc
return result;
}
public static Dictionary<ItemKind, ushort> GetItemStackDict(string pathBCSV, string fn = "ItemKind.bcsv")
{
var path = Path.Combine(pathBCSV, fn);
var data = File.ReadAllBytes(path);
var bcsv = new BCSV(data);
var dict = bcsv.GetFieldDictionary();
var fStack = dict[0x4C9BA961]; // MultiHoldMaxNum
var fKind = dict[0x87BF00E8]; // Label
// clothing is split out more granularly in ItemKind and would cause errors
// since it's not likely to ever be stackable, we can skip
// none-type can be skipped and doesn't exist in ItemKind either
List<string> skipLabels = new List<string>
{
"TopsDefault",
"Tops",
"OnePiece",
"MarineSuit",
"BottomsDefault",
"Bottoms",
"Shoes",
"None"
};
var result = new Dictionary<ItemKind, ushort>();
for (int i = 0; i < bcsv.EntryCount; i++)
{
var stack = bcsv.ReadValue(i, fStack);
switch (stack)
{
case "-1": // for some reason turnips have a stack value of -1, should be 10...
stack = "10";
break;
case "0": // the game stores items that cannot be stacked as 0, so technically they stack to 1
stack = "1";
break;
}
var stackval = ushort.Parse(stack);
var kind = bcsv.ReadValue(i, fKind).TrimEnd('\0');
if (skipLabels.Contains(kind))
continue;
kind = "Kind_" + kind;
if (!Enum.TryParse<ItemKind>(kind, out var k))
throw new InvalidEnumArgumentException($"{kind} is not a known enum value @ index {i}. Update the enum index first.");
result.Add(k, stackval);
}
return result;
}
public static ushort[] GetItemMenuIconArray(string pathBCSV, string fn = "ItemParam.bcsv")
{
var path = Path.Combine(pathBCSV, fn);

View File

@@ -154,6 +154,7 @@ private void InitializeComponent()
this.L_Count.TabIndex = 7;
this.L_Count.Text = "Count:";
this.L_Count.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
this.L_Count.DoubleClick += new System.EventHandler(this.L_Count_DoubleClick);
//
// L_Uses
//

View File

@@ -278,6 +278,16 @@ private void ToggleEditorVisibility(ItemKind k)
}
}
private void L_Count_DoubleClick(object sender, EventArgs e)
{
Item currentItem = SetItem(new Item());
var result = ItemInfo.TryGetMaxStackCount(currentItem, out var max);
if (!result)
return;
currentItem.Count = (ushort)(max - 1);
LoadItem(currentItem);
}
private void CB_CountAlias_SelectedValueChanged(object sender,EventArgs e)
{
var val = WinFormsUtil.GetIndex((ComboBox)sender);