Skip to content

Commit

Permalink
fixed duke addons launch with eduke32
Browse files Browse the repository at this point in the history
  • Loading branch information
fgsfds committed Sep 26, 2024
1 parent 89ca137 commit 1f7ddcf
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 99 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ Another goal of this project is to create a unification standard for Build Engin
<tr>
<td valign="center">

- Caribbean and Duke it out in DC can't be launched with EDuke32 and RedNukem
- Wanton Destruction launched from Raze has episodes and maps names from the original game unless downloaded from the lancher
- Skip intro checkbox doesn't work with RedNukem

Expand Down
30 changes: 24 additions & 6 deletions src/Common/Helpers/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ public static string ToTimeString(this TimeSpan time)
{
if (time.TotalSeconds > 2)
{
sb.Append($" {time.Seconds} seconds");
_ = sb.Append($" {time.Seconds} seconds");
}
else if (time.TotalSeconds >= 1)
{
sb.Append($" {time.Seconds} second");
_ = sb.Append($" {time.Seconds} second");
}

return sb.ToString();
Expand All @@ -56,22 +56,40 @@ public static string ToTimeString(this TimeSpan time)

if (time.TotalHours >= 2)
{
sb.Append($" {(int)time.TotalHours} hours");
_ = sb.Append($" {(int)time.TotalHours} hours");
}
else if (time.TotalHours >= 1)
{
sb.Append($" {(int)time.TotalHours} hour");
_ = sb.Append($" {(int)time.TotalHours} hour");
}

if (time.Minutes >= 2)
{
sb.Append($" {time.Minutes} minutes");
_ = sb.Append($" {time.Minutes} minutes");
}
else if (time.Minutes >= 1)
{
sb.Append($" {time.Minutes} minute");
_ = sb.Append($" {time.Minutes} minute");
}

return sb.Replace(" ", " ").ToString();
}

/// <summary>
/// Add new element or replace value of and existing element
/// </summary>
/// <param name="dict">Dictionary</param>
/// <param name="key">Key</param>
/// <param name="value">Value</param>
public static void AddOrReplace<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key, TValue value)
{
if (dict.ContainsKey(key))
{
dict[key] = value;
}
else
{
dict.Add(key, value);
}
}
}
21 changes: 0 additions & 21 deletions src/Games/Games/BaseGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,4 @@ protected bool IsInstalled(List<string> files, string? path = null)

return true;
}


/// <summary>
/// Does the file exist in the game install folder
/// </summary>
/// <param name="file">File</param>
protected bool IsInstalled(string file)
{
if (GameInstallFolder is null)
{
return false;
}

if (!File.Exists(Path.Combine(GameInstallFolder, file)) &&
!File.Exists(Path.Combine(GameInstallFolder, "addons", file)))
{
return false;
}

return true;
}
}
76 changes: 73 additions & 3 deletions src/Games/Games/DukeGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ public sealed class DukeGame : BaseGame
/// <summary>
/// Is Duke it Out in DC installed
/// </summary>
public bool IsDukeDCInstalled => IsInstalled("DUKEDC.GRP");
public bool IsDukeDCInstalled => GetDukeAddon(DukeAddonEnum.DukeDC);

/// <summary>
/// Is Nuclear Winter installed
/// </summary>
public bool IsNuclearWinterInstalled => IsInstalled("NWINTER.GRP");
public bool IsNuclearWinterInstalled => GetDukeAddon(DukeAddonEnum.DukeNW);

/// <summary>
/// Is Caribbean installed
/// </summary>
public bool IsCaribbeanInstalled => IsInstalled("VACATION.GRP");
public bool IsCaribbeanInstalled => GetDukeAddon(DukeAddonEnum.DukeVaca);

/// <summary>
/// Is World Tour installed
Expand All @@ -60,6 +60,11 @@ public sealed class DukeGame : BaseGame
/// </summary>
public bool IsDuke64Installed => File.Exists(Duke64RomPath);

/// <summary>
/// List of paths to Duke's addons folders
/// </summary>
public Dictionary<DukeAddonEnum, string> AddonsPaths { get; set; } = [];


public DukeGame() : base()
{
Expand Down Expand Up @@ -303,4 +308,69 @@ private void CreateWTStopgapFolder()

archive.ExtractToDirectory(stopgapFolder);
}


