Skip to content

Commit

Permalink
Add topic editing and the fruits of RE labor (#190)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonko0493 authored Jun 3, 2023
1 parent 0e87ba9 commit 6bdd9a7
Show file tree
Hide file tree
Showing 18 changed files with 324 additions and 128 deletions.
2 changes: 1 addition & 1 deletion src/SerialLoops.Lib/Items/BackgroundItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public BackgroundItem(string name, int id, BgTableEntry entry, Project project)
if (cgEntry is not null)
{
CgName = cgEntry?.Name?.GetSubstitutedString(project);
ExtrasShort = cgEntry?.Unknown02 ?? 0;
ExtrasShort = cgEntry?.Flag ?? 0;
ExtrasInt = cgEntry?.Unknown04 ?? 0;
}
PopulateScriptUses(project.Evt);
Expand Down
3 changes: 2 additions & 1 deletion src/SerialLoops.Lib/Items/BackgroundMusicItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class BackgroundMusicItem : Item, ISoundItem
public string BgmFile { get; set; }
public int Index { get; set; }
public string BgmName { get; set; }
public string ExtrasShort { get; set; }
public short? Flag { get; set; }
public string CachedWaveFile { get; set; }
public (string ScriptName, ScriptCommandInvocation command)[] ScriptUses { get; set; }

Expand All @@ -30,6 +30,7 @@ public BackgroundMusicItem(string bgmFile, int index, Project project) : base(Pa
_bgmFile = bgmFile;
Index = index;
BgmName = project.Extra.Bgms.FirstOrDefault(b => b.Index == Index)?.Name?.GetSubstitutedString(project) ?? "";
Flag = project.Extra.Bgms.FirstOrDefault(b => b.Index == Index)?.Flag;
DisplayName = string.IsNullOrEmpty(BgmName) ? Name : $"{Name} - {BgmName}";
CanRename = string.IsNullOrEmpty(BgmName);
PopulateScriptUses(project);
Expand Down
1 change: 1 addition & 0 deletions src/SerialLoops.Lib/Items/Item.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public Item(string name, ItemType type, string displayName = "") : base(name, ty
public class NoneItem : Item
{
public static readonly NoneItem VOICE = new(ItemType.Voice);
public static readonly NoneItem SCRIPT = new(ItemType.Script);

public NoneItem(ItemType type) : base("NONE", type)
{
Expand Down
6 changes: 3 additions & 3 deletions src/SerialLoops.Lib/Items/ScriptItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public ScriptItem(EventFile evt, ILogger log) : base(evt.Name[0..^1], ItemType.S
try
{
SearchableText = string.Join('\n', evt.ScriptSections.SelectMany(s => s.Objects.Select(c => c.Command.Mnemonic))
.Concat(evt.ConditionalsSection.Objects));
//.Concat(evt.LabelsSection.Objects.Select(l => l.Name))
//.Concat(evt.DialogueLines.Select(l => l.Text)));
.Concat(evt.ConditionalsSection.Objects)
.Concat(evt.LabelsSection.Objects.Select(l => l.Name)));
//.Concat(evt.DialogueLines.Select(l => l.Text)));
}
catch (Exception ex)
{
Expand Down
1 change: 1 addition & 0 deletions src/SerialLoops.Lib/Items/TopicItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace SerialLoops.Lib.Items
public class TopicItem : Item
{
public TopicStruct Topic { get; set; }
public TopicStruct HiddenMainTopic { get; set; }
public (string ScriptName, ScriptCommandInvocation command)[] ScriptUses { get; set; }

public TopicItem(TopicStruct topicStruct, Project project) : base($"{topicStruct.Id}", ItemType.Topic)
Expand Down
23 changes: 19 additions & 4 deletions src/SerialLoops.Lib/Project.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ public class Project
[JsonIgnore]
public ScenarioStruct Scenario { get; set; }
[JsonIgnore]
public EventFile TopicFile { get; set; }
[JsonIgnore]
public MessageInfoFile MessInfo { get; set; }
[JsonIgnore]
public VoiceMapFile VoiceMap { get; set; }
Expand Down Expand Up @@ -337,11 +339,24 @@ public LoadProjectResult LoadArchives(ILogger log, IProgressTracker tracker)
.Select(d => new PuzzleItem(d.CastTo<PuzzleFile>(), this, log)));
tracker.Finished++;

tracker.Focus("Topics", 2);
Evt.Files.First(f => f.Name == "TOPICS").InitializeTopicFile();
tracker.Finished++;
Items.AddRange(Evt.Files.First(f => f.Name == "TOPICS").TopicStructs.Select(t => new TopicItem(t, this)));
tracker.Finished++;
TopicFile = Evt.Files.First(f => f.Name == "TOPICS");
tracker.Focus("Topics", TopicFile.TopicStructs.Count);
foreach (TopicStruct topic in TopicFile.TopicStructs)
{
// Main topics have shadow topics that are located at ID + 40 (this is actually how the game finds them)
// So if we're a main topic and we see another topic 40 back, we know we're one of these shadow topics and should really be
// rolled into the original main topic
if (topic.Type == TopicType.Main && Items.Any(i => i.Type == ItemDescription.ItemType.Topic && ((TopicItem)i).Topic.Id == topic.Id - 40))
{
((TopicItem)Items.First(i => i.Type == ItemDescription.ItemType.Topic && ((TopicItem)i).Topic.Id == topic.Id - 40)).HiddenMainTopic = topic;
}
else
{
Items.Add(new TopicItem(topic, this));
}
tracker.Finished++;
}

// Scenario item must be created after script and puzzle items are constructed
tracker.Focus("Scenario", 1);
Expand Down
8 changes: 3 additions & 5 deletions src/SerialLoops.Lib/Script/Parameters/FlagScriptParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@ public class FlagScriptParameter : ScriptParameter
{
private short _internalFlagId;

public bool Global { get; set; }
public short Id { get => (short)(_internalFlagId - 1); set => _internalFlagId = (short)(value + 1); }
public string FlagName => Global ? $"G{Id:D2}" : $"F{Id:D2}";
public string FlagName => Id > 100 && Id < 121 ? $"G{Id - 100:D2}" : $"F{Id:D2}";
public override short[] GetValues(object obj = null) => new short[] { Id };

public FlagScriptParameter(string name, short id, bool global) : base(name, ParameterType.FLAG)
public FlagScriptParameter(string name, short id) : base(name, ParameterType.FLAG)
{
_internalFlagId = id;
Global = global;
}

public override FlagScriptParameter Clone(Project project, EventFile eventFile)
{
return new(Name, Id, Global);
return new(Name, Id);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using HaruhiChokuretsuLib.Archive.Event;

namespace SerialLoops.Lib.Script.Parameters
{
public class FriendshipLevelScriptParameter : ScriptParameter
{
public enum FriendshipCharacter : short
{
Haruhi = 2,
Mikuru = 3,
Nagato = 4,
Koizumi = 5,
// 6th slot is unreferenceable in the game itself
Tsuruya = 7,
}

public FriendshipCharacter Character { get; set; }

public override short[] GetValues(object obj = null) => new short[] { (short)Character };

public FriendshipLevelScriptParameter(string name, short character) : base(name, ParameterType.FRIENDSHIP_LEVEL)
{
Character = (FriendshipCharacter)character;
}

public override FriendshipLevelScriptParameter Clone(Project project, EventFile eventFile)
{
return new(Name, (short)Character);
}
}
}
1 change: 1 addition & 0 deletions src/SerialLoops.Lib/Script/Parameters/ScriptParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ public enum ParameterType
CHARACTER, // MESSINFO stuff, voice font & text speed
EPISODE_HEADER,
FLAG,
FRIENDSHIP_LEVEL,
ITEM,
MAP,
OPTION,
Expand Down
8 changes: 4 additions & 4 deletions src/SerialLoops.Lib/Script/ScriptItemCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ private static List<ScriptParameter> GetScriptParameters(ScriptCommandInvocation
switch (i)
{
case 0:
parameters.Add(new FlagScriptParameter("Flag", parameter, global: false));
parameters.Add(new FlagScriptParameter("Flag", parameter));
break;
case 1:
parameters.Add(new BoolScriptParameter("Set/Clear", parameter == 1));
Expand Down Expand Up @@ -545,14 +545,14 @@ private static List<ScriptParameter> GetScriptParameters(ScriptCommandInvocation
parameters.Add(new ShortScriptParameter("Scenes to Skip", parameter));
}
break;
case CommandVerb.GLOBAL:
case CommandVerb.MODIFY_FRIENDSHIP:
switch (i)
{
case 0:
parameters.Add(new FlagScriptParameter("Global", parameter, global: true));
parameters.Add(new FriendshipLevelScriptParameter("Character", parameter));
break;
case 1:
parameters.Add(new ShortScriptParameter("Value", parameter));
parameters.Add(new ShortScriptParameter("Modify by", parameter));
break;
}
break;
Expand Down
2 changes: 1 addition & 1 deletion src/SerialLoops.Lib/SerialLoops.Lib.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<PackageReference Include="BunLabs.NAudio.Flac" Version="2.0.1" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="2.8.2.3" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.macOS" Version="2.8.2.3" />
<PackageReference Include="HaruhiChokuretsuLib" Version="0.27.14" />
<PackageReference Include="HaruhiChokuretsuLib" Version="0.28.4" />
<PackageReference Include="NAudio.Vorbis" Version="1.5.0" />
<PackageReference Include="NitroPacker.Core" Version="2.1.0" />
<PackageReference Include="NLayer" Version="1.14.0" />
Expand Down
2 changes: 1 addition & 1 deletion src/SerialLoops/Controls/EditorTabsPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private DocumentPage CreateTab(ItemDescription item, Project project, ILogger lo
case ItemDescription.ItemType.Script:
return new ScriptEditor((ScriptItem)project.Items.First(i => i.Name == item.Name), log, project, this);
case ItemDescription.ItemType.Topic:
return new TopicEditor((TopicItem)project.Items.First(i => i.Name == item.Name), project, log);
return new TopicEditor((TopicItem)project.Items.First(i => i.Name == item.Name), project, this, log);
case ItemDescription.ItemType.Voice:
return new VoicedLineEditor((VoicedLineItem)project.Items.First(i => i.Name == item.Name), project, log);
default:
Expand Down
2 changes: 1 addition & 1 deletion src/SerialLoops/Editors/BackgroundMusicEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ public override Container GetEditorPanel()
};

return new TableLayout(
new TableRow(ControlGenerator.GetPlayerStackLayout(BgmPlayer, bgmTitleBox, _bgm.Name)),
new TableRow(ControlGenerator.GetPlayerStackLayout(BgmPlayer, bgmTitleBox, _bgm.Name, _bgm.Flag)),
new TableRow(new StackLayout
{
Orientation = Orientation.Horizontal,
Expand Down
12 changes: 12 additions & 0 deletions src/SerialLoops/Editors/GroupSelectionEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,17 @@ public override Container GetEditorPanel()
foreach (ScenarioRouteStruct route in routeSelection.Routes)
{
GroupBox routeBox = new() { Text = route.Title.GetSubstitutedString(_project) };
IEnumerable<TopicItem> kyonlessTopics = route.KyonlessTopics.Select(t => (TopicItem)_project.Items
.FirstOrDefault(i => i.Type == ItemDescription.ItemType.Topic && ((TopicItem)i).Topic.Id == t));
StackLayout kyonlessTopicsLayout = new();
foreach (TopicItem topicItem in kyonlessTopics)
{
if (topicItem is not null)
{
kyonlessTopicsLayout.Items.Add(ControlGenerator.GetFileLink(topicItem, _tabs, _log));
}
}
GroupBox kyonlessTopicsBox = new() { Text = "Kyonless Topics", Content = kyonlessTopicsLayout };
StackLayout routeLayout = new()
{
Orientation = Orientation.Vertical,
Expand All @@ -74,6 +85,7 @@ public override Container GetEditorPanel()
{
ControlGenerator.GetControlWithLabel("Script", ControlGenerator.GetFileLink(_project.Items.First(i => i.Type == ItemDescription.ItemType.Script && ((ScriptItem)i).Event.Index == route.ScriptIndex), _tabs, _log)),
ControlGenerator.GetControlWithLabel("Characters Involved", new Label { Text = string.Join(", ", route.CharactersInvolved) }),
kyonlessTopicsBox,
},
};
routeBox.Content = routeLayout;
Expand Down
Loading

0 comments on commit 6bdd9a7

Please sign in to comment.