Merge commit '5208b922d8fa07321cf33de56bdc2a8f389df681'

This commit is contained in:
Joonas Rikkonen
2019-06-04 16:57:05 +03:00
103 changed files with 1694 additions and 507 deletions

Binary file not shown.

View File

@@ -223,6 +223,7 @@
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\MathUtils.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\OpenFileDialog.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\TextureLoader.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Source\Utils\ToolBox.cs" />
</ItemGroup>

View File

@@ -80,8 +80,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="GameAnalytics.Mono, Version=1.0.6710.29255, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\GameAnalytics.Mono.dll</HintPath>
<Reference Include="GameAnalytics.Mono, Version=1.0.7018.15293, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\GameAnalytics.Mono.dll</HintPath>
</Reference>
<Reference Include="MonoGame.Framework, Version=3.7.1.189, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\lib\net45\MonoGame.Framework.dll</HintPath>
@@ -101,7 +101,7 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Data.SQLite, Version=1.0.102.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
@@ -247,6 +247,9 @@
<None Include="System.Configuration.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="Accessibility.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="System.Core.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -268,6 +271,12 @@
<None Include="System.Security.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="System.Windows.Forms.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="System.Windows.Forms.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="System.Xml.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -341,13 +350,13 @@
<Import Project="ClientCode.projitems" Label="Shared" />
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets'))" />
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets'))" />
<Error Condition="!Exists('..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets'))" />
</Target>
<Import Project="..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets" Condition="Exists('..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets')" />

View File

@@ -79,8 +79,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="GameAnalytics.Mono, Version=1.0.6710.29255, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\GameAnalytics.Mono.dll</HintPath>
<Reference Include="GameAnalytics.Mono, Version=1.0.7018.15293, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\GameAnalytics.Mono.dll</HintPath>
</Reference>
<Reference Include="MonoGame.Framework, Version=3.7.1.189, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\lib\net45\MonoGame.Framework.dll</HintPath>
@@ -100,7 +100,7 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Data.SQLite, Version=1.0.102.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
@@ -271,13 +271,12 @@
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets'))" />
<Error Condition="!Exists('..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets'))" />
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets'))" />
</Target>
<Import Project="..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets" Condition="Exists('..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\build\MonoGame.Framework.DesktopGL.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
@@ -288,8 +287,10 @@
<Target Name="AfterBuild">
<!-- Write version number to a "Version.txt" file in the output folder -->
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
<Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
<Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
</GetAssemblyIdentity>
<Exec Command="echo v%(CurrentAssembly.Version) > $(TargetDir)Version.txt"></Exec>
<Exec Command="echo v%(CurrentAssembly.Version) &gt; $(TargetDir)Version.txt">
</Exec>
</Target>
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
</Project>

View File

@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.0.2")]
[assembly: AssemblyFileVersion("0.9.0.2")]
[assembly: AssemblyVersion("0.9.0.4")]
[assembly: AssemblyFileVersion("0.9.0.4")]

View File

@@ -43,7 +43,7 @@ namespace Barotrauma
{
return text;
}
text = TextManager.Get(textTag).Replace("[key]", keyBind);
text = TextManager.GetWithVariable(textTag, "[key]", keyBind);
cachedHudTexts.Add(textTag + keyBind, text);
return text;
}

View File

@@ -119,11 +119,9 @@ namespace Barotrauma
if ((int)newLevel > (int)prevLevel)
{
GUI.AddMessage(
TextManager.Get("SkillIncreased")
.Replace("[name]", Name)
.Replace("[skillname]", TextManager.Get("SkillName." + skillIdentifier))
.Replace("[newlevel]", ((int)newLevel).ToString()),
Color.Green);
TextManager.GetWithVariables("SkillIncreased", new string[3] { "[name]", "[skillname]", "[newlevel]" },
new string[3] { Name, TextManager.Get("SkillName." + skillIdentifier), ((int)newLevel).ToString() },
new bool[3] { false, true, false }), Color.Green);
}
}

View File

@@ -181,13 +181,11 @@ namespace Barotrauma
bool attackInput = msg.ReadBoolean();
keys[(int)InputType.Attack].Held = attackInput;
keys[(int)InputType.Attack].SetState(false, attackInput);
if (aimInput)
{
double aimAngle = ((double)msg.ReadUInt16() / 65535.0) * 2.0 * Math.PI;
cursorPosition = AimRefPosition + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 60.0f;
TransformCursorPos();
}
double aimAngle = msg.ReadUInt16() / 65535.0 * 2.0 * Math.PI;
cursorPosition = AimRefPosition + new Vector2((float)Math.Cos(aimAngle), (float)Math.Sin(aimAngle)) * 60.0f;
TransformCursorPos();
bool ragdollInput = msg.ReadBoolean();
keys[(int)InputType.Ragdoll].Held = ragdollInput;
keys[(int)InputType.Ragdoll].SetState(false, ragdollInput);

View File

@@ -26,7 +26,7 @@ namespace Barotrauma
}
else if (state != InfectionState.Active && Character.Controlled == character)
{
GUI.AddMessage(TextManager.Get("HuskActivate").Replace("[Attack]", GameMain.Config.KeyBind(InputType.Attack).ToString()),
GUI.AddMessage(TextManager.GetWithVariable("HuskActivate", "[Attack]", GameMain.Config.KeyBind(InputType.Attack).ToString()),
Color.Red);
}
}

View File

@@ -606,7 +606,7 @@ namespace Barotrauma
.ThenByDescending(a => a.Strength).FirstOrDefault();
if (affliction.DamagePerSecond > 0 || affliction.Strength > 0)
{
var limbHealth = GetMathingLimbHealth(affliction);
var limbHealth = GetMatchingLimbHealth(affliction);
if (limbHealth != null)
{
selectedLimbIndex = limbHealths.IndexOf(limbHealth);

View File

@@ -401,6 +401,18 @@ namespace Barotrauma
GameMain.CharacterEditorScreen.Select();
}));
commands.Add(new Command("money", "", args =>
{
if (args.Length == 0) { return; }
if (GameMain.GameSession.GameMode is CampaignMode campaign)
{
if (int.TryParse(args[0], out int money))
{
campaign.Money += money;
}
}
}, isCheat: true));
AssignRelayToServer("kick", false);
AssignRelayToServer("kickid", false);
AssignRelayToServer("ban", false);

View File

@@ -343,7 +343,7 @@ namespace Barotrauma
SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume);
SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume * 5.0f);
SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume * 20.0f);
if (Config.EnableSplashScreen)
{
var pendingSplashScreens = TitleScreen.PendingSplashScreens;
@@ -519,10 +519,8 @@ namespace Barotrauma
var exePaths = contentPackage.GetFilesOfType(ContentType.Executable);
if (exePaths.Any() && AppDomain.CurrentDomain.FriendlyName != exePaths.First())
{
var msgBox = new GUIMessageBox(TextManager.Get("Error"),
TextManager.Get("IncorrectExe")
.Replace("[selectedpackage]", contentPackage.Name)
.Replace("[exename]", exePaths.First()),
var msgBox = new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("IncorrectExe",
new string[2] { "[selectedpackage]", "[exename]" }, new string[2] { contentPackage.Name, exePaths.First() }),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked += (_, userdata) =>
{
@@ -618,7 +616,7 @@ namespace Barotrauma
GameMain.ResetFrameTime();
if (TitleScreen.LoadState >= 100.0f &&
(!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length>0 || PlayerInput.LeftButtonClicked()))
(!waitForKeyHit || ((PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0 || PlayerInput.LeftButtonClicked()) && WindowActive)))
{
loadingScreenOpen = false;
}
@@ -637,7 +635,7 @@ namespace Barotrauma
{
SoundPlayer.Update((float)Timing.Step);
if (PlayerInput.KeyHit(Keys.Escape))
if (PlayerInput.KeyHit(Keys.Escape) && WindowActive)
{
// Check if a text input is selected.
if (GUI.KeyboardDispatcher.Subscriber != null)
@@ -862,7 +860,7 @@ namespace Barotrauma
{
if (NetworkMember != null) NetworkMember.Disconnect();
SteamManager.ShutDown();
if (GameSettings.SendUserStatistics) GameAnalytics.OnStop();
if (GameSettings.SendUserStatistics) GameAnalytics.OnQuit();
base.OnExiting(sender, args);
}
}

View File

@@ -8,7 +8,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -505,7 +504,10 @@ namespace Barotrauma
btn.OnClicked += (GUIButton button, object userData) =>
{
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
#if CLIENT
if (GameMain.Client != null && Character.Controlled == null) { return false; }
#endif
if (Character.Controlled != null && Character.Controlled.SpeechImpediment >= 100.0f) { return false; }
if (btn.GetChildByUserData("selected").Visible)
{
@@ -919,7 +921,9 @@ namespace Barotrauma
Font = GUI.SmallFont,
OnClicked = (btn, userData) =>
{
if (Character.Controlled == null) return false;
#if CLIENT
if (GameMain.Client != null && Character.Controlled == null) { return false; }
#endif
SetCharacterOrder(character, userData as Order, option, Character.Controlled);
orderTargetFrame = null;
OrderOptionButtons.Clear();
@@ -957,7 +961,9 @@ namespace Barotrauma
UserData = item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
OnClicked = (btn, userData) =>
{
if (Character.Controlled == null) return false;
#if CLIENT
if (GameMain.Client != null && Character.Controlled == null) { return false; }
#endif
SetCharacterOrder(character, userData as Order, option, Character.Controlled);
orderTargetFrame = null;
OrderOptionButtons.Clear();
@@ -1353,7 +1359,7 @@ namespace Barotrauma
bool hasLeaks = Character.Controlled.CurrentHull.Submarine != null && Character.Controlled.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f);
ToggleReportButton("reportbreach", hasLeaks);
bool hasIntruders = Character.CharacterList.Any(c => c.CurrentHull == Character.Controlled.CurrentHull && AIObjectiveFightIntruders.IsValidTarget(Character.Controlled, c));
bool hasIntruders = Character.CharacterList.Any(c => c.CurrentHull == Character.Controlled.CurrentHull && AIObjectiveFightIntruders.IsValidTarget(c, Character.Controlled));
ToggleReportButton("reportintruders", hasIntruders);
foreach (GUIComponent reportButton in reportButtonFrame.Children)

View File

@@ -113,8 +113,8 @@ namespace Barotrauma
if (GameMain.Client != null && interactor == Character.Controlled)
{
var msgBox = new GUIMessageBox("", TextManager.Get("CampaignEnterOutpostPrompt")
.Replace("[locationname]", Submarine.MainSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
var msgBox = new GUIMessageBox("", TextManager.GetWithVariable("CampaignEnterOutpostPrompt", "[locationname]",
Submarine.MainSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
UserData = "watchmanprompt"

View File

@@ -125,12 +125,12 @@ namespace Barotrauma
}
else if (leavingSub.AtEndPosition)
{
endRoundButton.Text = ToolBox.LimitString(TextManager.Get("EnterLocation").Replace("[locationname]", Map.SelectedLocation.Name), endRoundButton.Font, endRoundButton.Rect.Width - 5);
endRoundButton.Text = ToolBox.LimitString(TextManager.GetWithVariable("EnterLocation", "[locationname]", Map.SelectedLocation.Name), endRoundButton.Font, endRoundButton.Rect.Width - 5);
endRoundButton.Visible = true;
}
else if (leavingSub.AtStartPosition)
{
endRoundButton.Text = ToolBox.LimitString(TextManager.Get("EnterLocation").Replace("[locationname]", Map.CurrentLocation.Name), endRoundButton.Font, endRoundButton.Rect.Width - 5);
endRoundButton.Text = ToolBox.LimitString(TextManager.GetWithVariable("EnterLocation", "[locationname]", Map.CurrentLocation.Name), endRoundButton.Font, endRoundButton.Rect.Width - 5);
endRoundButton.Visible = true;
}
else
@@ -189,8 +189,8 @@ namespace Barotrauma
{
return;
}
var msgBox = new GUIMessageBox("", TextManager.Get("CampaignEnterOutpostPrompt")
.Replace("[locationname]", leavingSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
var msgBox = new GUIMessageBox("", TextManager.GetWithVariable("CampaignEnterOutpostPrompt", "[locationname]",
leavingSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
UserData = "watchmanprompt"

View File

@@ -165,9 +165,9 @@ namespace Barotrauma.Tutorials
{
yield return null;
GameMain.GameSession.CrewManager.HighlightOrderButton(captain_mechanic, "repairsystems", highlightColor, new Vector2(5, 5));
HighlightOrderOption("jobspecific");
//HighlightOrderOption("jobspecific");
}
while (!HasOrder(captain_mechanic, "repairsystems", "jobspecific"));
while (!HasOrder(captain_mechanic, "repairsystems"));
RemoveCompletedObjective(segments[1]);
yield return new WaitForSeconds(2f, false);
TriggerTutorialSegment(2);
@@ -230,7 +230,7 @@ namespace Barotrauma.Tutorials
} while (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0);
RemoveCompletedObjective(segments[6]);
yield return new WaitForSeconds(3f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Captain.Radio.Complete").Replace("[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.GetWithVariable("Captain.Radio.Complete", "[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
SetHighlight(captain_navConsole.Item, false);
SetHighlight(captain_sonar.Item, false);
SetHighlight(captain_statusMonitor, false);

View File

@@ -364,6 +364,10 @@ namespace Barotrauma.Tutorials
{
yield return new WaitForSeconds(1.0f, false);
}
subPatients[2].Oxygen = -50;
CoroutineManager.StartCoroutine(KeepPatientAlive(subPatients[2]), "KeepPatient3Alive");
yield return new WaitForSeconds(5.0f, false);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.EnteredSub"), ChatMessageType.Radio, null);
@@ -376,8 +380,6 @@ namespace Barotrauma.Tutorials
patient.AIController.Enabled = true;
SetHighlight(patient, true);
}
subPatients[2].Oxygen = -50;
CoroutineManager.StartCoroutine(KeepPatientAlive(subPatients[2]), "KeepPatient3Alive");
double subEnterTime = Timing.TotalTime;

View File

@@ -193,6 +193,7 @@ namespace Barotrauma.Tutorials
engineer_submarineJunctionBox_2 = Item.ItemList.Find(i => i.HasTag("engineer_submarinejunctionbox_2"));
engineer_submarineJunctionBox_3 = Item.ItemList.Find(i => i.HasTag("engineer_submarinejunctionbox_3"));
engineer_submarineReactor = Item.ItemList.Find(i => i.HasTag("engineer_submarinereactor")).GetComponent<Reactor>();
engineer_submarineReactor.OnOffSwitch.BarScrollValue = .25f;
engineer_submarineReactor.IsActive = engineer_submarineReactor.AutoTemp = false;
engineer_submarineJunctionBox_1.Indestructible = false;

View File

@@ -330,7 +330,6 @@ namespace Barotrauma.Tutorials
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
RemoveCompletedObjective(segments[3]);
SetDoorAccess(mechanic_thirdDoor, mechanic_thirdDoorLight, true);
yield return new WaitForSeconds(1.5f, false);
//TriggerTutorialSegment(11, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Up), GameMain.Config.KeyBind(InputType.Down), GameMain.Config.KeyBind(InputType.Select)); // Ladder objective
//do { yield return null; } while (!mechanic_ladderSensor.MotionDetected);
//RemoveCompletedObjective(segments[11]);
@@ -348,52 +347,46 @@ namespace Barotrauma.Tutorials
SetHighlight(mechanic_craftingCabinet.Item, true);
do
{
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Items.Length; i++)
{
if (mechanic_craftingCabinet.Inventory.Items[i] != null)
{
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
}
}
if (mechanic.SelectedConstruction == mechanic_craftingCabinet.Item)
{
for (int i = 0; i < mechanic.Inventory.slots.Length; i++)
{
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
}
}
yield return null;
} while (mechanic.Inventory.FindItemByIdentifier("oxygentank") == null || mechanic.Inventory.FindItemByIdentifier("sodium") == null); // Wait until looted
yield return new WaitForSeconds(1.0f, false);
SetHighlight(mechanic_craftingCabinet.Item, false);
SetHighlight(mechanic_deconstructor.Item, true);
do
{
if (IsSelectedItem(mechanic_deconstructor.Item))
{
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") != null)
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") == null && mechanic.Inventory.FindItemByIdentifier("aluminium") == null)
{
HighlightInventorySlot(mechanic.Inventory, "oxygentank", highlightColor, .5f, .5f, 0f);
if (mechanic_deconstructor.InputContainer.Inventory.slots != null)
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Items.Length; i++)
{
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.slots.Length; i++)
Item item = mechanic_craftingCabinet.Inventory.Items[i];
if (item != null && item.prefab.Identifier == "oxygentank")
{
HighlightInventorySlot(mechanic_deconstructor.InputContainer.Inventory, i, highlightColor, .5f, .5f, 0f);
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
}
}
}
if (mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") != null && !mechanic_deconstructor.IsActive)
if (mechanic.Inventory.FindItemByIdentifier("sodium") == null)
{
if (mechanic_deconstructor.ActivateButton.Frame.FlashTimer <= 0)
for (int i = 0; i < mechanic_craftingCabinet.Inventory.Items.Length; i++)
{
mechanic_deconstructor.ActivateButton.Frame.Flash(highlightColor, 1.5f, false);
Item item = mechanic_craftingCabinet.Inventory.Items[i];
if (item != null && item.prefab.Identifier == "sodium")
{
HighlightInventorySlot(mechanic_craftingCabinet.Inventory, i, highlightColor, .5f, .5f, 0f);
}
}
}
}
yield return null;
} while ((mechanic.Inventory.FindItemByIdentifier("oxygentank") == null && mechanic.Inventory.FindItemByIdentifier("aluminium") == null) || mechanic.Inventory.FindItemByIdentifier("sodium") == null); // Wait until looted
yield return new WaitForSeconds(1.0f, false);
SetHighlight(mechanic_craftingCabinet.Item, false);
SetHighlight(mechanic_deconstructor.Item, true);
do
{
if (IsSelectedItem(mechanic_deconstructor.Item))
{
if (mechanic_deconstructor.OutputContainer.Inventory.FindItemByIdentifier("aluminium") != null)
{
HighlightInventorySlot(mechanic_deconstructor.OutputContainer.Inventory, "aluminium", highlightColor, .5f, .5f, 0f);
@@ -403,6 +396,29 @@ namespace Barotrauma.Tutorials
if (mechanic.Inventory.Items[i] == null) HighlightInventorySlot(mechanic.Inventory, i, highlightColor, .5f, .5f, 0f);
}
}
else
{
if (mechanic.Inventory.FindItemByIdentifier("oxygentank") != null && mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") == null)
{
HighlightInventorySlot(mechanic.Inventory, "oxygentank", highlightColor, .5f, .5f, 0f);
if (mechanic_deconstructor.InputContainer.Inventory.slots != null)
{
for (int i = 0; i < mechanic_deconstructor.InputContainer.Inventory.slots.Length; i++)
{
HighlightInventorySlot(mechanic_deconstructor.InputContainer.Inventory, i, highlightColor, .5f, .5f, 0f);
}
}
}
if (mechanic_deconstructor.InputContainer.Inventory.FindItemByIdentifier("oxygentank") != null && !mechanic_deconstructor.IsActive)
{
if (mechanic_deconstructor.ActivateButton.Frame.FlashTimer <= 0)
{
mechanic_deconstructor.ActivateButton.Frame.Flash(highlightColor, 1.5f, false);
}
}
}
}
yield return null;
} while (mechanic.Inventory.FindItemByIdentifier("aluminium") == null); // Wait until deconstructed

View File

@@ -123,7 +123,7 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), Mission.Name, font: GUI.LargeFont);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), TextManager.Get("MissionReward").Replace("[reward]", Mission.Reward.ToString()));
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), paddedFrame.RectTransform), TextManager.GetWithVariable("MissionReward", "[reward]", Mission.Reward.ToString()));
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), Mission.Description, wrap: true);
}

View File

@@ -44,12 +44,9 @@ namespace Barotrauma
GUIListBox infoTextBox = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.7f), paddedFrame.RectTransform));
string summaryText = TextManager.Get(gameOver ? "RoundSummaryGameOver" :
(progress ? "RoundSummaryProgress" : "RoundSummaryReturn"));
summaryText = summaryText
.Replace("[sub]", Submarine.MainSub.Name)
.Replace("[location]", progress ? GameMain.GameSession.EndLocation.Name : GameMain.GameSession.StartLocation.Name);
string summaryText = TextManager.GetWithVariables(gameOver ? "RoundSummaryGameOver" :
(progress ? "RoundSummaryProgress" : "RoundSummaryReturn"), new string[2] { "[sub]", "[location]" },
new string[2] { Submarine.MainSub.Name, progress ? GameMain.GameSession.EndLocation.Name : GameMain.GameSession.StartLocation.Name });
var infoText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
summaryText, wrap: true);
@@ -61,25 +58,27 @@ namespace Barotrauma
}
//don't show the mission info if the mission was not completed and there's no localized "mission failed" text available
if (GameMain.GameSession.Mission != null &&
(GameMain.GameSession.Mission.Completed || !string.IsNullOrEmpty(GameMain.GameSession.Mission.FailureMessage)))
if (GameMain.GameSession.Mission != null)
{
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), infoTextBox.Content.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
TextManager.AddPunctuation(':', TextManager.Get("Mission"), GameMain.GameSession.Mission.Name),
font: GUI.LargeFont);
var missionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
GameMain.GameSession.Mission.Completed ? GameMain.GameSession.Mission.SuccessMessage : GameMain.GameSession.Mission.FailureMessage,
wrap: true);
if (GameMain.GameSession.Mission.Completed && singleplayer)
string message = GameMain.GameSession.Mission.Completed ? GameMain.GameSession.Mission.SuccessMessage : GameMain.GameSession.Mission.FailureMessage;
if (!string.IsNullOrEmpty(message))
{
var missionReward = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
TextManager.Get("MissionReward").Replace("[reward]", GameMain.GameSession.Mission.Reward.ToString()));
}
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), infoTextBox.Content.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
TextManager.AddPunctuation(':', TextManager.Get("Mission"), GameMain.GameSession.Mission.Name),
font: GUI.LargeFont);
var missionInfo = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
message, wrap: true);
if (GameMain.GameSession.Mission.Completed && singleplayer)
{
var missionReward = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoTextBox.Content.RectTransform),
TextManager.GetWithVariable("MissionReward", "[reward]", GameMain.GameSession.Mission.Reward.ToString()));
}
}
}
foreach (GUIComponent child in infoTextBox.Content.Children)

