Remove WorldItem class
There was no need for that class. Removing it enforces all items (besides furniture) as "Items". Mainly done for consistency.
This commit is contained in:
parent
899e2ead58
commit
88b0bcc05e
8 changed files with 236 additions and 371 deletions
|
@ -117,81 +117,6 @@ public override int GetHashCode()
|
|||
}
|
||||
}
|
||||
|
||||
public class WorldItem : Item, IEquatable<WorldItem>
|
||||
{
|
||||
public readonly Point Location;
|
||||
public readonly int Index;
|
||||
public bool Buried;
|
||||
public bool Watered;
|
||||
|
||||
public WorldItem(ushort itemId, byte flag1, byte flag2, int position) : base(itemId, flag1, flag2)
|
||||
{
|
||||
Location = new Point(position % 16, position / 16);
|
||||
Index = position;
|
||||
Buried = Flag1 == 0x80;
|
||||
Watered = Flag1 == 0x40;
|
||||
}
|
||||
|
||||
public WorldItem(ushort itemId, int position) : this(itemId, 0, 0, position) { }
|
||||
|
||||
public WorldItem(int position)
|
||||
{
|
||||
Location = new Point(position % 16, position / 16);
|
||||
Index = position;
|
||||
}
|
||||
|
||||
public WorldItem(Item cloningItem, int position) : base(cloningItem)
|
||||
{
|
||||
Index = position;
|
||||
Location = new Point(Index % 16, Index / 16);
|
||||
}
|
||||
|
||||
public WorldItem(uint itemId, int position) : this((ushort) itemId, (byte) (itemId >> 24),
|
||||
(byte) (itemId >> 16), position) { }
|
||||
|
||||
public bool Equals(WorldItem item)
|
||||
{
|
||||
if (ReferenceEquals(item, null)) return false;
|
||||
return ReferenceEquals(item, this) || base.Equals(item);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
case WorldItem _:
|
||||
return Equals((WorldItem) obj);
|
||||
case Item _:
|
||||
return Equals((Item) obj);
|
||||
case ushort _:
|
||||
return Equals((ushort) obj);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool operator ==(WorldItem obj1, WorldItem obj2)
|
||||
{
|
||||
return Equals(obj1, obj2);
|
||||
}
|
||||
|
||||
public static bool operator !=(WorldItem obj1, WorldItem obj2)
|
||||
{
|
||||
return !Equals(obj1, obj2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
var hashCode = base.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ Location.GetHashCode();
|
||||
hashCode = (hashCode * 397) ^ Index;
|
||||
return hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class Furniture : Item, IEquatable<Furniture>
|
||||
{
|
||||
public readonly ushort BaseItemId;
|
||||
|
|
|
@ -31,27 +31,29 @@ public Acre(byte acreId, int position)
|
|||
|
||||
public class WorldAcre : Acre
|
||||
{
|
||||
public WorldItem[] AcreItems = new WorldItem[16 * 16];
|
||||
public Item[] Items = new Item[16 * 16];
|
||||
public int TownIndex;
|
||||
public bool IsIslandAcre;
|
||||
|
||||
public WorldAcre(ushort acreId, int position, ushort[] items = null, uint[] nlItems = null,
|
||||
int townPosition = -1) : base(acreId, position)
|
||||
int townPosition = -1, bool isIslandAcre = false) : base(acreId, position)
|
||||
{
|
||||
TownIndex = townPosition;
|
||||
IsIslandAcre = isIslandAcre;
|
||||
|
||||
if (items != null)
|
||||
{
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
AcreItems[i] = new WorldItem(items[i], i);
|
||||
AcreItems[i].Buried = IsItemBuried(AcreItems[i], Save.SaveInstance.SaveGeneration);
|
||||
Items[i] = new Item(items[i]);
|
||||
//Items[i].Buried = IsItemBuried(Items[i], Save.SaveInstance.SaveGeneration);
|
||||
}
|
||||
}
|
||||
else if (nlItems != null)
|
||||
{
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
AcreItems[i] = new WorldItem(nlItems[i], i);
|
||||
Items[i] = new Item(nlItems[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,21 +63,21 @@ public WorldAcre(ushort acreId, int position) : base(acreId, position) { }
|
|||
public WorldAcre(ushort acreId, int position, uint[] items = null) : this(acreId, position, null, items)
|
||||
{ }
|
||||
|
||||
public WorldAcre(ushort acreId, int position, WorldItem[] items, int townPosition = -1) : base(acreId, position)
|
||||
public WorldAcre(ushort acreId, int position, Item[] items, int townPosition = -1) : base(acreId, position)
|
||||
{
|
||||
AcreItems = items;
|
||||
Items = items;
|
||||
if (townPosition <= -1) return;
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
AcreItems[i].Buried = IsItemBuried(AcreItems[i], Save.SaveInstance.SaveGeneration);
|
||||
//Items[i].Buried = IsItemBuried(Items[i], Save.SaveInstance.SaveGeneration);
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsItemBuried(Item item, SaveGeneration generation)
|
||||
{
|
||||
if (item == null || !AcreItems.Contains(item)) return false;
|
||||
if (item == null || !Items.Contains(item)) return false;
|
||||
|
||||
var itemIdx = Array.IndexOf(AcreItems, item);
|
||||
var itemIdx = Array.IndexOf(Items, item);
|
||||
if (itemIdx < 0 || itemIdx > 255) return false;
|
||||
|
||||
int offset;
|
||||
|
@ -99,11 +101,13 @@ public bool IsItemBuried(Item item, SaveGeneration generation)
|
|||
return false;
|
||||
}
|
||||
|
||||
public bool IsItemBuried(Item item) => IsItemBuried(item, Save.SaveInstance.SaveGeneration);
|
||||
|
||||
public bool SetItemBuried(Item item, bool buried, SaveGeneration generation)
|
||||
{
|
||||
if (item == null || !AcreItems.Contains(item)) return false;
|
||||
if (item == null || !Items.Contains(item)) return false;
|
||||
|
||||
var itemIdx = Array.IndexOf(AcreItems, item);
|
||||
var itemIdx = Array.IndexOf(Items, item);
|
||||
if (itemIdx < 0 || itemIdx > 255) return false;
|
||||
|
||||
int offset;
|
||||
|
@ -161,7 +165,7 @@ public bool LoadDefaultItems(Save saveFile)
|
|||
{
|
||||
if (i >= 0x100) // Don't read past the maximum item slot.
|
||||
break;
|
||||
AcreItems[i] = new WorldItem(reader.ReadUInt16().Reverse(), i);
|
||||
Items[i] = new Item(reader.ReadUInt16().Reverse());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using ACSE.Core.Housing;
|
||||
using ACSE.Core.Items;
|
||||
using ACSE.Core.Patterns;
|
||||
using ACSE.Core.Players;
|
||||
using ACSE.Core.Saves;
|
||||
using ACSE.Core.Town.Acres;
|
||||
using ACSE.Core.Villagers;
|
||||
|
||||
namespace ACSE.Core.Town.Island
|
||||
|
@ -38,7 +40,7 @@ public sealed class Island
|
|||
public string TownName;
|
||||
public ushort TownId;
|
||||
public Player Owner;
|
||||
public WorldItem[][] Items;
|
||||
public WorldAcre[] Acres;
|
||||
public House Cabana;
|
||||
public Villager Islander;
|
||||
public Pattern FlagPattern;
|
||||
|
@ -68,17 +70,11 @@ public Island(int offset, IEnumerable<Player> players, Save saveFile)
|
|||
|
||||
BuriedDataArray = saveFile.ReadByteArray(offset + BuriedData, 0x40);
|
||||
|
||||
Items = new WorldItem[2][];
|
||||
Acres = new WorldAcre[2];
|
||||
for (var acre = 0; acre < 2; acre++)
|
||||
{
|
||||
Items[acre] = new WorldItem[0x100];
|
||||
var i = 0;
|
||||
foreach (var itemId in saveFile.ReadUInt16Array(offset + WorldData + acre * 0x200, 0x100, true))
|
||||
{
|
||||
Items[acre][i] = new WorldItem(itemId, i % 256);
|
||||
SetBuried(Items[acre][i], acre, BuriedDataArray, saveFile.SaveType);
|
||||
i++;
|
||||
}
|
||||
Acres[acre] = new WorldAcre(0, acre,
|
||||
saveFile.ReadUInt16Array(offset + WorldData + acre * 0x200, 0x100, true), null, acre, true);
|
||||
}
|
||||
|
||||
Cabana = new House(-1, offset + CottageData, 1, 0);
|
||||
|
@ -127,56 +123,79 @@ private static ushort IslandAcreIndexToIslandAcreId(byte side, byte index)
|
|||
}
|
||||
}
|
||||
|
||||
private static int GetBuriedDataLocation(WorldItem item, int acre, SaveType saveType)
|
||||
{
|
||||
if (item == null) return -1;
|
||||
var worldPosition = 0;
|
||||
switch (saveType)
|
||||
{
|
||||
case SaveType.AnimalCrossing:
|
||||
case SaveType.DoubutsuNoMoriEPlus:
|
||||
case SaveType.AnimalForestEPlus:
|
||||
case SaveType.CityFolk:
|
||||
worldPosition = (acre * 256) + (15 - item.Location.X) + item.Location.Y * 16; //15 - item.Location.X because it's stored as a ushort in memory w/ reversed endianess
|
||||
break;
|
||||
case SaveType.WildWorld:
|
||||
worldPosition = (acre * 256) + item.Index;
|
||||
break;
|
||||
}
|
||||
return worldPosition / 8;
|
||||
}
|
||||
|
||||
private static void SetBuried(WorldItem item, int acre, IReadOnlyList<byte> buriedItemData, SaveType saveType)
|
||||
{
|
||||
var burriedDataOffset = GetBuriedDataLocation(item, acre, saveType);
|
||||
if (burriedDataOffset > -1 && burriedDataOffset < buriedItemData.Count)
|
||||
{
|
||||
item.Buried = buriedItemData[burriedDataOffset].GetBit(item.Location.X % 8) == 1;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make a toggle to enable/disable the island.
|
||||
private bool IsPurchased()
|
||||
=> (_saveFile.ReadByte(_offset + IslandInfoFlag) & 0x80) == 0x80;
|
||||
|
||||
public void SetBuriedInMemory(WorldItem item, int acre, byte[] buriedItemData, bool buried, SaveType saveType)
|
||||
{
|
||||
if (saveType == SaveType.NewLeaf || saveType == SaveType.WelcomeAmiibo) return;
|
||||
var buriedLocation = GetBuriedDataLocation(item, acre, saveType);
|
||||
if (buriedLocation > -1)
|
||||
{
|
||||
buriedItemData[buriedLocation] = buriedItemData[buriedLocation].SetBit(item.Location.X % 8, buried);
|
||||
item.Buried = buriedItemData[buriedLocation].GetBit(item.Location.X % 8) == 1;
|
||||
}
|
||||
else
|
||||
item.Buried = false;
|
||||
}
|
||||
|
||||
public ushort[] GetAcreIds()
|
||||
{
|
||||
return new[] { IslandAcreIndexToIslandAcreId(0, IslandLeftAcreIndex), IslandAcreIndexToIslandAcreId(1, IslandRightAcreIndex) };
|
||||
}
|
||||
|
||||
public bool IsItemBuried(WorldAcre acre, Item item, SaveGeneration generation)
|
||||
{
|
||||
if (item == null || !acre.Items.Contains(item)) return false;
|
||||
|
||||
var itemIdx = Array.IndexOf(acre.Items, item);
|
||||
if (itemIdx < 0 || itemIdx > 255) return false;
|
||||
|
||||
int offset;
|
||||
switch (generation)
|
||||
{
|
||||
case SaveGeneration.N64:
|
||||
case SaveGeneration.GCN:
|
||||
case SaveGeneration.iQue:
|
||||
case SaveGeneration.Wii:
|
||||
offset = Save.SaveInstance.SaveInfo.SaveOffsets.BuriedData + (acre.Index * 16 + itemIdx / 16) * 2;
|
||||
return Save.SaveInstance.ReadUInt16(offset, true, true).GetBit(itemIdx % 16) == 1;
|
||||
|
||||
case SaveGeneration.NDS:
|
||||
offset = Save.SaveInstance.SaveInfo.SaveOffsets.BuriedData + (acre.Index * 256 + itemIdx) / 8;
|
||||
return Save.SaveInstance.ReadByte(offset, true).GetBit(itemIdx % 8) == 1;
|
||||
|
||||
case SaveGeneration.N3DS:
|
||||
return (item.Flag1 & 0x80) == 0x80;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsItemBuried(WorldAcre acre, Item item) =>
|
||||
IsItemBuried(acre, item, Save.SaveInstance.SaveGeneration);
|
||||
|
||||
public bool SetItemBuried(WorldAcre acre, Item item, bool buried, SaveGeneration generation)
|
||||
{
|
||||
if (item == null || !acre.Items.Contains(item)) return false;
|
||||
|
||||
var itemIdx = Array.IndexOf(acre.Items, item);
|
||||
if (itemIdx < 0 || itemIdx > 255) return false;
|
||||
|
||||
int offset;
|
||||
switch (generation)
|
||||
{
|
||||
case SaveGeneration.N64:
|
||||
case SaveGeneration.GCN:
|
||||
case SaveGeneration.iQue:
|
||||
case SaveGeneration.Wii:
|
||||
offset = Save.SaveInstance.SaveInfo.SaveOffsets.BuriedData + (acre.Index * 16 + itemIdx / 16) * 2;
|
||||
Save.SaveInstance.Write(offset,
|
||||
Save.SaveInstance.ReadUInt16(offset, true, true).SetBit(itemIdx % 16, buried), true, true);
|
||||
break;
|
||||
|
||||
case SaveGeneration.NDS:
|
||||
offset = Save.SaveInstance.SaveInfo.SaveOffsets.BuriedData + (acre.Index * 256 + itemIdx) / 8;
|
||||
Save.SaveInstance.Write(offset,
|
||||
Save.SaveInstance.ReadByte(offset, true).SetBit(itemIdx % 8, buried), true);
|
||||
break;
|
||||
|
||||
case SaveGeneration.N3DS:
|
||||
item.Flag1 &= 0x7F;
|
||||
break;
|
||||
}
|
||||
|
||||
return IsItemBuried(acre, item, generation);
|
||||
}
|
||||
|
||||
public void Write()
|
||||
{
|
||||
if (Owner != null)
|
||||
|
@ -192,7 +211,7 @@ public void Write()
|
|||
{
|
||||
for (var item = 0; item < 0x100; item++)
|
||||
{
|
||||
_saveFile.Write(_offset + WorldData + acre * 0x200 + item * 2, Items[acre][item].ItemId, true);
|
||||
_saveFile.Write(_offset + WorldData + acre * 0x200 + item * 2, Acres[acre].Items[item].ItemId, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -68,11 +68,17 @@ public static Tuple<byte[], bool> FindVillagerHouse(ushort villagerId, WorldAcre
|
|||
var villagerHouseId = (ushort)(0x5000 + (villagerId & 0xFF));
|
||||
foreach (var acre in townAcres)
|
||||
{
|
||||
var villagerHouse = acre.AcreItems.FirstOrDefault(o => o.ItemId == villagerHouseId);
|
||||
var villagerHouse = acre.Items.FirstOrDefault(o => o.ItemId == villagerHouseId);
|
||||
if (villagerHouse != null)
|
||||
{
|
||||
var idx = Array.IndexOf(acre.Items, villagerHouse);
|
||||
|
||||
return new Tuple<byte[], bool>(
|
||||
new[] { (byte)(acre.Index % 7), (byte)(acre.Index / 7), (byte)(villagerHouse.Location.X), (byte)(villagerHouse.Location.Y + 1) },
|
||||
new[]
|
||||
{
|
||||
(byte) (acre.Index % 7), (byte) (acre.Index / 7), (byte) (idx % 16),
|
||||
(byte) (idx / 16 + 1)
|
||||
},
|
||||
true);
|
||||
}
|
||||
}
|
||||
|
@ -86,14 +92,16 @@ public static (byte[], bool) FindVillagerHouseWildWorld(int villagerIndex, World
|
|||
var houseId = 0x5001 + villagerIndex;
|
||||
foreach (var acre in townAcres)
|
||||
{
|
||||
var villagerHouse = acre.AcreItems.FirstOrDefault(o => o.ItemId == houseId);
|
||||
var villagerHouse = acre.Items.FirstOrDefault(o => o.ItemId == houseId);
|
||||
if (villagerHouse != null)
|
||||
{
|
||||
var idx = Array.IndexOf(acre.Items, villagerHouse);
|
||||
|
||||
return (
|
||||
new[]
|
||||
{
|
||||
(byte) (((acre.Index % 4 + 1) << 4) | (villagerHouse.Location.X % 16)),
|
||||
(byte) (((acre.Index / 4 + 1) << 4) | (villagerHouse.Location.Y % 16))
|
||||
(byte) (((acre.Index % 4 + 1) << 4) | (idx % 16)),
|
||||
(byte) (((acre.Index / 4 + 1) << 4) | (idx / 16))
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
@ -125,13 +133,13 @@ public static bool[] CheckPerfectTownRequirements(WorldAcre[] acres, bool makePe
|
|||
var weedCount = 0;
|
||||
for (var o = 0; o < 256; o++)
|
||||
{
|
||||
var item = acre.AcreItems[o];
|
||||
var item = acre.Items[o];
|
||||
if (item.Name == "Weed")
|
||||
{
|
||||
weedCount++;
|
||||
if (makePerfect)
|
||||
{
|
||||
acre.AcreItems[o] = new WorldItem(0, o);
|
||||
acre.Items[o] = new Item(0);
|
||||
}
|
||||
}
|
||||
else if (ItemData.GetItemType(item.ItemId, Save.SaveInstance.SaveType) == ItemType.Tree)
|
||||
|
@ -147,9 +155,9 @@ public static bool[] CheckPerfectTownRequirements(WorldAcre[] acres, bool makePe
|
|||
{
|
||||
for (var x = 0; x < 256; x++)
|
||||
{
|
||||
if (ItemData.GetItemType(acre.AcreItems[x].ItemId,
|
||||
if (ItemData.GetItemType(acre.Items[x].ItemId,
|
||||
Save.SaveInstance.SaveType) != ItemType.Tree) continue;
|
||||
acre.AcreItems[x] = new WorldItem(0, x);
|
||||
acre.Items[x] = new Item(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -161,12 +169,12 @@ public static bool[] CheckPerfectTownRequirements(WorldAcre[] acres, bool makePe
|
|||
for (var x = 0; x < 256; x++)
|
||||
{
|
||||
// Check to make sure the item directly above, below, and to the left and right isn't already occupied.
|
||||
if (acre.AcreItems[x].ItemId != 0 ||
|
||||
(x >= 16 && acre.AcreItems[x - 16].ItemId != 0) ||
|
||||
(x <= 239 && acre.AcreItems[x + 16].ItemId != 0) ||
|
||||
(x != 0 && acre.AcreItems[x - 1].ItemId != 0) ||
|
||||
(x != 255 && acre.AcreItems[x + 1].ItemId != 0)) continue;
|
||||
acre.AcreItems[x] = new WorldItem(0x0804, x);
|
||||
if (acre.Items[x].ItemId != 0 ||
|
||||
(x >= 16 && acre.Items[x - 16].ItemId != 0) ||
|
||||
(x <= 239 && acre.Items[x + 16].ItemId != 0) ||
|
||||
(x != 0 && acre.Items[x - 1].ItemId != 0) ||
|
||||
(x != 255 && acre.Items[x + 1].ItemId != 0)) continue;
|
||||
acre.Items[x] = new Item(0x0804);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -205,10 +213,10 @@ public static void PlaceStructure(WorldAcre acre, int startIndex, List<ushort[]>
|
|||
case 0: // Just for alignment
|
||||
break;
|
||||
case 1:
|
||||
acre.AcreItems[index] = new WorldItem(0xFFFF, index);
|
||||
acre.Items[index] = new Item(0xFFFF);
|
||||
break;
|
||||
default:
|
||||
acre.AcreItems[index] = new WorldItem(structureInfo[y][x], index);
|
||||
acre.Items[index] = new Item(structureInfo[y][x]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -260,45 +268,6 @@ public static void FloodFillItemArray(ref Item[] items, int itemsPerRow, int sta
|
|||
}
|
||||
}
|
||||
|
||||
public static void FloodFillWorldItemArray(ref WorldItem[] items, int itemsPerRow, int startIndex, WorldItem originalItem, WorldItem newItem)
|
||||
{
|
||||
var rows = items.Length / itemsPerRow;
|
||||
var locationStack = new Stack<Point>();
|
||||
var previousPoints = new int[items.Length];
|
||||
|
||||
var x = startIndex % itemsPerRow;
|
||||
var y = startIndex / itemsPerRow;
|
||||
|
||||
locationStack.Push(new Point(x, y));
|
||||
|
||||
while (locationStack.Count > 0)
|
||||
{
|
||||
var p = locationStack.Pop();
|
||||
|
||||
var idx = p.X + p.Y * itemsPerRow;
|
||||
|
||||
if (p.X < itemsPerRow && p.X > -1 &&
|
||||
p.Y < rows && p.Y > -1 && previousPoints[idx] == 0) // Make sure we stay within bounds
|
||||
{
|
||||
var i = items[idx];
|
||||
if (i.Equals(originalItem))
|
||||
{
|
||||
Save.SaveInstance.ChangesMade = true;
|
||||
items[idx] = new WorldItem(newItem.ItemId, newItem.Flag1, newItem.Flag2, i.Index);
|
||||
if (p.X - 1 > -1)
|
||||
locationStack.Push(new Point(p.X - 1, p.Y));
|
||||
if (p.X + 1 < itemsPerRow)
|
||||
locationStack.Push(new Point(p.X + 1, p.Y));
|
||||
if (p.Y - 1 > -1)
|
||||
locationStack.Push(new Point(p.X, p.Y - 1));
|
||||
if (p.Y + 1 < rows)
|
||||
locationStack.Push(new Point(p.X, p.Y + 1));
|
||||
}
|
||||
}
|
||||
previousPoints[idx] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
public static void FloodFillFurnitureArray(ref Furniture[] items, int itemsPerRow, int startIndex, Furniture originalItem, Furniture newItem)
|
||||
{
|
||||
var rows = items.Length / itemsPerRow;
|
||||
|
|
|
@ -18,10 +18,10 @@ public sealed class AcreItemEditor : ItemEditor
|
|||
/// <summary>
|
||||
/// The <see cref="WorldItem"/>s associated with the acre.
|
||||
/// </summary>
|
||||
public new WorldItem[] Items => Acre?.AcreItems;
|
||||
public new Item[] Items => Acre?.Items;
|
||||
|
||||
|
||||
public AcreItemEditor(MainForm form, WorldItem Items, int itemsPerRow)
|
||||
public AcreItemEditor(MainForm form, Item items, int itemsPerRow)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
using ACSE.Core.Items;
|
||||
using ACSE.Core.Players;
|
||||
using ACSE.Core.Saves;
|
||||
using ACSE.Core.Town.Acres;
|
||||
using ACSE.Core.Town.Buildings;
|
||||
using ACSE.Core.Villagers;
|
||||
using ACSE.WinForms.Controls;
|
||||
|
@ -74,7 +75,7 @@ public static Image SetImageColor(Image grayscaleImage, ColorMatrix transformMat
|
|||
}
|
||||
}
|
||||
|
||||
public static void DrawBuriedIcons(Bitmap map, WorldItem[] items, int itemSize)
|
||||
public static void DrawBuriedIcons(Bitmap map, WorldAcre acre, int itemSize)
|
||||
{
|
||||
using (var bitmapGraphics = Graphics.FromImage(map))
|
||||
{
|
||||
|
@ -84,11 +85,13 @@ public static void DrawBuriedIcons(Bitmap map, WorldItem[] items, int itemSize)
|
|||
|
||||
using (Image buriedIcon = Properties.Resources.Buried)
|
||||
{
|
||||
foreach (var item in items)
|
||||
for (var i = 0; i < acre.Items.Length; i++)
|
||||
{
|
||||
if (!item.Buried || item.Type == ItemType.Empty) continue;
|
||||
bitmapGraphics.DrawImage(buriedIcon, item.Location.X * itemSize + 1,
|
||||
item.Location.Y * itemSize + 1, itemSize - 1, itemSize - 1);
|
||||
var item = acre.Items[i];
|
||||
if (!acre.IsItemBuried(item, Save.SaveInstance.SaveGeneration) ||
|
||||
item.Type == ItemType.Empty) continue;
|
||||
bitmapGraphics.DrawImage(buriedIcon, (i % 16) * itemSize + 1,
|
||||
(i / 16) * itemSize + 1, itemSize - 1, itemSize - 1);
|
||||
}
|
||||
|
||||
bitmapGraphics.Flush();
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Forms.VisualStyles;
|
||||
using ACSE.Core.BitFields.Catalog;
|
||||
using ACSE.Core.BitFields.Encyclopedia;
|
||||
using ACSE.Core.BitFields.Museum;
|
||||
|
@ -39,6 +40,7 @@
|
|||
using ACSE.WinForms.Imaging;
|
||||
using ACSE.WinForms.Managers;
|
||||
using ACSE.WinForms.Utilities;
|
||||
using ContentAlignment = System.Drawing.ContentAlignment;
|
||||
using ItemChangedEventArgs = ACSE.Core.Items.ItemChangedEventArgs;
|
||||
|
||||
namespace ACSE.WinForms
|
||||
|
@ -2454,7 +2456,7 @@ private void SetupMapPictureBoxes()
|
|||
var townAcre = (y - CurrentSaveInfo.TownYAcreStart) * (CurrentSaveInfo.XAcreCount - 2) + (x - 1);
|
||||
if (townAcre >= CurrentSaveInfo.TownAcreCount) continue;
|
||||
{
|
||||
var townAcreBitmap = GenerateAcreItemsBitmap(TownAcres[townAcreCount].AcreItems, townAcre);
|
||||
var townAcreBitmap = GenerateAcreItemsBitmap(TownAcres[townAcreCount]);
|
||||
if (townAcre >= CurrentSaveInfo.TownAcreCount) continue;
|
||||
_townAcreMap[townAcre] = new PictureBoxWithInterpolationMode
|
||||
{
|
||||
|
@ -2533,25 +2535,25 @@ private void SetupMapPictureBoxes()
|
|||
SaveFile.SaveDataStartOffset + CurrentSaveInfo.SaveOffsets.IslandAcreData + idx * 2,
|
||||
SaveFile.IsBigEndian);
|
||||
|
||||
var acreItems = new WorldItem[256];
|
||||
var acreItems = new Item[256];
|
||||
for (var i = 0; i < 256; i++)
|
||||
if (SaveFile.SaveGeneration == SaveGeneration.GCN)
|
||||
{
|
||||
acreItems[i] =
|
||||
new WorldItem(
|
||||
new Item(
|
||||
SaveFile.ReadUInt16(
|
||||
SaveFile.SaveDataStartOffset + CurrentSaveInfo.SaveOffsets.IslandWorldData +
|
||||
idx * 512 + i * 2, true), i);
|
||||
idx * 512 + i * 2, true));
|
||||
}
|
||||
else if ((idx > 4 && idx < 7) || (idx > 8 && idx < 11)) //Other acres are water acres
|
||||
{
|
||||
var worldIdx = (y - 1) * 2 + ((x - 1) % 4);
|
||||
acreItems[i] =
|
||||
new WorldItem(
|
||||
new Item(
|
||||
SaveFile.ReadUInt32(SaveFile.SaveDataStartOffset +
|
||||
CurrentSaveInfo.SaveOffsets.IslandWorldData +
|
||||
worldIdx * 1024 +
|
||||
i * 4), i);
|
||||
i * 4));
|
||||
}
|
||||
|
||||
IslandAcres[idx] = new WorldAcre(acreId, idx, acreItems);
|
||||
|
@ -2572,13 +2574,12 @@ private void SetupMapPictureBoxes()
|
|||
SaveFile.SaveType == SaveType.AnimalForestEPlus)
|
||||
{
|
||||
_islandAcreMap[idx].Image =
|
||||
GenerateAcreItemsBitmap(_selectedIsland.Items[idx], idx, true);
|
||||
GenerateAcreItemsBitmap(_selectedIsland.Acres[idx], true);
|
||||
_islandAcreMap[idx].BackgroundImage = GetAcreImage(_acres[0x3C + idx].BaseAcreId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_islandAcreMap[idx].Image = GenerateAcreItemsBitmap(IslandAcres[idx].AcreItems,
|
||||
IslandAcres[idx].Index, true);
|
||||
_islandAcreMap[idx].Image = GenerateAcreItemsBitmap(IslandAcres[idx], true);
|
||||
_islandAcreMap[idx].BackgroundImage = GetAcreImage(acreId);
|
||||
}
|
||||
|
||||
|
@ -2792,7 +2793,7 @@ private void GeneratePastVillagersPanel()
|
|||
|
||||
#endregion
|
||||
|
||||
private Bitmap GenerateAcreItemsBitmap(WorldItem[] items, int acre, bool islandAcre = false,
|
||||
private Bitmap GenerateAcreItemsBitmap(WorldAcre acre, bool islandAcre = false,
|
||||
int hoveredAcre = -1, int xLoc = -1, int yLoc = -1)
|
||||
{
|
||||
var itemSize = _townMapCellSize;
|
||||
|
@ -2802,14 +2803,16 @@ private Bitmap GenerateAcreItemsBitmap(WorldItem[] items, int acre, bool islandA
|
|||
var bitmapBuffer = new byte[4 * (acreSize * acreSize)];
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
var item = items[i];
|
||||
var item = acre.Items[i];
|
||||
var xLocation = i % 16;
|
||||
var yLocation = i / 16;
|
||||
if (item.Type == ItemType.Empty) continue;
|
||||
var itemColor = ItemData.GetItemColor(item.Type);
|
||||
// Draw Item Box
|
||||
for (var x = 0; x < itemSize * itemSize; x++)
|
||||
Buffer.BlockCopy(BitConverter.GetBytes(itemColor), 0, bitmapBuffer,
|
||||
((item.Location.Y * itemSize + x / itemSize) * acreSize * 4) +
|
||||
((item.Location.X * itemSize + x % itemSize) * 4), 4);
|
||||
((yLocation * itemSize + x / itemSize) * acreSize * 4) +
|
||||
((xLocation * itemSize + x % itemSize) * 4), 4);
|
||||
}
|
||||
|
||||
// Draw Border
|
||||
|
@ -2826,10 +2829,10 @@ private Bitmap GenerateAcreItemsBitmap(WorldItem[] items, int acre, bool islandA
|
|||
Marshal.Copy(bitmapBuffer, 0, bitmapData.Scan0, bitmapBuffer.Length);
|
||||
acreBitmap.UnlockBits(bitmapData);
|
||||
// Draw Buried X
|
||||
ImageGeneration.DrawBuriedIcons(acreBitmap, items, _townMapCellSize);
|
||||
ImageGeneration.DrawBuriedIcons(acreBitmap, acre, _townMapCellSize);
|
||||
|
||||
// Draw Current Cell Glow
|
||||
if (hoveredAcre == acre && hoveredAcre > -1 && xLoc > -1 && yLoc > -1)
|
||||
if (hoveredAcre == acre.Index && hoveredAcre > -1 && xLoc > -1 && yLoc > -1)
|
||||
{
|
||||
ImageGeneration.OverlayItemBoxGlow(acreBitmap, itemSize, xLoc, yLoc);
|
||||
}
|
||||
|
@ -2839,9 +2842,9 @@ private Bitmap GenerateAcreItemsBitmap(WorldItem[] items, int acre, bool islandA
|
|||
{
|
||||
return islandAcre
|
||||
? ((SaveFile.SaveGeneration == SaveGeneration.N3DS)
|
||||
? ImageGeneration.DrawBuildings(acreBitmap, _islandBuildings, acre - 5, _townMapCellSize)
|
||||
? ImageGeneration.DrawBuildings(acreBitmap, _islandBuildings, acre.Index - 5, _townMapCellSize)
|
||||
: acreBitmap)
|
||||
: ImageGeneration.DrawBuildings(acreBitmap, _buildings, acre, _townMapCellSize);
|
||||
: ImageGeneration.DrawBuildings(acreBitmap, _buildings, acre.Index, _townMapCellSize);
|
||||
}
|
||||
|
||||
return acreBitmap;
|
||||
|
@ -3047,7 +3050,7 @@ private void AcreClick(object sender, MouseEventArgs e, bool island = false)
|
|||
if (island)
|
||||
{
|
||||
IslandAcres[acreIndex] = new WorldAcre((ushort)(_selectedAcreId + _acreHeightModifier), acreIndex,
|
||||
IslandAcres[acreIndex].AcreItems);
|
||||
IslandAcres[acreIndex].Items);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3086,14 +3089,14 @@ private void AcreClick(object sender, MouseEventArgs e, bool island = false)
|
|||
{
|
||||
var currentTownAcre = TownAcres[townAcre];
|
||||
TownAcres[townAcre] = new WorldAcre((ushort)(_selectedAcreId + _acreHeightModifier),
|
||||
townAcre, currentTownAcre.AcreItems);
|
||||
townAcre, currentTownAcre.Items);
|
||||
if (loadDefaultItems)
|
||||
{
|
||||
TownAcres[townAcre].LoadDefaultItems(SaveFile);
|
||||
_acres[acreIndex].AcreItems = TownAcres[townAcre].AcreItems;
|
||||
_acres[acreIndex].Items = TownAcres[townAcre].Items;
|
||||
}
|
||||
_townAcreMap[townAcre].BackgroundImage = acreBox.BackgroundImage;
|
||||
RefreshPictureBoxImage(_townAcreMap[townAcre], GenerateAcreItemsBitmap(currentTownAcre.AcreItems, acreIndex));
|
||||
RefreshPictureBoxImage(_townAcreMap[townAcre], GenerateAcreItemsBitmap(currentTownAcre));
|
||||
}
|
||||
|
||||
if (_grassMap != null && _grassMap.Length == _townAcreMap.Length)
|
||||
|
@ -3119,7 +3122,7 @@ private void AcreClick(object sender, MouseEventArgs e, bool island = false)
|
|||
}
|
||||
|
||||
RefreshPictureBoxImage(_islandAcreMap[acreIndex],
|
||||
GenerateAcreItemsBitmap(IslandAcres[acreIndex].AcreItems, acreIndex));
|
||||
GenerateAcreItemsBitmap(IslandAcres[acreIndex]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3710,7 +3713,7 @@ private void BuildingListIndexChanged(object sender, EventArgs e)
|
|||
: editedBuilding.Id != 0xFC;
|
||||
|
||||
_townAcreMap[editedBuilding.AcreIndex].Image =
|
||||
GenerateAcreItemsBitmap(TownAcres[editedBuilding.AcreIndex].AcreItems, editedBuilding.AcreIndex);
|
||||
GenerateAcreItemsBitmap(TownAcres[editedBuilding.AcreIndex]);
|
||||
}
|
||||
|
||||
//TODO: Update textboxes on change with mouse
|
||||
|
@ -3736,9 +3739,9 @@ private void BuildingPositionChanged(object sender, bool isY = false)
|
|||
editedBuilding.YPos = (byte)(newPosition % 16);
|
||||
}
|
||||
editedBuilding.AcreIndex = (byte)((editedBuilding.AcreY - 1) * 5 + (editedBuilding.AcreX - 1));
|
||||
_townAcreMap[oldAcre].Image = GenerateAcreItemsBitmap(TownAcres[oldAcre].AcreItems, oldAcre);
|
||||
_townAcreMap[oldAcre].Image = GenerateAcreItemsBitmap(TownAcres[oldAcre]);
|
||||
if (oldAcre != newAcre)
|
||||
_townAcreMap[newAcre].Image = GenerateAcreItemsBitmap(TownAcres[newAcre].AcreItems, newAcre);
|
||||
_townAcreMap[newAcre].Image = GenerateAcreItemsBitmap(TownAcres[newAcre]);
|
||||
}
|
||||
else //Return text to original position
|
||||
{
|
||||
|
@ -3840,7 +3843,7 @@ private void TownEnter(object sender)
|
|||
_lastTownIndex = -1;
|
||||
}
|
||||
|
||||
private void HandleTownClick(object sender, WorldItem item, int acre, int index, MouseEventArgs e, bool island = false)
|
||||
private void HandleTownClick(object sender, Item item, WorldAcre acre, int index, MouseEventArgs e, bool island = false)
|
||||
{
|
||||
if (!(sender is PictureBoxWithInterpolationMode box)) return;
|
||||
Building b;
|
||||
|
@ -3854,7 +3857,7 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
{
|
||||
b = island ? _islandBuildings[_selectedBuilding] : _buildings[_selectedBuilding];
|
||||
int oldAcre = b.AcreIndex;
|
||||
var adjustedAcre = island ? acre - 5 : acre;
|
||||
var adjustedAcre = island ? acre.Index - 5 : acre.Index;
|
||||
if (CheckBuildingIsHere(adjustedAcre, index % 16, index / 16, island) != null)
|
||||
return; //Don't place buildings on top of each other
|
||||
b.AcreIndex = (byte)adjustedAcre;
|
||||
|
@ -3873,34 +3876,25 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
//These two items has "actor" items at their location
|
||||
if (b.Name != "Sign" && b.Name != "Bus Stop")
|
||||
{
|
||||
if (island)
|
||||
{
|
||||
IslandAcres[acre].AcreItems[index] = new WorldItem(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
TownAcres[acre].AcreItems[index] =
|
||||
new WorldItem(index); //Clear any item at the new building position
|
||||
}
|
||||
acre.Items[index] = new Item();
|
||||
}
|
||||
else
|
||||
{
|
||||
TownAcres[acre].AcreItems[index] =
|
||||
new WorldItem(b.Name == "Sign" ? (ushort) 0xD000 : (ushort) 0x7003, index);
|
||||
acre.Items[index] = new Item(b.Name == "Sign" ? (ushort) 0xD000 : (ushort) 0x7003);
|
||||
}
|
||||
|
||||
if ((!island && oldAcre != acre) || (island && oldAcre != adjustedAcre))
|
||||
if ((!island && oldAcre != acre.Index) || (island && oldAcre != adjustedAcre))
|
||||
{
|
||||
var oldImage = island ? _islandAcreMap[oldAcre + 5].Image : _townAcreMap[oldAcre].Image;
|
||||
if (island)
|
||||
{
|
||||
_islandAcreMap[oldAcre + 5].Image =
|
||||
GenerateAcreItemsBitmap(IslandAcres[oldAcre + 5].AcreItems, oldAcre + 5, true);
|
||||
GenerateAcreItemsBitmap(IslandAcres[oldAcre + 5], true);
|
||||
_islandAcreMap[oldAcre + 5].Refresh();
|
||||
}
|
||||
else
|
||||
{
|
||||
_townAcreMap[oldAcre].Image = GenerateAcreItemsBitmap(TownAcres[oldAcre].AcreItems, oldAcre);
|
||||
_townAcreMap[oldAcre].Image = GenerateAcreItemsBitmap(TownAcres[oldAcre]);
|
||||
_townAcreMap[oldAcre].Refresh();
|
||||
}
|
||||
oldImage?.Dispose();
|
||||
|
@ -3921,8 +3915,8 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
|
||||
if (itemFlag1.Enabled)
|
||||
{
|
||||
var newItem = new WorldItem(_currentItem.ItemId, index);
|
||||
byte.TryParse(itemFlag1.Text, NumberStyles.AllowHexSpecifier, null, out newItem.Flag1);
|
||||
var newItem = new Item(_currentItem.ItemId);
|
||||
/*byte.TryParse(itemFlag1.Text, NumberStyles.AllowHexSpecifier, null, out newItem.Flag1);
|
||||
byte.TryParse(itemFlag2.Text, NumberStyles.AllowHexSpecifier, null, out newItem.Flag2);
|
||||
switch (newItem.Flag1)
|
||||
{
|
||||
|
@ -3934,23 +3928,12 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
newItem.Watered = false;
|
||||
newItem.Buried = true;
|
||||
break;
|
||||
}
|
||||
if (island)
|
||||
IslandAcres[acre].AcreItems[index] = newItem;
|
||||
else
|
||||
TownAcres[acre].AcreItems[index] = newItem;
|
||||
}*/
|
||||
acre.Items[index] = newItem;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (island)
|
||||
{
|
||||
if (_selectedIsland == null)
|
||||
IslandAcres[acre].AcreItems[index] = new WorldItem(_currentItem.ItemId, index);
|
||||
else
|
||||
_selectedIsland.Items[acre][index] = new WorldItem(_currentItem.ItemId, index);
|
||||
}
|
||||
else
|
||||
TownAcres[acre].AcreItems[index] = new WorldItem(_currentItem.ItemId, index);
|
||||
acre.Items[index] = new Item(_currentItem.ItemId);
|
||||
|
||||
Villager villager;
|
||||
switch (SaveFile.SaveGeneration)
|
||||
|
@ -3980,66 +3963,39 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
{
|
||||
switch (SaveFile.SaveGeneration)
|
||||
{
|
||||
case SaveGeneration.N3DS when island:
|
||||
if (IslandAcres[acre].AcreItems[index].ItemId != 0x7FFE)
|
||||
{
|
||||
IslandAcres[acre].AcreItems[index].Flag1 = 0x80;
|
||||
IslandAcres[acre].AcreItems[index].Buried = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case SaveGeneration.N3DS:
|
||||
if (TownAcres[acre].AcreItems[index].ItemId != 0x7FFE)
|
||||
if (acre.Items[index].ItemId != 0x7FFE)
|
||||
{
|
||||
TownAcres[acre].AcreItems[index].Flag1 = 0x80;
|
||||
TownAcres[acre].AcreItems[index].Buried = true;
|
||||
acre.Items[index].Flag1 = 0x80;
|
||||
//TownAcres[acre].Items[index].Buried = true;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
if (island)
|
||||
if (island && _selectedIsland != null)
|
||||
{
|
||||
if (_selectedIsland != null)
|
||||
{
|
||||
// TODO: Island buried items
|
||||
}
|
||||
else
|
||||
{
|
||||
IslandAcres[acre].AcreItems[index].Buried = IslandAcres[acre].SetItemBuried(
|
||||
IslandAcres[acre].AcreItems[index], true,
|
||||
SaveFile.SaveGeneration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TownAcres[acre].AcreItems[index].Buried = TownAcres[acre].SetItemBuried(
|
||||
TownAcres[acre].AcreItems[index], true,
|
||||
SaveFile.SaveGeneration);
|
||||
//TownAcres[acre].Items[index].Buried =
|
||||
acre.SetItemBuried(acre.Items[index], true, SaveFile.SaveGeneration);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var img = box.Image;
|
||||
WorldItem[] items;
|
||||
if (island)
|
||||
{
|
||||
items = _selectedIsland == null ? IslandAcres[acre].AcreItems : _selectedIsland.Items[acre];
|
||||
}
|
||||
else
|
||||
{
|
||||
items = TownAcres[acre].AcreItems;
|
||||
}
|
||||
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(items, acre, island));
|
||||
var img = box.Image;
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(acre, island));
|
||||
box.Refresh();
|
||||
img?.Dispose();
|
||||
TownMove(sender, e, island, true); // Force ToolTip update
|
||||
break;
|
||||
}
|
||||
case MouseButtons.Right:
|
||||
b = CheckBuildingIsHere(acre, index % 16, index / 16, island);
|
||||
b = CheckBuildingIsHere(acre.Index, index % 16, index / 16, island);
|
||||
if (b != null)
|
||||
{
|
||||
if (_selectedBuilding == -1)
|
||||
|
@ -4062,7 +4018,7 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
selectedItem.SelectedValue = oldSelectedItemId;
|
||||
else
|
||||
{
|
||||
buriedCheckbox.Checked = item.Buried || item.Flag1 == 0x80;
|
||||
buriedCheckbox.Checked = acre.IsItemBuried(item) || item.Flag1 == 0x80;
|
||||
if (itemFlag1.Enabled)
|
||||
{
|
||||
itemFlag1.Text = item.Flag1.ToString("X2");
|
||||
|
@ -4078,18 +4034,9 @@ private void HandleTownClick(object sender, WorldItem item, int acre, int index,
|
|||
case MouseButtons.Middle:
|
||||
{
|
||||
box.Capture = false;
|
||||
WorldItem[] items;
|
||||
if (island)
|
||||
{
|
||||
items = _selectedIsland == null ? IslandAcres[acre].AcreItems : _selectedIsland.Items[acre];
|
||||
}
|
||||
else
|
||||
{
|
||||
items = TownAcres[acre].AcreItems;
|
||||
}
|
||||
Utility.FloodFillWorldItemArray(ref items, 16, index, items[index], new WorldItem(_currentItem.ItemId, byte.Parse(itemFlag1.Text),
|
||||
byte.Parse(itemFlag2.Text), items[index].Index));
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(items, acre, island));
|
||||
Utility.FloodFillItemArray(ref acre.Items, 16, index, acre.Items[index],
|
||||
new Item(_currentItem.ItemId, byte.Parse(itemFlag1.Text), byte.Parse(itemFlag2.Text)));
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(acre, island));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4116,12 +4063,12 @@ private void TownMove(object sender, MouseEventArgs e, bool island = false, bool
|
|||
townInfoLabel.Text = $"X: {x} | Y: {y} | Index: {index}";
|
||||
townInfoLabel.Refresh();
|
||||
|
||||
WorldItem item;
|
||||
WorldItem[] items;
|
||||
Item item;
|
||||
WorldAcre wAcre;
|
||||
if (island)
|
||||
{
|
||||
items = _selectedIsland == null ? IslandAcres[acre].AcreItems : _selectedIsland.Items[acre];
|
||||
item = _selectedIsland == null ? IslandAcres[acre].AcreItems[index] : _selectedIsland.Items[acre][index];
|
||||
wAcre = _selectedIsland == null ? IslandAcres[acre] : _selectedIsland.Acres[acre];
|
||||
item = _selectedIsland == null ? IslandAcres[acre].Items[index] : _selectedIsland.Acres[acre].Items[index];
|
||||
|
||||
// TODO: This doesn't handle the ocean acres to the left & right.
|
||||
if (SaveFile.SaveGeneration == SaveGeneration.N3DS && _lastTownAcre < 5 || _lastTownAcre > 10)
|
||||
|
@ -4131,13 +4078,13 @@ private void TownMove(object sender, MouseEventArgs e, bool island = false, bool
|
|||
}
|
||||
else
|
||||
{
|
||||
items = TownAcres[acre].AcreItems;
|
||||
item = TownAcres[acre].AcreItems[index];
|
||||
wAcre = TownAcres[acre];
|
||||
item = TownAcres[acre].Items[index];
|
||||
}
|
||||
|
||||
if (_clicking && !forceOverride)
|
||||
{
|
||||
HandleTownClick(sender, item, acre, index, e, island);
|
||||
HandleTownClick(sender, item, wAcre, index, e, island);
|
||||
}
|
||||
|
||||
//Console.WriteLine($"Index: {index} | ItemId: {item.ItemId:X4} | Name: {item.Name}");
|
||||
|
@ -4149,17 +4096,17 @@ private void TownMove(object sender, MouseEventArgs e, bool island = false, bool
|
|||
townToolTip.Show(
|
||||
b != null
|
||||
? $"{b.Name} - [0x{b.Id:X2} - Building]"
|
||||
: $"{item.Name}{(item.Buried ? " (Buried)" : (item.Watered ? " (Watered)" : (item.Flag1 == 1 ? " (Perfect Fruit)" : "")))} - [0x{item.ItemId:X4}]",
|
||||
: $"{item.Name}{(wAcre.IsItemBuried(item) ? " (Buried)" : ((item.Flag1 & 0x40) != 0 ? " (Watered)" : (item.Flag1 == 1 ? " (Perfect Fruit)" : "")))} - [0x{item.ItemId:X4}]",
|
||||
box, e.X + 15, e.Y + 10, 100000);
|
||||
}
|
||||
else
|
||||
{
|
||||
townToolTip.Show($"{item.Name}{(item.Buried ? " (Buried)" : "")} - [0x{item.ItemId:X4}]", box, e.X + 15,
|
||||
townToolTip.Show($"{item.Name}{(wAcre.IsItemBuried(item) ? " (Buried)" : "")} - [0x{item.ItemId:X4}]", box, e.X + 15,
|
||||
e.Y + 10, 100000);
|
||||
}
|
||||
|
||||
// Draw Cell Highlight
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(items, acre, island, acre, x, y));
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(wAcre, island, acre, x, y));
|
||||
box.Refresh();
|
||||
|
||||
if (acre == _lastTownAcre) return;
|
||||
|
@ -4174,18 +4121,18 @@ private void TownMove(object sender, MouseEventArgs e, bool island = false, bool
|
|||
_lastTownAcre = 0;
|
||||
}
|
||||
|
||||
WorldItem[] lastAcreItems;
|
||||
WorldAcre lastWorldAcre;
|
||||
if (island)
|
||||
{
|
||||
lastAcreItems = _selectedIsland == null ? IslandAcres[_lastTownAcre].AcreItems : _selectedIsland.Items[_lastTownAcre];
|
||||
lastWorldAcre = _selectedIsland == null ? IslandAcres[_lastTownAcre] : _selectedIsland.Acres[_lastTownAcre];
|
||||
}
|
||||
else
|
||||
{
|
||||
lastAcreItems = TownAcres[_lastTownAcre].AcreItems;
|
||||
lastWorldAcre = TownAcres[_lastTownAcre];
|
||||
}
|
||||
|
||||
RefreshPictureBoxImage(island ? _islandAcreMap[_lastTownAcre] : _townAcreMap[_lastTownAcre],
|
||||
GenerateAcreItemsBitmap(lastAcreItems, _lastTownAcre, island));
|
||||
GenerateAcreItemsBitmap(lastWorldAcre, island));
|
||||
if (island)
|
||||
{
|
||||
_islandAcreMap[_lastTownAcre].Refresh();
|
||||
|
@ -4209,18 +4156,19 @@ private void TownMouseDown(object sender, MouseEventArgs e, bool island = false)
|
|||
var x = e.X / _townMapCellSize;
|
||||
var y = e.Y / _townMapCellSize;
|
||||
var index = x + y * 16;
|
||||
if (index > 255)
|
||||
return;
|
||||
WorldItem item;
|
||||
if (index > 255) return;
|
||||
|
||||
WorldAcre wAcre;
|
||||
if (island)
|
||||
{
|
||||
item = _selectedIsland == null ? IslandAcres[acre].AcreItems[index] : _selectedIsland.Items[acre][index];
|
||||
wAcre = _selectedIsland == null ? IslandAcres[acre] : _selectedIsland.Acres[acre];
|
||||
}
|
||||
else
|
||||
{
|
||||
item = TownAcres[acre].AcreItems[index];
|
||||
wAcre = TownAcres[acre];
|
||||
}
|
||||
HandleTownClick(sender, item, acre, index, e, island);
|
||||
|
||||
HandleTownClick(sender, wAcre.Items[index], wAcre, index, e, island);
|
||||
_clicking = true;
|
||||
}
|
||||
|
||||
|
@ -4323,13 +4271,13 @@ private void SaveToolStripMenuItemClick(object sender, EventArgs e)
|
|||
if (SaveFile.SaveGeneration == SaveGeneration.N3DS)
|
||||
{
|
||||
SaveFile.Write(SaveFile.SaveDataStartOffset + CurrentSaveInfo.SaveOffsets.TownData + i * 1024 + x * 4,
|
||||
ItemData.EncodeItem(TownAcres[i].AcreItems[x]));
|
||||
ItemData.EncodeItem(TownAcres[i].Items[x]));
|
||||
}
|
||||
else
|
||||
{
|
||||
SaveFile.Write(
|
||||
SaveFile.SaveDataStartOffset + CurrentSaveInfo.SaveOffsets.TownData + i * 512 + x * 2,
|
||||
TownAcres[i].AcreItems[x].ItemId,
|
||||
TownAcres[i].Items[x].ItemId,
|
||||
SaveFile.IsBigEndian);
|
||||
}
|
||||
}
|
||||
|
@ -4491,26 +4439,26 @@ private void ClearWeedsButtonClick()
|
|||
var idx = Array.IndexOf(_townAcreMap, box);
|
||||
var acreIdx = idx;
|
||||
var acre = TownAcres[acreIdx];
|
||||
if (acre.AcreItems == null) continue;
|
||||
if (acre.Items == null) continue;
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
if (ItemData.GetItemType(acre.AcreItems[i].ItemId, SaveFile.SaveType) != ItemType.Weed) continue; // Weed
|
||||
if (ItemData.GetItemType(acre.Items[i].ItemId, SaveFile.SaveType) != ItemType.Weed) continue; // Weed
|
||||
switch (SaveFile.SaveGeneration)
|
||||
{
|
||||
case SaveGeneration.NDS:
|
||||
case SaveGeneration.Wii:
|
||||
acre.AcreItems[i] = new WorldItem(0xFFF1, acre.AcreItems[i].Index);
|
||||
acre.Items[i] = new Item(0xFFF1);
|
||||
break;
|
||||
case SaveGeneration.N3DS:
|
||||
acre.AcreItems[i] = new WorldItem(0x7FFE, acre.AcreItems[i].Index);
|
||||
acre.Items[i] = new Item(0x7FFE);
|
||||
break;
|
||||
default:
|
||||
acre.AcreItems[i] = new WorldItem(0, acre.AcreItems[i].Index);
|
||||
acre.Items[i] = new Item(0);
|
||||
break;
|
||||
}
|
||||
weedsCleared++;
|
||||
}
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(acre.AcreItems, acreIdx));
|
||||
RefreshPictureBoxImage(box, GenerateAcreItemsBitmap(acre));
|
||||
}
|
||||
MessageBox.Show($"{weedsCleared} weeds {(weedsCleared == 1 ? "was" : "were")} removed!",
|
||||
"Weeds Cleared", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
||||
|
@ -4648,8 +4596,8 @@ private void PerfectFruitsButtonClick()
|
|||
foreach (var box in _townAcreMap)
|
||||
{
|
||||
var acre = TownAcres[Array.IndexOf(_townAcreMap, box)];
|
||||
if (acre.AcreItems == null) continue;
|
||||
foreach (var fruitTree in acre.AcreItems.Where(i =>
|
||||
if (acre.Items == null) continue;
|
||||
foreach (var fruitTree in acre.Items.Where(i =>
|
||||
i.ItemId >= 0x3A && i.ItemId <= 0x52 && i.Flag1 == 0 && i.Flag2 == 0))
|
||||
{
|
||||
fruitTree.Flag1 = 1;
|
||||
|
@ -4935,11 +4883,11 @@ private void RemoveAllItemsToolStripMenuItemClick(object sender, EventArgs e)
|
|||
{
|
||||
for (var i = 0; i < TownAcres.Length; i++)
|
||||
{
|
||||
for (var x = 0; x < TownAcres[i].AcreItems.Length; x++)
|
||||
for (var x = 0; x < TownAcres[i].Items.Length; x++)
|
||||
{
|
||||
TownAcres[i].AcreItems[x] = new WorldItem(TownAcres[i].AcreItems[x].Index);
|
||||
TownAcres[i].Items[x] = new Item(TownAcres[i].Items[x]);
|
||||
}
|
||||
_townAcreMap[i].Image = GenerateAcreItemsBitmap(TownAcres[i].AcreItems, i);
|
||||
_townAcreMap[i].Image = GenerateAcreItemsBitmap(TownAcres[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5161,29 +5109,29 @@ private void ReplaceToolStripMenuItemClick(object sender, EventArgs e)
|
|||
!ushort.TryParse(_replaceItemBox.Text, NumberStyles.HexNumber, null, out var replaceId) ||
|
||||
!ushort.TryParse(_replacingItemBox.Text, NumberStyles.HexNumber, null, out var replacingId)) return;
|
||||
var replacedItems = 0;
|
||||
var replacingItem = new WorldItem(replacingId, 0, 0, 0);
|
||||
var replacingItem = new Item(replacingId, 0, 0);
|
||||
|
||||
for (var i = 0; i < TownAcres.Length; i++)
|
||||
{
|
||||
var changed = false;
|
||||
var acre = TownAcres[i];
|
||||
if (acre.AcreItems == null) continue;
|
||||
if (acre.Items == null) continue;
|
||||
|
||||
for (var index = 0; index < acre.AcreItems.Length; index++)
|
||||
for (var index = 0; index < acre.Items.Length; index++)
|
||||
{
|
||||
if (acre.AcreItems[index].ItemId != replaceId) continue;
|
||||
if (acre.Items[index].ItemId != replaceId) continue;
|
||||
|
||||
changed = true;
|
||||
replacedItems++;
|
||||
SaveFile.ChangesMade = true;
|
||||
acre.AcreItems[index] = new WorldItem(replacingItem, index);
|
||||
acre.Items[index] = new Item(replacingItem);
|
||||
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
RefreshPictureBoxImage(_townAcreMap[i],
|
||||
GenerateAcreItemsBitmap(acre.AcreItems, i)); // TODO: Make this work on island acres somehow.
|
||||
GenerateAcreItemsBitmap(acre)); // TODO: Make this work on island acres somehow.
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5230,9 +5178,9 @@ private void GenerateRandomTownToolStripMenuItemClick(object sender, EventArgs e
|
|||
var townAcre = (y - CurrentSaveInfo.TownYAcreStart) * (CurrentSaveInfo.XAcreCount - 2) + (x - 1);
|
||||
if (townAcre >= CurrentSaveInfo.TownAcreCount) continue;
|
||||
|
||||
TownAcres[townAcre] = new WorldAcre(_acres[i].AcreId, townAcre, _acres[i].AcreItems);
|
||||
TownAcres[townAcre] = new WorldAcre(_acres[i].AcreId, townAcre, _acres[i].Items);
|
||||
RefreshPictureBoxImage(_townAcreMap[townAcre],
|
||||
GenerateAcreItemsBitmap(TownAcres[townAcre].AcreItems, townAcre));
|
||||
GenerateAcreItemsBitmap(TownAcres[townAcre]));
|
||||
_townAcreMap[townAcre].BackgroundImage = _acreMap[i].BackgroundImage;
|
||||
_townAcreMap[townAcre].Refresh();
|
||||
|
||||
|
@ -5254,23 +5202,21 @@ private void WaterFlowersButtonClick()
|
|||
{
|
||||
var acreIdx = Array.IndexOf(_townAcreMap, box);
|
||||
var acre = TownAcres[acreIdx];
|
||||
if (acre.AcreItems == null) continue;
|
||||
if (acre.Items == null) continue;
|
||||
switch (SaveFile.SaveGeneration)
|
||||
{
|
||||
case SaveGeneration.NDS:
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
var itemType = ItemData.GetItemType(acre.AcreItems[i].ItemId, SaveFile.SaveType);
|
||||
var itemType = ItemData.GetItemType(acre.Items[i].ItemId, SaveFile.SaveType);
|
||||
switch (itemType)
|
||||
{
|
||||
case ItemType.ParchedFlower:
|
||||
acre.AcreItems[i] = new WorldItem((ushort) (acre.AcreItems[i].ItemId + 0x1C),
|
||||
acre.AcreItems[i].Index);
|
||||
acre.Items[i] = new Item((ushort) (acre.Items[i].ItemId + 0x1C));
|
||||
flowersWatered++;
|
||||
break;
|
||||
case ItemType.Flower:
|
||||
acre.AcreItems[i] = new WorldItem((ushort) (acre.AcreItems[i].ItemId + 0x8A),
|
||||
acre.AcreItems[i].Index);
|
||||
acre.Items[i] = new Item((ushort) (acre.Items[i].ItemId + 0x8A));
|
||||
flowersWatered++;
|
||||
break;
|
||||
}
|
||||
|
@ -5280,10 +5226,9 @@ private void WaterFlowersButtonClick()
|
|||
case SaveGeneration.Wii:
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
if (ItemData.GetItemType(acre.AcreItems[i].ItemId, SaveFile.SaveType) != ItemType.ParchedFlower)
|
||||
if (ItemData.GetItemType(acre.Items[i].ItemId, SaveFile.SaveType) != ItemType.ParchedFlower)
|
||||
continue;
|
||||
acre.AcreItems[i] = new WorldItem((ushort) (acre.AcreItems[i].ItemId - 0x20),
|
||||
acre.AcreItems[i].Index);
|
||||
acre.Items[i] = new Item((ushort) (acre.Items[i].ItemId - 0x20));
|
||||
flowersWatered++;
|
||||
}
|
||||
|
||||
|
@ -5291,17 +5236,17 @@ private void WaterFlowersButtonClick()
|
|||
case SaveGeneration.N3DS:
|
||||
for (var i = 0; i < 256; i++)
|
||||
{
|
||||
if (ItemData.GetItemType(acre.AcreItems[i].ItemId, SaveFile.SaveType) != ItemType.Flower)
|
||||
if (ItemData.GetItemType(acre.Items[i].ItemId, SaveFile.SaveType) != ItemType.Flower)
|
||||
continue;
|
||||
acre.AcreItems[i].Flag1 = 0x40;
|
||||
acre.AcreItems[i].Watered = true;
|
||||
acre.Items[i].Flag1 = 0x40;
|
||||
//acre.Items[i].Watered = true;
|
||||
flowersWatered++;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
var oldImage = box.Image;
|
||||
box.Image = GenerateAcreItemsBitmap(acre.AcreItems, acreIdx);
|
||||
box.Image = GenerateAcreItemsBitmap(acre);
|
||||
oldImage?.Dispose();
|
||||
}
|
||||
|
||||
|
@ -5452,10 +5397,10 @@ private void IslandTabIndexChanged(object sender, TabControlEventArgs e)
|
|||
|
||||
private void ReloadIslandItemPicture()
|
||||
{
|
||||
if (_selectedIsland?.Items == null) return;
|
||||
if (_selectedIsland?.Acres == null) return;
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
RefreshPictureBoxImage(_islandAcreMap[i], GenerateAcreItemsBitmap(_selectedIsland.Items[i], i, true));
|
||||
RefreshPictureBoxImage(_islandAcreMap[i], GenerateAcreItemsBitmap(_selectedIsland.Acres[i], true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public static void ExportTown(WorldAcre[] acres, SaveGeneration saveGeneration,
|
|||
{
|
||||
foreach (var acre in acres)
|
||||
{
|
||||
foreach (var item in acre.AcreItems)
|
||||
foreach (var item in acre.Items)
|
||||
{
|
||||
writer.Write(BitConverter.GetBytes(item.ToUInt32()));
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ public static void ExportTown(WorldAcre[] acres, SaveGeneration saveGeneration,
|
|||
{
|
||||
foreach (var acre in acres)
|
||||
{
|
||||
foreach (var item in acre.AcreItems)
|
||||
foreach (var item in acre.Items)
|
||||
{
|
||||
writer.Write(BitConverter.GetBytes(item.ItemId));
|
||||
}
|
||||
|
@ -152,9 +152,9 @@ public static void ImportTown(ref WorldAcre[] acres, SaveGeneration saveGenerati
|
|||
{
|
||||
foreach (var acre in acres)
|
||||
{
|
||||
for (var x = 0; x < acre.AcreItems.Length; x++)
|
||||
for (var x = 0; x < acre.Items.Length; x++)
|
||||
{
|
||||
acre.AcreItems[x] = new WorldItem(reader.ReadUInt32(), acre.AcreItems[x].Index);
|
||||
acre.Items[x] = new Item(reader.ReadUInt32());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,9 +162,9 @@ public static void ImportTown(ref WorldAcre[] acres, SaveGeneration saveGenerati
|
|||
{
|
||||
foreach (var acre in acres)
|
||||
{
|
||||
for (var x = 0; x < acre.AcreItems.Length; x++)
|
||||
for (var x = 0; x < acre.Items.Length; x++)
|
||||
{
|
||||
acre.AcreItems[x] = new WorldItem(reader.ReadUInt16(), acre.AcreItems[x].Index);
|
||||
acre.Items[x] = new Item(reader.ReadUInt16());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue