Compare commits

...

11 Commits

6 changed files with 104 additions and 82 deletions

View File

@ -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))
{ {
return path; if (_omResources.texturePathMap.TryGetValue(textureName, out var 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);

View File

@ -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);
} }
} }

View File

@ -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);
} }
} }

View File

@ -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)
{ {

View File

@ -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;
} }

View File

@ -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")