Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Objentry additions #95

Merged
merged 17 commits into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 90 additions & 30 deletions OpenKh.Kh2/Objentry.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using Xe.BinaryMapper;
Expand All @@ -9,47 +10,106 @@ public class Objentry
{
public enum Type : byte
{
Player = 0x0,
PartyMember = 0x1,
Dummy = 0x2,
Boss = 0x3,
NormalEnemy = 0x4,
Keyblade = 0x5,
Placeholders = 0x6, //???
WorldSavePoint = 0x7,
Neutral = 0x8,
OutOfPartyPartner = 0x9,
Chest = 0xA,
Moogle = 0xB,
GiantBoss = 0xC,
Unknown1 = 0xD,
PauseMenuDummy = 0xE,
NPC = 0xF,
Unknown2 = 0x10,
WorldMapObject = 0x11,
DropPrize = 0x12,
Summon = 0x13,
ShopPoint = 0x14,
NormalEnemy2 = 0x15,
CrowdSpawner = 0x16,
Unknown3 = 0x17, //pots in hercules world?
[Description("Player")]
PLAYER = 0x0,
[Description("Party Member")]
FRIEND = 0x1,
[Description("NPC")]
NPC = 0x2,
[Description("Boss")]
BOSS = 0x3,
[Description("Normal Enemy")]
ZAKO = 0x4,
[Description("Weapon")]
WEAPON = 0x5,
[Description("Placeholder (?)")]
E_WEAPON = 0x6,
[Description("Save Point")]
SP = 0x7,
[Description("Neutral")]
F_OBJ = 0x8,
[Description("Out of Party Member")]
BTLNPC = 0x9,
[Description("Chest")]
TREASURE = 0xA,
[Description("Moogle (?)")]
SUBMENU = 0xB,
[Description("Large Boss")]
L_BOSS = 0xC,
[Description]
G_OBJ = 0xD,
[Description]
MEMO = 0xE,
[Description]
RTN = 0xF,
[Description]
MINIGAME = 0x10,
[Description("World Map Object")]
WORLDMAP = 0x11,
[Description("Drop Item Container")]
PRIZEBOX = 0x12,
[Description("Summon")]
SUMMON = 0x13,
[Description("Shop")]
SHOP = 0x14,
[Description("Normal Enemy 2")]
L_ZAKO = 0x15,
[Description("Crowd Spawner")]
MASSEFFECT = 0x16,
[Description]
E_OBJ = 0x17,
[Description("Puzzle Piece")]
JIGSAW = 0x18,
}

public enum CommandMenuOptions : byte
{
[Description("Sora / Roxas")]
SoraRoxasDefault = 0x0,
[Description("Valor Form")]
ValorForm = 0x1,
[Description("Wisdom Form")]
WisdomForm = 0x2,
[Description("Limit Form")]
LimitForm = 0x3,
[Description("Master Form")]
MasterForm = 0x4,
[Description("Final Form")]
FinalForm = 0x5,
[Description("Anti Form")]
AntiForm = 0x6,
[Description("Lion King Sora")]
LionKingSora = 0x7,
[Description("Magic, Drive, Party and Limit commands are greyed out")]
Unk08 = 0x8,
[Description("Drive, Party and Limit commands are greyed out (not used ingame)")]
Unk09 = 0x9,
[Description("Roxas Dual-Wield")]
RoxasDualWield = 0xA,
[Description("Only Attack and Summon commands are available")]
Default = 0xB,
[Description("Sora in Cube / Card Form (Luxord battle, not used ingame)")]
CubeCardForm = 0xC,
}

[Data] public ushort ObjectId { get; set; }
[Data] public ushort Unknown02 { get; set; }
[Data] public ushort Unknown02 { get; set; } // has something to do with if the obj is rendered or not, NO: ObjectId is actually an uint, but it's bitshifted afterwards?! see z_un_003216b8
[Data] public Type ObjectType { get; set; }
[Data] public byte Unknown05{ get; set; }
[Data] public byte Unknown05{ get; set; } //padding? isn't used ingame
[Data] public byte Unknown06 { get; set; }
[Data] public byte WeaponJoint { get; set; }
[Data(Count = 32)] public string ModelName { get; set; }
[Data(Count = 32)] public string AnimationName { get; set; }
[Data] public uint Unknown48 { get; set; }
[Data] public ushort Unknown48 { get; set; } //z_un_00169398 (00169840)
[Data] public ushort Unknown4a { get; set; }
[Data] public ushort NeoStatus { get; set; }
[Data] public ushort NeoMoveset { get; set; }
[Data] public uint Unknown50 { get; set; }
[Data] public ushort Unknown50 { get; set; } // some kind of floating point calculation? z_un_0016a0a0
[Data] public short Weight { get; set; }
[Data] public byte SpawnLimiter { get; set; }
[Data] public byte Unknown55 { get; set; }
[Data] public byte Unknown55 { get; set; } // padding?
[Data] public byte Unknown56{ get; set; }
[Data] public byte Unknown57{ get; set; }
[Data] public CommandMenuOptions CommandMenuOption { get; set; }
[Data] public ushort SpawnObject1 { get; set; }
[Data] public ushort SpawnObject2 { get; set; }
[Data] public ushort SpawnObject3 { get; set; }
Expand Down
9 changes: 9 additions & 0 deletions OpenKh.Tests/kh2/ObjentryTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using OpenKh.Kh2;
using System.IO;
using System.Linq;
using Xunit;

namespace OpenKh.Tests.kh2
Expand All @@ -24,5 +25,13 @@ public void WriteBackTheSameFile() => Common.FileOpenRead("kh2/res/00objentry.bi
return outStream;
});
});

