diff --git a/src/HexManiac.Core/Models/Map/MapModel.cs b/src/HexManiac.Core/Models/Map/MapModel.cs index de93a34e..812dabdc 100644 --- a/src/HexManiac.Core/Models/Map/MapModel.cs +++ b/src/HexManiac.Core/Models/Map/MapModel.cs @@ -24,7 +24,7 @@ namespace HavenSoft.HexManiac.Core.Models.Map { return new MapBankModel(bank, index); } } - public int Count => Table.Count; + public int Count => Table?.Count ?? 0; private IEnumerable Enumerate() { for (int i = 0; i < Count; i++) yield return this[i]; diff --git a/src/HexManiac.Core/ViewModels/Map/EventTemplate.cs b/src/HexManiac.Core/ViewModels/Map/EventTemplate.cs index 98d1687d..33b71685 100644 --- a/src/HexManiac.Core/ViewModels/Map/EventTemplate.cs +++ b/src/HexManiac.Core/ViewModels/Map/EventTemplate.cs @@ -70,6 +70,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { public IPixelViewModel ObjectTemplateImage { get; private set; } + public IReadOnlyList OverworldGraphics { get; private set; } + public EventTemplate(IWorkDispatcher dispatcher, IDataModel model, ScriptParser parser, IReadOnlyList owGraphics) { (this.model, this.parser) = (model, parser); RefreshLists(owGraphics); @@ -95,6 +97,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { } public void RefreshLists(IReadOnlyList owGraphics) { + OverworldGraphics = owGraphics; AvailableTemplateTypes.Clear(); AvailableTemplateTypes.Add(TemplateType.None); AvailableTemplateTypes.Add(TemplateType.Npc); diff --git a/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs b/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs index 8ae0ba4e..7cae1dcb 100644 --- a/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs +++ b/src/HexManiac.Core/ViewModels/Map/MapEditorViewModel.cs @@ -381,15 +381,15 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { public bool IsValidState { get; private set; } - public static bool TryCreateMapEditor(IFileSystem fileSystem, IEditableViewPort viewPort, Singletons singletons, MapTutorialsViewModel tutorials, out MapEditorViewModel editor) { + public static bool TryCreateMapEditor(IFileSystem fileSystem, IEditableViewPort viewPort, Singletons singletons, MapTutorialsViewModel tutorials, EventTemplate templates, out MapEditorViewModel editor) { editor = null; var maps = viewPort.Model.GetTable(HardcodeTablesModel.MapBankTable); if (maps == null) return false; - editor = new MapEditorViewModel(fileSystem, viewPort, singletons, tutorials); + editor = new MapEditorViewModel(fileSystem, viewPort, singletons, tutorials, templates); return editor.IsValidState; } - private MapEditorViewModel(IFileSystem fileSystem, IEditableViewPort viewPort, Singletons singletons, MapTutorialsViewModel tutorials) { + private MapEditorViewModel(IFileSystem fileSystem, IEditableViewPort viewPort, Singletons singletons, MapTutorialsViewModel tutorials, EventTemplate eventTemplate) { (this.fileSystem, this.viewPort) = (fileSystem, viewPort); (this.singletons, Tutorials) = (singletons, tutorials); (model, history) = (viewPort.Model, viewPort.ChangeHistory); @@ -401,9 +401,8 @@ namespace HavenSoft.HexManiac.Core.ViewModels.Map { PrimaryBlocks = PrimaryTiles; this.format = new Format(model); - var owSprites = BlockMapViewModel.RenderOWs(model); - templates = new(singletons.WorkDispatcher, model, viewPort.Tools.CodeTool.ScriptParser, owSprites); - var map = new BlockMapViewModel(fileSystem, Tutorials, viewPort, format, templates, 3, 0) { AllOverworldSprites = owSprites }; + templates = eventTemplate; + var map = new BlockMapViewModel(fileSystem, Tutorials, viewPort, format, templates, 3, 0) { AllOverworldSprites = eventTemplate.OverworldGraphics }; UpdatePrimaryMap(map); for (int i = 0; i < 0x40; i++) CollisionOptions.Add(i.ToString("X2")); diff --git a/src/HexManiac.Core/ViewModels/ViewPort.cs b/src/HexManiac.Core/ViewModels/ViewPort.cs index 2ea84b00..fea57a88 100644 --- a/src/HexManiac.Core/ViewModels/ViewPort.cs +++ b/src/HexManiac.Core/ViewModels/ViewPort.cs @@ -814,7 +814,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels { public bool CanDuplicate => true; public IEditableViewPort CreateDuplicate() { - var child = new ViewPort(FileName, Model, dispatcher, Singletons, mapper?.Tutorials, mapper?.FileSystem, PythonTool, history); + var child = new ViewPort(FileName, Model, dispatcher, Singletons, mapper?.Tutorials, mapper?.FileSystem, PythonTool, history, mapper?.Templates); child.selection.GotoAddress(scroll.DataIndex); return child; } @@ -1011,7 +1011,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels { public ViewPort() : this(new LoadedFile(string.Empty, new byte[0])) { } - public ViewPort(string fileName, IDataModel model, IWorkDispatcher dispatcher, Singletons singletons = null, MapTutorialsViewModel tutorials = null, IFileSystem fs = null, PythonTool pythonTool = null, ChangeHistory changeHistory = null) { + public ViewPort(string fileName, IDataModel model, IWorkDispatcher dispatcher, Singletons singletons = null, MapTutorialsViewModel tutorials = null, IFileSystem fs = null, PythonTool pythonTool = null, ChangeHistory changeHistory = null, EventTemplate eventTemplate = null) { Singletons = singletons ?? new Singletons(); PythonTool = pythonTool; ownsHistory = changeHistory == null; @@ -1063,12 +1063,13 @@ namespace HavenSoft.HexManiac.Core.ViewModels { InitializationWorkload = model.InitializationWorkload.ContinueWith(task => { var firstViewPort = changeHistory == null; if (firstViewPort) { + if (eventTemplate == null) eventTemplate = new EventTemplate(singletons?.WorkDispatcher ?? InstantDispatch.Instance, Model, Tools.CodeTool.ScriptParser, BlockMapViewModel.RenderOWs(Model)); CascadeScripts(); ValidateMatchedWords(); } dispatcher.DispatchWork(RefreshBackingData); // this work must be done on the UI thread if (fs != null) { - if (MapEditorViewModel.TryCreateMapEditor(fs, this, singletons, tutorials, out mapper)) { + if (MapEditorViewModel.TryCreateMapEditor(fs, this, singletons, tutorials, eventTemplate, out mapper)) { Tools.CodeTool.Investigator = mapper.Templates; } else { mapper = null; @@ -1746,7 +1747,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels { } public void OpenInNewTab(int destination) { - var child = new ViewPort(FileName, Model, dispatcher, Singletons, mapper?.Tutorials, mapper?.FileSystem, PythonTool, history); + var child = new ViewPort(FileName, Model, dispatcher, Singletons, mapper?.Tutorials, mapper?.FileSystem, PythonTool, history, mapper?.Templates); child.selection.GotoAddress(destination); RequestTabChange?.Invoke(this, new(child)); } diff --git a/src/HexManiac.Integration/MapTests.cs b/src/HexManiac.Integration/MapTests.cs index 6c1d2a17..ef70982d 100644 --- a/src/HexManiac.Integration/MapTests.cs +++ b/src/HexManiac.Integration/MapTests.cs @@ -213,5 +213,12 @@ namespace HavenSoft.HexManiac.Integration { map.PrimaryUp(0, 0); // no crash = pass } + + [SkippableFact] + public void FireRed_DuplicateMapTab_SameTemplate() { + var firered = LoadFireRed(); + var dup = firered.CreateDuplicate(); + Assert.Same(firered.MapEditor.Templates, dup.MapEditor.Templates); + } } }