View File

@@ -106,18 +106,15 @@ namespace Barotrauma
{
tickBox.TextColor = Color.Red;
tickBox.Enabled = false;
tickBox.ToolTip = TextManager.Get(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
.Replace("[packagename]", contentPackage.Name)
.Replace("[packageversion]", contentPackage.GameVersion.ToString())
.Replace("[gameversion]", GameMain.Version.ToString());
tickBox.ToolTip = TextManager.GetWithVariables(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { contentPackage.Name, contentPackage.GameVersion.ToString(), GameMain.Version.ToString() });
}
else if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes))
{
tickBox.TextColor = Color.Red;
tickBox.Enabled = false;
tickBox.ToolTip = TextManager.Get("ContentPackageMissingCoreFiles")
.Replace("[packagename]", contentPackage.Name)
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes));
tickBox.ToolTip = TextManager.GetWithVariables("ContentPackageMissingCoreFiles", new string[2] { "[packagename]", "[missingfiletypes]" },
new string[2] { contentPackage.Name, string.Join(", ", missingContentTypes) }, new bool[2] { false, true });
}
}

View File

@@ -110,7 +110,7 @@ namespace Barotrauma.Items.Components
if (child.UserData is Hull hull)
{
if (hull.Submarine == null || !hull.Submarine.IsOutpost) { continue; }
string text = TextManager.Get("MiniMapOutpostDockingInfo").Replace("[outpost]", hull.Submarine.Name);
string text = TextManager.GetWithVariable("MiniMapOutpostDockingInfo", "[outpost]", hull.Submarine.Name);
Vector2 textSize = GUI.Font.MeasureString(text);
Vector2 textPos = child.Center;
if (textPos.X + textSize.X / 2 > submarineContainer.Rect.Right)

View File

@@ -290,9 +290,9 @@ namespace Barotrauma.Items.Components
noPowerTip = TextManager.Get("SteeringNoPowerTip");
autoPilotMaintainPosTip = TextManager.Get("SteeringAutoPilotMaintainPosTip");
autoPilotLevelStartTip = TextManager.Get("SteeringAutoPilotLocationTip").Replace("[locationname]",
autoPilotLevelStartTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.StartLocation == null ? "Start" : GameMain.GameSession.StartLocation.Name);
autoPilotLevelEndTip = TextManager.Get("SteeringAutoPilotLocationTip").Replace("[locationname]",
autoPilotLevelEndTip = TextManager.GetWithVariable("SteeringAutoPilotLocationTip", "[locationname]",
GameMain.GameSession?.EndLocation == null ? "End" : GameMain.GameSession.EndLocation.Name);
steerArea = new GUICustomComponent(new RectTransform(new Point(viewSize), GuiFrame.RectTransform, Anchor.CenterLeft),

View File

@@ -57,8 +57,8 @@ namespace Barotrauma.Items.Components
}
}
Vector2 rightPos = new Vector2(x + width - 130 * GUI.xScale, y + 80 * GUI.yScale);
Vector2 leftPos = new Vector2(x + 130 * GUI.xScale, y + 80 * GUI.yScale);
Vector2 rightPos = new Vector2(x + width - 110 * GUI.xScale, y + 80 * GUI.yScale);
Vector2 leftPos = new Vector2(x + 110 * GUI.xScale, y + 80 * GUI.yScale);
Vector2 rightWirePos = new Vector2(x + width - 5 * GUI.xScale, y + 30 * GUI.yScale);
Vector2 leftWirePos = new Vector2(x + 5 * GUI.xScale, y + 30 * GUI.yScale);

View File

@@ -120,13 +120,13 @@ namespace Barotrauma.Items.Components
if (uiElements[i] is GUIButton button)
{
button.Text = string.IsNullOrWhiteSpace(customInterfaceElementList[i].Label) ?
TextManager.Get("connection.signaloutx").Replace("[num]", (i + 1).ToString()) :
TextManager.GetWithVariable("connection.signaloutx", "[num]", (i + 1).ToString()) :
customInterfaceElementList[i].Label;
}
else if (uiElements[i] is GUITickBox tickBox)
{
tickBox.Text = string.IsNullOrWhiteSpace(customInterfaceElementList[i].Label) ?
TextManager.Get("connection.signaloutx").Replace("[num]", (i + 1).ToString()) :
TextManager.GetWithVariable("connection.signaloutx", "[num]", (i + 1).ToString()) :
customInterfaceElementList[i].Label;
}
}

View File

@@ -721,7 +721,7 @@ namespace Barotrauma
var shadowSprite = GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0];
string toolTip = mouseOnHealthInterface ? TextManager.Get("QuickUseAction.UseTreatment") :
Character.Controlled.FocusedItem != null ?
TextManager.Get("PutItemIn").Replace("[itemname]", Character.Controlled.FocusedItem.Name) :
TextManager.GetWithVariable("PutItemIn", "[itemname]", Character.Controlled.FocusedItem.Name, true) :
TextManager.Get("DropItem");
int textWidth = (int)Math.Max(GUI.Font.MeasureString(draggingItem.Name).X, GUI.SmallFont.MeasureString(toolTip).X);
int textSpacing = (int)(15 * GUI.Scale);
@@ -771,11 +771,11 @@ namespace Barotrauma
{
if (idJob == null)
{
description = TextManager.Get("IDCardName").Replace("[name]", idName);
description = TextManager.GetWithVariable("IDCardName", "[name]", idName);
}
else
{
description = TextManager.Get("IDCardNameJob").Replace("[name]", idName).Replace("[job]", idJob);
description = TextManager.GetWithVariables("IDCardNameJob", new string[2] { "[name]", "[job]" }, new string[2] { idName, idJob }, new bool[2] { false, true });
}
if (!string.IsNullOrEmpty(item.Description))
{

View File

@@ -51,7 +51,7 @@ namespace Barotrauma
{
itemInUseWarning = new GUITextBlock(new RectTransform(new Point(10), GUI.Canvas), "",
textColor: Color.Orange, color: Color.Black,
textAlignment:Alignment.Center, style: "OuterGlow");
textAlignment: Alignment.Center, style: "OuterGlow");
}
return itemInUseWarning;
}
@@ -662,7 +662,7 @@ namespace Barotrauma
new Rectangle(
20, 20,
GameMain.GraphicsWidth - 40,
HUDLayoutSettings.InventoryTopY > 0 ? HUDLayoutSettings.InventoryTopY - 20 : GameMain.GraphicsHeight - 80));
HUDLayoutSettings.InventoryTopY > 0 ? HUDLayoutSettings.InventoryTopY - 40 : GameMain.GraphicsHeight - 80));
foreach (ItemComponent ic in activeHUDs)
{
@@ -740,9 +740,9 @@ namespace Barotrauma
}
}
if (itemInUseWarning != null && mergedHUDRect != Rectangle.Empty)
if (mergedHUDRect != Rectangle.Empty)
{
itemInUseWarning.Visible = false;
if (itemInUseWarning != null) { itemInUseWarning.Visible = false; }
foreach (Character otherCharacter in Character.CharacterList)
{
if (otherCharacter != character &&
@@ -754,7 +754,7 @@ namespace Barotrauma
itemInUseWarning.RectTransform.NonScaledSize = new Point(mergedHUDRect.Width, (int)(50 * GUI.Scale));
if (itemInUseWarning.UserData != otherCharacter)
{
itemInUseWarning.Text = TextManager.Get("ItemInUse").Replace("[character]", otherCharacter.Name);
itemInUseWarning.Text = TextManager.GetWithVariable("ItemInUse", "[character]", otherCharacter.Name);
itemInUseWarning.UserData = otherCharacter;
}
break;

View File

@@ -127,7 +127,7 @@ namespace Barotrauma
if (!File.Exists(pathBox.Text))
{
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("ReloadLinkedSubError").Replace("[file]", pathBox.Text));
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariable("ReloadLinkedSubError", "[file]", pathBox.Text));
pathBox.Flash(Color.Red);
pathBox.Text = filePath;
return false;

View File

@@ -310,7 +310,7 @@ namespace Barotrauma
Vector2 realWorldDimensions = Dimensions * Physics.DisplayToRealWorldRatio;
if (realWorldDimensions != Vector2.Zero)
{
string dimensionsStr = TextManager.Get("DimensionsFormat").Replace("[width]", ((int)(realWorldDimensions.X)).ToString()).Replace("[height]", ((int)(realWorldDimensions.Y)).ToString());
string dimensionsStr = TextManager.GetWithVariables("DimensionsFormat", new string[2] { "[width]", "[height]" }, new string[2] { ((int)realWorldDimensions.X).ToString(), ((int)realWorldDimensions.Y).ToString() });
var dimensionsText = new GUITextBlock(new RectTransform(new Vector2(1, 0), descriptionBox.Content.RectTransform),
TextManager.Get("Dimensions"), textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)

View File

@@ -81,7 +81,7 @@ namespace Barotrauma.Networking
new GUITextBlock(new RectTransform(new Vector2(0.6f, 0.0f), paddedPlayerFrame.RectTransform),
bannedPlayer.ExpirationTime == null ?
TextManager.Get("BanPermanent") : TextManager.Get("BanExpires").Replace("[time]", bannedPlayer.ExpirationTime.Value.ToString()),
TextManager.Get("BanPermanent") : TextManager.GetWithVariable("BanExpires", "[time]", bannedPlayer.ExpirationTime.Value.ToString()),
font: GUI.SmallFont);
var reasonText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 0.0f), paddedPlayerFrame.RectTransform),

View File

@@ -269,7 +269,7 @@ namespace Barotrauma.Networking
catch
{
new GUIMessageBox(TextManager.Get("CouldNotConnectToServer"),
TextManager.Get("InvalidIPAddress").Replace("[serverip]", serverIP).Replace("[port]", Port.ToString()));
TextManager.GetWithVariables("InvalidIPAddress", new string[2] { "[serverip]", "[port]" }, new string[2] { serverIP, Port.ToString() }));
return;
}
@@ -319,10 +319,11 @@ namespace Barotrauma.Networking
}
private bool connectCancelled;
private bool CancelConnect(GUIButton button, object obj)
private void CancelConnect()
{
connectCancelled = true;
return true;
steamAuthTicket?.Cancel();
steamAuthTicket = null;
}
// Before main looping starts, we loop here and wait for approval message
@@ -346,8 +347,8 @@ namespace Barotrauma.Networking
{
if (reconnectBox == null)
{
reconnectBox = new GUIMessageBox(connectingText, TextManager.Get("ConnectingTo").Replace("[serverip]", serverIP), new string[] { TextManager.Get("Cancel") });
reconnectBox.Buttons[0].OnClicked += CancelConnect;
reconnectBox = new GUIMessageBox(connectingText, TextManager.GetWithVariable("ConnectingTo", "[serverip]", serverIP), new string[] { TextManager.Get("Cancel") });
reconnectBox.Buttons[0].OnClicked += (btn, userdata) => { CancelConnect(); return true; };
reconnectBox.Buttons[0].OnClicked += reconnectBox.Close;
}
@@ -447,7 +448,7 @@ namespace Barotrauma.Networking
if (connectionStatus == NetConnectionStatus.Disconnected)
{
ReadDisconnectMessage(inc, false);
connectCancelled = true;
CancelConnect();
}
break;
}
@@ -467,8 +468,9 @@ namespace Barotrauma.Networking
reconnectBox = null;
}
var msgBox = new GUIMessageBox(pwMsg, "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") });
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 0.1f), msgBox.InnerFrame.RectTransform, Anchor.Center))
var msgBox = new GUIMessageBox(pwMsg, "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") },
relativeSize: new Vector2(0.25f, 0.2f), minSize: new Point(400, 150));
var passwordBox = new GUITextBox(new RectTransform(new Vector2(0.8f, 0.1f), msgBox.InnerFrame.RectTransform, Anchor.Center) { MinSize = new Point(0, 20) })
{
IgnoreLayoutGroups = true,
UserData = "password"
@@ -489,7 +491,7 @@ namespace Barotrauma.Networking
{
ReadDisconnectMessage(inc, false);
msgBox.Close(null, null);
connectCancelled = true;
CancelConnect();
}
break;
}
@@ -521,7 +523,7 @@ namespace Barotrauma.Networking
else if (cancelButton.Selected)
{
msgBox.Close(null, null);
connectCancelled = true;
CancelConnect();
}
else
{
@@ -665,7 +667,7 @@ namespace Barotrauma.Networking
string errorMsg = "Error while reading a message from server. {" + e + "}\n" + e.StackTrace;
GameAnalyticsManager.AddErrorEventOnce("GameClient.Update:CheckServerMessagesException" + e.TargetSite.ToString(), GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
DebugConsole.ThrowError("Error while reading a message from server.", e);
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("MessageReadError").Replace("[message]", e.Message).Replace("[targetsite]", e.TargetSite.ToString()));
new GUIMessageBox(TextManager.Get("Error"), TextManager.GetWithVariables("MessageReadError", new string[2] { "[message]", "[targetsite]" }, new string[2] { e.Message, e.TargetSite.ToString() }));
Disconnect();
GameMain.MainMenuScreen.Select();
return;
@@ -1197,7 +1199,7 @@ namespace Barotrauma.Networking
{
secondsLeft -= CoroutineManager.UnscaledDeltaTime;
yield return CoroutineStatus.Running;
} while (secondsLeft > 0.0f);
} while (secondsLeft > 0.0f && Screen.Selected == GameMain.GameScreen);
}
Submarine.Unload();
@@ -1684,7 +1686,7 @@ namespace Barotrauma.Networking
switch (transfer.FileType)
{
case FileTransferType.Submarine:
new GUIMessageBox(TextManager.Get("ServerDownloadFinished"), TextManager.Get("FileDownloadedNotification").Replace("[filename]", transfer.FileName));
new GUIMessageBox(TextManager.Get("ServerDownloadFinished"), TextManager.GetWithVariable("FileDownloadedNotification", "[filename]", transfer.FileName));
var newSub = new Submarine(transfer.FilePath);
var existingSubs = Submarine.SavedSubmarines.Where(s => s.Name == newSub.Name && s.MD5Hash.Hash == newSub.MD5Hash.Hash).ToList();
foreach (Submarine existingSub in existingSubs)
@@ -1803,7 +1805,6 @@ namespace Barotrauma.Networking
{
client.Shutdown("");
steamAuthTicket?.Cancel();
steamAuthTicket = null;
foreach (var fileTransfer in FileReceiver.ActiveTransfers)
@@ -2263,7 +2264,7 @@ namespace Barotrauma.Networking
GUI.DrawString(spriteBatch,
pos,
ToolBox.LimitString(TextManager.Get("DownloadingFile").Replace("[filename]", transfer.FileName), GUI.SmallFont, (int)downloadBarSize.X),
ToolBox.LimitString(TextManager.GetWithVariable("DownloadingFile", "[filename]", transfer.FileName), GUI.SmallFont, (int)downloadBarSize.X),
Color.White, null, 0, GUI.SmallFont);
GUI.DrawProgressBar(spriteBatch, new Vector2(pos.X, -pos.Y - downloadBarSize.Y / 2), new Vector2(downloadBarSize.X * 0.7f, downloadBarSize.Y / 2), transfer.Progress, Color.Green);
GUI.DrawString(spriteBatch, pos + new Vector2(5, downloadBarSize.Y / 2),
@@ -2296,9 +2297,7 @@ namespace Barotrauma.Networking
}
else
{
string endVoteText = TextManager.Get("EndRoundVotes")
.Replace("[votes]", EndVoteCount.ToString())
.Replace("[max]", EndVoteMax.ToString());
string endVoteText = TextManager.GetWithVariables("EndRoundVotes", new string[2] { "[votes]", "[max]" }, new string[2] { EndVoteCount.ToString(), EndVoteMax.ToString() });
GUI.DrawString(spriteBatch, EndVoteTickBox.Rect.Center.ToVector2() - GUI.SmallFont.MeasureString(endVoteText) / 2,
endVoteText,
Color.White,
@@ -2316,14 +2315,13 @@ namespace Barotrauma.Networking
if (respawnManager.CurrentState == RespawnManager.State.Waiting &&
respawnManager.CountdownStarted)
{
respawnInfo = TextManager.Get(respawnManager.UsingShuttle ? "RespawnShuttleDispatching" : "RespawningIn");
respawnInfo = respawnInfo.Replace("[time]", ToolBox.SecondsToReadableTime(respawnManager.RespawnTimer));
respawnInfo = TextManager.GetWithVariable(respawnManager.UsingShuttle ? "RespawnShuttleDispatching" : "RespawningIn", "[time]", ToolBox.SecondsToReadableTime(respawnManager.RespawnTimer));
}
else if (respawnManager.CurrentState == RespawnManager.State.Transporting)
{
respawnInfo = respawnManager.TransportTimer <= 0.0f ?
"" :
TextManager.Get("RespawnShuttleLeavingIn").Replace("[time]", ToolBox.SecondsToReadableTime(respawnManager.TransportTimer));
TextManager.GetWithVariable("RespawnShuttleLeavingIn", "[time]", ToolBox.SecondsToReadableTime(respawnManager.TransportTimer));
}
if (respawnManager != null)

View File

@@ -203,23 +203,20 @@ namespace Barotrauma.Networking
if (ContentPackage.List.Any(cp => cp.MD5hash.Hash == ContentPackageHashes[i]))
{
packageText.TextColor = Color.Orange;
packageText.ToolTip = TextManager.Get("ServerListContentPackageNotEnabled")
.Replace("[contentpackage]", ContentPackageNames[i]);
packageText.ToolTip = TextManager.GetWithVariable("ServerListContentPackageNotEnabled", "[contentpackage]", ContentPackageNames[i]);
}
//workshop download link found
else if (i < ContentPackageWorkshopUrls.Count && !string.IsNullOrEmpty(ContentPackageWorkshopUrls[i]))
{
availableWorkshopUrls.Add(ContentPackageWorkshopUrls[i]);
packageText.TextColor = Color.Yellow;
packageText.ToolTip = TextManager.Get("ServerListIncompatibleContentPackageWorkshopAvailable")
.Replace("[contentpackage]", ContentPackageNames[i]);
packageText.ToolTip = TextManager.GetWithVariable("ServerListIncompatibleContentPackageWorkshopAvailable", "[contentpackage]", ContentPackageNames[i]);
}
else //no package or workshop download link found, tough luck
{
packageText.TextColor = Color.Red;
packageText.ToolTip = TextManager.Get("ServerListIncompatibleContentPackage")
.Replace("[contentpackage]", ContentPackageNames[i])
.Replace("[hash]", ContentPackageHashes[i]);
packageText.ToolTip = TextManager.GetWithVariables("ServerListIncompatibleContentPackage",
new string[2] { "[contentpackage]", "[hash]" }, new string[2] { ContentPackageNames[i], ContentPackageHashes[i] });
}
}
}

View File

@@ -464,7 +464,8 @@ namespace Barotrauma.Networking
((GUIComponent)obj).Visible = !((GUIComponent)obj).Visible;
return true;
};
InitMonstersEnabled();
List<string> monsterNames = MonsterEnabled.Keys.ToList();
tempMonsterEnabled = new Dictionary<string, bool>(MonsterEnabled);
foreach (string s in monsterNames)

View File

@@ -1,11 +1,11 @@
using Barotrauma.Networking;
using Facepunch.Steamworks;
using RestSharp;
using RestSharp.Extensions.MonoHttp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
namespace Barotrauma.Steam
{
@@ -467,13 +467,29 @@ namespace Barotrauma.Steam
string previewImagePath = Path.GetFullPath(Path.Combine(itemEditor.Folder, PreviewImageName));
itemEditor.PreviewImage = previewImagePath;
using (WebClient client = new WebClient())
try
{
if (File.Exists(previewImagePath))
if (File.Exists(previewImagePath)) { File.Delete(previewImagePath); }
Uri baseAddress = new Uri(existingItem.PreviewImageUrl);
Uri directory = new Uri(baseAddress, "."); // "." == current dir, like MS-DOS
string fileName = Path.GetFileName(baseAddress.LocalPath);
IRestClient client = new RestClient(directory);
var request = new RestRequest(fileName, Method.GET);
var response = client.Execute(request);
if (response.ResponseStatus == ResponseStatus.Completed)
{
File.Delete(previewImagePath);
File.WriteAllBytes(previewImagePath, response.RawBytes);
}
client.DownloadFile(new Uri(existingItem.PreviewImageUrl), previewImagePath);
}
catch (Exception e)
{
string errorMsg = "Failed to save workshop item preview image to \"" + previewImagePath + "\" when creating workshop item staging folder.";
GameAnalyticsManager.AddErrorEventOnce("SteamManager.CreateWorkshopItemStaging:WriteAllBytesFailed" + previewImagePath,
GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + e.Message);
}
ContentPackage tempContentPackage = new ContentPackage(Path.Combine(existingItem.Directory.FullName, MetadataFileName));
@@ -580,7 +596,7 @@ namespace Barotrauma.Steam
{
if (!item.Installed)
{
errorMsg = TextManager.Get("WorkshopErrorInstallRequiredToEnable").Replace("[itemname]", item.Title);
errorMsg = TextManager.GetWithVariable("WorkshopErrorInstallRequiredToEnable", "[itemname]", item.Title);
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
return false;
}
@@ -591,18 +607,15 @@ namespace Barotrauma.Steam
if (!contentPackage.IsCompatible())
{
errorMsg = TextManager.Get(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
.Replace("[packagename]", contentPackage.Name)
.Replace("[packageversion]", contentPackage.GameVersion.ToString())
.Replace("[gameversion]", GameMain.Version.ToString());
errorMsg = TextManager.GetWithVariables(contentPackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { contentPackage.Name, contentPackage.GameVersion.ToString(), GameMain.Version.ToString() });
return false;
}
if (contentPackage.CorePackage && !contentPackage.ContainsRequiredCorePackageFiles(out List<ContentType> missingContentTypes))
{
errorMsg = TextManager.Get("ContentPackageMissingCoreFiles")
.Replace("[packagename]", contentPackage.Name)
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes));
errorMsg = TextManager.GetWithVariables("ContentPackageMissingCoreFiles", new string[2] { "[packagename]", "[missingfiletypes]" },
new string[2] { contentPackage.Name, string.Join(", ", missingContentTypes) }, new bool[2] { false, true });
return false;
}
@@ -624,9 +637,7 @@ namespace Barotrauma.Steam
{
if (File.Exists(newContentPackagePath) && !CheckFileEquality(newContentPackagePath, metaDataFilePath))
{
errorMsg = TextManager.Get("WorkshopErrorOverwriteOnEnable")
.Replace("[itemname]", item.Title)
.Replace("[filename]", newContentPackagePath);
errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] { "[itemname]", "[filename]" }, new string[2] { item.Title, newContentPackagePath });
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
return false;
}
@@ -636,9 +647,7 @@ namespace Barotrauma.Steam
string sourceFile = Path.Combine(item.Directory.FullName, contentFile.Path);
if (File.Exists(sourceFile) && File.Exists(contentFile.Path) && !CheckFileEquality(sourceFile, contentFile.Path))
{
errorMsg = TextManager.Get("WorkshopErrorOverwriteOnEnable")
.Replace("[itemname]", item.Title)
.Replace("[filename]", contentFile.Path);
errorMsg = TextManager.GetWithVariables("WorkshopErrorOverwriteOnEnable", new string[2] { "[itemname]", "[filename]" }, new string[2] { item.Title, contentFile.Path });
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
return false;
}
@@ -657,15 +666,14 @@ namespace Barotrauma.Steam
//the content package is trying to copy a file to a prohibited path, which is not allowed
if (File.Exists(sourceFile))
{
errorMsg = TextManager.Get("WorkshopErrorIllegalPathOnEnable").Replace("[filename]", contentFile.Path);
errorMsg = TextManager.GetWithVariable("WorkshopErrorIllegalPathOnEnable", "[filename]", contentFile.Path);
return false;
}
//not trying to copy anything, so this is a reference to an external file
//if the external file doesn't exist, we cannot enable the package
else if (!File.Exists(contentFile.Path))
{
//TODO: add the error message to localization
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " {File \"" + contentFile.Path + "\" not found.}";
errorMsg = TextManager.GetWithVariable("WorkshopErrorEnableFailed", "[itemname]", item.Title) + " " + TextManager.GetWithVariable("WorkshopFileNotFound", "[path]", "\"" + contentFile.Path + "\"");
return false;
}
continue;
@@ -680,8 +688,7 @@ namespace Barotrauma.Steam
else
{
//file not present in either the mod or the game folder -> cannot enable the package
//TODO: add the error message to localization
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " {File \"" + contentFile.Path + "\" not found.}";
errorMsg = TextManager.GetWithVariable("WorkshopErrorEnableFailed", "[itemname]", item.Title) + " " + TextManager.GetWithVariable("WorkshopFileNotFound", "[path]", "\"" + contentFile.Path + "\"");
return false;
}
}
@@ -697,7 +704,7 @@ namespace Barotrauma.Steam
if (!File.Exists(sourceFile)) { continue; }
if (!ContentPackage.IsModFilePathAllowed(nonContentFile))
{
DebugConsole.ThrowError(TextManager.Get("WorkshopErrorIllegalPathOnEnable").Replace("[filename]", nonContentFile));
DebugConsole.ThrowError(TextManager.GetWithVariable("WorkshopErrorIllegalPathOnEnable", "[filename]", nonContentFile));
continue;
}
Directory.CreateDirectory(Path.GetDirectoryName(nonContentFile));
@@ -706,7 +713,7 @@ namespace Barotrauma.Steam
}
catch (Exception e)
{
errorMsg = TextManager.Get("WorkshopErrorEnableFailed").Replace("[itemname]", item.Title) + " {" + e.Message + "}";
errorMsg = TextManager.GetWithVariable("WorkshopErrorEnableFailed", "[itemname]", item.Title) + " {" + e.Message + "}";
DebugConsole.NewMessage(errorMsg, Microsoft.Xna.Framework.Color.Red);
return false;
}
@@ -921,11 +928,11 @@ namespace Barotrauma.Steam
DebugConsole.ThrowError(errorMsg);
new GUIMessageBox(
TextManager.Get("Error"),
TextManager.Get("WorkshopItemUpdateFailed").Replace("[itemname]", item.Title).Replace("[errormessage]", errorMsg));
TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { item.Title, errorMsg }));
}
else
{
new GUIMessageBox("", TextManager.Get("WorkshopItemUpdated").Replace("[itemname]", item.Title));
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", item.Title));
itemsUpdated = true;
}
}