[Fact]
public void GroupByUnknown02() => Common.FileOpenRead("kh2/res/00objentry.bin", stream =>
{
var table = BaseTable<Objentry>.Read(stream);
var grouped = table.Items.GroupBy(x => x.Unknown5e).ToList();
Assert.Equal(0x076C, table.Count);
});
}
}
47 changes: 47 additions & 0 deletions OpenKh.Tools.ObjentryEditor/Converters/EnumDescriptionConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.ComponentModel;
using System.Globalization;
using System.Reflection;
using System.Windows.Data;

namespace OpenKh.Tools.ObjentryEditor.Converters
{
public class EnumDescriptionConverter : IValueConverter
{
private string GetEnumDescription(Enum enumObj)
{
FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);

if (attribArray.Length == 0)
return enumObj.ToString();
else
{
DescriptionAttribute attrib = null;

foreach (var att in attribArray)
{
if (att is DescriptionAttribute)
attrib = att as DescriptionAttribute;
}

if (attrib != null)
return attrib.Description;

return enumObj.ToString();
}
}

object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Enum myEnum = (Enum)value;
string description = GetEnumDescription(myEnum);
return description;
}

object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return string.Empty;
}
}
}
29 changes: 14 additions & 15 deletions OpenKh.Tools.ObjentryEditor/ViewModels/MainViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using OpenKh.Common;
using OpenKh.Kh2;
using OpenKh.Tools.Common;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
Expand All @@ -17,6 +18,7 @@ public class MainViewModel : BaseNotifyPropertyChanged
private static readonly string ApplicationName = Utilities.GetApplicationName();
private Window Window => Application.Current.Windows.OfType<Window>().FirstOrDefault(x => x.IsActive);
private string _fileName;
private static readonly List<FileDialogFilter> Filters = FileDialogFilterComposer.Compose().AddExtensions("00objentry.bin", "bin").AddAllFiles();

public string Title => $"{FileName ?? "untitled"} | {ApplicationName}";

Expand All @@ -42,16 +44,10 @@ public MainViewModel()
{
OpenCommand = new RelayCommand(x =>
{
var fd = FileDialog.Factory(Window, FileDialog.Behavior.Open, new[]
FileDialog.OnOpen(fileName =>
{
("00objentry.bin", "bin"),
("All files", "*")
});

if (fd.ShowDialog() == true)
{
OpenFile(fd.FileName);
}
OpenFile(fileName);
}, Filters);
}, x => true);

SaveCommand = new RelayCommand(x =>
Expand All @@ -68,12 +64,11 @@ public MainViewModel()

SaveAsCommand = new RelayCommand(x =>
{
var fd = FileDialog.Factory(Window, FileDialog.Behavior.Save);
if (fd.ShowDialog() == true)
FileDialog.OnSave(fileName =>
{
SaveFile(FileName, fd.FileName);
FileName = fd.FileName;
}
SaveFile(FileName, fileName);
FileName = fileName;
}, Filters);
}, x => true);

ExitCommand = new RelayCommand(x =>
Expand All @@ -85,7 +80,6 @@ public MainViewModel()
{
new AboutDialog(Assembly.GetExecutingAssembly()).ShowDialog();
}, x => true);

}

public bool OpenFile(string fileName) => File.OpenRead(fileName).Using(stream =>
Expand All @@ -98,8 +92,13 @@ public bool OpenFile(string fileName) => File.OpenRead(fileName).Using(stream =>

public void SaveFile(string previousFileName, string fileName)
{
var search = Objentry.SearchTerm;
Objentry.SearchTerm = string.Empty;

using (var f = File.Create(fileName))
Kh2.Objentry.Write(f, Objentry.AsObjEntries());

Objentry.SearchTerm = search;
}
}
}
61 changes: 33 additions & 28 deletions OpenKh.Tools.ObjentryEditor/ViewModels/ObjentryViewModel.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using OpenKh.Kh2;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Windows;
using Xe.Tools;
using Xe.Tools.Models;
Expand Down Expand Up @@ -33,20 +33,38 @@ public ushort ObjectId
}