/// <summary>
/// Find Duke's addon files
/// </summary>
/// <param name="addon">Duke addon</param>
private bool GetDukeAddon(DukeAddonEnum addon)
{
if (GameInstallFolder is null)
{
return false;
}

var file = addon switch
{
DukeAddonEnum.DukeDC => "DUKEDC.GRP",
DukeAddonEnum.DukeNW => "NWINTER.GRP",
DukeAddonEnum.DukeVaca => "VACATION.GRP",
DukeAddonEnum.Base => throw new NotImplementedException(),
_ => throw new NotImplementedException(),
};

//root
var path = Path.Combine(GameInstallFolder, file);
if (File.Exists(path))
{
AddonsPaths.AddOrReplace(addon, Path.GetDirectoryName(path));
return true;
}

//zoom
path = Path.Combine(GameInstallFolder, "AddOns", file);
if (File.Exists(path))
{
AddonsPaths.AddOrReplace(addon, Path.GetDirectoryName(path));
return true;
}

//megaton
path = Path.Combine(GameInstallFolder, "addons", "dc", file);
if (File.Exists(path))
{
AddonsPaths.AddOrReplace(addon, Path.GetDirectoryName(path));
return true;
}

//megaton
path = Path.Combine(GameInstallFolder, "addons", "nw", file);
if (File.Exists(path))
{
AddonsPaths.AddOrReplace(addon, Path.GetDirectoryName(path));
return true;
}

//megaton
path = Path.Combine(GameInstallFolder, "addons", "vacation", file);
if (File.Exists(path))
{
AddonsPaths.AddOrReplace(addon, Path.GetDirectoryName(path));
return true;
}

_ = AddonsPaths.Remove(addon);
return false;
}
}
2 changes: 1 addition & 1 deletion src/Games/Providers/GamesPathsProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public GamesPathsProvider(IConfigProvider config)
}

//Megaton
pathToGame = Path.Combine(lib, "Duke Nukem 3D", "gameroot", "classic");
pathToGame = Path.Combine(lib, "Duke Nukem 3D", "gameroot");
if (Directory.Exists(pathToGame))
{
_dukePath ??= pathToGame;
Expand Down
77 changes: 54 additions & 23 deletions src/Ports/Ports/EDuke32/EDuke32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,33 +174,57 @@ protected void GetDukeArgs(StringBuilder sb, DukeGame game, IAddon addon)
}
else
{
var dukeAddon = (byte)DukeAddonEnum.Base;
_ = sb.Append($@" {AddDirectoryParam}""{game.GameInstallFolder}""");

if (addon.DependentAddons is null)
{
dukeAddon = (byte)DukeAddonEnum.Base;
}
else if (addon.DependentAddons.ContainsKey(nameof(DukeAddonEnum.DukeDC)))
{
dukeAddon = (byte)DukeAddonEnum.DukeDC;
}
else if (addon.DependentAddons.ContainsKey(nameof(DukeAddonEnum.DukeNW)))
{
dukeAddon = (byte)DukeAddonEnum.DukeNW;
}
else if (addon.DependentAddons.ContainsKey(nameof(DukeAddonEnum.DukeVaca)))
if (addon.DependentAddons is not null)
{
dukeAddon = (byte)DukeAddonEnum.DukeVaca;
}
//DUKE IT OUT IN DC
if (addon.DependentAddons.ContainsKey(nameof(DukeAddonEnum.DukeDC)))
{
var addonPath = game.AddonsPaths[DukeAddonEnum.DukeDC];

_ = sb.Append($@" {AddDirectoryParam}""{game.GameInstallFolder}""");
if (!addonPath.Equals(game.GameInstallFolder))
{
_ = sb.Append($@" {AddDirectoryParam}""{addonPath}""");
}
if (Directory.Exists(Path.Combine(game.GameInstallFolder!, "AddOns")))
{
_ = sb.Append($@" {AddDirectoryParam}""{Path.Combine(game.GameInstallFolder!, "AddOns")}""");
}
_ = sb.Append($@" {AddGrpParam}DUKEDC.GRP");

_ = sb.Append($" -addon {dukeAddon}");
if (File.Exists(Path.Combine(addonPath, "DUKEDC.CON")))
{
_ = sb.Append($@" {MainConParam}DUKEDC.CON");
}
}
//NUCLEAR WINTER
else if (addon.DependentAddons.ContainsKey(nameof(DukeAddonEnum.DukeNW)))
{
var addonPath = game.AddonsPaths[DukeAddonEnum.DukeNW];

if (!addonPath.Equals(game.GameInstallFolder))
{
_ = sb.Append($@" {AddDirectoryParam}""{addonPath}""");
}
_ = sb.Append($@" {AddGrpParam}NWINTER.GRP {MainConParam}NWINTER.CON");
}
//CARIBBEAN
else if (addon.DependentAddons.ContainsKey(nameof(DukeAddonEnum.DukeVaca)))
{
var addonPath = game.AddonsPaths[DukeAddonEnum.DukeVaca];

if (!addonPath.Equals(game.GameInstallFolder))
{
_ = sb.Append($@" {AddDirectoryParam}""{addonPath}""");
}
_ = sb.Append($@" {AddGrpParam}VACATION.GRP");

if (File.Exists(Path.Combine(addonPath, "VACATION.CON")))
{
_ = sb.Append($@" {MainConParam}VACATION.CON");
}
}
}
}


