Skip to content

Commit

Permalink
Nautilus .prefab importer
Browse files Browse the repository at this point in the history
Creates a BandCharDesc from a .prefab. Right click on a directory, hit import asset, and then select your .prefab file to import.
  • Loading branch information
ihatecompvir committed Jan 1, 2025
1 parent 01a08fd commit c06be24
Show file tree
Hide file tree
Showing 4 changed files with 378 additions and 30 deletions.
17 changes: 16 additions & 1 deletion MiloEditor/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using MiloLib.Assets.Band;
using MiloLib.Assets.Rnd;
using MiloLib.Utils;
using MiloLib.Utils.Conversion;
using System.Diagnostics;
using System.DirectoryServices;
using System.Reflection;
Expand Down Expand Up @@ -447,13 +448,27 @@ private void ImportAsset(TreeNode node)
// create a popup to ask for the file to import
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = "All Files(*.*)|*.*",
Filter = "All Files(*.*)|*.*|DirectDraw Surface Textures (*.dds)|*.dds|Nautilus Prefabs (*.prefab)|*.prefab",
Title = "Import Asset"
};

// present it
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// special handling of certain asset types

// detect .prefab file
if (Path.GetExtension(openFileDialog.FileName) == ".prefab")
{
// read file
BandCharDesc desc = NautilusInterop.ToBandCharDesc(File.ReadAllText(openFileDialog.FileName));
// add the BandCharDesc to the MiloFile
currentMiloScene.dirMeta.entries.Add(new DirectoryMeta.Entry("BandCharDesc", "prefab_" + Path.GetFileNameWithoutExtension(openFileDialog.FileName), desc));
// redraw the UI
PopulateListWithEntries();
return;
}


DirectoryMeta directoryEntry = (DirectoryMeta)node.Tag;

Expand Down
32 changes: 29 additions & 3 deletions MiloEditor/Panels/EditorPanel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ private void BuildUI(object obj, int startX, int startY, bool drawTypeLabels)
break;
// text box for strings and Symbols
case object stringValue when field.FieldType == typeof(string) || field.FieldType.Name == "Symbol":
inputControl = BuildTextField(stringValue);
inputControl = BuildTextField(stringValue, field);
break;
// drop down for enums
// TODO: add a way to give "friendly" names to enum cases, like the Name and Description attributes
Expand Down Expand Up @@ -479,14 +479,40 @@ private Control BuildCheckBox(bool boolValue, FieldInfo field)
return checkBox;
}

private Control BuildTextField(object fieldValue)
private Control BuildTextField(object fieldValue, FieldInfo field)
{
return new TextBox
var textBox = new TextBox
{
Text = fieldValue?.ToString(),
Dock = DockStyle.Fill,
Margin = new Padding(5, 3, 10, 3)
};

textBox.TextChanged += (sender, e) =>
{
// check if type is Symbol
if (fieldValue != null && fieldValue.GetType().Name == "Symbol")
{
var control = (System.Windows.Forms.TextBox)sender;
object ownerObject = ResolveFieldOwner(targetObject, field);
if (ownerObject != null)
{
field.SetValue(ownerObject, new Symbol((uint)textBox.Text.Length, textBox.Text));
}
}
else
{
// if it's not a Symbol, just set the value to the text
var control = (System.Windows.Forms.TextBox)sender;
object ownerObject = ResolveFieldOwner(targetObject, field);
if (ownerObject != null)
{
field.SetValue(ownerObject, textBox.Text);
}
}
};

return textBox;
}