View File

@@ -281,7 +281,7 @@ namespace Barotrauma
{
CrashMessageBox("A crash report (\"" + filePath + "\") was saved in the root folder of the game and sent to the developers.");
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Critical, crashReport);
GameAnalytics.OnStop();
GameAnalytics.OnQuit();
}
else
{

View File

@@ -121,8 +121,7 @@ namespace Barotrauma
if (!hasRequiredContentPackages)
{
var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"),
TextManager.Get("ContentPackageMismatchWarning")
.Replace("[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)),
TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked = msgBox.Close;
@@ -253,7 +252,7 @@ namespace Barotrauma
public void UpdateSubList(IEnumerable<Submarine> submarines)
{
#if DEBUG
#if !DEBUG
var subsToShow = submarines.Where(s => !s.HasTag(SubmarineTag.HideInMenus));
#else
var subsToShow = submarines;

View File

@@ -636,7 +636,7 @@ namespace Barotrauma
CanBeFocused = false
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), container.RectTransform),
TextManager.Get("Reward").Replace("[reward]", selectedMission.Reward.ToString()))
TextManager.GetWithVariable("Reward", "[reward]", selectedMission.Reward.ToString()))
{
CanBeFocused = false
};
@@ -860,8 +860,7 @@ namespace Barotrauma
public string GetMoney()
{
return TextManager.Get("PlayerCredits").Replace("[credits]",
((GameMain.GameSession == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", Campaign.Money)));
return TextManager.GetWithVariable("PlayerCredits", "[credits]", (GameMain.GameSession == null) ? "0" : string.Format(CultureInfo.InvariantCulture, "{0:N0}", Campaign.Money));
}
private bool SelectCharacter(GUIComponent component, object selection)
@@ -902,7 +901,7 @@ namespace Barotrauma
{
var confirmDialog = new GUIMessageBox(
TextManager.Get("FireWarningHeader"),
TextManager.Get("FireWarningText").Replace("[charactername]", ((CharacterInfo)obj).Name),
TextManager.GetWithVariable("FireWarningText", "[charactername]", ((CharacterInfo)obj).Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
confirmDialog.Buttons[0].UserData = (CharacterInfo)obj;
confirmDialog.Buttons[0].OnClicked = FireCharacter;

View File

@@ -8,19 +8,31 @@ namespace Barotrauma
{
private GUIListBox listBox;
private readonly float scrollSpeed;
private XElement configElement;
private float scrollSpeed;
public CreditsPlayer(RectTransform rectT, string configFile) : base(null, rectT)
{
var doc = XMLExtensions.TryLoadXml(configFile);
scrollSpeed = doc.Root.GetAttributeFloat("scrollspeed", 100.0f);
int spacing = doc.Root.GetAttributeInt("spacing", 0);
GameMain.Instance.OnResolutionChanged += () => { ClearChildren(); Load(); };
listBox = new GUIListBox(new RectTransform(Vector2.One, rectT), style: null)
var doc = XMLExtensions.TryLoadXml(configFile);
configElement = doc.Root;
Load();
}
private void Load()
{
scrollSpeed = configElement.GetAttributeFloat("scrollspeed", 100.0f);
int spacing = configElement.GetAttributeInt("spacing", 0);
listBox = new GUIListBox(new RectTransform(Vector2.One, RectTransform), style: null)
{
Spacing = spacing
};
foreach (XElement subElement in doc.Root.Elements())
foreach (XElement subElement in configElement.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
{

View File

@@ -277,7 +277,7 @@ namespace Barotrauma
Stretch = true
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), commonnessContainer.RectTransform),
TextManager.Get("LevelEditorLevelObjCommonness").Replace("[leveltype]", selectedParams.Name), textAlignment: Alignment.Center);
TextManager.GetWithVariable("LevelEditorLevelObjCommonness", "[leveltype]", selectedParams.Name), textAlignment: Alignment.Center);
new GUINumberInput(new RectTransform(new Vector2(0.5f, 0.4f), commonnessContainer.RectTransform), GUINumberInput.NumberType.Float)
{
MinValueFloat = 0,

View File

@@ -584,11 +584,32 @@ namespace Barotrauma
private void UpdateTutorialList()
{
var tutorialList = menuTabs[(int)Tab.Tutorials].GetChild<GUIListBox>();
int completedTutorials = 0;
foreach (GUITextBlock tutorialText in tutorialList.Content.Children)
{
if (((Tutorial)tutorialText.UserData).Completed)
{
tutorialText.TextColor = Color.LightGreen;
completedTutorials++;
}
}
for (int i = 0; i < tutorialList.Content.Children.Count(); i++)
{
if (i < completedTutorials + 1)
{
(tutorialList.Content.GetChild(i) as GUITextBlock).TextColor = Color.LightGreen;
#if !DEBUG
(tutorialList.Content.GetChild(i) as GUITextBlock).CanBeFocused = true;
#endif
}
else
{
(tutorialList.Content.GetChild(i) as GUITextBlock).TextColor = Color.Gray;
#if !DEBUG
(tutorialList.Content.GetChild(i) as GUITextBlock).CanBeFocused = false;
#endif
}
}
}
@@ -691,11 +712,8 @@ namespace Barotrauma
" -ownerkey " + ownerKey.ToString();
string filename = "DedicatedServer.exe";
#if LINUX
#if LINUX || OSX
filename = "./DedicatedServer";
#elif OSX
filename = "mono";
arguments = "./DedicatedServer.exe " + arguments;
#endif
var processInfo = new ProcessStartInfo
{

View File

@@ -1986,16 +1986,17 @@ namespace Barotrauma
string errorMsg = "";
if (sub == null)
{
errorMsg = TextManager.Get("SubNotFoundError").Replace("[subname]", subName) + " ";
errorMsg = TextManager.GetWithVariable("SubNotFoundError", "[subname]", subName) + " ";
}
else if (sub.MD5Hash.Hash == null)
{
errorMsg = TextManager.Get("SubLoadError").Replace("[subname]", subName) + " ";
errorMsg = TextManager.GetWithVariable("SubLoadError", "[subname]", subName) + " ";
if (matchingListSub != null) matchingListSub.GetChild<GUITextBox>().TextColor = Color.Red;
}
else
{
errorMsg = TextManager.Get("SubDoesntMatchError").Replace("[subname]", sub.Name).Replace("[myhash]", sub.MD5Hash.ShortHash).Replace("[serverhash]", Md5Hash.GetShortHash(md5Hash)) + " ";
errorMsg = TextManager.GetWithVariables("SubDoesntMatchError", new string[3] { "[subname]" , "[myhash]", "[serverhash]" },
new string[3] { sub.Name, sub.MD5Hash.ShortHash, Md5Hash.GetShortHash(md5Hash) }) + " ";
}
errorMsg += TextManager.Get("DownloadSubQuestion");

View File

@@ -120,10 +120,11 @@ namespace Barotrauma
serverList = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), serverListHolder.RectTransform, Anchor.Center))
{
OnSelected = (btn, obj) => {
ServerInfo serverInfo = (ServerInfo)obj;
serverInfo.CreatePreviewWindow(serverPreview);
if (obj is ServerInfo)
{
ServerInfo serverInfo = (ServerInfo)obj;
serverInfo.CreatePreviewWindow(serverPreview);
}
return true;
}
};
@@ -218,7 +219,7 @@ namespace Barotrauma
private bool SelectServer(GUIComponent component, object obj)
{
if (obj == null || waitingForRefresh) { return false; }
if (obj == null || waitingForRefresh || (!(obj is ServerInfo))) { return false; }
if (!string.IsNullOrWhiteSpace(clientNameBox.Text))
{
@@ -468,16 +469,15 @@ namespace Barotrauma
{
string toolTip = "";
if (serverInfo.GameVersion != GameMain.Version.ToString())
toolTip = TextManager.Get("ServerListIncompatibleVersion").Replace("[version]", serverInfo.GameVersion);
toolTip = TextManager.GetWithVariable("ServerListIncompatibleVersion", "[version]", serverInfo.GameVersion);
for (int i = 0; i < serverInfo.ContentPackageNames.Count; i++)
{
if (!GameMain.SelectedPackages.Any(cp => cp.MD5hash.Hash == serverInfo.ContentPackageHashes[i]))
{
if (toolTip != "") toolTip += "\n";
toolTip += TextManager.Get("ServerListIncompatibleContentPackage")
.Replace("[contentpackage]", serverInfo.ContentPackageNames[i])
.Replace("[hash]", Md5Hash.GetShortHash(serverInfo.ContentPackageHashes[i]));
toolTip += TextManager.GetWithVariables("ServerListIncompatibleContentPackage", new string[2] { "[contentpackage]", "[hash]" },
new string[2] { serverInfo.ContentPackageNames[i], Md5Hash.GetShortHash(serverInfo.ContentPackageHashes[i]) });
}
}
@@ -541,7 +541,7 @@ namespace Barotrauma
if (masterServerResponse.ErrorException != null)
{
serverList.ClearChildren();
new GUIMessageBox(TextManager.Get("MasterServerErrorLabel"), TextManager.Get("MasterServerErrorException").Replace("[error]", masterServerResponse.ErrorException.ToString()));
new GUIMessageBox(TextManager.Get("MasterServerErrorLabel"), TextManager.GetWithVariable("MasterServerErrorException", "[error]", masterServerResponse.ErrorException.ToString()));
}
else if (masterServerResponse.StatusCode != System.Net.HttpStatusCode.OK)
{
@@ -551,24 +551,16 @@ namespace Barotrauma
{
case System.Net.HttpStatusCode.NotFound:
new GUIMessageBox(TextManager.Get("MasterServerErrorLabel"),
TextManager.Get("MasterServerError404")
.Replace("[masterserverurl]", NetConfig.MasterServerUrl)
.Replace("[statuscode]", masterServerResponse.StatusCode.ToString())
.Replace("[statusdescription]", masterServerResponse.StatusDescription));
TextManager.GetWithVariable("MasterServerError404", "[masterserverurl]", NetConfig.MasterServerUrl));
break;
case System.Net.HttpStatusCode.ServiceUnavailable:
new GUIMessageBox(TextManager.Get("MasterServerErrorLabel"),
TextManager.Get("MasterServerErrorUnavailable")
.Replace("[masterserverurl]", NetConfig.MasterServerUrl)
.Replace("[statuscode]", masterServerResponse.StatusCode.ToString())
.Replace("[statusdescription]", masterServerResponse.StatusDescription));
TextManager.Get("MasterServerErrorUnavailable"));
break;
default:
new GUIMessageBox(TextManager.Get("MasterServerErrorLabel"),
TextManager.Get("MasterServerError404")
.Replace("[masterserverurl]", NetConfig.MasterServerUrl)
.Replace("[statuscode]", masterServerResponse.StatusCode.ToString())
.Replace("[statusdescription]", masterServerResponse.StatusDescription));
TextManager.GetWithVariables("MasterServerErrorDefault", new string[2] { "[statuscode]", "[statusdescription]" },
new string[2] { masterServerResponse.StatusCode.ToString(), masterServerResponse.StatusDescription }));
break;
}

View File

@@ -1,11 +1,11 @@
using Barotrauma.Steam;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RestSharp;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Forms;
@@ -357,20 +357,25 @@ namespace Barotrauma
if (!pendingPreviewImageDownloads.Contains(item.PreviewImageUrl))
{
pendingPreviewImageDownloads.Add(item.PreviewImageUrl);
using (WebClient client = new WebClient())
if (File.Exists(imagePreviewPath))
{
if (File.Exists(imagePreviewPath))
{
File.Delete(imagePreviewPath);
}
Directory.CreateDirectory(SteamManager.WorkshopItemPreviewImageFolder);
client.DownloadFileAsync(new Uri(item.PreviewImageUrl), imagePreviewPath);
CoroutineManager.StartCoroutine(WaitForItemPreviewDownloaded(item, listBox, imagePreviewPath));
client.DownloadFileCompleted += (sender, args) =>
{
pendingPreviewImageDownloads.Remove(item.PreviewImageUrl);
};
File.Delete(imagePreviewPath);
}
Directory.CreateDirectory(SteamManager.WorkshopItemPreviewImageFolder);
Uri baseAddress = new Uri(item.PreviewImageUrl);
Uri directory = new Uri(baseAddress, "."); // "." == current dir, like MS-DOS
string fileName = Path.GetFileName(baseAddress.LocalPath);
IRestClient client = new RestClient(directory);
var request = new RestRequest(fileName, Method.GET);
client.ExecuteAsync(request, response =>
{
pendingPreviewImageDownloads.Remove(item.PreviewImageUrl);
OnPreviewImageDownloaded(response, imagePreviewPath);
CoroutineManager.StartCoroutine(WaitForItemPreviewDownloaded(item, listBox, imagePreviewPath));
});
}
else
{
@@ -410,14 +415,14 @@ namespace Barotrauma
{
if (SteamManager.UpdateWorkshopItem(item, out string errorMsg))
{
new GUIMessageBox("", TextManager.Get("WorkshopItemUpdated").Replace("[itemname]", TextManager.EnsureUTF8(item.Title)));
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemUpdated", "[itemname]", TextManager.EnsureUTF8(item.Title)));
}
else
{
DebugConsole.ThrowError(errorMsg);
new GUIMessageBox(
TextManager.Get("Error"),
TextManager.Get("WorkshopItemUpdateFailed").Replace("[itemname]", TextManager.EnsureUTF8(item.Title)).Replace("[errormessage]", errorMsg));
TextManager.GetWithVariables("WorkshopItemUpdateFailed", new string[2] { "[itemname]", "[errormessage]" }, new string[2] { TextManager.EnsureUTF8(item.Title), errorMsg }));
}
btn.Enabled = false;
btn.Visible = false;
@@ -539,6 +544,24 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), innerFrame.RectTransform), contentPackage.Name, textAlignment: Alignment.CenterLeft);
}
private void OnPreviewImageDownloaded(IRestResponse response, string previewImagePath)
{
if (response.ResponseStatus == ResponseStatus.Completed)
{
try
{
File.WriteAllBytes(previewImagePath, response.RawBytes);
}
catch (Exception e)
{
string errorMsg = "Failed to save workshop item preview image to \"" + previewImagePath + "\".";
GameAnalyticsManager.AddErrorEventOnce("SteamWorkshopScreen.OnItemPreviewDownloaded:WriteAllBytesFailed" + previewImagePath,
GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg + "\n" + e.Message);
return;
}
}
}
private IEnumerable<object> WaitForItemPreviewDownloaded(Facepunch.Steamworks.Workshop.Item item, GUIListBox listBox, string previewImagePath)
{
while (pendingPreviewImageDownloads.Contains(item.PreviewImageUrl))
@@ -710,7 +733,7 @@ namespace Barotrauma
new GUIImage(new RectTransform(new Point(scoreContainer.Rect.Height), scoreContainer.RectTransform),
i < starCount ? "GUIStarIconBright" : "GUIStarIconDark");
}
new GUITextBlock(new RectTransform(new Vector2(0.2f, 0.0f), scoreContainer.RectTransform), TextManager.Get("WorkshopItemVotes").Replace("[votecount]", (item.VotesUp + item.VotesDown).ToString()));
new GUITextBlock(new RectTransform(new Vector2(0.2f, 0.0f), scoreContainer.RectTransform), TextManager.GetWithVariable("WorkshopItemVotes", "[votecount]", (item.VotesUp + item.VotesDown).ToString()));
//tags ------------------------------------
var tagContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.05f), content.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
@@ -834,7 +857,7 @@ namespace Barotrauma
if (!item.Installed)
{
new GUIMessageBox(TextManager.Get("Error"),
TextManager.Get("WorkshopErrorInstallRequiredToEdit").Replace("[itemname]", TextManager.EnsureUTF8(item.Title)));
TextManager.GetWithVariable("WorkshopErrorInstallRequiredToEdit", "[itemname]", TextManager.EnsureUTF8(item.Title)));
return;
}
SteamManager.CreateWorkshopItemStaging(item, out itemEditor, out itemContentPackage);
@@ -942,34 +965,38 @@ namespace Barotrauma
{
OnClicked = (btn, userdata) =>
{
OpenFileDialog ofd = new OpenFileDialog()
try
{
InitialDirectory = Path.GetFullPath(SteamManager.WorkshopItemStagingFolder),
Filter = TextManager.Get("WorkshopItemPreviewImage")+"|*.png",
Title = TextManager.Get("WorkshopItemPreviewImageDialogTitle")
};
if (ofd.ShowDialog() == DialogResult.OK)
Barotrauma.OpenFileDialog ofd = new Barotrauma.OpenFileDialog()
{
Multiselect = true,
InitialDirectory = Path.GetFullPath(SteamManager.WorkshopItemStagingFolder),
Filter = TextManager.Get("WorkshopItemPreviewImage") + "|*.png",
Title = TextManager.Get("WorkshopItemPreviewImageDialogTitle")
};
if (ofd.ShowDialog() == DialogResult.OK)
{
OnPreviewImageSelected(previewIcon, ofd.FileName);
}
}
catch
{
string previewImagePath = Path.GetFullPath(Path.Combine(SteamManager.WorkshopItemStagingFolder, SteamManager.PreviewImageName));
if (new FileInfo(ofd.FileName).Length > 1024 * 1024)
{
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("WorkshopItemPreviewImageTooLarge"));
return false;
}
if (ofd.FileName != previewImagePath)
{
File.Copy(ofd.FileName, previewImagePath, overwrite: true);
}
//use a custom prompt if OpenFileDialog fails (Linux/Mac)
var msgBox = new GUIMessageBox(TextManager.Get("WorkshopItemPreviewImageDialogTitle"), "", relativeSize: new Vector2(0.4f, 0.2f),
buttons: new string[] { TextManager.Get("Cancel"), TextManager.Get("OK") });
if (itemPreviewSprites.ContainsKey(previewImagePath))
var pathBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), msgBox.Content.RectTransform, Anchor.Center) { MinSize = new Point(0,25) });
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += (btn2, userdata2) =>
{
itemPreviewSprites[previewImagePath].Remove();
}
var newPreviewImage = new Sprite(previewImagePath, sourceRectangle: null);
previewIcon.Sprite = newPreviewImage;
itemPreviewSprites[previewImagePath] = newPreviewImage;
itemEditor.PreviewImage = previewImagePath;
if (File.Exists(pathBox.Text))
{
OnPreviewImageSelected(previewIcon, pathBox.Text);
};
return true;
};
}
return true;
}
@@ -998,9 +1025,8 @@ namespace Barotrauma
{
new GUIMessageBox(
TextManager.Get("Error"),
TextManager.Get("ContentPackageCantMakeCorePackage")
.Replace("[packagename]", itemContentPackage.Name)
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes)));
TextManager.GetWithVariables("ContentPackageCantMakeCorePackage", new string[2] { "[packagename]", "[missingfiletypes]" },
new string[2] { itemContentPackage.Name, string.Join(", ", missingContentTypes) }, new bool[2] { false, true }));
tickbox.Selected = false;
}
else
@@ -1049,40 +1075,40 @@ namespace Barotrauma
{
OnClicked = (btn, userdata) =>
{
OpenFileDialog ofd = new OpenFileDialog()
try
{
InitialDirectory = Path.GetFullPath(SteamManager.WorkshopItemStagingFolder),
Title = "Select the files you want to add to the Steam Workshop item",
};
if (ofd.ShowDialog() == DialogResult.OK)
{
foreach (string file in ofd.FileNames)
Barotrauma.OpenFileDialog ofd = new Barotrauma.OpenFileDialog()
{
string filePathRelativeToStagingFolder = UpdaterUtil.GetRelativePath(file, Path.Combine(Environment.CurrentDirectory, SteamManager.WorkshopItemStagingFolder));
string filePathRelativeToBaseFolder = UpdaterUtil.GetRelativePath(file, Environment.CurrentDirectory);
//file is not inside the staging folder
if (filePathRelativeToStagingFolder.StartsWith(".."))
{
//submarines can be included in the content package directly
string basePath = Path.GetDirectoryName(filePathRelativeToBaseFolder.Replace("..", ""));
if (basePath == "Submarines")
{
string destinationPath = Path.Combine(SteamManager.WorkshopItemStagingFolder, "Submarines", Path.GetFileName(file));
File.Copy(file, destinationPath);
itemContentPackage.AddFile(filePathRelativeToBaseFolder, ContentType.Submarine);
}
else
{
itemContentPackage.AddFile(filePathRelativeToBaseFolder, ContentType.None);
}
}
else
{
itemContentPackage.AddFile(filePathRelativeToStagingFolder, ContentType.None);
}
InitialDirectory = Path.GetFullPath(SteamManager.WorkshopItemStagingFolder),
Title = TextManager.Get("workshopitemaddfiles"),
};
if (ofd.ShowDialog() == DialogResult.OK)
{
OnAddFilesSelected(ofd.FileNames);
}
RefreshCreateItemFileList();
}
catch
{
//use a custom prompt if OpenFileDialog fails (Linux/Mac)
var msgBox = new GUIMessageBox(TextManager.Get("workshopitemaddfiles"), "", relativeSize: new Vector2(0.4f, 0.2f),
buttons: new string[] { TextManager.Get("Cancel"), TextManager.Get("OK") });
var pathBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.5f), msgBox.Content.RectTransform, Anchor.Center) { MinSize = new Point(0, 25) });
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += (btn2, userdata2) =>
{
if (string.IsNullOrEmpty(pathBox?.Text)) { return true; }
string[] filePaths = pathBox.Text.Split(',');
if (File.Exists(pathBox.Text))
{
OnAddFilesSelected(filePaths);
};
return true;
};
}
return true;
}
};
@@ -1127,7 +1153,7 @@ namespace Barotrauma
OnClicked = (btn, userData) =>
{
if (itemEditor == null) { return false; }
var deleteVerification = new GUIMessageBox("", TextManager.Get("WorkshopItemDeleteVerification").Replace("[itemname]", itemEditor.Title),
var deleteVerification = new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemDeleteVerification", "[itemname]", itemEditor.Title),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
deleteVerification.Buttons[0].OnClicked = (yesBtn, userdata) =>
{
@@ -1144,7 +1170,7 @@ namespace Barotrauma
}
};
}
new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), bottomButtonContainer.RectTransform, Anchor.CenterRight),
var publishBtn = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), bottomButtonContainer.RectTransform, Anchor.CenterRight),
TextManager.Get(itemEditor.Id > 0 ? "WorkshopItemUpdate" : "WorkshopItemPublish"), style: "GUIButtonLarge")
{
IgnoreLayoutGroups = true,
@@ -1172,7 +1198,67 @@ namespace Barotrauma
return true;
}
};
publishBtn.TextBlock.AutoScale = true;
}
private void OnPreviewImageSelected(GUIImage previewImageElement, string filePath)
{
string previewImagePath = Path.GetFullPath(Path.Combine(SteamManager.WorkshopItemStagingFolder, SteamManager.PreviewImageName));
if (new FileInfo(filePath).Length > 1024 * 1024)
{
new GUIMessageBox(TextManager.Get("Error"), TextManager.Get("WorkshopItemPreviewImageTooLarge"));
return;
}
if (filePath != previewImagePath)
{
File.Copy(filePath, previewImagePath, overwrite: true);
}
if (itemPreviewSprites.ContainsKey(previewImagePath))
{
itemPreviewSprites[previewImagePath].Remove();
}
var newPreviewImage = new Sprite(previewImagePath, sourceRectangle: null);
previewImageElement.Sprite = newPreviewImage;
itemPreviewSprites[previewImagePath] = newPreviewImage;
itemEditor.PreviewImage = previewImagePath;
}
private void OnAddFilesSelected(string[] fileNames)
{
if (fileNames == null) { return; }
for(int i = 0; i < fileNames.Length; i++)
{
string file = fileNames[i];
if (string.IsNullOrEmpty(file)) { continue; }
file = file.Trim();
if (!File.Exists(file)) { continue; }
string filePathRelativeToStagingFolder = UpdaterUtil.GetRelativePath(file, Path.Combine(Environment.CurrentDirectory, SteamManager.WorkshopItemStagingFolder));
string filePathRelativeToBaseFolder = UpdaterUtil.GetRelativePath(file, Environment.CurrentDirectory);
//file is not inside the staging folder
if (filePathRelativeToStagingFolder.StartsWith(".."))
{
//submarines can be included in the content package directly
string basePath = Path.GetDirectoryName(filePathRelativeToBaseFolder.Replace("..", ""));
if (basePath == "Submarines")
{
string destinationPath = Path.Combine(SteamManager.WorkshopItemStagingFolder, "Submarines", Path.GetFileName(file));
File.Copy(file, destinationPath);
itemContentPackage.AddFile(filePathRelativeToBaseFolder, ContentType.Submarine);
}
else
{
itemContentPackage.AddFile(filePathRelativeToBaseFolder, ContentType.None);
}
}
else
{
itemContentPackage.AddFile(filePathRelativeToStagingFolder, ContentType.None);
}
}
RefreshCreateItemFileList();
}
private void RefreshCreateItemFileList()
@@ -1269,7 +1355,7 @@ namespace Barotrauma
string pleaseWaitText = TextManager.Get("WorkshopPublishPleaseWait");
var msgBox = new GUIMessageBox(
pleaseWaitText,
TextManager.Get("WorkshopPublishInProgress").Replace("[itemname]", TextManager.EnsureUTF8(item.Title)),
TextManager.GetWithVariable("WorkshopPublishInProgress", "[itemname]", TextManager.EnsureUTF8(item.Title)),
new string[] { TextManager.Get("Cancel") });
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
@@ -1291,13 +1377,13 @@ namespace Barotrauma
if (string.IsNullOrEmpty(item.Error))
{
new GUIMessageBox("", TextManager.Get("WorkshopItemPublished").Replace("[itemname]", TextManager.EnsureUTF8(item.Title)));
new GUIMessageBox("", TextManager.GetWithVariable("WorkshopItemPublished", "[itemname]", TextManager.EnsureUTF8(item.Title)));
}
else
{
new GUIMessageBox(
TextManager.Get("Error"),
TextManager.Get("WorkshopItemPublishFailed").Replace("[itemname]", TextManager.EnsureUTF8(item.Title)) + item.Error);
TextManager.GetWithVariable("WorkshopItemPublishFailed", "[itemname]", TextManager.EnsureUTF8(item.Title)) + item.Error);
}
createItemFrame.ClearChildren();

