diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs index f4820eec0..9a8d2b202 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs @@ -312,7 +312,7 @@ namespace Barotrauma public void DrawForeground(SpriteBatch spriteBatch) { - if (Character is null || GameMain.IsSingleplayer) { return; } + if (Character is null || !(GameMain.GameSession?.Campaign is MultiPlayerCampaign)) { return; } const int million = 1000000; int xfraction = (int)(HUDLayoutSettings.BottomRightInfoArea.Width * 0.2f); int yoffset = GUI.IntScale(6); diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj index c16a0f7df..8abd79e7a 100644 --- a/Barotrauma/BarotraumaClient/LinuxClient.csproj +++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.17.10.0 + 0.17.11.0 Copyright © FakeFish 2018-2022 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index 6ad2b78d6..74386e05d 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.17.10.0 + 0.17.11.0 Copyright © FakeFish 2018-2022 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index 5e021b602..61c82a062 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.17.10.0 + 0.17.11.0 Copyright © FakeFish 2018-2022 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaServer/LinuxServer.csproj b/Barotrauma/BarotraumaServer/LinuxServer.csproj index 47c2ebaba..c820ba315 100644 --- a/Barotrauma/BarotraumaServer/LinuxServer.csproj +++ b/Barotrauma/BarotraumaServer/LinuxServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.17.10.0 + 0.17.11.0 Copyright © FakeFish 2018-2022 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/MacServer.csproj b/Barotrauma/BarotraumaServer/MacServer.csproj index dadf01b82..9fe959493 100644 --- a/Barotrauma/BarotraumaServer/MacServer.csproj +++ b/Barotrauma/BarotraumaServer/MacServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.17.10.0 + 0.17.11.0 Copyright © FakeFish 2018-2022 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index 444720c82..ed4390605 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.17.10.0 + 0.17.11.0 Copyright © FakeFish 2018-2022 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaShared/Lua/ModLoader.lua b/Barotrauma/BarotraumaShared/Lua/ModLoader.lua index bd2b8ad5c..1dc3d28c0 100644 --- a/Barotrauma/BarotraumaShared/Lua/ModLoader.lua +++ b/Barotrauma/BarotraumaShared/Lua/ModLoader.lua @@ -1,5 +1,9 @@ -local allPackages = ContentPackageManager.AllPackages -local localPackages = ContentPackageManager.LocalPackages +local LUA_MOD_REQUIRE_PATH = "/Lua/?.lua" +local LUA_MOD_AUTORUN_PATH = "/Lua/Autorun" +local LUA_MOD_FORCEDAUTORUN_PATH = "/Lua/ForcedAutorun" + +local allPackages = ContentPackageManager.AllPackages +local localPackages = ContentPackageManager.LocalPackages local enabledPackages = ContentPackageManager.EnabledPackages.All local function EndsWith(str, suffix) @@ -30,52 +34,111 @@ local function RunFolder(folder, rootFolder, package) end end +local function assertTypes(expectedTypes, ...) + local args = table.pack(...) + assert( + #args == #expectedTypes, + string.format( + "Assertion failed: incorrect number of args\n\texpected = %s\n\tgot = %s", + #expectedTypes, + #args + ) + ) + for i = 1, #args do + local arg = args[i] + local expectedType = expectedTypes[i] + assert( + type(arg) == expectedType, + string.format( + "Assertion failed: incorrect argument type (arg #%d)\n\texpected = %s\n\tgot = %s", + i, + expectedType, + type(arg) + ) + ) + end +end -for contentPackage in enabledPackages do - if contentPackage then - local d = contentPackage.Path:gsub("\\", "/") - d = d:gsub("/filelist.xml", "") +local function ExecutionQueue() + local queue = {} + local function processQueueFIFO() + while queue[1] ~= nil do + RunFolder( + table.unpack( + table.remove(queue) + ) + ) + end + end + local function queueExecutionFIFO(...) + assertTypes( + { 'string', 'string', 'userdata' }, + ... + ) + table.insert( + queue, + table.pack(...) + ) + end + return queueExecutionFIFO, processQueueFIFO +end - table.insert(package.path, (d .. "/Lua/?.lua")) +local queueAutorun, processAutorun = ExecutionQueue() +local queueForcedAutorun, processForcedAutorun = ExecutionQueue() - if File.DirectoryExists(d .. "/Lua/Autorun") then - RunFolder(d .. "/Lua/Autorun", d, contentPackage) +local function processPackages(packages, fn) + for pkg in packages do + if pkg then + local pkgPath = pkg.Path + :gsub("\\", "/") + :gsub("/filelist.xml", "") + fn(pkg, pkgPath) end end end +processPackages( + enabledPackages, + function(pkg, pkgPath) + table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH) + local autorunPath = pkgPath .. LUA_MOD_AUTORUN_PATH + if File.DirectoryExists(autorunPath) then + queueAutorun(autorunPath, pkgPath, pkg) + end + end +) + -- we don't want to execute workshop ForcedAutorun if we have a local Package local executedLocalPackages = {} -for contentPackage in localPackages do - if contentPackage then - local d = contentPackage.Path:gsub("\\", "/") - d = d:gsub("/filelist.xml", "") - - table.insert(package.path, (d .. "/Lua/?.lua")) - - if File.DirectoryExists(d .. "/Lua/ForcedAutorun") then - RunFolder(d .. "/Lua/ForcedAutorun", d, contentPackage) - - executedLocalPackages[contentPackage.Name] = true +processPackages( + localPackages, + function(pkg, pkgPath) + table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH) + local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH + if File.DirectoryExists(forcedAutorunPath) then + queueForcedAutorun(forcedAutorunPath, pkgPath, pkg) + executedLocalPackages[pkg.Name] = true end end -end +) -for contentPackage in allPackages do - if contentPackage and executedLocalPackages[contentPackage.Name] == nil then - local d = contentPackage.Path:gsub("\\", "/") - d = d:gsub("/filelist.xml", "") - - table.insert(package.path, (d .. "/Lua/?.lua")) - - if File.DirectoryExists(d .. "/Lua/ForcedAutorun") then - RunFolder(d .. "/Lua/ForcedAutorun", d, contentPackage) +processPackages( + allPackages, + function(pkg, pkgPath) + if not executedLocalPackages[pkg.Name] then + table.insert(package.path, pkgPath .. LUA_MOD_REQUIRE_PATH) + local forcedAutorunPath = pkgPath .. LUA_MOD_FORCEDAUTORUN_PATH + if File.DirectoryExists(forcedAutorunPath) then + queueForcedAutorun(forcedAutorunPath, pkgPath, pkg) + end end end -end +) setmodulepaths(package.path) +processAutorun() +processForcedAutorun() Hook.Add("stop", "luaSetup.stop", function () print("Stopping Lua...") diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs index 5dbf55fa0..fa1aeaf55 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs @@ -341,7 +341,7 @@ namespace Barotrauma if (levelData.HasBeaconStation && !levelData.IsBeaconActive) { - var beaconMissionPrefabs = MissionPrefab.Prefabs.Where(m => m.Tags.Any(t => t.Equals("beaconnoreward", StringComparison.OrdinalIgnoreCase))); + var beaconMissionPrefabs = MissionPrefab.Prefabs.Where(m => m.Tags.Any(t => t.Equals("beaconnoreward", StringComparison.OrdinalIgnoreCase))).OrderBy(m => m.UintIdentifier); if (beaconMissionPrefabs.Any()) { Random rand = new MTRandom(ToolBox.StringToInt(levelData.Seed)); @@ -354,7 +354,7 @@ namespace Barotrauma } if (levelData.HasHuntingGrounds) { - var huntingGroundsMissionPrefabs = MissionPrefab.Prefabs.Where(m => m.Tags.Any(t => t.Equals("huntinggrounds", StringComparison.OrdinalIgnoreCase))); + var huntingGroundsMissionPrefabs = MissionPrefab.Prefabs.Where(m => m.Tags.Any(t => t.Equals("huntinggrounds", StringComparison.OrdinalIgnoreCase))).OrderBy(m => m.UintIdentifier); if (!huntingGroundsMissionPrefabs.Any()) { DebugConsole.AddWarning("Could not find a hunting grounds mission for the level. No mission with the tag \"huntinggrounds\" found."); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/Powered.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/Powered.cs index 91768fd93..b6d481651 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/Powered.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/Powered.cs @@ -397,11 +397,6 @@ namespace Barotrauma.Items.Components //Only add valid connections if (otherC.Grid != grid && (otherC.Grid == null || !Grids.ContainsKey(otherC.Grid.ID)) && ValidPowerConnection(c, otherC)) { - if (otherC.Item.Condition <= 0.0f) - { - continue; - } - otherC.Grid = grid; //Assigning ID early prevents unncessary adding to stack probeStack.Push(otherC); } @@ -665,7 +660,10 @@ namespace Barotrauma.Items.Components public static bool ValidPowerConnection(Connection conn1, Connection conn2) { - return conn1.IsPower && conn2.IsPower && (conn1.Item.HasTag("junctionbox") || conn2.Item.HasTag("junctionbox") || conn1.Item.HasTag("dock") || conn2.Item.HasTag("dock") || conn1.IsOutput != conn2.IsOutput); + return + conn1.IsPower && conn2.IsPower && + conn1.Item.Condition > 0.0f && conn2.Item.Condition > 0.0f && + (conn1.Item.HasTag("junctionbox") || conn2.Item.HasTag("junctionbox") || conn1.Item.HasTag("dock") || conn2.Item.HasTag("dock") || conn1.IsOutput != conn2.IsOutput); } /// diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/RelayComponent.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/RelayComponent.cs index ab0034584..0a0a3e691 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/RelayComponent.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/RelayComponent.cs @@ -141,7 +141,7 @@ namespace Barotrauma.Items.Components ApplyStatusEffects(ActionType.OnActive, deltaTime, null); - if (Voltage > OverloadVoltage && CanBeOverloaded) + if (Voltage > OverloadVoltage && CanBeOverloaded && item.Repairables.Any()) { item.Condition = 0.0f; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs index 453f2a412..74532ffa6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs @@ -957,7 +957,18 @@ namespace Barotrauma public PriceInfo GetPriceInfo(Location.StoreInfo store) { - if (!store.Identifier.IsEmpty && StorePrices != null && StorePrices.TryGetValue(store.Identifier, out var storePriceInfo)) + if (store == null) + { + string message = $"Tried to get price info for \"{Identifier}\" with a null store parameter!\n{Environment.StackTrace.CleanupStackTrace()}"; +#if DEBUG + DebugConsole.ShowError(message); +#else + DebugConsole.AddWarning(message); + GameAnalyticsManager.AddErrorEventOnce("ItemPrefab.GetPriceInfo:StoreParameterNull", GameAnalyticsManager.ErrorSeverity.Error, message); +#endif + return null; + } + else if (!store.Identifier.IsEmpty && StorePrices != null && StorePrices.TryGetValue(store.Identifier, out var storePriceInfo)) { return storePriceInfo; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaRequire.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaRequire.cs new file mode 100644 index 000000000..0509bc0a6 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/Lua/LuaRequire.cs @@ -0,0 +1,41 @@ + + +using System; +using System.Collections.Generic; +using MoonSharp.Interpreter; + +namespace Barotrauma +{ + class LuaRequire { + private Script lua { get; set; } + private Dictionary, DynValue> LoadedModules { get; set; } + + private bool GetExistingReturnValue(Tuple key, ref DynValue returnValue) { + return LoadedModules.TryGetValue(key, out returnValue); + } + + private void ExecuteModule(Tuple key, ref DynValue returnValue) { + string moduleName = key.Item1; + Table globalContext = key.Item2; + returnValue = lua.Call(lua.RequireModule(moduleName, globalContext)); + LoadedModules[key] = returnValue; + } + + // Lua modules that have been previously loaded by require() will + // not be loaded again; instead, their initial return value is + // preserved and returned again on subsequent attempts. + public DynValue Require(string moduleName, Table globalContext) { + DynValue returnValue = DynValue.Nil; + var key = new Tuple(moduleName, globalContext); + + if (GetExistingReturnValue(key, ref returnValue)) return returnValue; + ExecuteModule(key, ref returnValue); + return returnValue; + } + + public LuaRequire(Script lua) { + this.lua = lua; + LoadedModules = new Dictionary, DynValue>(); + } + } +} \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs index 0e3baa80b..fd2c0c57d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/LuaCs/LuaCsSetup.cs @@ -46,6 +46,7 @@ namespace Barotrauma public LuaCsHook Hook { get; private set; } public LuaCsNetworking Networking { get; private set; } public LuaCsModStore ModStore { get; private set; } + private LuaRequire require { get; set; } public CsScriptLoader CsScriptLoader { get; private set; } public CsLua Lua { get; private set; } @@ -71,9 +72,9 @@ namespace Barotrauma } - public static ContentPackage GetPackage(Identifier name) + public static ContentPackage GetPackage(Identifier name, bool fallbackToAll = true) { - foreach (ContentPackage package in ContentPackageManager.LocalPackages) + foreach (ContentPackage package in ContentPackageManager.EnabledPackages.All) { if (package.NameMatches(name)) { @@ -81,11 +82,22 @@ namespace Barotrauma } } - foreach (ContentPackage package in ContentPackageManager.AllPackages) + if (fallbackToAll) { - if (package.NameMatches(name)) + foreach (ContentPackage package in ContentPackageManager.LocalPackages) { - return package; + if (package.NameMatches(name)) + { + return package; + } + } + + foreach (ContentPackage package in ContentPackageManager.AllPackages) + { + if (package.NameMatches(name)) + { + return package; + } } } @@ -264,22 +276,18 @@ namespace Barotrauma return null; } - - private DynValue Require(string modname, Table globalContext) + public DynValue Require(string moduleName, Table globalContexts) { try { - return lua.Call(lua.RequireModule(modname, globalContext)); - + return require.Require(moduleName, globalContexts); } catch (Exception e) { HandleException(e); } - return null; } - public object CallLuaFunction(object function, params object[] arguments) { try @@ -362,6 +370,8 @@ namespace Barotrauma Lua = new CsLua(this); CsScript = new CsScriptRunner(this); + require = new LuaRequire(lua); + Game = new LuaGame(); Networking = new LuaCsNetworking(); Hook.Initialize(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/StructurePrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/StructurePrefab.cs index 0a1356efd..30c8ae40b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/StructurePrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/StructurePrefab.cs @@ -153,7 +153,10 @@ namespace Barotrauma { Name = TextManager.GetWithVariable("wreckeditemformat", "[name]", Name); } - Name = Name.Fallback(OriginalName); + if (!string.IsNullOrEmpty(OriginalName)) + { + Name = Name.Fallback(OriginalName); + } var tags = new HashSet(); string joinedTags = element.GetAttributeString("tags", ""); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Submarine.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Submarine.cs index ec08d2c38..a046b1098 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Submarine.cs @@ -1229,6 +1229,7 @@ namespace Barotrauma { if (!connectedSubs.Contains(item.Submarine)) { continue; } if (!item.HasTag("cargocontainer")) { continue; } + if (item.NonInteractable || item.HiddenInGame) { continue; } var itemContainer = item.GetComponent(); if (itemContainer == null) { continue; } int emptySlots = 0; diff --git a/Barotrauma/BarotraumaShared/changelog.txt b/Barotrauma/BarotraumaShared/changelog.txt index 0187318b1..3572e4841 100644 --- a/Barotrauma/BarotraumaShared/changelog.txt +++ b/Barotrauma/BarotraumaShared/changelog.txt @@ -1,3 +1,15 @@ +--------------------------------------------------------------------------------------------------------- +v0.17.11.0 +--------------------------------------------------------------------------------------------------------- + +Fixes: +- Fixed occasional crash when talking to an outpost merchant. +- Fixed cargo missions putting cargo in non-interactable and hidden-in-game containers. +- Don't show wallet info on character portrait in other multiplayer game modes than the campaign. +- Fixed certainstructure names not showing up properly in the submarine editor in languages other than English. +- Fixed relays that have "can be overloaded" set to true breaking when overloaded (should never happen because relays can't be repaired). +- Fixed occasional mission mismatch errors in multiplayer when there's a hunting grounds or beacon mission in the level. + --------------------------------------------------------------------------------------------------------- v0.17.10.0 --------------------------------------------------------------------------------------------------------- diff --git a/Libraries/MoonSharp.Interpreter.dll b/Libraries/MoonSharp.Interpreter.dll index a90fea344..8262e293e 100644 Binary files a/Libraries/MoonSharp.Interpreter.dll and b/Libraries/MoonSharp.Interpreter.dll differ