private Control BuildEnumComboBox(object enumValue, FieldInfo field)
Expand Down
52 changes: 26 additions & 26 deletions MiloLib/Assets/Band/BandCharDesc.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,29 +146,29 @@ public void Write(EndianWriter writer)
public class Outfit
{
[Name("Eyebrows"), Description("The name of the eyebrows Milo scene that this character uses.")]
public OutfitPiece eyebrows;
public OutfitPiece eyebrows = new();
[Name("Face Hair"), Description("The name of the face hair Milo scene that this character uses.")]
public OutfitPiece faceHair;
public OutfitPiece faceHair = new();
[Name("Hair"), Description("The name of the hair Milo scene that this character uses.")]
public OutfitPiece hair;
public OutfitPiece hair = new();
[Name("Earrings"), Description("The name of the earrings Milo scene that this character uses.")]
public OutfitPiece earrings;
public OutfitPiece earrings = new();
[Name("Glasses"), Description("The name of the glasses Milo scene that this character uses.")]
public OutfitPiece glasses;
public OutfitPiece glasses = new();
[Name("Piercings"), Description("The name of the piercings Milo scene that this character uses.")]
public OutfitPiece piercings;
public OutfitPiece piercings = new();
[Name("Feet"), Description("The name of the feet Milo scene that this character uses.")]
public OutfitPiece feet;
public OutfitPiece feet = new();
[Name("Hands"), Description("The name of the hands Milo scene that this character uses.")]
public OutfitPiece hands;
public OutfitPiece hands = new();
[Name("Legs"), Description("The name of the legs Milo scene that this character uses.")]
public OutfitPiece legs;
public OutfitPiece legs = new();
[Name("Rings"), Description("The name of the rings Milo scene that this character uses.")]
public OutfitPiece rings;
public OutfitPiece rings = new();
[Name("Torso"), Description("The name of the torso Milo scene that this character uses.")]
public OutfitPiece torso;
public OutfitPiece torso = new();
[Name("Wrist"), Description("The name of the wrist Milo scene that this character uses.")]
public OutfitPiece wrist;
public OutfitPiece wrist = new();


public void Read(EndianReader reader)
Expand Down Expand Up @@ -206,11 +206,11 @@ public void Write(EndianWriter writer)
[Name("Instrument Outfit"), Description("The instruments a character will use")]
public class InstrumentOutfit
{
public OutfitPiece guitar;
public OutfitPiece bass;
public OutfitPiece drum;
public OutfitPiece mic;
public OutfitPiece keyboard;
public OutfitPiece guitar = new();
public OutfitPiece bass = new();
public OutfitPiece drum = new();
public OutfitPiece mic = new();
public OutfitPiece keyboard = new();
public InstrumentOutfit Read(EndianReader reader)
{
guitar = new OutfitPiece().Read(reader);
Expand Down Expand Up @@ -239,13 +239,13 @@ public class Patch
[Name("Category"), Description("Category of this patch")]
public PatchCategory category;
[Name("Mesh Name"), Description("name of placement mesh or mapping mesh. Valid placement meshes:\nplacement_legs_L-back.mesh placement_legs_L-front.mesh placement_legs_R-back.mesh placement_legs_R-front.mesh placement_torso_back.mesh placement_torso_front.mesh placement_torso_L-lowerArm.mesh placement_torso_L-shoulder.mesh placement_torso_R-lowerArm.mesh placement_torso_R-shoulder.mesh")]
public string meshName;
public Symbol meshName = "";
[Name("Rotation"), Description("in radians, about the uv space z axis.")]
public float rotation;
[Name("UV"), Description("UV in the mesh, u == -1 means mesh is mapping mesh.")]
public Classes.Vector2 uv;
public Vector2 uv = new();
[Name("Scale"), Description("local x and y scale factors.")]
public Classes.Vector2 scale;
public Vector2 scale = new();
public Patch Read(EndianReader reader)
{
texture = reader.ReadInt32();
Expand All @@ -271,24 +271,24 @@ public void Write(EndianWriter writer)
public class BandCharDesc : Object
{
public ushort altRevision;
public ushort revision; // Constant for revision 0x11 (17)
public ushort revision;

[Name("Prefab"), Description("Prefab name if this is a non-editable prefab")]
public Symbol prefab;
public Symbol prefab = new(0, "");

[Name("Gender"), Description("take a wild guess")]
public Symbol gender;
public Symbol gender = new(0, "");

[Name("skin_color"), Description("skin color, taken from skin.pal")]
public int skinColor;

public Head head;
public Head head = new();

[Name("instruments"), Description("instruments")]
public InstrumentOutfit instruments;
public InstrumentOutfit instruments = new();

[Name("outfit"), Description("clothing")]
public Outfit outfit;
public Outfit outfit = new();

public List<Patch> patches = new List<Patch>();

Expand Down
Loading

0 comments on commit c06be24

Please sign in to comment.