View File

@@ -115,7 +115,7 @@ namespace Barotrauma
{
if (buoyancyVol / selectedVol < 1.0f)
{
retVal += " (" + TextManager.Get("OptimalBallastLevel").Replace("[value]", (buoyancyVol / selectedVol).ToString("0.000")) + ")";
retVal += " (" + TextManager.GetWithVariable("OptimalBallastLevel", "[value]", (buoyancyVol / selectedVol).ToString("0.000")) + ")";
}
else
{
@@ -572,7 +572,7 @@ namespace Barotrauma
ItemAssemblyPrefab assemblyPrefab = userData as ItemAssemblyPrefab;
var msgBox = new GUIMessageBox(
TextManager.Get("DeleteDialogLabel"),
TextManager.Get("DeleteDialogQuestion").Replace("[file]", assemblyPrefab.Name),
TextManager.GetWithVariable("DeleteDialogQuestion", "[file]", assemblyPrefab.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") });
msgBox.Buttons[0].OnClicked += (deleteBtn, userData2) =>
{
@@ -584,7 +584,7 @@ namespace Barotrauma
}
catch (Exception e)
{
DebugConsole.ThrowError(TextManager.Get("DeleteFileError").Replace("[file]", assemblyPrefab.Name), e);
DebugConsole.ThrowError(TextManager.GetWithVariable("DeleteFileError", "[file]", assemblyPrefab.Name), e);
}
return true;
};
@@ -861,7 +861,7 @@ namespace Barotrauma
{
if (nameBox.Text.Contains(illegalChar))
{
GUI.AddMessage(TextManager.Get("SubNameIllegalCharsWarning").Replace("[illegalchar]", illegalChar.ToString()), Color.Red);
GUI.AddMessage(TextManager.GetWithVariable("SubNameIllegalCharsWarning", "[illegalchar]", illegalChar.ToString()), Color.Red);
nameBox.Flash();
return false;
}
@@ -907,7 +907,7 @@ namespace Barotrauma
}
Submarine.MainSub.CheckForErrors();
GUI.AddMessage(TextManager.Get("SubSavedNotification").Replace("[filepath]", Submarine.MainSub.FilePath), Color.Green);
GUI.AddMessage(TextManager.GetWithVariable("SubSavedNotification", "[filepath]", Submarine.MainSub.FilePath), Color.Green);
Submarine.RefreshSavedSub(savePath);
if (prevSavePath != null && prevSavePath != savePath)
@@ -1074,7 +1074,7 @@ namespace Barotrauma
{
OnClicked = (btn, userdata) =>
{
OpenFileDialog ofd = new OpenFileDialog()
Barotrauma.OpenFileDialog ofd = new Barotrauma.OpenFileDialog()
{
InitialDirectory = Path.GetFullPath(Submarine.SavePath),
Filter = "PNG file|*.png",
@@ -1259,7 +1259,7 @@ namespace Barotrauma
{
if (nameBox.Text.Contains(illegalChar))
{
GUI.AddMessage(TextManager.Get("ItemAssemblyNameIllegalCharsWarning").Replace("[illegalchar]", illegalChar.ToString()), Color.Red);
GUI.AddMessage(TextManager.GetWithVariable("ItemAssemblyNameIllegalCharsWarning", "[illegalchar]", illegalChar.ToString()), Color.Red);
nameBox.Flash();
return false;
}
@@ -1476,7 +1476,7 @@ namespace Barotrauma
var msgBox = new GUIMessageBox(
TextManager.Get("DeleteDialogLabel"),
TextManager.Get("DeleteDialogQuestion").Replace("[file]", sub.Name),
TextManager.GetWithVariable("DeleteDialogQuestion", "[file]", sub.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") });
msgBox.Buttons[0].OnClicked += (btn, userData) =>
{
@@ -1489,7 +1489,7 @@ namespace Barotrauma
}
catch (Exception e)
{
DebugConsole.ThrowError(TextManager.Get("DeleteFileError").Replace("[file]", sub.FilePath), e);
DebugConsole.ThrowError(TextManager.GetWithVariable("DeleteFileError", "[file]", sub.FilePath), e);
}
return true;
};

View File

@@ -536,12 +536,12 @@ namespace Barotrauma
if (translatedText == null)
{
propertyBox.TextColor = Color.Gray;
propertyBox.ToolTip = TextManager.Get("StringPropertyCannotTranslate").Replace("[tag]", text ?? "");
propertyBox.ToolTip = TextManager.GetWithVariable("StringPropertyCannotTranslate", "[tag]", text ?? string.Empty);
}
else
{
propertyBox.TextColor = Color.LightGreen;
propertyBox.ToolTip = TextManager.Get("StringPropertyTranslate").Replace("[translation]", translatedText);
propertyBox.ToolTip = TextManager.GetWithVariable("StringPropertyTranslate", "[translation]", translatedText);
}
return true;
};

View File

@@ -0,0 +1,467 @@
/***
MIT License
Copyright (c) 2018 Nathan Glover
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
****************
Further modified for use in Barotrauma.
Original source code at https://github.com/NathanielGlover/OpenAL.NETCore/
***/
using System;
using System.Runtime.InteropServices;
namespace OpenAL
{
public class Al
{
#if OSX
public const string OpenAlDll = "/System/Library/Frameworks/OpenAL.framework/OpenAL";
#elif LINUX
public const string OpenAlDll = "libopenal.so.1";
#elif WINDOWS
#if X86
public const string OpenAlDll = "soft_oal_x86.dll";
#elif X64
public const string OpenAlDll = "soft_oal_x64.dll";
#endif
#endif
#region Enum
public const int None = 0;
public const int False = 0;
public const int True = 1;
public const int SourceRelative = 0x202;
public const int ConeInnerAngle = 0x1001;
public const int ConeOuterAngle = 0x1002;
public const int Pitch = 0x1003;
public const int Position = 0x1004;
public const int Direction = 0x1005;
public const int Velocity = 0x1006;
public const int Looping = 0x1007;
public const int Buffer = 0x1009;
public const int Gain = 0x100A;
public const int MinGain = 0x100D;
public const int MaxGain = 0x100E;
public const int Orientation = 0x100F;
public const int SourceState = 0x1010;
public const int Initial = 0x1011;
public const int Playing = 0x1012;
public const int Paused = 0x1013;
public const int Stopped = 0x1014;
public const int BuffersQueued = 0x1015;
public const int BuffersProcessed = 0x1016;
public const int SecOffset = 0x1024;
public const int SampleOffset = 0x1025;
public const int ByteOffset = 0x1026;
public const int SourceType = 0x1027;
public const int Static = 0x1028;
public const int Streaming = 0x1029;
public const int Undetermined = 0x1030;
public const int FormatMono8 = 0x1100;
public const int FormatMono16 = 0x1101;
public const int FormatStereo8 = 0x1102;
public const int FormatStereo16 = 0x1103;
public const int ReferenceDistance = 0x1020;
public const int RolloffFactor = 0x1021;
public const int ConeOuterGain = 0x1022;
public const int MaxDistance = 0x1023;
public const int Frequency = 0x2001;
public const int Bits = 0x2002;
public const int Channels = 0x2003;
public const int Size = 0x2004;
public const int Unused = 0x2010;
public const int Pending = 0x2011;
public const int Processed = 0x2012;
public const int NoError = False;
public const int InvalidName = 0xA001;
public const int InvalidEnum = 0xA002;
public const int InvalidValue = 0xA003;
public const int InvalidOperation = 0xA004;
public const int OutOfMemory = 0xA005;
public const int Vendor = 0xB001;
public const int Version = 0xB002;
public const int Renderer = 0xB003;
public const int Extensions = 0xB004;
public const int EnumDopplerFactor = 0xC000;
public const int EnumDopplerVelocity = 0xC001;
public const int EnumSpeedOfSound = 0xC003;
public const int EnumDistanceModel = 0xD000;
public const int InverseDistance = 0xD001;
public const int InverseDistanceClamped = 0xD002;
public const int LinearDistance = 0xD003;
public const int LinearDistanceClamped = 0xD004;
public const int ExponentDistance = 0xD005;
public const int ExponentDistanceClamped = 0xD006;
#endregion
#region Functions
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alEnable")]
public static extern void Enable(int capability);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alDisable")]
public static extern void Disable(int capability);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alIsEnabled")]
public static extern bool IsEnabled(int capability);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetString")]
private static extern IntPtr _GetString(int param);
public static string GetString(int param) => Marshal.PtrToStringAnsi(_GetString(param));
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetBooleanv")]
public static extern void GetBooleanv(int param, out bool data);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetIntegerv")]
public static extern void GetIntegerv(int param, out int data);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetFloatv")]
public static extern void GetFloatv(int param, out float data);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetDoublev")]
public static extern void GetDoublev(int param, out double data);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetBoolean")]
public static extern bool GetBoolean(int param);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetInteger")]
public static extern int GetInteger(int param);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetFloat")]
public static extern float GetFloat(int param);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetDouble")]
public static extern double GetDouble(int param);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetError")]
public static extern int GetError();
public static string GetErrorString(int error)
{
switch (error)
{
case NoError:
return "No error";
case InvalidName:
return "Invalid name";
case InvalidEnum:
return "Invalid enum";
case InvalidValue:
return "Invalid value";
case InvalidOperation:
return "Invalid operation";
case OutOfMemory:
return "Out of memory";
default:
return "Unknown error";
}
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alIsExtensionPresent")]
public static extern bool IsExtensionPresent(string extname);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetProcAddress")]
public static extern IntPtr GetProcAddress(string fname);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetEnumValue")]
public static extern int GetEnumValue(string ename);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alListenerf")]
public static extern void Listenerf(int param, float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alListener3f")]
public static extern void Listener3f(int param, float value1, float value2, float value3);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alListenerfv")]
public static extern void Listenerfv(int param, float[] values);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetListenerf")]
public static extern void GetListenerf(int param, out float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetListener3f")]
public static extern void GetListener3f(int param, out float value1, out float value2, out float value3);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetListenerfv")]
private static extern void _GetListenerfv(int param, IntPtr values);
public static void GetListenerfv(int param, out float[] values)
{
int len;
switch(param)
{
case Gain:
len = 1;
break;
case Position:
case Velocity:
len = 3;
break;
case Orientation:
len = 6;
break;
default:
len = 0;
break;
}
values = new float[len];
GCHandle arrayHandle = GCHandle.Alloc(values, GCHandleType.Pinned);
_GetListenerfv(param, arrayHandle.AddrOfPinnedObject());
arrayHandle.Free();
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGenSources")]
private static extern void _GenSources(int n, IntPtr sources);
public static void GenSources(int n, out uint[] sources)
{
sources = new uint[n];
GCHandle arrayHandle = GCHandle.Alloc(sources, GCHandleType.Pinned);
_GenSources(n, arrayHandle.AddrOfPinnedObject());
arrayHandle.Free();
}
public static void GenSource(out uint source)
{
GenSources(1, out var sources);
source = sources[0];
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alDeleteSources")]
public static extern void DeleteSources(int n, uint[] sources);
public static void DeleteSource(uint source) => DeleteSources(1, new[] {source});
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alIsSource")]
public static extern bool IsSource(uint sid);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcef")]
public static extern void Sourcef(uint sid, int param, float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSource3f")]
public static extern void Source3f(uint sid, int param, float value1, float value2, float value3);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcefv")]
public static extern void Sourcefv(uint sid, int param, float[] values);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcei")]
public static extern void Sourcei(uint sid, int param, int value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSource3i")]
public static extern void Source3i(uint sid, int param, int value1, int value2, int value3);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceiv")]
public static extern void Sourceiv(uint sid, int param, int[] values);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetSourcef")]
public static extern void GetSourcef(uint sid, int param, out float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetSource3f")]
public static extern void GetSource3f(uint sid, int param, out float value1, out float value2, out float value3);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetSourcefv")]
private static extern void _GetSourcefv(uint sid, int param, IntPtr values);
public static void GetSourcefv(uint sid, int param, out float[] values)
{
int len;
switch(param)
{
case Pitch:
case Gain:
case MaxDistance:
case RolloffFactor:
case ReferenceDistance:
case MinGain:
case MaxGain:
case ConeOuterGain:
case ConeInnerAngle:
case ConeOuterAngle:
case SecOffset:
case SampleOffset:
case ByteOffset:
len = 1;
break;
case Position:
case Velocity:
case Direction:
len = 3;
break;
default:
len = 0;
break;
}
values = new float[len];
GCHandle arrayHandle = GCHandle.Alloc(values, GCHandleType.Pinned);
_GetSourcefv(sid, param, arrayHandle.AddrOfPinnedObject());
arrayHandle.Free();
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetSourcei")]
public static extern void GetSourcei(uint sid, int param, out int value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetSource3i")]
public static extern void GetSource3i(uint sid, int param, out int value1, out int value2, out int value3);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetSourceiv")]
private static extern void _GetSourceiv(uint sid, int param, IntPtr values);
public static void GetSourceiv(uint sid, int param, out int[] values)
{
int len;
switch(param)
{
case MaxDistance:
case RolloffFactor:
case ReferenceDistance:
case ConeInnerAngle:
case ConeOuterAngle:
case SourceRelative:
case SourceType:
case Looping:
case Buffer:
case SourceState:
case BuffersQueued:
case BuffersProcessed:
case SecOffset:
case SampleOffset:
case ByteOffset:
len = 1;
break;
case Direction:
len = 3;
break;
default:
len = 0;
break;
}
values = new int[len];
GCHandle arrayHandle = GCHandle.Alloc(values, GCHandleType.Pinned);
_GetSourceiv(sid, param, arrayHandle.AddrOfPinnedObject());
arrayHandle.Free();
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcePlayv")]
public static extern void SourcePlayv(int ns, uint[] sids);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceStopv")]
public static extern void SourceStopv(int ns, uint[] sids);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceRewindv")]
public static extern void SourceRewindv(int ns, uint[] sids);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcePausev")]
public static extern void SourcePausev(int ns, uint[] sids);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcePlay")]
public static extern void SourcePlay(uint sid);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceStop")]
public static extern void SourceStop(uint sid);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceRewind")]
public static extern void SourceRewind(uint sid);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourcePause")]
public static extern void SourcePause(uint sid);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceQueueBuffers")]
public static extern void SourceQueueBuffers(uint sid, int numEntries, uint[] bids);
public static void SourceQueueBuffer(uint sid, uint bid)
{
uint[] bids = new uint[1]; bids[0] = bid;
SourceQueueBuffers(sid, 1, bids);
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSourceUnqueueBuffers")]
public static extern void SourceUnqueueBuffers(uint sid, int numEntries, uint[] bids);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGenBuffers")]
private static extern void _GenBuffers(int n, IntPtr buffers);
public static void GenBuffers(int n, out uint[] buffers)
{
buffers = new uint[n];
GCHandle arrayHandle = GCHandle.Alloc(buffers, GCHandleType.Pinned);
_GenBuffers(n, arrayHandle.AddrOfPinnedObject());
arrayHandle.Free();
}
public static void GenBuffer(out uint buffer)
{
GenBuffers(1, out var buffers);
buffer = buffers[0];
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alDeleteBuffers")]
public static extern void DeleteBuffers(int n, uint[] buffers);
public static void DeleteBuffer(uint buffer) => DeleteBuffers(1, new[] {buffer});
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alIsBuffer")]
public static extern bool IsBuffer(uint bid);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alBufferData")]
public static extern void BufferData(uint bid, int format, IntPtr data, int size, int freq);
public static void BufferData<T>(uint bid, int format, T[] data, int len, int freq)
{
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
BufferData(bid, format, handle.AddrOfPinnedObject(), len, freq);
handle.Free();
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alBufferi")]
public static extern void Bufferi(uint bid, int param, int value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alGetBufferi")]
public static extern void GetBufferi(uint bid, int param, out int value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alDopplerFactor")]
public static extern void DopplerFactor(float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alDopplerVelocity")]
public static extern void DopplerVelocity(float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alSpeedOfSound")]
public static extern void SpeedOfSound(float value);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alDistanceModel")]
public static extern void DistanceModel(int distanceModel);
#endregion
}
}

View File

@@ -0,0 +1,220 @@
/***
MIT License
Copyright (c) 2018 Nathan Glover
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
****************
Further modified for use in Barotrauma.
Original source code at https://github.com/NathanielGlover/OpenAL.NETCore/
***/
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Text;
namespace OpenAL
{
public class Alc
{
#if OSX
public const string OpenAlDll = "/System/Library/Frameworks/OpenAL.framework/OpenAL";
#elif LINUX
public const string OpenAlDll = "libopenal.so.1";
#elif WINDOWS
#if X86
public const string OpenAlDll = "soft_oal_x86.dll";
#elif X64
public const string OpenAlDll = "soft_oal_x64.dll";
#endif
#endif
#region Enum
public const int False = 0;
public const int True = 1;
public const int Frequency = 0x1007;
public const int Refresh = 0x1008;
public const int Sync = 0x1009;
public const int MonoSources = 0x1010;
public const int StereoSources = 0x1011;
public const int NoError = False;
public const int InvalidDevice = 0xA001;
public const int InvalidContext = 0xA002;
public const int InvalidEnum = 0xA003;
public const int InvalidValue = 0xA004;
public const int OutOfMemory = 0xA005;
public const int DefaultDeviceSpecifier = 0x1004;
public const int DeviceSpecifier = 0x1005;
public const int Extensions = 0x1006;
public const int MajorVersion = 0x1000;
public const int MinorVersion = 0x1001;
public const int AttributesSize = 0x1002;
public const int AllAttributes = 0x1003;
public const int DefaultAllDevicesSpecifier = 0x1012;
public const int AllDevicesSpecifier = 0x1013;
public const int CaptureDeviceSpecifier = 0x310;
public const int CaptureDefaultDeviceSpecifier = 0x311;
public const int EnumCaptureSamples = 0x312;
#endregion
#region Context Management Functions
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCreateContext")]
private static extern IntPtr _CreateContext(IntPtr device, IntPtr attrlist);
public static IntPtr CreateContext(IntPtr device, int[] attrList)
{
GCHandle handle = GCHandle.Alloc(attrList, GCHandleType.Pinned);
IntPtr retVal = _CreateContext(device, handle.AddrOfPinnedObject());
handle.Free();
return retVal;
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcMakeContextCurrent")]
public static extern bool MakeContextCurrent(IntPtr context);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcProcessContext")]
public static extern void ProcessContext(IntPtr context);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcSuspendContext")]
public static extern void SuspendContext(IntPtr context);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcDestroyContext")]
public static extern void DestroyContext(IntPtr context);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetCurrentContext")]
public static extern IntPtr GetCurrentContext();
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetContextsDevice")]
public static extern IntPtr GetContextsDevice(IntPtr context);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcOpenDevice")]
public static extern IntPtr OpenDevice(string deviceName);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCloseDevice")]
public static extern bool CloseDevice(IntPtr device);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetError")]
public static extern int GetError(IntPtr device);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcIsExtensionPresent")]
public static extern bool IsExtensionPresent(IntPtr device, string extname);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetProcAddress")]
public static extern IntPtr GetProcAddress(IntPtr device, string funcname);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetEnumValue")]
public static extern int GetEnumValue(IntPtr device, string enumname);
#endregion
#region Query Functions
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetString")]
private static extern IntPtr _GetString(IntPtr device, int param);
public static string GetString(IntPtr device, int param)
{
IntPtr strPtr = _GetString(device, param);
int strLen = 0;
while (Marshal.ReadByte(strPtr,strLen)!='\0') { strLen++; }
byte[] bytes = new byte[strLen];
Marshal.Copy(strPtr, bytes, 0, strLen);
return Encoding.UTF8.GetString(bytes);
}
public static IList<string> GetStringList(IntPtr device, int param)
{
List<string> retVal = new List<string>();
IntPtr strPtr = _GetString(device, param);
int strStart = 0;
int strEnd = 0;
byte currChar = Marshal.ReadByte(strPtr, strEnd);
if (currChar == '\0') { return retVal; }
byte prevChar = 255;
while (true) {
strEnd++;
prevChar = currChar;
currChar = Marshal.ReadByte(strPtr, strEnd);
if (currChar == '\0')
{
if (prevChar == '\0')
{
break;
}
byte[] bytes = new byte[strEnd-strStart];
Marshal.Copy(strPtr+strStart, bytes, 0, strEnd - strStart);
retVal.Add(Encoding.UTF8.GetString(bytes));
strStart = strEnd+1;
}
}
return retVal;
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcGetIntegerv")]
public static extern void GetIntegerv(IntPtr device, int param, int size, IntPtr data);
public static void GetInteger(IntPtr device, int param, out int data)
{
int[] dataArr = new int[1];
GCHandle handle = GCHandle.Alloc(dataArr,GCHandleType.Pinned);
GetIntegerv(device, param, 1, handle.AddrOfPinnedObject());
handle.Free();
data = dataArr[0];
}
#endregion
#region Capture Functions
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCaptureOpenDevice")]
private static extern IntPtr CaptureOpenDevice(IntPtr devicename, uint frequency, int format, int buffersize);
public static IntPtr CaptureOpenDevice(string devicename, uint frequency, int format, int buffersize)
{
byte[] devicenameBytes = Encoding.UTF8.GetBytes(devicename);
GCHandle devicenameHandle = GCHandle.Alloc(devicenameBytes, GCHandleType.Pinned);
IntPtr retVal = CaptureOpenDevice(devicenameHandle.AddrOfPinnedObject(), frequency, format, buffersize);
devicenameHandle.Free();
return retVal;
}
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCaptureCloseDevice")]
public static extern bool CaptureCloseDevice(IntPtr device);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCaptureStart")]
public static extern void CaptureStart(IntPtr device);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCaptureStop")]
public static extern void CaptureStop(IntPtr device);
[DllImport(OpenAlDll, CallingConvention = CallingConvention.Cdecl, EntryPoint = "alcCaptureSamples")]
public static extern void CaptureSamples(IntPtr device, IntPtr buffer, int samples);
#endregion
}
}

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Barotrauma
{
public class OpenFileDialog
{
private System.Windows.Forms.OpenFileDialog ofd;
public bool Multiselect;
public string InitialDirectory;
public string Filter;
public string Title;
public string FileName { get; private set; }
public string[] FileNames { get; private set; }
public OpenFileDialog()
{
ofd = new System.Windows.Forms.OpenFileDialog();
}
public System.Windows.Forms.DialogResult ShowDialog()
{
ofd.Multiselect = Multiselect;
ofd.InitialDirectory = InitialDirectory;
ofd.Filter = Filter;
ofd.Title = Title;
#if LINUX
var wrapperForm = new WrapperForm(ofd);
System.Windows.Forms.Application.Run(wrapperForm);
System.Windows.Forms.Application.Exit();
FileName = wrapperForm.FileName;
FileNames = wrapperForm.FileNames;
return wrapperForm.Result;
#else
var result = ofd.ShowDialog();
FileName = ofd.FileName;
FileNames = ofd.FileNames;
return result;
#endif
}
#if LINUX
private class WrapperForm : System.Windows.Forms.Form
{
private System.Windows.Forms.OpenFileDialog ofd;
public System.Windows.Forms.DialogResult Result { get; private set; }
public string FileName { get; private set; }
public string[] FileNames { get; private set; }
public WrapperForm(System.Windows.Forms.OpenFileDialog dialog)
{
ofd = dialog;
Load += WrapperForm_Load;
}
private void WrapperForm_Load(object sender, EventArgs e)
{
Result = ofd.ShowDialog();
FileName = ofd.FileName;
FileNames = ofd.FileNames;
System.Threading.Thread.Sleep(100);
this.Close();
}
}
#endif
}
}

Binary file not shown.

View File

@@ -0,0 +1,11 @@
<configuration>
<dllmap dll="gdiplus" target="libgdiplus.so.0"/>
<dllmap dll="X11" target="libX11.so.6"/>
<dllmap dll="libX11" target="libX11.so.6"/>
<dllmap dll="libXcursor" target="libXcursor.so.1"/>
<dllmap dll="libglib-2.0.so" target="libglib-2.0.so.0"/>
<dllmap dll="libgobject-2.0.so" target="libgobject-2.0.so.0"/>
<dllmap dll="libgdk-x11-2.0.so" target="libgdk-x11-2.0.so.0"/>
<dllmap dll="libgtk-x11-2.0.so" target="libgtk-x11-2.0.so.0"/>
<dllmap dll="libgdk_pixbuf-2.0.so" target="libgdk_pixbuf-2.0.so.0"/>
</configuration>

View File

@@ -80,8 +80,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="GameAnalytics.Mono, Version=1.0.6710.29255, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\GameAnalytics.Mono.dll</HintPath>
<Reference Include="GameAnalytics.Mono, Version=1.0.7018.15293, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\GameAnalytics.Mono.dll</HintPath>
</Reference>
<Reference Include="MonoGame.Framework, Version=3.7.1.189, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.7.1.189\lib\net45\MonoGame.Framework.dll</HintPath>
@@ -132,7 +132,7 @@
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Data.SQLite, Version=1.0.102.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
@@ -306,13 +306,13 @@
<Import Project="ClientCode.projitems" Label="Shared" />
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets'))" />
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets'))" />
<Error Condition="!Exists('..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.7.1.189\build\MonoGame.Framework.WindowsDX.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.7.1.189\build\MonoGame.Framework.WindowsDX.targets'))" />
</Target>
<Import Project="..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.7.1.189\build\MonoGame.Framework.WindowsDX.targets" Condition="Exists('..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.7.1.189\build\MonoGame.Framework.WindowsDX.targets')" />

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="GameAnalytics.Mono.SDK" version="1.1.12" targetFramework="net45" />
<package id="GameAnalytics.Mono.SDK" version="2.1.6" targetFramework="net45" />
<package id="Microsoft.NETCore.Platforms" version="3.0.0-preview.19073.11" targetFramework="net45" />
<package id="MonoGame.Framework.DesktopGL" version="3.7.1.189" targetFramework="net45" />
<package id="MonoGame.Framework.WindowsDX" version="3.7.1.189" targetFramework="net45" />

Binary file not shown.

Binary file not shown.

View File

@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.9.0.2")]
[assembly: AssemblyFileVersion("0.9.0.2")]
[assembly: AssemblyVersion("0.9.0.3")]
[assembly: AssemblyFileVersion("0.9.0.3")]

View File

@@ -149,7 +149,13 @@
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="GameAnalytics.Mono, Version=1.0.7018.15293, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\GameAnalytics.Mono.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data.SQLite, Version=1.0.102.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="Microsoft.CSharp" />
@@ -163,12 +169,6 @@
<Reference Include="NLog">
<HintPath>..\..\Libraries\NuGet\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="GameAnalytics.Mono">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\GameAnalytics.Mono.dll</HintPath>
</Reference>
<Reference Include="System.Data.SQLite">
<HintPath>..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="RestSharp">
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
</Reference>
@@ -293,5 +293,11 @@
<Import Project="..\BarotraumaShared\SharedCode.projitems" Label="Shared" />
<Import Project="..\BarotraumaShared\SharedContent.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.1.1.12\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Import Project="..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets" Condition="Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\Libraries\NuGet\GameAnalytics.Mono.SDK.2.1.6\build\net45\GameAnalytics.Mono.SDK.targets'))" />
</Target>
</Project>

View File

@@ -354,12 +354,10 @@ namespace Barotrauma
tempBuffer.Write(((HumanoidAnimController)AnimController).Crouching);
}
tempBuffer.Write(attack);
if (aiming)
{
Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
tempBuffer.Write((UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI)));
}
Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
tempBuffer.Write((UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI)));
tempBuffer.Write(IsRagdolled || IsUnconscious || Stun > 0.0f || IsDead);
tempBuffer.Write(AnimController.Dir > 0.0f);

View File

@@ -128,9 +128,7 @@ namespace Barotrauma
var exePaths = contentPackage.GetFilesOfType(ContentType.ServerExecutable);
if (exePaths.Count() > 0 && AppDomain.CurrentDomain.FriendlyName != exePaths.First())
{
DebugConsole.ShowQuestionPrompt(TextManager.Get("IncorrectExe")
.Replace("[selectedpackage]", contentPackage.Name)
.Replace("[exename]", exePaths.First()),
DebugConsole.ShowQuestionPrompt(TextManager.GetWithVariables("IncorrectExe", new string[2] { "[selectedpackage]", "[exename]" }, new string[2] { contentPackage.Name, exePaths.First() }),
(option) =>
{
if (option.ToLower() == "y" || option.ToLower() == "yes")
@@ -298,7 +296,7 @@ namespace Barotrauma
CloseServer();
SteamManager.ShutDown();
if (GameSettings.SendUserStatistics) GameAnalytics.OnStop();
if (GameSettings.SendUserStatistics) GameAnalytics.OnQuit();
}
public static void ResetFrameTime()

View File

@@ -16,10 +16,9 @@ namespace Barotrauma
public void Greet(GameServer server, string codeWords, string codeResponse)
{
string greetingMessage = TextManager.Get("TraitorStartMessage").Replace("[targetname]", TargetCharacter.Name);
string moreAgentsMessage = TextManager.Get("TraitorMoreAgentsMessage")
.Replace("[codewords]", codeWords)
.Replace("[coderesponse]", codeResponse);
string greetingMessage = TextManager.GetWithVariable("TraitorStartMessage", "[targetname]", TargetCharacter.Name);
string moreAgentsMessage = TextManager.GetWithVariables("TraitorMoreAgentsMessage",
new string[2] { "[codewords]", "[coderesponse]" }, new string[2] { codeWords, codeResponse });
var greetingChatMsg = ChatMessage.Create(null, greetingMessage, ChatMessageType.Server, null);
var moreAgentsChatMsg = ChatMessage.Create(null, moreAgentsMessage, ChatMessageType.Server, null);
@@ -38,7 +37,7 @@ namespace Barotrauma
{
var ownerMsg = ChatMessage.Create(
null,//TextManager.Get("NewTraitor"),
TextManager.Get("TraitorStartMessageServer").Replace("[targetname]", TargetCharacter.Name).Replace("[traitorname]", Character.Name),
TextManager.GetWithVariables("TraitorStartMessageServer", new string[2] { "[targetname]", "[traitorname]" }, new string[2] { TargetCharacter.Name, Character.Name }),
ChatMessageType.MessageBox,
null
);
@@ -168,9 +167,8 @@ namespace Barotrauma
}
}
endMessage += (TextManager.ReplaceGenderPronouns(TextManager.Get(messageTag), traitorCharacter.Info.Gender) + "\n")
.Replace("[traitorname]", traitorCharacter.Name)
.Replace("[targetname]", targetCharacter.Name);
endMessage += (TextManager.ReplaceGenderPronouns(TextManager.GetWithVariables(messageTag, new string[2] { "[traitorname]", "[targetname]" },
new string[2] { traitorCharacter.Name, targetCharacter.Name }), traitorCharacter.Info.Gender) + "\n");
}
return endMessage;

View File

@@ -62,7 +62,16 @@ namespace Barotrauma
if (newItemIDs[i] == 0 || (newItem != Items[i]))
{
if (Items[i] != null) Items[i].Drop(null);
if (Items[i] != null)
{
Item droppedItem = Items[i];
Entity prevOwner = Owner;
droppedItem.Drop(null);
if (droppedItem.body != null && prevOwner != null)
{
droppedItem.body.SetTransform(prevOwner.SimPosition, 0.0f);
}
}
System.Diagnostics.Debug.Assert(Items[i] == null);
}
}
@@ -79,7 +88,10 @@ namespace Barotrauma
var holdable = item.GetComponent<Holdable>();
if (holdable != null && !holdable.CanBeDeattached()) continue;
if (!item.CanClientAccess(c)) continue;
if (!prevItems.Contains(item) && !item.CanClientAccess(c))
{
continue;
}
}
TryPutItem(item, i, true, true, c.Character, false);
for (int j = 0; j < capacity; j++)

View File

@@ -193,7 +193,7 @@ namespace Barotrauma
{
if (GameMain.Server == null) return;
msg.Write(Prefab.Name);
msg.Write(Prefab.OriginalName);
msg.Write(Prefab.Identifier);
msg.Write(Description != prefab.Description);
if (Description != prefab.Description)

View File

@@ -182,6 +182,10 @@ namespace Barotrauma.Networking
if (SteamManager.USE_STEAM)
{
SteamManager.CreateServer(this, isPublic);
if (isPublic)
{
registeredToMaster = true;
}
}
if (isPublic && !GameMain.Config.UseSteamMatchmaking)
{
@@ -411,7 +415,7 @@ namespace Barotrauma.Networking
{
if (endRoundTimer <= 0.0f)
{
SendChatMessage(TextManager.Get("CrewDeadNoRespawns").Replace("[time]", "60"), ChatMessageType.Server);
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60"), ChatMessageType.Server);
}
endRoundTimer += deltaTime;
}
@@ -724,7 +728,7 @@ namespace Barotrauma.Networking
if (matchingSub == null)
{
SendDirectChatMessage(
TextManager.Get("CampaignStartFailedSubNotFound").Replace("[subname]", subName),
TextManager.GetWithVariable("CampaignStartFailedSubNotFound", "[subname]", subName),
connectedClient, ChatMessageType.MessageBox);
}
else

View File

@@ -232,7 +232,7 @@ namespace Barotrauma.Networking
//add the ID card tags they should've gotten when spawning in the shuttle
foreach (Item item in character.Inventory.Items)
{
if (item == null || item.Prefab.Name != "ID Card") continue;
if (item == null || item.Prefab.Identifier != "idcard") continue;
foreach (string s in shuttleSpawnPoints[i].IdCardTags)
{
item.AddTag(s);

View File

@@ -37,7 +37,7 @@ namespace Barotrauma.Steam
public static bool RefreshServerDetails(Networking.GameServer server)
{
if (instance == null || !instance.isInitialized)
if (instance?.server == null || !instance.isInitialized)
{
return false;
}
@@ -48,6 +48,7 @@ namespace Barotrauma.Steam
instance.server.ServerName = server.Name;
instance.server.MaxPlayers = server.ServerSettings.MaxPlayers;
instance.server.Passworded = server.ServerSettings.HasPassword;
instance.server.MapName = GameMain.NetLobbyScreen?.SelectedSub?.DisplayName ?? "";
Instance.server.SetKey("message", GameMain.Server.ServerSettings.ServerMessageText);
Instance.server.SetKey("version", GameMain.Version.ToString());
Instance.server.SetKey("contentpackage", string.Join(",", GameMain.Config.SelectedContentPackages.Select(cp => cp.Name)));

View File

@@ -35,7 +35,7 @@ namespace Barotrauma
inputThread.Start();
game.Run();
inputThread.Abort(); inputThread.Join();
if (GameSettings.SendUserStatistics) GameAnalytics.OnStop();
if (GameSettings.SendUserStatistics) GameAnalytics.OnQuit();
SteamManager.ShutDown();
#if !DEBUG
}
@@ -105,7 +105,7 @@ namespace Barotrauma
if (GameSettings.SendUserStatistics)
{
GameAnalytics.AddErrorEvent(EGAErrorSeverity.Error, crashReport);
GameAnalytics.OnStop();
GameAnalytics.OnQuit();
Console.Write("A crash report (\"crashreport.log\") was saved in the root folder of the game and sent to the developers.");
}
else

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="GameAnalytics.Mono.SDK" version="1.1.12" targetFramework="net45" />
<package id="GameAnalytics.Mono.SDK" version="2.1.6" targetFramework="net45" />
<package id="NLog" version="4.3.8" targetFramework="net45" />
<package id="RestSharp" version="105.2.3" targetFramework="net45" />
</packages>

View File

@@ -202,22 +202,18 @@ namespace Barotrauma
if (run || speedMultiplier <= 0.0f) targetMovement *= speedMultiplier;
Character.ResetSpeedMultiplier(); // Reset, items will set the value before the next update
Character.AnimController.TargetMovement = targetMovement;
if (!NeedsDivingGear(Character.CurrentHull))
{
bool oxygenLow = Character.OxygenAvailable < CharacterHealth.LowOxygenThreshold;
bool highPressure = Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 0 && Character.PressureProtection <= 0;
bool shouldKeepTheGearOn = !ObjectiveManager.IsCurrentObjective<AIObjectiveIdle>();
// Don't allow to drop the diving suit in water or while climbing or if the current path has stairs
bool removeDivingSuit =
(oxygenLow && !highPressure) ||
(!shouldKeepTheGearOn &&
Character.CurrentHull.WaterPercentage < 1 &&
!Character.IsClimbing &&
steeringManager == insideSteering &&
!PathSteering.InStairs);
bool removeDivingSuit = oxygenLow && !highPressure;
if (!removeDivingSuit)
{
bool targetHasNoSuit = objectiveManager.CurrentOrder is AIObjectiveGoTo gtObj && gtObj.mimic && !HasDivingSuit(gtObj.Target as Character);
bool canDropTheSuit = Character.CurrentHull.WaterPercentage < 1 && !Character.IsClimbing && steeringManager == insideSteering && !PathSteering.InStairs;
removeDivingSuit = (!shouldKeepTheGearOn || targetHasNoSuit) && canDropTheSuit;
}
if (removeDivingSuit)
{
var divingSuit = Character.Inventory.FindItemByIdentifier("divingsuit") ?? Character.Inventory.FindItemByTag("divingsuit");
@@ -227,7 +223,8 @@ namespace Barotrauma
divingSuit.Drop(Character);
}
}
bool takeMaskOff = oxygenLow || (!shouldKeepTheGearOn && Character.CurrentHull.WaterPercentage < 20);
bool targetHasNoMask = objectiveManager.CurrentOrder is AIObjectiveGoTo gotoObjective && gotoObjective.mimic && !HasDivingMask(gotoObjective.Target as Character);
bool takeMaskOff = oxygenLow || (!shouldKeepTheGearOn && Character.CurrentHull.WaterPercentage < 20) || targetHasNoMask;
if (takeMaskOff)
{
var mask = Character.Inventory.FindItemByIdentifier("divingmask");
@@ -321,11 +318,13 @@ namespace Barotrauma
if (c.CurrentHull != hull) { continue; }
if (AIObjectiveRescueAll.IsValidTarget(c, Character))
{
AddTargets<AIObjectiveRescueAll, Character>(c, Character);
if (newOrder == null)
if (AddTargets<AIObjectiveRescueAll, Character>(c, Character))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid");
newOrder = new Order(orderPrefab, c.CurrentHull, null, orderGiver: Character);
if (newOrder == null)
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid");
newOrder = new Order(orderPrefab, c.CurrentHull, null, orderGiver: Character);
}
}
}
}
@@ -334,7 +333,7 @@ namespace Barotrauma
if (AIObjectiveFixLeaks.IsValidTarget(gap, Character))
{
AddTargets<AIObjectiveFixLeaks, Gap>(Character, gap);
if (newOrder == null)
if (newOrder == null && !gap.IsRoomToRoom)
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach");
newOrder = new Order(orderPrefab, hull, null, orderGiver: Character);
@@ -382,8 +381,8 @@ namespace Barotrauma
}
if (Character.PressureTimer > 50.0f && Character.CurrentHull != null)
{
Character.Speak(TextManager.Get("DialogPressure").Replace("[roomname]", Character.CurrentHull.DisplayName), null, 0, "pressure", 30.0f);
{
Character.Speak(TextManager.GetWithVariable("DialogPressure", "[roomname]", Character.CurrentHull.DisplayName, true), null, 0, "pressure", 30.0f);
}
}

View File

@@ -110,8 +110,8 @@ namespace Barotrauma
move = false;
extinguisher.Use(deltaTime, character);
if (!targetHull.FireSources.Contains(fs))
{
character.Speak(TextManager.Get("DialogPutOutFire").Replace("[roomname]", targetHull.Name), null, 0, "putoutfire", 10.0f);
{
character.Speak(TextManager.GetWithVariable("DialogPutOutFire", "[roomname]", targetHull.Name, true), null, 0, "putoutfire", 10.0f);
}
}
}

View File

@@ -122,9 +122,8 @@ namespace Barotrauma
goToObjective = null;
}
TryAddSubObjective(ref goToObjective,
constructor: () => new AIObjectiveGoTo(currentSafeHull, character, objectiveManager, getDivingGearIfNeeded: false)
constructor: () => new AIObjectiveGoTo(currentSafeHull, character, objectiveManager, getDivingGearIfNeeded: true)
{
// If we need diving gear, we should already have it, if possible.
AllowGoingOutside = HumanAIController.HasDivingSuit(character)
},
onAbandon: () => unreachable.Add(goToObjective.Target as Hull));

View File

@@ -21,6 +21,7 @@ namespace Barotrauma
public bool AddTarget(T target)
{
if (character.IsDead) { return false; }
if (ReportedTargets.Contains(target))
{
return false;

View File

@@ -234,6 +234,7 @@ namespace Barotrauma
switch (order.AITag.ToLowerInvariant())
{
case "follow":
if (orderGiver == null) { return null; }
newObjective = new AIObjectiveGoTo(orderGiver, character, this, repeat: true, priorityModifier: priorityModifier)
{
CloseEnough = 150,

View File

@@ -60,7 +60,7 @@ namespace Barotrauma
ItemComponent target = useController ? controller : component;
if (useController && controller == null)
{
character.Speak(TextManager.Get("DialogCantFindController").Replace("[item]", component.Item.Name), null, 2.0f, "cantfindcontroller", 30.0f);
character.Speak(TextManager.GetWithVariable("DialogCantFindController", "[item]", component.Item.Name, true), null, 2.0f, "cantfindcontroller", 30.0f);
abandon = true;
return;
}

View File

@@ -44,8 +44,8 @@ namespace Barotrauma
{
bool isCompleted = Item.IsFullCondition;
if (isCompleted)
{
character?.Speak(TextManager.Get("DialogItemRepaired").Replace("[itemname]", Item.Name), null, 0.0f, "itemrepaired", 10.0f);
{
character?.Speak(TextManager.GetWithVariable("DialogItemRepaired", "[itemname]", Item.Name, true), null, 0.0f, "itemrepaired", 10.0f);
}
return isCompleted;
}
@@ -140,7 +140,7 @@ namespace Barotrauma
{
// If the current condition is less than the previous condition, we can't complete the task, so let's abandon it. The item is probably deteriorating at a greater speed than we can repair it.
abandon = true;
character?.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f);
character?.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f);
}
}
repairable.CurrentFixer = abandon && repairable.CurrentFixer == character ? null : character;
@@ -161,8 +161,8 @@ namespace Barotrauma
objective.CloseEnough = repairTool.Range * 0.75f;
}
return objective;
},
onAbandon: () => character.Speak(TextManager.Get("DialogCannotRepair").Replace("[itemname]", Item.Name), null, 0.0f, "cannotrepair", 10.0f));
},
onAbandon: () => character.Speak(TextManager.GetWithVariable("DialogCannotRepair", "[itemname]", Item.Name, true), null, 0.0f, "cannotrepair", 10.0f));
}
}

View File

@@ -57,11 +57,10 @@ namespace Barotrauma
if (targetCharacter.IsUnconscious && HumanAIController.GetHullSafety(targetCharacter.CurrentHull, targetCharacter) < HumanAIController.HULL_SAFETY_THRESHOLD)
{
if (character.SelectedCharacter != targetCharacter)
{
character.Speak(TextManager.Get("DialogFoundUnconsciousTarget")
.Replace("[targetname]", targetCharacter.Name).Replace("[roomname]", targetCharacter.CurrentHull.DisplayName),
null, 1.0f,
"foundunconscioustarget" + targetCharacter.Name, 60.0f);
{
character.Speak(TextManager.GetWithVariables("DialogFoundUnconsciousTarget", new string[2] { "[targetname]", "[roomname]" },
new string[2] { targetCharacter.Name, targetCharacter.CurrentHull.DisplayName }, new bool[2] { false, true }),
null, 1.0f, "foundunconscioustarget" + targetCharacter.Name, 60.0f);
// Go to the target and select it
if (!character.CanInteractWith(targetCharacter))
@@ -113,11 +112,10 @@ namespace Barotrauma
{
// We can start applying treatment
if (character.SelectedCharacter != targetCharacter)
{
character.Speak(TextManager.Get("DialogFoundWoundedTarget")
.Replace("[targetname]", targetCharacter.Name).Replace("[roomname]", targetCharacter.CurrentHull.DisplayName),
null, 1.0f,
"foundwoundedtarget" + targetCharacter.Name, 60.0f);
{
character.Speak(TextManager.GetWithVariables("DialogFoundWoundedTarget", new string[2] { "[targetname]", "[roomname]" },
new string[2] { targetCharacter.Name, targetCharacter.CurrentHull.DisplayName }, new bool[2] { false, true }),
null, 1.0f, "foundwoundedtarget" + targetCharacter.Name, 60.0f);
character.SelectCharacter(targetCharacter);
}
@@ -191,9 +189,10 @@ namespace Barotrauma
{
itemListStr = string.Join(" or ", string.Join(", ", itemNameList.Take(itemNameList.Count - 1)), itemNameList.Last());
}
character.Speak(TextManager.Get("DialogListRequiredTreatments")
.Replace("[targetname]", targetCharacter.Name)
.Replace("[treatmentlist]", itemListStr),
character.Speak(TextManager.GetWithVariables("DialogListRequiredTreatments", new string[2] { "[targetname]", "[treatmentlist]" },
new string[2] { targetCharacter.Name, itemListStr }, new bool[2] { false, true }),
null, 2.0f, "listrequiredtreatments" + targetCharacter.Name, 60.0f);
}
character.DeselectCharacter();
@@ -235,8 +234,8 @@ namespace Barotrauma
bool isCompleted = targetCharacter.Bleeding <= 0 && targetCharacter.Vitality / targetCharacter.MaxVitality > AIObjectiveRescueAll.GetVitalityThreshold(objectiveManager);
if (isCompleted)
{
character.Speak(TextManager.Get("DialogTargetHealed").Replace("[targetname]", targetCharacter.Name),
{
character.Speak(TextManager.GetWithVariable("DialogTargetHealed", "[targetname]", targetCharacter.Name),
null, 1.0f, "targethealed" + targetCharacter.Name, 60.0f);
}
return isCompleted || targetCharacter.IsDead;

View File

@@ -10,7 +10,17 @@ namespace Barotrauma
private const float vitalityThreshold = 0.8f;
private const float vitalityThresholdForOrders = 0.95f;
public static float GetVitalityThreshold(AIObjectiveManager manager) => manager.CurrentOrder is AIObjectiveRescueAll ? vitalityThresholdForOrders : vitalityThreshold;
public static float GetVitalityThreshold(AIObjectiveManager manager)
{
if (manager == null)
{
return vitalityThreshold;
}
else
{
return manager.CurrentOrder is AIObjectiveRescueAll ? vitalityThresholdForOrders : vitalityThreshold;
}
}
public AIObjectiveRescueAll(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier) { }
@@ -35,8 +45,14 @@ namespace Barotrauma
{
if (target == null || target.IsDead || target.Removed) { return false; }
if (!HumanAIController.IsFriendly(character, target)) { return false; }
if (!(character.AIController is HumanAIController humanAI)) { return false; }
if (target.Bleeding < 1 && target.Vitality / target.MaxVitality > GetVitalityThreshold(humanAI.ObjectiveManager)) { return false; }
if (character.AIController is HumanAIController humanAI)
{
if (target.Bleeding < 1 && target.Vitality / target.MaxVitality > GetVitalityThreshold(humanAI.ObjectiveManager)) { return false; }
}
else
{
if (target.Bleeding < 1 && target.Vitality / target.MaxVitality > vitalityThreshold) { return false; }
}
if (target.Submarine == null) { return false; }
if (target.Submarine.TeamID != character.Submarine.TeamID) { return false; }
if (target.CurrentHull == null) { return false; }

View File

@@ -171,12 +171,12 @@ namespace Barotrauma
string messageTag = (givingOrderToSelf && !TargetAllCharacters ? "OrderDialogSelf." : "OrderDialog.") + AITag;
if (!string.IsNullOrEmpty(orderOption)) messageTag += "." + orderOption;
string msg = TextManager.Get(messageTag, true);
if (targetCharacterName == null) targetCharacterName = "";
if (targetRoomName == null) targetRoomName = "";
string msg = TextManager.GetWithVariables(messageTag, new string[2] { "[name]", "[roomname]" }, new string[2] { targetCharacterName, targetRoomName }, new bool[2] { false, true });
if (msg == null) return "";
if (targetCharacterName == null) targetCharacterName = "";
if (targetRoomName == null) targetRoomName = "";
return msg.Replace("[name]", targetCharacterName).Replace("[roomname]", targetRoomName);
return msg;
}
}

View File

@@ -36,7 +36,8 @@ namespace Barotrauma
[Serialize(1.0f, true), Editable(MIN_SCALE, MAX_SCALE, DecimalCount = 3)]
public float JointScale { get; set; }
[Serialize(1f, true), Editable(DecimalCount = 2)]
// Don't show in the editor, because shouldn't be edited in runtime. Requires that the limb scale and the collider sizes are adjusted. TODO: automatize.
[Serialize(1f, false)]
public float TextureScale { get; set; }
[Serialize(45f, true), Editable(0f, 1000f)]

View File

@@ -17,6 +17,12 @@ namespace Barotrauma
{
public abstract RagdollParams RagdollParams { get; protected set; }
const float ImpactDamageMultiplayer = 10.0f;
/// <summary>
/// Maximum damage per impact (0.1 = 10% of the character's maximum health)
/// </summary>
const float MaxImpactDamage = 0.1f;
private static List<Ragdoll> list = new List<Ragdoll>();
protected Hull currentHull;
@@ -688,8 +694,10 @@ namespace Barotrauma
Vector2 impactPos = ConvertUnits.ToDisplayUnits(points[0]);
if (character.Submarine != null) impactPos += character.Submarine.Position;
float impactDamage = Math.Min((impact - ImpactTolerance) * ImpactDamageMultiplayer, character.MaxVitality * MaxImpactDamage);
character.LastDamageSource = null;
character.AddDamage(impactPos, new List<Affliction>() { AfflictionPrefab.InternalDamage.Instantiate((impact - ImpactTolerance) * 10.0f) }, 0.0f, true);
character.AddDamage(impactPos, new List<Affliction>() { AfflictionPrefab.InternalDamage.Instantiate(impactDamage) }, 0.0f, true);
strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance);
character.ApplyStatusEffects(ActionType.OnImpact, 1.0f);
//briefly disable impact damage

View File

@@ -217,7 +217,16 @@ namespace Barotrauma
limb.body.AngularVelocity = matchingLimb.body.AngularVelocity;
}
}
for (int i = 0; i < character.Inventory.Items.Length; i++)
if (character.Inventory.Items.Length != husk.Inventory.Items.Length)
{
string errorMsg = "Failed to move items from a human's inventory into a humanhusk's inventory (inventory sizes don't match)";
DebugConsole.ThrowError(errorMsg);
GameAnalyticsManager.AddErrorEventOnce("AfflictionHusk.CreateAIHusk:InventoryMismatch", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
yield return CoroutineStatus.Success;
}
for (int i = 0; i < character.Inventory.Items.Length && i < husk.Inventory.Items.Length; i++)
{
if (character.Inventory.Items[i] == null) continue;
husk.Inventory.TryPutItem(character.Inventory.Items[i], i, true, false, null);

View File

@@ -232,13 +232,13 @@ namespace Barotrauma
}
private LimbHealth GetMatchingLimbHealth(Limb limb) => limbHealths[limb.HealthIndex];
private LimbHealth GetMathingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb));
private LimbHealth GetMatchingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb));
/// <summary>
/// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb.
/// </summary>
private IEnumerable<Affliction> GetMatchingAfflictions(LimbHealth limb, Func<Affliction, bool> predicate)
=> limb.Afflictions.Where(predicate).Union(afflictions.Where(a => predicate(a) && GetMathingLimbHealth(a) == limb));
=> limb.Afflictions.Where(predicate).Union(afflictions.Where(a => predicate(a) && GetMatchingLimbHealth(a) == limb));
public Affliction GetAffliction(string afflictionType, bool allowLimbAfflictions = true)
{

View File

@@ -988,18 +988,6 @@ namespace Barotrauma
#endif
NewMessage("Set packet duplication to " + (int)(duplicates * 100) + "%.", Color.White);
}));
commands.Add(new Command("money", "", args =>
{
if (args.Length == 0) { return; }
if (GameMain.GameSession.GameMode is CampaignMode campaign)
{
if (int.TryParse(args[0], out int money))
{
campaign.Money += money;
}
}
}, isCheat: true));
#endif
//"dummy commands" that only exist so that the server can give clients permissions to use them

View File

@@ -36,7 +36,10 @@ namespace Barotrauma
{
get
{
if (Winner == Character.TeamType.None) { return ""; }
if (Winner == Character.TeamType.None || string.IsNullOrEmpty(base.SuccessMessage)) { return ""; }
//disable success message for now if it hasn't been translated
if (!TextManager.ContainsTag("MissionSuccess." + Prefab.Identifier)) { return ""; }
var loser = Winner == Character.TeamType.Team1 ?
Character.TeamType.Team2 :

View File

@@ -16,9 +16,18 @@ namespace Barotrauma
public static void Init()
{
#if DEBUG
GameAnalytics.SetEnabledInfoLog(true);
try
{
GameAnalytics.SetEnabledInfoLog(true);
}
catch (Exception e)
{
DebugConsole.ThrowError("Initializing GameAnalytics failed. Disabling user statistics...", e);
GameSettings.SendUserStatistics = false;
return;
}
#endif
string exePath = Assembly.GetEntryAssembly().Location;
string exeName = null;
Md5Hash exeHash = null;

View File

@@ -108,7 +108,7 @@ namespace Barotrauma
}
#if CLIENT
new GUIMessageBox("", TextManager.Get("CargoSpawnNotification").Replace("[roomname]", cargoRoom.DisplayName));
new GUIMessageBox("", TextManager.GetWithVariable("CargoSpawnNotification", "[roomname]", cargoRoom.DisplayName, true));
#endif
Dictionary<ItemContainer, int> availableContainers = new Dictionary<ItemContainer, int>();

View File

@@ -193,7 +193,7 @@ namespace Barotrauma
character.TeamID = Character.TeamType.FriendlyNPC;
character.SetCustomInteract(
WatchmanInteract,
hudText: TextManager.Get("TalkHint").Replace("[key]", GameMain.Config.KeyBind(InputType.Select).ToString()));
hudText: TextManager.GetWithVariable("TalkHint", "[key]", GameMain.Config.KeyBind(InputType.Select).ToString()));
}
protected abstract void WatchmanInteract(Character watchman, Character interactor);

View File

@@ -206,7 +206,7 @@ namespace Barotrauma
{
voiceChatVolume = MathHelper.Clamp(value, 0.0f, 1.0f);
#if CLIENT
GameMain.SoundManager?.SetCategoryGainMultiplier("voip", voiceChatVolume * 5.0f);
GameMain.SoundManager?.SetCategoryGainMultiplier("voip", voiceChatVolume * 20.0f);
#endif
}
}
@@ -569,14 +569,12 @@ namespace Barotrauma
//to make sure the package that contains text files has been loaded before we attempt to use TextManager
foreach (string missingPackagePath in missingPackagePaths)
{
DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath));
DebugConsole.ThrowError(TextManager.GetWithVariable("ContentPackageNotFound", "[packagepath]", missingPackagePath));
}
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
{
DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
.Replace("[packagename]", incompatiblePackage.Name)
.Replace("[packageversion]", incompatiblePackage.GameVersion.ToString())
.Replace("[gameversion]", GameMain.Version.ToString()));
DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }));
}
foreach (ContentPackage contentPackage in SelectedContentPackages)
{
@@ -955,14 +953,12 @@ namespace Barotrauma
//to make sure the package that contains text files has been loaded before we attempt to use TextManager
foreach (string missingPackagePath in missingPackagePaths)
{
DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath));
DebugConsole.ThrowError(TextManager.GetWithVariable("ContentPackageNotFound", "[packagepath]", missingPackagePath));
}
foreach (ContentPackage incompatiblePackage in incompatiblePackages)
{
DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage")
.Replace("[packagename]", incompatiblePackage.Name)
.Replace("[packageversion]", incompatiblePackage.GameVersion.ToString())
.Replace("[gameversion]", GameMain.Version.ToString()));
DebugConsole.ThrowError(TextManager.GetWithVariables(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage",
new string[3] { "[packagename]", "[packageversion]", "[gameversion]" }, new string[3] { incompatiblePackage.Name, incompatiblePackage.GameVersion.ToString(), GameMain.Version.ToString() }));
}
}

View File

@@ -40,6 +40,9 @@ namespace Barotrauma.Items.Components
[Serialize(false, false)]
public bool RepairThroughWalls { get; set; }
[Serialize(false, false)]
public bool RepairMultiple { get; set; }
public Vector2 TransformedBarrelPos
{
get
@@ -158,12 +161,22 @@ namespace Barotrauma.Items.Components
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
{
var collisionCategories = Physics.CollisionWall | Physics.CollisionCharacter | Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionRepair;
if (RepairThroughWalls)
if (RepairMultiple)
{
var bodies = Submarine.PickBodies(rayStart, rayEnd, ignoredBodies, collisionCategories, ignoreSensors: false, allowInsideFixture: true);
Type lastHitType = null;
foreach (Body body in bodies)
{
FixBody(user, deltaTime, degreeOfSuccess, body);
Type bodyType = body.UserData?.GetType();
if (!RepairThroughWalls && bodyType != null && bodyType != lastHitType)
{
//stop the ray if it already hit a door/wall and is now about to hit some other type of entity
if (lastHitType == typeof(Item) || lastHitType == typeof(Structure)) { break; }
}
if (FixBody(user, deltaTime, degreeOfSuccess, body))
{
if (bodyType != null) { lastHitType = bodyType; }
}
}
}
else
@@ -202,19 +215,19 @@ namespace Barotrauma.Items.Components
}
}
private void FixBody(Character user, float deltaTime, float degreeOfSuccess, Body targetBody)
private bool FixBody(Character user, float deltaTime, float degreeOfSuccess, Body targetBody)
{
if (targetBody?.UserData == null) { return; }
if (targetBody?.UserData == null) { return false; }
pickedPosition = Submarine.LastPickedPosition;
if (targetBody.UserData is Structure targetStructure)
{
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) return;
if (targetStructure.IsPlatform) return;
if (!fixableEntities.Contains("structure") && !fixableEntities.Contains(targetStructure.Prefab.Identifier)) { return false; }
if (targetStructure.IsPlatform) { return false; }
int sectionIndex = targetStructure.FindSectionIndex(ConvertUnits.ToDisplayUnits(pickedPosition));
if (sectionIndex < 0) return;
if (sectionIndex < 0) { return false; }
FixStructureProjSpecific(user, deltaTime, targetStructure, sectionIndex);
targetStructure.AddDamage(sectionIndex, -StructureFixAmount * degreeOfSuccess, user);
@@ -232,18 +245,21 @@ namespace Barotrauma.Items.Components
targetStructure.AddDamage(sectionIndex + i, -StructureFixAmount * degreeOfSuccess);
}
}
return true;
}
else if (targetBody.UserData is Character targetCharacter)
{
targetCharacter.LastDamageSource = item;
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new List<ISerializableEntity>() { targetCharacter });
FixCharacterProjSpecific(user, deltaTime, targetCharacter);
return true;
}
else if (targetBody.UserData is Limb targetLimb)
{
targetLimb.character.LastDamageSource = item;
ApplyStatusEffectsOnTarget(user, deltaTime, ActionType.OnUse, new List<ISerializableEntity>() { targetLimb.character, targetLimb });
FixCharacterProjSpecific(user, deltaTime, targetLimb.character);
return true;
}
else if (targetBody.UserData is Item targetItem)
{
@@ -268,7 +284,9 @@ namespace Barotrauma.Items.Components
#endif
}
FixItemProjSpecific(user, deltaTime, targetItem, prevCondition);
return true;
}
return false;
}
partial void FixStructureProjSpecific(Character user, float deltaTime, Structure targetStructure, int sectionIndex);
@@ -378,11 +396,12 @@ namespace Barotrauma.Items.Components
sinTime = 0;
if (!leak.FlowTargetHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.Open > 0.0f))
{
character.Speak(TextManager.Get("DialogLeaksFixed").Replace("[roomname]", leak.FlowTargetHull.DisplayName), null, 0.0f, "leaksfixed", 10.0f);
character.Speak(TextManager.GetWithVariable("DialogLeaksFixed", "[roomname]", leak.FlowTargetHull.DisplayName, true), null, 0.0f, "leaksfixed", 10.0f);
}
else
{
character.Speak(TextManager.Get("DialogLeakFixed").Replace("[roomname]", leak.FlowTargetHull.DisplayName), null, 0.0f, "leakfixed", 10.0f);
character.Speak(TextManager.GetWithVariable("DialogLeakFixed", "[roomname]", leak.FlowTargetHull.DisplayName, true), null, 0.0f, "leakfixed", 10.0f);
}
}

View File

@@ -219,8 +219,10 @@ namespace Barotrauma.Items.Components
{
dialogTag = "DialogSonarTargetLarge";
}
character.Speak(TextManager.Get(dialogTag).Replace("[direction]", targetGroup.Key).Replace("[count]", targetGroup.Value.Count.ToString()),
null, 0, "sonartarget" + targetGroup.Value[0].ID, 30);
character.Speak(TextManager.GetWithVariables(dialogTag, new string[2] { "[direction]", "[count]" },
new string[2] { targetGroup.Key.ToString(), targetGroup.Value.Count.ToString() },
new bool[2] { true, false }), null, 0, "sonartarget" + targetGroup.Value[0].ID, 30);
//prevent the character from reporting other targets in the group
for (int i = 1; i < targetGroup.Value.Count; i++)
@@ -239,7 +241,7 @@ namespace Barotrauma.Items.Components
int clockDir = (int)Math.Round((angle / MathHelper.TwoPi) * 12);
if (clockDir == 0) clockDir = 12;
return TextManager.Get("roomname.subdiroclock").Replace("[dir]", clockDir.ToString());
return TextManager.GetWithVariable("roomname.subdiroclock", "[dir]", clockDir.ToString());
}
private Vector2 GetTransducerPos()

