NLSE/Subforms/Garden.cs
Kaphotics df7081efc3 Fix || && comparison
Resolves #12

Thanks @Will-The-Lion for reporting!
2016-05-06 13:33:14 -07:00

1348 lines
54 KiB
C#

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace NLSE
{
public partial class Garden : Form
{
// Form Variables
private ushort[] TownAcreTiles, IslandAcreTiles, aeTownAcreTiles, aeIslandAcreTiles;
private PictureBox[] TownAcres, IslandAcres, aeTownAcres, aeIslandAcres, PlayerPics;
private ComboBox[] TownVillagers, PlayerBadges;
private TextBox[] TownVillagersCatch;
private CheckBox[] TownVillagersBoxed;
private Player[] Players;
private Building[] Buildings;
private Villager[] Villagers;
private Item[] TownItems, IslandItems;
private Button[] PlayerBankCheat;
// Dynamic Text
private string DefaultBankText;
// Form Handling
public Garden()
{
InitializeComponent();
CB_Item.DisplayMember = "Text";
CB_Item.ValueMember = "Value";
CB_Item.DataSource = new BindingSource(Main.itemList, null);
TB_Flag1.KeyPress += EnterKey;
TB_Flag2.KeyPress += EnterKey;
#region Array Initialization
TownAcres = new[]
{
PB_acre00, PB_acre10, PB_acre20, PB_acre30, PB_acre40, PB_acre50, PB_acre60,
PB_acre01, PB_acre11, PB_acre21, PB_acre31, PB_acre41, PB_acre51, PB_acre61,
PB_acre02, PB_acre12, PB_acre22, PB_acre32, PB_acre42, PB_acre52, PB_acre62,
PB_acre03, PB_acre13, PB_acre23, PB_acre33, PB_acre43, PB_acre53, PB_acre63,
PB_acre04, PB_acre14, PB_acre24, PB_acre34, PB_acre44, PB_acre54, PB_acre64,
PB_acre05, PB_acre15, PB_acre25, PB_acre35, PB_acre45, PB_acre55, PB_acre65,
};
IslandAcres = new[]
{
PB_island00, PB_island10, PB_island20, PB_island30,
PB_island01, PB_island11, PB_island21, PB_island31,
PB_island02, PB_island12, PB_island22, PB_island32,
PB_island03, PB_island13, PB_island23, PB_island33,
};
aeTownAcres = new[]
{
PB_aeT00, PB_aeT10, PB_aeT20, PB_aeT30, PB_aeT40, PB_aeT50, PB_aeT60,
PB_aeT01, PB_aeT11, PB_aeT21, PB_aeT31, PB_aeT41, PB_aeT51, PB_aeT61,
PB_aeT02, PB_aeT12, PB_aeT22, PB_aeT32, PB_aeT42, PB_aeT52, PB_aeT62,
PB_aeT03, PB_aeT13, PB_aeT23, PB_aeT33, PB_aeT43, PB_aeT53, PB_aeT63,
PB_aeT04, PB_aeT14, PB_aeT24, PB_aeT34, PB_aeT44, PB_aeT54, PB_aeT64,
PB_aeT05, PB_aeT15, PB_aeT25, PB_aeT35, PB_aeT45, PB_aeT55, PB_aeT65,
};
aeIslandAcres = new[]
{
PB_aeI00, PB_aeI10, PB_aeI20, PB_aeI30,
PB_aeI01, PB_aeI11, PB_aeI21, PB_aeI31,
PB_aeI02, PB_aeI12, PB_aeI22, PB_aeI32,
PB_aeI03, PB_aeI13, PB_aeI23, PB_aeI33,
};
PlayerPics = new[]
{
PB_JPEG0, PB_JPEG1, PB_JPEG2, PB_JPEG3
};
PlayerBadges = new[]
{
CB_Badge00, CB_Badge01, CB_Badge02, CB_Badge03, CB_Badge04,
CB_Badge05, CB_Badge06, CB_Badge07, CB_Badge08, CB_Badge09,
CB_Badge10, CB_Badge11, CB_Badge12, CB_Badge13, CB_Badge14,
CB_Badge15, CB_Badge16, CB_Badge17, CB_Badge18, CB_Badge19,
CB_Badge20, CB_Badge21, CB_Badge22, CB_Badge23,
};
TownVillagers = new[]
{
CB_Villager1, CB_Villager2, CB_Villager3, CB_Villager4, CB_Villager5,
CB_Villager6, CB_Villager7, CB_Villager8, CB_Villager9, CB_Villager10
};
foreach (ComboBox id in TownVillagers)
{
id.DisplayMember = "Text";
id.ValueMember = "Value";
id.DataSource = new BindingSource(Main.vList, null);
}
TownVillagersCatch = new[]
{
TB_VillagerCatch1, TB_VillagerCatch2, TB_VillagerCatch3, TB_VillagerCatch4, TB_VillagerCatch5,
TB_VillagerCatch6, TB_VillagerCatch7, TB_VillagerCatch8, TB_VillagerCatch9, TB_VillagerCatch10
};
TownVillagersBoxed = new[]
{
CHK_V01, CHK_V02, CHK_V03, CHK_V04, CHK_V05, CHK_V06, CHK_V07, CHK_V08, CHK_V09, CHK_V10
};
PlayerBankCheat = new[]
{
B_Bank0, B_Bank1, B_Bank2, B_Bank3
};
DefaultBankText = B_Bank0.Text;
#endregion
#region Load Event Methods to Controls
foreach (PictureBox p in TownAcres) { p.MouseMove += mouseTown; p.MouseClick += clickTown; }
foreach (PictureBox p in IslandAcres) { p.MouseMove += mouseIsland; p.MouseClick += clickIsland; }
foreach (PictureBox p in aeTownAcres) { p.MouseMove += mouseTownAcre; p.MouseClick += clickTownAcre; }
foreach (PictureBox p in aeIslandAcres) { p.MouseMove += mouseIslandAcre; p.MouseClick += clickIslandAcre; }
{ PB_Pocket.MouseMove += mouseCustom; PB_Pocket.MouseClick += clickCustom; }
{ PB_Dresser1.MouseMove += mouseCustom; PB_Dresser1.MouseClick += clickCustom; }
{ PB_Dresser2.MouseMove += mouseCustom; PB_Dresser2.MouseClick += clickCustom; }
{ PB_Island.MouseMove += mouseCustom; PB_Island.MouseClick += clickCustom; }
#endregion
// Load
loadData();
reloadCurrentItem(currentItem);
}
private void B_Save_Click(object sender, EventArgs e)
{
Main.SaveData = saveData();
Close();
}
private void B_Cancel_Click(object sender, EventArgs e)
{
Close();
}
private void B_Import_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog
{
FileName = "acnlram.bin",
Filter = "RAM Dump|*.bin"
};
if (ofd.ShowDialog() != DialogResult.OK)
return;
var len = new FileInfo(ofd.FileName).Length;
if (new FileInfo(ofd.FileName).Length != 0x80000)
{
Util.Error(String.Format(
"Data lengths do not match.{0}" +
"Expected: 0x{1}{0}" +
"Received: 0x{2}",
Environment.NewLine, 0x80000.ToString("X5"), len.ToString("X5")));
return;
}
byte[] data = File.ReadAllBytes(ofd.FileName);
Array.Copy(data, 0, Save.Data, 0x80, Save.Data.Length - 0x80);
loaded = false;
loadData();
}
private void B_Export_Click(object sender, EventArgs e)
{
var sfd = new SaveFileDialog
{
FileName = "acnlram.bin",
Filter = "RAM Dump|*.bin"
};
if (sfd.ShowDialog() != DialogResult.OK)
return;
byte[] RAM = saveData().Skip(0x80).ToArray();
if (RAM.Length < 0x80000)
Array.Resize(ref RAM, 0x80000);
File.WriteAllBytes(sfd.FileName, RAM);
}
// Garden Save Editing
private GardenData Save;
class GardenData
{
public byte[] Data;
public byte[] TownBytes;
public string TownName;
public int TownHallColor;
public int TrainStationColor;
public int GrassType;
public int NativeFruit;
public uint SecondsPlayed;
public ushort PlayDays;
public GardenData(byte[] data)
{
Data = data;
TownBytes = getTownBytes();
TownName = Encoding.Unicode.GetString(Data.Skip(0x5C7BA).Take(0x12).ToArray()).Trim('\0');
GrassType = Data[0x4DA81];
TownHallColor = Data[0x5C7B8] & 3;
TrainStationColor = Data[0x5C7B9] & 3;
NativeFruit = Data[0x5C836];
SecondsPlayed = BitConverter.ToUInt32(Data, 0x5C7B0);
PlayDays = BitConverter.ToUInt16(Data, 0x5C83A);
}
public byte[] Write()
{
Data[0x5C7B8] = (byte)(Data[0x5C7B8] & 0xFC | TownHallColor);
Data[0x5C7B9] = (byte)(Data[0x5C7B9] & 0xFC | TrainStationColor);
Array.Copy(Encoding.Unicode.GetBytes(TownName.PadRight(9, '\0')), 0, Data, 0x5C7BA, 0x12);
Data[0x4DA81] = (byte)GrassType;
Data[0x5C836] = (byte)NativeFruit;
Array.Copy(BitConverter.GetBytes(SecondsPlayed), 0, Data, 0x5C7B0, 4);
Array.Copy(BitConverter.GetBytes(PlayDays), 0, Data, 0x5C83A, 2);
return Data;
}
public byte[] getTownBytes()
{
return Data.Skip(0x5C7B8).Take(0x14).ToArray();
}
}
class Player
{
public byte[] Data;
public byte[] PlayerBytes;
private uint U32;
public byte Hair, HairColor,
Face, EyeColor,
Tan, U9;
public string Name;
public int Gender;
public string HomeTown;
public Image JPEG;
public byte[] Badges;
public Item[] Pockets = new Item[16];
public Item[] IslandBox = new Item[5 * 8];
public Item[] Dressers = new Item[5 * 36];
public Player(byte[] data)
{
Data = data;
PlayerBytes = getPlayerBytes();
U32 = BitConverter.ToUInt32(data, 0);
Hair = Data[4];
HairColor = Data[5];
Face = Data[6];
EyeColor = Data[7];
Tan = Data[8];
U9 = Data[9];
Name = Encoding.Unicode.GetString(Data.Skip(0x55A8).Take(0x12).ToArray()).Trim('\0');
Gender = Data[0x55BA];
HomeTown = Encoding.Unicode.GetString(Data.Skip(0x55BE).Take(0x12).ToArray()).Trim('\0');
try { JPEG = Image.FromStream(new MemoryStream(Data.Skip(0x5724).Take(0x1400).ToArray())); }
catch { JPEG = null; }
Badges = Data.Skip(0x569C).Take(24).ToArray();
for (int i = 0; i < Pockets.Length; i++)
Pockets[i] = new Item(Data.Skip(0x6BB0 + i*4).Take(4).ToArray());
for (int i = 0; i < IslandBox.Length; i++)
IslandBox[i] = new Item(Data.Skip(0x6E60 + i*4).Take(4).ToArray());
for (int i = 0; i < Dressers.Length; i++)
Dressers[i] = new Item(Data.Skip(0x8E18 + i*4).Take(4).ToArray());
}
public byte[] Write()
{
Array.Copy(BitConverter.GetBytes(U32), 0, Data, 0, 4);
Data[4] = Hair;
Data[5] = HairColor;
Data[6] = Face;
Data[7] = EyeColor;
Data[8] = Tan;
Data[9] = U9;
Array.Copy(Encoding.Unicode.GetBytes(Name.PadRight(9, '\0')), 0, Data, 0x55A8, 0x12);
Data[0x55BA] = (byte)Gender;
Array.Copy(Encoding.Unicode.GetBytes(HomeTown.PadRight(9, '\0')), 0, Data, 0x55BE, 0x12);
Array.Copy(Badges, 0, Data, 0x569C, Badges.Length);
for (int i = 0; i < Pockets.Length; i++)
Array.Copy(Pockets[i].Write(), 0, Data, 0x6BB0 + i*4, 4);
for (int i = 0; i < IslandBox.Length; i++)
Array.Copy(IslandBox[i].Write(), 0, Data, 0x6E60 + i*4, 4);
for (int i = 0; i < Dressers.Length; i++)
Array.Copy(Dressers[i].Write(), 0, Data, 0x8E18 + i*4, 4);
return Data;
}
public byte[] getPlayerBytes()
{
return Data.Skip(0x55A6).Take(0x2E).ToArray();
}
}
class Building
{
public int X, Y, ID;
public Building(byte[] data)
{
if (data.Length != 4) return;
ID = BitConverter.ToUInt16(data, 0);
X = data[2];
Y = data[3];
}
public byte[] Write()
{
using(var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
bw.Write((ushort)ID);
bw.Write((byte)X);
bw.Write((byte)Y);
return ms.ToArray();
}
}
}
class Villager
{
// Fetch from raw data
public byte[] Data;
public short ID;
public byte Type;
public string CatchPhrase;
private string HomeTown1;
private string HomeTown2;
public bool Boxed;
public Villager(byte[] data, int offset, int size)
{
Data = data.Skip(offset).Take(size).ToArray();
ID = BitConverter.ToInt16(Data, 0);
Type = Data[2];
Boxed = (Data[0x24C4] & 1) == 1;
CatchPhrase = Encoding.Unicode.GetString(Data.Skip(0x24A6).Take(22).ToArray()).Trim('\0');
HomeTown1 = Encoding.Unicode.GetString(Data.Skip(0x24CE).Take(0x12).ToArray()).Trim('\0');
HomeTown2 = Encoding.Unicode.GetString(Data.Skip(0x24E4).Take(0x12).ToArray()).Trim('\0');
}
public byte[] Write()
{
Array.Copy(BitConverter.GetBytes(ID), 0, Data, 0, 2);
Data[2] = Type;
Data[0x24C4] = (byte)((Data[0x24C4] & ~1) | (Boxed ? 1 : 0));
Array.Copy(Encoding.Unicode.GetBytes(CatchPhrase.PadRight(11, '\0')), 0, Data, 0x24A6, 22);
Array.Copy(Encoding.Unicode.GetBytes(HomeTown1.PadRight(9, '\0')), 0, Data, 0x24CE, 0x12);
Array.Copy(Encoding.Unicode.GetBytes(HomeTown2.PadRight(9, '\0')), 0, Data, 0x24E4, 0x12);
return Data;
}
}
class Item
{
public byte Flag1, Flag2;
public bool Buried, Watered;
public ushort ID;
public Item(byte[] data)
{
ID = BitConverter.ToUInt16(data, 0);
Flag1 = data[2];
Flag2 = data[3];
Watered = Flag2 >> 6 == 1;
Buried = Flag2 >> 7 == 1;
}
public byte[] Write()
{
using (var ms = new MemoryStream())
using (var bw = new BinaryWriter(ms))
{
bw.Write(ID);
bw.Write(Flag1);
Flag2 = (byte)((Flag2 & 0x3F)
| (Watered ? 1 << 6 : 0)
| (Buried ? 1 << 7 : 0));
bw.Write(Flag2);
return ms.ToArray();
}
}
}
// Data Usage
private void loadData()
{
Save = new GardenData(Main.SaveData);
// Load Players
Players = new Player[4];
for (int i = 0; i < Players.Length; i++)
Players[i] = new Player(Save.Data.Skip(0xA0 + i * 0x9F10).Take(0x9F10).ToArray());
for (int i = 0; i < Players.Length; i++)
PlayerPics[i].Image = Players[i].JPEG;
loadPlayer(0);
for (int i = 0; i < Players.Length; i++)
{
PlayerBankCheat[i].Text = String.Format(DefaultBankText, Players[i].Name);
PlayerBankCheat[i].Visible = Players[i].Name != "";
}
// Load Town
TownAcreTiles = new ushort[TownAcres.Length];
for (int i = 0; i < TownAcreTiles.Length; i++)
TownAcreTiles[i] = BitConverter.ToUInt16(Save.Data, 0x4DA84 + i * 2);
fillMapAcres(TownAcreTiles, TownAcres);
aeTownAcreTiles = (ushort[])TownAcreTiles.Clone();
fillMapAcres(aeTownAcreTiles, aeTownAcres);
TownItems = getMapItems(Save.Data.Skip(0x4DAD8).Take(0x5000).ToArray());
fillTownItems(TownItems, TownAcres);
// Load Island
IslandAcreTiles = new ushort[IslandAcres.Length];
for (int i = 0; i < IslandAcreTiles.Length; i++)
IslandAcreTiles[i] = BitConverter.ToUInt16(Save.Data, 0x6A488 + i * 2);
fillMapAcres(IslandAcreTiles, IslandAcres);
aeIslandAcreTiles = (ushort[])IslandAcreTiles.Clone();
fillMapAcres(aeIslandAcreTiles, aeIslandAcres);
IslandItems = getMapItems(Save.Data.Skip(0x6A4A8).Take(0x1000).ToArray());
fillIslandItems(IslandItems, IslandAcres);
// Load Buildings
Buildings = new Building[58];
for (int i = 0; i < Buildings.Length; i++)
Buildings[i] = new Building(Save.Data.Skip(0x0495A8 + i * 4).Take(4).ToArray());
populateBuildingList();
// Load Villagers
Villagers = new Villager[10];
for (int i = 0; i < Villagers.Length; i++)
loadVillager(i);
// Load Overall
{
TB_TownName.Text = Save.TownName;
CB_GrassShape.SelectedIndex = Save.GrassType;
CB_NativeFruit.SelectedIndex = Save.NativeFruit;
CB_TownHallColor.SelectedIndex = Save.TownHallColor;
CB_TrainStationColor.SelectedIndex = Save.TrainStationColor;
NUD_Seconds.Value = Save.SecondsPlayed % 60;
NUD_Minutes.Value = (Save.SecondsPlayed / 60) % 60;
NUD_Hours.Value = (Save.SecondsPlayed / 3600) % 24;
NUD_Days.Value = (Save.SecondsPlayed / 86400) % 25000;
NUD_OverallDays.Value = Save.PlayDays;
}
loaded = true;
}
private byte[] saveData()
{
savePlayer(currentPlayer);
// Write Players
for (int i = 0; i < Players.Length; i++)
Array.Copy(Players[i].Write(), 0, Save.Data, 0xA0 + i * 0x9F10, 0x9F10);
// Write Town
for (int i = 0; i < TownAcreTiles.Length; i++) // Town Acres
Array.Copy(BitConverter.GetBytes(TownAcreTiles[i]), 0, Save.Data, 0x4DA84 + i * 2, 2);
for (int i = 0; i < TownItems.Length; i++) // Town Items
Array.Copy(TownItems[i].Write(), 0, Save.Data, 0x4DAD8 + i * 4, 4);
// Write Island
for (int i = 0; i < IslandAcreTiles.Length; i++) // Island Acres
Array.Copy(BitConverter.GetBytes(IslandAcreTiles[i]), 0, Save.Data, 0x6A488 + i * 2, 2);
for (int i = 0; i < IslandItems.Length; i++) // Island Items
Array.Copy(IslandItems[i].Write(), 0, Save.Data, 0x6A4A8 + i * 4, 4);
saveBuildingList();
// Write Buildings
for (int i = 0; i < Buildings.Length; i++)
Array.Copy(Buildings[i].Write(), 0, Save.Data, 0x0495A8 + i * 4, 4);
// Write Villagers
for (int i = 0; i < Villagers.Length; i++)
saveVillager(i);
// Write Overall
{
Save.TownName = TB_TownName.Text;
Save.GrassType = CB_GrassShape.SelectedIndex;
Save.NativeFruit = CB_NativeFruit.SelectedIndex;
Save.TownHallColor = CB_TownHallColor.SelectedIndex;
Save.TrainStationColor = CB_TrainStationColor.SelectedIndex;
Save.SecondsPlayed = 0;
Save.SecondsPlayed += (uint)NUD_Seconds.Value;
Save.SecondsPlayed += (uint)NUD_Minutes.Value * 60;
Save.SecondsPlayed += (uint)NUD_Hours.Value * 3600;
Save.SecondsPlayed += (uint)NUD_Days.Value * 86400;
Save.PlayDays = (ushort)NUD_OverallDays.Value;
}
byte[] finalData = (byte[])Save.Write().Clone();
{
// Update ID references with their current values
for (int i = 0; i < 4; i++)
Util.ReplaceAllBytes(finalData, Players[i].PlayerBytes, Players[i].getPlayerBytes());
Util.ReplaceAllBytes(finalData, Save.TownBytes, Save.getTownBytes());
}
return finalData;
}
private int currentPlayer = -1;
private void loadPlayer(int i)
{
currentPlayer = i;
PB_LPlayer0.Image = Players[i].JPEG;
PB_Pocket.Image = getItemPic(16, 16, Players[i].Pockets);
PB_Dresser1.Image = getItemPic(16, 5, Players[i].Dressers.Take(Players[i].Dressers.Length / 2).ToArray());
PB_Dresser2.Image = getItemPic(16, 5, Players[i].Dressers.Skip(Players[i].Dressers.Length / 2).ToArray());
PB_Island.Image = getItemPic(16, 5, Players[i].IslandBox);
TB_Name.Text = Players[i].Name;
for (int j = 0; j < PlayerBadges.Length; j++)
PlayerBadges[j].SelectedIndex = Players[i].Badges[j];
CB_HairStyle.SelectedIndex = Players[i].Hair;
CB_HairColor.SelectedIndex = Players[i].HairColor;
CB_FaceShape.SelectedIndex = Players[i].Face;
CB_EyeColor.SelectedIndex = Players[i].EyeColor;
CB_SkinColor.SelectedIndex = Players[i].Tan;
CB_Gender.SelectedIndex = Players[i].Gender;
}
private void savePlayer(int i)
{
Players[i].Name = TB_Name.Text;
for (int j = 0; j < PlayerBadges.Length; j++)
Players[i].Badges[j] = (byte)PlayerBadges[j].SelectedIndex;
Players[i].Hair = (byte)CB_HairStyle.SelectedIndex;
Players[i].HairColor = (byte)CB_HairColor.SelectedIndex;
Players[i].Face = (byte)CB_FaceShape.SelectedIndex;
Players[i].EyeColor = (byte)CB_EyeColor.SelectedIndex;
Players[i].Tan = (byte)CB_SkinColor.SelectedIndex;
Players[i].Gender = (byte)CB_Gender.SelectedIndex;
}
private void loadVillager(int i)
{
Villagers[i] = new Villager(Save.Data, 0x027D10 + 0x24F8 * i, 0x24F8);
TownVillagers[i].Enabled = TownVillagersCatch[i].Enabled = TownVillagersBoxed[i].Enabled = (Villagers[i].ID != -1);
TownVillagers[i].SelectedValue = (int)Villagers[i].ID;
TownVillagersCatch[i].Text = Villagers[i].CatchPhrase;
TownVillagersBoxed[i].Checked = Villagers[i].Boxed;
}
private void saveVillager(int i)
{
Villagers[i].ID = (TownVillagers[i].SelectedItem == null)
? (short)-1
: (short)Util.getIndex(TownVillagers[i]);
Villagers[i].CatchPhrase = TownVillagersCatch[i].Text;
Villagers[i].Boxed = TownVillagersBoxed[i].Checked;
Array.Copy(Villagers[i].Write(), 0, Save.Data, 0x027D10 + 0x24F8 * i, 0x24F8);
}
// Utility
private void fillMapAcres(ushort[] Acres, PictureBox[] Tiles)
{
for (int i = 0; i < Tiles.Length; i++)
Tiles[i].BackgroundImage = (Image)Properties.Resources.ResourceManager.GetObject("acre_" + Acres[i]);
}
private void fillTownItems(Item[] items, PictureBox[] Tiles)
{
int ctr = 0;
for (int i = 0; i < Tiles.Length; i++)
{
if (i%7 == 0 || i/7 == 0 || i%7 == 6 || i/36 > 0) continue;
Tiles[i].Image = getAcreItemPic(ctr, items);
ctr++;
}
}
private void fillIslandItems(Item[] items, PictureBox[] Tiles)
{
int ctr = 0;
for (int i = 0; i < Tiles.Length; i++)
{
if (i % 4 == 0 || i / 4 == 0 || i % 4 == 3 || i / 12 > 0) continue;
Tiles[i].Image = getAcreItemPic(ctr, items);
ctr++;
}
}
private Item[] getMapItems(byte[] itemData)
{
var items = new Item[itemData.Length / 4];
for (int i = 0; i < items.Length; i++)
items[i] = new Item(itemData.Skip(4*i).Take(4).ToArray());
return items;
}
private bool getIsWeed(uint item)
{
return (item >= 0x7c && item <= 0x7f) || (item >= 0xcb && item <= 0xcd) || (item == 0xf8);
}
private bool getIsWilted(ushort item)
{
return (item >= 0xce && item <= 0xfb);
}
// Quick Cheats
private void B_WaterFlowers_Click(object sender, EventArgs e)
{
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Water all flowers?"))
return;
int ctr = waterFlowers(ref TownItems);
fillTownItems(TownItems, TownAcres);
Util.Alert(String.Format("{0} flowers were watered!", ctr));
}
private void B_RemoveWeeds_Click(object sender, EventArgs e)
{
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNo, "Clear all weeds?"))
return;
int ctr = clearWeeds(ref TownItems);
fillTownItems(TownItems, TownAcres);
Util.Alert(String.Format("{0} weeds were cleared!", ctr));
}
private int waterFlowers(ref Item[] items)
{
int ctr = 0;
foreach (Item i in items.Where(t => getIsWilted(t.ID)))
{
ctr++;
i.Watered = true;
}
return ctr;
}
private int clearWeeds(ref Item[] items)
{
int ctr = 0;
foreach (Item i in items.Where(t => getIsWeed(t.ID)))
{
ctr++;
i.ID = 0x7FFE;
i.Flag1 = 0;
i.Flag2 = 0;
}
return ctr;
}
private Item currentItem = new Item(new byte[] {0xFE, 0x7F, 0, 0});
private const int mapScale = 2;
private void mouseTown(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(TownAcres, sender as PictureBox);
int baseX = acre % 7;
int baseY = acre / 7;
int X = baseX * 16 + e.X / (4 * mapScale);
int Y = baseY * 16 + e.Y / (4 * mapScale);
// Get Base Acre
int index = getItemIndex(X, Y, 5);
Item item = TownItems[index];
hoverItem(item, X, Y);
}
private void mouseIsland(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(IslandAcres, sender as PictureBox);
int baseX = acre % 4;
int baseY = acre / 4;
int X = baseX * 16 + e.X / (4 * mapScale);
int Y = baseY * 16 + e.Y / (4 * mapScale);
// Get Base Acre
int index = getItemIndex(X, Y, 2);
Item item = IslandItems[index];
hoverItem(item, X, Y);
}
private void clickTown(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(TownAcres, sender as PictureBox);
int baseX = acre % 7;
int baseY = acre / 7;
int X = baseX * 16 + e.X / (4 * mapScale);
int Y = baseY * 16 + e.Y / (4 * mapScale);
// Get Base Acre
int index = getItemIndex(X, Y, 5);
if (e.Button == MouseButtons.Right) // Read
reloadCurrentItem(TownItems[index]);
else // Write
{
TownItems[index] = copyCurrentItem();
int zX = (X - 16) / 16;
int zY = (Y - 16) / 16;
int zAcre = zX + zY * 5;
TownAcres[acre].Image = getAcreItemPic(zAcre, TownItems);
}
}
private void clickIsland(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(IslandAcres, sender as PictureBox);
int baseX = acre % 4;
int baseY = acre / 4;
int X = baseX * 16 + e.X / (4 * mapScale);
int Y = baseY * 16 + e.Y / (4 * mapScale);
// Get Base Acre
int index = getItemIndex(X, Y, 2);
if (e.Button == MouseButtons.Right) // Read
reloadCurrentItem(IslandItems[index]);
else // Write
{
IslandItems[index] = copyCurrentItem();
int zX = (X - 16) / 16;
int zY = (Y - 16) / 16;
int zAcre = zX + zY * 2;
IslandAcres[acre].Image = getAcreItemPic(zAcre, IslandItems);
}
}
private void mouseCustom(object sender, MouseEventArgs e)
{
int width = (sender as PictureBox).Width / 16; // 16pixels per item
int X = e.X / (16);
int Y = e.Y / (16);
if (e.X == (sender as PictureBox).Width - 1 - 2) // tweak because the furthest pixel is unused for transparent effect, and 2 px are used for border
X -= 1;
if (e.Y == (sender as PictureBox).Height - 1 - 2)
Y -= 1;
// Get Base Acre
int index = width * Y + X;
var s = (sender as PictureBox);
bool pocket = s == PB_Pocket;
bool dress1 = s == PB_Dresser1;
bool dress2 = s == PB_Dresser2;
bool island = s == PB_Island;
bool dress = dress1 | dress2;
if (dress2) index += Players[currentPlayer].Dressers.Length / 2;
Item item = null;
if (pocket)
item = Players[currentPlayer].Pockets[index];
else if (dress)
item = Players[currentPlayer].Dressers[index];
else if (island)
item = Players[currentPlayer].IslandBox[index];
hoverItem(item, X, Y);
}
private void clickCustom(object sender, MouseEventArgs e)
{
int width = (sender as PictureBox).Width / 16; // 16pixels per item
int X = e.X / (16);
int Y = e.Y / (16);
// Get Base Acre
int index = width * Y + X;
var s = (sender as PictureBox);
bool pocket = s == PB_Pocket;
bool dress1 = s == PB_Dresser1;
bool dress2 = s == PB_Dresser2;
bool island = s == PB_Island;
bool dress = dress1 | dress2;
if (dress2) index += Players[currentPlayer].Dressers.Length / 2;
if (e.Button == MouseButtons.Right) // Read
{
if (pocket)
reloadCurrentItem(Players[currentPlayer].Pockets[index]);
else if (dress)
reloadCurrentItem(Players[currentPlayer].Dressers[index]);
else if (island)
reloadCurrentItem(Players[currentPlayer].IslandBox[index]);
}
else // Write
{
if (pocket)
{
Players[currentPlayer].Pockets[index] = copyCurrentItem();
PB_Pocket.Image = getItemPic(16, 16, Players[currentPlayer].Pockets);
}
else if (dress)
{
Players[currentPlayer].Dressers[index] = copyCurrentItem();
if (dress1)
PB_Dresser1.Image = getItemPic(16, 5, Players[currentPlayer].Dressers.Take(Players[currentPlayer].Dressers.Length / 2).ToArray());
else
PB_Dresser2.Image = getItemPic(16, 5, Players[currentPlayer].Dressers.Skip(Players[currentPlayer].Dressers.Length / 2).ToArray());
}
else if (island)
{
Players[currentPlayer].IslandBox[index] = copyCurrentItem();
PB_Island.Image = getItemPic(16, 5, Players[currentPlayer].IslandBox);
}
}
}
private void reloadCurrentItem(Item item)
{
currentItem = new Item(item.Write());
CB_Item.SelectedValue = (int)item.ID;
TB_Flag1.Text = item.Flag1.ToString("X2");
TB_Flag2.Text = item.Flag2.ToString("X2");
}
private void hoverItem(Item item, int X, int Y)
{
string itemName = Main.itemNames[item.ID];
L_ItemHover.Text = String.Format("[0x{0}{1}{2}] {3}x{4}: {5}",
item.Flag2.ToString("X2"), item.Flag1.ToString("X2"), item.ID.ToString("X4"),
X.ToString("00"), Y.ToString("00"),
itemName);
}
private Item copyCurrentItem()
{
return new Item(currentItem.Write());
}
private int getItemIndex(int X, int Y, int width)
{
int zX = (X - 16) / 16;
int zY = (Y - 16) / 16;
int zAcre = zX + zY * width;
int index = zAcre * 0x100 + (X % 16) + (Y % 16) * 0x10;
return index;
}
private Image getAcreItemPic(int quadrant, Item[] items)
{
const int itemsize = 4 * mapScale;
const int width = 64 * mapScale, height = 64*mapScale;
byte[] bmpData = new byte[4 * ((width) * (height))];
for (int i = 0; i < 0x100; i++) // loop over acre data
{
int X = i % 16;
int Y = i / 16;
var item = items[quadrant*0x100 + i];
if (item.ID == 0x7FFE)
continue; // skip this one.
string itemType = getItemType(item.ID);
uint itemColor = getItemColor(itemType);
// Plop into image
for (int x = 0; x < itemsize*itemsize; x++)
{
Buffer.BlockCopy(BitConverter.GetBytes(itemColor), 0, bmpData,
((Y*itemsize + x/itemsize)*width*4) + ((X*itemsize + x%itemsize)*4), 4);
}
// Buried
if (item.Buried)
{
for (int z = 2; z < itemsize - 1; z++)
{
Buffer.BlockCopy(BitConverter.GetBytes(0xFF000000), 0, bmpData,
((Y*itemsize + z)*width*4) + ((X*itemsize + z)*4), 4);
Buffer.BlockCopy(BitConverter.GetBytes(0xFF000000), 0, bmpData,
((Y*itemsize + z)*width*4) + ((X*itemsize + itemsize - z)*4), 4);
}
}
}
for (int i = 0; i < width * height; i++) // slap on a grid
if (i % (itemsize) == 0 || (i / (16 * itemsize)) % (itemsize) == 0)
Buffer.BlockCopy(BitConverter.GetBytes(0x41FFFFFF), 0, bmpData,
((i/(16*itemsize))*width*4) + ((i%(16*itemsize))*4), 4);
Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData bData = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bData.Scan0, bmpData.Length);
b.UnlockBits(bData);
return b;
}
private string getItemType(ushort ID)
{
if (getIsWilted(ID)) return "wiltedflower";
if (getIsWeed(ID)) return "weed";
if (ID==0x009d) return "pattern";
if (ID>=0x9f && ID<=0xca) return "flower";
if (ID>=0x20a7 && ID<=0x2112) return "money";
if (ID>=0x98 && ID<=0x9c) return "rock";
if (ID>=0x2126 && ID<=0x2239) return "song";
if (ID>=0x223a && ID<=0x227a) return "paper";
if (ID>=0x227b && ID<=0x2285) return "turnip";
if (ID>=0x2286 && ID<=0x2341) return "catchable";
if ((ID>=0x2342 && ID<=0x2445) || ID==0x2119 || ID==0x211a) return "wallfloor";
if (ID>=0x2446 && ID<=0x28b1) return "clothes";
if (ID>=0x28b2 && ID<=0x2934) return "gyroids";
if (ID>=0x2e2c && ID<=0x2e2f) return "mannequin";
if (ID>=0x2e30 && ID<=0x2e8f) return "art";
if (ID>=0x2e90 && ID<=0x2ed2) return "fossil";
if (ID>=0x303b && ID<=0x307a) return "tool";
if (ID!=0x7ffe) return "furniture";
return "unknown";
}
private uint getItemColor(string itemType)
{
switch (itemType)
{
case "furniture": return 0xc83cde30;
case "flower": return 0xc8ec67b8;
case "wiltedflower": return 0xc8ac2778;
case "pattern": return 0xc8877861;
case "money": return 0xc8ffff00;
case "rock": return 0xc8000000;
case "song": return 0xc8a4ecb8;
case "paper": return 0xc8a4ece8;
case "turnip": return 0xc8bbac9d;
case "catchable": return 0xc8bae33e;
case "wallfloor": return 0xc8994040;
case "clothes": return 0xc82874aa;
case "gyroids": return 0xc8d48324;
case "mannequin": return 0xc82e5570;
case "art": return 0xc8cf540a;
case "fossil": return 0xc8868686;
case "tool": return 0xc8818181;
case "tree": return 0xc8ffffff;
case "weed": return 0xc8008000;
}
return 0xc8ff0000;
}
private Image getItemPic(int itemsize, int itemsPerRow, Item[] items)
{
int width = itemsize * itemsPerRow, height = itemsize * items.Length / itemsPerRow;
byte[] bmpData = new byte[4 * ((width) * (height))];
for (int i = 0; i < items.Length; i++) // loop over acre data
{
int X = i % itemsPerRow;
int Y = i / itemsPerRow;
var item = items[i];
if (item.ID == 0x7FFE)
continue; // skip this one.
string itemType = getItemType(item.ID);
uint itemColor = getItemColor(itemType);
// Plop into image
for (int x = 0; x < itemsize * itemsize; x++)
{
Buffer.BlockCopy(BitConverter.GetBytes(itemColor), 0, bmpData,
((Y*itemsize + x%itemsize)*width*4) + ((X*itemsize + x/itemsize)*4), 4);
}
// Buried
if (item.Buried)
{
for (int z = 2; z < itemsize - 1; z++)
{
Buffer.BlockCopy(BitConverter.GetBytes(0xFF000000), 0, bmpData,
((Y*itemsize + z)*width*4) + ((X*itemsize + z)*4), 4);
Buffer.BlockCopy(BitConverter.GetBytes(0xFF000000), 0, bmpData,
((Y*itemsize + z)*width*4) + ((X*itemsize + itemsize - z)*4), 4);
}
}
}
for (int i = 0; i < width * height; i++) // slap on a grid
if (i%(itemsize) == 0 || (i/(itemsize*itemsPerRow))%(itemsize) == 0)
Buffer.BlockCopy(BitConverter.GetBytes(0x17000000), 0, bmpData,
((i/(itemsize*itemsPerRow))*width*4) + ((i%(itemsize*itemsPerRow))*4), 4);
Bitmap b = new Bitmap(width, height, PixelFormat.Format32bppArgb);
BitmapData bData = b.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
System.Runtime.InteropServices.Marshal.Copy(bmpData, 0, bData.Scan0, bmpData.Length);
b.UnlockBits(bData);
return b;
}
private void clickPlayerPic(object sender, EventArgs e)
{
int index = Array.IndexOf(PlayerPics, sender as PictureBox);
if (currentPlayer > -1)
savePlayer(currentPlayer);
loadPlayer(index);
tabControl1.SelectedIndex = 2;
}
private void changeItemID(object sender, EventArgs e)
{
int index = Util.getIndex(CB_Item);
currentItem.ID = (ushort)((index == 0) ? 0x7FFE : index);
if (currentItem.ID == 0x7FFE)
{
TB_Flag1.Text = 0.ToString("X2");
TB_Flag2.Text = 0.ToString("X2");
}
else
L_CurrentItem.Text = String.Format("Current Item: [0x{0}{1}{2}]",
currentItem.Flag2.ToString("X2"),
currentItem.Flag1.ToString("X2"),
currentItem.ID.ToString("X4"));
}
private void EnterKey(object sender, KeyPressEventArgs e)
{
// this will only allow valid hex values [0-9][a-f][A-F] to be entered. See ASCII table
char c = e.KeyChar;
if (!(c == '\b' || ('0' <= c && c <= '9') || ('A' <= c && c <= 'F'))) // et cetera
{
e.Handled = true;
}
}
private void changeItemFlag(object sender, EventArgs e)
{
currentItem.Flag1 = Convert.ToByte(TB_Flag1.Text, 16);
currentItem.Flag2 = Convert.ToByte(TB_Flag2.Text, 16);
L_CurrentItem.Text = String.Format("Current Item: [0x{0}{1}{2}]",
currentItem.Flag2.ToString("X2"),
currentItem.Flag1.ToString("X2"),
currentItem.ID.ToString("X4"));
}
private bool loaded;
private void changeVillager(object sender, EventArgs e)
{
if (!loaded) return;
int index = Array.IndexOf(TownVillagers, sender as ComboBox);
int value = Util.getIndex(sender as ComboBox);
if (index == -1 || value == -1) return;
Villagers[index].Type = Main.villagerList[value].Type;
if (DialogResult.Yes != Util.Prompt(MessageBoxButtons.YesNoCancel, String.Format("Do you want to reset villager {0}'s data? (furniture, clothes...)", index+1)))
return;
Array.Copy(Main.villagerList[value].DefaultBytes, 0, Villagers[index].Data, 0x244E, 88);
TownVillagersCatch[index].Text = Main.villagerList[value].CatchPhrase;
}
private void saveBuildingList()
{
int itemcount = dataGridView1.Rows.Count;
for (int i = 0; i < itemcount; i++)
{
int ID = (int)dataGridView1.Rows[i].Cells[0].Value;
if (ID > 0xF8 || ID < 0)
{
Buildings[i].ID = 0xF8;
Buildings[i].X = 0;
Buildings[i].Y = 0;
}
else
{
Buildings[i].ID = ID;
try
{ Buildings[i].X = Convert.ToUInt16(dataGridView1.Rows[i].Cells[1].Value.ToString()); }
catch { }
try
{ Buildings[i].Y = Convert.ToUInt16(dataGridView1.Rows[i].Cells[2].Value.ToString()); }
catch { }
}
}
}
private void populateBuildingList()
{
dataGridView1.Rows.Clear();
dataGridView1.Columns.Clear();
DataGridViewComboBoxColumn dgvItemVal = new DataGridViewComboBoxColumn
{
DisplayStyle = DataGridViewComboBoxDisplayStyle.Nothing,
DisplayIndex = 0,
DisplayMember = "Text",
ValueMember = "Value",
DataSource = Main.buildingList,
Width = 215,
FlatStyle = FlatStyle.Flat
};
DataGridViewColumn dgvX = new DataGridViewTextBoxColumn
{
HeaderText = "X",
DisplayIndex = 1,
Width = 35,
};
DataGridViewColumn dgvY = new DataGridViewTextBoxColumn
{
HeaderText = "Y",
DisplayIndex = 2,
Width = 35,
};
dgvX.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dgvY.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
dataGridView1.Columns.Add(dgvItemVal);
dataGridView1.Columns.Add(dgvX);
dataGridView1.Columns.Add(dgvY);
dataGridView1.Rows.Add(Buildings.Length);
dataGridView1.CancelEdit();
string itemname = "";
for (int i = 0; i < Buildings.Length; i++)
{
int itemvalue = Buildings[i].ID;
try { itemname = Main.buildingNames[itemvalue]; }
catch
{
Util.Error("Unknown building detected.", "Building ID: " + itemvalue, "Building is after: " + itemname);
continue;
}
int itemarrayval = Array.IndexOf(Main.buildingNames, itemname);
if (itemarrayval == -1)
{
Buildings[i].ID = 0xFE;
Buildings[i].X = 0;
Buildings[i].Y = 0;
Util.Alert(itemname + " removed from Building List.", "If you save changes to Garden, the Building will no longer be in the Town.");
}
dataGridView1.Rows[i].Cells[0].Value = Buildings[i].ID;
dataGridView1.Rows[i].Cells[1].Value = Buildings[i].X;
dataGridView1.Rows[i].Cells[2].Value = Buildings[i].Y;
}
}
private void dropclick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex != 0) return;
ComboBox comboBox = (ComboBox)dataGridView1.EditingControl;
comboBox.DroppedDown = true;
}
private void reloadOverviewLabel()
{
L_Info.Text = String.Format("{1}{0}{0}Players:{0}{2}{0}{3}{0}{4}{0}{5}", Environment.NewLine,
Save.TownName,
Players[0].Name, Players[1].Name, Players[2].Name, Players[3].Name);
}
private void changePlayerName(object sender, EventArgs e)
{
PlayerBankCheat[currentPlayer].Text = String.Format(DefaultBankText, TB_Name.Text);
Players[currentPlayer].Name = TB_Name.Text;
reloadOverviewLabel();
}
private void changeTownName(object sender, EventArgs e)
{
Save.TownName = TB_TownName.Text;
reloadOverviewLabel();
}
// Leaftools ported cheats, thanks to NeoKamek for hosting the source code for his tools.
// https://bitbucket.org/neokamek/leaftools/src
private void B_PWP_Click(object sender, EventArgs e)
{
const int offset = 0x4D9C8 + 0x80;
byte[] PWPUnlock =
{
0xFF, 0xFF, 0xFF, 0xFF, // 0
0xFF, 0xFF, 0xFF, 0xFF, // 1
0xFF, 0xFF, 0xFF, 0xFF, // 2
0xFF, 0xFF, 0xFF, 0xFF, // 3
0xFF, 0xFF, 0xFF, 0xFF, // 4
0x2A, 0xD6, 0xE4, 0x58, // 5
};
Array.Copy(PWPUnlock, 0, Save.Data, offset, PWPUnlock.Length);
Util.Alert("All Public Works Projects unlocked!");
}
private void B_Bank_Click(object sender, EventArgs e)
{
int player = Array.IndexOf(PlayerBankCheat, sender as Button);
if (player < 0) return;
const int offset = 0x6B8C + 0x80 - 0xA0; // within player data
if (BitConverter.ToUInt64(Players[player].Data, offset) == 0x0D1186368CF95678)
{ Util.Alert(String.Format("(Player {0}) {1}'s account is already maxed!", player, Players[player].Name)); return; }
Array.Copy(BitConverter.GetBytes((ulong)0x0D1186368CF95678), 0, Players[player].Data, offset, 8);
Util.Alert(String.Format("(Player {0}) {1}'s account has been maxed at 999,999,999 Bells!", player, Players[player].Name));
}
private void B_Grass_Click(object sender, EventArgs e)
{
//
const byte tileValue = 0xFF;
const int offset = 0x53E80 + 0x80;
for (int i = 0; i < 0x2800; i++)
Save.Data[offset + i] = tileValue;
Util.Alert("All Map Tiles have had their grass refreshed!!");
}
private void B_Desert_Click(object sender, EventArgs e)
{
const byte tileValue = 0x00;
const int offset = 0x53E80 + 0x80;
for (int i = 0; i < 0x2800; i++)
Save.Data[offset + i] = tileValue;
Util.Alert("All Map Tiles have had their grass removed (desertified)!");
}
private void mouseTownAcre(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(aeTownAcres, sender as PictureBox);
if (acre < 0) return;
L_AcreInfo.Text = String.Format("Acre Info:{0}X: {1}{0}Y: {2}{0}Index: {3}",
Environment.NewLine, acre%7, acre/7, aeTownAcreTiles[acre]);
}
private void mouseIslandAcre(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(aeIslandAcres, sender as PictureBox);
if (acre < 0) return;
L_AcreInfo.Text = String.Format("Acre Info:{0}X: {1}{0}Y: {2}{0}Index: {3}",
Environment.NewLine, acre % 4, acre / 4, aeIslandAcreTiles[acre]);
}
private void clickTownAcre(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(aeTownAcres, sender as PictureBox);
if (acre < 0) return;
int newAcre = aeTownAcreTiles[acre] + (e.Button == MouseButtons.Right ? -1 : 1);
if (newAcre < 0)
newAcre = CHK_IslandAcresOnTown.Checked ? 203 : 153;
else if (newAcre > 203 || (newAcre > 153 && !CHK_IslandAcresOnTown.Checked))
newAcre = 1;
aeTownAcreTiles[acre] = (ushort)newAcre;
aeTownAcres[acre].BackgroundImage = (Image)Properties.Resources.ResourceManager.GetObject("acre_" + aeTownAcreTiles[acre]);
}
private void clickIslandAcre(object sender, MouseEventArgs e)
{
int acre = Array.IndexOf(aeIslandAcres, sender as PictureBox);
if (acre < 0) return;
if (e.Button == MouseButtons.Right) // Decrement (180-203 allowed)
{
aeIslandAcreTiles[acre]--;
if (aeIslandAcreTiles[acre] < 180) aeIslandAcreTiles[acre] = 203;
}
else // Increment (180-203 allowed)
{
aeIslandAcreTiles[acre]--;
if (aeIslandAcreTiles[acre] > 203) aeIslandAcreTiles[acre] = 180;
}
aeIslandAcres[acre].BackgroundImage = (Image)Properties.Resources.ResourceManager.GetObject("acre_" + aeIslandAcreTiles[acre]);
}
private void B_ApplyAcres_Click(object sender, EventArgs e)
{
if (DialogResult.Yes !=
Util.Prompt(MessageBoxButtons.YesNo,
String.Format("Applying acres will copy the Acre Editor's {0} map to the Save File's {0} map.", Tab_AcreTown.Text),
"Continue?"))
return;
if (TC_AcreEditor.SelectedIndex == 0)
{
Array.Copy(aeTownAcreTiles, TownAcreTiles, TownAcreTiles.Length);
fillMapAcres(TownAcreTiles, TownAcres);
}
else
{
Array.Copy(aeIslandAcreTiles, IslandAcreTiles, IslandAcreTiles.Length);
fillMapAcres(IslandAcreTiles, IslandAcres);
}
}
private void B_ResetAcres_Click(object sender, EventArgs e)
{
if (DialogResult.Yes !=
Util.Prompt(MessageBoxButtons.YesNo,
String.Format("Applying acres will copy the Save File's {0} map to the Acre Editor's {0} map.", Tab_AcreTown.Text),
"Continue?"))
return;
if (TC_AcreEditor.SelectedIndex == 0)
{
Array.Copy(TownAcreTiles, aeTownAcreTiles, TownAcreTiles.Length);
fillMapAcres(aeTownAcreTiles, aeTownAcres);
}
else
{
Array.Copy(IslandAcreTiles, aeIslandAcreTiles, IslandAcreTiles.Length);
fillMapAcres(aeIslandAcreTiles, aeIslandAcres);
}
}
private void B_ImportAcres_Click(object sender, EventArgs e)
{
var ofd = new OpenFileDialog
{
FileName = ((TC_AcreEditor.SelectedIndex == 0) ? "Town" : "Island") + "AcreData.acnlmap"
};
if (DialogResult.OK != ofd.ShowDialog())
return;
byte[] data = File.ReadAllBytes(ofd.FileName);
if (data.Length != 2*6*7 && data.Length != 2*4*4)
{
Util.Error("Input file length is not a valid acre map.",
String.Format("Data Size: {1}{0}Acre Count: {2}", Environment.NewLine, data.Length, data.Length/2));
return;
}
ushort[] uA = new ushort[data.Length/2];
using (MemoryStream ms = new MemoryStream(data))
using (BinaryReader br = new BinaryReader(ms))
{
for (int i = 0; i < uA.Length; i++)
uA[i] = br.ReadUInt16();
}
if (uA.Length == 6*7) // Town Map
{
Array.Copy(uA, aeIslandAcreTiles, uA.Length);
fillMapAcres(aeTownAcreTiles, aeTownAcres);
}
else if (uA.Length == 4*4) // Island Map
{
Array.Copy(uA, aeIslandAcreTiles, uA.Length);
fillMapAcres(aeIslandAcreTiles, aeIslandAcres);
}
//else
// return; // unreachable.
}
private void B_ExportAcres_Click(object sender, EventArgs e)
{
// obtain acre data
var sfd = new SaveFileDialog
{
FileName = ((TC_AcreEditor.SelectedIndex == 0) ? "Town" : "Island") + "AcreData.acnlmap"
};
if (DialogResult.OK != sfd.ShowDialog())
return;
byte[] data;
ushort[] usD = (TC_AcreEditor.SelectedIndex == 0) ? aeTownAcreTiles : aeIslandAcreTiles;
using (MemoryStream ms = new MemoryStream())
using (BinaryWriter bw = new BinaryWriter(ms))
{
foreach (ushort u in usD)
bw.Write(u);
data = ms.ToArray();
}
File.WriteAllBytes(sfd.FileName, data);
}
}
}