mirror of
https://github.com/AdAstra-LD/DS-Pokemon-Rom-Editor.git
synced 2026-05-12 06:54:33 -05:00
2493 lines
101 KiB
C#
2493 lines
101 KiB
C#
using DSPRE.Resources;
|
|
using DSPRE.ROMFiles;
|
|
using Ekona.Images.Formats;
|
|
using LibNDSFormats.NSBMD;
|
|
using NSMBe4.NSBMD;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Data;
|
|
using System.Drawing;
|
|
using System.Drawing.Drawing2D;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Documents;
|
|
using System.Windows.Forms;
|
|
using static DSPRE.RomInfo;
|
|
using static Tao.Platform.Windows.Winmm;
|
|
|
|
namespace DSPRE.Editors
|
|
{
|
|
public partial class EventEditor : UserControl
|
|
{
|
|
MainProgram _parent;
|
|
public bool eventEditorIsReady { get; set; } = false;
|
|
public EventEditor()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
#region Event Editor
|
|
|
|
#region Variables
|
|
public bool itemComboboxIsUpToDate = false;
|
|
public static NSBMDGlRenderer eventMapRenderer = new NSBMDGlRenderer();
|
|
public static NSBMDGlRenderer eventBuildingsRenderer = new NSBMDGlRenderer();
|
|
public static MapFile eventMapFile;
|
|
public NSMBe4.NSBMD.NSBTX_File overworldFrames;
|
|
public GameMatrix eventMatrix;
|
|
|
|
public const byte tileSize = 16;
|
|
public EventFile currentEvFile;
|
|
public Event selectedEvent;
|
|
|
|
/* Painters to draw the matrix grid */
|
|
public Pen eventPen;
|
|
public Brush eventBrush;
|
|
public Rectangle eventMatrixRectangle;
|
|
#endregion
|
|
|
|
|
|
|
|
#region Subroutines
|
|
private void itemsSelectorHelpBtn_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show("This selector allows you to pick a preset Ground Item script from the game data.\n" +
|
|
"Unlike in previous DSPRE versions, you can now change the Ground Item to be obtained even if you decided not to apply the Standardize Items patch from the Patch Toolbox.\n\n" +
|
|
"However, some items are unavailable by default. The aforementioned patch can neutralize this limitation.\n\n",
|
|
"About Ground Items", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
private void CenterEventViewOnEntities()
|
|
{
|
|
int destX = 0;
|
|
int destY = 0;
|
|
if (currentEvFile.overworlds.Count > 0)
|
|
{
|
|
destX = currentEvFile.overworlds[0].xMatrixPosition;
|
|
destY = currentEvFile.overworlds[0].yMatrixPosition;
|
|
}
|
|
else if (currentEvFile.warps.Count > 0)
|
|
{
|
|
destX = currentEvFile.warps[0].xMatrixPosition;
|
|
destY = currentEvFile.warps[0].yMatrixPosition;
|
|
}
|
|
else if (currentEvFile.spawnables.Count > 0)
|
|
{
|
|
destX = currentEvFile.spawnables[0].xMatrixPosition;
|
|
destY = currentEvFile.spawnables[0].yMatrixPosition;
|
|
}
|
|
else if (currentEvFile.triggers.Count > 0)
|
|
{
|
|
destX = currentEvFile.triggers[0].xMatrixPosition;
|
|
destY = currentEvFile.triggers[0].yMatrixPosition;
|
|
}
|
|
|
|
if (destX > eventMatrixXUpDown.Maximum || destY > eventMatrixYUpDown.Maximum)
|
|
{
|
|
//MessageBox.Show("One of the events tried to reference a bigger Matrix.\nMake sure the Header File associated to this Event File is using the correct Matrix.", "Error",
|
|
// MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
eventMatrixXUpDown.Value = eventMatrixYUpDown.Value = 0;
|
|
}
|
|
else
|
|
{
|
|
eventMatrixXUpDown.Value = destX;
|
|
eventMatrixYUpDown.Value = destY;
|
|
}
|
|
}
|
|
private void centerEventViewOnSelectedEvent_Click(object sender, EventArgs e)
|
|
{
|
|
if (selectedEvent is null)
|
|
{
|
|
MessageBox.Show("You haven't selected any event.", "Nothing to do here", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
eventMatrixXUpDown.Value = selectedEvent.xMatrixPosition;
|
|
eventMatrixYUpDown.Value = selectedEvent.yMatrixPosition;
|
|
}
|
|
catch (ArgumentOutOfRangeException)
|
|
{
|
|
DialogResult main = MessageBox.Show("The selected event tried to reference a bigger Matrix than the one which is currently being displayed.\nDo you want to check for another potentially compatible matrix?", "Event is out of range", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
|
|
|
if (main.Equals(DialogResult.Yes))
|
|
{
|
|
ushort[] result = HeaderSearch.AdvancedSearch(0, (ushort)EditorPanels.headerEditor.internalNames.Count, EditorPanels.headerEditor.internalNames, (int)MapHeader.SearchableFields.EventFileID, (int)HeaderSearch.NumOperators.Equal, selectEventComboBox.SelectedIndex.ToString())
|
|
.Select(x => ushort.Parse(x.Split()[0]))
|
|
.ToArray();
|
|
|
|
Dictionary<ushort, ushort> dict = new Dictionary<ushort, ushort>();
|
|
|
|
if (gameFamily.Equals(GameFamilies.DP))
|
|
{
|
|
foreach (ushort headerID in result)
|
|
{
|
|
HeaderDP hdp = (HeaderDP)MapHeader.LoadFromARM9(headerID);
|
|
|
|
if (hdp.matrixID != eventMatrixUpDown.Value && hdp.locationName != 0)
|
|
{
|
|
dict.Add(hdp.ID, hdp.matrixID);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
foreach (ushort headerID in result)
|
|
{
|
|
HeaderPt hpt;
|
|
|
|
if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied())
|
|
{
|
|
hpt = (HeaderPt)MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerID.ToString("D4"), headerID, 0);
|
|
}
|
|
else
|
|
{
|
|
hpt = (HeaderPt)MapHeader.LoadFromARM9(headerID);
|
|
}
|
|
|
|
if (hpt.matrixID != eventMatrixUpDown.Value && hpt.locationName != 0)
|
|
{
|
|
dict.Add(hpt.ID, hpt.matrixID);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (dict.Count < 1)
|
|
{
|
|
MessageBox.Show("DSPRE could not find another Header referencing the same Event File and a different Matrix.", "Search failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
eventMatrixXUpDown.Value = 0;
|
|
eventMatrixYUpDown.Value = 0;
|
|
}
|
|
else
|
|
{
|
|
if (dict.Count > 1)
|
|
{
|
|
if (dict.Keys.Contains(EditorPanels.headerEditor.currentHeader.ID))
|
|
{
|
|
DialogResult yn = MessageBox.Show("DSPRE found multiple Headers referencing the same Event File and a different Matrix.\n" +
|
|
$"The last selected Header ({EditorPanels.headerEditor.currentHeader.ID}) is one of those.\n" +
|
|
$"Do you want to load its matrix (#{EditorPanels.headerEditor.currentHeader.matrixID}?)", "Potential solution found", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
|
|
if (yn.Equals(DialogResult.Yes))
|
|
{
|
|
eventMatrixUpDown.Value = EditorPanels.headerEditor.currentHeader.matrixID;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var kvp = dict.First();
|
|
|
|
DialogResult yn = MessageBox.Show($"DSPRE found {dict.Count} Headers referencing the same Event File and a different Matrix.\n" +
|
|
$"Do you want to load Header {kvp.Key}'s matrix (#{kvp.Value})?", "Potential solution found", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
|
|
if (yn.Equals(DialogResult.Yes))
|
|
{
|
|
eventMatrixUpDown.Value = kvp.Value;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var kvp = dict.First();
|
|
|
|
DialogResult yn = MessageBox.Show($"Header {kvp.Key}'s matrix (#{kvp.Value}) seems to be the only match for this Event File.\n" +
|
|
$"Do you want to load it?", "Potential solution found", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
|
|
if (yn.Equals(DialogResult.Yes))
|
|
{
|
|
eventMatrixUpDown.Value = kvp.Value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
Update();
|
|
}
|
|
}
|
|
}
|
|
private void eventPictureBox_MouseMove(object sender, MouseEventArgs e)
|
|
{
|
|
Point coordinates = eventPictureBox.PointToClient(Cursor.Position);
|
|
Point mouseTilePos = new Point(coordinates.X / (tileSize + 1), coordinates.Y / (tileSize + 1));
|
|
Helpers.statusLabelMessage("Local: " + mouseTilePos.X + ", " + mouseTilePos.Y + " | " + "Global: " + (eventMatrixXUpDown.Value * MapFile.mapSize + mouseTilePos.X).ToString() + ", " + (eventMatrixYUpDown.Value * MapFile.mapSize + mouseTilePos.Y).ToString());
|
|
}
|
|
|
|
private void DisplayActiveEvents()
|
|
{
|
|
eventPictureBox.Image = new Bitmap(eventPictureBox.Width, eventPictureBox.Height);
|
|
|
|
using (Graphics g = Graphics.FromImage(eventPictureBox.Image))
|
|
{
|
|
Bitmap icon;
|
|
|
|
/* Draw spawnables */
|
|
if (showSpawnablesCheckBox.Checked)
|
|
{
|
|
icon = (Bitmap)Properties.Resources.ResourceManager.GetObject("sign");
|
|
|
|
for (int i = 0; i < currentEvFile.spawnables.Count; i++)
|
|
{
|
|
Spawnable spawnable = currentEvFile.spawnables[i];
|
|
|
|
if (isEventOnCurrentMatrix(spawnable))
|
|
{
|
|
g.DrawImage(icon, spawnable.xMapPosition * (tileSize + 1), spawnable.yMapPosition * (tileSize + 1));
|
|
if (selectedEvent == spawnable)
|
|
{ // Draw selection rectangle if event is the selected one
|
|
DrawSelectionRectangle(g, spawnable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Draw overworlds */
|
|
if (showOwsCheckBox.Checked)
|
|
{
|
|
for (int i = 0; i < currentEvFile.overworlds.Count; i++)
|
|
{
|
|
Overworld overworld = currentEvFile.overworlds[i];
|
|
|
|
if (isEventOnCurrentMatrix(overworld))
|
|
{ // Draw image only if event is in current map
|
|
Bitmap sprite = GetOverworldImage(overworld.overlayTableEntry, overworld.orientation);
|
|
sprite.MakeTransparent();
|
|
g.DrawImage(sprite, (overworld.xMapPosition) * (tileSize + 1) - 7 + (32 - sprite.Width) / 2, (overworld.yMapPosition - 1) * (tileSize + 1) + (32 - sprite.Height));
|
|
|
|
if (selectedEvent == overworld)
|
|
{
|
|
DrawSelectionRectangleOverworld(g, overworld);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Draw warps */
|
|
if (showWarpsCheckBox.Checked)
|
|
{
|
|
DrawWarpCollisions(g);
|
|
|
|
icon = (Bitmap)Properties.Resources.ResourceManager.GetObject("warp");
|
|
for (int i = 0; i < currentEvFile.warps.Count; i++)
|
|
{
|
|
Warp warp = currentEvFile.warps[i];
|
|
|
|
if (isEventOnCurrentMatrix(warp))
|
|
{
|
|
g.DrawImage(icon, warp.xMapPosition * (tileSize + 1), warp.yMapPosition * (tileSize + 1));
|
|
|
|
if (selectedEvent == warp)
|
|
{ // Draw selection rectangle if event is the selected one
|
|
DrawSelectionRectangle(g, warp);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Draw triggers */
|
|
if (showTriggersCheckBox.Checked)
|
|
{
|
|
icon = (Bitmap)Properties.Resources.ResourceManager.GetObject("trigger");
|
|
|
|
for (int i = 0; i < currentEvFile.triggers.Count; i++)
|
|
{
|
|
Trigger trigger = currentEvFile.triggers[i];
|
|
|
|
if (isEventOnCurrentMatrix(trigger))
|
|
{
|
|
for (int y = 0; y < currentEvFile.triggers[i].heightY; y++)
|
|
{
|
|
for (int x = 0; x < currentEvFile.triggers[i].widthX; x++)
|
|
{
|
|
g.DrawImage(icon, (trigger.xMapPosition + x) * (tileSize + 1), (trigger.yMapPosition + y) * (tileSize + 1));
|
|
}
|
|
}
|
|
if (selectedEvent == trigger)
|
|
{// Draw selection rectangle if event is the selected one
|
|
DrawSelectionRectangleTrigger(g, trigger);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
eventPictureBox.Invalidate();
|
|
}
|
|
private void DrawWarpCollisions(Graphics g)
|
|
{
|
|
if (eventMapFile != null)
|
|
{
|
|
Bitmap icon = (Bitmap)Properties.Resources.ResourceManager.GetObject("warpCollision");
|
|
for (int y = 0; y < MapFile.mapSize; y++)
|
|
{
|
|
for (int x = 0; x < MapFile.mapSize; x++)
|
|
{
|
|
byte moveperm = eventMapFile.types[x, y];
|
|
if (PokeDatabase.System.MapCollisionTypePainters.TryGetValue(moveperm, out string val))
|
|
{
|
|
if (val.IndexOf("Warp", StringComparison.InvariantCultureIgnoreCase) >= 0)
|
|
{
|
|
g.DrawImage(icon, y * (tileSize + 1), x * (tileSize + 1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private void DrawSelectionRectangle(Graphics g, Event ev)
|
|
{
|
|
eventPen = Pens.Red;
|
|
g.DrawRectangle(eventPen, (ev.xMapPosition) * (tileSize + 1) - 1, (ev.yMapPosition) * (tileSize + 1) - 1, 18, 18);
|
|
g.DrawRectangle(eventPen, (ev.xMapPosition) * (tileSize + 1) - 2, (ev.yMapPosition) * (tileSize + 1) - 2, 20, 20);
|
|
}
|
|
private void DrawSelectionRectangleTrigger(Graphics g, Trigger t)
|
|
{
|
|
eventPen = Pens.Red;
|
|
g.DrawRectangle(eventPen, (t.xMapPosition) * (tileSize + 1) - 1, (t.yMapPosition) * (tileSize + 1) - 1, 17 * t.widthX + 1, (tileSize + 1) * t.heightY + 1);
|
|
g.DrawRectangle(eventPen, (t.xMapPosition) * (tileSize + 1) - 2, (t.yMapPosition) * (tileSize + 1) - 2, 17 * t.widthX + 3, (tileSize + 1) * t.heightY + 3);
|
|
}
|
|
private void DrawSelectionRectangleOverworld(Graphics g, Overworld ow)
|
|
{
|
|
eventPen = Pens.Red;
|
|
g.DrawRectangle(eventPen, (ow.xMapPosition) * (tileSize + 1) - 8, (ow.yMapPosition - 1) * (tileSize + 1), 34, 34);
|
|
g.DrawRectangle(eventPen, (ow.xMapPosition) * (tileSize + 1) - 9, (ow.yMapPosition - 1) * (tileSize + 1) - 1, 36, 36);
|
|
}
|
|
private void DisplayEventMap(bool readGraphicsFromHeader = true)
|
|
{
|
|
/* Determine map file to open and open it in BinaryReader, unless map is VOID */
|
|
uint mapIndex = GameMatrix.EMPTY;
|
|
if (eventMatrixXUpDown.Value > eventMatrix.width || eventMatrixYUpDown.Value > eventMatrix.height)
|
|
{
|
|
String errorMsg = "This event file contains elements located on an unreachable map, beyond the current matrix.\n" +
|
|
"It is strongly advised that you bring every Overworld, Spawnable, Warp and Trigger of this event to a map that belongs to the matrix's range.";
|
|
MessageBox.Show(errorMsg, "Can't load proper map", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
}
|
|
else
|
|
{
|
|
mapIndex = eventMatrix.maps[(int)(eventMatrixYUpDown.Value), (int)(eventMatrixXUpDown.Value)];
|
|
}
|
|
|
|
if (mapIndex == GameMatrix.EMPTY)
|
|
{
|
|
eventPictureBox.BackgroundImage = new Bitmap(eventPictureBox.Width, eventPictureBox.Height);
|
|
using (Graphics g = Graphics.FromImage(eventPictureBox.BackgroundImage))
|
|
{
|
|
g.Clear(Color.Black);
|
|
}
|
|
eventMapFile = null;
|
|
}
|
|
else
|
|
{
|
|
/* Determine area data */
|
|
byte areaDataID;
|
|
if (eventMatrix.hasHeadersSection && readGraphicsFromHeader)
|
|
{
|
|
ushort headerID = (ushort)eventMatrix.headers[(short)eventMatrixYUpDown.Value, (short)eventMatrixXUpDown.Value];
|
|
MapHeader h;
|
|
if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied())
|
|
{
|
|
h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + headerID.ToString("D4"), headerID, 0);
|
|
}
|
|
else
|
|
{
|
|
h = MapHeader.LoadFromARM9(headerID);
|
|
}
|
|
|
|
areaDataID = h.areaDataID;
|
|
|
|
Helpers.BackUpDisableHandler();
|
|
Helpers.DisableHandlers();
|
|
eventAreaDataUpDown.Value = h.areaDataID;
|
|
Helpers.RestoreDisableHandler();
|
|
}
|
|
else
|
|
{
|
|
areaDataID = (byte)eventAreaDataUpDown.Value;
|
|
}
|
|
|
|
/* get texture file numbers from area data */
|
|
AreaData areaData = new AreaData(areaDataID);
|
|
|
|
/* Read map and building models, match them with textures and render them*/
|
|
eventMapFile = new MapFile((int)mapIndex, RomInfo.gameFamily, discardMoveperms: false);
|
|
Helpers.MW_LoadModelTextures(eventMapFile.mapModel, RomInfo.gameDirs[DirNames.mapTextures].unpackedDir, areaData.mapTileset);
|
|
|
|
bool isInteriorMap = false;
|
|
if ((RomInfo.gameVersion == GameVersions.HeartGold || RomInfo.gameVersion == GameVersions.SoulSilver) && areaData.areaType == 0x0)
|
|
isInteriorMap = true;
|
|
|
|
for (int i = 0; i < eventMapFile.buildings.Count; i++)
|
|
{
|
|
eventMapFile.buildings[i].LoadModelData(_parent.romInfo.GetBuildingModelsDirPath(isInteriorMap)); // Load building nsbmd
|
|
Helpers.MW_LoadModelTextures(eventMapFile.buildings[i].NSBMDFile, RomInfo.gameDirs[DirNames.buildingTextures].unpackedDir, areaData.buildingsTileset); // Load building textures
|
|
}
|
|
|
|
Helpers.RenderMap(ref eventMapRenderer, ref eventBuildingsRenderer, ref eventMapFile, 0f, 115.0f, 90f, 4f, eventOpenGlControl.Width, eventOpenGlControl.Height, true, true);
|
|
eventPictureBox.BackgroundImage = Helpers.GrabMapScreenshot(eventOpenGlControl.Width, eventOpenGlControl.Height);
|
|
}
|
|
eventPictureBox.Invalidate();
|
|
}
|
|
private void DrawEventMatrix()
|
|
{
|
|
eventMatrixPictureBox.Image = new Bitmap(1 + 16 * eventMatrix.width, 1 + 16 * eventMatrix.height);
|
|
|
|
using (Graphics g = Graphics.FromImage(eventMatrixPictureBox.Image))
|
|
{
|
|
/* First, fill the rectangle with black */
|
|
g.Clear(Color.Black);
|
|
|
|
/* Now, draw the white cell borders on the black rectangle */
|
|
eventPen = Pens.White;
|
|
for (int y = 0; y < eventMatrix.height; y++)
|
|
{
|
|
for (int x = 0; x < eventMatrix.width; x++)
|
|
{
|
|
eventMatrixRectangle = new Rectangle(1 + 16 * x, 1 + 16 * y, 14, 14);
|
|
g.DrawRectangle(eventPen, eventMatrixRectangle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
private void FillSpawnablesBox()
|
|
{
|
|
spawnablesListBox.Items.Clear();
|
|
int count = currentEvFile.spawnables.Count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
spawnablesListBox.Items.Add(i.ToString("D" + Math.Max(0, count - 1).ToString().Length) + ": " + currentEvFile.spawnables[i].ToString());
|
|
}
|
|
}
|
|
private void FillOverworldsBox()
|
|
{
|
|
overworldsListBox.Items.Clear();
|
|
int count = currentEvFile.overworlds.Count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
overworldsListBox.Items.Add(i.ToString("D" + Math.Max(0, count - 1).ToString().Length) + ": " + currentEvFile.overworlds[i].ToString());
|
|
}
|
|
}
|
|
private void FillWarpsBox()
|
|
{
|
|
warpsListBox.Items.Clear();
|
|
int count = currentEvFile.warps.Count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
warpsListBox.Items.Add(i.ToString("D" + Math.Max(0, count - 1).ToString().Length) + ": " + currentEvFile.warps[i].ToString());
|
|
}
|
|
}
|
|
private void FillTriggersBox()
|
|
{
|
|
triggersListBox.Items.Clear();
|
|
int count = currentEvFile.triggers.Count;
|
|
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
triggersListBox.Items.Add(i.ToString("D" + Math.Max(0, count - 1).ToString().Length) + ": " + currentEvFile.triggers[i].ToString());
|
|
}
|
|
}
|
|
private Bitmap GetOverworldImage(ushort eventEntryID, ushort orientation)
|
|
{
|
|
/* Find sprite corresponding to ID and load it*/
|
|
if (RomInfo.ow3DSpriteDict.TryGetValue(eventEntryID, out string imageName))
|
|
{ // If overworld is 3D, load image from dictionary
|
|
return (Bitmap)Properties.Resources.ResourceManager.GetObject(imageName);
|
|
}
|
|
|
|
if (!RomInfo.OverworldTable.TryGetValue(eventEntryID, out (uint spriteID, ushort properties) result))
|
|
{ // try loading image from dictionary
|
|
return (Bitmap)Properties.Resources.ResourceManager.GetObject("overworld"); //if there's no match, load bounding box
|
|
}
|
|
|
|
try
|
|
{
|
|
FileStream stream = new FileStream(RomInfo.gameDirs[DirNames.OWSprites].unpackedDir + "\\" + result.spriteID.ToString("D4"), FileMode.Open);
|
|
NSBTX_File nsbtx = new NSBTX_File(stream);
|
|
|
|
if (nsbtx.texInfo.num_objs <= 1)
|
|
{
|
|
return nsbtx.GetBitmap(0, 0).bmp; // Read nsbtx slot 0 if ow has only 2 frames
|
|
}
|
|
if (nsbtx.texInfo.num_objs <= 4)
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case 0:
|
|
return nsbtx.GetBitmap(0, 0).bmp;
|
|
case 1:
|
|
return nsbtx.GetBitmap(1, 0).bmp;
|
|
case 2:
|
|
return nsbtx.GetBitmap(2, 0).bmp;
|
|
default:
|
|
return nsbtx.GetBitmap(3, 0).bmp;
|
|
}
|
|
}
|
|
if (nsbtx.texInfo.num_objs <= 8)
|
|
{ //Read nsbtx slot corresponding to overworld's movement
|
|
switch (orientation)
|
|
{
|
|
case 0:
|
|
return nsbtx.GetBitmap(0, 0).bmp;
|
|
case 1:
|
|
return nsbtx.GetBitmap(2, 0).bmp;
|
|
case 2:
|
|
return nsbtx.GetBitmap(4, 0).bmp;
|
|
default:
|
|
return nsbtx.GetBitmap(6, 0).bmp;
|
|
}
|
|
}
|
|
if (nsbtx.texInfo.num_objs <= 16)
|
|
{ // Read nsbtx slot corresponding to overworld's movement
|
|
switch (orientation)
|
|
{
|
|
case 0:
|
|
return nsbtx.GetBitmap(0, 0).bmp;
|
|
case 1:
|
|
return nsbtx.GetBitmap(11, 0).bmp;
|
|
case 2:
|
|
return nsbtx.GetBitmap(2, 0).bmp;
|
|
default:
|
|
return nsbtx.GetBitmap(4, 0).bmp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (orientation)
|
|
{
|
|
case 0:
|
|
return nsbtx.GetBitmap(0, 0).bmp;
|
|
case 1:
|
|
return nsbtx.GetBitmap(27, 0).bmp;
|
|
case 2:
|
|
return nsbtx.GetBitmap(2, 0).bmp;
|
|
default:
|
|
return nsbtx.GetBitmap(4, 0).bmp;
|
|
}
|
|
}
|
|
}
|
|
catch
|
|
{ // Load bounding box if sprite cannot be found
|
|
return (Bitmap)Properties.Resources.ResourceManager.GetObject("overworldUnreadable");
|
|
}
|
|
}
|
|
private void MarkUsedCells()
|
|
{
|
|
using (Graphics g = Graphics.FromImage(eventMatrixPictureBox.Image))
|
|
{
|
|
eventBrush = Brushes.Orange;
|
|
|
|
for (int i = 0; i < currentEvFile.spawnables.Count; i++)
|
|
{
|
|
eventMatrixRectangle = new Rectangle(2 + 16 * currentEvFile.spawnables[i].xMatrixPosition, 2 + 16 * currentEvFile.spawnables[i].yMatrixPosition, 13, 13);
|
|
g.FillRectangle(eventBrush, eventMatrixRectangle);
|
|
}
|
|
for (int i = 0; i < currentEvFile.overworlds.Count; i++)
|
|
{
|
|
eventMatrixRectangle = new Rectangle(2 + 16 * currentEvFile.overworlds[i].xMatrixPosition, 2 + 16 * currentEvFile.overworlds[i].yMatrixPosition, 13, 13);
|
|
g.FillRectangle(eventBrush, eventMatrixRectangle);
|
|
}
|
|
for (int i = 0; i < currentEvFile.warps.Count; i++)
|
|
{
|
|
eventMatrixRectangle = new Rectangle(2 + 16 * currentEvFile.warps[i].xMatrixPosition, 2 + 16 * currentEvFile.warps[i].yMatrixPosition, 13, 13);
|
|
g.FillRectangle(eventBrush, eventMatrixRectangle);
|
|
}
|
|
for (int i = 0; i < currentEvFile.triggers.Count; i++)
|
|
{
|
|
eventMatrixRectangle = new Rectangle(2 + 16 * currentEvFile.triggers[i].xMatrixPosition, 2 + 16 * currentEvFile.triggers[i].yMatrixPosition, 13, 13);
|
|
g.FillRectangle(eventBrush, eventMatrixRectangle);
|
|
}
|
|
}
|
|
eventMatrixPictureBox.Invalidate();
|
|
}
|
|
private void MarkActiveCell(int xPosition, int yPosition)
|
|
{
|
|
/* Redraw the matrix to avoid multiple green cells */
|
|
DrawEventMatrix();
|
|
MarkUsedCells();
|
|
|
|
/* Set rectangle to paint and brush color */
|
|
eventMatrixRectangle = new Rectangle(2 + 16 * xPosition, 2 + 16 * yPosition, 13, 13);
|
|
eventBrush = Brushes.Lime;
|
|
|
|
/* Paint cell */
|
|
using (Graphics g = Graphics.FromImage(eventMatrixPictureBox.Image))
|
|
{
|
|
g.FillRectangle(eventBrush, eventMatrixRectangle);
|
|
}
|
|
|
|
/* Update PictureBox and current coordinates labels */
|
|
eventMatrixPictureBox.Invalidate();
|
|
eventMatrixXUpDown.Value = xPosition;
|
|
eventMatrixYUpDown.Value = yPosition;
|
|
}
|
|
|
|
private bool isEventOnCurrentMatrix(Event ev)
|
|
{
|
|
if (ev.xMatrixPosition == eventMatrixXUpDown.Value)
|
|
{
|
|
if (ev.yMatrixPosition == eventMatrixYUpDown.Value)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
private bool isEventUnderMouse(Event ev, Point mouseTilePos, int widthX = 0, int heightY = 0)
|
|
{
|
|
if (isEventOnCurrentMatrix(ev))
|
|
{
|
|
Point evLocalCoords = new Point(ev.xMapPosition, ev.yMapPosition);
|
|
Func<int, int, int, bool> checkRange = (mouseCoord, evCoord, extension) => mouseCoord >= evCoord && mouseCoord <= evCoord + extension;
|
|
|
|
if (checkRange(mouseTilePos.X, evLocalCoords.X, widthX) && checkRange(mouseTilePos.Y, evLocalCoords.Y, heightY))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
#endregion
|
|
public void SetupEventEditor(MainProgram parent, bool force = false)
|
|
{
|
|
if (eventEditorIsReady && !force) return;
|
|
eventEditorIsReady = true;
|
|
this._parent = parent;
|
|
/* Extract essential NARCs sub-archives*/
|
|
|
|
|
|
Helpers.statusLabelMessage("Attempting to unpack Event Editor NARCs... Please wait. This might take a while");
|
|
_parent.toolStripProgressBar.Visible = true;
|
|
_parent.toolStripProgressBar.Maximum = 12;
|
|
_parent.toolStripProgressBar.Value = 0;
|
|
Update();
|
|
|
|
DSUtils.TryUnpackNarcs(new List<DirNames> { DirNames.matrices,
|
|
DirNames.maps,
|
|
DirNames.exteriorBuildingModels,
|
|
DirNames.buildingConfigFiles,
|
|
DirNames.buildingTextures,
|
|
DirNames.mapTextures,
|
|
DirNames.areaData,
|
|
|
|
DirNames.eventFiles,
|
|
DirNames.trainerProperties,
|
|
DirNames.OWSprites,
|
|
|
|
DirNames.scripts,
|
|
});
|
|
|
|
RomInfo.SetOWtable();
|
|
RomInfo.Set3DOverworldsDict();
|
|
|
|
if (RomInfo.gameFamily == GameFamilies.HGSS)
|
|
{
|
|
DSUtils.TryUnpackNarcs(new List<DirNames> { DirNames.interiorBuildingModels });
|
|
}
|
|
|
|
Helpers.DisableHandlers();
|
|
if (File.Exists(RomInfo.OWtablePath))
|
|
{
|
|
switch (RomInfo.gameFamily)
|
|
{
|
|
case GameFamilies.DP:
|
|
case GameFamilies.Plat:
|
|
break;
|
|
default:
|
|
// HGSS Overlay 1 must be decompressed in order to read the overworld table
|
|
if (OverlayUtils.OverlayTable.IsDefaultCompressed(1))
|
|
{
|
|
if (OverlayUtils.IsCompressed(1))
|
|
{
|
|
if (OverlayUtils.Decompress(1) < 0)
|
|
{
|
|
MessageBox.Show("Overlay 1 couldn't be decompressed.\nOverworld sprites in the Event Editor will be " +
|
|
"displayed incorrectly or not displayed at all.", "Unexpected EOF", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Add event file numbers to box */
|
|
Helpers.statusLabelMessage("Loading Events... Please wait.");
|
|
Update();
|
|
|
|
int eventCount = RomInfo.GetEventFileCount();
|
|
RomInfo.ReadOWTable();
|
|
|
|
eventEditorWarpHeaderListBox.Items.Clear();
|
|
eventEditorWarpHeaderListBox.Items.AddRange(EditorPanels.headerEditor.headerListBoxNames.ToArray());
|
|
eventEditorHeaderLocationNameLabel.Text = "";
|
|
|
|
string[] trainerNames = Helpers.GetTrainerNames();
|
|
_parent.toolStripProgressBar.Maximum = (int)(eventCount + RomInfo.OverworldTable.Keys.Max() + trainerNames.Length);
|
|
_parent.toolStripProgressBar.Value = 0;
|
|
Update();
|
|
|
|
/* Add event list to event combobox */
|
|
selectEventComboBox.Items.Clear();
|
|
for (int i = 0; i < eventCount; i++)
|
|
{
|
|
selectEventComboBox.Items.Add("Event File " + i);
|
|
_parent.toolStripProgressBar.Value++;
|
|
}
|
|
|
|
/* Add sprite list to ow sprite box */
|
|
owSpriteComboBox.Items.Clear();
|
|
foreach (ushort key in RomInfo.OverworldTable.Keys)
|
|
{
|
|
owSpriteComboBox.Items.Add("OW Entry " + key);
|
|
_parent.toolStripProgressBar.Value++;
|
|
}
|
|
|
|
/* Add trainer list to ow trainer box */
|
|
owTrainerComboBox.Items.Clear();
|
|
owTrainerComboBox.Items.AddRange(trainerNames);
|
|
|
|
/* Add item list to ow item box */
|
|
string[] itemNames = RomInfo.GetItemNames();
|
|
if (PatchToolboxDialog.CheckScriptsStandardizedItemNumbers())
|
|
{
|
|
_parent.UpdateItemComboBox(itemNames);
|
|
}
|
|
else
|
|
{
|
|
ScriptFile itemScript = new ScriptFile(RomInfo.itemScriptFileNumber);
|
|
owItemComboBox.Items.Clear();
|
|
foreach (ScriptCommandContainer cont in itemScript.allScripts)
|
|
{
|
|
if (cont.commands.Count > 4)
|
|
{
|
|
continue;
|
|
}
|
|
owItemComboBox.Items.Add(BitConverter.ToUInt16(cont.commands[1].cmdParams[1], 0) + "x " + itemNames[BitConverter.ToUInt16(cont.commands[0].cmdParams[1], 0)]);
|
|
}
|
|
}
|
|
|
|
/* Add ow movement list to box */
|
|
owMovementComboBox.Items.Clear();
|
|
spawnableDirComboBox.Items.Clear();
|
|
spawnableTypeComboBox.Items.Clear();
|
|
owMovementComboBox.Items.AddRange(PokeDatabase.EventEditor.Overworlds.movementTypesArray);
|
|
spawnableDirComboBox.Items.AddRange(PokeDatabase.EventEditor.Spawnables.orientationsArray);
|
|
spawnableTypeComboBox.Items.AddRange(PokeDatabase.EventEditor.Spawnables.typesArray);
|
|
|
|
/* Draw matrix 0 in matrix navigator */
|
|
eventMatrix = new GameMatrix(0);
|
|
|
|
showSpawnablesCheckBox.Checked = SettingsManager.Settings.renderSpawnables;
|
|
showOwsCheckBox.Checked = SettingsManager.Settings.renderOverworlds;
|
|
showWarpsCheckBox.Checked = SettingsManager.Settings.renderWarps;
|
|
showTriggersCheckBox.Checked = SettingsManager.Settings.renderTriggers;
|
|
|
|
if (owOrientationComboBox.SelectedIndex < 0 && overworldsListBox.Items.Count <= 0)
|
|
{
|
|
owOrientationComboBox.SelectedIndex = 2;
|
|
}
|
|
|
|
if (owMovementComboBox.SelectedIndex < 0 && overworldsListBox.Items.Count <= 0)
|
|
{
|
|
owOrientationComboBox.SelectedIndex = 1;
|
|
}
|
|
|
|
eventMatrixUpDown.Maximum = _parent.romInfo.GetMatrixCount() - 1;
|
|
eventAreaDataUpDown.Maximum = _parent.romInfo.GetAreaDataCount() - 1;
|
|
|
|
// Creating a dictionary linking events to headers to fetch header data for Event Editor
|
|
if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied())
|
|
{
|
|
for (ushort i = 0; i < EditorPanels.headerEditor.internalNames.Count; i++)
|
|
{
|
|
MapHeader h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + i.ToString("D4"), i, 0);
|
|
_parent.eventToHeader[h.eventFileID] = i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (ushort i = 0; i < EditorPanels.headerEditor.internalNames.Count; i++)
|
|
{
|
|
MapHeader h = MapHeader.LoadFromARM9(i);
|
|
_parent.eventToHeader[h.eventFileID] = i;
|
|
}
|
|
}
|
|
|
|
Helpers.EnableHandlers();
|
|
|
|
selectEventComboBox.SelectedIndex = 0;
|
|
owItemComboBox.SelectedIndex = 0;
|
|
owTrainerComboBox.SelectedIndex = 0;
|
|
|
|
_parent.toolStripProgressBar.Value = 0;
|
|
_parent.toolStripProgressBar.Visible = false;
|
|
|
|
Helpers.statusLabelMessage();
|
|
}
|
|
private void addEventFileButton_Click(object sender, EventArgs e)
|
|
{
|
|
/* Add copy of event 0 to event folder */
|
|
new EventFile().SaveToFileDefaultDir(selectEventComboBox.Items.Count);
|
|
|
|
/* Update ComboBox and select new file */
|
|
selectEventComboBox.Items.Add("Event File " + selectEventComboBox.Items.Count);
|
|
selectEventComboBox.SelectedIndex = selectEventComboBox.Items.Count - 1;
|
|
}
|
|
|
|
private void eventMatrixPictureBox_Click(object sender, EventArgs e)
|
|
{
|
|
const int squareSize = 16;
|
|
Point coordinates = eventMatrixPictureBox.PointToClient(Cursor.Position);
|
|
Point mouseTilePos = new Point(coordinates.X / squareSize, coordinates.Y / squareSize);
|
|
|
|
MarkActiveCell(mouseTilePos.X, mouseTilePos.Y);
|
|
eventMatrixXUpDown.Value = mouseTilePos.X;
|
|
eventMatrixYUpDown.Value = mouseTilePos.Y;
|
|
}
|
|
public void eventMatrixUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
Helpers.DisableHandlers();
|
|
|
|
eventMatrix = new GameMatrix((int)eventMatrixUpDown.Value);
|
|
eventMatrixXUpDown.Maximum = eventMatrix.width - 1;
|
|
eventMatrixYUpDown.Maximum = eventMatrix.height - 1;
|
|
eventEditorFullMapReload((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value);
|
|
|
|
Helpers.EnableHandlers();
|
|
|
|
CenterEventViewOnEntities();
|
|
}
|
|
private void eventShiftLeftButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (eventMatrixXUpDown.Value > 0)
|
|
{
|
|
eventMatrixXUpDown.Value -= 1;
|
|
}
|
|
}
|
|
private void eventShiftUpButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (eventMatrixYUpDown.Value > 0)
|
|
{
|
|
eventMatrixYUpDown.Value -= 1;
|
|
}
|
|
}
|
|
private void eventShiftRightButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (eventMatrixXUpDown.Value < eventMatrix.width - 1)
|
|
{
|
|
eventMatrixXUpDown.Value += 1;
|
|
}
|
|
}
|
|
private void eventShiftDownButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (eventMatrixYUpDown.Value < eventMatrix.height - 1)
|
|
{
|
|
eventMatrixYUpDown.Value += 1;
|
|
}
|
|
}
|
|
private void eventMatrixCoordsUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
eventEditorFullMapReload((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value);
|
|
}
|
|
private void eventEditorFullMapReload(int coordX, int coordY)
|
|
{
|
|
/* Draw matrix image in the navigator */
|
|
MarkActiveCell(coordX, coordY);
|
|
/* Render events on map */
|
|
DisplayEventMap();
|
|
DisplayActiveEvents();
|
|
eventMatrixPictureBox.Invalidate();
|
|
}
|
|
private void exportEventFileButton_Click(object sender, EventArgs e)
|
|
{
|
|
currentEvFile.SaveToFileExplorePath("Event File " + selectEventComboBox.SelectedIndex);
|
|
}
|
|
private void saveEventsButton_Click(object sender, EventArgs e)
|
|
{
|
|
|
|
|
|
|
|
currentEvFile.SaveToFileDefaultDir(selectEventComboBox.SelectedIndex);
|
|
}
|
|
private void importEventFileButton_Click(object sender, EventArgs e)
|
|
{
|
|
/* Prompt user to select .evt file */
|
|
OpenFileDialog of = new OpenFileDialog
|
|
{
|
|
Filter = EventFile.DefaultFilter
|
|
};
|
|
if (of.ShowDialog(this) != DialogResult.OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
EventFile toImport = new EventFile(File.OpenRead(of.FileName));
|
|
if (toImport.isEmpty())
|
|
{
|
|
DialogResult d = MessageBox.Show("Are you sure you want to import an empty event file?\nAll existing entities in the current file will disappear.", "Empty File loaded", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
if (!d.Equals(DialogResult.Yes))
|
|
{
|
|
return;
|
|
}
|
|
|
|
/* Update event object on disk */
|
|
File.Copy(of.FileName, RomInfo.gameDirs[DirNames.eventFiles].unpackedDir + "\\" + selectEventComboBox.SelectedIndex.ToString("D4"), true);
|
|
|
|
|
|
/* Refresh controls */
|
|
selectEventComboBox_SelectedIndexChanged(null, null);
|
|
|
|
/* Display success message */
|
|
MessageBox.Show("Events imported successfully!", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
|
|
/* Refresh controls */
|
|
selectEventComboBox_SelectedIndexChanged(null, null);
|
|
}
|
|
else
|
|
{
|
|
EventFileImport efi = new EventFileImport(toImport);
|
|
efi.ShowDialog();
|
|
|
|
if (!efi.DialogResult.Equals(DialogResult.OK))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (efi.blankCurrentEvents)
|
|
{
|
|
DialogResult confirm = MessageBox.Show("You chose to import the entities into blank event file, which means all existing entities in the destination file will be deleted.\nProceed?", "Awaiting user confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
if (!confirm.Equals(DialogResult.Yes))
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile = new EventFile();
|
|
spawnablesListBox.Items.Clear();
|
|
overworldsListBox.Items.Clear();
|
|
warpsListBox.Items.Clear();
|
|
triggersListBox.Items.Clear();
|
|
}
|
|
|
|
|
|
int[] currentArray;
|
|
|
|
currentArray = efi.userSelected[(int)EventFile.serializationOrder.Spawnables];
|
|
if (currentArray != null)
|
|
{
|
|
foreach (int index in currentArray)
|
|
{
|
|
currentEvFile.spawnables.Add(toImport.spawnables[index]);
|
|
|
|
spawnablesListBox.Items.Add("");
|
|
spawnablesListBox.SelectedIndex = spawnablesListBox.Items.Count - 1;
|
|
updateSelectedSpawnableName();
|
|
}
|
|
}
|
|
|
|
currentArray = efi.userSelected[(int)EventFile.serializationOrder.Overworlds];
|
|
if (currentArray != null)
|
|
{
|
|
foreach (int index in currentArray)
|
|
{
|
|
currentEvFile.overworlds.Add(toImport.overworlds[index]);
|
|
|
|
overworldsListBox.Items.Add("");
|
|
overworldsListBox.SelectedIndex = overworldsListBox.Items.Count - 1;
|
|
updateSelectedOverworldName();
|
|
}
|
|
}
|
|
|
|
currentArray = efi.userSelected[(int)EventFile.serializationOrder.Warps];
|
|
if (currentArray != null)
|
|
{
|
|
foreach (int index in currentArray)
|
|
{
|
|
currentEvFile.warps.Add(toImport.warps[index]);
|
|
|
|
warpsListBox.Items.Add("");
|
|
warpsListBox.SelectedIndex = warpsListBox.Items.Count - 1;
|
|
updateSelectedWarpName();
|
|
}
|
|
}
|
|
|
|
currentArray = efi.userSelected[(int)EventFile.serializationOrder.Triggers];
|
|
if (currentArray != null)
|
|
{
|
|
foreach (int index in currentArray)
|
|
{
|
|
currentEvFile.triggers.Add(toImport.triggers[index]);
|
|
|
|
triggersListBox.Items.Add("");
|
|
triggersListBox.SelectedIndex = triggersListBox.Items.Count - 1;
|
|
updateSelectedTriggerName();
|
|
}
|
|
}
|
|
|
|
/* Display success message */
|
|
MessageBox.Show("Events imported successfully!\nRemember to save the current Event File.", "", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
}
|
|
private void removeEventFileButton_Click(object sender, EventArgs e)
|
|
{
|
|
DialogResult d = MessageBox.Show("Are you sure you want to delete the last Event File?", "Confirm deletion", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
|
|
if (d.Equals(DialogResult.Yes))
|
|
{
|
|
/* Delete event file */
|
|
File.Delete(RomInfo.gameDirs[DirNames.eventFiles].unpackedDir + "\\" + (selectEventComboBox.Items.Count - 1).ToString("D4"));
|
|
|
|
/* Check if currently selected file is the last one, and in that case select the one before it */
|
|
int lastIndex = selectEventComboBox.Items.Count - 1;
|
|
if (selectEventComboBox.SelectedIndex == lastIndex)
|
|
{
|
|
selectEventComboBox.SelectedIndex--;
|
|
}
|
|
|
|
/* Remove item from ComboBox */
|
|
selectEventComboBox.Items.RemoveAt(lastIndex);
|
|
}
|
|
}
|
|
public void selectEventComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ChangeLoadedEventFile(selectEventComboBox.SelectedIndex, 0);
|
|
}
|
|
|
|
private void ChangeLoadedEventFile(int evfile, ushort mapHeader)
|
|
{
|
|
Helpers.DisableHandlers();
|
|
|
|
/* Load events data into EventFile class instance */
|
|
currentEvFile = new EventFile(evfile);
|
|
|
|
/* Update ListBoxes */
|
|
FillSpawnablesBox();
|
|
FillOverworldsBox();
|
|
FillTriggersBox();
|
|
FillWarpsBox();
|
|
|
|
if (mapHeader > 0 || _parent.eventToHeader.TryGetValue((ushort)selectEventComboBox.SelectedIndex, out mapHeader))
|
|
{
|
|
MapHeader h;
|
|
if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied())
|
|
{
|
|
h = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + mapHeader.ToString("D4"), mapHeader, 0);
|
|
}
|
|
else
|
|
{
|
|
h = MapHeader.LoadFromARM9(mapHeader);
|
|
}
|
|
eventMatrixUpDown.Value = h.matrixID;
|
|
|
|
eventMatrix = new GameMatrix((int)eventMatrixUpDown.Value);
|
|
eventMatrixXUpDown.Maximum = eventMatrix.width - 1;
|
|
eventMatrixYUpDown.Maximum = eventMatrix.height - 1;
|
|
eventAreaDataUpDown.Value = h.areaDataID;
|
|
|
|
Helpers.statusLabelMessage($"Detected link between Event File {selectEventComboBox.SelectedIndex} and Header {mapHeader}");
|
|
}
|
|
else
|
|
{
|
|
Helpers.statusLabelError($"Could not link Event File {selectEventComboBox.SelectedIndex} to any Header");
|
|
}
|
|
|
|
eventEditorFullMapReload((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value);
|
|
|
|
Helpers.EnableHandlers();
|
|
|
|
CenterEventViewOnEntities();
|
|
}
|
|
|
|
private void showEventsCheckBoxes_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
|
|
DisplayActiveEvents();
|
|
SettingsManager.Settings.renderSpawnables = showSpawnablesCheckBox.Checked;
|
|
SettingsManager.Settings.renderOverworlds = showOwsCheckBox.Checked;
|
|
SettingsManager.Settings.renderWarps = showWarpsCheckBox.Checked;
|
|
SettingsManager.Settings.renderTriggers = showTriggersCheckBox.Checked;
|
|
}
|
|
private void eventAreaDataUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
DisplayEventMap(readGraphicsFromHeader: false);
|
|
}
|
|
private void eventPictureBox_Click(object sender, EventArgs e)
|
|
{
|
|
Point coordinates = eventPictureBox.PointToClient(Cursor.Position);
|
|
Point mouseTilePos = new Point(coordinates.X / (tileSize + 1), coordinates.Y / (tileSize + 1));
|
|
MouseEventArgs mea = (MouseEventArgs)e;
|
|
|
|
if (mea.Button == MouseButtons.Left)
|
|
{
|
|
if (selectedEvent != null)
|
|
{
|
|
switch (selectedEvent.evType)
|
|
{
|
|
case Event.EventType.Spawnable:
|
|
if (!showSpawnablesCheckBox.Checked)
|
|
{
|
|
return;
|
|
}
|
|
spawnablexMapUpDown.Value = (short)mouseTilePos.X;
|
|
spawnableYMapUpDown.Value = (short)mouseTilePos.Y;
|
|
spawnableXMatrixUpDown.Value = (short)eventMatrixXUpDown.Value;
|
|
spawnableYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value;
|
|
|
|
break;
|
|
case Event.EventType.Overworld:
|
|
if (!showOwsCheckBox.Checked)
|
|
{
|
|
return;
|
|
}
|
|
owXMapUpDown.Value = (short)mouseTilePos.X;
|
|
owYMapUpDown.Value = (short)mouseTilePos.Y;
|
|
owXMatrixUpDown.Value = (short)eventMatrixXUpDown.Value;
|
|
owYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value;
|
|
|
|
break;
|
|
case Event.EventType.Warp:
|
|
if (!showWarpsCheckBox.Checked)
|
|
{
|
|
return;
|
|
}
|
|
warpXMapUpDown.Value = (short)mouseTilePos.X;
|
|
warpYMapUpDown.Value = (short)mouseTilePos.Y;
|
|
warpXMatrixUpDown.Value = (short)eventMatrixXUpDown.Value;
|
|
warpYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value;
|
|
|
|
break;
|
|
case Event.EventType.Trigger:
|
|
if (!showTriggersCheckBox.Checked)
|
|
{
|
|
return;
|
|
}
|
|
triggerXMapUpDown.Value = (short)mouseTilePos.X;
|
|
triggerYMapUpDown.Value = (short)mouseTilePos.Y;
|
|
triggerXMatrixUpDown.Value = (short)eventMatrixXUpDown.Value;
|
|
triggerYMatrixUpDown.Value = (short)eventMatrixYUpDown.Value;
|
|
|
|
break;
|
|
}
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
else if (mea.Button == MouseButtons.Right)
|
|
{
|
|
if (showWarpsCheckBox.Checked)
|
|
for (int i = 0; i < currentEvFile.warps.Count; i++)
|
|
{
|
|
Warp ev = currentEvFile.warps[i];
|
|
|
|
if (isEventUnderMouse(ev, mouseTilePos))
|
|
{
|
|
if (ev == selectedEvent)
|
|
{
|
|
goToWarpDestination_Click(sender, e);
|
|
return;
|
|
}
|
|
selectedEvent = ev;
|
|
eventsTabControl.SelectedTab = warpsTabPage;
|
|
warpsListBox.SelectedIndex = i;
|
|
DisplayActiveEvents();
|
|
return;
|
|
}
|
|
}
|
|
if (showSpawnablesCheckBox.Checked)
|
|
for (int i = 0; i < currentEvFile.spawnables.Count; i++)
|
|
{
|
|
Spawnable ev = currentEvFile.spawnables[i];
|
|
|
|
if (isEventUnderMouse(ev, mouseTilePos))
|
|
{
|
|
selectedEvent = ev;
|
|
eventsTabControl.SelectedTab = signsTabPage;
|
|
spawnablesListBox.SelectedIndex = i;
|
|
DisplayActiveEvents();
|
|
return;
|
|
}
|
|
}
|
|
if (showOwsCheckBox.Checked)
|
|
for (int i = 0; i < currentEvFile.overworlds.Count; i++)
|
|
{
|
|
Overworld ev = currentEvFile.overworlds[i];
|
|
|
|
if (isEventUnderMouse(ev, mouseTilePos))
|
|
{
|
|
selectedEvent = ev;
|
|
eventsTabControl.SelectedTab = overworldsTabPage;
|
|
overworldsListBox.SelectedIndex = i;
|
|
DisplayActiveEvents();
|
|
return;
|
|
}
|
|
}
|
|
for (int i = 0; i < currentEvFile.triggers.Count; i++)
|
|
{
|
|
Trigger ev = currentEvFile.triggers[i];
|
|
|
|
if (isEventUnderMouse(ev, mouseTilePos, ev.widthX - 1, ev.heightY - 1))
|
|
{
|
|
selectedEvent = ev;
|
|
eventsTabControl.SelectedTab = triggersTabPage;
|
|
triggersListBox.SelectedIndex = i;
|
|
DisplayActiveEvents();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
else if (mea.Button == MouseButtons.Middle)
|
|
{
|
|
for (int i = 0; i < currentEvFile.warps.Count; i++)
|
|
{
|
|
Warp ev = currentEvFile.warps[i];
|
|
|
|
if (isEventUnderMouse(ev, mouseTilePos))
|
|
{
|
|
if (ev == selectedEvent)
|
|
{
|
|
goToWarpDestination_Click(sender, e);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#region Spawnables Tab
|
|
private void addSpawnableButton_Click(object sender, EventArgs e)
|
|
{
|
|
int spCount = currentEvFile.spawnables.Count;
|
|
|
|
currentEvFile.spawnables.Add(new Spawnable((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value));
|
|
|
|
spawnablesListBox.Items.Add("");
|
|
spawnablesListBox.SelectedIndex = spCount;
|
|
updateSelectedSpawnableName();
|
|
}
|
|
private void removeSpawnableButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (spawnablesListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Helpers.DisableHandlers();
|
|
|
|
/* Remove trigger object from list and the corresponding entry in the ListBox */
|
|
int spawnableNumber = spawnablesListBox.SelectedIndex;
|
|
currentEvFile.spawnables.RemoveAt(spawnableNumber);
|
|
spawnablesListBox.Items.RemoveAt(spawnableNumber);
|
|
|
|
FillSpawnablesBox(); // Update ListBox
|
|
|
|
Helpers.EnableHandlers();
|
|
|
|
if (spawnableNumber > 0)
|
|
{
|
|
spawnablesListBox.SelectedIndex = spawnableNumber - 1;
|
|
}
|
|
else
|
|
{
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
private void duplicateSpawnableButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (spawnablesListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables.Add(new Spawnable((Spawnable)selectedEvent));
|
|
|
|
spawnablesListBox.Items.Add("");
|
|
spawnablesListBox.SelectedIndex = spawnablesListBox.Items.Count - 1;
|
|
updateSelectedSpawnableName();
|
|
}
|
|
private void spawnablesListBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled || spawnablesListBox.SelectedIndex < 0)
|
|
return;
|
|
Helpers.DisableHandlers();
|
|
|
|
/* Set Event */
|
|
selectedEvent = currentEvFile.spawnables[spawnablesListBox.SelectedIndex];
|
|
|
|
/* Update Controls */
|
|
spawnableDirComboBox.SelectedIndex = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].dir;
|
|
spawnableTypeComboBox.SelectedIndex = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].type;
|
|
|
|
spawnableScriptUpDown.Value = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].scriptNumber;
|
|
spawnablexMapUpDown.Value = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].xMapPosition;
|
|
spawnableYMapUpDown.Value = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].yMapPosition;
|
|
spawnableUpDown.Value = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].zPosition;
|
|
spawnableXMatrixUpDown.Value = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].xMatrixPosition;
|
|
spawnableYMatrixUpDown.Value = currentEvFile.spawnables[spawnablesListBox.SelectedIndex].yMatrixPosition;
|
|
|
|
DisplayActiveEvents();
|
|
Helpers.EnableHandlers();
|
|
}
|
|
private void spawnableMatrixXUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].xMatrixPosition = (ushort)spawnableXMatrixUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void spawnableMatrixYUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].yMatrixPosition = (ushort)spawnableYMatrixUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void spawnableScriptUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].scriptNumber = (ushort)spawnableScriptUpDown.Value;
|
|
updateSelectedSpawnableName();
|
|
}
|
|
private void spawnableMapXUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].xMapPosition = (short)spawnablexMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void spawnableMapYUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].yMapPosition = (short)spawnableYMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void spawnableZUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].zPosition = (short)spawnableUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void spawnableDirComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].dir = (ushort)spawnableDirComboBox.SelectedIndex;
|
|
updateSelectedSpawnableName();
|
|
}
|
|
private void spawnableTypeComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedSpawnable = spawnablesListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selectedSpawnable < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
spawnableDirComboBox.Enabled = spawnableTypeComboBox.SelectedIndex != Spawnable.TYPE_HIDDENITEM;
|
|
|
|
currentEvFile.spawnables[selectedSpawnable].type = (ushort)spawnableTypeComboBox.SelectedIndex;
|
|
updateSelectedSpawnableName();
|
|
}
|
|
#endregion
|
|
|
|
#region Overworlds Tab
|
|
private void addOverworldButton_Click(object sender, EventArgs e)
|
|
{
|
|
int owCount = currentEvFile.overworlds.Count;
|
|
// Find the smallest unused ID
|
|
int newID = 0;
|
|
while (currentEvFile.overworlds.Any(ow => ow.owID == newID))
|
|
{
|
|
newID++;
|
|
}
|
|
currentEvFile.overworlds.Add(new Overworld(newID, (int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value));
|
|
|
|
overworldsListBox.Items.Add("");
|
|
overworldsListBox.SelectedIndex = owCount;
|
|
updateSelectedOverworldName();
|
|
}
|
|
private void removeOverworldButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (overworldsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Helpers.DisableHandlers();
|
|
|
|
/* Remove overworld object from list and the corresponding entry in the ListBox */
|
|
int owNumber = overworldsListBox.SelectedIndex;
|
|
currentEvFile.overworlds.RemoveAt(owNumber);
|
|
overworldsListBox.Items.RemoveAt(owNumber);
|
|
|
|
FillOverworldsBox(); // Update ListBox
|
|
Helpers.EnableHandlers();
|
|
|
|
if (owNumber > 0)
|
|
{
|
|
overworldsListBox.SelectedIndex = owNumber - 1;
|
|
}
|
|
else
|
|
{
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
private void sortOWsByIDAscButton_Click(object sender, EventArgs e)
|
|
{
|
|
currentEvFile.overworlds.Sort((x, y) => x.owID.CompareTo(y.owID));
|
|
overworldsListBox.BeginUpdate();
|
|
FillOverworldsBox();
|
|
overworldsListBox.EndUpdate();
|
|
}
|
|
|
|
private void sortOWsByIDDescButton_Click(object sender, EventArgs e)
|
|
{
|
|
currentEvFile.overworlds.Sort((x, y) => y.owID.CompareTo(x.owID));
|
|
overworldsListBox.BeginUpdate();
|
|
FillOverworldsBox();
|
|
overworldsListBox.EndUpdate();
|
|
}
|
|
|
|
private void locateCurrentEvFile_Click(object sender, EventArgs e)
|
|
{
|
|
Helpers.ExplorerSelect(Path.Combine(gameDirs[DirNames.eventFiles].unpackedDir, selectEventComboBox.SelectedIndex.ToString("D4")));
|
|
}
|
|
|
|
private void duplicateOverworldsButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (overworldsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Find the smallest unused ID
|
|
int newID = 0;
|
|
while (currentEvFile.overworlds.Any(ow => ow.owID == newID))
|
|
{
|
|
newID++;
|
|
}
|
|
var newOvw = new Overworld(selectedEvent as Overworld);
|
|
newOvw.owID = (ushort)newID;
|
|
currentEvFile.overworlds.Add(newOvw);
|
|
|
|
overworldsListBox.Items.Add("");
|
|
overworldsListBox.SelectedIndex = currentEvFile.overworlds.Count - 1;
|
|
updateSelectedOverworldName();
|
|
}
|
|
private void eventsTabControl_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (eventsTabControl.SelectedTab == signsTabPage)
|
|
{
|
|
int spawnablesCount = spawnablesListBox.Items.Count;
|
|
|
|
if (spawnablesCount > 0)
|
|
{
|
|
spawnablesListBox.SelectedIndex = 0;
|
|
}
|
|
}
|
|
else if (eventsTabControl.SelectedTab == overworldsTabPage)
|
|
{
|
|
int overworldsCount = overworldsListBox.Items.Count;
|
|
|
|
int selected = 0;
|
|
|
|
if (overworldsCount > 0)
|
|
{
|
|
if (selectedEvent is Overworld)
|
|
{
|
|
int owId = (selectedEvent as Overworld).owID;
|
|
if (owId < overworldsCount)
|
|
{
|
|
selected = owId;
|
|
}
|
|
}
|
|
overworldsListBox.SelectedIndex = selected;
|
|
}
|
|
}
|
|
else if (eventsTabControl.SelectedTab == warpsTabPage)
|
|
{
|
|
int warpsCount = warpsListBox.Items.Count;
|
|
|
|
if (warpsCount > 0)
|
|
{
|
|
warpsListBox.SelectedIndex = 0;
|
|
}
|
|
}
|
|
else if (eventsTabControl.SelectedTab == triggersTabPage)
|
|
{
|
|
int triggersCount = triggersListBox.Items.Count;
|
|
|
|
if (triggersCount > 0)
|
|
{
|
|
triggersListBox.SelectedIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
public void OWTypeChanged(object sender, EventArgs e)
|
|
{
|
|
if (overworldsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (normalRadioButton.Checked == true)
|
|
{
|
|
owScriptNumericUpDown.Enabled = true;
|
|
owSpecialGroupBox.Enabled = false;
|
|
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].type = 0x0;
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].scriptNumber = (ushort)(owScriptNumericUpDown.Value = 0);
|
|
}
|
|
else if (isItemRadioButton.Checked == true)
|
|
{
|
|
owScriptNumericUpDown.Enabled = false;
|
|
|
|
owSpecialGroupBox.Enabled = true;
|
|
owTrainerComboBox.Enabled = false;
|
|
owTrainerLabel.Enabled = false;
|
|
owSightRangeUpDown.Enabled = false;
|
|
owSightRangeLabel.Enabled = false;
|
|
owPartnerTrainerCheckBox.Enabled = false;
|
|
|
|
if (isItemRadioButton.Enabled)
|
|
{
|
|
owItemComboBox.Enabled = true;
|
|
itemsSelectorHelpBtn.Enabled = true;
|
|
owItemLabel.Enabled = true;
|
|
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].type = 0x3;
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].scriptNumber = (ushort)(owScriptNumericUpDown.Value = 7000 + owItemComboBox.SelectedIndex);
|
|
}
|
|
}
|
|
else
|
|
{ //trainer
|
|
owScriptNumericUpDown.Enabled = false;
|
|
|
|
owSpecialGroupBox.Enabled = true;
|
|
owTrainerComboBox.Enabled = true;
|
|
owTrainerLabel.Enabled = true;
|
|
owItemLabel.Enabled = false;
|
|
owSightRangeUpDown.Enabled = true;
|
|
owSightRangeLabel.Enabled = true;
|
|
owPartnerTrainerCheckBox.Enabled = true;
|
|
|
|
owItemComboBox.Enabled = false;
|
|
itemsSelectorHelpBtn.Enabled = false;
|
|
|
|
if (Helpers.HandlersDisabled)
|
|
{
|
|
return;
|
|
}
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].type = 0x1;
|
|
if (owTrainerComboBox.SelectedIndex >= 0)
|
|
{
|
|
owTrainerComboBox_SelectedIndexChanged(null, null);
|
|
}
|
|
}
|
|
}
|
|
private void owItemComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled || overworldsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
owScriptNumericUpDown.Value = currentEvFile.overworlds[overworldsListBox.SelectedIndex].scriptNumber = (ushort)(7000 + owItemComboBox.SelectedIndex);
|
|
}
|
|
private void overworldsListBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
int index = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || index < 0)
|
|
{
|
|
return;
|
|
}
|
|
Helpers.DisableHandlers();
|
|
|
|
selectedEvent = currentEvFile.overworlds[index];
|
|
Overworld selectedOw = (Overworld)selectedEvent;
|
|
try
|
|
{
|
|
/* Sprite index and image controls */
|
|
owSpriteComboBox.SelectedIndex = Array.IndexOf(RomInfo.overworldTableKeys, selectedOw.overlayTableEntry);
|
|
owSpritePictureBox.BackgroundImage = GetOverworldImage(selectedOw.overlayTableEntry, selectedOw.orientation);
|
|
}
|
|
catch (ArgumentOutOfRangeException)
|
|
{
|
|
String errorMsg = "This Overworld's sprite ID couldn't be read correctly.";
|
|
MessageBox.Show(errorMsg, "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
|
|
try
|
|
{
|
|
/* Special settings controls */
|
|
if (selectedOw.type == (ushort)Overworld.OwType.TRAINER)
|
|
{
|
|
isTrainerRadioButton.Checked = true;
|
|
if (selectedOw.scriptNumber >= 4999)
|
|
{
|
|
owTrainerComboBox.SelectedIndex = Math.Max(selectedOw.scriptNumber - 4999, 0); // Partner of double battle trainer
|
|
owPartnerTrainerCheckBox.Checked = true;
|
|
}
|
|
else
|
|
{
|
|
owTrainerComboBox.SelectedIndex = Math.Max(selectedOw.scriptNumber - 2999, 0); // Normal trainer
|
|
owPartnerTrainerCheckBox.Checked = false;
|
|
}
|
|
}
|
|
else if (selectedOw.type == (ushort)Overworld.OwType.ITEM || selectedOw.scriptNumber >= 7000 && selectedOw.scriptNumber <= 8000)
|
|
{
|
|
isItemRadioButton.Checked = true;
|
|
owItemComboBox.SelectedIndex = Math.Max(selectedOw.scriptNumber - 7000, 0);
|
|
}
|
|
else
|
|
{
|
|
normalRadioButton.Checked = true;
|
|
}
|
|
|
|
/* Set coordinates controls */
|
|
owXMapUpDown.Value = selectedOw.xMapPosition;
|
|
owYMapUpDown.Value = selectedOw.yMapPosition;
|
|
owXMatrixUpDown.Value = selectedOw.xMatrixPosition;
|
|
owYMatrixUpDown.Value = selectedOw.yMatrixPosition;
|
|
|
|
int zFld = (selectedOw.zPosition >> 4) /*convert from overworld units to fx*/;
|
|
owZPositionUpDown.Value = zFld / 0x1000; //then convert from fixed point to decimal
|
|
|
|
/*ID, Flag and Script number controls */
|
|
owIDNumericUpDown.Value = selectedOw.owID;
|
|
owFlagNumericUpDown.Value = selectedOw.flag;
|
|
owScriptNumericUpDown.Value = selectedOw.scriptNumber;
|
|
|
|
/* Movement settings */
|
|
owMovementComboBox.SelectedIndex = selectedOw.movement;
|
|
owOrientationComboBox.SelectedIndex = selectedOw.orientation;
|
|
owSightRangeUpDown.Value = selectedOw.sightRange;
|
|
owXRangeUpDown.Value = selectedOw.xRange;
|
|
owYRangeUpDown.Value = selectedOw.yRange;
|
|
|
|
try
|
|
{
|
|
uint spriteID = RomInfo.OverworldTable[currentEvFile.overworlds[overworldsListBox.SelectedIndex].overlayTableEntry].spriteID;
|
|
if (spriteID == 0x3D3D)
|
|
{
|
|
spriteIDlabel.Text = "3D Overworld";
|
|
}
|
|
else
|
|
{
|
|
spriteIDlabel.Text = "Sprite ID: " + spriteID;
|
|
}
|
|
}
|
|
catch { }
|
|
DisplayActiveEvents();
|
|
}
|
|
catch (ArgumentOutOfRangeException)
|
|
{
|
|
String errorMsg = "There was a problem loading the overworld events of this Event file.";
|
|
MessageBox.Show(errorMsg, "Something went wrong", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
}
|
|
|
|
Helpers.EnableHandlers();
|
|
}
|
|
private void owFlagNumericUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[selection].flag = (ushort)owFlagNumericUpDown.Value;
|
|
}
|
|
private void owIDNumericUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[selection].owID = (ushort)owIDNumericUpDown.Value;
|
|
updateSelectedOverworldName();
|
|
}
|
|
private void owMovementComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[selection].movement = (ushort)owMovementComboBox.SelectedIndex;
|
|
}
|
|
private void owOrientationComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
ushort orientation = (ushort)owOrientationComboBox.SelectedIndex;
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
if (owSpriteComboBox.SelectedIndex < 0 || orientation < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (selection >= 0)
|
|
{
|
|
owSpritePictureBox.BackgroundImage = GetOverworldImage(currentEvFile.overworlds[selection].overlayTableEntry, orientation);
|
|
|
|
if (Helpers.HandlersEnabled)
|
|
{
|
|
currentEvFile.overworlds[selection].orientation = orientation;
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
owSpritePictureBox.BackgroundImage = GetOverworldImage((ushort)owSpriteComboBox.SelectedIndex, orientation);
|
|
}
|
|
|
|
owSpritePictureBox.Invalidate();
|
|
}
|
|
private void owScriptNumericUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[selection].scriptNumber = (ushort)owScriptNumericUpDown.Value;
|
|
updateSelectedOverworldName();
|
|
}
|
|
private void owSightRangeUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
currentEvFile.overworlds[selection].sightRange = (ushort)owSightRangeUpDown.Value;
|
|
}
|
|
|
|
private void owSpriteComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
if (owSpriteComboBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
ushort overlayTableEntryID = (ushort)RomInfo.OverworldTable.Keys.ElementAt(owSpriteComboBox.SelectedIndex);
|
|
uint spriteID = RomInfo.OverworldTable[overlayTableEntryID].spriteID;
|
|
|
|
if (spriteID == 0x3D3D)
|
|
{
|
|
spriteIDlabel.Text = "3D Overworld";
|
|
}
|
|
else
|
|
{
|
|
spriteIDlabel.Text = "Sprite ID: " + spriteID;
|
|
}
|
|
|
|
if (selection >= 0)
|
|
{
|
|
owSpritePictureBox.BackgroundImage = GetOverworldImage(overlayTableEntryID, currentEvFile.overworlds[selection].orientation);
|
|
|
|
if (Helpers.HandlersEnabled)
|
|
{
|
|
currentEvFile.overworlds[selection].overlayTableEntry = overlayTableEntryID;
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
owSpritePictureBox.BackgroundImage = GetOverworldImage(overlayTableEntryID, (ushort)owOrientationComboBox.SelectedIndex);
|
|
}
|
|
owSpritePictureBox.Invalidate();
|
|
updateSelectedOverworldName();
|
|
}
|
|
private void owPartnerTrainerCheckBox_CheckedChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
owScriptNumericUpDown.Value = (ushort)(currentEvFile.overworlds[selection].scriptNumber + (owPartnerTrainerCheckBox.Checked ? 2000 : -2000));
|
|
}
|
|
|
|
private void owTrainerComboBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
ushort scriptNum = (ushort)(owTrainerComboBox.SelectedIndex + (owPartnerTrainerCheckBox.Checked ? 4999 : 2999));
|
|
if (owTrainerComboBox.SelectedIndex > trainerFunnyScriptNumber - 1)
|
|
{
|
|
scriptNum++;
|
|
}
|
|
owScriptNumericUpDown.Value = scriptNum;
|
|
}
|
|
|
|
private void owXMapUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].xMapPosition = (short)owXMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void owXRangeUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].xRange = (ushort)owXRangeUpDown.Value;
|
|
}
|
|
private void owYRangeUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].yRange = (ushort)owYRangeUpDown.Value;
|
|
}
|
|
private void owYMapUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[overworldsListBox.SelectedIndex].yMapPosition = (short)owYMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void owZPositionUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int zFld = (short)owZPositionUpDown.Value << 4; //decimal to overworld units
|
|
currentEvFile.overworlds[selection].zPosition = zFld * 0x1000; //overworld units to fixed point
|
|
}
|
|
private void owXMatrixUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[selection].xMatrixPosition = (ushort)owXMatrixUpDown.Value;
|
|
eventMatrixPictureBox.Image = new Bitmap(eventMatrixPictureBox.Width, eventMatrixPictureBox.Height);
|
|
MarkActiveCell((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value);
|
|
DisplayActiveEvents();
|
|
}
|
|
private void owYMatrixUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = overworldsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.overworlds[selection].yMatrixPosition = (ushort)owYMatrixUpDown.Value;
|
|
eventMatrixPictureBox.Image = new Bitmap(eventMatrixPictureBox.Width, eventMatrixPictureBox.Height);
|
|
MarkActiveCell((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value);
|
|
DisplayActiveEvents();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Warps Tab
|
|
private void addWarpButton_Click(object sender, EventArgs e)
|
|
{
|
|
Warp n = new Warp((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value);
|
|
currentEvFile.warps.Add(n);
|
|
|
|
int index = currentEvFile.warps.Count - 1;
|
|
|
|
warpsListBox.Items.Add("");
|
|
warpsListBox.SelectedIndex = index;
|
|
updateSelectedWarpName();
|
|
|
|
eventEditorWarpHeaderListBox.SelectedIndex = n.header;
|
|
}
|
|
private void removeWarpButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (warpsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Helpers.DisableHandlers();
|
|
|
|
/* Remove warp object from list and the corresponding entry in the ListBox */
|
|
int warpNumber = warpsListBox.SelectedIndex;
|
|
currentEvFile.warps.RemoveAt(warpNumber);
|
|
warpsListBox.Items.RemoveAt(warpNumber);
|
|
|
|
FillWarpsBox(); // Update ListBox
|
|
|
|
Helpers.EnableHandlers();
|
|
|
|
if (warpNumber > 0)
|
|
{
|
|
warpsListBox.SelectedIndex = warpNumber - 1;
|
|
}
|
|
else
|
|
{
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
private void duplicateWarpsButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (warpsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Warp n = new Warp(selectedEvent as Warp);
|
|
currentEvFile.warps.Add(n);
|
|
|
|
int index = currentEvFile.warps.Count - 1;
|
|
|
|
warpsListBox.Items.Add("");
|
|
warpsListBox.SelectedIndex = index;
|
|
updateSelectedWarpName();
|
|
|
|
eventEditorWarpHeaderListBox.SelectedIndex = n.header;
|
|
}
|
|
private void warpAnchorUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled || warpsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.warps[warpsListBox.SelectedIndex].anchor = (ushort)warpAnchorUpDown.Value;
|
|
updateSelectedWarpName();
|
|
}
|
|
private void eventEditorWarpHeaderListBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (eventEditorWarpHeaderListBox.SelectedIndex < 0)
|
|
{
|
|
eventEditorHeaderLocationNameLabel.Text = "";
|
|
return;
|
|
}
|
|
|
|
|
|
ushort destHeaderID = (ushort)eventEditorWarpHeaderListBox.SelectedIndex;
|
|
|
|
MapHeader destHeader;
|
|
if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied())
|
|
{
|
|
destHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + destHeaderID.ToString("D4"), destHeaderID, 0);
|
|
}
|
|
else
|
|
{
|
|
destHeader = MapHeader.LoadFromARM9(destHeaderID);
|
|
}
|
|
|
|
int locNum;
|
|
switch (RomInfo.gameFamily)
|
|
{
|
|
case GameFamilies.DP:
|
|
{
|
|
HeaderDP h = (HeaderDP)destHeader;
|
|
|
|
locNum = h.locationName;
|
|
break;
|
|
}
|
|
case GameFamilies.Plat:
|
|
{
|
|
HeaderPt h = (HeaderPt)destHeader;
|
|
|
|
locNum = h.locationName;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
HeaderHGSS h = (HeaderHGSS)destHeader;
|
|
|
|
locNum = h.locationName;
|
|
break;
|
|
}
|
|
}
|
|
|
|
eventEditorHeaderLocationNameLabel.Text = (string)EditorPanels.headerEditor.locationNameComboBox.Items[locNum];
|
|
|
|
int warpSel = warpsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || warpSel < 0)
|
|
{
|
|
return;
|
|
}
|
|
currentEvFile.warps[warpSel].header = destHeaderID;
|
|
updateSelectedWarpName();
|
|
}
|
|
private void updateSelectedSpawnableName()
|
|
{
|
|
int index = spawnablesListBox.SelectedIndex;
|
|
if (index < 0)
|
|
{
|
|
return;
|
|
}
|
|
spawnablesListBox.Items[index] = index.ToString("D" + Math.Max(0, spawnablesListBox.Items.Count - 1).ToString().Length) + ": " + (selectedEvent as Spawnable).ToString();
|
|
}
|
|
private void updateSelectedOverworldName()
|
|
{
|
|
int index = overworldsListBox.SelectedIndex;
|
|
if (index < 0)
|
|
{
|
|
return;
|
|
}
|
|
overworldsListBox.Items[index] = index.ToString("D" + Math.Max(0, overworldsListBox.Items.Count - 1).ToString().Length) + ": " + (selectedEvent as Overworld).ToString();
|
|
}
|
|
private void updateSelectedWarpName()
|
|
{
|
|
int index = warpsListBox.SelectedIndex;
|
|
if (index < 0)
|
|
{
|
|
return;
|
|
}
|
|
warpsListBox.Items[index] = index.ToString("D" + Math.Max(0, warpsListBox.Items.Count - 1).ToString().Length) + ": " + (selectedEvent as Warp).ToString();
|
|
}
|
|
private void updateSelectedTriggerName()
|
|
{
|
|
int index = triggersListBox.SelectedIndex;
|
|
if (index < 0)
|
|
{
|
|
return;
|
|
}
|
|
triggersListBox.Items[index] = index.ToString("D" + Math.Max(0, triggersListBox.Items.Count - 1).ToString().Length) + ": " + (selectedEvent as Trigger).ToString();
|
|
}
|
|
|
|
private void warpsListBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
if (Helpers.HandlersDisabled || warpsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
selectedEvent = currentEvFile.warps[warpsListBox.SelectedIndex];
|
|
eventEditorWarpHeaderListBox.SelectedIndex = currentEvFile.warps[warpsListBox.SelectedIndex].header;
|
|
|
|
Helpers.DisableHandlers();
|
|
|
|
warpAnchorUpDown.Value = currentEvFile.warps[warpsListBox.SelectedIndex].anchor;
|
|
warpXMapUpDown.Value = currentEvFile.warps[warpsListBox.SelectedIndex].xMapPosition;
|
|
warpYMapUpDown.Value = currentEvFile.warps[warpsListBox.SelectedIndex].yMapPosition;
|
|
warpZUpDown.Value = currentEvFile.warps[warpsListBox.SelectedIndex].zPosition;
|
|
warpXMatrixUpDown.Value = currentEvFile.warps[warpsListBox.SelectedIndex].xMatrixPosition;
|
|
warpYMatrixUpDown.Value = currentEvFile.warps[warpsListBox.SelectedIndex].yMatrixPosition;
|
|
|
|
DisplayActiveEvents(); // Redraw events to show selection box
|
|
|
|
#region Re-enable events
|
|
Helpers.EnableHandlers();
|
|
#endregion
|
|
}
|
|
private void warpMatrixXUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int index = warpsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || index < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.warps[index].xMatrixPosition = (ushort)warpXMatrixUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void warpMatrixYUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int index = warpsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || index < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.warps[index].yMatrixPosition = (ushort)warpYMatrixUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void warpXMapUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int index = warpsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || index < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.warps[index].xMapPosition = (short)warpXMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void warpYMapUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int index = warpsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || index < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.warps[index].yMapPosition = (short)warpYMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void warpZUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int index = warpsListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || index < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.warps[index].zPosition = (short)warpZUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void goToWarpDestination_Click(object sender, EventArgs e)
|
|
{
|
|
if (warpsListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
int destAnchor = (int)warpAnchorUpDown.Value;
|
|
ushort destHeaderID = (ushort)eventEditorWarpHeaderListBox.SelectedIndex;
|
|
|
|
MapHeader destHeader;
|
|
if (PatchToolboxDialog.flag_DynamicHeadersPatchApplied || PatchToolboxDialog.CheckFilesDynamicHeadersPatchApplied())
|
|
{
|
|
destHeader = MapHeader.LoadFromFile(RomInfo.gameDirs[DirNames.dynamicHeaders].unpackedDir + "\\" + destHeaderID.ToString("D4"), destHeaderID, 0);
|
|
}
|
|
else
|
|
{
|
|
destHeader = MapHeader.LoadFromARM9(destHeaderID);
|
|
}
|
|
|
|
if (new EventFile(destHeader.eventFileID).warps.Count < destAnchor + 1)
|
|
{
|
|
DialogResult d = MessageBox.Show("The selected warp's destination anchor doesn't exist.\n" +
|
|
"Do you want to open the destination map anyway?", "Warp is not connected", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
|
if (d == DialogResult.Yes)
|
|
{
|
|
eventMatrixUpDown.Value = destHeader.matrixID;
|
|
eventAreaDataUpDown.Value = destHeader.areaDataID;
|
|
|
|
Helpers.DisableHandlers();
|
|
selectEventComboBox.SelectedIndex = destHeader.eventFileID;
|
|
ChangeLoadedEventFile(destHeader.eventFileID, destHeaderID);
|
|
|
|
CenterEventViewOnEntities();
|
|
}
|
|
return;
|
|
}
|
|
|
|
eventMatrixUpDown.Value = destHeader.matrixID;
|
|
eventAreaDataUpDown.Value = destHeader.areaDataID;
|
|
|
|
Helpers.DisableHandlers();
|
|
selectEventComboBox.SelectedIndex = destHeader.eventFileID;
|
|
ChangeLoadedEventFile(destHeader.eventFileID, destHeaderID);
|
|
|
|
|
|
warpsListBox.SelectedIndex = destAnchor;
|
|
centerEventViewOnSelectedEvent_Click(sender, e);
|
|
}
|
|
#endregion
|
|
|
|
#region Triggers Tab
|
|
private void addTriggerButton_Click(object sender, EventArgs e)
|
|
{
|
|
currentEvFile.triggers.Add(new Trigger((int)eventMatrixXUpDown.Value, (int)eventMatrixYUpDown.Value));
|
|
|
|
triggersListBox.Items.Add("");
|
|
triggersListBox.SelectedIndex = currentEvFile.triggers.Count - 1;
|
|
updateSelectedTriggerName();
|
|
}
|
|
private void removeTriggerButton_Click(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
|
|
if (selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Helpers.DisableHandlers();
|
|
|
|
/* Remove trigger object from list and the corresponding entry in the ListBox */
|
|
currentEvFile.triggers.RemoveAt(selection);
|
|
triggersListBox.Items.RemoveAt(selection);
|
|
|
|
FillTriggersBox(); // Update ListBox
|
|
|
|
Helpers.EnableHandlers();
|
|
|
|
if (selection > 0)
|
|
{
|
|
triggersListBox.SelectedIndex = selection - 1;
|
|
}
|
|
else
|
|
{
|
|
DisplayActiveEvents();
|
|
}
|
|
}
|
|
private void duplicateTriggersButton_Click(object sender, EventArgs e)
|
|
{
|
|
if (triggersListBox.SelectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers.Add(new Trigger(selectedEvent as Trigger));
|
|
|
|
triggersListBox.Items.Add("");
|
|
triggersListBox.SelectedIndex = currentEvFile.triggers.Count - 1;
|
|
updateSelectedTriggerName();
|
|
}
|
|
private void triggersListBox_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
int selectedIndex = triggersListBox.SelectedIndex;
|
|
|
|
if (Helpers.HandlersDisabled || selectedIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
Helpers.DisableHandlers();
|
|
|
|
Trigger t = (selectedEvent = currentEvFile.triggers[selectedIndex]) as Trigger;
|
|
|
|
triggerScriptUpDown.Value = t.scriptNumber;
|
|
triggerVariableWatchedUpDown.Value = t.variableWatched;
|
|
expectedVarValueTriggerUpDown.Value = t.expectedVarValue;
|
|
|
|
triggerWidthUpDown.Value = t.widthX;
|
|
triggerLengthUpDown.Value = t.heightY;
|
|
|
|
triggerXMapUpDown.Value = t.xMapPosition;
|
|
triggerYMapUpDown.Value = t.yMapPosition;
|
|
triggerZUpDown.Value = t.zPosition;
|
|
triggerXMatrixUpDown.Value = t.xMatrixPosition;
|
|
triggerYMatrixUpDown.Value = t.yMatrixPosition;
|
|
|
|
DisplayActiveEvents();
|
|
|
|
Helpers.EnableHandlers();
|
|
}
|
|
private void triggerVariableWatchedUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].variableWatched = (ushort)triggerVariableWatchedUpDown.Value;
|
|
updateSelectedTriggerName();
|
|
}
|
|
private void expectedVarValueTriggerUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].expectedVarValue = (ushort)expectedVarValueTriggerUpDown.Value;
|
|
updateSelectedTriggerName();
|
|
}
|
|
private void triggerScriptUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].scriptNumber = (ushort)triggerScriptUpDown.Value;
|
|
updateSelectedTriggerName();
|
|
}
|
|
private void triggerXMapUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].xMapPosition = (short)triggerXMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void triggerYMapUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].yMapPosition = (short)triggerYMapUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void triggerZUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].zPosition = (ushort)triggerZUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void triggerXMatrixUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].xMatrixPosition = (ushort)triggerXMatrixUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void triggerYMatrixUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].yMatrixPosition = (ushort)triggerYMatrixUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void triggerWidthUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].widthX = (ushort)triggerWidthUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
private void triggerLengthUpDown_ValueChanged(object sender, EventArgs e)
|
|
{
|
|
int selection = triggersListBox.SelectedIndex;
|
|
if (Helpers.HandlersDisabled || selection < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
currentEvFile.triggers[selection].heightY = (ushort)triggerLengthUpDown.Value;
|
|
DisplayActiveEvents();
|
|
}
|
|
#endregion
|
|
|
|
#endregion
|
|
|
|
private void eventOpenGlControl_Load(object sender, EventArgs e)
|
|
{
|
|
eventOpenGlControl.InitializeContexts();
|
|
}
|
|
|
|
private void screenshotButton_Click(object sender, EventArgs e)
|
|
{
|
|
MessageBox.Show("Choose where to save the map screenshot.", "Choose destination path", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
SaveFileDialog imageSFD = new SaveFileDialog
|
|
{
|
|
Filter = "PNG File(*.png)|*.png",
|
|
};
|
|
if (imageSFD.ShowDialog() != DialogResult.OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
|
|
Helpers.RenderMap(ref eventMapRenderer, ref eventBuildingsRenderer, ref eventMapFile, 0f, 115.0f, 90f, 4f, eventOpenGlControl.Width, eventOpenGlControl.Height, true, true);
|
|
eventPictureBox.BackgroundImage = Helpers.GrabMapScreenshot(eventOpenGlControl.Width, eventOpenGlControl.Height);
|
|
|
|
int newW = 512, newH = 512;
|
|
Bitmap newImage = new Bitmap(newW, newH);
|
|
using (var graphCtr = Graphics.FromImage(newImage))
|
|
{
|
|
graphCtr.SmoothingMode = SmoothingMode.HighQuality;
|
|
graphCtr.InterpolationMode = InterpolationMode.NearestNeighbor;
|
|
graphCtr.PixelOffsetMode = PixelOffsetMode.HighQuality;
|
|
graphCtr.DrawImage(eventPictureBox.BackgroundImage, 0, 0, newW, newH);
|
|
graphCtr.DrawImage(eventPictureBox.Image, 0, 0, newW, newH);
|
|
}
|
|
newImage.Save(imageSFD.FileName);
|
|
MessageBox.Show("Screenshot saved.", "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
|
|
}
|
|
}
|
|
}
|