View File

@@ -244,9 +244,10 @@ namespace Barotrauma.Items.Components
#if CLIENT
rechargeSpeedSlider.BarScroll = RechargeSpeed / Math.Max(maxRechargeSpeed, 1.0f);
#endif
character.Speak(TextManager.Get("DialogChargeBatteries")
.Replace("[itemname]", item.Name)
.Replace("[rate]", ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString()), null, 1.0f, "chargebattery", 10.0f);
character.Speak(TextManager.GetWithVariables("DialogChargeBatteries", new string[2] { "[itemname]", "[rate]" },
new string[2] { item.Name, ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString() },
new bool[2] { true, false }), null, 1.0f, "chargebattery", 10.0f);
}
}
else
@@ -260,9 +261,9 @@ namespace Barotrauma.Items.Components
#if CLIENT
rechargeSpeedSlider.BarScroll = RechargeSpeed / Math.Max(maxRechargeSpeed, 1.0f);
#endif
character.Speak(TextManager.Get("DialogStopChargingBatteries")
.Replace("[itemname]", item.Name)
.Replace("[rate]", ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString()), null, 1.0f, "chargebattery", 10.0f);
character.Speak(TextManager.GetWithVariables("DialogStopChargingBatteries", new string[2] { "[itemname]", "[rate]" },
new string[2] { item.Name, ((int)(rechargeSpeed / maxRechargeSpeed * 100.0f)).ToString() },
new bool[2] { true, false }), null, 1.0f, "chargebattery", 10.0f);
}
}

