Compare commits
11 Commits
cb2f016455
...
655a188a69
Author | SHA1 | Date |
---|---|---|
Jarrod Doyle | 655a188a69 | |
Jarrod Doyle | ad68c25447 | |
Jarrod Doyle | 0c0394df86 | |
Jarrod Doyle | 85599b4069 | |
Jarrod Doyle | be205897bb | |
Jarrod Doyle | 3270d89b05 | |
Jarrod Doyle | 659843c743 | |
Jarrod Doyle | 56a5aa6869 | |
Jarrod Doyle | 1c3c4cacb4 | |
Jarrod Doyle | 68f2a851f4 | |
Jarrod Doyle | 3d41441f2a |
|
@ -5,7 +5,7 @@ using System.Linq;
|
||||||
|
|
||||||
namespace KeepersCompound.LGS;
|
namespace KeepersCompound.LGS;
|
||||||
|
|
||||||
// TODO: Support FMs resource paths!
|
// TODO: Merge the two versions of GetXXX and handle null campaign string as OM
|
||||||
public class ResourcePathManager
|
public class ResourcePathManager
|
||||||
{
|
{
|
||||||
private record CampaignResources
|
private record CampaignResources
|
||||||
|
@ -84,51 +84,81 @@ public class ResourcePathManager
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetMissionPath(string missionName)
|
public List<string> GetCampaignNames()
|
||||||
{
|
{
|
||||||
if (!_initialised) return null;
|
if (!_initialised) return null;
|
||||||
|
|
||||||
if (_omResources.missionPathMap.TryGetValue(missionName, out var path))
|
var names = new List<string>(_fmResources.Keys);
|
||||||
{
|
names.Sort();
|
||||||
return path;
|
return names;
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetMissionPath(string campaignName, string missionName)
|
public string GetMissionPath(string campaignName, string missionName)
|
||||||
{
|
{
|
||||||
if (!_initialised) return null;
|
if (!_initialised) return null;
|
||||||
|
|
||||||
if (_fmResources.TryGetValue(campaignName, out var campaign) &&
|
if (campaignName == null || campaignName == "")
|
||||||
campaign.missionPathMap.TryGetValue(missionName, out var path))
|
|
||||||
{
|
{
|
||||||
return path;
|
if (_omResources.missionPathMap.TryGetValue(missionName, out var omPath))
|
||||||
|
{
|
||||||
|
return omPath;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (
|
||||||
|
_fmResources.TryGetValue(campaignName, out var campaign) &&
|
||||||
|
campaign.missionPathMap.TryGetValue(missionName, out var fmPath))
|
||||||
|
{
|
||||||
|
return fmPath;
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetTexturePath(string textureName)
|
public List<string> GetMissionNames(string campaignName)
|
||||||
{
|
{
|
||||||
if (!_initialised) return null;
|
if (!_initialised) return null;
|
||||||
|
|
||||||
textureName = textureName.ToLower();
|
if (campaignName == null || campaignName == "")
|
||||||
if (_omResources.texturePathMap.TryGetValue(textureName, out var path))
|
|
||||||
{
|
{
|
||||||
return path;
|
var names = new List<string>(_omResources.missionPathMap.Keys);
|
||||||
|
names.Sort();
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
else if (_fmResources.TryGetValue(campaignName, out var campaign))
|
||||||
|
{
|
||||||
|
var names = new List<string>(campaign.missionPathMap.Keys);
|
||||||
|
names.Sort();
|
||||||
|
return names;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: OMs fail to find a path, but FMs using OM textures do find them
|
||||||
|
// The OMs still fail even if I put them in a folder with FMs that work=??
|
||||||
public string GetTexturePath(string campaignName, string textureName)
|
public string GetTexturePath(string campaignName, string textureName)
|
||||||
{
|
{
|
||||||
if (!_initialised) return null;
|
if (!_initialised) return null;
|
||||||
|
|
||||||
textureName = textureName.ToLower();
|
textureName = textureName.ToLower();
|
||||||
if (_fmResources.TryGetValue(campaignName, out var campaign) &&
|
if (campaignName == null || campaignName == "")
|
||||||
campaign.texturePathMap.TryGetValue(textureName, out var path))
|
{
|
||||||
|
if (_omResources.texturePathMap.TryGetValue(textureName, out var path))
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if (_fmResources.TryGetValue(campaignName, out var campaign))
|
||||||
|
{
|
||||||
|
if (campaign.texturePathMap.TryGetValue(textureName, out var fmPath))
|
||||||
|
{
|
||||||
|
return fmPath;
|
||||||
|
}
|
||||||
|
else if (_omResources.texturePathMap.TryGetValue(textureName, out var omPath))
|
||||||
|
{
|
||||||
|
return omPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +262,7 @@ public class ResourcePathManager
|
||||||
{
|
{
|
||||||
MatchCasing = MatchCasing.CaseInsensitive,
|
MatchCasing = MatchCasing.CaseInsensitive,
|
||||||
};
|
};
|
||||||
foreach (var path in Directory.GetFiles(root, "*.mis", searchOptions))
|
foreach (var path in Directory.GetFiles(omsPath, "*.mis", searchOptions))
|
||||||
{
|
{
|
||||||
var baseName = Path.GetFileName(path).ToLower();
|
var baseName = Path.GetFileName(path).ToLower();
|
||||||
map.Add(baseName, path);
|
map.Add(baseName, path);
|
||||||
|
|
|
@ -39,6 +39,8 @@ public partial class Mission : Node3D
|
||||||
[Export]
|
[Export]
|
||||||
public bool Dump = false;
|
public bool Dump = false;
|
||||||
|
|
||||||
|
string _campaignName;
|
||||||
|
string _missionName;
|
||||||
ResourcePathManager _installPaths;
|
ResourcePathManager _installPaths;
|
||||||
DbFile _file;
|
DbFile _file;
|
||||||
TextureLoader _textureLoader;
|
TextureLoader _textureLoader;
|
||||||
|
@ -48,11 +50,12 @@ public partial class Mission : Node3D
|
||||||
var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp");
|
var extractPath = ProjectSettings.GlobalizePath($"user://extracted/tmp");
|
||||||
_installPaths = new ResourcePathManager(extractPath);
|
_installPaths = new ResourcePathManager(extractPath);
|
||||||
var missionSelector = GetNode<Control>("%MissionSelector") as MissionSelector;
|
var missionSelector = GetNode<Control>("%MissionSelector") as MissionSelector;
|
||||||
missionSelector.LoadMission += (string rootPath, string missionPath) =>
|
missionSelector.pathManager = _installPaths;
|
||||||
|
missionSelector.MissionSelected += (string campaign, string mission) =>
|
||||||
{
|
{
|
||||||
var inited = _installPaths.Init(rootPath);
|
_campaignName = campaign;
|
||||||
GD.Print($"Inited paths: {inited}");
|
_missionName = mission;
|
||||||
FileName = missionPath;
|
FileName = _installPaths.GetMissionPath(campaign, mission);
|
||||||
Build = true;
|
Build = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -95,8 +98,7 @@ public partial class Mission : Node3D
|
||||||
ClearMap();
|
ClearMap();
|
||||||
|
|
||||||
// TODO: This shouldn't be set for things that aren't actually FMs
|
// TODO: This shouldn't be set for things that aren't actually FMs
|
||||||
var fmName = FileName.GetBaseDir().GetFile();
|
_textureLoader = new TextureLoader(_campaignName);
|
||||||
_textureLoader = new TextureLoader(fmName);
|
|
||||||
_file = new(FileName);
|
_file = new(FileName);
|
||||||
UseChunk<TxList>("TXLIST", LoadTextures);
|
UseChunk<TxList>("TXLIST", LoadTextures);
|
||||||
UseChunk<WorldRep>("WREXT", BuildWrMeshes);
|
UseChunk<WorldRep>("WREXT", BuildWrMeshes);
|
||||||
|
@ -216,20 +218,18 @@ public partial class Mission : Node3D
|
||||||
objPath ??= _installPaths.GetObjectPath(modelName + ".bin");
|
objPath ??= _installPaths.GetObjectPath(modelName + ".bin");
|
||||||
|
|
||||||
var pos = brush.position.ToGodotVec3();
|
var pos = brush.position.ToGodotVec3();
|
||||||
var model = new Model();
|
var rawRot = brush.angle;
|
||||||
model.Position = pos;
|
var rot = new Vector3(rawRot.Y, rawRot.Z, rawRot.X) * 360 / ushort.MaxValue;
|
||||||
|
var model = new Model
|
||||||
|
{
|
||||||
|
Position = pos,
|
||||||
|
RotationDegrees = rot
|
||||||
|
};
|
||||||
if (objPath != null)
|
if (objPath != null)
|
||||||
{
|
{
|
||||||
model.BuildModel("", objPath);
|
model.BuildModel("", objPath);
|
||||||
}
|
}
|
||||||
AddChild(model);
|
AddChild(model);
|
||||||
|
|
||||||
// var pos = brush.position.ToGodotVec3();
|
|
||||||
// var cube = new CsgBox3D
|
|
||||||
// {
|
|
||||||
// Position = pos
|
|
||||||
// };
|
|
||||||
// AddChild(cube);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,7 +53,6 @@ public partial class Model : Node3D
|
||||||
var b = (material.Handle) & 0xff;
|
var b = (material.Handle) & 0xff;
|
||||||
var g = (material.Handle >> 8) & 0xff;
|
var g = (material.Handle >> 8) & 0xff;
|
||||||
var r = (material.Handle >> 16) & 0xff;
|
var r = (material.Handle >> 16) & 0xff;
|
||||||
GD.Print($"Handle: {material.Handle}, R: {r}, G: {g}, B: {b}");
|
|
||||||
var colour = new Color(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
|
var colour = new Color(r / 255.0f, g / 255.0f, b / 255.0f, 1.0f);
|
||||||
materials.Add(new StandardMaterial3D
|
materials.Add(new StandardMaterial3D
|
||||||
{
|
{
|
||||||
|
@ -108,7 +107,8 @@ public partial class Model : Node3D
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var meshInstance = new MeshInstance3D { Mesh = mesh };
|
var pos = -modelFile.Header.Center.ToGodotVec3();
|
||||||
|
var meshInstance = new MeshInstance3D { Mesh = mesh, Position = pos };
|
||||||
AddChild(meshInstance);
|
AddChild(meshInstance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,16 +29,7 @@ public partial class TextureLoader
|
||||||
public bool Load(ResourcePathManager installManager, int id, string path)
|
public bool Load(ResourcePathManager installManager, int id, string path)
|
||||||
{
|
{
|
||||||
var loaded = false;
|
var loaded = false;
|
||||||
string texPath;
|
string texPath = installManager.GetTexturePath(_fmName, path);
|
||||||
if (_fmName != null)
|
|
||||||
{
|
|
||||||
texPath = installManager.GetTexturePath(_fmName, path);
|
|
||||||
texPath ??= installManager.GetTexturePath(path);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
texPath = installManager.GetTexturePath(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (texPath != null)
|
if (texPath != null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using Godot;
|
using Godot;
|
||||||
|
using KeepersCompound.LGS;
|
||||||
|
|
||||||
namespace KeepersCompound.TMV.UI;
|
namespace KeepersCompound.TMV.UI;
|
||||||
|
|
||||||
public partial class MissionSelector : Control
|
public partial class MissionSelector : Control
|
||||||
{
|
{
|
||||||
[Signal]
|
public event MissionSelectedEventHandler MissionSelected;
|
||||||
public delegate void LoadMissionEventHandler(string rootPath, string missionPath);
|
public delegate void MissionSelectedEventHandler(string campaign, string mission);
|
||||||
|
|
||||||
private InstallPaths _installPaths;
|
public ResourcePathManager pathManager;
|
||||||
|
|
||||||
private FileDialog _FolderSelect;
|
private FileDialog _FolderSelect;
|
||||||
private LineEdit _FolderPath;
|
private LineEdit _FolderPath;
|
||||||
|
@ -22,7 +21,6 @@ public partial class MissionSelector : Control
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
// TODO: Load initial folderpath from config and prefil everything
|
// TODO: Load initial folderpath from config and prefil everything
|
||||||
|
|
||||||
_FolderSelect = GetNode<FileDialog>("%FolderSelect");
|
_FolderSelect = GetNode<FileDialog>("%FolderSelect");
|
||||||
_FolderPath = GetNode<LineEdit>("%FolderPath");
|
_FolderPath = GetNode<LineEdit>("%FolderPath");
|
||||||
_BrowseButton = GetNode<Button>("%BrowseButton");
|
_BrowseButton = GetNode<Button>("%BrowseButton");
|
||||||
|
@ -32,8 +30,8 @@ public partial class MissionSelector : Control
|
||||||
_CancelButton = GetNode<Button>("%CancelButton");
|
_CancelButton = GetNode<Button>("%CancelButton");
|
||||||
|
|
||||||
_BrowseButton.Pressed += () => _FolderSelect.Visible = true;
|
_BrowseButton.Pressed += () => _FolderSelect.Visible = true;
|
||||||
_FolderSelect.DirSelected += (string dir) => { _FolderPath.Text = dir; BuildCampaignList(dir); };
|
_FolderSelect.DirSelected += SetInstallPath;
|
||||||
_FolderPath.TextSubmitted += BuildCampaignList;
|
_FolderPath.TextSubmitted += SetInstallPath;
|
||||||
_Missions.ItemSelected += (long _) => _LoadButton.Disabled = false;
|
_Missions.ItemSelected += (long _) => _LoadButton.Disabled = false;
|
||||||
_Campaigns.ItemSelected += BuildMissionList;
|
_Campaigns.ItemSelected += BuildMissionList;
|
||||||
_LoadButton.Pressed += EmitLoadMission;
|
_LoadButton.Pressed += EmitLoadMission;
|
||||||
|
@ -51,19 +49,25 @@ public partial class MissionSelector : Control
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BuildCampaignList(string path)
|
private void SetInstallPath(string path)
|
||||||
{
|
{
|
||||||
_installPaths = new InstallPaths(path);
|
_FolderPath.Text = path;
|
||||||
|
if (pathManager.Init(path))
|
||||||
|
{
|
||||||
|
BuildCampaignList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildCampaignList()
|
||||||
|
{
|
||||||
_Campaigns.Clear();
|
_Campaigns.Clear();
|
||||||
_Missions.Clear();
|
_Missions.Clear();
|
||||||
_LoadButton.Disabled = true;
|
_LoadButton.Disabled = true;
|
||||||
|
|
||||||
_Campaigns.AddItem("Original Missions");
|
_Campaigns.AddItem("Original Missions");
|
||||||
var paths = Directory.GetDirectories(_installPaths.fmsPath);
|
foreach (var campaign in pathManager.GetCampaignNames())
|
||||||
foreach (var c in paths.OrderBy(s => s))
|
|
||||||
{
|
{
|
||||||
_Campaigns.AddItem(c.TrimPrefix(_installPaths.fmsPath));
|
_Campaigns.AddItem(campaign);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,39 +76,28 @@ public partial class MissionSelector : Control
|
||||||
_Missions.Clear();
|
_Missions.Clear();
|
||||||
_LoadButton.Disabled = true;
|
_LoadButton.Disabled = true;
|
||||||
|
|
||||||
var campaignPath = "";
|
var campaignName = _Campaigns.GetItemText((int)idx);
|
||||||
if (idx == 0)
|
var missionNames = pathManager.GetMissionNames(idx == 0 ? null : campaignName);
|
||||||
|
foreach (var mission in missionNames)
|
||||||
{
|
{
|
||||||
campaignPath = _installPaths.omsPath;
|
_Missions.AddItem(mission);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
campaignPath = _installPaths.fmsPath + _Campaigns.GetItemText((int)idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] extensions = { "mis", "cow" };
|
|
||||||
var paths = Directory.GetFiles(campaignPath);
|
|
||||||
foreach (var f in paths.OrderBy(s => s))
|
|
||||||
{
|
|
||||||
if (extensions.Contains(f.GetExtension().ToLower()))
|
|
||||||
{
|
|
||||||
_Missions.AddItem(f.TrimPrefix(campaignPath));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmitLoadMission()
|
private void EmitLoadMission()
|
||||||
{
|
{
|
||||||
var selectedCampaign = _Campaigns.GetSelectedItems()[0];
|
var campaignIdxs = _Campaigns.GetSelectedItems();
|
||||||
var selected = _Missions.GetSelectedItems();
|
var missionIdxs = _Missions.GetSelectedItems();
|
||||||
if (selected.IsEmpty())
|
if (campaignIdxs.IsEmpty() || missionIdxs.IsEmpty())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var campaignPath = selectedCampaign == 0 ? _installPaths.omsPath : _installPaths.fmsPath + _Campaigns.GetItemText(selectedCampaign);
|
var campaignIdx = campaignIdxs[0];
|
||||||
var path = campaignPath + _Missions.GetItemText(selected[0]);
|
var missionIdx = missionIdxs[0];
|
||||||
EmitSignal(SignalName.LoadMission, _installPaths.rootPath, path);
|
var campaignName = campaignIdx == 0 ? null : _Campaigns.GetItemText(campaignIdx);
|
||||||
|
var missionName = _Missions.GetItemText(missionIdx);
|
||||||
|
MissionSelected(campaignName, missionName);
|
||||||
|
|
||||||
Visible = false;
|
Visible = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
[gd_scene load_steps=4 format=3 uid="uid://boxi211q3kx6c"]
|
[gd_scene load_steps=5 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/TMV/Mission.cs" id="1_3gnqe"]
|
||||||
[ext_resource type="Script" path="res://project/code/camera.gd" id="2_w5otl"]
|
[ext_resource type="Script" path="res://project/code/camera.gd" id="2_w5otl"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cekg1xb5f0ux1" path="res://project/scenes/ui/mission_selector.tscn" id="3_hwfcj"]
|
[ext_resource type="PackedScene" uid="uid://cekg1xb5f0ux1" path="res://project/scenes/ui/mission_selector.tscn" id="3_hwfcj"]
|
||||||
|
|
||||||
|
[sub_resource type="Environment" id="Environment_cckyk"]
|
||||||
|
ambient_light_source = 2
|
||||||
|
ambient_light_color = Color(1, 1, 1, 1)
|
||||||
|
ssao_enabled = true
|
||||||
|
|
||||||
[node name="Main" type="Node3D"]
|
[node name="Main" type="Node3D"]
|
||||||
|
|
||||||
[node name="Mission" type="Node3D" parent="."]
|
[node name="Mission" type="Node3D" parent="."]
|
||||||
|
@ -17,3 +22,6 @@ script = ExtResource("2_w5otl")
|
||||||
|
|
||||||
[node name="MissionSelector" parent="UI" instance=ExtResource("3_hwfcj")]
|
[node name="MissionSelector" parent="UI" instance=ExtResource("3_hwfcj")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = SubResource("Environment_cckyk")
|
||||||
|
|
Loading…
Reference in New Issue