Compare commits
4 Commits
7c38c876de
...
8bd2e53d7e
Author | SHA1 | Date |
---|---|---|
|
8bd2e53d7e | |
|
1177474fd6 | |
|
202edd424b | |
|
f924470e8d |
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Godot.NET.Sdk/4.3.0">
|
||||
<Project Sdk="Godot.NET.Sdk/4.4.1">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
|
|
|
@ -12,7 +12,7 @@ config_version=5
|
|||
|
||||
config/name="Thief Mission Viewer"
|
||||
run/main_scene="res://project/scenes/main.tscn"
|
||||
config/features=PackedStringArray("4.3", "C#", "Forward Plus")
|
||||
config/features=PackedStringArray("4.4", "C#", "Forward Plus")
|
||||
config/icon="res://icon.svg"
|
||||
|
||||
[autoload]
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://ddyj2xlmr0rfe
|
|
@ -0,0 +1 @@
|
|||
uid://b8n4k0ssnlvu2
|
|
@ -0,0 +1 @@
|
|||
uid://b1bo0tyeqog6h
|
|
@ -0,0 +1 @@
|
|||
uid://64d8uwu3n6hq
|
|
@ -0,0 +1 @@
|
|||
uid://biy323fj0ke5v
|
|
@ -0,0 +1 @@
|
|||
uid://bn66ccq4fqwqm
|
|
@ -0,0 +1 @@
|
|||
uid://dpjlv5b4wrwq
|
|
@ -0,0 +1 @@
|
|||
uid://cngbjlen8cwhu
|
|
@ -0,0 +1 @@
|
|||
uid://cjb2tw7hxompq
|
|
@ -17,7 +17,7 @@ public class RendParams : IChunk
|
|||
|
||||
public string palette;
|
||||
public Vector3 ambientLight;
|
||||
public int useSunlight;
|
||||
public bool useSunlight;
|
||||
public SunlightMode sunlightMode;
|
||||
public Vector3 sunlightDirection;
|
||||
public float sunlightHue;
|
||||
|
@ -32,7 +32,8 @@ public class RendParams : IChunk
|
|||
{
|
||||
palette = reader.ReadNullString(16);
|
||||
ambientLight = reader.ReadVec3();
|
||||
useSunlight = reader.ReadInt32();
|
||||
useSunlight = reader.ReadBoolean();
|
||||
reader.ReadBytes(3);
|
||||
sunlightMode = (SunlightMode)reader.ReadUInt32();
|
||||
sunlightDirection = reader.ReadVec3();
|
||||
sunlightHue = reader.ReadSingle();
|
||||
|
@ -59,6 +60,7 @@ public class RendParams : IChunk
|
|||
writer.WriteNullString(palette, 16);
|
||||
writer.WriteVec3(ambientLight);
|
||||
writer.Write(useSunlight);
|
||||
writer.Write(new byte[3]);
|
||||
writer.Write((uint)sunlightMode);
|
||||
writer.WriteVec3(sunlightDirection);
|
||||
writer.Write(sunlightHue);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://c2byqoq1n4dhj
|
|
@ -0,0 +1 @@
|
|||
uid://dhaj07j75kai8
|
|
@ -246,12 +246,30 @@ public class WorldRep : IChunk
|
|||
// TODO: This ONLY works for rgba (bpp = 4)!!!
|
||||
public void AddLight(int layer, int x, int y, float r, float g, float b)
|
||||
{
|
||||
ArgumentOutOfRangeException.ThrowIfLessThan(layer, 0, nameof(layer));
|
||||
ArgumentOutOfRangeException.ThrowIfGreaterThan(layer, Layers, nameof(layer));
|
||||
|
||||
var idx = (x + y * Width) * Bpp;
|
||||
var pLayer = Pixels[layer];
|
||||
pLayer[idx] = (byte)Math.Clamp(pLayer[idx] + r, 0, 255);
|
||||
pLayer[idx + 1] = (byte)Math.Clamp(pLayer[idx + 1] + g, 0, 255);
|
||||
pLayer[idx + 2] = (byte)Math.Clamp(pLayer[idx + 2] + b, 0, 255);
|
||||
pLayer[idx + 3] = 255;
|
||||
switch (Bpp)
|
||||
{
|
||||
// 1bpp isn't really supported (does nd dromed even produce it?)
|
||||
case 2:
|
||||
var raw2 = pLayer[idx] + (pLayer[idx + 1] << 8);
|
||||
var newR = (int)Math.Clamp((raw2 & 31) + r * 32f / 255f, 0, 31);
|
||||
var newG = (int)Math.Clamp(((raw2 >> 5) & 31) + g * 32f / 255f, 0, 31);
|
||||
var newB = (int)Math.Clamp(((raw2 >> 10) & 31) + b * 32f / 255f, 0, 31);
|
||||
raw2 = newR + (newG << 5) + (newB << 10);
|
||||
pLayer[idx] = (byte)(raw2 & 0xff);
|
||||
pLayer[idx + 1] = (byte)((raw2 >> 8) & 0xff);
|
||||
break;
|
||||
case 4:
|
||||
pLayer[idx] = (byte)Math.Clamp(pLayer[idx] + b, 0, 255);
|
||||
pLayer[idx + 1] = (byte)Math.Clamp(pLayer[idx + 1] + g, 0, 255);
|
||||
pLayer[idx + 2] = (byte)Math.Clamp(pLayer[idx + 2] + r, 0, 255);
|
||||
pLayer[idx + 3] = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
_litLayers[layer] = true;
|
||||
}
|
||||
|
@ -274,7 +292,7 @@ public class WorldRep : IChunk
|
|||
c /= ratio;
|
||||
}
|
||||
|
||||
AddLight(layer, x, y, c.Z, c.Y, c.X);
|
||||
AddLight(layer, x, y, c.X, c.Y, c.Z);
|
||||
}
|
||||
|
||||
public void Reset(Vector3 ambientLight, bool hdr)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://bgrwq2pe10awh
|
|
@ -159,6 +159,8 @@ public class DbFile
|
|||
"P$Scale" => new PropertyChunk<PropVector>(),
|
||||
"P$RenderTyp" => new PropertyChunk<PropRenderType>(),
|
||||
"P$JointPos" => new PropertyChunk<PropJointPos>(),
|
||||
"P$Immobile" => new PropertyChunk<PropBool>(),
|
||||
"P$StatShad" => new PropertyChunk<PropBool>(),
|
||||
"P$OTxtRepr0" => new PropertyChunk<PropString>(),
|
||||
"P$OTxtRepr1" => new PropertyChunk<PropString>(),
|
||||
"P$OTxtRepr2" => new PropertyChunk<PropString>(),
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://b4qbr6xsdhvgn
|
|
@ -94,6 +94,8 @@ public class ObjectHierarchy
|
|||
AddProp<PropVector>("P$Scale");
|
||||
AddProp<PropRenderType>("P$RenderTyp");
|
||||
AddProp<PropJointPos>("P$JointPos");
|
||||
AddProp<PropBool>("P$Immobile");
|
||||
AddProp<PropBool>("P$StatShad");
|
||||
AddProp<PropString>("P$OTxtRepr0");
|
||||
AddProp<PropString>("P$OTxtRepr1");
|
||||
AddProp<PropString>("P$OTxtRepr2");
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://fxq8jvky04oh
|
|
@ -0,0 +1 @@
|
|||
uid://cn6fjsjh2ne1c
|
|
@ -0,0 +1 @@
|
|||
uid://dnm5qcj36s51w
|
|
@ -0,0 +1 @@
|
|||
uid://bfv1v2tgj21sq
|
|
@ -151,38 +151,44 @@ public class ResourcePathManager
|
|||
throw new InvalidOperationException("Failed to find all installation config paths.");
|
||||
}
|
||||
|
||||
// Get the paths of the base Fam and Obj resources so we can extract them.
|
||||
// We need to know where all the texture and object resources are
|
||||
var installCfgLines = File.ReadAllLines(configPaths[(int)ConfigFile.Install]);
|
||||
FindConfigVar(installCfgLines, "resname_base", out var resPaths);
|
||||
var baseFamPath = "";
|
||||
var baseObjPath = "";
|
||||
if (!FindConfigVar(installCfgLines, "resname_base", out var resPaths))
|
||||
{
|
||||
throw new InvalidOperationException("Failed to find resnames in install config");
|
||||
}
|
||||
|
||||
var zipPaths = new List<string>();
|
||||
foreach (var resPath in resPaths.Split('+'))
|
||||
{
|
||||
var dir = Path.Join(installPath, ConvertSeparator(resPath));
|
||||
if (!Directory.Exists(dir))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var path in Directory.GetFiles(dir))
|
||||
{
|
||||
var name = Path.GetFileName(path).ToLower();
|
||||
if (name == "fam.crf" && baseFamPath == "")
|
||||
if (name is "fam.crf" or "obj.crf")
|
||||
{
|
||||
baseFamPath = path;
|
||||
}
|
||||
else if (name == "obj.crf" && baseObjPath == "")
|
||||
{
|
||||
baseObjPath = path;
|
||||
zipPaths.Add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do the extraction bro
|
||||
(string, string)[] resources = [("fam", baseFamPath), ("obj", baseObjPath)];
|
||||
foreach (var (extractName, zipPath) in resources)
|
||||
// The path order is a priority order, so we don't want to overwrite any files when extracting
|
||||
// TODO: Check if there's any problems caused by case sensitivity
|
||||
if (Directory.Exists(_extractionPath))
|
||||
{
|
||||
var extractPath = Path.Join(_extractionPath, extractName);
|
||||
if (Directory.Exists(extractPath))
|
||||
{
|
||||
Directory.Delete(extractPath, true);
|
||||
}
|
||||
ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath);
|
||||
Directory.Delete(_extractionPath, true);
|
||||
}
|
||||
foreach (var zipPath in zipPaths)
|
||||
{
|
||||
var resType = Path.GetFileNameWithoutExtension(zipPath);
|
||||
var extractPath = Path.Join(_extractionPath, resType);
|
||||
ZipFile.OpenRead(zipPath).ExtractToDirectory(extractPath, false);
|
||||
}
|
||||
|
||||
FindConfigVar(installCfgLines, "load_path", out var omsPath);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://do02v3prhultx
|
|
@ -0,0 +1 @@
|
|||
uid://8slua3vhscjw
|
|
@ -0,0 +1 @@
|
|||
uid://cbko1cr0u6nu4
|
|
@ -265,14 +265,12 @@ public partial class Mission : Node3D
|
|||
var meshDetails = Timing.TimeStage("Get Models", () => Context.Instance.ModelLoader.Load(modelName));
|
||||
if (meshDetails.Length != 0)
|
||||
{
|
||||
var model = new Node3D();
|
||||
var joints = jointPosProp != null ? jointPosProp.Positions : [0, 0, 0, 0, 0, 0];
|
||||
var model = ModelLoader.TransformMeshes(joints, meshDetails);
|
||||
model.Position = pos;
|
||||
model.RotationDegrees = rot;
|
||||
model.Scale = scale;
|
||||
|
||||
var joints = jointPosProp != null ? jointPosProp.Positions : [0, 0, 0, 0, 0, 0];
|
||||
var meshes = ModelLoader.TransformMeshes(joints, meshDetails);
|
||||
|
||||
bool GetTextReplPath(PropString prop, out string path)
|
||||
{
|
||||
path = "";
|
||||
|
@ -301,26 +299,29 @@ public partial class Mission : Node3D
|
|||
}
|
||||
|
||||
var repls = new PropString[] { txtRepl0, txtRepl1, txtRepl2, txtRepl3 };
|
||||
foreach (var meshInstance in meshes)
|
||||
foreach (var child in model.FindChildren("*", "MeshInstance3D", true, false))
|
||||
{
|
||||
var meshInstance = child as MeshInstance3D;
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
if (GetTextReplPath(repls[i], out var path))
|
||||
if (!GetTextReplPath(repls[i], out var path))
|
||||
{
|
||||
var overrideMat = new StandardMaterial3D
|
||||
{
|
||||
AlbedoTexture = TextureLoader.LoadTexture(path),
|
||||
Transparency = BaseMaterial3D.TransparencyEnum.AlphaDepthPrePass,
|
||||
};
|
||||
continue;
|
||||
}
|
||||
|
||||
var overrideMat = new StandardMaterial3D
|
||||
{
|
||||
AlbedoTexture = TextureLoader.LoadTexture(path),
|
||||
Transparency = BaseMaterial3D.TransparencyEnum.AlphaDepthPrePass,
|
||||
};
|
||||
|
||||
var surfaceCount = meshInstance.Mesh.GetSurfaceCount();
|
||||
for (var idx = 0; idx < surfaceCount; idx++)
|
||||
var surfaceCount = meshInstance.Mesh.GetSurfaceCount();
|
||||
for (var idx = 0; idx < surfaceCount; idx++)
|
||||
{
|
||||
var surfaceMat = meshInstance.Mesh.SurfaceGetMaterial(idx);
|
||||
if (surfaceMat.HasMeta($"TxtRepl{i}"))
|
||||
{
|
||||
var surfaceMat = meshInstance.Mesh.SurfaceGetMaterial(idx);
|
||||
if (surfaceMat.HasMeta($"TxtRepl{i}"))
|
||||
{
|
||||
meshInstance.SetSurfaceOverrideMaterial(idx, overrideMat);
|
||||
}
|
||||
meshInstance.SetSurfaceOverrideMaterial(idx, overrideMat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -329,8 +330,6 @@ public partial class Mission : Node3D
|
|||
{
|
||||
meshInstance.Transparency = 1.0f - renderAlpha.value;
|
||||
}
|
||||
|
||||
model.AddChild(meshInstance);
|
||||
}
|
||||
|
||||
model.AddToGroup(OBJECT_MODELS_GROUP);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://ci24h68n7606n
|
|
@ -19,13 +19,8 @@ public partial class Model : Node3D
|
|||
}
|
||||
|
||||
Context.Instance.SetCampaign(campaignName);
|
||||
var model = new Node3D();
|
||||
var meshDetails = Context.Instance.ModelLoader.Load(modelPath);
|
||||
var meshes = ModelLoader.TransformMeshes([0, 0, 0, 0, 0, 0], meshDetails);
|
||||
foreach (var meshInstance in meshes)
|
||||
{
|
||||
model.AddChild(meshInstance);
|
||||
}
|
||||
var model = ModelLoader.TransformMeshes([0, 0, 0, 0, 0, 0], meshDetails);
|
||||
AddChild(model);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://6v4368eednxc
|
|
@ -8,11 +8,12 @@ namespace KeepersCompound.TMV;
|
|||
// TODO: Work out a way to share base game models again in the cache
|
||||
public class ModelLoader
|
||||
{
|
||||
public struct MeshDetails(int jointIdx, Transform3D transform, MeshInstance3D mesh)
|
||||
public struct MeshDetails(int jointIdx, Transform3D transform, MeshInstance3D mesh, int parentIdx)
|
||||
{
|
||||
public readonly int JointIdx = jointIdx;
|
||||
public readonly Transform3D Transform = transform;
|
||||
public readonly MeshInstance3D Mesh = mesh;
|
||||
public int ParentIdx = parentIdx;
|
||||
}
|
||||
|
||||
private readonly Dictionary<(string, string), MeshDetails[]> _cache = new();
|
||||
|
@ -40,15 +41,20 @@ public class ModelLoader
|
|||
return details;
|
||||
}
|
||||
|
||||
public static MeshInstance3D[] TransformMeshes(float[] joints, MeshDetails[] meshDetails)
|
||||
public static Node3D TransformMeshes(float[] joints, MeshDetails[] meshDetails)
|
||||
{
|
||||
for (var i = 0; i < joints.Length; i++)
|
||||
{
|
||||
joints[i] = float.DegreesToRadians(joints[i]);
|
||||
}
|
||||
|
||||
var meshes = new List<MeshInstance3D>();
|
||||
foreach (var details in meshDetails)
|
||||
{
|
||||
var mesh = details.Mesh.Duplicate() as MeshInstance3D;
|
||||
if (details.JointIdx != -1)
|
||||
{
|
||||
var ang = float.DegreesToRadians(joints[details.JointIdx]);
|
||||
var ang = joints[details.JointIdx];
|
||||
var r1 = new Quaternion(new Vector3(0, 0, 1), ang);
|
||||
var r2 = details.Transform.Basis.GetRotationQuaternion();
|
||||
var basis = new Basis(r2 * r1);
|
||||
|
@ -61,8 +67,23 @@ public class ModelLoader
|
|||
|
||||
meshes.Add(mesh);
|
||||
}
|
||||
|
||||
var root = new Node3D();
|
||||
for (var i = 0; i < meshes.Count; i++)
|
||||
{
|
||||
var details = meshDetails[i];
|
||||
var parentId = details.ParentIdx;
|
||||
if (parentId == -1)
|
||||
{
|
||||
root.AddChild(meshes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
meshes[parentId].AddChild(meshes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return [..meshes];
|
||||
return root;
|
||||
}
|
||||
|
||||
public static MeshDetails[] LoadModel(string modelName)
|
||||
|
@ -186,7 +207,19 @@ public class ModelLoader
|
|||
|
||||
var pos = -modelFile.Header.Center.ToGodotVec3();
|
||||
var meshInstance = new MeshInstance3D { Mesh = mesh, Position = pos };
|
||||
meshDetails[i] = new MeshDetails(jointIdx, transform, meshInstance);
|
||||
meshDetails[i] = new MeshDetails(jointIdx, transform, meshInstance, -1);
|
||||
}
|
||||
|
||||
// Build parentage
|
||||
for (var i = 0; i < objCount; i++)
|
||||
{
|
||||
var subObj = modelFile.Objects[i];
|
||||
var childIdx = subObj.Child;
|
||||
while (childIdx != -1)
|
||||
{
|
||||
meshDetails[childIdx].ParentIdx = i;
|
||||
childIdx = modelFile.Objects[childIdx].Next;
|
||||
}
|
||||
}
|
||||
|
||||
return meshDetails;
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
uid://c8dcucbcfsnd0
|
|
@ -0,0 +1 @@
|
|||
uid://wwf2ie0kv0kp
|
|
@ -0,0 +1 @@
|
|||
uid://dfvg4cc3huaai
|
|
@ -0,0 +1 @@
|
|||
uid://cmt5nfysu7p6h
|
|
@ -0,0 +1 @@
|
|||
uid://ndn3nkupjo76
|
|
@ -0,0 +1 @@
|
|||
uid://bul3d5u1jbg3g
|
|
@ -0,0 +1 @@
|
|||
uid://beoujsbxyth70
|
|
@ -0,0 +1 @@
|
|||
uid://cbsjt5rmif150
|
|
@ -0,0 +1 @@
|
|||
uid://c8c7y5qlasj1x
|
|
@ -0,0 +1 @@
|
|||
uid://dy6yk7onoihyd
|
|
@ -0,0 +1 @@
|
|||
uid://bghumseqcj7g2
|
|
@ -0,0 +1 @@
|
|||
uid://c032d00skt5fu
|
|
@ -1,8 +1,8 @@
|
|||
[gd_scene load_steps=9 format=3 uid="uid://byknmqac1a5vn"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://b208ufsau5jhb" path="res://project/jorge.png" id="1_1vlw2"]
|
||||
[ext_resource type="Script" path="res://project/code/TMV/UI/AssetBrowser.cs" id="1_5rr8c"]
|
||||
[ext_resource type="Script" path="res://project/code/TMV/UI/TextureBrowser.cs" id="1_72xft"]
|
||||
[ext_resource type="Script" uid="uid://beoujsbxyth70" path="res://project/code/TMV/UI/AssetBrowser.cs" id="1_5rr8c"]
|
||||
[ext_resource type="Script" uid="uid://dy6yk7onoihyd" path="res://project/code/TMV/UI/TextureBrowser.cs" id="1_72xft"]
|
||||
[ext_resource type="Texture2D" uid="uid://beb4tj06ivjae" path="res://project/assets/icons/Search.svg" id="1_ityvd"]
|
||||
[ext_resource type="Texture2D" uid="uid://dx8paqeom7dtb" path="res://project/assets/icons/Sort.svg" id="3_0k1fm"]
|
||||
[ext_resource type="Texture2D" uid="uid://dqefy830o4foj" path="res://project/assets/icons/Folder.svg" id="3_xdjfn"]
|
||||
|
@ -82,6 +82,7 @@ item_count = 4
|
|||
popup/item_0/text = "Name"
|
||||
popup/item_0/checkable = 2
|
||||
popup/item_0/checked = true
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Family"
|
||||
popup/item_1/checkable = 2
|
||||
popup/item_1/id = 1
|
||||
|
@ -228,6 +229,7 @@ size_flags_horizontal = 3
|
|||
selected = 0
|
||||
item_count = 2
|
||||
popup/item_0/text = "Linear"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Nearest"
|
||||
popup/item_1/id = 1
|
||||
|
||||
|
@ -241,6 +243,7 @@ size_flags_horizontal = 3
|
|||
selected = 0
|
||||
item_count = 2
|
||||
popup/item_0/text = "Scaled"
|
||||
popup/item_0/id = 0
|
||||
popup/item_1/text = "Tiled"
|
||||
popup/item_1/id = 1
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[gd_scene load_steps=6 format=3 uid="uid://boxi211q3kx6c"]
|
||||
|
||||
[ext_resource type="Script" path="res://project/code/TMV/Mission.cs" id="1_3gnqe"]
|
||||
[ext_resource type="Script" path="res://project/code/camera.gd" id="2_w5otl"]
|
||||
[ext_resource type="Script" uid="uid://ci24h68n7606n" path="res://project/code/TMV/Mission.cs" id="1_3gnqe"]
|
||||
[ext_resource type="Script" uid="uid://c032d00skt5fu" path="res://project/code/camera.gd" id="2_w5otl"]
|
||||
[ext_resource type="PackedScene" uid="uid://bfxdpxkcgwlkx" path="res://project/scenes/ui/resource_selector.tscn" id="3_kdn7u"]
|
||||
[ext_resource type="PackedScene" uid="uid://0h2w7w84vbea" path="res://project/scenes/ui/lightmap_layer_toggler.tscn" id="4_naip8"]
|
||||
|
||||
|
@ -13,7 +13,6 @@ ssao_enabled = true
|
|||
[node name="Main" type="Node3D"]
|
||||
|
||||
[node name="Mission" type="Node3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.110309, 0.187101, -0.461656)
|
||||
script = ExtResource("1_3gnqe")
|
||||
|
||||
[node name="Camera3D" type="Camera3D" parent="."]
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[gd_scene load_steps=5 format=3 uid="uid://iegbijrr5amb"]
|
||||
|
||||
[ext_resource type="Script" path="res://project/code/TMV/Model.cs" id="1_dax7s"]
|
||||
[ext_resource type="Script" path="res://project/code/camera.gd" id="2_ov7rc"]
|
||||
[ext_resource type="Script" uid="uid://6v4368eednxc" path="res://project/code/TMV/Model.cs" id="1_dax7s"]
|
||||
[ext_resource type="Script" uid="uid://c032d00skt5fu" path="res://project/code/camera.gd" id="2_ov7rc"]
|
||||
[ext_resource type="PackedScene" uid="uid://bfxdpxkcgwlkx" path="res://project/scenes/ui/resource_selector.tscn" id="3_yp5sl"]
|
||||
|
||||
[sub_resource type="Environment" id="Environment_e4172"]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://bfxdpxkcgwlkx"]
|
||||
|
||||
[ext_resource type="Script" path="res://project/code/TMV/UI/ResourceSelector.cs" id="1_4lx6q"]
|
||||
[ext_resource type="Script" uid="uid://c8c7y5qlasj1x" path="res://project/code/TMV/UI/ResourceSelector.cs" id="1_4lx6q"]
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_4v24o"]
|
||||
font_size = 20
|
||||
|
|
Loading…
Reference in New Issue