Files
2024-06-02 18:56:55 -05:00

917 lines
31 KiB
C#

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using pk3DS.Core;
using pk3DS.Core.CTR;
namespace pk3DS.WinForms;
public sealed partial class OWSE : Form
{
public OWSE()
{
InitializeComponent();
// Script Drag&Drop
AllowDrop = true;
DragEnter += TabMain_DragEnter;
DragDrop += TabMain_DragDrop;
// Finished
OpenQuick(Directory.GetFiles("encdata"));
mapView.Show();
tb_Zone.SelectedIndex = 1; // Show Overworlds tab
}
private readonly string[] gameLocations = Main.Config.GetText(TextName.metlist_000000);
private string[] filepaths;
private string[] encdatapaths;
private byte[] masterZoneData;
private bool debugToolDumping;
// Generated Storage
private string[] zdLocations;
private string[] rawLocations;
private byte[][] locationData;
// Map Viewer References
internal static Zone CurrentZone;
internal static MapMatrix mm;
private readonly MapPermView mapView = new();
private void OpenQuick(string[] encdata)
{
// Gather
encdatapaths = encdata;
Array.Sort(encdatapaths);
filepaths = encdatapaths.Skip(Main.Config.ORAS ? 2 : 1).Take(encdatapaths.Length - (Main.Config.ORAS ? 2 : 1)).ToArray();
masterZoneData = File.ReadAllBytes(encdatapaths[0]);
zdLocations = new string[filepaths.Length];
rawLocations = new string[filepaths.Length];
tb_File5.Visible = Main.Config.ORAS; // 5th File is only present with OR/AS.
// Analyze
for (int f = 0; f < filepaths.Length; f++)
{
string name = Path.GetFileNameWithoutExtension(filepaths[f]);
int LocationNum = Convert.ToInt16(name[4..]);
var zo = new ZoneData(masterZoneData.Skip(f * ZoneData.Size).Take(ZoneData.Size).ToArray());
string LocationName = gameLocations[zo.ParentMap];
zdLocations[f] = LocationNum.ToString("000") + " - " + LocationName;
rawLocations[f] = LocationName;
}
// Assign
CB_LocationID.DataSource = zdLocations;
CB_LocationID.Enabled = true;
CB_LocationID_SelectedIndexChanged(null, null);
NUD_WMap.Maximum = zdLocations.Length; // Cap map warp destinations to the amount of maps.
}
private void B_Map_Click(object sender, EventArgs e)
{
if (!mapView.Visible)
mapView.Show();
}
private void ClosingForm(object sender, FormClosingEventArgs e)
{
// Close map view
mapView.Close();
mapView.Dispose();
}
private void CB_LocationID_SelectedIndexChanged(object sender, EventArgs e)
{
SetEntry();
entry = CB_LocationID.SelectedIndex;
GetEntry();
}
private void GetEntry()
{
if (entry < 0) return;
byte[] raw = File.ReadAllBytes(filepaths[entry]);
locationData = Mini.UnpackMini(raw, "ZO");
if (locationData == null) return;
// Read master ZD table
byte[] zd = masterZoneData.Skip(ZoneData.Size * entry).Take(ZoneData.Size).ToArray();
RTB_ZDMaster.Lines = Scripts.GetHexLines(zd, 0x10);
// Load from location Data.
CurrentZone = new Zone(locationData);
// File 0 - ZoneData
RTB_ZD.Lines = Scripts.GetHexLines(locationData[0], 0x10);
GetZoneData();
// File 1 - Overworld Setup & Script
RTB_OWSC.Lines = Scripts.GetHexLines(locationData[1], 0x10);
GetOWSData();
// File 2 - Map Script
RTB_MapSC.Lines = Scripts.GetHexLines(locationData[2], 0x10);
GetScriptData();
// File 3 - Encounters
RTB_Encounter.Lines = Scripts.GetHexLines(locationData[3], 0x10);
// File 4 - ?? (ORAS Only?)
RTB_File5.Lines = Scripts.GetHexLines(locationData.Length <= 4 ? null : locationData[4], 0x10);
}
private void SetEntry()
{
if (entry < 0) return;
if (debugToolDumping) return;
// Set the data back into the class object
// Currently only the first two files.
SetZoneData(); // File 0
SetOWSData();
// setMSData();
// setEncounterData();
// if (Main.Config.ORAS)
// setUnknown();
// Reassemble files
byte[][] data = CurrentZone.Write();
// Debug Check (can stay, why not.)
if (!locationData.Where((t, i) => !data[i].SequenceEqual(t)).Any())
return;
// Util.Alert("Zone has been edited!");
System.Media.SystemSounds.Asterisk.Play();
// Package the files into the permanent package file.
byte[] raw = Mini.PackMini(data, "ZO");
File.WriteAllBytes(filepaths[entry], raw);
}
// Loading of Data
private void GetZoneData()
{
L_ZDPreview.Text = "Text File: " + CurrentZone.ZD.TextFile
+ Environment.NewLine + "Map File: " + CurrentZone.ZD.MapMatrix;
L_ZD.Text = string.Format("X: {0,5}{3}Y: {1,5}{3}Z:{2,6}{3}{3}X: {4,5}{3}Y: {5,5}{3}Z:{6,6}", CurrentZone.ZD.PX, CurrentZone.ZD.PY,
CurrentZone.ZD.Z, Environment.NewLine, CurrentZone.ZD.PX2, CurrentZone.ZD.PY2,
CurrentZone.ZD.Z2);
if (Math.Abs(CurrentZone.ZD.PX - CurrentZone.ZD.PX2) > 0.01
|| Math.Abs(CurrentZone.ZD.PY - CurrentZone.ZD.PY2) > 0.01
|| CurrentZone.ZD.Z != CurrentZone.ZD.Z2)
{
L_ZD.Text += Environment.NewLine + "COORDINATE MISMATCH";
}
// Fetch Map Image
mapView.SetMap(CurrentZone.ZD.MapMatrix);
}
private void GetOWSData()
{
// Reset Fields a little.
RTB_F.Text = RTB_N.Text = RTB_W.Text = RTB_T1.Text = RTB_T2.Text = string.Empty;
fEntry = nEntry = wEntry = tEntry = uEntry = -1;
// Set Counters
NUD_FurnCount.Value = CurrentZone.Entities.FurnitureCount; ChangeFurnitureCount(null, null);
NUD_NPCCount.Value = CurrentZone.Entities.NPCCount; ChangeNPCCount(null, null);
NUD_WarpCount.Value = CurrentZone.Entities.WarpCount; ChangeWarpCount(null, null);
NUD_TrigCount.Value = CurrentZone.Entities.TriggerCount; ChangeTriggerCount(null, null);
NUD_UnkCount.Value = CurrentZone.Entities.UnknownCount; ChangeUnkCount(null, null);
// Collect/Load Data
NUD_FE.Value = NUD_FE.Maximum < 0 ? -1 : 0; ChangeFurniture(null, null);
NUD_NE.Value = NUD_NE.Maximum < 0 ? -1 : 0; ChangeNPC(null, null);
NUD_WE.Value = NUD_WE.Maximum < 0 ? -1 : 0; ChangeWarp(null, null);
NUD_TE.Value = NUD_TE.Maximum < 0 ? -1 : 0; ChangeTrigger1(null, null);
NUD_UE.Value = NUD_UE.Maximum < 0 ? -1 : 0; ChangeTrigger2(null, null);
// Process Scripts
var script = CurrentZone.Entities.Script;
if (script.Raw.Length > 4)
{
RTB_OS.Lines = Scripts.GetHexLines(script.Raw);
L_OWSCDesc.Text = script.Info;
uint[] Instructions = script.DecompressedInstructions;
RTB_OWSCMD.Lines = Scripts.GetHexLines(Instructions);
if (script.DecompressedLength / 4 != Instructions.Length)
RTB_OWSCMD.Text = RTB_OSP.Text = "DCMP FAIL";
else
RTB_OSP.Lines = [.. script.ParseScript, .. script.ParseMoves];
}
else
{
RTB_OWSCMD.Lines = RTB_OS.Lines = ["No Data"];
}
}
private void GetScriptData()
{
var script = CurrentZone.MapScript.Script;
if (script.Raw.Length > 4)
{
RTB_MS.Lines = Scripts.GetHexLines(script.Raw);
L_MSSCDesc.Text = script.Info;
uint[] Instructions = script.DecompressedInstructions;
RTB_MSCMD.Lines = Scripts.GetHexLines(Instructions);
if (script.DecompressedLength / 4 != Instructions.Length)
RTB_MSCMD.Text = RTB_OSP.Text = "DCMP FAIL";
else
RTB_MSP.Lines = [.. script.ParseScript, .. script.ParseMoves];
}
else
{
RTB_MSCMD.Lines = RTB_OS.Lines = ["No Data"];
}
}
private static void SetZoneData()
{
// Nothing, ZoneData is not currently researched enough.
}
private void SetOWSData()
{
// Force all entities to be written back
SetFurniture();
SetNPC();
SetWarp();
SetTrigger1();
SetTrigger2();
}
// Overworld Viewing
private int entry = -1;
private int fEntry, nEntry, wEntry, tEntry, uEntry = -1;
#region Enabling
internal static void ToggleEnable(NumericUpDown master, NumericUpDown slave, GroupBox display)
{
slave.Maximum = master.Value - 1;
slave.Enabled = display.Visible = slave.Maximum > -1;
slave.Minimum = slave.Enabled ? 0 : -1;
}
private void ChangeFurnitureCount(object sender, EventArgs e)
{
// Resize array
int count = (int)NUD_FurnCount.Value;
CurrentZone.Entities.FurnitureCount = count;
Array.Resize(ref CurrentZone.Entities.Furniture, count);
for (int i = 0; i < count; i++)
CurrentZone.Entities.Furniture[i] ??= new Zone.ZoneEntities.EntityFurniture();
ToggleEnable(NUD_FurnCount, NUD_FE, GB_F);
}
private void ChangeNPCCount(object sender, EventArgs e)
{
// Resize array
int count = (int)NUD_NPCCount.Value;
CurrentZone.Entities.NPCCount = count;
Array.Resize(ref CurrentZone.Entities.NPCs, count);
for (int i = 0; i < count; i++)
CurrentZone.Entities.NPCs[i] ??= new Zone.ZoneEntities.EntityNPC();
ToggleEnable(NUD_NPCCount, NUD_NE, GB_N);
}
private void ChangeWarpCount(object sender, EventArgs e)
{
// Resize array
int count = (int)NUD_WarpCount.Value;
CurrentZone.Entities.WarpCount = count;
Array.Resize(ref CurrentZone.Entities.Warps, count);
for (int i = 0; i < count; i++)
CurrentZone.Entities.Warps[i] ??= new Zone.ZoneEntities.EntityWarp();
ToggleEnable(NUD_WarpCount, NUD_WE, GB_W);
}
private void ChangeTriggerCount(object sender, EventArgs e)
{
// Resize array
int count = (int)NUD_TrigCount.Value;
CurrentZone.Entities.TriggerCount = count;
Array.Resize(ref CurrentZone.Entities.Triggers1, count);
for (int i = 0; i < count; i++)
CurrentZone.Entities.Triggers1[i] ??= new Zone.ZoneEntities.EntityTrigger1();
ToggleEnable(NUD_TrigCount, NUD_TE, GB_T1);
}
private void ChangeUnkCount(object sender, EventArgs e)
{
// Resize array
int count = (int)NUD_UnkCount.Value;
CurrentZone.Entities.UnknownCount = count;
Array.Resize(ref CurrentZone.Entities.Triggers2, count);
for (int i = 0; i < count; i++)
CurrentZone.Entities.Triggers2[i] ??= new Zone.ZoneEntities.EntityTrigger2();
ToggleEnable(NUD_UnkCount, NUD_UE, GB_T2);
}
#endregion
#region Updating
private void ChangeFurniture(object sender, EventArgs e)
{
if (NUD_FE.Value < 0) return;
SetFurniture();
fEntry = (int)NUD_FE.Value;
GetFurniture();
}
private void GetFurniture()
{
if (NUD_FE.Value < 0) return;
var Furniture = CurrentZone.Entities.Furniture[fEntry];
NUD_FX.Value = Furniture.X;
NUD_FY.Value = Furniture.Y;
NUD_FWX.Value = Furniture.WX;
NUD_FWY.Value = Furniture.WY;
RTB_F.Text = Util.GetHexString(Furniture.Raw);
}
private void SetFurniture()
{
if (NUD_FE.Value < 0) return;
if (fEntry < 0) return;
var FUrniture = CurrentZone.Entities.Furniture[fEntry];
FUrniture.X = (int)NUD_FX.Value;
FUrniture.Y = (int)NUD_FY.Value;
FUrniture.WX = (int)NUD_FWX.Value;
FUrniture.WY = (int)NUD_FWY.Value;
}
private void ChangeNPC(object sender, EventArgs e)
{
if (NUD_NE.Value < 0) return;
SetNPC();
nEntry = (int)NUD_NE.Value;
GetNPC();
}
private void GetNPC()
{
if (NUD_NE.Value < 0) return;
var NPC = CurrentZone.Entities.NPCs[nEntry];
// Load new Attributes
NUD_NID.Value = NPC.ID;
NUD_NModel.Value = NPC.Model;
NUD_NFlag.Value = NPC.SpawnFlag;
NUD_NScript.Value = NPC.Script;
NUD_NFace.Value = NPC.FaceDirection;
NUD_NRange.Value = NPC.SightRange;
NUD_NX.Value = NPC.X;
NUD_NY.Value = NPC.Y;
NUD_NMove1.Value = NPC.MovePermissions;
NUD_NMove2.Value = NPC.MovePermissions2;
// Uneditables
TB_NDeg.Text = NPC.Deg18.ToString(CultureInfo.InvariantCulture);
TB_Leash.Text = NPC.L1 == NPC.L2 && NPC.L2 == NPC.L3 && NPC.L3 == -1
? TB_Leash.Text = "No Leash!"
: $"{NPC.L1}, {NPC.L2}, {NPC.L3} -- {NPC.LDir}";
RTB_N.Text = Util.GetHexString(NPC.Raw);
}
private void SetNPC()
{
if (NUD_NE.Value < 0) return;
if (nEntry < 0) return;
var NPC = CurrentZone.Entities.NPCs[nEntry];
NPC.ID = (int)NUD_NID.Value;
NPC.Model = (int)NUD_NModel.Value;
NPC.SpawnFlag = (int)NUD_NFlag.Value;
NPC.Script = (int)NUD_NScript.Value;
NPC.FaceDirection = (int)NUD_NFace.Value;
NPC.SightRange = (int)NUD_NRange.Value;
NPC.X = (int)NUD_NX.Value;
NPC.Y = (int)NUD_NY.Value;
NPC.MovePermissions = (int)NUD_NMove1.Value;
NPC.MovePermissions2 = (int)NUD_NMove2.Value;
}
private void ChangeWarp(object sender, EventArgs e)
{
if (NUD_WE.Value < 0) return;
SetWarp();
wEntry = (int)NUD_WE.Value;
GetWarp();
}
private void GetWarp()
{
if (NUD_WE.Value < 0) return;
var Warp = CurrentZone.Entities.Warps[wEntry];
RTB_W.Text = Util.GetHexString(Warp.Raw);
// Load new Attributes
NUD_WMap.Value = Warp.DestinationMap;
NUD_WTile.Value = Warp.DestinationTileIndex;
NUD_WX.Value = Warp.X;
NUD_WY.Value = Warp.Y;
// Flavor Mods
L_WarpDest.Text = zdLocations[Warp.DestinationMap];
}
private void SetWarp()
{
if (NUD_WE.Value < 0) return;
if (wEntry < 0) return;
var Warp = CurrentZone.Entities.Warps[wEntry];
Warp.DestinationMap = (int)NUD_WMap.Value;
Warp.DestinationTileIndex = (int)NUD_WTile.Value;
Warp.X = (short)NUD_WX.Value;
Warp.Y = (short)NUD_WY.Value;
}
private void ChangeTrigger1(object sender, EventArgs e)
{
if (NUD_TE.Value < 0) return;
SetTrigger1();
tEntry = (int)NUD_TE.Value;
GetTrigger1();
}
private void GetTrigger1()
{
if (NUD_TE.Value < 0) return;
var Trigger1 = CurrentZone.Entities.Triggers1[tEntry];
NUD_T1X.Value = Trigger1.X;
NUD_T1Y.Value = Trigger1.Y;
RTB_T1.Text = Util.GetHexString(Trigger1.Raw);
}
private void SetTrigger1()
{
if (NUD_TE.Value < 0) return;
if (tEntry < 0) return;
var Trigger1 = CurrentZone.Entities.Triggers1[tEntry];
Trigger1.X = (int)NUD_T1X.Value;
Trigger1.Y = (int)NUD_T1Y.Value;
}
private void ChangeTrigger2(object sender, EventArgs e)
{
if (NUD_UE.Value < 0) return;
SetTrigger2();
uEntry = (int)NUD_UE.Value;
GetTrigger2();
}
private void GetTrigger2()
{
if (NUD_UE.Value < 0) return;
// Load New Data
var Trigger2 = CurrentZone.Entities.Triggers2[uEntry];
NUD_T2X.Value = Trigger2.X;
NUD_T2Y.Value = Trigger2.Y;
RTB_T2.Text = Util.GetHexString(Trigger2.Raw);
}
private void SetTrigger2()
{
if (NUD_UE.Value < 0) return;
if (uEntry < 0) return;
var Trigger2 = CurrentZone.Entities.Triggers2[uEntry];
Trigger2.X = (int)NUD_T2X.Value;
Trigger2.Y = (int)NUD_T2Y.Value;
}
#endregion
// Overworld User Enhancements
private void ChangeNPC_ID(object sender, EventArgs e) => L_NID.ForeColor = NUD_NID.Value != NUD_NE.Value ? Color.Red : Color.Black;
private void ChangeNPC_Model(object sender, EventArgs e) => L_ModelAsHex.Text = "0x" + ((int)NUD_NModel.Value).ToString("X4");
private void DclickDestMap(object sender, EventArgs e)
{
var Tile = NUD_WTile.Value;
CB_LocationID.SelectedIndex = (int)NUD_WMap.Value;
try
{ NUD_WE.Value = Tile; }
catch
{ try { NUD_WE.Value = 0; } catch { } }
}
private void ChangeWarp_X(object sender, EventArgs e) => L_WpX.Text = (NUD_WX.Value / 18).ToString(CultureInfo.InvariantCulture);
private void ChangeWarp_Y(object sender, EventArgs e) => L_WpY.Text = (NUD_WY.Value / 18).ToString(CultureInfo.InvariantCulture);
// Script Handling
private void B_HLCMD_Click(object sender, EventArgs e)
{
int ctr = WinFormsUtil.HighlightText(RTB_OSP, "**", Color.Red) + (WinFormsUtil.HighlightText(RTB_MSP, "**", Color.Red) / 2);
WinFormsUtil.Alert($"{ctr} instance{(ctr > 1 ? "s" : "")} of \"*\" present.");
}
private void TabMain_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
}
private void TabMain_DragDrop(object sender, DragEventArgs e)
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
string path = files[0]; // open first D&D
if (new FileInfo(path).Length < 10000000)
ParseScriptInput(File.ReadAllBytes(path));
}
private void ParseScriptInput(byte[] data)
{
var scr = new Script(data);
RTB_CompressedScript.Lines = Scripts.GetHexLines(scr.CompressedBytes);
System.Media.SystemSounds.Asterisk.Play();
}
private void PasteScript(object sender, EventArgs e)
{
// import data as bytes
try
{
string text = RTB_CompressedScript.Text.Replace(Environment.NewLine, "").Replace("\n", "").Replace(" ", "");
byte[] data = Util.StringToByteArray(text);
byte[] dec = Scripts.DecompressScript(data);
RTB_DecompressedScript.Lines = Scripts.GetHexLines(dec);
}
catch
{
RTB_DecompressedScript.Text = "DECMP ERROR";
}
}
// Dev Dumpers
private void B_DumpFurniture_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all Furniture?") != DialogResult.Yes)
return;
debugToolDumping = true;
List<string> result = [];
List<byte[]> data = [];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
CB_LocationID.SelectedIndex = i;
for (int j = 0; j < CurrentZone.Entities.FurnitureCount; j++)
{
result.Add(Util.GetHexString(CurrentZone.Entities.Furniture[j].Raw));
data.Add(CurrentZone.Entities.Furniture[j].Raw);
}
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write Furniture to file?") == DialogResult.Yes)
File.WriteAllBytes("Furniture.bin", data.SelectMany(z => z).ToArray());
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy Furniture to Clipboard?") == DialogResult.Yes)
Clipboard.SetText(string.Join(Environment.NewLine, result));
CB_LocationID.SelectedIndex = 0;
debugToolDumping = false;
}
private void B_DumpNPC_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all NPCs?") != DialogResult.Yes)
return;
debugToolDumping = true;
List<string> result = [];
List<byte[]> data = [];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
CB_LocationID.SelectedIndex = i;
for (int j = 0; j < CurrentZone.Entities.NPCCount; j++)
{
result.Add(Util.GetHexString(CurrentZone.Entities.NPCs[j].Raw));
data.Add(CurrentZone.Entities.NPCs[j].Raw);
}
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write NPCs to file?") == DialogResult.Yes)
File.WriteAllBytes("NPCs.bin", data.SelectMany(z => z).ToArray());
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy NPCs to Clipboard?") == DialogResult.Yes)
Clipboard.SetText(string.Join(Environment.NewLine, result));
CB_LocationID.SelectedIndex = 0;
debugToolDumping = false;
}
private void B_DumpWarp_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all Warps?") != DialogResult.Yes)
return;
debugToolDumping = true;
List<string> result = [];
List<byte[]> data = [];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
CB_LocationID.SelectedIndex = i;
for (int j = 0; j < CurrentZone.Entities.WarpCount; j++)
{
result.Add(Util.GetHexString(CurrentZone.Entities.Warps[j].Raw));
data.Add(CurrentZone.Entities.Warps[j].Raw);
}
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write Warps to file?") == DialogResult.Yes)
File.WriteAllBytes("Warps.bin", data.SelectMany(z => z).ToArray());
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy Warps to Clipboard?") == DialogResult.Yes)
Clipboard.SetText(string.Join(Environment.NewLine, result));
CB_LocationID.SelectedIndex = 0;
debugToolDumping = false;
}
private void B_DumpTrigger_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all Triggers?") != DialogResult.Yes)
return;
debugToolDumping = true;
List<string> result = [];
List<byte[]> data = [];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
CB_LocationID.SelectedIndex = i;
for (int j = 0; j < CurrentZone.Entities.TriggerCount; j++)
{
result.Add(Util.GetHexString(CurrentZone.Entities.Triggers1[j].Raw));
data.Add(CurrentZone.Entities.Triggers1[j].Raw);
}
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write Triggers to file?") == DialogResult.Yes)
File.WriteAllBytes("Triggers.bin", data.SelectMany(z => z).ToArray());
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy Triggers to Clipboard?") == DialogResult.Yes)
Clipboard.SetText(string.Join(Environment.NewLine, result));
CB_LocationID.SelectedIndex = 0;
debugToolDumping = false;
}
private void B_DumpUnk_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all Unks?") != DialogResult.Yes)
return;
debugToolDumping = true;
List<string> result = [];
List<byte[]> data = [];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
CB_LocationID.SelectedIndex = i;
for (int j = 0; j < CurrentZone.Entities.UnknownCount; j++)
{
result.Add(Util.GetHexString(CurrentZone.Entities.Triggers2[j].Raw));
data.Add(CurrentZone.Entities.Triggers2[j].Raw);
}
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write Unks to file?") == DialogResult.Yes)
File.WriteAllBytes("Unks.bin", data.SelectMany(z => z).ToArray());
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy Unks to Clipboard?") == DialogResult.Yes)
Clipboard.SetText(string.Join(Environment.NewLine, result));
CB_LocationID.SelectedIndex = 0;
debugToolDumping = false;
}
private void B_DumpMaps_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all MapImages?") != DialogResult.Yes)
return;
debugToolDumping = true;
const string folder = "MapImages";
if (!Directory.Exists(folder))
Directory.CreateDirectory(folder);
string[] result = new string[CB_LocationID.Items.Count];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
mapView.DrawMap = i;
Image img = mapView.GetMapImage(crop: true);
using (var ms = new MemoryStream())
{
//error will throw from here
img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
byte[] data = ms.ToArray();
File.WriteAllBytes(Path.Combine(folder, $"{zdLocations[i].Replace('?', '-')} ({i}).png"), data);
}
string l = mm.EntryList.Where(t => t != 0xFFFF).Aggregate("", (current, t) => current + t.ToString("000 "));
result[i] = $"{i:000}\t{CB_LocationID.Items[i]}\t{l}";
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write Map parse output?") == DialogResult.Yes)
File.WriteAllLines("MapLocations.txt", result);
CB_LocationID.SelectedIndex = 0;
WinFormsUtil.Alert("All Map images have been dumped to " + folder + ".");
debugToolDumping = false;
}
private void B_DumpZD_Click(object sender, EventArgs e)
{
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Export all ZD?") != DialogResult.Yes)
return;
debugToolDumping = true;
List<string> result = [];
List<byte[]> data = [];
for (int i = 0; i < CB_LocationID.Items.Count; i++)
{
CB_LocationID.SelectedIndex = i;
result.Add(Util.GetHexString(CurrentZone.ZD.Data));
data.Add(CurrentZone.ZD.Data);
}
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Write ZDs to file?") == DialogResult.Yes)
File.WriteAllBytes("ZDs.bin", data.SelectMany(z => z).ToArray());
if (WinFormsUtil.Prompt(MessageBoxButtons.YesNoCancel, "Copy ZDs to Clipboard?") == DialogResult.Yes)
Clipboard.SetText(string.Join(Environment.NewLine, result));
CB_LocationID.SelectedIndex = 0;
debugToolDumping = false;
}
// Raw file editing
private void ChangeRAWCheck(object sender, EventArgs e)
{
bool chk = ((CheckBox)sender).Checked;
foreach (NumericUpDown nud in GB_F.Controls.OfType<NumericUpDown>())
nud.Enabled = !chk;
foreach (NumericUpDown nud in GB_N.Controls.OfType<NumericUpDown>())
nud.Enabled = !chk;
foreach (NumericUpDown nud in GB_W.Controls.OfType<NumericUpDown>())
nud.Enabled = !chk;
foreach (NumericUpDown nud in GB_T1.Controls.OfType<NumericUpDown>())
nud.Enabled = !chk;
foreach (NumericUpDown nud in GB_T2.Controls.OfType<NumericUpDown>())
nud.Enabled = !chk;
foreach (RichTextBox rtb in new[] { RTB_F, RTB_N, RTB_W, RTB_T1, RTB_T2 })
rtb.Visible = chk;
}
private void ChangeRAW_F(object sender, EventArgs e)
{
if (sender is not RichTextBox { Visible: true })
return;
try
{
byte[] data = Util.StringToByteArray(((RichTextBox)sender).Text.Replace(Environment.NewLine, " ").Replace(" ", ""));
if (data.Length != Zone.ZoneEntities.EntityFurniture.Size)
return;
CurrentZone.Entities.Furniture[fEntry].Raw = data;
GetFurniture();
}
catch
{
((RichTextBox)sender).Text = Util.GetHexString(CurrentZone.Entities.Furniture[fEntry].Raw);
}
}
private void ChangeRAW_N(object sender, EventArgs e)
{
if (sender is not RichTextBox { Visible: true })
return;
try
{
byte[] data = Util.StringToByteArray(((RichTextBox)sender).Text.Replace(Environment.NewLine, " ").Replace(" ", ""));
if (data.Length != Zone.ZoneEntities.EntityNPC.Size)
return;
CurrentZone.Entities.NPCs[nEntry].Raw = data;
GetNPC();
}
catch
{
((RichTextBox)sender).Text = Util.GetHexString(CurrentZone.Entities.NPCs[nEntry].Raw);
}
}
private void ChangeRAW_W(object sender, EventArgs e)
{
if (sender is not RichTextBox { Visible: true })
return;
try
{
byte[] data = Util.StringToByteArray(((RichTextBox)sender).Text.Replace(Environment.NewLine, " ").Replace(" ", ""));
if (data.Length != Zone.ZoneEntities.EntityWarp.Size)
return;
CurrentZone.Entities.Warps[wEntry].Raw = data;
GetWarp();
}
catch
{
((RichTextBox)sender).Text = Util.GetHexString(CurrentZone.Entities.Warps[wEntry].Raw);
}
}
private void ChangeRAW_T1(object sender, EventArgs e)
{
if (sender is not RichTextBox { Visible: true })
return;
try
{
byte[] data = Util.StringToByteArray(((RichTextBox)sender).Text.Replace(Environment.NewLine, " ").Replace(" ", ""));
if (data.Length != Zone.ZoneEntities.EntityTrigger1.Size)
return;
CurrentZone.Entities.Triggers1[tEntry].Raw = data;
GetTrigger1();
}
catch
{
((RichTextBox)sender).Text = Util.GetHexString(CurrentZone.Entities.Triggers1[tEntry].Raw);
}
}
private void ChangeRAW_T2(object sender, EventArgs e)
{
if (sender is not RichTextBox { Visible: true })
return;
try
{
byte[] data = Util.StringToByteArray(((RichTextBox)sender).Text.Replace(Environment.NewLine, " ").Replace(" ", ""));
if (data.Length != Zone.ZoneEntities.EntityTrigger2.Size)
return;
CurrentZone.Entities.Triggers2[uEntry].Raw = data;
GetTrigger2();
}
catch
{
((RichTextBox)sender).Text = Util.GetHexString(CurrentZone.Entities.Triggers2[uEntry].Raw);
}
}
// RAW Resets
private void B_ResetOverworlds_Click(object sender, EventArgs e)
{
if (DialogResult.Yes != WinFormsUtil.Prompt(MessageBoxButtons.YesNo, "Reset all overworld entities?"))
return;
// since scripts are not editable, just reset the overworld file.
CurrentZone.Entities = new Zone.ZoneEntities(locationData[1]);
GetOWSData();
}
private void B_ResetFurniture_Click(object sender, EventArgs e)
{
CurrentZone.Entities.Furniture[fEntry].OriginalData.CopyTo(CurrentZone.Entities.Furniture[fEntry].Raw, 0);
GetFurniture();
}
private void B_ResetNPC_Click(object sender, EventArgs e)
{
CurrentZone.Entities.NPCs[nEntry].OriginalData.CopyTo(CurrentZone.Entities.NPCs[nEntry].Raw, 0);
GetNPC();
}
private void B_ResetWarp_Click(object sender, EventArgs e)
{
CurrentZone.Entities.Warps[wEntry].OriginalData.CopyTo(CurrentZone.Entities.Warps[wEntry].Raw, 0);
GetWarp();
}
private void B_ResetTrigger1_Click(object sender, EventArgs e)
{
CurrentZone.Entities.Triggers1[tEntry].OriginalData.CopyTo(CurrentZone.Entities.Triggers1[tEntry].Raw, 0);
GetTrigger1();
}
private void B_ResetTrigger2_Click(object sender, EventArgs e)
{
CurrentZone.Entities.Triggers2[uEntry].OriginalData.CopyTo(CurrentZone.Entities.Triggers2[uEntry].Raw, 0);
GetTrigger2();
}
}