Split ACSE into Core & WinForms projects

This will help code maintainability, and allow for cross platform support if another UI system is created.

Code refactoring will come at some point in the future.
This commit is contained in:
Cuyler36 2018-10-31 19:01:03 -04:00
parent d7a384cdcd
commit b8f8f866fd
1929 changed files with 7703 additions and 1503 deletions

View file

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Costura.Fody" Version="3.1.6" />
<PackageReference Include="Fody" Version="3.2.16">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="System.Drawing.Common" Version="4.5.1" />
</ItemGroup>
</Project>

View file

@ -1,7 +1,11 @@
using System;
using System.IO;
using ACSE.Core.Debug;
using ACSE.Core.Items;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Acres
{
public class Acre
{
@ -28,7 +32,9 @@ public class WorldAcre : Acre
{
public WorldItem[] AcreItems = new WorldItem[16 * 16];
public WorldAcre(ushort acreId, int position, ushort[] items = null, byte[] buriedItemData = null, SaveType saveType = SaveType.AnimalCrossing, uint[] nlItems = null, int townPosition = -1) : base(acreId, position)
public WorldAcre(ushort acreId, int position, ushort[] items = null, byte[] buriedItemData = null,
SaveType saveType = SaveType.AnimalCrossing, uint[] nlItems = null, int townPosition = -1) : base(acreId,
position)
{
if (items != null)
{
@ -36,7 +42,7 @@ public WorldAcre(ushort acreId, int position, ushort[] items = null, byte[] buri
{
AcreItems[i] = new WorldItem(items[i], i);
if (buriedItemData != null)
SetBuried(AcreItems[i], townPosition == -1 ? position : townPosition, buriedItemData, saveType); //Broken in original save editor lol.. needs a position - 1 to function properly
SetBuried(AcreItems[i], townPosition == -1 ? position : townPosition, buriedItemData, saveType);
}
}
else if (nlItems != null)
@ -54,13 +60,15 @@ public WorldAcre(ushort acreId, int position) : base(acreId, position) { }
public WorldAcre(ushort acreId, int position, uint[] items = null, byte[] buriedItemData = null, SaveType saveType = SaveType.AnimalCrossing)
: this(acreId, position, null, null, saveType, items) { }
public WorldAcre(ushort acreId, int position, WorldItem[] items, byte[] buriedItemData = null, SaveType saveType = SaveType.AnimalCrossing, int townPosition = -1) : base(acreId, position)
public WorldAcre(ushort acreId, int position, WorldItem[] items, byte[] buriedItemData = null,
SaveType saveType = SaveType.AnimalCrossing, int townPosition = -1) : base(acreId, position)
{
AcreItems = items;
if (buriedItemData == null || townPosition <= -1) return;
for (var i = 0; i < 256; i++)
SetBuried(AcreItems[i], townPosition, buriedItemData, saveType);
}
//TODO: Change BuriedData from byte[] to ushort[] and use updated code
private static int GetBuriedDataLocation(WorldItem item, int acre, SaveType saveType)
{
@ -68,11 +76,12 @@ private static int GetBuriedDataLocation(WorldItem item, int acre, SaveType save
var worldPosition = 0;
switch (saveType)
{
//15 - item.Location.X because it's stored as a ushort in memory w/ reversed endianess
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
worldPosition = (acre * 256) + (15 - item.Location.X) + item.Location.Y * 16;
break;
case SaveType.WildWorld:
worldPosition = (acre * 256) + item.Index;
@ -110,7 +119,7 @@ private static void SetBuried(WorldItem item, int acre, byte[] buriedItemData, S
/// <returns>bool ItemsWereLoaded</returns>
public bool LoadDefaultItems(Save saveFile)
{
var defaultAcreDataFolder = MainForm.AssemblyLocation + Path.DirectorySeparatorChar + "Resources" + Path.DirectorySeparatorChar + "Default Acre Items";
var defaultAcreDataFolder = Path.Combine(PathUtility.GetExeDirectory(), "Resources", "Default Acre Items");
switch (saveFile.SaveGeneration)
{
@ -140,7 +149,7 @@ public bool LoadDefaultItems(Save saveFile)
}
catch
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"Unable to open default acre data for Acre Id 0x{BaseAcreId:X4}", DebugLevel.Error);
}

View file

@ -1,6 +1,8 @@
using System.Collections.Generic;
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.BitFields.Catalog
{
public static class Catalog
{

View file

@ -1,6 +1,8 @@
using System.Collections.Generic;
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.BitFields.Encyclopedia
{
public static class Encyclopedia
{
@ -280,8 +282,6 @@ private static Dictionary<int, byte> GetBitMap(SaveType saveType)
case SaveType.WelcomeAmiibo:
return WelcomeAmiiboEncyclopediaBitMap;
default:
System.Windows.Forms.MessageBox.Show("Encylopedia data for this game has not been implemented yet!", "Unimplemented Notification",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
return null;
}
}

View file

@ -1,4 +1,7 @@
namespace ACSE
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE.Core.BitFields.Museum
{
public static class Museum
{

View file

@ -1,6 +1,8 @@
using System.Collections.Generic;
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.BitFields.SongLibrary
{
public static class SongLibrary
{
@ -110,8 +112,6 @@ private static Dictionary<int, byte> GetBitMap(SaveType saveType)
case SaveType.WelcomeAmiibo:
return WelcomeAmiiboSongLibraryBitMap;
default:
System.Windows.Forms.MessageBox.Show("Songs for this game have not been implemented yet!", "Unimplemented Notification",
System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
return null;
}
}

View file

@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.Buildings
{
/// <summary>
/// Building class for editing buildings in City Folk & New Leaf.
@ -496,7 +497,7 @@ public static Building[] GetBuildings(Save save, bool islandBuildings = false)
if (islandBuildings == false)
for (var i = 0; i < 58; i++)
{
var dataOffset = save.SaveDataStartOffset + MainForm.CurrentSaveInfo.SaveOffsets.Buildings +
var dataOffset = save.SaveDataStartOffset + Save.SaveInstance.SaveInfo.SaveOffsets.Buildings +
i * 4;
buildings.Add(new Building(save.ReadByte(dataOffset), save.ReadByte(dataOffset + 2),
save.ReadByte(dataOffset + 3), save.SaveType));
@ -506,7 +507,7 @@ public static Building[] GetBuildings(Save save, bool islandBuildings = false)
for (var i = 0; i < 2; i++)
{
var dataOffset = save.SaveDataStartOffset +
MainForm.CurrentSaveInfo.SaveOffsets.IslandBuildings + i * 4;
Save.SaveInstance.SaveInfo.SaveOffsets.IslandBuildings + i * 4;
buildings.Add(new Building(save.ReadByte(dataOffset), save.ReadByte(dataOffset + 2),
save.ReadByte(dataOffset + 3), save.SaveType));
}

View file

@ -1,7 +1,8 @@
using System;
using System.IO;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.Debug
{
public enum DebugLevel
{
@ -17,13 +18,18 @@ public class DebugManager
private FileStream _logFile;
private StreamWriter _logWriter;
private const int MaxLogSize = 5000000; // 5MB Max Size
public bool Enabled;
public Save SaveFile;
public DebugManager()
public bool Enabled;
public DebugLevel Level;
public DebugManager(Save saveFile, DebugLevel level = DebugLevel.Info)
{
SaveFile = saveFile;
Level = level;
CheckAndDeleteLogFile();
if (Properties.Settings.Default.DebugLevel > 0)
if (level > 0)
{
InitializeDebugLogWriter();
Enabled = true;
@ -86,7 +92,7 @@ public static string GetLogFilePath() =>
public void WriteLine(string contents, DebugLevel level = DebugLevel.Info)
{
if (_logWriter == null || level > Properties.Settings.Default.DebugLevel) return;
if (_logWriter == null || level > Level) return;
if (!CheckLogSizeOk())
{
CloseDebugLogWriter();
@ -95,7 +101,7 @@ public void WriteLine(string contents, DebugLevel level = DebugLevel.Info)
}
_logWriter.WriteLine(
$"[{level}] - ({(MainForm.SaveFile != null ? MainForm.SaveFile.SaveType.ToString().Replace("_", " ") : "No Save")}) - {DateTime.Now} => {contents}");
$"[{level}] - ({(SaveFile != null ? SaveFile.SaveType.ToString().Replace("_", " ") : "No Save")}) - {DateTime.Now} => {contents}");
_logWriter.Flush();
}
}

View file

@ -1,4 +1,7 @@
namespace ACSE
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE.Core.Emotions
{
public static class Emotion
{

View file

@ -1,9 +1,10 @@
using System;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Encryption
{
/*
* Animal Crossing: New Leaf (and Welcome Amiibo) Interger Encryption Documentation
* Animal Crossing: New Leaf (and Welcome Amiibo) Integer Encryption Documentation
*
* Animal Crossing: New Leaf uses a combination of methods to obfuscate their integer values in the save file.
* The encryption consists of two integer values. The first integer is the encrypted integer. The second integer contains the checksum of the encryption and
@ -52,7 +53,7 @@ public NewLeafInt32(uint intA, uint intB)
if (intChecksum != computedChecksum)
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"Encrypted Int had an invalid Checksum! Checksum: 0x{intChecksum:X2} | Calculated Checksum: 0x{computedChecksum:X2}");
Int1 = 0;
Int2 = 0;
@ -71,7 +72,7 @@ public NewLeafInt32(uint intA, uint intB)
}
else
{
MainForm.DebugManager.WriteLine("Invalid Shift Count was detected!", DebugLevel.Info);
DebugUtility.DebugManagerInstance.WriteLine("Invalid Shift Count was detected!");
Value = (intA << rightShiftCount) - (adjustValue + 0x8F187432);
Valid = true; // Is this right?
}

View file

@ -1,6 +1,6 @@
namespace ACSE
namespace ACSE.Core.Enums
{
// TODO: Move all enums to this file
// TODO: Split all enums into their own files.
public enum AnimalCrossingGrassType : byte
{
Triangle = 0,

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<Costura />
</Weavers>

View file

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
namespace ACSE.Generators
namespace ACSE.Core.Generators
{
public class GCNGenerator : IGenerator
public sealed class GCNGenerator : IGenerator
{
private int _randomSeed = Environment.TickCount;

View file

@ -1,4 +1,6 @@
namespace ACSE.Generators
using ACSE.Core.Saves;
namespace ACSE.Core.Generators
{
public static class Generator
{

View file

@ -1,4 +1,4 @@
namespace ACSE.Generators
namespace ACSE.Core.Generators
{
public interface IGenerator
{

View file

@ -1,7 +1,11 @@
using ACSE.Utilities;
using System.Reflection;
using System.Reflection;
using ACSE.Core.Encryption;
using ACSE.Core.Items;
using ACSE.Core.Players;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Housing
{
public class House
{
@ -17,20 +21,20 @@ public House(int index, int offset, int roomCount = -1, int roomStart = -1)
Index = index;
Offset = offset;
var houseSize = HouseInfo.GetHouseSize(offset, MainForm.SaveFile.SaveType);
var houseSize = HouseInfo.GetHouseSize(offset, Save.SaveInstance.SaveType);
var basement = false;
//Console.WriteLine("House Index: " + Index);
//Console.WriteLine("House Offset: 0x" + Offset.ToString("X"));
//Console.WriteLine("House Size: " + HouseSize.ToString());
if (MainForm.SaveFile.SaveGeneration == SaveGeneration.N64 || MainForm.SaveFile.SaveGeneration == SaveGeneration.GCN)
if (Save.SaveInstance.SaveGeneration == SaveGeneration.N64 || Save.SaveInstance.SaveGeneration == SaveGeneration.GCN)
{
basement = HouseInfo.HasBasement(offset, MainForm.SaveFile.SaveType);
basement = HouseInfo.HasBasement(offset, Save.SaveInstance.SaveType);
//Console.WriteLine("Basement: " + Basement.ToString());
}
// Load House Data
var offsets = HouseInfo.GetHouseOffsets(MainForm.SaveFile.SaveType);
var saveData = MainForm.SaveFile;
var offsets = HouseInfo.GetHouseOffsets(Save.SaveInstance.SaveType);
var saveData = Save.SaveInstance;
var playerDataType = typeof(HouseData);
var playerSaveInfoType = typeof(HouseOffsets);
object boxedData = new HouseData();
@ -156,7 +160,7 @@ public House(int index, int offset, int roomCount = -1, int roomStart = -1)
public virtual void Write()
{
var saveData = MainForm.SaveFile;
var saveData = Save.SaveInstance;
var offsets = HouseInfo.GetHouseOffsets(saveData.SaveType);
// Set House TownID & Name
@ -165,15 +169,15 @@ public virtual void Write()
if (offsets.OwningPlayerName != -1 && offsets.TownId != -1)
{
Data.TownId =
saveData.ReadUInt16(saveData.SaveDataStartOffset + MainForm.CurrentSaveInfo.SaveOffsets.TownId,
saveData.ReadUInt16(saveData.SaveDataStartOffset + Save.SaveInstance.SaveInfo.SaveOffsets.TownId,
saveData.IsBigEndian); // Might not be UInt16 in all games
}
if (offsets.OwningPlayerName != -1 && offsets.TownName != -1)
{
Data.TownName = saveData.ReadString(
saveData.SaveDataStartOffset + MainForm.CurrentSaveInfo.SaveOffsets.TownName,
MainForm.CurrentSaveInfo.SaveOffsets.TownNameSize);
saveData.SaveDataStartOffset + Save.SaveInstance.SaveInfo.SaveOffsets.TownName,
Save.SaveInstance.SaveInfo.SaveOffsets.TownNameSize);
}
if (offsets.OwningPlayerName != -1)

View file

@ -1,8 +1,10 @@
using System;
using System.Reflection;
using ACSE.Utilities;
using ACSE.Core.Items;
using ACSE.Core.Patterns;
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.Housing
{
public struct HouseOffsets
{
@ -69,7 +71,7 @@ public class Layer
public void Write()
{
if (Items == null || Index <= -1) return;
var saveFile = MainForm.SaveFile;
var saveFile = Save.SaveInstance;
if (saveFile.SaveGeneration == SaveGeneration.N3DS)
{
for (var i = 0; i < Items.Length; i++)
@ -105,7 +107,7 @@ public class Room
public void Write()
{
var saveFile = MainForm.SaveFile;
var saveFile = Save.SaveInstance;
foreach (var l in Layers)
{
@ -473,13 +475,13 @@ public static int GetHouseSize(int offset, SaveType saveType)
switch (saveType)
{
case SaveType.AnimalCrossing: // NOTE: N64 & GameCube titles don't include Basement in the size
return (MainForm.SaveFile.SaveData[offset + 0x2A] >> 5) & 7;
return (Save.SaveInstance.SaveData[offset + 0x2A] >> 5) & 7;
case SaveType.DoubutsuNoMoriPlus:
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
return (MainForm.SaveFile.SaveData[offset + 0x26] >> 5) & 7;
return (Save.SaveInstance.SaveData[offset + 0x26] >> 5) & 7;
case SaveType.WildWorld:
return MainForm.SaveFile.ReadByte(MainForm.SaveFile.SaveDataStartOffset + 0xFAF8) & 7; // Not sure about this
return Save.SaveInstance.ReadByte(Save.SaveInstance.SaveDataStartOffset + 0xFAF8) & 7; // Not sure about this
default:
return 0;
}
@ -490,18 +492,18 @@ public static void SetHouseSize(int offset, SaveType saveType, int value)
switch (saveType)
{
case SaveType.AnimalCrossing: // NOTE: N64 & GameCube titles don't include Basement in the size
MainForm.SaveFile.Write(offset + 0x2A,
(byte) (MainForm.SaveFile.ReadByte(offset + 0x2A) & ~(7 << 5) | ((value & 7) << 5)));
Save.SaveInstance.Write(offset + 0x2A,
(byte) (Save.SaveInstance.ReadByte(offset + 0x2A) & ~(7 << 5) | ((value & 7) << 5)));
break;
case SaveType.DoubutsuNoMoriPlus:
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
MainForm.SaveFile.Write(offset + 0x26,
(byte) (MainForm.SaveFile.ReadByte(offset + 0x26) & ~(7 << 5) | ((value & 7) << 5)));
Save.SaveInstance.Write(offset + 0x26,
(byte) (Save.SaveInstance.ReadByte(offset + 0x26) & ~(7 << 5) | ((value & 7) << 5)));
break;
case SaveType.WildWorld:
offset = MainForm.SaveFile.SaveDataStartOffset + 0xFAF8;
MainForm.SaveFile.Write(offset, (byte) ((MainForm.SaveFile.ReadByte(offset) & ~7) | (value & 7))); // Not sure about this
offset = Save.SaveInstance.SaveDataStartOffset + 0xFAF8;
Save.SaveInstance.Write(offset, (byte) ((Save.SaveInstance.ReadByte(offset) & ~7) | (value & 7))); // Not sure about this
break;
}
}
@ -511,12 +513,12 @@ public static bool HasStatue(int offset, SaveType saveType)
switch (saveType)
{
case SaveType.DoubutsuNoMoriPlus:
return ((MainForm.SaveFile.ReadByte(offset + 0x26) >> 2) & 7) == 4;
return ((Save.SaveInstance.ReadByte(offset + 0x26) >> 2) & 7) == 4;
case SaveType.AnimalCrossing:
return ((MainForm.SaveFile.ReadByte(offset + 0x2A) >> 2) & 7) == 4;
return ((Save.SaveInstance.ReadByte(offset + 0x2A) >> 2) & 7) == 4;
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
return ((MainForm.SaveFile.ReadByte(offset + 0x26) >> 2) & 7) == 5;
return ((Save.SaveInstance.ReadByte(offset + 0x26) >> 2) & 7) == 5;
default:
return false;
}
@ -529,16 +531,16 @@ public static void SetStatueEnabled(int offset, SaveType saveType, bool enabled)
{
case SaveType.DoubutsuNoMoriPlus:
writeValue = enabled ? (4 << 2) : (5 << 2);
MainForm.SaveFile.Write(offset + 0x26, (byte)((MainForm.SaveFile.ReadByte(offset + 0x26) & ~(7 << 2) | writeValue)));
Save.SaveInstance.Write(offset + 0x26, (byte)((Save.SaveInstance.ReadByte(offset + 0x26) & ~(7 << 2) | writeValue)));
break;
case SaveType.AnimalCrossing:
writeValue = enabled ? (4 << 2) : (5 << 2);
MainForm.SaveFile.Write(offset + 0x2A, (byte)((MainForm.SaveFile.ReadByte(offset + 0x2A) & ~(7 << 2) | writeValue)));
Save.SaveInstance.Write(offset + 0x2A, (byte)((Save.SaveInstance.ReadByte(offset + 0x2A) & ~(7 << 2) | writeValue)));
break;
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
writeValue = enabled ? (5 << 2) : (6 << 2);
MainForm.SaveFile.Write(offset + 0x26, (byte)((MainForm.SaveFile.ReadByte(offset + 0x26) & ~(7 << 2) | writeValue)));
Save.SaveInstance.Write(offset + 0x26, (byte)((Save.SaveInstance.ReadByte(offset + 0x26) & ~(7 << 2) | writeValue)));
break;
}
}
@ -549,7 +551,7 @@ public static int GetHouseUpgradeSize(int offset, SaveType saveType)
{
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
return (MainForm.SaveFile.SaveData[offset + 0x26] >> 2) & 7;
return (Save.SaveInstance.SaveData[offset + 0x26] >> 2) & 7;
default:
return 0;
}
@ -557,7 +559,7 @@ public static int GetHouseUpgradeSize(int offset, SaveType saveType)
public static int GetRoomSize(int offset) // NL/WA only
{
return Math.Min(8, MainForm.SaveFile.ReadByte(offset - 0x44) * 2);
return Math.Min(8, Save.SaveInstance.ReadByte(offset - 0x44) * 2);
}
public static bool HasBasement(int offset, SaveType saveType)
@ -565,10 +567,10 @@ public static bool HasBasement(int offset, SaveType saveType)
switch (saveType)
{
case SaveType.AnimalCrossing:
return (MainForm.SaveFile.SaveData[offset + 0x24] & 0x10) == 0x10;
return (Save.SaveInstance.SaveData[offset + 0x24] & 0x10) == 0x10;
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
return (MainForm.SaveFile.SaveData[offset + 0x20] & 0x10) == 0x10;
return (Save.SaveInstance.SaveData[offset + 0x20] & 0x10) == 0x10;
default:
return false;
}
@ -576,7 +578,7 @@ public static bool HasBasement(int offset, SaveType saveType)
public static void SetHasBasement(bool enabled, House selectedHouse)
{
var saveFile = MainForm.SaveFile;
var saveFile = Save.SaveInstance;
if (saveFile.SaveGeneration != SaveGeneration.N64 && saveFile.SaveGeneration != SaveGeneration.GCN &&
saveFile.SaveGeneration != SaveGeneration.iQue) return;
var basementFlagOffset = selectedHouse.Offset;

View file

@ -0,0 +1,65 @@
using System.Linq;
using System.IO;
using System.Drawing;
using System.Drawing.Drawing2D;
using ACSE.Core.Debug;
using ACSE.Core.Utilities;
namespace ACSE.Core.Imaging
{
public static class ImageGeneration
{
public static Bitmap DrawGrid2(Image img, int cellSize, Size imageSize, Pen gridPen = null, bool resize = true,
bool drawVertical = true, bool skipFirstLine = false)
{
if (gridPen == null)
gridPen = Pens.Black;
var gridBitmap = resize ? new Bitmap(imageSize.Width, imageSize.Height) : new Bitmap(img);
using (var gridGraphics = Graphics.FromImage(gridBitmap))
{
gridGraphics.InterpolationMode = InterpolationMode.NearestNeighbor;
if (resize)
gridGraphics.DrawImage(img, new Rectangle(0, 0, imageSize.Width, imageSize.Height),
new RectangleF((float) -0.5, (float) -0.5, 32, 32), GraphicsUnit.Pixel);
if (drawVertical)
for (var x = 0; x < gridBitmap.Width; x += cellSize)
{
gridGraphics.DrawLine(gridPen, x, 0, x, gridBitmap.Height);
}
for (var y = skipFirstLine ? cellSize : 0; y < gridBitmap.Height; y += cellSize)
{
gridGraphics.DrawLine(gridPen, 0, y, gridBitmap.Width, y);
}
}
return gridBitmap;
}
public static Image GetTpcImage(byte[] tpcBytes)
{
if (tpcBytes.Length != 0x1400)
{
return null;
}
for (var i = tpcBytes.Length - 1; i > 0; i--)
{
if (i > 0 && tpcBytes[i - 1] == 0xFF && tpcBytes[i] == 0xD9)
{
using (var ms = new MemoryStream(tpcBytes.Take(i).ToArray()))
{
return Image.FromStream(ms);
}
}
}
DebugUtility.DebugManagerInstance.WriteLine("Unable to find JPEG End-of-File marker. No TPC?",
DebugLevel.Error);
return null;
}
}
}

View file

@ -1,7 +1,13 @@
using System;
using System.Collections.Generic;
using ACSE.Core.Housing;
using ACSE.Core.Items;
using ACSE.Core.Patterns;
using ACSE.Core.Players;
using ACSE.Core.Saves;
using ACSE.Core.Villagers;
namespace ACSE
namespace ACSE.Core.Island
{
/// <summary>
/// Island class for Doubutsu no Mori e+

View file

@ -2,8 +2,11 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using ACSE.Core.Players;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Items
{
public class Inventory
{
@ -60,7 +63,8 @@ public static Image GetItemPic(int itemsize, int itemsPerRow, Item[] items, Save
var dataPosition = (y * itemsize + x2 % itemsize) * width * 4 + (x * itemsize + x2 / itemsize) * 4;
if (dataPosition >= bmpData.Length)
{
System.Windows.Forms.MessageBox.Show("Item Bitmap generation received more items than allocated space. Skipping " + (items.Length - i) + " Item(s).");
DebugUtility.DebugManagerInstance.WriteLine(
$"Item Bitmap generation received more items than allocated space. Skipping {items.Length - i} item(s).");
break;
}
Buffer.BlockCopy(BitConverter.GetBytes(itemColor), 0, bmpData, dataPosition, 4);

View file

@ -1,8 +1,8 @@
using System;
using System.Drawing;
using System.Runtime.Remoting.Messaging;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.Core.Items
{
public class Item : IEquatable<Item>, IEquatable<ushort>
{
@ -16,7 +16,7 @@ public class Item : IEquatable<Item>, IEquatable<ushort>
public Item()
{
var saveType = MainForm.SaveFile == null ? SaveType.AnimalCrossing : MainForm.SaveFile.SaveType;
var saveType = Save.SaveInstance == null ? SaveType.AnimalCrossing : Save.SaveInstance.SaveType;
switch (saveType)
{
case SaveType.WildWorld:
@ -29,14 +29,14 @@ public Item()
break;
}
Name = ItemData.GetItemName(ItemId);
Type = ItemData.GetItemType(ItemId, MainForm.SaveFile?.SaveType ?? SaveType.AnimalCrossing);
Type = ItemData.GetItemType(ItemId, Save.SaveInstance?.SaveType ?? SaveType.AnimalCrossing);
}
public Item(ushort itemId)
{
ItemId = itemId;
Name = ItemData.GetItemName(ItemId);
Type = ItemData.GetItemType(ItemId, MainForm.SaveFile?.SaveType ?? SaveType.AnimalCrossing);
Type = ItemData.GetItemType(ItemId, Save.SaveInstance?.SaveType ?? SaveType.AnimalCrossing);
}
public Item(uint itemId)
@ -45,7 +45,7 @@ public Item(uint itemId)
Flag1 = (byte)(itemId >> 24);
Flag2 = (byte)(itemId >> 16);
Name = ItemData.GetItemName(ItemId);
Type = ItemData.GetItemType(ItemId, MainForm.SaveFile?.SaveType ?? SaveType.AnimalCrossing);
Type = ItemData.GetItemType(ItemId, Save.SaveInstance?.SaveType ?? SaveType.AnimalCrossing);
}
public Item(Item cloningItem)
@ -63,7 +63,7 @@ public Item(ushort itemId, byte flag1, byte flag2)
Flag1 = flag1;
Flag2 = flag2;
Name = ItemData.GetItemName(ItemId);
Type = ItemData.GetItemType(ItemId, MainForm.SaveFile?.SaveType ?? SaveType.AnimalCrossing);
Type = ItemData.GetItemType(ItemId, Save.SaveInstance?.SaveType ?? SaveType.AnimalCrossing);
}
public uint ToUInt32()
@ -199,7 +199,7 @@ public class Furniture : Item, IEquatable<Furniture>
public Furniture(ushort itemId) : base(itemId)
{
if (MainForm.SaveFile.SaveGeneration == SaveGeneration.N3DS)
if (Save.SaveInstance.SaveGeneration == SaveGeneration.N3DS)
{
BaseItemId = itemId;
Rotation = 0;
@ -207,8 +207,8 @@ public Furniture(ushort itemId) : base(itemId)
else
{
BaseItemId = (ushort)(ItemId & 0xFFFC);
if (ItemData.GetItemType(itemId, MainForm.SaveFile.SaveType) == ItemType.Furniture ||
ItemData.GetItemType(itemId, MainForm.SaveFile.SaveType) == ItemType.Gyroid)
if (ItemData.GetItemType(itemId, Save.SaveInstance.SaveType) == ItemType.Furniture ||
ItemData.GetItemType(itemId, Save.SaveInstance.SaveType) == ItemType.Gyroid)
{
Rotation = ItemId & 3;
}
@ -223,7 +223,7 @@ public Furniture(uint item) : base(item)
public Furniture(ushort item, byte flag1, byte flag2) : base(item, flag1, flag2)
{
if (MainForm.SaveFile.SaveGeneration == SaveGeneration.N3DS)
if (Save.SaveInstance.SaveGeneration == SaveGeneration.N3DS)
{
BaseItemId = ItemId;
Rotation = (Flag1 >> 4) / 4;
@ -231,8 +231,8 @@ public Furniture(ushort item, byte flag1, byte flag2) : base(item, flag1, flag2)
else
{
BaseItemId = (ushort)(ItemId & 0xFFFC);
if (ItemData.GetItemType(ItemId, MainForm.SaveFile.SaveType) == ItemType.Furniture ||
ItemData.GetItemType(ItemId, MainForm.SaveFile.SaveType) == ItemType.Gyroid)
if (ItemData.GetItemType(ItemId, Save.SaveInstance.SaveType) == ItemType.Furniture ||
ItemData.GetItemType(ItemId, Save.SaveInstance.SaveType) == ItemType.Gyroid)
{
Rotation = ItemId & 3;
}
@ -241,7 +241,7 @@ public Furniture(ushort item, byte flag1, byte flag2) : base(item, flag1, flag2)
public Furniture(Item item) : base (item)
{
if (MainForm.SaveFile.SaveGeneration == SaveGeneration.N3DS)
if (Save.SaveInstance.SaveGeneration == SaveGeneration.N3DS)
{
BaseItemId = ItemId;
Rotation = (Flag1 >> 4) / 4;
@ -249,8 +249,8 @@ public Furniture(Item item) : base (item)
else
{
BaseItemId = (ushort)(ItemId & 0xFFFC);
if (ItemData.GetItemType(ItemId, MainForm.SaveFile.SaveType) == ItemType.Furniture ||
ItemData.GetItemType(ItemId, MainForm.SaveFile.SaveType) == ItemType.Gyroid)
if (ItemData.GetItemType(ItemId, Save.SaveInstance.SaveType) == ItemType.Furniture ||
ItemData.GetItemType(ItemId, Save.SaveInstance.SaveType) == ItemType.Gyroid)
{
Rotation = ItemId & 3;
}

View file

@ -1,4 +1,4 @@
namespace ACSE
namespace ACSE.Core.Items
{
public class ItemChange
{

View file

@ -1,4 +1,4 @@
namespace ACSE
namespace ACSE.Core.Items
{
public class ItemChangedEventArgs
{

View file

@ -1,10 +1,13 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using ACSE.Core.Buildings;
using ACSE.Core.Debug;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Items
{
public enum ItemType
{
@ -46,9 +49,14 @@ public enum ItemType
public class ItemData
{
/// <summary>
/// A dictionary containing string-uint pairs for item colors.
/// </summary>
public static Dictionary<string, uint> ItemColorsSettings;
public static List<KeyValuePair<ushort, string>> ItemDatabase = new List<KeyValuePair<ushort, string>>();
internal static readonly string[] ItemTypeNames =
public static readonly string[] ItemTypeNames =
{
"Empty",
"Furniture",
@ -441,81 +449,80 @@ public static ItemType GetItemType(ushort id, SaveType saveType)
}
public static uint GetItemColor(ItemType itemType)
{
var settings = ItemColorSettings.Default;
switch (itemType)
{
case ItemType.Furniture:
return settings.FurnitureColor;
return ItemColorsSettings["FurnitureColor"];
case ItemType.Flower:
return settings.FlowerColor;
return ItemColorsSettings["FlowerColor"];
case ItemType.Pattern:
return settings.PatternColor;
return ItemColorsSettings["PatternColor"];
case ItemType.ParchedFlower:
return settings.ParchedFlowerColor;
return ItemColorsSettings["ParchedFlowerColor"];
case ItemType.WiltedFlower:
return settings.WiltedFlowerColor;
return ItemColorsSettings["WiltedFlowerColor"];
case ItemType.WateredFlower:
return settings.WateredFlowerColor;
return ItemColorsSettings["WateredFlowerColor"];
case ItemType.Money:
return settings.MoneyColor;
return ItemColorsSettings["MoneyColor"];
case ItemType.Rock:
return settings.RockColor;
return ItemColorsSettings["RockColor"];
case ItemType.MoneyRock:
return settings.MoneyRockColor;
return ItemColorsSettings["MoneyRockColor"];
case ItemType.Signboard:
return settings.SignboardColor;
return ItemColorsSettings["SignboardColor"];
case ItemType.Song:
return settings.SongColor;
return ItemColorsSettings["SongColor"];
case ItemType.Paper:
return settings.PaperColor;
return ItemColorsSettings["PaperColor"];
case ItemType.Turnip:
return settings.TurnipColor;
return ItemColorsSettings["TurnipColor"];
case ItemType.Catchable:
return settings.CatchableColor;
return ItemColorsSettings["CatchableColor"];
case ItemType.WallpaperCarpet:
return settings.WallpaperCarpetColor;
return ItemColorsSettings["WallpaperCarpetColor"];
case ItemType.Clothes:
return settings.ClothesColor;
return ItemColorsSettings["ClothesColor"];
case ItemType.Gyroid:
return settings.GyroidColor;
return ItemColorsSettings["GyroidColor"];
case ItemType.Fossil:
return settings.FossilColor;
return ItemColorsSettings["FossilColor"];
case ItemType.Tool:
return settings.ToolColor;
return ItemColorsSettings["ToolColor"];
case ItemType.Item:
return settings.ItemColor;
return ItemColorsSettings["ItemColor"];
case ItemType.Fruit:
return settings.FruitColor;
return ItemColorsSettings["FruitColor"];
case ItemType.Trash:
return settings.TrashColor;
return ItemColorsSettings["TrashColor"];
case ItemType.QuestItem:
return settings.QuestItemColor;
return ItemColorsSettings["QuestItemColor"];
case ItemType.RaffleTicket:
return settings.RaffleTicketColor;
return ItemColorsSettings["RaffleTicketColor"];
case ItemType.Tree:
return settings.TreeColor;
return ItemColorsSettings["TreeColor"];
case ItemType.Weed:
return settings.WeedColor;
return ItemColorsSettings["WeedColor"];
case ItemType.Shell:
return settings.ShellColor;
return ItemColorsSettings["ShellColor"];
case ItemType.Empty:
return 0x00FFFFFF; // No setting for empty since we always want it transparent
case ItemType.Occupied:
return settings.OccupiedColor;
return ItemColorsSettings["OccupiedColor"];
case ItemType.Building:
return settings.BuildingColor;
return ItemColorsSettings["BuildingColor"];
case ItemType.Diary:
return settings.DiaryColor;
return ItemColorsSettings["DiaryColor"];
case ItemType.HouseObject:
return settings.HouseObjectColor;
return ItemColorsSettings["HouseObjectColor"];
default:
return settings.InvalidColor;
return ItemColorsSettings["InvalidColor"];
}
}
public static string GetItemFlag1Type(Item item, byte itemFlag)
{
var itemType = GetItemType(item.ItemId, MainForm.SaveFile.SaveType);
var itemType = GetItemType(item.ItemId, Save.SaveInstance.SaveType);
switch (itemType)
{
case ItemType.Fruit:
@ -641,12 +648,12 @@ public static string GetFurnitureItemFlag2Type(byte itemFlag) //Our Flag 2, but
public static string GetItemName(ushort itemId)
{
switch (MainForm.SaveFile.SaveGeneration)
switch (Save.SaveInstance.SaveGeneration)
{
case SaveGeneration.N3DS:
return ItemDatabase.FirstOrDefault(o => o.Key == itemId).Value ?? "Unknown";
default:
if (GetItemType(itemId, MainForm.SaveFile.SaveType) == ItemType.Furniture)
if (GetItemType(itemId, Save.SaveInstance.SaveType) == ItemType.Furniture)
{
return ItemDatabase.FirstOrDefault(o => o.Key == (ushort)(itemId & 0xFFFC)).Value ?? "Unknown";
}
@ -675,7 +682,7 @@ public static Dictionary<ushort, string> LoadItemDatabase(StreamReader reader)
}
catch
{
Debug.WriteLine($"Error in loading item: {line}");
DebugUtility.DebugManagerInstance.WriteLine($"Error in loading item: {line}", DebugLevel.Error);
}
}

View file

@ -1,6 +1,7 @@
using System;
using ACSE.Core.Items;
namespace ACSE.Messages.Mail
namespace ACSE.Core.Messages.Mail
{
public sealed class GCNAnimalMail
{

View file

@ -1,4 +1,8 @@
namespace ACSE.Messages.Mail
using ACSE.Core.Items;
using ACSE.Core.Players;
using ACSE.Core.Saves;
namespace ACSE.Core.Messages.Mail
{
public sealed class GcnPlayerMail : PlayerMailBase
{

View file

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ACSE.Core.Items;
using ACSE.Core.Saves;
namespace ACSE.Messages.Mail
namespace ACSE.Core.Messages.Mail
{
/// <summary>
/// N64/GameCube/iQue letter type/state

View file

@ -1,4 +1,4 @@
namespace ACSE.Messages.Mail
namespace ACSE.Core.Messages.Mail
{
public class PlayerMailBase : MailBase
{

View file

@ -1,6 +1,6 @@
using ACSE.Utilities;
using ACSE.Core.Utilities;
namespace ACSE.Messages
namespace ACSE.Core.Messages
{
public abstract class MessageBase
{

View file

@ -1,4 +1,4 @@
namespace ACSE.Messages
namespace ACSE.Core.Messages
{
public class MessageBoardPost : MessageBase
{

View file

@ -1,9 +1,9 @@
namespace ACSE
namespace ACSE.Core.Modifiable
{
/// <summary>
/// Interface for all modifiable things that implement a modified stack.
/// </summary>
internal interface IModifiable
public interface IModifiable
{
void Undo();
void Redo();

View file

@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
namespace ACSE
namespace ACSE.Core.Modifiable
{
internal class ModifiedHandler : IModifiable
public class ModifiedHandler : IModifiable
{
public readonly Stack<IModifiable> UndoStack;
public readonly Stack<IModifiable> RedoStack;

View file

@ -1,10 +1,10 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using ACSE.Utilities;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Patterns
{
/// <summary>
/// GameCube Pattern Data Write-up
@ -19,7 +19,7 @@ namespace ACSE
/// [Byte Array] Alignment Bytes?: 0xF bytes
/// [Byte Array] Pattern Data: 0x200 bytes
/// </summary>
class PatternData
public static class PatternData
{
#region Palettes
@ -324,7 +324,7 @@ public static byte ClosestColorRgb(uint color, uint[] paletteData, bool gen1 = f
}
}
public class Pattern
public sealed class Pattern
{
private readonly Save _saveFile;
private readonly int _offset;
@ -351,7 +351,6 @@ public uint[][] GetPaletteArray(SaveGeneration saveGeneration)
{
switch (saveGeneration)
{
case SaveGeneration.GCN:
default:
return PatternData.AcPaletteData;
case SaveGeneration.NDS:
@ -364,15 +363,20 @@ public uint[][] GetPaletteArray(SaveGeneration saveGeneration)
// AC / CF
public void GeneratePatternBitmap(byte[] importData = null, bool decode = true)
{
var patternRawData = importData ?? (_saveFile.SaveType == SaveType.CityFolk ? _saveFile.ReadByteArray(_offset, 0x200) : _saveFile.ReadByteArray(_offset + 0x20, 0x200));
var paletteData = _saveFile.SaveType == SaveType.CityFolk ? PatternData.CfPaletteData : PatternData.AcPaletteData;
var patternRawData = importData ?? (_saveFile.SaveType == SaveType.CityFolk
? _saveFile.ReadByteArray(_offset, 0x200)
: _saveFile.ReadByteArray(_offset + 0x20, 0x200));
var paletteData = _saveFile.SaveType == SaveType.CityFolk
? PatternData.CfPaletteData
: PatternData.AcPaletteData;
if (decode)
{
DecodedData = PatternUtility.DecodeC4(patternRawData);
}
PatternBitmap = PatternUtility.C4PaletteMapToBitmap(DecodedData, paletteData[Palette], 32, 32);
PatternBitmap = PatternUtility.C4PaletteMapToBitmap(DecodedData, paletteData[Palette]);
}
public void GenerateWwPatternBitmap(byte[] importData = null, bool decode = true)
@ -482,9 +486,6 @@ public void Read(int index)
//No specific palette in NL/WA
GenerateNlPatternBitmap();
break;
default:
MessageBox.Show("Patterns: Unknown Save Type");
break;
}
}
@ -495,7 +496,7 @@ public void RedrawBitmap()
case SaveGeneration.GCN:
case SaveGeneration.Wii:
GeneratePatternBitmap(DecodedData, false);
Write(PatternUtility.EncodeC4(DecodedData, 32, 32));
Write(PatternUtility.EncodeC4(DecodedData));
break;
case SaveGeneration.NDS:
GenerateWwPatternBitmap(DecodedData, false);

View file

@ -1,9 +1,15 @@
using System;
using System.Reflection;
using ACSE.Utilities;
using ACSE.Messages.Mail;
using ACSE.Core.Encryption;
using ACSE.Core.Housing;
using ACSE.Core.Imaging;
using ACSE.Core.Items;
using ACSE.Core.Messages.Mail;
using ACSE.Core.Patterns;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Players
{
public sealed class Player
{
@ -262,9 +268,13 @@ public void Write()
_saveData.Write(dataOffset, (byte)playerDataType.GetField(field.Name).GetValue(Data));
}
}
else if (fieldType == typeof(ushort) || fieldType == typeof(uint))
else if (fieldType == typeof(ushort))
{
_saveData.Write(dataOffset, (dynamic)playerDataType.GetField(field.Name).GetValue(Data), _saveData.IsBigEndian);
_saveData.Write(dataOffset, (ushort)playerDataType.GetField(field.Name).GetValue(Data), _saveData.IsBigEndian);
}
else if (fieldType == typeof(uint))
{
_saveData.Write(dataOffset, (uint)playerDataType.GetField(field.Name).GetValue(Data), _saveData.IsBigEndian);
}
else if (fieldType == typeof(Inventory))
{

View file

@ -1,8 +1,12 @@
using ACSE.Utilities;
using System;
using System;
using System.Drawing;
using ACSE.Core.Encryption;
using ACSE.Core.Items;
using ACSE.Core.Patterns;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Players
{
public struct PlayerSaveInfo
{

View file

@ -1,12 +1,12 @@
using System.Collections.Generic;
namespace ACSE.Checksums
namespace ACSE.Core.Saves.Checksums
{
/// <inheritdoc />
/// <summary>
/// Generic CRC32 checksum used in Animal Crossing: City Folk.
/// </summary>
internal class CRC32 : IChecksum<uint>
public sealed class CRC32 : IChecksum<uint>
{
private static readonly uint[] Crc32Table = {
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,

View file

@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace ACSE.Checksums
namespace ACSE.Core.Saves.Checksums
{
/// <summary>
/// Interface for all checksum calculating objects.

View file

@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
namespace ACSE.Checksums
namespace ACSE.Core.Saves.Checksums
{
internal class NewLeafCRC32Type1 : IChecksum<uint>
public sealed class NewLeafCRC32Type1 : IChecksum<uint>
{
public static uint[] NewLeafCrcTableType1 = {
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4, 0xC79A971F,

View file

@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
namespace ACSE.Checksums
namespace ACSE.Core.Saves.Checksums
{
internal class NewLeafCRC32Type2 : IChecksum<uint>
public sealed class NewLeafCRC32Type2 : IChecksum<uint>
{
private static readonly uint[] NewLeafCrcTableType2 = {
0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC,

View file

@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
namespace ACSE.Checksums
namespace ACSE.Core.Saves.Checksums
{
/// <summary>
/// 16-bit big-endian checksum implementation used by N64, GCN, & iQue games.
/// </summary>
internal class UInt16BEChecksum : IChecksum<ushort>
public sealed class UInt16BEChecksum : IChecksum<ushort>
{
/// <inheritdoc />
/// <summary>

View file

@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
namespace ACSE.Checksums
namespace ACSE.Core.Saves.Checksums
{
/// <summary>
/// 16-bit little-endian checksum implementation used by Animal Crossing: Wild World.
/// </summary>
internal class UInt16LEChecksum : IChecksum<ushort>
public sealed class UInt16LEChecksum : IChecksum<ushort>
{
/// <inheritdoc />
/// <summary>

View file

@ -1,12 +1,12 @@
using System;
using System.Linq;
using System.IO;
using System.Windows.Forms;
using System.Text;
using ACSE.Checksums;
using ACSE.Utilities;
using ACSE.Core.Debug;
using ACSE.Core.Saves.Checksums;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Saves
{
public enum SaveType : byte
{
@ -48,6 +48,8 @@ public enum Region : byte
public class Save
{
public static Save SaveInstance { get; private set; }
public readonly SaveType SaveType;
public readonly SaveGeneration SaveGeneration;
public readonly SaveInfo SaveInfo;
@ -64,10 +66,9 @@ public class Save
private FileStream _saveFile;
private readonly BinaryReader _saveReader;
private BinaryWriter _saveWriter;
private readonly Backup _backup;
private readonly bool _byteswap = false;
public Save(string filePath)
public Save(string filePath, bool createBackup = false)
{
if (File.Exists(filePath))
{
@ -79,9 +80,9 @@ public Save(string filePath)
try { _saveFile = new FileStream(filePath, FileMode.Open); } catch { SuccessfullyLoaded = false; }
if (_saveFile == null || !SuccessfullyLoaded || !_saveFile.CanWrite)
{
MessageBox.Show(
DebugUtility.DebugManagerInstance.WriteLine(
$"Error: File {Path.GetFileName(filePath)} is being used by another process. Please close any process using it before editing!",
"File Opening Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
DebugLevel.Error);
try
{
_saveFile?.Close();
@ -119,12 +120,12 @@ public Save(string filePath)
_saveReader.Dispose();
_saveFile.Dispose();
// Create a Backup
if (Properties.Settings.Default.BackupFiles)
_backup = new Backup(this);
SaveInstance = this;
}
else
MessageBox.Show("File doesn't exist!");
{
DebugUtility.DebugManagerInstance.WriteLine("File doesn't exist!", DebugLevel.Error);
}
}
public void Flush()

View file

@ -3,9 +3,11 @@
using System.Globalization;
using System.IO;
using System.Text;
using System.Windows.Forms;
using ACSE.Core.Debug;
using ACSE.Core.Items;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Saves
{
public struct Offsets
{
@ -796,34 +798,42 @@ public static SaveInfo GetSaveInfo(SaveType saveType)
public static Dictionary<ushort, string> GetItemInfo(SaveType saveType, string language = "en")
{
var itemDbLocation = MainForm.AssemblyLocation + "\\Resources\\";
var itemDbLocation = "";
switch (saveType)
{
case SaveType.DoubutsuNoMori:
case SaveType.DongwuSenlin:
itemDbLocation += "DnM_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"DnM_Items_{language}.txt");
break;
case SaveType.DoubutsuNoMoriPlus:
itemDbLocation += "DBNM_Plus_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"DBNM_Plus_Items_{language}.txt");
break;
case SaveType.AnimalCrossing:
itemDbLocation += "AC_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"AC_Items_{language}.txt");
break;
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
itemDbLocation += "DBNM_e_Plus_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"DBNM_e_Plus_Items_{language}.txt");
break;
case SaveType.WildWorld:
itemDbLocation += "WW_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"WW_Items_{language}.txt");
break;
case SaveType.CityFolk:
itemDbLocation += "CF_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"CF_Items_{language}.txt");
break;
case SaveType.NewLeaf:
itemDbLocation += "NL_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"NL_Items_{language}.txt");
break;
case SaveType.WelcomeAmiibo:
itemDbLocation += "WA_Items_" + language + ".txt";
itemDbLocation = Path.Combine(PathUtility.GetExeDirectory(), "Resources",
$"WA_Items_{language}.txt");
break;
}
@ -836,7 +846,7 @@ public static Dictionary<ushort, string> GetItemInfo(SaveType saveType, string l
}
catch (Exception e)
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"An error occured opening item database file:\n\"{itemDbLocation}\"\nError Info:\n{e.Message}", DebugLevel.Error);
return null;
}
@ -844,108 +854,86 @@ public static Dictionary<ushort, string> GetItemInfo(SaveType saveType, string l
public static Dictionary<byte, string> GetAcreInfo(SaveType saveType, string language = "en")
{
StreamReader contents;
var acreDbLocation = MainForm.AssemblyLocation + "\\Resources\\";
if (saveType == SaveType.WildWorld)
acreDbLocation += "WW_Acres_" + language + ".txt";
try { contents = File.OpenText(acreDbLocation); }
catch (Exception e)
if (saveType != SaveType.WildWorld) return null;
var (result, database) =
DatabaseUtility.LoadDatabaseByte(Path.Combine(PathUtility.GetExeDirectory(),
$"WW_Acres_{language}.txt"));
switch (result)
{
MainForm.DebugManager.WriteLine(
$"An error occured opening acre database file:\n\"{acreDbLocation}\"\nError Info:\n{e.Message}", DebugLevel.Error);
return null;
}
var acreDictionary = new Dictionary<byte, string>();
string line;
while ((line = contents.ReadLine()) != null)
{
if (!Properties.Settings.Default.DebuggingEnabled && line.Contains("//"))
MessageBox.Show("Now loading Acre type: " + line.Replace("//", ""));
else if (line.Contains("0x"))
{
string acreIdString = line.Substring(0, 4), acreName = line.Substring(5);
if (byte.TryParse(acreIdString.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out var acreId))
acreDictionary.Add(acreId, acreName);
else
MainForm.DebugManager.WriteLine("Unable to add Acre: " + acreIdString + " | " + acreName, DebugLevel.Error);
}
case DatabaseUtility.DatabaseReturnCode.FailedToOpen:
DebugUtility.DebugManagerInstance.WriteLine(
"Failed to open the Wild World acre database file.", DebugLevel.Error);
break;
case DatabaseUtility.DatabaseReturnCode.FailedToRead:
DebugUtility.DebugManagerInstance.WriteLine(
"Failed to read the Wild World acre database file.", DebugLevel.Error);
break;
}
contents.Close();
contents.Dispose();
return acreDictionary;
return database;
}
public static Dictionary<ushort, string> GetAcreInfoUInt16(SaveType saveType, string language = "en")
{
StreamReader contents;
var acreDbLocation = MainForm.AssemblyLocation + "\\Resources\\";
{;
var databaseName = "";
switch (saveType)
{
case SaveType.DoubutsuNoMori:
case SaveType.DongwuSenlin:
case SaveType.AnimalCrossing: // TODO: DnM needs to have a custom list, since the docks/islands don't exist
acreDbLocation += "AC_Acres_" + language + ".txt";
databaseName = $"AC_Acres_{language}.txt";
break;
case SaveType.DoubutsuNoMoriPlus:
acreDbLocation += "DBNM_Plus_Acres_" + language + ".txt";
databaseName = $"DBNM_Plus_Acres_{language}.txt";
break;
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
acreDbLocation += "DBNM_e_Plus_Acres_" + language + ".txt";
databaseName = $"DBNM_e_Plus_Acres_{language}.txt";
break;
case SaveType.CityFolk:
acreDbLocation += "CF_Acres_" + language + ".txt";
databaseName = $"CF_Acres_{language}.txt";
break;
case SaveType.NewLeaf:
acreDbLocation += "NL_Acres_" + language + ".txt";
databaseName = $"NL_Acres_{language}.txt";
break;
case SaveType.WelcomeAmiibo:
acreDbLocation += "WA_Acres_" + language + ".txt";
databaseName = $"WA_Acres_{language}.txt";
break;
}
try { contents = File.OpenText(acreDbLocation); }
catch (Exception e)
var (result, database) =
DatabaseUtility.LoadDatabase(Path.Combine(PathUtility.GetExeDirectory(), databaseName));
switch (result)
{
MainForm.DebugManager.WriteLine(
$"An error occured opening acre database file:\n\"{acreDbLocation}\"\nError Info:\n{e.Message}", DebugLevel.Error);
return null;
}
var acreDictionary = new Dictionary<ushort, string>();
string line;
while ((line = contents.ReadLine()) != null)
{
if (!Properties.Settings.Default.DebuggingEnabled && line.Contains("//"))
MessageBox.Show("Now loading Acre type: " + line.Replace("//", ""));
else if (line.Contains("0x"))
{
string acreIdString = line.Substring(0, 6), acreName = line.Substring(7);
if (ushort.TryParse(acreIdString.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out var acreId))
acreDictionary.Add(acreId, acreName);
else
MainForm.DebugManager.WriteLine("Unable to add Acre: " + acreIdString + " | " + acreName, DebugLevel.Error);
}
case DatabaseUtility.DatabaseReturnCode.FailedToOpen:
DebugUtility.DebugManagerInstance.WriteLine(
"Failed to open the acre database file.", DebugLevel.Error);
break;
case DatabaseUtility.DatabaseReturnCode.FailedToRead:
DebugUtility.DebugManagerInstance.WriteLine(
"Failed to read the acre database file.", DebugLevel.Error);
break;
}
contents.Close();
contents.Dispose();
return acreDictionary;
return database;
}
public static Dictionary<string, List<byte>> GetFiledAcreData(SaveType saveType, string language = "en")
{
StreamReader contents;
var acreDbLocation = MainForm.AssemblyLocation + "\\Resources\\";
var acreDbLocation = PathUtility.GetExeDirectory();
if (saveType == SaveType.WildWorld)
acreDbLocation += "WW_Acres_" + language + ".txt";
try { contents = File.OpenText(acreDbLocation); }
catch (Exception e)
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"An error occured opening acre database file:\n\"{acreDbLocation}\"\nError Info:\n{e.Message}", DebugLevel.Error);
return null;
}
@ -968,10 +956,12 @@ public static Dictionary<string, List<byte>> GetFiledAcreData(SaveType saveType,
if (!filedList.ContainsKey(currentAcreType))
filedList.Add(currentAcreType, new List<byte>());
string acreIdString = line.Substring(0, 4), acreName = line.Substring(5);
if (byte.TryParse(acreIdString.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out var acreId))
if (byte.TryParse(acreIdString.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null,
out var acreId))
filedList[currentAcreType].Add(acreId);
else
MainForm.DebugManager.WriteLine("Unable to add Acre: " + acreIdString + " | " + acreName, DebugLevel.Error);
DebugUtility.DebugManagerInstance.WriteLine(
"Unable to add Acre: " + acreIdString + " | " + acreName, DebugLevel.Error);
}
}
@ -984,7 +974,7 @@ public static Dictionary<string, List<byte>> GetFiledAcreData(SaveType saveType,
public static Dictionary<string, Dictionary<ushort, string>> GetFiledAcreDataUInt16(SaveType saveType, string language = "en")
{
StreamReader contents;
var acreDbLocation = MainForm.AssemblyLocation + "\\Resources\\";
var acreDbLocation = PathUtility.GetExeDirectory();
switch (saveType)
{
case SaveType.DoubutsuNoMori:
@ -1013,7 +1003,7 @@ public static Dictionary<string, Dictionary<ushort, string>> GetFiledAcreDataUIn
try { contents = File.OpenText(acreDbLocation); }
catch (Exception e)
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"An error occured opening acre database file:\n\"{acreDbLocation}\"\nError Info:\n{e.Message}", DebugLevel.Error);
return null;
}
@ -1036,10 +1026,12 @@ public static Dictionary<string, Dictionary<ushort, string>> GetFiledAcreDataUIn
if (!filedList.ContainsKey(currentAcreType))
filedList.Add(currentAcreType, new Dictionary<ushort, string>());
string acreIdString = line.Substring(0, 6), acreName = line.Substring(7);
if (ushort.TryParse(acreIdString.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null, out var acreId))
if (ushort.TryParse(acreIdString.Replace("0x", ""), NumberStyles.AllowHexSpecifier, null,
out var acreId))
filedList[currentAcreType].Add(acreId, line.Substring(7));
else
MainForm.DebugManager.WriteLine("Unable to add Acre: " + acreIdString + " | " + acreName, DebugLevel.Error);
DebugUtility.DebugManagerInstance.WriteLine(
"Unable to add Acre: " + acreIdString + " | " + acreName, DebugLevel.Error);
}
}

View file

@ -1,4 +1,8 @@
namespace ACSE
using ACSE.Core.Items;
using ACSE.Core.Patterns;
using ACSE.Core.Saves;
namespace ACSE.Core.Shops
{
public class ShopOffsets
{
@ -139,7 +143,7 @@ public FurnitureShop(Save saveFile, int offset) : base(saveFile, offset)
public byte GetSize(SaveGeneration generation)
{
var saveFile = MainForm.SaveFile;
var saveFile = Save.SaveInstance;
var shopOffsets = ShopInfo.GetShopOffsets(saveFile.SaveType);
if (shopOffsets == null) return 0;
switch (generation)
@ -156,7 +160,7 @@ public byte GetSize(SaveGeneration generation)
public void SetSize(byte size)
{
var saveFile = MainForm.SaveFile;
var saveFile = Save.SaveInstance;
var shopOffsets = ShopInfo.GetShopOffsets(saveFile.SaveType);
if (shopOffsets == null) return;
switch (saveFile.SaveGeneration)

View file

@ -1,7 +1,10 @@
using System.Drawing;
using System.IO;
using ACSE.Core.Debug;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.TownBuildings
{
public static class TrainStation
{
@ -11,7 +14,9 @@ public static bool HasModifiableTrainStation(SaveGeneration generation)
public static Image GetStationImage(int station)
{
Image stationImg = null;
var stationFile = MainForm.AssemblyLocation + "\\Resources\\Images\\Icons\\Stations\\" + (station + 1).ToString() + ".png";
var stationFile = Path.Combine(PathUtility.GetResourcesDirectory(), "Images", "Icons",
$"Stations{station + 1}.png");
if (!File.Exists(stationFile)) return null;
try
{
@ -19,7 +24,8 @@ public static Image GetStationImage(int station)
}
catch
{
MainForm.DebugManager.WriteLine("Unable to load station image #" + (station + 1), DebugLevel.Error);
DebugUtility.DebugManagerInstance.WriteLine("Unable to load station image #" + (station + 1),
DebugLevel.Error);
}
return stationImg;
}

View file

@ -2,11 +2,12 @@
using System.IO;
using System.Net;
using System.Reflection;
using ACSE.Core.Utilities;
using Newtonsoft.Json.Linq;
namespace ACSE
namespace ACSE.Core.Updater
{
internal sealed class Updater
public sealed class Updater
{
private int _versionMajor;
private int _versionMinor;
@ -16,7 +17,7 @@ internal sealed class Updater
private void SetCurrentVersionInfo()
{
var versionInfo = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
var versionInfo = FileVersionInfo.GetVersionInfo(PathUtility.GetExeLocation());
_versionMajor = versionInfo.FileMajorPart;
_versionMinor = versionInfo.FileMinorPart;
_versionRevision = versionInfo.ProductBuildPart;

View file

@ -0,0 +1,98 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
namespace ACSE.Core.Utilities
{
public static class DatabaseUtility
{
public enum DatabaseReturnCode
{
FailedToRead = -2,
FailedToOpen = -1,
Success = 0
}
/// <summary>
/// Loads a specified database with the key type as bytes.
/// </summary>
/// <param name="databasePath">The path to the database to load.</param>
/// <returns>The result of the method <see cref="DatabaseReturnCode"/>, and the loaded database if execution was successful.</returns>
public static (DatabaseReturnCode, Dictionary<byte, string>) LoadDatabaseByte(string databasePath)
{
StreamReader databaseReader;
try
{
databaseReader = File.OpenText(databasePath);
}
catch
{
return (DatabaseReturnCode.FailedToOpen, null);
}
try
{
using (databaseReader)
{
var database = new Dictionary<byte, string>();
string line;
while ((line = databaseReader.ReadLine()) != null)
{
if (line.Contains("//")) continue;
database.Add(byte.Parse(line.Substring(0, 4).Replace("0x", ""), NumberStyles.HexNumber),
line.Substring(5));
}
return (DatabaseReturnCode.Success, database);
}
}
catch
{
return (DatabaseReturnCode.FailedToRead, null);
}
}
/// <summary>
/// Loads a specified database with the key type as ushorts.
/// </summary>
/// <param name="databasePath">The path to the database to load.</param>
/// <returns>The result of the method <see cref="DatabaseReturnCode"/>, and the loaded database if execution was successful.</returns>
public static (DatabaseReturnCode, Dictionary<ushort, string>) LoadDatabase(string databasePath)
{
StreamReader databaseReader;
try
{
databaseReader = File.OpenText(databasePath);
}
catch
{
return (DatabaseReturnCode.FailedToOpen, null);
}
try
{
using (databaseReader)
{
var database = new Dictionary<ushort, string>();
string line;
while ((line = databaseReader.ReadLine()) != null)
{
if (line.Contains("//")) continue;
database.Add(ushort.Parse(line.Substring(0, 6).Replace("0x", ""), NumberStyles.HexNumber),
line.Substring(7));
}
return (DatabaseReturnCode.Success, database);
}
}
catch
{
return (DatabaseReturnCode.FailedToRead, null);
}
}
}
}

View file

@ -1,6 +1,7 @@
using System;
using ACSE.Core.Saves;
namespace ACSE.Utilities
namespace ACSE.Core.Utilities
{
public class AcDate
{
@ -38,7 +39,7 @@ public AcDate()
public AcDate(byte[] dateData)
{
switch (MainForm.SaveFile.SaveType)
switch (Save.SaveInstance.SaveType)
{
case SaveType.DoubutsuNoMori:
case SaveType.DoubutsuNoMoriPlus:
@ -125,7 +126,7 @@ public string Format(string formatString)
public byte[] ToFullDateData()
{
switch (MainForm.SaveFile.SaveGeneration)
switch (Save.SaveInstance.SaveGeneration)
{
case SaveGeneration.N64:
case SaveGeneration.GCN:
@ -147,7 +148,7 @@ public byte[] ToFullDateData()
public byte[] ToYearMonthDayDateData()
{
switch (MainForm.SaveFile.SaveGeneration)
switch (Save.SaveInstance.SaveGeneration)
{
case SaveGeneration.N64:
case SaveGeneration.GCN:
@ -173,7 +174,7 @@ public byte[] ToYearMonthDayDateData()
public byte[] ToMonthDayDateData()
{
switch (MainForm.SaveFile.SaveGeneration)
switch (Save.SaveInstance.SaveGeneration)
{
case SaveGeneration.N64:
case SaveGeneration.GCN:

View file

@ -0,0 +1,22 @@
using ACSE.Core.Debug;
using ACSE.Core.Saves;
namespace ACSE.Core.Utilities
{
public static class DebugUtility
{
/// <summary>
/// The current DebugManager instance.
/// </summary>
public static DebugManager DebugManagerInstance { get; private set; }
/// <summary>
/// Initializes the DebugManager and returns the instance. If it is already initialized, it will return that instance.
/// </summary>
/// <param name="saveFile">The current save file to initialize the debug manager with.</param>
/// <param name="debugLevel">The debug level to initialize the manager with.</param>
/// <returns>The <see cref="DebugManager"/> object that is now initialized.</returns>
public static DebugManager InitializeDebugManager(Save saveFile, DebugLevel debugLevel = DebugLevel.Info) =>
DebugManagerInstance ?? (DebugManagerInstance = new DebugManager(saveFile, debugLevel));
}
}

View file

@ -0,0 +1,26 @@
using System.IO;
using System.Reflection;
namespace ACSE.Core.Utilities
{
public static class PathUtility
{
/// <summary>
/// Gets the path to the current executable.
/// </summary>
/// <returns>The path string of the current executable.</returns>
public static string GetExeLocation() => Assembly.GetEntryAssembly().Location;
/// <summary>
/// Gets the directory of the executable folder.
/// </summary>
/// <returns>The path string of the folder the executable was launched in.</returns>
public static string GetExeDirectory() => Path.GetDirectoryName(GetExeLocation());
/// <summary>
/// Gets the directory of the Resources folder.
/// </summary>
/// <returns>The path string of the Resources folder.</returns>
public static string GetResourcesDirectory() => Path.Combine(GetExeDirectory(), "Resources");
}
}

View file

@ -2,8 +2,9 @@
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using ACSE.Core.Imaging;
namespace ACSE.Utilities
namespace ACSE.Core.Utilities
{
public static class PatternUtility
{

View file

@ -3,8 +3,10 @@
using System.Text;
using System.Globalization;
using System.Text.RegularExpressions;
using ACSE.Core.Debug;
using ACSE.Core.Saves;
namespace ACSE.Utilities
namespace ACSE.Core.Utilities
{
internal static class CharacterSets
{
@ -472,9 +474,6 @@ public AcString(byte[] stringBuffer, SaveType saveType)
if (result >= CharacterSets.DongwuSenlinCharacterSet.Length)
{
System.Windows.Forms.MessageBox.Show(
$"Unknown Dongwu Senlin character encountered: {result:X4}");
String += "?";
}
else
@ -617,10 +616,6 @@ public static byte[] GetBytes(string String, int maxSize = 0)
Array.Resize(ref stringBuffer, maxSize);
return stringBuffer;
}
case SaveType.Unknown:
MainForm.DebugManager.WriteLine(
$"StringUtil was passed an unknown SaveType enum. Received Type: {_saveType.ToString()}", DebugLevel.Error);
return null;
default:
return null;
}

View file

@ -4,8 +4,13 @@
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using ACSE.Core.Acres;
using ACSE.Core.Encryption;
using ACSE.Core.Items;
using ACSE.Core.Saves;
using ACSE.Core.Villagers;
namespace ACSE.Utilities
namespace ACSE.Core.Utilities
{
public static class Utility
{
@ -57,41 +62,11 @@ public static int[] FindLargestMatch(ref List<byte> dictionary, int[] matchesFou
return bestMatch;
}
public static void Scan_For_NL_Int32()
public static Tuple<byte[], bool> FindVillagerHouse(ushort villagerId, WorldAcre[] townAcres) // TODO: Apply to WW
{
if (MainForm.SaveFile == null || MainForm.SaveFile.SaveGeneration != SaveGeneration.N3DS) return;
using (var int32Stream = File.CreateText(MainForm.AssemblyLocation + "\\" +
(MainForm.SaveFile.SaveType == SaveType.WelcomeAmiibo ? "WA_" : "") + "NL_Int32_Database.txt"))
for (var i = 0; i < MainForm.SaveFile.SaveData.Length - 4; i += 4)
{
var possibleNlInt32 = new NewLeafInt32(MainForm.SaveFile.ReadUInt32(i), MainForm.SaveFile.ReadUInt32(i + 4));
if (possibleNlInt32.Valid)
int32Stream.WriteLine(
$"Found Valid NewLeafInt32 at offset 0x{i:X} | Value: {possibleNlInt32.Value}");
}
}
public static Image Set_Image_Color(Image grayscaleImage, ColorMatrix transformMatrix)
{
using (var attributes = new ImageAttributes())
{
attributes.SetColorMatrix(transformMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
var transformedImage = new Bitmap(grayscaleImage.Width, grayscaleImage.Height);
using (var g = Graphics.FromImage(transformedImage))
{
g.DrawImage(grayscaleImage, 0, 0);
g.DrawImage(transformedImage, new Rectangle(0, 0, grayscaleImage.Size.Width, grayscaleImage.Size.Height),
0, 0, grayscaleImage.Size.Width, grayscaleImage.Size.Height, GraphicsUnit.Pixel, attributes);
return transformedImage;
}
}
}
public static Tuple<byte[], bool> Find_Villager_House(ushort villagerId) // TODO: Apply to WW
{
if (MainForm.SaveFile == null) return new Tuple<byte[], bool>(new byte[] {0xFF, 0xFF, 0xFF, 0xFF}, false);
if (Save.SaveInstance == null) return new Tuple<byte[], bool>(new byte[] {0xFF, 0xFF, 0xFF, 0xFF}, false);
var villagerHouseId = (ushort)(0x5000 + (villagerId & 0xFF));
foreach (var acre in MainForm.TownAcres)
foreach (var acre in townAcres)
{
var villagerHouse = acre.AcreItems.FirstOrDefault(o => o.ItemId == villagerHouseId);
if (villagerHouse != null)
@ -104,12 +79,12 @@ public static Tuple<byte[], bool> Find_Villager_House(ushort villagerId) // TODO
return new Tuple<byte[], bool>(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF }, false);
}
public static (byte[], bool) FindVillagerHouseWildWorld(int villagerIndex)
public static (byte[], bool) FindVillagerHouseWildWorld(int villagerIndex, WorldAcre[] townAcres)
{
if (MainForm.SaveFile == null) return (new byte[] {0xFF, 0xFF}, false);
if (Save.SaveInstance == null) return (new byte[] {0xFF, 0xFF}, false);
var houseId = 0x5001 + villagerIndex;
foreach (var acre in MainForm.TownAcres)
foreach (var acre in townAcres)
{
var villagerHouse = acre.AcreItems.FirstOrDefault(o => o.ItemId == houseId);
if (villagerHouse != null)
@ -133,14 +108,14 @@ public static Villager GetVillagerFromHouse(ushort houseId, Villager[] villagers
}
public static bool[] Check_Perfect_Town_Requirements(WorldAcre[] acres, bool makePerfect = false)
public static bool[] CheckPerfectTownRequirements(WorldAcre[] acres, bool makePerfect = false)
{
var acreResults = new bool[acres.Length];
var points = 0;
for (var i = 0; i < acreResults.Length; i++)
{
var acre = acres[i];
switch (MainForm.SaveFile.SaveGeneration)
switch (Save.SaveInstance.SaveGeneration)
{
case SaveGeneration.N64:
case SaveGeneration.GCN:
@ -159,7 +134,7 @@ public static bool[] Check_Perfect_Town_Requirements(WorldAcre[] acres, bool mak
acre.AcreItems[o] = new WorldItem(0, o);
}
}
else if (ItemData.GetItemType(item.ItemId, MainForm.SaveFile.SaveType) == ItemType.Tree)
else if (ItemData.GetItemType(item.ItemId, Save.SaveInstance.SaveType) == ItemType.Tree)
{
treeCount++;
}
@ -173,7 +148,7 @@ public static bool[] Check_Perfect_Town_Requirements(WorldAcre[] acres, bool mak
for (var x = 0; x < 256; x++)
{
if (ItemData.GetItemType(acre.AcreItems[x].ItemId,
MainForm.SaveFile.SaveType) != ItemType.Tree) continue;
Save.SaveInstance.SaveType) != ItemType.Tree) continue;
acre.AcreItems[x] = new WorldItem(0, x);
break;
}
@ -215,10 +190,10 @@ public static bool[] Check_Perfect_Town_Requirements(WorldAcre[] acres, bool mak
return acreResults;
}
public static void Place_Structure(WorldAcre acre, int startIndex, List<ushort[]> structureInfo)
public static void PlaceStructure(WorldAcre acre, int startIndex, List<ushort[]> structureInfo)
{
if (startIndex <= -1 || startIndex >= 256) return;
if (MainForm.SaveFile.SaveGeneration != SaveGeneration.GCN) return;
if (Save.SaveInstance.SaveGeneration != SaveGeneration.GCN) return;
for (var y = 0; y < structureInfo.Count; y++)
{
for (var x = 0; x < structureInfo[y].Length; x++)
@ -269,7 +244,7 @@ public static void FloodFillItemArray(ref Item[] items, int itemsPerRow, int sta
var i = items[idx];
if (i.Equals(originalItem))
{
MainForm.SaveFile.ChangesMade = true;
Save.SaveInstance.ChangesMade = true;
items[idx] = new Item(newItem);
if (p.X - 1 > -1)
locationStack.Push(new Point(p.X - 1, p.Y));
@ -308,7 +283,7 @@ public static void FloodFillWorldItemArray(ref WorldItem[] items, int itemsPerRo
var i = items[idx];
if (i.Equals(originalItem))
{
MainForm.SaveFile.ChangesMade = true;
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));
@ -347,7 +322,7 @@ public static void FloodFillFurnitureArray(ref Furniture[] items, int itemsPerRo
var i = items[idx];
if (i.Equals(originalItem))
{
MainForm.SaveFile.ChangesMade = true;
Save.SaveInstance.ChangesMade = true;
items[idx] = new Furniture(newItem);
if (p.X - 1 > -1)
locationStack.Push(new Point(p.X - 1, p.Y));
@ -362,176 +337,5 @@ public static void FloodFillFurnitureArray(ref Furniture[] items, int itemsPerRo
previousPoints[idx] = 1;
}
}
// Export/Import Methods
public static void ExportAcres(WorldAcre[] acres, SaveGeneration saveGeneration, string saveFileName)
{
using (var saveDialog = new System.Windows.Forms.SaveFileDialog())
{
saveDialog.Filter = "ACSE Acre Save (*.aas)|*.aas";
saveDialog.FileName = saveFileName + " Acre Data.aas";
if (saveDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
try
{
using (var stream = new FileStream(saveDialog.FileName, FileMode.Create))
{
using (var writer = new BinaryWriter(stream))
{
writer.Write(new byte[] { 0x41, 0x41, 0x53 }); // "AAS" Identifier
writer.Write((byte)acres.Length); // Total Acre Count
writer.Write((byte)saveGeneration); // Save Generation
writer.Write(new byte[] { 0, 0, 0 }); // Padding
foreach (var t in acres)
{
writer.Write(BitConverter.GetBytes(t.AcreId));
}
writer.Flush();
}
}
}
catch
{
System.Windows.Forms.MessageBox.Show("Acre exportation failed!", "Acre Export Error", System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
}
}
public static void ImportAcres(ref WorldAcre[] acres, SaveGeneration saveGeneration)
{
using (var openDialog = new System.Windows.Forms.OpenFileDialog())
{
openDialog.Filter = "ACSE Acre Save (*.aas)|*.aas";
openDialog.FileName = "";
if (openDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
try
{
using (var stream = new FileStream(openDialog.FileName, FileMode.Open))
{
using (var reader = new BinaryReader(stream))
{
if (!System.Text.Encoding.ASCII.GetString(reader.ReadBytes(3)).Equals("AAS") ||
reader.ReadByte() != acres.Length ||
(SaveGeneration) reader.ReadByte() != saveGeneration) return;
reader.BaseStream.Seek(8, SeekOrigin.Begin);
foreach (var t in acres)
{
t.AcreId = reader.ReadUInt16();
t.BaseAcreId = (ushort)(t.AcreId & 0xFFFC);
}
}
}
}
catch
{
System.Windows.Forms.MessageBox.Show("Acre importation failed!", "Acre Import Error", System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
}
}
public static void ExportTown(WorldAcre[] acres, SaveGeneration saveGeneration, string saveFileName)
{
using (var saveDialog = new System.Windows.Forms.SaveFileDialog())
{
saveDialog.Filter = "ACSE Town Save (*.ats)|*.ats";
saveDialog.FileName = saveFileName + " Town Data.ats";
if (saveDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
try
{
using (var stream = new FileStream(saveDialog.FileName, FileMode.Create))
{
using (var writer = new BinaryWriter(stream))
{
writer.Write(new byte[] { 0x41, 0x54, 0x53 }); // "ATS" Identifier
writer.Write((byte)acres.Length); // Total Acre Count
writer.Write((byte)saveGeneration); // Save Generation
writer.Write(new byte[] { 0, 0, 0 }); // Padding
if (saveGeneration == SaveGeneration.N3DS)
{
foreach (var acre in acres)
{
foreach (var item in acre.AcreItems)
{
writer.Write(BitConverter.GetBytes(item.ToUInt32()));
}
}
}
else
{
foreach (var acre in acres)
{
foreach (var item in acre.AcreItems)
{
writer.Write(BitConverter.GetBytes(item.ItemId));
}
}
}
writer.Flush();
}
}
}
catch
{
System.Windows.Forms.MessageBox.Show("Town exportation failed!", "Town Export Error", System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
}
}
public static void ImportTown(ref WorldAcre[] acres, SaveGeneration saveGeneration)
{
using (var openDialog = new System.Windows.Forms.OpenFileDialog())
{
openDialog.Filter = "ACSE Town Save (*.ats)|*.ats";
openDialog.FileName = "";
if (openDialog.ShowDialog() != System.Windows.Forms.DialogResult.OK) return;
try
{
using (var stream = new FileStream(openDialog.FileName, FileMode.Open))
{
using (var reader = new BinaryReader(stream))
{
if (!System.Text.Encoding.ASCII.GetString(reader.ReadBytes(3)).Equals("ATS") ||
reader.ReadByte() != acres.Length ||
(SaveGeneration) reader.ReadByte() != saveGeneration) return;
reader.BaseStream.Seek(8, SeekOrigin.Begin);
if (saveGeneration == SaveGeneration.N3DS)
{
foreach (var acre in acres)
{
for (var x = 0; x < acre.AcreItems.Length; x++)
{
acre.AcreItems[x] = new WorldItem(reader.ReadUInt32(), acre.AcreItems[x].Index);
}
}
}
else
{
foreach (var acre in acres)
{
for (var x = 0; x < acre.AcreItems.Length; x++)
{
acre.AcreItems[x] = new WorldItem(reader.ReadUInt16(), acre.AcreItems[x].Index);
}
}
}
}
}
}
catch
{
System.Windows.Forms.MessageBox.Show("Acre importation failed!", "Acre Import Error", System.Windows.Forms.MessageBoxButtons.OK,
System.Windows.Forms.MessageBoxIcon.Error);
}
}
}
}
}

View file

@ -1,9 +1,11 @@
using ACSE.Utilities;
using ACSE.Messages.Mail;
using ACSE.Core.Messages.Mail;
using ACSE.Core.Players;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Villagers.AnimalMemories
{
public abstract class PlayerRelation
public abstract class AnimalMemory
{
public bool Exists;
@ -28,13 +30,13 @@ public abstract class PlayerRelation
public abstract void Write();
}
public class AcPlayerRelation : PlayerRelation
public class AnimalCrossingAnimalMemory : AnimalMemory
{
public byte[] Unknown1;
public byte[] Unknown2;
public byte[] Unknown3;
public AcPlayerRelation(Save saveFile, Villager villager, int dataOffset)
public AnimalCrossingAnimalMemory(Save saveFile, Villager villager, int dataOffset)
{
SaveFile = saveFile;
Villager = villager;

View file

@ -1,6 +1,7 @@
using System;
using ACSE.Core.Saves;
namespace ACSE.Quests
namespace ACSE.Core.Villagers.Quests
{
public enum QuestCategory
{

View file

@ -1,4 +1,6 @@
namespace ACSE
using ACSE.Core.Items;
namespace ACSE.Core.Villagers
{
public class SimpleVillager
{

View file

@ -2,15 +2,19 @@
using System.Linq;
using System.Reflection;
using System.Text;
using ACSE.Utilities;
using ACSE.Core.Items;
using ACSE.Core.Players;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
using ACSE.Core.Villagers.AnimalMemories;
namespace ACSE
namespace ACSE.Core.Villagers
{
public class Villager
{
public VillagerOffsets Offsets;
public VillagerDataStruct Data;
public PlayerRelation[] PlayerRelations;
public AnimalMemory[] AnimalMemories;
public readonly int Index;
public readonly int Offset;
public string Name;
@ -107,10 +111,10 @@ public Villager(int offset, int idx, Save save)
// Create Player Relations;
if (save.SaveType != SaveType.AnimalCrossing) return;
{
PlayerRelations = new PlayerRelation[7];
AnimalMemories = new AnimalMemory[7];
for (var i = 0; i < 7; i++)
{
PlayerRelations[i] = new AcPlayerRelation(save, this, Offset + 0x10 + i * 0x138);
AnimalMemories[i] = new AnimalCrossingAnimalMemory(save, this, Offset + 0x10 + i * 0x138);
}
}
}
@ -130,9 +134,9 @@ public override string ToString()
return Name ?? "Unknown";
}
public PlayerRelation GetPlayerRelation(Player player)
public AnimalMemory GetAnimalMemory(Player player)
{
return PlayerRelations?.First(o => o.PlayerId == player.Data.Identifier && o.PlayerName.Equals(player.Data.Name));
return AnimalMemories?.First(o => o.PlayerId == player.Data.Identifier && o.PlayerName.Equals(player.Data.Name));
}
public void SetDlcVillager(int dlcIndex)
@ -165,7 +169,10 @@ public void Write(string townName)
{
if (Offsets.TownId != -1)
{
Data.TownId = _saveData.ReadUInt16(_saveData.SaveDataStartOffset + MainForm.CurrentSaveInfo.SaveOffsets.TownId, _saveData.IsBigEndian); // Might not be UInt16 in all games
Data.TownId =
_saveData.ReadUInt16(
_saveData.SaveDataStartOffset + Save.SaveInstance.SaveInfo.SaveOffsets.TownId,
_saveData.IsBigEndian); // Might not be UInt16 in all games
}
if (!string.IsNullOrWhiteSpace(townName) && Offsets.TownName != -1)
{
@ -200,7 +207,9 @@ public void Write(string townName)
default:
if (fieldType == typeof(string))
{
_saveData.Write(dataOffset, AcString.GetBytes(dataObject, (int)villagerOffsetData.GetField(field.Name + "Size").GetValue(Offsets)));
_saveData.Write(dataOffset,
AcString.GetBytes(dataObject,
(int) villagerOffsetData.GetField(field.Name + "Size").GetValue(Offsets)));
}
else if (fieldType == typeof(byte[]))
{
@ -244,10 +253,10 @@ public void Write(string townName)
}
}
// Write PlayerRelations
if (Exists && PlayerRelations != null)
// Write AnimalMemories
if (Exists && AnimalMemories != null)
{
foreach (var relation in PlayerRelations)
foreach (var relation in AnimalMemories)
{
if (relation.Exists)
{

View file

@ -2,12 +2,15 @@
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Globalization;
using ACSE.Core.Debug;
using ACSE.Core.Items;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core.Villagers
{
internal class VillagerData
public static class VillagerData
{
public static readonly Dictionary<ushort, string> WaSpecialVillagers = new Dictionary<ushort, string>
{
@ -45,10 +48,11 @@ internal class VillagerData
{0x2010, "Isabelle (2)"}
};
public static BindingSource GetCaravanBindingSource()
public static Dictionary<ushort, SimpleVillager> GetCaravanBindingSource()
{
var waDatabase = VillagerInfo.GetVillagerDatabase(SaveType.WelcomeAmiibo);
if (waDatabase == null) return new BindingSource(WaSpecialVillagers, null);
if (waDatabase == null) return null;
foreach (var v in WaSpecialVillagers)
{
var specialVillager = new SimpleVillager
@ -59,7 +63,7 @@ public static BindingSource GetCaravanBindingSource()
waDatabase.Add(v.Key, specialVillager);
}
return new BindingSource(waDatabase, null);
return waDatabase;
}
}
@ -325,7 +329,7 @@ public static Dictionary<ushort, SimpleVillager> GetVillagerDatabase(SaveType sa
{
var database = new Dictionary<ushort, SimpleVillager>();
StreamReader contents;
var databaseFilename = MainForm.AssemblyLocation + "\\Resources\\{0}_Villagers_" + language + ".txt";
var databaseFilename = "{0}_Villagers_" + language + ".txt";
switch (saveType)
{
case SaveType.DoubutsuNoMori:
@ -357,14 +361,17 @@ public static Dictionary<ushort, SimpleVillager> GetVillagerDatabase(SaveType sa
throw new ArgumentOutOfRangeException(nameof(saveType), saveType, null);
}
databaseFilename = Path.Combine(PathUtility.GetResourcesDirectory(), databaseFilename);
try
{
contents = File.OpenText(databaseFilename);
}
catch (Exception e)
{
MessageBox.Show(
$"An error occured opening villager database file:\n\"{databaseFilename}\"\nError Info:\n{e.Message}");
DebugUtility.DebugManagerInstance.WriteLine(
$"An error occured opening villager database file:\n\"{databaseFilename}\"\nError Info:\n{e.Message}",
DebugLevel.Error);
return null;
}

View file

@ -1,4 +1,6 @@
namespace ACSE
using ACSE.Core.Saves;
namespace ACSE.Core.Weather
{
public static class Weather
{
@ -36,7 +38,9 @@ public static byte ToWeatherByte(byte index, SaveGeneration generation)
{
case SaveGeneration.N64:
case SaveGeneration.GCN:
return (byte)((MainForm.SaveFile.ReadByte(MainForm.SaveFile.SaveDataStartOffset + MainForm.SaveFile.SaveInfo.SaveOffsets.Weather) & 0x0F) | (index << 4));
return (byte) ((Save.SaveInstance.ReadByte(
Save.SaveInstance.SaveDataStartOffset +
Save.SaveInstance.SaveInfo.SaveOffsets.Weather) & 0x0F) | (index << 4));
default:
return index;
}
@ -46,13 +50,6 @@ public static bool UpdateWeather(Save saveFile, byte index)
{
if (saveFile.SaveGeneration != SaveGeneration.N64 && saveFile.SaveGeneration != SaveGeneration.GCN)
return false;
if (saveFile.SaveType != SaveType.DoubutsuNoMoriEPlus && saveFile.SaveType != SaveType.AnimalForestEPlus
&& index == 4 && System.Windows.Forms.MessageBox.Show(
"Setting the Weather to Fall Leaves will cause glitches, and will crash your game if you run."
+ "Are you sure you want to change the weather to it?", "Weather Warning",
System.Windows.Forms.MessageBoxButtons.YesNo,
System.Windows.Forms.MessageBoxIcon.Question) !=
System.Windows.Forms.DialogResult.Yes) return false;
saveFile.Write(saveFile.SaveDataStartOffset + saveFile.SaveInfo.SaveOffsets.Weather, ToWeatherByte(index, saveFile.SaveGeneration));
return true;
}

View file

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using ACSE.Utilities;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.Core
{
public static class Yaz0
{

File diff suppressed because it is too large Load diff

View file

Before

Width:  |  Height:  |  Size: 361 KiB

After

Width:  |  Height:  |  Size: 361 KiB

View file

@ -1,4 +1,4 @@
namespace ACSE
namespace ACSE.WinForms
{
partial class AboutBox
{

View file

@ -2,9 +2,9 @@
using System.Reflection;
using System.Windows.Forms;
namespace ACSE
namespace ACSE.WinForms
{
partial class AboutBox : Form
public partial class AboutBox : Form
{
public AboutBox()
{

42
ACSE.WinForms/App.config Normal file
View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="ACSE.WinForms.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
</startup>
<userSettings>
<ACSE.WinForms.Properties.Settings>
<setting name="DebuggingEnabled" serializeAs="String">
<value>True</value>
</setting>
<setting name="ImageResizeMode" serializeAs="String">
<value>5</value>
</setting>
<setting name="DebugLevel" serializeAs="String">
<value>2</value>
</setting>
<setting name="TownMapSize" serializeAs="String">
<value>256</value>
</setting>
<setting name="AcreMapSize" serializeAs="String">
<value>96</value>
</setting>
<setting name="ShowDumpAcreWarning" serializeAs="String">
<value>True</value>
</setting>
<setting name="ShowBetaAcreWarning" serializeAs="String">
<value>True</value>
</setting>
<setting name="BackupFiles" serializeAs="String">
<value>True</value>
</setting>
<setting name="BackupLocation" serializeAs="String">
<value />
</setting>
</ACSE.WinForms.Properties.Settings>
</userSettings>
</configuration>

View file

@ -3,10 +3,13 @@
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using ACSE.Core.Debug;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.WinForms.Backups
{
public class Backup
public sealed class Backup
{
private readonly Save _save;
@ -35,7 +38,7 @@ private static string GetBackupLocation()
}
catch
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"The requested backup path {Properties.Settings.Default.BackupLocation} couldn't be accessed!\n" +
"The backup folder was reset to the default in ApplicationData/ACSE/Backups/!");
Properties.Settings.Default.BackupLocation = "";
@ -97,13 +100,13 @@ public bool CreateBackup()
using (var backupFile = File.Create(saveLocation))
{
backupFile.Write(_save.SaveData, 0, _save.SaveData.Length);
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"Save File {_save.SaveName} was backuped to {backupLocation}");
}
}
catch
{
MainForm.DebugManager.WriteLine(
DebugUtility.DebugManagerInstance.WriteLine(
$"Failed to create backup for save {_save.SaveName} at {backupLocation}", DebugLevel.Error);
return false;
}

View file

@ -1,10 +1,12 @@
using System;
using System.Drawing;
using System.Windows.Forms;
using ACSE.Core.Encryption;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.WinForms.Controls
{
public class BadgeControl : OffsetablePictureBox
public sealed class BadgeControl : OffsetablePictureBox
{
private static readonly Bitmap BadgeImage = Properties.Resources.Animal_Crossing_NL_Badges_28x28;
private static readonly Bitmap NoBadgeImage = Properties.Resources.Animal_Crossing_NL_NoBadge_28x28;

View file

@ -2,8 +2,11 @@
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ACSE.Core.Items;
using ACSE.Core.Utilities;
using ACSE.WinForms.Imaging;
namespace ACSE
namespace ACSE.WinForms.Controls
{
internal sealed class FurnitureItemEditor : ItemEditor
{
@ -70,7 +73,7 @@ protected override void OnEditorMouseDown(object sender, MouseEventArgs e)
break;
case MouseButtons.Middle:
var tempItems = (Furniture[]) Items;
Utilities.Utility.FloodFillFurnitureArray(ref tempItems, ItemsPerRow, index,
Utility.FloodFillFurnitureArray(ref tempItems, ItemsPerRow, index,
(Furniture) Items[index], new Furniture(MainFormReference.GetCurrentItem()));
Items = tempItems;
break;

View file

@ -1,12 +1,15 @@
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ACSE.Core.Housing;
using ACSE.Core.Saves;
using ItemChangedEventArgs = ACSE.Core.Items.ItemChangedEventArgs;
namespace ACSE
namespace ACSE.WinForms.Controls
{
/// <inheritdoc/>
/// <summary>
/// An all-in-one Control for editing <see cref="ACSE.House"/> objects.
/// An all-in-one Control for editing <see cref="Core.Housing.House"/> objects.
/// </summary>
internal sealed class HouseControl : FlowLayoutPanel
{

View file

@ -3,8 +3,11 @@
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ACSE.Core.Items;
using ACSE.Core.Modifiable;
using ACSE.Core.Utilities;
namespace ACSE
namespace ACSE.WinForms.Controls
{
/// <inheritdoc cref="IModifiable" />
/// <summary>
@ -185,7 +188,7 @@ protected virtual void OnEditorMouseDown(object sender, MouseEventArgs e)
MainFormReference.SetCurrentItem(selectedItem);
break;
case MouseButtons.Middle:
Utilities.Utility.FloodFillItemArray(ref _items, ItemsPerRow, index, _items[index],
Utility.FloodFillItemArray(ref _items, ItemsPerRow, index, _items[index],
MainFormReference.GetCurrentItem());
SetItemPicture();
break;

View file

@ -2,7 +2,7 @@
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ACSE
namespace ACSE.WinForms.Controls
{
public enum MaskingType
{

View file

@ -1,7 +1,7 @@
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace ACSE
namespace ACSE.WinForms.Controls
{
/// <inheritdoc />
/// <summary>

View file

@ -1,8 +1,9 @@
using System.Windows.Forms;
using ACSE.Core.Items;
namespace ACSE
namespace ACSE.WinForms.Controls
{
class ShopEditorControl : Panel
public class ShopEditorControl : Panel
{
protected ItemEditor ShopEditor;
protected Label ShopLabel;

View file

@ -1,4 +1,4 @@
namespace ACSE
namespace ACSE.WinForms.Controls
{
partial class SingleItemEditor
{

View file

@ -3,8 +3,11 @@
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ACSE.Core.Items;
using ACSE.Core.Modifiable;
using ItemChangedEventArgs = ACSE.Core.Items.ItemChangedEventArgs;
namespace ACSE
namespace ACSE.WinForms.Controls
{
/// <inheritdoc cref="IModifiable" />
/// <summary>

View file

@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using ACSE.Core.Encryption;
using ACSE.Core.Saves;
namespace ACSE
namespace ACSE.WinForms.Controls
{
internal sealed class StalkMarketEditor : FlowLayoutPanel
{

View file

@ -3,9 +3,14 @@
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using ACSE.Utilities;
using ACSE.Core;
using ACSE.Core.Items;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
using ACSE.Core.Villagers;
using ItemChangedEventArgs = ACSE.Core.Items.ItemChangedEventArgs;
namespace ACSE.Controls
namespace ACSE.WinForms.Controls
{
/// <inheritdoc/>
/// <summary>
@ -261,9 +266,11 @@ private void VillagerSelectionBoxChanged()
else
{
// TODO: Update islander house location. In e+, update all four islander house locations.
// TODO: Remove the static reference to MainForm.TownAcres.
if (_saveFile.SaveGeneration != SaveGeneration.GCN || _villager.Index < 15)
{
var houseCoordinatesInfo = Utility.Find_Villager_House(_villager.Data.VillagerId);
var houseCoordinatesInfo =
Utility.FindVillagerHouse(_villager.Data.VillagerId, MainForm.TownAcres);
_villager.Data.HouseCoordinates = houseCoordinatesInfo.Item1;
if (!houseCoordinatesInfo.Item2)
{
@ -281,7 +288,8 @@ private void VillagerSelectionBoxChanged()
}
else
{
var (houseCoordinates, found) = Utility.FindVillagerHouseWildWorld(_villager.Index);
var (houseCoordinates, found) =
Utility.FindVillagerHouseWildWorld(_villager.Index, MainForm.TownAcres);
_villager.Data.HouseCoordinates = houseCoordinates;
if (!found)
{

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<Costura />
</Weavers>

View file

@ -6,8 +6,15 @@
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using ACSE.Core.Buildings;
using ACSE.Core.Debug;
using ACSE.Core.Items;
using ACSE.Core.Players;
using ACSE.Core.Saves;
using ACSE.Core.Villagers;
using ACSE.WinForms.Controls;
namespace ACSE
namespace ACSE.WinForms.Imaging
{
public static class ImageGeneration
{
@ -51,6 +58,22 @@ private static void ReplaceGrayscaleColor(ref Bitmap editingImage, Color replaci
}
}
public static Image SetImageColor(Image grayscaleImage, ColorMatrix transformMatrix)
{
using (var attributes = new ImageAttributes())
{
attributes.SetColorMatrix(transformMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
var transformedImage = new Bitmap(grayscaleImage.Width, grayscaleImage.Height);
using (var g = Graphics.FromImage(transformedImage))
{
g.DrawImage(grayscaleImage, 0, 0);
g.DrawImage(transformedImage, new Rectangle(0, 0, grayscaleImage.Size.Width, grayscaleImage.Size.Height),
0, 0, grayscaleImage.Size.Width, grayscaleImage.Size.Height, GraphicsUnit.Pixel, attributes);
return transformedImage;
}
}
}
public static void DrawBuriedIcons(Bitmap map, WorldItem[] items, int itemSize)
{
using (var bitmapGraphics = Graphics.FromImage(map))

View file

@ -1,4 +1,4 @@
namespace ACSE
namespace ACSE.WinForms
{
partial class ItemColorEditor
{

View file

@ -1,8 +1,10 @@
using System.Collections.Generic;
using System.Configuration;
using System.Drawing;
using System.Windows.Forms;
using ACSE.Core.Items;
namespace ACSE
namespace ACSE.WinForms
{
public partial class ItemColorEditor : Form
{
@ -11,6 +13,7 @@ public partial class ItemColorEditor : Form
public ItemColorEditor()
{
InitializeComponent();
UpdateItemColors(); // Initialize at the start
CreateEditorControls();
}
@ -109,9 +112,23 @@ private static void SetColor(Control colorPreview, uint newColor)
colorPreview.BackColor = Color.FromArgb((int)newColor);
}
// TODO: I don't like this at all. Come up with a better way. Possibly expose the colors from ACSE.Core instead.
public static void UpdateItemColors()
{
var database = new Dictionary<string, uint>();
foreach (SettingsProperty prop in ItemColorSettings.Default.Properties)
{
database.Add(prop.Name, (uint) ItemColorSettings.Default[prop.Name]);
}
ItemData.ItemColorsSettings = database;
}
private void Done()
{
ItemColorSettings.Default.Save();
UpdateItemColors();
Close();
Dispose();
}

View file

@ -0,0 +1,410 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ACSE {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
internal sealed partial class ItemColorSettings : global::System.Configuration.ApplicationSettingsBase {
private static ItemColorSettings defaultInstance = ((ItemColorSettings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new ItemColorSettings())));
public static ItemColorSettings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3359432240")]
public uint FurnitureColor {
get {
return ((uint)(this["FurnitureColor"]));
}
set {
this["FurnitureColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3369370404")]
public uint GyroidColor {
get {
return ((uint)(this["GyroidColor"]));
}
set {
this["GyroidColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3372155007")]
public uint DiaryColor {
get {
return ((uint)(this["DiaryColor"]));
}
set {
this["DiaryColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3358094506")]
public uint ClothesColor {
get {
return ((uint)(this["ClothesColor"]));
}
set {
this["ClothesColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3366251704")]
public uint SongColor {
get {
return ((uint)(this["SongColor"]));
}
set {
this["SongColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3366251752")]
public uint PaperColor {
get {
return ((uint)(this["PaperColor"]));
}
set {
this["PaperColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3361041199")]
public uint TrashColor {
get {
return ((uint)(this["TrashColor"]));
}
set {
this["TrashColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3372204235")]
public uint ShellColor {
get {
return ((uint)(this["ShellColor"]));
}
set {
this["ShellColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3369967837")]
public uint FruitColor {
get {
return ((uint)(this["FruitColor"]));
}
set {
this["FruitColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3367742621")]
public uint TurnipColor {
get {
return ((uint)(this["TurnipColor"]));
}
set {
this["TurnipColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3367691070")]
public uint CatchableColor {
get {
return ((uint)(this["CatchableColor"]));
}
set {
this["CatchableColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3367876459")]
public uint QuestItemColor {
get {
return ((uint)(this["QuestItemColor"]));
}
set {
this["QuestItemColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3372197120")]
public uint ItemColor {
get {
return ((uint)(this["ItemColor"]));
}
set {
this["ItemColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3357446399")]
public uint RaffleTicketColor {
get {
return ((uint)(this["RaffleTicketColor"]));
}
set {
this["RaffleTicketColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3365486656")]
public uint WallpaperCarpetColor {
get {
return ((uint)(this["WallpaperCarpetColor"]));
}
set {
this["WallpaperCarpetColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3360767279")]
public uint FossilColor {
get {
return ((uint)(this["FossilColor"]));
}
set {
this["FossilColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3363930497")]
public uint ToolColor {
get {
return ((uint)(this["ToolColor"]));
}
set {
this["ToolColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3364570387")]
public uint TreeColor {
get {
return ((uint)(this["TreeColor"]));
}
set {
this["TreeColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3355475968")]
public uint WeedColor {
get {
return ((uint)(this["WeedColor"]));
}
set {
this["WeedColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3370936248")]
public uint FlowerColor {
get {
return ((uint)(this["FlowerColor"]));
}
set {
this["FlowerColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3355443200")]
public uint RockColor {
get {
return ((uint)(this["RockColor"]));
}
set {
this["RockColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3366137647")]
public uint MoneyRockColor {
get {
return ((uint)(this["MoneyRockColor"]));
}
set {
this["MoneyRockColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3362140928")]
public uint SignboardColor {
get {
return ((uint)(this["SignboardColor"]));
}
set {
this["SignboardColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3372220160")]
public uint MoneyColor {
get {
return ((uint)(this["MoneyColor"]));
}
set {
this["MoneyColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3366295701")]
public uint HouseObjectColor {
get {
return ((uint)(this["HouseObjectColor"]));
}
set {
this["HouseObjectColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("4286019447")]
public uint BuildingColor {
get {
return ((uint)(this["BuildingColor"]));
}
set {
this["BuildingColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3366151936")]
public uint ParchedFlowerColor {
get {
return ((uint)(this["ParchedFlowerColor"]));
}
set {
this["ParchedFlowerColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3355484320")]
public uint WateredFlowerColor {
get {
return ((uint)(this["WateredFlowerColor"]));
}
set {
this["WateredFlowerColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3365509631")]
public uint PatternColor {
get {
return ((uint)(this["PatternColor"]));
}
set {
this["PatternColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3360509235")]
public uint WiltedFlowerColor {
get {
return ((uint)(this["WiltedFlowerColor"]));
}
set {
this["WiltedFlowerColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3717831065")]
public uint OccupiedColor {
get {
return ((uint)(this["OccupiedColor"]));
}
set {
this["OccupiedColor"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("3372154880")]
public uint InvalidColor {
get {
return ((uint)(this["InvalidColor"]));
}
set {
this["InvalidColor"] = value;
}
}
}
}

View file

@ -0,0 +1,102 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="ACSE" GeneratedClassName="ItemColorSettings">
<Profiles />
<Settings>
<Setting Name="FurnitureColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3359432240</Value>
</Setting>
<Setting Name="GyroidColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3369370404</Value>
</Setting>
<Setting Name="DiaryColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3372155007</Value>
</Setting>
<Setting Name="ClothesColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3358094506</Value>
</Setting>
<Setting Name="SongColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3366251704</Value>
</Setting>
<Setting Name="PaperColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3366251752</Value>
</Setting>
<Setting Name="TrashColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3361041199</Value>
</Setting>
<Setting Name="ShellColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3372204235</Value>
</Setting>
<Setting Name="FruitColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3369967837</Value>
</Setting>
<Setting Name="TurnipColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3367742621</Value>
</Setting>
<Setting Name="CatchableColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3367691070</Value>
</Setting>
<Setting Name="QuestItemColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3367876459</Value>
</Setting>
<Setting Name="ItemColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3372197120</Value>
</Setting>
<Setting Name="RaffleTicketColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3357446399</Value>
</Setting>
<Setting Name="WallpaperCarpetColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3365486656</Value>
</Setting>
<Setting Name="FossilColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3360767279</Value>
</Setting>
<Setting Name="ToolColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3363930497</Value>
</Setting>
<Setting Name="TreeColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3364570387</Value>
</Setting>
<Setting Name="WeedColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3355475968</Value>
</Setting>
<Setting Name="FlowerColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3370936248</Value>
</Setting>
<Setting Name="RockColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3355443200</Value>
</Setting>
<Setting Name="MoneyRockColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3366137647</Value>
</Setting>
<Setting Name="SignboardColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3362140928</Value>
</Setting>
<Setting Name="MoneyColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3372220160</Value>
</Setting>
<Setting Name="HouseObjectColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3366295701</Value>
</Setting>
<Setting Name="BuildingColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">4286019447</Value>
</Setting>
<Setting Name="ParchedFlowerColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3366151936</Value>
</Setting>
<Setting Name="WateredFlowerColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3355484320</Value>
</Setting>
<Setting Name="PatternColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3365509631</Value>
</Setting>
<Setting Name="WiltedFlowerColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3360509235</Value>
</Setting>
<Setting Name="OccupiedColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3717831065</Value>
</Setting>
<Setting Name="InvalidColor" Type="System.UInt32" Scope="User">
<Value Profile="(Default)">3372154880</Value>
</Setting>
</Settings>
</SettingsFile>

View file

@ -1,4 +1,6 @@
namespace ACSE
using ACSE.WinForms.Controls;
namespace ACSE.WinForms
{
sealed partial class MainForm
{
@ -37,7 +39,7 @@ private void InitializeComponent()
this.palettePreviousButton = new System.Windows.Forms.Button();
this.paletteNextButton = new System.Windows.Forms.Button();
this.patternEditorPanel = new System.Windows.Forms.Panel();
this.patternEditorPictureBox = new ACSE.PictureBoxWithInterpolationMode();
this.patternEditorPictureBox = new PictureBoxWithInterpolationMode();
this.patternEditorPreviewPanel = new System.Windows.Forms.Panel();
this.patternGroupTabControl = new System.Windows.Forms.TabControl();
this.player1Tab = new System.Windows.Forms.TabPage();
@ -344,7 +346,7 @@ private void InitializeComponent()
// paletteColorSelectedPictureBox
//
this.paletteColorSelectedPictureBox.Anchor = System.Windows.Forms.AnchorStyles.None;
this.paletteColorSelectedPictureBox.Image = global::ACSE.Properties.Resources.PaletteArrow;
this.paletteColorSelectedPictureBox.Image = global::ACSE.WinForms.Properties.Resources.PaletteArrow;
this.paletteColorSelectedPictureBox.Location = new System.Drawing.Point(114, 21);
this.paletteColorSelectedPictureBox.Name = "paletteColorSelectedPictureBox";
this.paletteColorSelectedPictureBox.Size = new System.Drawing.Size(16, 32);
@ -975,7 +977,7 @@ private void InitializeComponent()
this.clearEncylopediaButton.TabIndex = 5;
this.clearEncylopediaButton.Text = "Clear Encyclopedia";
this.clearEncylopediaButton.UseVisualStyleBackColor = true;
this.clearEncylopediaButton.Click += new System.EventHandler(this.ClearEncylopediaButtonClick);
this.clearEncylopediaButton.Click += new System.EventHandler(this.ClearEncyclopediaButtonClick);
//
// fillEncyclopediaButton
//

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,15 @@
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using ACSE.Core.Saves;
using ACSE.Core.Utilities;
using ACSE.WinForms.Controls;
namespace ACSE
namespace ACSE.WinForms.Managers
{
// TODO: Check if any references to the Image exist, and if not, dispose of them.
public static class AcreData
public static class AcreImageManager
{
private static Dictionary<ushort, Image> _loadedImageDictionary = new Dictionary<ushort, Image>();
private static Dictionary<byte, Image> _loadedAnimalCrossingMapIcons = new Dictionary<byte, Image>();
@ -34,7 +36,7 @@ public static Image FetchAcreImage(SaveType saveType, ushort acreId)
Image result = null;
var imageDir = MainForm.AssemblyLocation + "\\Resources\\Images\\";
var imageDir = Path.Combine(PathUtility.GetResourcesDirectory(), "Images");
switch (saveType)
{
case SaveType.DoubutsuNoMori:
@ -44,19 +46,19 @@ public static Image FetchAcreImage(SaveType saveType, ushort acreId)
case SaveType.AnimalForestEPlus:
// TODO: DnM needs its own set?
case SaveType.DongwuSenlin:
imageDir += "Acre_Images";
imageDir = Path.Combine(imageDir, "Acre_Images");
break;
case SaveType.WildWorld:
imageDir += "WW_Acre_Images";
imageDir = Path.Combine(imageDir, "WW_Acre_Images");
break;
case SaveType.CityFolk:
imageDir += "CF_Acre_Images";
imageDir = Path.Combine(imageDir, "CF_Acre_Images");
break;
case SaveType.NewLeaf:
imageDir += "NL_Acre_Images";
imageDir = Path.Combine(imageDir, "NL_Acre_Images");
break;
case SaveType.WelcomeAmiibo:
imageDir += "WA_Acre_Images";
imageDir = Path.Combine(imageDir, "WA_Acre_Images");
break;
default:
return null;
@ -110,7 +112,7 @@ public static Image FetchAcMapIcon(byte index)
Image result = null;
var iconDirectory = MainForm.AssemblyLocation + "\\Resources\\Images\\AC_Map_Icons";
var iconDirectory = Path.Combine(PathUtility.GetResourcesDirectory(), "Images", "AC_Map_Icons");
if (Directory.Exists(iconDirectory))
{
foreach (var iconFile in Directory.GetFiles(iconDirectory))
@ -134,10 +136,12 @@ public static Image FetchAcMapIcon(byte index)
return result;
}
public static void CheckReferencesAndDispose(Image referencedImage, PictureBoxWithInterpolationMode[] pictureBoxes, PictureBoxWithInterpolationMode selectedAcreBox)
public static void CheckReferencesAndDispose(Image referencedImage,
PictureBoxWithInterpolationMode[] pictureBoxes, PictureBoxWithInterpolationMode selectedAcreBox)
{
if (referencedImage == null || selectedAcreBox.Image == referencedImage
|| pictureBoxes.Any(box => box != null && box.BackgroundImage == referencedImage)) return;
|| pictureBoxes.Any(
box => box != null && box.BackgroundImage == referencedImage)) return;
foreach (var pair in _loadedImageDictionary)
if (pair.Value == referencedImage)
@ -172,20 +176,20 @@ public static void DisposeLoadedImages()
_loadedAnimalCrossingMapIcons = new Dictionary<byte, Image>();
}
public static Dictionary<ushort, byte> Load_AC_Map_Index(SaveType saveType)
public static Dictionary<ushort, byte> LoadAcMapIndex(SaveType saveType)
{
var indexFile = MainForm.AssemblyLocation;
var indexFile = PathUtility.GetResourcesDirectory();
switch (saveType)
{
case SaveType.DoubutsuNoMori:
case SaveType.DoubutsuNoMoriPlus:
case SaveType.DongwuSenlin:
indexFile += "\\Resources\\DnM_Map_Icon_Index.txt";
indexFile = Path.Combine(indexFile, "DnM_Map_Icon_Index.txt");
break;
case SaveType.AnimalCrossing:
case SaveType.DoubutsuNoMoriEPlus:
case SaveType.AnimalForestEPlus:
indexFile += "\\Resources\\AC_Map_Icon_Index.txt";
indexFile = Path.Combine(indexFile, "AC_Map_Icon_Index.txt");
break;
}
@ -200,7 +204,9 @@ public static Dictionary<ushort, byte> Load_AC_Map_Index(SaveType saveType)
{
if (!line.Contains("0x")) continue;
string acreIdStr = line.Substring(0, 6).Replace("0x", ""), indexStr = line.Substring(7).Trim();
if (ushort.TryParse(acreIdStr, NumberStyles.AllowHexSpecifier, null, out var acreId) && byte.TryParse(indexStr, out var index))
if (ushort.TryParse(acreIdStr, NumberStyles.AllowHexSpecifier, null, out var acreId) &&
byte.TryParse(indexStr, out var index))
{
iconIndex.Add(acreId, index);
}

View file

@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ACSE
namespace ACSE.WinForms
{
static class Program
{
@ -13,8 +16,7 @@ static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
}
}

View file

@ -2,7 +2,7 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ACSE")]
@ -14,25 +14,23 @@
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("52b2adb4-812e-4b42-9955-9e8f1f14dbea")]
[assembly: Guid("b4a73545-0177-4159-8602-648aa3058650")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.4.1.0")]
[assembly: AssemblyFileVersion("0.4.1.0")]
[assembly: InternalsVisibleTo("ACSE.Tests")]

Some files were not shown because too many files have changed in this diff Show more