protected override void OnEditorMouseDown(object sender, MouseEventArgs e) { IsMouseDown = true; if (!GetXyPosition(e, out _, out _, out var index)) { return; } var selectedItem = Items[index]; switch (e.Button) { case MouseButtons.Left: var newItem = new Furniture(MainFormReference.GetCurrentItem()); if (selectedItem != newItem) { // Save Old Item PushNewItemChange(selectedItem, index, UndoStack); // Clear Redo Stack NewChange(null); // Set New Item Items[index] = newItem; // Redraw Item Image var img = EditorPictureBox.Image; EditorPictureBox.Image = ImageGeneration.DrawFurnitureArrows((Bitmap)Inventory.GetItemPic(ItemCellSize, ItemsPerRow, Items, MainForm.SaveFile.SaveType, EditorPictureBox.Size), (Furniture[])Items, ItemsPerRow); img?.Dispose(); // Update ToolTip ItemToolTip.Show( string.Format(HoverText, newItem.Name, newItem.ItemId.ToString("X4"), newItem.ItemFlag.ToString()), this, e.X + 10, e.Y + 10, int.MaxValue); // Fire ItemChanged Event OnItemChanged(selectedItem, newItem, index); MainForm.SaveFile.ChangesMade = true; Modified = true; } break; case MouseButtons.Right: MainFormReference.SetCurrentItem(selectedItem); break; case MouseButtons.Middle: var tempItems = (Furniture[])Items; Utilities.Utility.FloodFillFurnitureArray(ref tempItems, ItemsPerRow, index, (Furniture)Items[index], new Furniture(MainFormReference.GetCurrentItem())); Items = tempItems; break; } }
protected override void SetItemPicture() { var img = EditorPictureBox.Image; if (Items != null) { Size = new Size(ItemCellSize * ItemsPerRow + 3, ItemCellSize * (int)(Math.Ceiling((decimal)Items.Length / ItemsPerRow)) + 3); EditorPictureBox.Image = ImageGeneration.DrawFurnitureArrows((Bitmap)Inventory.GetItemPic(ItemCellSize, ItemsPerRow, Items, MainForm.SaveFile.SaveType, EditorPictureBox.Size), (Furniture[])Items, ItemsPerRow); } img?.Dispose(); }
public override void Undo() { if (!UndoStack.Any()) { return; } // Get Previous Change var previousItemChange = UndoStack.Pop(); var selectedItem = Items[previousItemChange.Index]; // Set Redo Change PushNewItemChange(selectedItem, previousItemChange.Index, RedoStack); // Undo Items[previousItemChange.Index] = (Furniture)previousItemChange.Item; var img = EditorPictureBox.Image; EditorPictureBox.Image = ImageGeneration.DrawFurnitureArrows((Bitmap)Inventory.GetItemPic(ItemCellSize, ItemsPerRow, Items, MainForm.SaveFile.SaveType, EditorPictureBox.Size), (Furniture[])Items, ItemsPerRow); img?.Dispose(); OnItemChanged(selectedItem, Items[previousItemChange.Index], previousItemChange.Index); }
public NewPlayer(int offset, int idx, Save save) { SaveData = save; Index = idx; Offset = offset; Offsets = PlayerInfo.GetPlayerInfo(save.Save_Type); Exists = SaveData.ReadByte(offset + Offsets.Identifier) != 0 && SaveData.ReadByte(offset + Offsets.Identifier) != 0xFF; if (Exists) { object BoxedData = new PlayerData(); foreach (var Field in typeof(PlayerSaveInfo).GetFields(BindingFlags.Public | BindingFlags.Instance)) { if (Field.GetValue(Offsets) != null && !Field.Name.Contains("Count") && !Field.Name.Contains("Size")) { if (typeof(PlayerData).GetField(Field.Name) != null) { if (Field.FieldType == typeof(int) && (int)Field.GetValue(Offsets) != -1) { var Current_Field = typeof(PlayerData).GetField(Field.Name); Type FieldType = Current_Field.FieldType; int DataOffset = Offset + (int)Field.GetValue(Offsets); if (Field.Name == "TownPassCardImage" && (save.Save_Type == SaveType.New_Leaf || save.Save_Type == SaveType.Welcome_Amiibo)) { typeof(PlayerData).GetField("TownPassCardData").SetValue(BoxedData, SaveData.ReadByteArray(DataOffset, 0x1400)); Current_Field.SetValue(BoxedData, ImageGeneration.GetTPCImage((byte[])typeof(PlayerData).GetField("TownPassCardData").GetValue(BoxedData))); } else if (FieldType == typeof(byte)) { Current_Field.SetValue(BoxedData, SaveData.ReadByte(DataOffset)); } else if (FieldType == typeof(byte[]) && typeof(PlayerSaveInfo).GetField(Field.Name + "Count") != null) { Current_Field.SetValue(BoxedData, SaveData.ReadByteArray(DataOffset, (int)typeof(PlayerSaveInfo).GetField(Field.Name + "Count").GetValue(Offsets))); } else if (FieldType == typeof(ushort)) { Current_Field.SetValue(BoxedData, SaveData.ReadUInt16(DataOffset, SaveData.Is_Big_Endian)); } else if (FieldType == typeof(ushort[])) { Current_Field.SetValue(BoxedData, SaveData.ReadUInt16Array(DataOffset, (int)typeof(PlayerSaveInfo).GetField(Field.Name + "Count").GetValue(Offsets), SaveData.Is_Big_Endian)); } else if (FieldType == typeof(uint)) { Current_Field.SetValue(BoxedData, SaveData.ReadUInt32(DataOffset, SaveData.Is_Big_Endian)); } else if (FieldType == typeof(string)) { Current_Field.SetValue(BoxedData, new ACString(SaveData.ReadByteArray(DataOffset, (int)typeof(PlayerSaveInfo).GetField(Field.Name + "Size").GetValue(Offsets)), SaveData.Save_Type).Trim()); } else if (FieldType == typeof(Inventory)) { if (save.Save_Type == SaveType.New_Leaf || save.Save_Type == SaveType.Welcome_Amiibo) { Current_Field.SetValue(BoxedData, new Inventory(SaveData.ReadUInt32Array(DataOffset, (int)typeof(PlayerSaveInfo).GetField(Field.Name + "Count").GetValue(Offsets), false))); } else { Current_Field.SetValue(BoxedData, new Inventory(SaveData.ReadUInt16Array(DataOffset, (int)typeof(PlayerSaveInfo).GetField(Field.Name + "Count").GetValue(Offsets), SaveData.Is_Big_Endian))); } } else if (FieldType == typeof(Item)) { if (save.Save_Type == SaveType.New_Leaf || save.Save_Type == SaveType.Welcome_Amiibo) { Current_Field.SetValue(BoxedData, new Item(SaveData.ReadUInt32(DataOffset, false))); } else { Current_Field.SetValue(BoxedData, new Item(SaveData.ReadUInt16(DataOffset, SaveData.Is_Big_Endian))); } } else if (FieldType == typeof(NL_Int32)) { uint[] Int_Data = SaveData.ReadUInt32Array(DataOffset, 2); Current_Field.SetValue(BoxedData, new NL_Int32(Int_Data[0], Int_Data[1])); } } } } } Data = (PlayerData)BoxedData; //MessageBox.Show("ID: " + Data.Identifier.ToString("X")); if (save.Save_Type == SaveType.Wild_World) { byte Condensed_Data = Data.HairColor; Data.HairColor = (byte)(Condensed_Data & 0x0F); Data.Tan = (byte)((Condensed_Data & 0xF0) >> 4); //Has to be 0 - 3 Condensed_Data = Data.HairType; Data.FaceType = (byte)(Condensed_Data & 0x0F); Data.HairType = (byte)((Condensed_Data & 0xF0) >> 4); if (Data.Tan > 3) { Data.Tan = 0; } if (Data.HairColor > 7) { Data.HairColor = 0; } } else if (save.Save_Type == SaveType.City_Folk) { Data.Tan = (byte)(Data.Tan >> 1); //Not 100% sure about this, but this is what ACToolkit does if (Data.Tan > 7) { Data.Tan = 0; } if (Data.HairType > 0x19) { Data.HairType = 0x19; } Data.FaceType = (byte)(Data.FaceType & 0x0F); Data.EyeColor = (byte)(Data.FaceType & 0xF0); //Not actually eye color, just there to hold the upper nibble } if (Offsets.Patterns > -1) { Data.Patterns = new Pattern[Offsets.PatternCount]; for (int i = 0; i < Data.Patterns.Length; i++) { Data.Patterns[i] = new Pattern(offset + Offsets.Patterns + Offsets.PatternSize * i, save); } } } }
public Player(int offset, int idx, Save save) { _saveData = save; Index = idx; Offset = offset; Offsets = PlayerInfo.GetPlayerInfo(save.SaveType); Exists = _saveData.ReadByte(offset + Offsets.Identifier) != 0 && _saveData.ReadByte(offset + Offsets.Identifier) != 0xFF; if (!Exists) { return; } var playerDataType = typeof(PlayerData); var playerSaveInfoType = typeof(PlayerSaveInfo); object boxedData = new PlayerData(); foreach (var field in playerSaveInfoType.GetFields(BindingFlags.Public | BindingFlags.Instance)) { if (field.GetValue(Offsets) != null && !field.Name.Contains("Count") && !field.Name.Contains("Size")) { if (playerDataType.GetField(field.Name) != null) { if (field.FieldType != typeof(int) || (int)field.GetValue(Offsets) == -1) { continue; } var currentField = playerDataType.GetField(field.Name); var fieldType = currentField.FieldType; var dataOffset = Offset + (int)field.GetValue(Offsets); switch (field.Name) { case "TownPassCardImage" when save.SaveGeneration == SaveGeneration.N3DS: playerDataType.GetField("TownPassCardData").SetValue(boxedData, _saveData.ReadByteArray(dataOffset, 0x1400)); currentField.SetValue(boxedData, ImageGeneration.GetTpcImage((byte[])playerDataType.GetField("TownPassCardData").GetValue(boxedData))); break; case "Reset" when save.SaveGeneration == SaveGeneration.GCN: currentField.SetValue(boxedData, _saveData.ReadUInt32(dataOffset, _saveData.IsBigEndian) != 0); break; default: if (fieldType == typeof(byte)) { currentField.SetValue(boxedData, _saveData.ReadByte(dataOffset)); } else if (fieldType == typeof(byte[]) && playerSaveInfoType.GetField(field.Name + "Count") != null) { currentField.SetValue(boxedData, _saveData.ReadByteArray(dataOffset, (int)playerSaveInfoType.GetField(field.Name + "Count").GetValue(Offsets))); } else if (fieldType == typeof(ushort)) { currentField.SetValue(boxedData, _saveData.ReadUInt16(dataOffset, _saveData.IsBigEndian)); } else if (fieldType == typeof(ushort[])) { currentField.SetValue(boxedData, _saveData.ReadUInt16Array(dataOffset, (int)playerSaveInfoType.GetField(field.Name + "Count").GetValue(Offsets), _saveData.IsBigEndian)); } else if (fieldType == typeof(uint)) { currentField.SetValue(boxedData, _saveData.ReadUInt32(dataOffset, _saveData.IsBigEndian)); } else if (fieldType == typeof(string)) { currentField.SetValue(boxedData, new AcString(_saveData.ReadByteArray(dataOffset, (int)playerSaveInfoType.GetField(field.Name + "Size").GetValue(Offsets)), _saveData.SaveType).Trim()); } else if (fieldType == typeof(Inventory)) { if (save.SaveGeneration == SaveGeneration.N3DS) { currentField.SetValue(boxedData, new Inventory(_saveData.ReadUInt32Array(dataOffset, (int)playerSaveInfoType.GetField(field.Name + "Count").GetValue(Offsets), false))); } else { currentField.SetValue(boxedData, new Inventory(_saveData.ReadUInt16Array(dataOffset, (int)playerSaveInfoType.GetField(field.Name + "Count").GetValue(Offsets), _saveData.IsBigEndian), save, this)); } } else if (fieldType == typeof(Item)) { if (save.SaveGeneration == SaveGeneration.N3DS) { currentField.SetValue(boxedData, new Item(_saveData.ReadUInt32(dataOffset, false))); } else { currentField.SetValue(boxedData, new Item(_saveData.ReadUInt16(dataOffset, _saveData.IsBigEndian))); } } else if (fieldType == typeof(Item[])) { if (field.Name.Equals("Dressers")) { switch (_saveData.SaveGeneration) { case SaveGeneration.NDS: dataOffset = 0x15430 + 0xB4 * Index; // Terrible hack break; case SaveGeneration.Wii: dataOffset = 0x1F3038 + 0x140 * Index; break; } } var itemArray = new Item[(int)playerSaveInfoType.GetField(field.Name + "Count").GetValue(Offsets)]; for (var i = 0; i < itemArray.Length; i++) { if (save.SaveGeneration == SaveGeneration.N3DS) { itemArray[i] = new Item(_saveData.ReadUInt32(dataOffset + i * 4, false)); } else { itemArray[i] = new Item(_saveData.ReadUInt16(dataOffset + i * 2, _saveData.IsBigEndian)); } } currentField.SetValue(boxedData, itemArray); } else if (fieldType == typeof(NewLeafInt32)) { var intData = _saveData.ReadUInt32Array(dataOffset, 2); currentField.SetValue(boxedData, new NewLeafInt32(intData[0], intData[1])); } else if (fieldType == typeof(AcDate) && dataOffset > 0) { currentField.SetValue(boxedData, new AcDate(_saveData.ReadByteArray(dataOffset, (int)playerSaveInfoType.GetField(field.Name + "Size").GetValue(Offsets)))); } break; } } } } Data = (PlayerData)boxedData; switch (save.SaveType) { case SaveType.WildWorld: var condensedData = Data.HairColor; Data.HairColor = (byte)(condensedData & 0x0F); Data.Tan = (byte)((condensedData & 0xF0) >> 4); //Has to be 0 - 3 condensedData = Data.HairType; Data.FaceType = (byte)(condensedData & 0x0F); Data.HairType = (byte)((condensedData & 0xF0) >> 4); if (Data.Tan > 3) { Data.Tan = 0; } if (Data.HairColor > 7) { Data.HairColor = 0; } break; case SaveType.CityFolk: Data.Tan = (byte)(Data.Tan >> 1); //Not 100% sure about this, but this is what ACToolkit does if (Data.Tan > 7) { Data.Tan = 0; } if (Data.HairType > 0x19) { Data.HairType = 0x19; } Data.FaceType = (byte)(Data.FaceType & 0x0F); Data.EyeColor = (byte)(Data.FaceType & 0xF0); //Not actually eye color, just there to hold the upper nibble break; } if (Offsets.Patterns > -1) { Data.Patterns = new Pattern[Offsets.PatternCount]; for (var i = 0; i < Data.Patterns.Length; i++) { Data.Patterns[i] = new Pattern(offset + Offsets.Patterns + Offsets.PatternSize * i, i, save); } } if (_saveData.SaveType == SaveType.CityFolk) { Data.Reset = (_saveData.ReadByte(Offset + 0x8670) & 0x02) == 0x02; } else if (_saveData.SaveType == SaveType.NewLeaf) { Data.Reset = (_saveData.ReadByte(Offset + 0x5702) & 0x02) == 0x02; } else if (_saveData.SaveType == SaveType.WelcomeAmiibo) { Data.Reset = (_saveData.ReadByte(Offset + 0x570A) & 0x02) == 0x02; } // Get the Player's House House = HouseInfo.GetHouse(this, save.SaveType); if (House != null) { if (House.Data.Bed != null) { Data.Bed = House.Data.Bed; } } Console.WriteLine($"Player {Index}'s house = {House}"); // Mail Test if (_saveData.SaveGeneration != SaveGeneration.GCN) { return; } { for (var i = 0; i < 10; i++) { var mail = new GcnPlayerMail(_saveData, this, i); //System.Windows.Forms.MessageBox.Show(Mail.GetFormattedMailString()); } } }