mirror of
https://github.com/kwsch/NHSE.git
synced 2026-09-08 03:05:18 -05:00
Add feature to populate max item stack (#396)
* Add event handler for count label click
This commit is contained in:
Binary file not shown.
@@ -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},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ public enum ItemKind : byte
|
||||
Kind_WoodenStickTool,
|
||||
Kind_WrappingPaper,
|
||||
Kind_YutaroWisp,
|
||||
Kind_XmasDeco,
|
||||
Onepiece_Dress,
|
||||
Onepiece_Long,
|
||||
Onepiece_Middle,
|
||||
|
||||
@@ -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);
|
||||
|
||||
1
NHSE.WinForms/Controls/ItemEditor.Designer.cs
generated
1
NHSE.WinForms/Controls/ItemEditor.Designer.cs
generated
@@ -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
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user