public ushort Unknown02 { get => Objentry.Unknown02; set => Objentry.Unknown02 = value; }
public Objentry.Type ObjectType { get => Objentry.ObjectType; set => Objentry.ObjectType = value; }
public Objentry.Type ObjectType
{
get => Objentry.ObjectType;
set
{
Objentry.ObjectType = value;
OnPropertyChanged(nameof(ObjectType));
}
}
public byte Unknown05 { get => Objentry.Unknown05; set => Objentry.Unknown05 = value; }
public byte Unknown06 { get => Objentry.Unknown06; set => Objentry.Unknown06 = value; }
public byte WeaponJoint { get => Objentry.WeaponJoint; set => Objentry.WeaponJoint = value; }
public string ModelName { get => Objentry.ModelName; set => Objentry.ModelName = value; }
public string AnimationName { get => Objentry.AnimationName; set => Objentry.AnimationName = value; }
public uint Unknown48 { get => Objentry.Unknown48; set => Objentry.Unknown48 = value; }
public ushort Unknown48 { get => Objentry.Unknown48; set => Objentry.Unknown48 = value; }
public ushort Unknown4a { get => Objentry.Unknown4a; set => Objentry.Unknown4a = value; }
public ushort NeoStatus { get => Objentry.NeoStatus; set => Objentry.NeoStatus = value; }
public ushort NeoMoveset { get => Objentry.NeoMoveset; set => Objentry.NeoMoveset = value; }
public uint Unknown50 { get => Objentry.Unknown50; set => Objentry.Unknown50 = value; }
public ushort Unknown50 { get => Objentry.Unknown50; set => Objentry.Unknown50 = value; }
public short Weight { get => Objentry.Weight; set => Objentry.Weight = value; }
public byte SpawnLimiter { get => Objentry.SpawnLimiter; set => Objentry.SpawnLimiter = value; }
public byte Unknown55 { get => Objentry.Unknown55; set => Objentry.Unknown55 = value; }
public byte Unknown56 { get => Objentry.Unknown56; set => Objentry.Unknown56 = value; }
public byte Unknown57 { get => Objentry.Unknown57; set => Objentry.Unknown57 = value; }
public Objentry.CommandMenuOptions CommandMenuOption
{
get => Objentry.CommandMenuOption;
set
{
Objentry.CommandMenuOption = value;
OnPropertyChanged(nameof(CommandMenuOption));
}
}
public ushort SpawnObject1 { get => Objentry.SpawnObject1; set => Objentry.SpawnObject1 = value; }
public ushort SpawnObject2 { get => Objentry.SpawnObject2; set => Objentry.SpawnObject2 = value; }
public ushort SpawnObject3 { get => Objentry.SpawnObject3; set => Objentry.SpawnObject3 = value; }
Expand All @@ -60,6 +78,7 @@ public ushort ObjectId
private string _searchTerm;

public EnumModel<Objentry.Type> ObjEntryTypes { get; }
public EnumModel<Objentry.CommandMenuOptions> CommandMenuOptions { get; }

public ObjentryViewModel(BaseTable<Objentry> objentry) :
this(objentry.Id, objentry.Items)
Expand All @@ -70,6 +89,7 @@ public ObjentryViewModel(int type, IEnumerable<Objentry> items) :
{
_type = type;
ObjEntryTypes = new EnumModel<Objentry.Type>();
CommandMenuOptions = new EnumModel<Objentry.CommandMenuOptions>();
AddAndSelectCommand = new RelayCommand(x =>
{
AddCommand.Execute(null);
Expand Down Expand Up @@ -128,29 +148,14 @@ protected override ObjentryEntryViewModel OnNewItem()

private Objentry Clone(Objentry source)
{
return new Objentry()
var newObj = Activator.CreateInstance<Objentry>();
foreach(var field in newObj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
ObjectId = GetObjectIdForNewEntry(),
Unknown02 = source.Unknown02,
ObjectType = source.ObjectType,
Unknown05 = source.Unknown05,
Unknown06 = source.Unknown06,
WeaponJoint = source.WeaponJoint,
ModelName = source.ModelName,
AnimationName = source.AnimationName,
Unknown48 = source.Unknown48,
NeoStatus = source.NeoStatus,
NeoMoveset = source.NeoMoveset,
Unknown50 = source.Unknown50,
SpawnLimiter = source.SpawnLimiter,
Unknown55 = source.Unknown55,
Unknown56 = source.Unknown56,
Unknown57 = source.Unknown57,
SpawnObject1 = source.SpawnObject1,
SpawnObject2 = source.SpawnObject2,
SpawnObject3 = source.SpawnObject3,
Unknown5e = source.Unknown5e
};
field.SetValue(newObj, field.GetValue(source));
}

newObj.ObjectId = GetObjectIdForNewEntry();
return newObj;
}

private ushort GetObjectIdForNewEntry()
Expand Down
Loading