View File

@@ -276,12 +276,34 @@ namespace Barotrauma.Items.Components
private List<HitscanResult> DoRayCast(Vector2 rayStart, Vector2 rayEnd)
{
List<HitscanResult> hits = new List<HitscanResult>();
Vector2 dir = rayEnd - rayStart;
dir = dir.LengthSquared() < 0.00001f ? Vector2.UnitY : Vector2.Normalize(dir);
//do an AABB query first to see if the start of the ray is inside a fixture
var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.One * 0.001f, rayStart + Vector2.One * 0.001f);
GameMain.World.QueryAABB((fixture) =>
{
//ignore sensors and items
if (fixture?.Body == null || fixture.IsSensor) return true;
if (fixture.UserData is Item) return true;
//ignore everything else than characters, sub walls and level walls
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) &&
!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) return true;
hits.Add(new HitscanResult(fixture, rayStart, -dir, 0.0f));
return true;
}, ref aabb);
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
if (fixture == null || fixture.IsSensor) return -1;
//ignore sensors and items
if (fixture?.Body == null || fixture.IsSensor) return -1;
if (fixture.UserData is Item) return -1;
//ignore everything else than characters, sub walls and level walls
if (!fixture.CollisionCategories.HasFlag(Physics.CollisionCharacter) &&
!fixture.CollisionCategories.HasFlag(Physics.CollisionWall) &&
!fixture.CollisionCategories.HasFlag(Physics.CollisionLevel)) return -1;

