mirror of
https://github.com/haven1433/HexManiacAdvance.git
synced 2026-03-21 17:34:13 -05:00
map editor support text, flags, and item with complex scripts
This commit is contained in:
parent
aae25c2383
commit
7ae7a58226
File diff suppressed because it is too large
Load Diff
|
|
@ -219,7 +219,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
|
|||
private Dictionary<string, List<IScriptLine>> tableDependencyCache = new();
|
||||
|
||||
public IEnumerable<IScriptLine> DependsOn(string basename) {
|
||||
if (tableDependencyCache.ContainsKey(basename)) return tableDependencyCache[basename];
|
||||
lock (tableDependencyCache) if (tableDependencyCache.ContainsKey(basename)) return tableDependencyCache[basename];
|
||||
var matches = new List<IScriptLine>();
|
||||
foreach (var line in engine) {
|
||||
foreach (var arg in line.Args) {
|
||||
|
|
@ -229,7 +229,7 @@ namespace HavenSoft.HexManiac.Core.Models.Code {
|
|||
}
|
||||
}
|
||||
}
|
||||
return tableDependencyCache[basename] = matches;
|
||||
lock (tableDependencyCache) return tableDependencyCache[basename] = matches;
|
||||
}
|
||||
|
||||
private HashSet<string> constantCache, keywordCache;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ namespace HavenSoft.HexManiac.Core.Models {
|
|||
void ClearFormat(ModelDelta changeToken, int start, int length);
|
||||
void ClearData(ModelDelta changeToken, int start, int length);
|
||||
void ClearFormatAndData(ModelDelta changeToken, int start, int length);
|
||||
void ClearCacheScope();
|
||||
void SetList(ModelDelta changeToken, string name, IEnumerable<string> list, IReadOnlyDictionary<int, string> comments, string hash);
|
||||
void UpdateGotoShortcut(int index, GotoShortcutModel shortcut);
|
||||
void ClearPointer(ModelDelta currentChange, int source, int destination);
|
||||
|
|
@ -142,7 +143,7 @@ namespace HavenSoft.HexManiac.Core.Models {
|
|||
public byte[] RawData { get; private set; }
|
||||
|
||||
private ModelCacheScope currentCacheScope;
|
||||
protected void ClearCacheScope() => currentCacheScope = null;
|
||||
public void ClearCacheScope() => currentCacheScope = null;
|
||||
public ModelCacheScope CurrentCacheScope {
|
||||
get {
|
||||
var instance = currentCacheScope;
|
||||
|
|
|
|||
|
|
@ -1495,7 +1495,7 @@ namespace HavenSoft.HexManiac.Core.Models {
|
|||
if (existingRun == null || existingRun.Start != run.Start) {
|
||||
// no format starts exactly at this anchor, so clear any format that goes over this anchor.
|
||||
ClearFormat(changeToken, location, run.Length);
|
||||
} else if (!(run is NoInfoRun)) {
|
||||
} else if (run is not NoInfoRun) {
|
||||
// a format starts exactly at this anchor.
|
||||
if (existingRun.Length < run.Length) {
|
||||
// the new format may extend further. Clear excess space to make room for the longer format.
|
||||
|
|
|
|||
|
|
@ -1348,8 +1348,26 @@ show:
|
|||
);
|
||||
|
||||
public ObservableCollection<EventTextViewModel> BasicText { get; } = new();
|
||||
public ObservableCollection<int> BasicItemAddresses { get; } = new();
|
||||
public ObservableCollection<int> BasicFlagAddresses { get; } = new();
|
||||
private int basicFlag = -1;
|
||||
public FilteringComboOptions BasicItem { get; } = new();
|
||||
public bool HasBasicItem => (BasicItem.AllOptions?.Count ?? 0) > 0;
|
||||
public int BasicFlag { get => basicFlag; set => Set(ref basicFlag, value, old => NotifyPropertyChanged(nameof(HasBasicFlag))); }
|
||||
public bool HasBasicFlag => basicFlag != -1;
|
||||
private string basicFlagText = string.Empty;
|
||||
public string BasicFlagText {
|
||||
get => basicFlagText;
|
||||
set => Set(ref basicFlagText, value, old => {
|
||||
if (!basicFlagText.TryParseHex(out int result)) return;
|
||||
foreach (var address in BasicFlagAddresses) element.Model.WriteMultiByteValue(address, 2, Token, result);
|
||||
basicFlag = result;
|
||||
NotifyPropertyChanged(nameof(BasicFlag));
|
||||
});
|
||||
}
|
||||
|
||||
private void FillBasicContent() {
|
||||
// text
|
||||
BasicText.Clear();
|
||||
foreach (var spot in Flags.GetAllScriptSpots(Element.Model, parser, new[] { ScriptAddress }, 0x0F)) {
|
||||
var element = new EventTextViewModel() { PointerAddress = spot.Address + 2, Text = { Content = GetText(spot.Address + 2) } };
|
||||
|
|
@ -1360,11 +1378,56 @@ show:
|
|||
BasicText.Add(element);
|
||||
}
|
||||
|
||||
// items
|
||||
BasicItemAddresses.Clear();
|
||||
var filter = new List<byte>();
|
||||
foreach (var line in parser.DependsOn(HardcodeTablesModel.ItemsTableName)) {
|
||||
if (line is MacroScriptLine macro && macro.Args[0] is SilentMatchArg silent) filter.Add(silent.ExpectedValue);
|
||||
if (line is ScriptLine sl) filter.Add(line.LineCode[0]);
|
||||
}
|
||||
var spots = new List<int>();
|
||||
var item = -1;
|
||||
foreach (var spot in Flags.GetAllScriptSpots(element.Model, parser, new[] { ScriptAddress }, true, filter.ToArray())) {
|
||||
var offset = spot.Address + spot.Line.Args.Until(arg => arg.EnumTableName == HardcodeTablesModel.ItemsTableName).Sum(arg => arg.Length(Element.Model, -1)) + spot.Line.LineCode.Count;
|
||||
var chosenItem = Element.Model.ReadMultiByteValue(offset, 2);
|
||||
if (item == -1 || item == chosenItem) {
|
||||
item = chosenItem;
|
||||
spots.Add(offset);
|
||||
} else {
|
||||
spots.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (spots.Count > 0) {
|
||||
BasicItem.Update(ComboOption.Convert(element.Model.GetOptions(HardcodeTablesModel.ItemsTableName)), item);
|
||||
foreach (var address in spots.Distinct()) BasicItemAddresses.Add(address);
|
||||
BasicItem.Bind(nameof(BasicItem.SelectedIndex), (sender, e) => {
|
||||
foreach (var address in BasicItemAddresses) element.Model.WriteMultiByteValue(address, 2, Token, sender.SelectedIndex);
|
||||
});
|
||||
}
|
||||
|
||||
// flags
|
||||
BasicFlagAddresses.Clear();
|
||||
spots.Clear();
|
||||
var flag = -1;
|
||||
foreach (var spot in Flags.GetAllScriptSpots(element.Model, parser, new[] { ScriptAddress }, false, 0x29, 0x2A, 0x2B)) { // setflag, clearflag, checkflag
|
||||
var offset = spot.Address + 1;
|
||||
var chosenFlag = element.Model.ReadMultiByteValue(offset, 2);
|
||||
if (flag == -1 || flag == chosenFlag) {
|
||||
flag = chosenFlag;
|
||||
spots.Add(offset);
|
||||
} else {
|
||||
spots.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (spots.Count > 0) {
|
||||
BasicFlag = flag;
|
||||
foreach (var address in spots.Distinct()) BasicFlagAddresses.Add(address);
|
||||
basicFlagText = flag.ToString("X4");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private string GetText(ref string cache, int? pointer) {
|
||||
|
|
|
|||
|
|
@ -1439,6 +1439,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
|
|||
|
||||
public void Refresh() {
|
||||
scroll.DataLength = Model.Count;
|
||||
Model.ClearCacheScope();
|
||||
var selectionStart = ConvertViewPointToAddress(SelectionStart);
|
||||
if (selectionStart > Model.Count + 1) SelectionStart = ConvertAddressToViewPoint(Model.Count + 1);
|
||||
scroll.UpdateHeaders();
|
||||
|
|
@ -1447,6 +1448,7 @@ namespace HavenSoft.HexManiac.Core.ViewModels {
|
|||
Tools?.TableTool.DataForCurrentRunChanged();
|
||||
Tools?.SpriteTool.DataForCurrentRunChanged();
|
||||
Tools?.CodeTool.ClearConstantCache();
|
||||
Tools?.CodeTool.DataForCurrentRunChanged();
|
||||
UpdateAnchorText(ConvertViewPointToAddress(SelectionStart));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -762,6 +762,22 @@
|
|||
</Decorator>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Grid Visibility="{Binding HasBasicFlag, Converter={StaticResource BoolToVisibility}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:AngleBorder Direction="Left" Content="Flag:" />
|
||||
<local:AngleTextBox Grid.Column="1" Direction="Out" TextBinding="{Binding BasicFlagText, UpdateSourceTrigger=PropertyChanged}" />
|
||||
</Grid>
|
||||
<Grid Visibility="{Binding HasBasicItem, Converter={StaticResource BoolToVisibility}}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition />
|
||||
</Grid.ColumnDefinitions>
|
||||
<local:AngleBorder Direction="Left" Content="Item:" />
|
||||
<local:AngleComboBox Grid.Column="1" Direction="Out" DataContext="{Binding BasicItem}" />
|
||||
</Grid>
|
||||
<ItemsControl ItemsSource="{Binding BasicText}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user