Expand Down Expand Up @@ -260,7 +284,7 @@ protected override void GetAutoloadModsArgs(StringBuilder sb, IGame game, IAddon
return;
}

_ = sb.Append($@" {AddDirectoryParam}""{game.ModsFolderPath}""");
var enabledModsCount = 0;

foreach (var mod in mods)
{
Expand Down Expand Up @@ -291,6 +315,13 @@ protected override void GetAutoloadModsArgs(StringBuilder sb, IGame game, IAddon
_ = sb.Append($@" {AddConParam}""{con}""");
}
}

enabledModsCount++;
}

if (enabledModsCount > 0)
{
_ = sb.Append($@" {AddDirectoryParam}""{game.ModsFolderPath}""");
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/Ports/Ports/EDuke32/RedNukem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ public sealed class RedNukem : EDuke32
/// <inheritdoc/>
public override string Name => "RedNukem";

/// <inheritdoc/>
protected override string AddGrpParam => "-g ";

/// <inheritdoc/>
public override List<GameEnum> SupportedGames =>
[
Expand Down
33 changes: 16 additions & 17 deletions src/Ports/Ports/Raze.cs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ protected override void BeforeStart(IGame game, IAddon campaign)
File.WriteAllText(config, DefaultConfig);
}

AddGamePathsToConfig(game.GameInstallFolder!, game.ModsFolderPath, config, campaign);
AddGamePathsToConfig(game, campaign, game.GameInstallFolder!, config);

FixRoute66Files(game, campaign);
}
Expand Down Expand Up @@ -214,7 +214,7 @@ private void GetDukeArgs(StringBuilder sb, DukeGame game, IAddon addon)
{
var config = Path.Combine(PathToExecutableFolder, ConfigFile);

AddGamePathsToConfig(game.DukeWTInstallPath!, game.ModsFolderPath, config, addon);
AddGamePathsToConfig(game, addon, game.DukeWTInstallPath!, config);

_ = sb.Append($" -addon {(byte)DukeAddonEnum.Base}");
}
Expand Down Expand Up @@ -350,7 +350,7 @@ private void GetRedneckArgs(StringBuilder sb, RedneckGame game, IAddon addon)
if (rCamp.Id.Equals(nameof(GameEnum.RidesAgain), StringComparison.OrdinalIgnoreCase))
{
var pathToConfig = Path.Combine(PathToExecutableFolder, ConfigFile);
AddGamePathsToConfig(game.AgainInstallPath!, game.ModsFolderPath, pathToConfig, addon);
AddGamePathsToConfig(game, addon, game.AgainInstallPath!, pathToConfig);
}


Expand Down Expand Up @@ -480,8 +480,7 @@ private void FixRoute66Files(IGame game, IAddon _)
/// <summary>
/// Add paths to game and mods folder to the config
/// </summary>
[Obsolete("Remove if this ever implemented https://github.com/ZDoom/Raze/issues/1060")]
private static void AddGamePathsToConfig(string gameFolder, string modsFolder, string config, IAddon campaign)
private static void AddGamePathsToConfig(IGame game, IAddon campaign, string gameInstallFolder, string config)
{
var contents = File.ReadAllLines(config);

Expand All @@ -493,12 +492,18 @@ private static void AddGamePathsToConfig(string gameFolder, string modsFolder, s
{
_ = sb.AppendLine(contents[i]);

var path = gameFolder.Replace('\\', '/');
//game folder
var path = gameInstallFolder.Replace('\\', '/');
_ = sb.Append("Path=").AppendLine(path);

if (Directory.Exists(Path.Combine(gameFolder, "addons")))
//duke addons folders
if (game is DukeGame dGame)
{
_ = sb.Append("Path=").AppendLine(path + "/addons");
foreach (var folder in dGame.AddonsPaths)
{
path = folder.Value.Replace('\\', '/');
_ = sb.Append("Path=").AppendLine(path);
}
}

do
Expand All @@ -515,17 +520,11 @@ private static void AddGamePathsToConfig(string gameFolder, string modsFolder, s
{
_ = sb.AppendLine(contents[i]);

var path = gameFolder.Replace('\\', '/');
_ = sb.Append("Path=").AppendLine(path);

if (Directory.Exists(Path.Combine(gameFolder, "addons")))
{
_ = sb.Append("Path=").AppendLine(path + "/addons");
}

path = modsFolder.Replace('\\', '/');
//mods folder
var path = game.ModsFolderPath.Replace('\\', '/');
_ = sb.Append("Path=").AppendLine(path);

//blood unpacked addons
if (campaign is BloodCampaign bCamp &&
bCamp.IsUnpacked)
{
Expand Down
Loading

0 comments on commit 1f7ddcf

Please sign in to comment.