View File

@@ -459,7 +459,7 @@ namespace Barotrauma.Items.Components
}
var containShellObjective = new AIObjectiveContainItem(character, container.ContainableItems[0].Identifiers[0], container, objective.objectiveManager);
character?.Speak(TextManager.Get("DialogLoadTurret").Replace("[itemname]", item.Name), null, 0.0f, "loadturret", 30.0f);
character?.Speak(TextManager.GetWithVariable("DialogLoadTurret", "[itemname]", item.Name, true), null, 0.0f, "loadturret", 30.0f);
containShellObjective.targetItemCount = usableProjectileCount + 1;
containShellObjective.ignoredContainerIdentifiers = new string[] { containerItem.prefab.Identifier };
objective.AddSubObjective(containShellObjective);
@@ -489,28 +489,24 @@ namespace Barotrauma.Items.Components
closestDist = dist;
}
if (closestEnemy == null) return false;
if (closestEnemy == null) { return false; }
character.AIController.SelectTarget(closestEnemy.AiTarget);
character.CursorPosition = closestEnemy.WorldPosition;
if (item.Submarine != null) character.CursorPosition -= item.Submarine.Position;
//force aim input even if the turret doesn't require it,
//because the cursor position (and consequently, turret aim direction) is only synced to clients when aiming
character.SetInput(InputType.Aim, false, true);
if (item.Submarine != null) { character.CursorPosition -= item.Submarine.Position; }
float enemyAngle = MathUtils.VectorToAngle(closestEnemy.WorldPosition - item.WorldPosition);
float turretAngle = -rotation;
if (Math.Abs(MathUtils.GetShortestAngle(enemyAngle, turretAngle)) > 0.15f) return false;
if (Math.Abs(MathUtils.GetShortestAngle(enemyAngle, turretAngle)) > 0.15f) { return false; }
var pickedBody = Submarine.PickBody(ConvertUnits.ToSimUnits(item.WorldPosition), closestEnemy.SimPosition, null);
if (pickedBody != null && !(pickedBody.UserData is Limb)) return false;
if (pickedBody != null && !(pickedBody.UserData is Limb)) { return false; }
if (objective.Option.ToLowerInvariant() == "fireatwill")
{
character?.Speak(TextManager.Get("DialogFireTurret").Replace("[itemname]", item.Name), null, 0.0f, "fireturret", 5.0f);
character?.Speak(TextManager.GetWithVariable("DialogFireTurret", "[itemname]", item.Name, true), null, 0.0f, "fireturret", 5.0f);
character.SetInput(InputType.Shoot, true, true);
}

