Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
ece15b8
feat: v2 tile kits, unified loader, and tile map compile to IndoorMap
th3w1zard1 Apr 28, 2026
c095935
chore: remove unused imports in tilemap compile and v2 tests
th3w1zard1 Apr 28, 2026
8c078e2
changes
th3w1zard1 Apr 28, 2026
783df4b
fix: tile BWM quat/offset, narrow except in tilekit_io, allow empty t…
cursoragent Apr 28, 2026
8e98514
Potential fix for pull request finding 'Unused global variable'
th3w1zard1 Apr 28, 2026
ccfdfc5
Merge branch 'cursor/indoor-builder-tilekit-v2' of https://github.com…
th3w1zard1 Apr 28, 2026
5f84526
feat(tilekit): parse kotor.net kitserializer_v0_1 format and tile hooks
cursoragent Apr 28, 2026
aed782a
feat(indoorkit): detect format 0.1 tile kits in unified loader
cursoragent Apr 28, 2026
7c1b3d5
feat(gl): add tile kit scene preview helper and invalidate_render_cache
cursoragent Apr 28, 2026
8c369c6
test(tilekit): cover kotor.net format 0.1 fixture load
cursoragent Apr 28, 2026
6b39c95
docs(specs): align kits v2 spec with kitserializer_v0_1 and gl preview
cursoragent Apr 28, 2026
184c127
feat(area-designer): add area serializer v0.1 json helpers
cursoragent Apr 28, 2026
0ac4bee
feat(indoormap): persist area_designer_v01; expand tilekit scene to m…
cursoragent Apr 28, 2026
54c13b7
chore(toolset): update submodule for indoor builder 3d preview
cursoragent Apr 28, 2026
100b16e
docs(patches): add holocron indoor builder 3d preview; restore submod…
cursoragent Apr 28, 2026
fdee74a
docs(patches): use unified diff apply instructions for holocron preview
cursoragent Apr 28, 2026
b4ffdc8
fix(tilekit): areaentity doorframe last hook, room objects; area seri…
cursoragent Apr 28, 2026
54e2eec
docs(patches): refresh holocron gl preview patch and parity notes
cursoragent Apr 28, 2026
432bed5
Merge branch 'master' into cursor/indoor-builder-tilekit-v2
th3w1zard1 Apr 28, 2026
5bc7b97
Update Libraries/PyKotor/tests/test_tilekit_v2.py
th3w1zard1 Apr 28, 2026
184638d
fix: address PR review feedback on tomllib, to_dict, missing_files, a…
Copilot Apr 28, 2026
1cae5df
fix: narrow bare except to specific exceptions in indoorkit.py else b…
Copilot Apr 28, 2026
e7d5cb7
Merge branch 'master' into cursor/indoor-builder-tilekit-v2
th3w1zard1 Apr 28, 2026
2a780cc
Update defender-for-devops.yml
th3w1zard1 Apr 28, 2026
70876b9
changes
th3w1zard1 Apr 28, 2026
02e38a7
Merge branch 'cursor/indoor-builder-tilekit-v2' of https://github.com…
th3w1zard1 Apr 28, 2026
809b903
chore(test): remove empty kits_v2 minimal_tiles gitkeep
th3w1zard1 May 1, 2026
b5c85a5
test(fixtures): add floor_plain kit stubs for minimal tilekit tests
th3w1zard1 May 1, 2026
274a20a
chore(toolset): bump HolocronToolset submodule for unified Layout editor
th3w1zard1 May 1, 2026
1b4de71
Merge branch 'master' into cursor/indoor-builder-tilekit-v2
th3w1zard1 May 1, 2026
c4ea450
chore(submodules): point HolocronToolset submodule at branch cursor/i…
th3w1zard1 May 1, 2026
758e4c5
docs(wiki): Layout Editor paths in shipped wiki tree; bump HolocronTo…
th3w1zard1 May 1, 2026
4809b97
chore: bump version to 2.3.13 in pyproject.toml, uv.lock, and update …
th3w1zard1 May 2, 2026
6afd175
chore(submodules): update HolocronToolset submodule to latest commit
th3w1zard1 May 2, 2026
75c3a81
chore: merge origin/master into cursor/indoor-builder-tilekit-v2 (res…
Copilot May 3, 2026
245d0c3
chore: merge origin/master into cursor/indoor-builder-tilekit-v2 (res…
Copilot May 9, 2026
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
82 changes: 82 additions & 0 deletions .cache/kotor_net_area_designer/AreaExportation_AreaExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Kotor.NET.Resources.KotorMDL;
using Kotor.NET.Resources.KotorMDL.Controllers;
using Kotor.NET.Resources.KotorMDL.Nodes;

namespace Kotor.DevelopmentKit.AreaDesigner.relocate.AreaExportation;

public static class AreaExporter
{
public static MDL RoomToMDL(Room room)
{
var mdl = new MDL();
mdl.Name = "test";

foreach (var tile in room.Tiles)
{
mdl.Root.Children.Add(FloorToMDLNode(tile.Floor));
//mdl.Root.Children.Add(CeilingToMDLNode(tile.Ceiling));
mdl.Root.Children.AddRange(tile.Walls.Where(x => x.Visible).Select(WallToMDLNode));
mdl.Root.Children.AddRange(tile.Walls.Select(x => x.DoorFrame).Where(x => x?.Visible == true).Select(DoorFrameToMDLNode));
mdl.Root.Children.AddRange(tile.InnerCorners.Where(x => x.Visible == true).Select(InnerCornerToMDLNode));
mdl.Root.Children.AddRange(room.Objects.Select(ObjectToMDLNode));
}

mdl.Root.GetAllDescendants().Select((x, i) => x.Name = i.ToString()).ToArray();
mdl.RedoNodeNumbers();
return mdl;
}

private static MDLNode FloorToMDLNode(Floor floor)
{
var floorMDL = MDL.FromFile($"{Kit.Manager.ActiveDirectory}/{floor.KitID}/{floor.Template.Model}.mdl");
floorMDL.Root.GetController<MDLControllerDataPosition>().AddLinear(0, new(floor.Position));
floorMDL.Root.GetController<MDLControllerDataOrientation>().AddLinear(0, new(floor.Orientation));
return floorMDL.Root;
}

private static MDLNode CeilingToMDLNode(Ceiling ceiling)
{
var ceilingMDL = MDL.FromFile($"{Kit.Manager.ActiveDirectory}/{ceiling.KitID}/{ceiling.Template.Model}.mdl");
ceilingMDL.Root.GetController<MDLControllerDataPosition>().AddLinear(0, new(ceiling.Position));
ceilingMDL.Root.GetController<MDLControllerDataOrientation>().AddLinear(0, new(ceiling.Orientation));
return ceilingMDL.Root;
}

private static MDLNode WallToMDLNode(Wall wall)
{
var wallMDL = MDL.FromFile($"{Kit.Manager.ActiveDirectory}/{wall.KitID}/{wall.Template.Model}.mdl");
wallMDL.Root.GetController<MDLControllerDataPosition>().AddLinear(0, new(wall.Position));
wallMDL.Root.GetController<MDLControllerDataOrientation>().AddLinear(0, new(wall.Orientation));
return wallMDL.Root;
}

private static MDLNode DoorFrameToMDLNode(DoorFrame doorframe)
{
var doorframeMDL = MDL.FromFile($"{Kit.Manager.ActiveDirectory}/{doorframe.KitID}/{doorframe.Template.Model}.mdl");
doorframeMDL.Root.GetController<MDLControllerDataPosition>().AddLinear(0, new(doorframe.Position));
doorframeMDL.Root.GetController<MDLControllerDataOrientation>().AddLinear(0, new(doorframe.Orientation));
return doorframeMDL.Root;
}

private static MDLNode InnerCornerToMDLNode(InnerCorner corner)
{
var cornerMDL = MDL.FromFile($"{Kit.Manager.ActiveDirectory}/{corner.KitID}/{corner.Template.Model}.mdl");
cornerMDL.Root.GetController<MDLControllerDataPosition>().AddLinear(0, new(corner.Position));
cornerMDL.Root.GetController<MDLControllerDataOrientation>().AddLinear(0, new(corner.Orientation));
return cornerMDL.Root;
}

private static MDLNode ObjectToMDLNode(Object @object)
{
var objectMDL = MDL.FromFile($"{Kit.Manager.ActiveDirectory}/{@object.KitID}/{@object.Template.Model}.mdl");
objectMDL.Root.GetController<MDLControllerDataPosition>().AddLinear(0, new(@object.LocalPosition));
objectMDL.Root.GetController<MDLControllerDataOrientation>().AddLinear(0, new(@object.LocalOrientation));
return objectMDL.Root;
}
}
31 changes: 31 additions & 0 deletions .cache/kotor_net_area_designer/AreaSerialization_AreaSerializer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kotor.DevelopmentKit.AreaDesigner.relocate.KitSerialization;
using Newtonsoft.Json;

namespace Kotor.DevelopmentKit.AreaDesigner.relocate.AreaSerialization;

public class AreaSerializer
{
public static Area Load(string filepath)
{
var json = File.ReadAllText(filepath);
dynamic data = JsonConvert.DeserializeObject(json);
string format = (string)data.format.Value;

return format switch
{
"0.1" => AreaSerializer_V0_1.Load(filepath),
_ => throw new ArgumentException("Kit version is unsupported.")
};
}

public static void Save(string filepath, Area area)
{
AreaSerializer_V0_1.Save(filepath, area);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using Kotor.DevelopmentKit.AreaDesigner.relocate.KitSerialization;
using Kotor.NET.Graphics.Extensions;
using Newtonsoft.Json;

namespace Kotor.DevelopmentKit.AreaDesigner.relocate.AreaSerialization;

public class AreaSerializer_V0_1
{
public const string FormatID = "0.1";

public static Area Load(string filepath)
{
var json = File.ReadAllText(filepath);
dynamic data = JsonConvert.DeserializeObject(json);

var area = new Area();

foreach (var roomData in data.rooms.ToObject<dynamic[]>())
{
var room = new Room();
area.AddRoom(room);

foreach (var tileData in roomData.tiles.ToObject<dynamic[]>())
{
var tile = new Tile(room, Kit.Manager.Get(tileData.kitID.Value).Tile(tileData.templateID.Value));
tile.LocalPosition = new Vector3(tileData.position.ToObject<float[]>());
tile.LocalOrientation = ((float[])tileData.orientation.ToObject<float[]>()).ToQuaternion();

var floorData = tileData.floor;
var floorTemplate = Kit.Manager.Get(floorData.kitID.Value).Floor(floorData.templateID.Value);
tile.Floor.SwitchTemplate(floorTemplate);

// TODO
//var ceilingData = tileData.ceiling;
//var ceilingTemplate = Kit.Manager.Get(ceilingData.kitID.Value).Ceiling(ceilingData.templateID.Value);
//tile.Ceiling.SwitchTemplate(ceilingTemplate);

for (int i = 0; i < tileData.walls.Count; i++)
{
var wallData = tileData.walls[i];
var wallTemplate = Kit.Manager.Get(wallData.kitID.Value).Wall(wallData.templateID.Value);
var wall = tile.Walls.ElementAt(i);
wall.SwitchTemplate(wallTemplate);
}

room.Tiles.Add(tile);
}

room.FixWalls();
}

return area;
}

public static void Save(string filepath, Area area)
{
dynamic data = new ExpandoObject();

data.format = FormatID;

data.rooms = area.Rooms.Select(room => new
{
position = room.Position.ToFloatArray(),
orientation = room.Orientation.ToFloatArray(),
tiles = room.Tiles.Select(tile => new
{
kitID = tile.KitID,
templateID = tile.TemplateID,
position = tile.LocalPosition.ToFloatArray(),
orientation = tile.LocalOrientation.ToFloatArray(),
floor = new
{
kitID = tile.Floor.KitID,
templateID = tile.Floor.TemplateID,
},
ceiling = new
{
kitID = "",
templateID = "",
},
walls = tile.Walls.Select(x => new
{
kitID = x.KitID,
templateID = x.TemplateID,
}),
})
});

var json = JsonConvert.SerializeObject(data, Formatting.Indented);
File.WriteAllText(filepath, json);
}
}
61 changes: 61 additions & 0 deletions .cache/kotor_net_area_designer/Kit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Kotor.DevelopmentKit.AreaDesigner.relocate.KitSerialization;

namespace Kotor.DevelopmentKit.AreaDesigner.relocate;

public class Kit
{
public static KitManager Manager { get; } = new();

public string ID { get; }
public string Name { get; }
public string FilePath { get; }
public int Version { get; }
public ICollection<FloorTemplate> Floors { get; init; } = [];
public ICollection<TileTemplate> Tiles { get; init; } = [];
public ICollection<WallTemplate> Walls { get; init; } = [];
public ICollection<DoorFrameTemplate> DoorFrames { get; init; } = [];
public ICollection<CeilingTemplate> Ceilings { get; init; } = [];
public ICollection<InnerCornerTemplate> InnerCorners { get; init; } = [];
public ICollection<OuterCornerTemplate> OuterCorners { get; init; } = [];
public ICollection<ObjectTemplate> Objects { get; init; } = [];

public FloorTemplate Floor(string id) => Floors.Single(x => x.ID == id);
public TileTemplate Tile(string id) => Tiles.Single(x => x.ID == id);
public WallTemplate Wall(string id) => Walls.Single(x => x.ID == id);
public DoorFrameTemplate DoorFrame(string id) => DoorFrames.Single(x => x.ID == id);
public CeilingTemplate Ceiling(string id) => Ceilings.Single(x => x.ID == id);
public InnerCornerTemplate InnerCorner(string id) => InnerCorners.Single(x => x.ID == id);
public OuterCornerTemplate OuterCorner(string id) => OuterCorners.Single(x => x.ID == id);
public ObjectTemplate Object(string id) => Objects.Single(x => x.ID == id);

public Kit(string filepath, string id, int version, string name)
{
FilePath = filepath;
ID = id;
Name = name;
Version = version;
}
}

public class KitManager
{
public string ActiveDirectory = @"C:/Kits";
public ICollection<Kit> Kits { get; } = [];

public void Refresh()
{
Kits.Clear();
Directory.GetFiles(Kit.Manager.ActiveDirectory)
.Where(x => Path.GetExtension(x).ToLower() == ".kit")
.Select(KitSerializer.Load)
.ToList()
.ForEach(Kits.Add);
}
public Kit Get(string id) => Kits.Single(x => x.ID == id);
}
Loading
Loading