View File

@@ -1539,9 +1539,8 @@ namespace Barotrauma
{
if (requiredSkill != null)
{
GUI.AddMessage(TextManager.Get("InsufficientSkills")
.Replace("[requiredskill]", TextManager.Get("SkillName." + requiredSkill.Identifier))
.Replace("[requiredlevel]", ((int)requiredSkill.Level).ToString()), Color.Red);
GUI.AddMessage(TextManager.GetWithVariables("InsufficientSkills", new string[2] { "[requiredskill]", "[requiredlevel]" },
new string[2] { TextManager.Get("SkillName." + requiredSkill.Identifier), ((int)requiredSkill.Level).ToString() }, new bool[2] { true, false }), Color.Red);
}
}
#endif
@@ -2033,8 +2032,8 @@ namespace Barotrauma
XElement element = new XElement("Item");
element.Add(
new XAttribute("name", prefab.Name),
new XAttribute("identifier", prefab.Identifier),
new XAttribute("name", Prefab.OriginalName),
new XAttribute("identifier", Prefab.Identifier),
new XAttribute("ID", ID));
if (FlippedX) element.Add(new XAttribute("flippedx", true));

View File

@@ -145,6 +145,11 @@ namespace Barotrauma
private List<XElement> fabricationRecipeElements = new List<XElement>();
/// <summary>
/// Original, non-translated name as defined in the xml
/// </summary>
public readonly string OriginalName;
public string ConfigFile
{
get { return configFile; }
@@ -440,7 +445,7 @@ namespace Barotrauma
configFile = filePath;
ConfigElement = element;
string nonTranslatedName = element.GetAttributeString("name", "");
OriginalName = element.GetAttributeString("name", "");
identifier = element.GetAttributeString("identifier", "");
//nameidentifier can be used to make multiple items use the same names and descriptions
@@ -448,11 +453,11 @@ namespace Barotrauma
if (string.IsNullOrEmpty(nameIdentifier))
{
name = TextManager.Get("EntityName." + identifier, true) ?? nonTranslatedName;
name = TextManager.Get("EntityName." + identifier, true) ?? OriginalName;
}
else
{
name = TextManager.Get("EntityName." + nameIdentifier, true) ?? nonTranslatedName;
name = TextManager.Get("EntityName." + nameIdentifier, true) ?? OriginalName;
}
if (name == "") { DebugConsole.ThrowError("Unnamed item in " + filePath + "!"); }
@@ -462,7 +467,7 @@ namespace Barotrauma
Aliases = new HashSet<string>
(element.GetAttributeStringArray("aliases", null, convertToLowerInvariant: true) ??
element.GetAttributeStringArray("Aliases", new string[0], convertToLowerInvariant: true));
Aliases.Add(nonTranslatedName.ToLowerInvariant());
Aliases.Add(OriginalName.ToLowerInvariant());
if (!Enum.TryParse(element.GetAttributeString("category", "Misc"), true, out MapEntityCategory category))
{

View File

@@ -366,14 +366,18 @@ namespace Barotrauma
public override MapEntity Clone()
{
var clone = new Structure(rect, Prefab, Submarine);
var clone = new Structure(rect, Prefab, Submarine)
{
defaultRect = defaultRect
};
foreach (KeyValuePair<string, SerializableProperty> property in SerializableProperties)
{
if (!property.Value.Attributes.OfType<Editable>().Any()) continue;
if (!property.Value.Attributes.OfType<Editable>().Any()) { continue; }
clone.SerializableProperties[property.Key].TrySetValue(clone, property.Value.GetValue(this));
}
if (FlippedX) clone.FlipX(false);
if (FlippedY) clone.FlipY(false);
return clone;
}

View File

@@ -730,7 +730,15 @@ namespace Barotrauma
return closestBody;
}
public static List<Body> PickBodies(Vector2 rayStart, Vector2 rayEnd, IEnumerable<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null, bool allowInsideFixture = false)
private static readonly Dictionary<Body, float> bodyDist = new Dictionary<Body, float>();
private static readonly List<Body> bodies = new List<Body>();
/// <summary>
/// Returns a list of physics bodies the ray intersects with, sorted according to distance (the closest body is at the beginning of the list).
/// </summary>
/// <param name="customPredicate">Can be used to filter the bodies based on some condition. If the predicate returns false, the body isignored.</param>
/// <param name="allowInsideFixture">Should fixtures that the start of the ray is inside be returned</param>
public static IEnumerable<Body> PickBodies(Vector2 rayStart, Vector2 rayEnd, IEnumerable<Body> ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate<Fixture> customPredicate = null, bool allowInsideFixture = false)
{
if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f)
{
@@ -738,20 +746,25 @@ namespace Barotrauma
}
float closestFraction = 1.0f;
List<Body> bodies = new List<Body>();
bodies.Clear();
bodyDist.Clear();
GameMain.World.RayCast((fixture, point, normal, fraction) =>
{
if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return -1; }
if (fixture.Body != null) { bodies.Add(fixture.Body); }
if (fixture.Body != null)
{
bodies.Add(fixture.Body);
bodyDist[fixture.Body] = fraction;
}
if (fraction < closestFraction)
{
lastPickedPosition = rayStart + (rayEnd - rayStart) * fraction;
lastPickedFraction = fraction;
lastPickedNormal = normal;
}
return fraction;
//continue
return -1;
}, rayStart, rayEnd);
if (allowInsideFixture)
@@ -770,10 +783,12 @@ namespace Barotrauma
lastPickedFraction = 0.0f;
lastPickedNormal = Vector2.Normalize(rayEnd - rayStart);
bodies.Add(fixture.Body);
bodyDist[fixture.Body] = 0.0f;
return false;
}, ref aabb);
}
bodies.Sort((b1, b2) => { return bodyDist[b1].CompareTo(bodyDist[b2]); });
return bodies;
}

View File

@@ -91,7 +91,7 @@ namespace Barotrauma
public WayPoint(MapEntityPrefab prefab, Rectangle rectangle)
: this (rectangle, Submarine.MainSub)
{
if (prefab.Name.Contains("Spawn"))
if (prefab.Identifier.Contains("spawn"))
{
spawnType = SpawnType.Human;
}

View File

@@ -656,7 +656,7 @@ namespace Barotrauma.Networking
private set;
} = new List<Pair<int, int>>();
public void ReadMonsterEnabled(NetBuffer inc)
private void InitMonstersEnabled()
{
//monster spawn settings
if (MonsterEnabled == null)
@@ -673,7 +673,11 @@ namespace Barotrauma.Networking
if (!MonsterEnabled.ContainsKey(s)) MonsterEnabled.Add(s, true);
}
}
}
public void ReadMonsterEnabled(NetBuffer inc)
{
InitMonstersEnabled();
List<string> monsterNames = MonsterEnabled.Keys.ToList();
foreach (string s in monsterNames)
{
@@ -681,7 +685,7 @@ namespace Barotrauma.Networking
}
inc.ReadPadBits();
}
public void WriteMonsterEnabled(NetBuffer msg, Dictionary<string, bool> monsterEnabled = null)
{
//monster spawn settings
@@ -703,13 +707,17 @@ namespace Barotrauma.Networking
Dictionary<ItemPrefab, int> extraCargo = new Dictionary<ItemPrefab, int>();
for (int i = 0; i < count; i++)
{
string prefabIdentifier = msg.ReadString();
string prefabName = msg.ReadString();
byte amount = msg.ReadByte();
ItemPrefab ip = MapEntityPrefab.List.Find(p => p is ItemPrefab && p.Name.Equals(prefabName, StringComparison.InvariantCulture)) as ItemPrefab;
if (ip != null && amount > 0)
var itemPrefab = string.IsNullOrEmpty(prefabIdentifier) ?
MapEntityPrefab.Find(prefabName, null, showErrorMessages: false) as ItemPrefab :
MapEntityPrefab.Find(prefabName, prefabIdentifier, showErrorMessages: false) as ItemPrefab;
if (itemPrefab != null && amount > 0)
{
if (changed || !ExtraCargo.ContainsKey(ip) || ExtraCargo[ip] != amount) changed = true;
extraCargo.Add(ip, amount);
if (changed || !ExtraCargo.ContainsKey(itemPrefab) || ExtraCargo[itemPrefab] != amount) changed = true;
extraCargo.Add(itemPrefab, amount);
}
}
if (changed) ExtraCargo = extraCargo;
@@ -727,7 +735,9 @@ namespace Barotrauma.Networking
msg.Write((UInt32)ExtraCargo.Count);
foreach (KeyValuePair<ItemPrefab, int> kvp in ExtraCargo)
{
msg.Write(kvp.Key.Name); msg.Write((byte)kvp.Value);
msg.Write(kvp.Key.Identifier ?? "");
msg.Write(kvp.Key.OriginalName ?? "");
msg.Write((byte)kvp.Value);
}
}
}

View File

@@ -176,6 +176,107 @@ namespace Barotrauma
}
}
public static string GetWithVariables(string textTag, string[] variableTags, string[] variableValues, bool[] formatCapitals = null, bool returnNull = false, string fallBackTag = null)
{
string text = Get(textTag, returnNull, fallBackTag);
if (text == null || text.Length == 0 || variableTags.Length != variableValues.Length)
{
#if DEBUG
if (variableTags.Length != variableValues.Length)
{
DebugConsole.ThrowError("variableTags.Length and variableValues.Length do not match for \"" + textTag + "\".");
}
if (formatCapitals != null && formatCapitals.Length != variableTags.Length)
{
DebugConsole.ThrowError("variableTags.Length and formatCapitals.Length do not match for \"" + textTag + "\".");
}
#endif
if (returnNull)
{
return null;
}
else
{
return textTag;
}
}
if (formatCapitals != null && !GameMain.Config.Language.Contains("Chinese"))
{
for (int i = 0; i < variableTags.Length; i++)
{
if (formatCapitals[i])
{
variableValues[i] = HandleVariableCapitalization(text, variableTags[i], variableValues[i]);
}
}
}
for (int i = 0; i < variableTags.Length; i++)
{
text = text.Replace(variableTags[i], variableValues[i]);
}
return text;
}
public static string GetWithVariable(string textTag, string variableTag, string variableValue, bool formatCapitals = false, bool returnNull = false, string fallBackTag = null)
{
string text = Get(textTag, returnNull, fallBackTag);
if (text == null || text.Length == 0)
{
if (returnNull)
{
return null;
}
else
{
return textTag;
}
}
if (formatCapitals && !GameMain.Config.Language.Contains("Chinese"))
{
variableValue = HandleVariableCapitalization(text, variableTag, variableValue);
}
return text.Replace(variableTag, variableValue);
}
private static string HandleVariableCapitalization(string text, string variableTag, string variableValue)
{
int index = text.IndexOf(variableTag) - 1;
if (index == -1)
{
return variableValue;
}
for (int i = index; i >= 0; i--)
{
if (text[i] == ' ')
{
continue;
}
else
{
if (text[i] != '.')
{
variableValue = variableValue.ToLower();
}
else
{
variableValue = Capitalize(variableValue);
break;
}
}
}
return variableValue;
}
public static string ParseInputTypes(string text)
{
foreach (InputType inputType in Enum.GetValues(typeof(InputType)))

Some files were not shown because too many files have changed in this diff Show More