2f107db...5202af9

This commit is contained in:
Joonas Rikkonen
2019-03-18 21:42:26 +02:00
parent 58c92888b7
commit 044fd3344b
395 changed files with 27417 additions and 19754 deletions

View File

@@ -1,412 +1,507 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">ReleaseLinux</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{008C0F83-E914-4966-9135-EA885059EDD8}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Barotrauma</RootNamespace>
<AssemblyName>Barotrauma</AssemblyName>
<FileAlignment>512</FileAlignment>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<ReleaseVersion>0.7.0.1</ReleaseVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>0.1.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseLinux|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\ReleaseLinux\</OutputPath>
<DefineConstants>TRACE;LINUX;CLIENT</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugLinux|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\DebugLinux\</OutputPath>
<DefineConstants>TRACE;LINUX;CLIENT;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseMac|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\ReleaseMac\</OutputPath>
<DefineConstants>TRACE;OSX;CLIENT</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugMac|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\DebugMac\</OutputPath>
<DefineConstants>TRACE;OSX;CLIENT;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\ReleaseWindows\</OutputPath>
<DefineConstants>TRACE;WINDOWS;CLIENT</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\DebugWindows\</OutputPath>
<DefineConstants>TRACE;WINDOWS;CLIENT;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Source\Camera.cs" />
<Compile Include="Source\Characters\AICharacter.cs" />
<Compile Include="Source\Characters\AI\AIController.cs" />
<Compile Include="Source\Characters\AI\AITarget.cs" />
<Compile Include="Source\Characters\AI\EnemyAIController.cs" />
<Compile Include="Source\Characters\AI\HumanAIController.cs" />
<Compile Include="Source\Characters\Animation\Ragdoll.cs" />
<Compile Include="Source\Characters\Attack.cs" />
<Compile Include="Source\Characters\Health\AfflictionPsychosis.cs" />
<Compile Include="Source\Events\EventManager.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\ContextualTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\ScenarioTutorial.cs" />
<Compile Include="Source\GUI\ChatBox.cs" />
<Compile Include="Source\GUI\ParamsEditor.cs" />
<Compile Include="Source\GUI\ShapeExtensions.cs" />
<Compile Include="Source\GUI\Graph.cs" />
<Compile Include="Source\Characters\CharacterHealth.cs" />
<Compile Include="Source\GameSession\GameModes\MultiPlayerCampaign.cs" />
<Compile Include="Source\GUI\GUICanvas.cs" />
<Compile Include="Source\GUI\GUICustomComponent.cs" />
<Compile Include="Source\GUI\GUILayoutGroup.cs" />
<Compile Include="Source\GUI\HUDLayoutSettings.cs" />
<Compile Include="Source\GUI\RectTransform.cs" />
<Compile Include="Source\GUI\SpriteSheetPlayer.cs" />
<Compile Include="Source\GUI\UISprite.cs" />
<Compile Include="Source\GUI\Widget.cs" />
<Compile Include="Source\Items\Components\ElectricalDischarger.cs" />
<Compile Include="Source\Items\Components\LevelResource.cs" />
<Compile Include="Source\Items\Components\Machines\Controller.cs" />
<Compile Include="Source\Items\Components\Repairable.cs" />
<Compile Include="Source\Items\Components\RepairTool.cs" />
<Compile Include="Source\Items\Components\Signal\CustomInterface.cs" />
<Compile Include="Source\Items\Components\Signal\MotionSensor.cs" />
<Compile Include="Source\Items\Components\Signal\WifiComponent.cs" />
<Compile Include="Source\Items\ItemInventory.cs" />
<Compile Include="Source\Map\ItemAssemblyPrefab.cs" />
<Compile Include="Source\Map\Levels\BackgroundCreatures\BackgroundCreature.cs" />
<Compile Include="Source\Map\Levels\BackgroundCreatures\BackgroundCreatureManager.cs" />
<Compile Include="Source\Map\Levels\BackgroundCreatures\BackgroundCreaturePrefab.cs" />
<Compile Include="Source\Characters\Character.cs" />
<Compile Include="Source\Characters\CharacterHUD.cs" />
<Compile Include="Source\Characters\CharacterInfo.cs" />
<Compile Include="Source\Characters\CharacterNetworking.cs" />
<Compile Include="Source\Characters\CharacterSound.cs" />
<Compile Include="Source\Characters\HUDProgressBar.cs" />
<Compile Include="Source\Characters\Jobs\JobPrefab.cs" />
<Compile Include="Source\Characters\Limb.cs" />
<Compile Include="Source\DebugConsole.cs" />
<Compile Include="Source\EventInput\EventInput.cs" />
<Compile Include="Source\EventInput\KeyboardDispatcher.cs" />
<Compile Include="Source\Events\Missions\Mission.cs" />
<Compile Include="Source\Events\Missions\MissionMode.cs" />
<Compile Include="Source\Fonts\ScalableFont.cs" />
<Compile Include="Source\GameMain.cs" />
<Compile Include="Source\GameSession\CrewManager.cs" />
<Compile Include="Source\GameSession\GameMode.cs" />
<Compile Include="Source\GameSession\GameModes\SinglePlayerCampaign.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\EditorTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\TutorialMode.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\Tutorial.cs" />
<Compile Include="Source\GameSession\GameSession.cs" />
<Compile Include="Source\GameSession\HireManager.cs" />
<Compile Include="Source\GameSession\RoundSummary.cs" />
<Compile Include="Source\GameSettings.cs" />
<Compile Include="Source\GUI\ComponentStyle.cs" />
<Compile Include="Source\GUI\GUI.cs" />
<Compile Include="Source\GUI\GUIButton.cs" />
<Compile Include="Source\GUI\GUIComponent.cs" />
<Compile Include="Source\GUI\GUIDropDown.cs" />
<Compile Include="Source\GUI\GUIFrame.cs" />
<Compile Include="Source\GUI\GUIImage.cs" />
<Compile Include="Source\GUI\GUIListBox.cs" />
<Compile Include="Source\GUI\GUIMessage.cs" />
<Compile Include="Source\GUI\GUIMessageBox.cs" />
<Compile Include="Source\GUI\GUINumberInput.cs" />
<Compile Include="Source\GUI\GUIProgressBar.cs" />
<Compile Include="Source\GUI\GUIScrollBar.cs" />
<Compile Include="Source\GUI\GUIStyle.cs" />
<Compile Include="Source\GUI\GUITextBlock.cs" />
<Compile Include="Source\GUI\GUITextBox.cs" />
<Compile Include="Source\GUI\GUITickBox.cs" />
<Compile Include="Source\GUI\LoadingScreen.cs" />
<Compile Include="Source\Items\CharacterInventory.cs" />
<Compile Include="Source\Items\Components\Door.cs" />
<Compile Include="Source\Items\Components\ItemComponent.cs" />
<Compile Include="Source\Items\Components\ItemContainer.cs" />
<Compile Include="Source\Items\Components\ItemLabel.cs" />
<Compile Include="Source\Items\Components\LightComponent.cs" />
<Compile Include="Source\Items\Components\Machines\Deconstructor.cs" />
<Compile Include="Source\Items\Components\Machines\Engine.cs" />
<Compile Include="Source\Items\Components\Machines\Fabricator.cs" />
<Compile Include="Source\Items\Components\Machines\MiniMap.cs" />
<Compile Include="Source\Items\Components\Machines\Pump.cs" />
<Compile Include="Source\Items\Components\Machines\Sonar.cs" />
<Compile Include="Source\Items\Components\Machines\Reactor.cs" />
<Compile Include="Source\Items\Components\Machines\Steering.cs" />
<Compile Include="Source\Items\Components\Power\PowerContainer.cs" />
<Compile Include="Source\Items\Components\Power\Powered.cs" />
<Compile Include="Source\Items\Components\Power\PowerTransfer.cs" />
<Compile Include="Source\Items\Components\Signal\Connection.cs" />
<Compile Include="Source\Items\Components\Signal\ConnectionPanel.cs" />
<Compile Include="Source\Items\Components\Signal\Wire.cs" />
<Compile Include="Source\Items\Components\StatusHUD.cs" />
<Compile Include="Source\Items\Components\Turret.cs" />
<Compile Include="Source\Items\DockingPort.cs" />
<Compile Include="Source\Items\Inventory.cs" />
<Compile Include="Source\Items\Item.cs" />
<Compile Include="Source\Items\ItemPrefab.cs" />
<Compile Include="Source\Items\Rope.cs" />
<Compile Include="Source\Map\Explosion.cs" />
<Compile Include="Source\Map\FireSource.cs" />
<Compile Include="Source\Map\Gap.cs" />
<Compile Include="Source\Map\Hull.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelObject.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelObjectManager.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelObjectPrefab.cs" />
<Compile Include="Source\Map\Levels\CaveGenerator.cs" />
<Compile Include="Source\Map\Levels\Level.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelTrigger.cs" />
<Compile Include="Source\Map\Levels\LevelRenderer.cs" />
<Compile Include="Source\Map\Levels\Ruins\RuinGenerator.cs" />
<Compile Include="Source\Map\Levels\WaterRenderer.cs" />
<Compile Include="Source\Map\Levels\LevelWall.cs" />
<Compile Include="Source\Map\Lights\ConvexHull.cs" />
<Compile Include="Source\Map\Lights\LightManager.cs" />
<Compile Include="Source\Map\Lights\LightSource.cs" />
<Compile Include="Source\Map\LinkedSubmarine.cs" />
<Compile Include="Source\Map\Map\Location.cs" />
<Compile Include="Source\Map\Map\Map.cs" />
<Compile Include="Source\Map\MapEntity.cs" />
<Compile Include="Source\Map\MapEntityPrefab.cs" />
<Compile Include="Source\Map\Structure.cs" />
<Compile Include="Source\Map\StructurePrefab.cs" />
<Compile Include="Source\Map\Submarine.cs" />
<Compile Include="Source\Map\WayPoint.cs" />
<Compile Include="Source\Networking\BanList.cs" />
<Compile Include="Source\Networking\ChatMessage.cs" />
<Compile Include="Source\Networking\EntitySpawner.cs" />
<Compile Include="Source\Networking\FileTransfer\FileReceiver.cs" />
<Compile Include="Source\Networking\GameClient.cs" />
<Compile Include="Source\Networking\GameServer.cs" />
<Compile Include="Source\Networking\GameServerSettings.cs" />
<Compile Include="Source\Networking\NetEntityEvent\ClientEntityEventManager.cs" />
<Compile Include="Source\Networking\NetEntityEvent\NetEntityEvent.cs" />
<Compile Include="Source\Networking\NetStats.cs" />
<Compile Include="Source\Networking\NetworkMember.cs" />
<Compile Include="Source\Networking\OrderChatMessage.cs" />
<Compile Include="Source\Networking\ServerInfo.cs" />
<Compile Include="Source\Networking\ServerLog.cs" />
<Compile Include="Source\Networking\Voting.cs" />
<Compile Include="Source\Networking\WhiteList.cs" />
<Compile Include="Source\Particles\Decal.cs" />
<Compile Include="Source\Particles\DecalManager.cs" />
<Compile Include="Source\Particles\DecalPrefab.cs" />
<Compile Include="Source\Particles\Particle.cs" />
<Compile Include="Source\Particles\ParticleEmitter.cs" />
<Compile Include="Source\Particles\ParticleManager.cs" />
<Compile Include="Source\Particles\ParticlePrefab.cs" />
<Compile Include="Source\Physics\PhysicsBody.cs" />
<Compile Include="Source\PlayerInput.cs" />
<Compile Include="Source\Program.cs" />
<Compile Include="Source\Screens\CharacterEditorScreen.cs" />
<Compile Include="Source\Screens\BlurEffect.cs" />
<Compile Include="Source\Screens\CampaignSetupUI.cs" />
<Compile Include="Source\Screens\CampaignUI.cs" />
<Compile Include="Source\Screens\LevelEditorScreen.cs" />
<Compile Include="Source\Screens\OldCharacterEditorScreen.cs" />
<Compile Include="Source\Screens\SpriteEditorScreen.cs" />
<Compile Include="Source\Screens\SteamWorkshopScreen.cs" />
<Compile Include="Source\Screens\SubEditorScreen.cs" />
<Compile Include="Source\Screens\GameScreen.cs" />
<Compile Include="Source\Screens\LobbyScreen.cs" />
<Compile Include="Source\Screens\MainMenuScreen.cs" />
<Compile Include="Source\Screens\NetLobbyScreen.cs" />
<Compile Include="Source\Screens\ParticleEditorScreen.cs" />
<Compile Include="Source\Screens\Screen.cs" />
<Compile Include="Source\Screens\ServerListScreen.cs" />
<Compile Include="Source\Serialization\SerializableEntityEditor.cs" />
<Compile Include="Source\Sounds\OggSound.cs" />
<Compile Include="Source\Sounds\Sound.cs" />
<Compile Include="Source\Sounds\SoundChannel.cs" />
<Compile Include="Source\Sounds\SoundManager.cs" />
<Compile Include="Source\Sounds\SoundPlayer.cs" />
<Compile Include="Source\Sprite\DeformableSprite.cs" />
<Compile Include="Source\Sprite\DeformAnimations\CustomDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\Inflate.cs" />
<Compile Include="Source\Sprite\DeformAnimations\NoiseDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\PositionalDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\JointBendDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\SpriteDeformation.cs" />
<Compile Include="Source\Sprite\Sprite.cs" />
<Compile Include="Source\Sprite\SpriteSheet.cs" />
<Compile Include="Source\Utils\MathUtils.cs" />
<Compile Include="Source\Utils\TextureLoader.cs" />
<Compile Include="Source\Utils\ToolBox.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>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="MonoGame.Framework.WindowsDX">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.6.0.1625\lib\net40\MonoGame.Framework.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="PresentationCore" />
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.WindowsDX.3.6.0.1625\lib\net40\SharpDX.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="NVorbis">
<HintPath>..\..\Libraries\NuGet\NVorbis.0.8.5.0\lib\NVorbis.dll</HintPath>
</Reference>
<Reference Include="OpenTK, Version=1.1.0.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\Libraries\NuGet\OpenTK.2.0.0\lib\net20\OpenTK.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.1.1.12\lib\net45\System.Data.SQLite.dll</HintPath>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Condition="$(DefineConstants.Contains('LINUX')) OR $(DefineConstants.Contains('OSX'))" Include="MonoGame.Framework.DesktopGL">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.6.0.1625\lib\net40\MonoGame.Framework.dll</HintPath>
</Reference>
<Reference Include="RestSharp">
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="freetype6.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="oalinst.exe">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="wrap_oal.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="MonoGame.Framework.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="OpenTK.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="SharpFont.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
<Visible>False</Visible>
<ProductName>Windows Installer 4.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.csproj">
<Project>{3af0347c-5a9b-4421-868c-8ee3dbfaebc6}</Project>
<Name>Facepunch.Steamworks</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.csproj">
<Project>{3b8f9edb-6e5e-450c-abc2-ec49075d0b50}</Project>
<Name>Hyper.ComponentModel</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.Network.csproj">
<Project>{49ba1c69-6104-41ac-a5d8-b54fa9f696e8}</Project>
<Name>Lidgren.Network</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.csproj">
<Project>{c293db32-fa42-486d-b128-5a12522fae4e}</Project>
<Name>SharpFont</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer Physics MonoGame.csproj">
<Project>{0AAD36E3-51A5-4A07-AB60-5C8A66BD38B7}</Project>
<Name>Farseer Physics MonoGame</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="..\BarotraumaShared\BarotraumaShared.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'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">ReleaseLinux</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x64</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{008C0F83-E914-4966-9135-EA885059EDD8}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Barotrauma</RootNamespace>
<AssemblyName>Barotrauma</AssemblyName>
<FileAlignment>512</FileAlignment>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<TargetFrameworkProfile />
<ReleaseVersion>0.9.0.0</ReleaseVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>0.1.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseLinux|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\ReleaseLinux\</OutputPath>
<DefineConstants>TRACE;LINUX;CLIENT</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugLinux|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\DebugLinux\</OutputPath>
<DefineConstants>TRACE;LINUX;CLIENT;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseMac|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\ReleaseMac\</OutputPath>
<DefineConstants>TRACE;OSX;CLIENT</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugMac|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\DebugMac\</OutputPath>
<DefineConstants>TRACE;OSX;CLIENT;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWindows|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\ReleaseWindows\</OutputPath>
<DefineConstants>TRACE;WINDOWS;CLIENT</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>..\bin\DebugWindows\</OutputPath>
<DefineConstants>TRACE;WINDOWS;CLIENT;DEBUG</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Source\Camera.cs" />
<Compile Include="Source\Characters\AICharacter.cs" />
<Compile Include="Source\Characters\AI\AIController.cs" />
<Compile Include="Source\Characters\AI\AITarget.cs" />
<Compile Include="Source\Characters\AI\EnemyAIController.cs" />
<Compile Include="Source\Characters\AI\HumanAIController.cs" />
<Compile Include="Source\Characters\Animation\Ragdoll.cs" />
<Compile Include="Source\Characters\Attack.cs" />
<Compile Include="Source\Characters\Health\AfflictionHusk.cs" />
<Compile Include="Source\Characters\Health\AfflictionPsychosis.cs" />
<Compile Include="Source\Characters\Health\CharacterHealth.cs" />
<Compile Include="Source\Characters\Health\DamageModifier.cs" />
<Compile Include="Source\Events\EventManager.cs" />
<Compile Include="Source\Events\Missions\CombatMission.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\ContextualTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\ScenarioTutorial.cs" />
<Compile Include="Source\GUI\ChatBox.cs" />
<Compile Include="Source\GUI\GUIRadioButtonGroup.cs" />
<Compile Include="Source\GUI\ParamsEditor.cs" />
<Compile Include="Source\GUI\ShapeExtensions.cs" />
<Compile Include="Source\GUI\Graph.cs" />
<Compile Include="Source\Characters\CharacterHealth.cs" />
<Compile Include="Source\GameSession\GameModes\MultiPlayerCampaign.cs" />
<Compile Include="Source\GUI\GUICanvas.cs" />
<Compile Include="Source\GUI\GUICustomComponent.cs" />
<Compile Include="Source\GUI\GUILayoutGroup.cs" />
<Compile Include="Source\GUI\HUDLayoutSettings.cs" />
<Compile Include="Source\GUI\RectTransform.cs" />
<Compile Include="Source\GUI\SpriteSheetPlayer.cs" />
<Compile Include="Source\GUI\UISprite.cs" />
<Compile Include="Source\GUI\Widget.cs" />
<Compile Include="Source\Items\Components\ElectricalDischarger.cs" />
<Compile Include="Source\Items\Components\LevelResource.cs" />
<Compile Include="Source\Items\Components\Machines\Controller.cs" />
<Compile Include="Source\Items\Components\Repairable.cs" />
<Compile Include="Source\Items\Components\RepairTool.cs" />
<Compile Include="Source\Items\Components\Signal\CustomInterface.cs" />
<Compile Include="Source\Items\Components\Signal\MotionSensor.cs" />
<Compile Include="Source\Items\Components\Signal\WifiComponent.cs" />
<Compile Include="Source\Items\ItemInventory.cs" />
<Compile Include="Source\Map\ItemAssemblyPrefab.cs" />
<Compile Include="Source\Map\Levels\BackgroundCreatures\BackgroundCreature.cs" />
<Compile Include="Source\Map\Levels\BackgroundCreatures\BackgroundCreatureManager.cs" />
<Compile Include="Source\Map\Levels\BackgroundCreatures\BackgroundCreaturePrefab.cs" />
<Compile Include="Source\Characters\Character.cs" />
<Compile Include="Source\Characters\CharacterHUD.cs" />
<Compile Include="Source\Characters\CharacterInfo.cs" />
<Compile Include="Source\Characters\CharacterNetworking.cs" />
<Compile Include="Source\Characters\CharacterSound.cs" />
<Compile Include="Source\Characters\HUDProgressBar.cs" />
<Compile Include="Source\Characters\Jobs\JobPrefab.cs" />
<Compile Include="Source\Characters\Limb.cs" />
<Compile Include="Source\DebugConsole.cs" />
<Compile Include="Source\EventInput\EventInput.cs" />
<Compile Include="Source\EventInput\KeyboardDispatcher.cs" />
<Compile Include="Source\Events\Missions\Mission.cs" />
<Compile Include="Source\Events\Missions\MissionMode.cs" />
<Compile Include="Source\Fonts\ScalableFont.cs" />
<Compile Include="Source\GameMain.cs" />
<Compile Include="Source\GameSession\CrewManager.cs" />
<Compile Include="Source\GameSession\GameMode.cs" />
<Compile Include="Source\GameSession\GameModes\SinglePlayerCampaign.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\BasicTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\EditorTutorial.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\TutorialMode.cs" />
<Compile Include="Source\GameSession\GameModes\Tutorials\Tutorial.cs" />
<Compile Include="Source\GameSession\GameSession.cs" />
<Compile Include="Source\GameSession\RoundSummary.cs" />
<Compile Include="Source\GameSettings.cs" />
<Compile Include="Source\GUI\ComponentStyle.cs" />
<Compile Include="Source\GUI\GUI.cs" />
<Compile Include="Source\GUI\GUIButton.cs" />
<Compile Include="Source\GUI\GUIComponent.cs" />
<Compile Include="Source\GUI\GUIDropDown.cs" />
<Compile Include="Source\GUI\GUIFrame.cs" />
<Compile Include="Source\GUI\GUIImage.cs" />
<Compile Include="Source\GUI\GUIListBox.cs" />
<Compile Include="Source\GUI\GUIMessage.cs" />
<Compile Include="Source\GUI\GUIMessageBox.cs" />
<Compile Include="Source\GUI\GUINumberInput.cs" />
<Compile Include="Source\GUI\GUIProgressBar.cs" />
<Compile Include="Source\GUI\GUIScrollBar.cs" />
<Compile Include="Source\GUI\GUIStyle.cs" />
<Compile Include="Source\GUI\GUITextBlock.cs" />
<Compile Include="Source\GUI\GUITextBox.cs" />
<Compile Include="Source\GUI\GUITickBox.cs" />
<Compile Include="Source\GUI\LoadingScreen.cs" />
<Compile Include="Source\Items\CharacterInventory.cs" />
<Compile Include="Source\Items\Components\Door.cs" />
<Compile Include="Source\Items\Components\ItemComponent.cs" />
<Compile Include="Source\Items\Components\ItemContainer.cs" />
<Compile Include="Source\Items\Components\ItemLabel.cs" />
<Compile Include="Source\Items\Components\LightComponent.cs" />
<Compile Include="Source\Items\Components\Machines\Deconstructor.cs" />
<Compile Include="Source\Items\Components\Machines\Engine.cs" />
<Compile Include="Source\Items\Components\Machines\Fabricator.cs" />
<Compile Include="Source\Items\Components\Machines\MiniMap.cs" />
<Compile Include="Source\Items\Components\Machines\Pump.cs" />
<Compile Include="Source\Items\Components\Machines\Sonar.cs" />
<Compile Include="Source\Items\Components\Machines\Reactor.cs" />
<Compile Include="Source\Items\Components\Machines\Steering.cs" />
<Compile Include="Source\Items\Components\Power\PowerContainer.cs" />
<Compile Include="Source\Items\Components\Power\Powered.cs" />
<Compile Include="Source\Items\Components\Power\PowerTransfer.cs" />
<Compile Include="Source\Items\Components\Signal\Connection.cs" />
<Compile Include="Source\Items\Components\Signal\ConnectionPanel.cs" />
<Compile Include="Source\Items\Components\Signal\Wire.cs" />
<Compile Include="Source\Items\Components\StatusHUD.cs" />
<Compile Include="Source\Items\Components\Turret.cs" />
<Compile Include="Source\Items\DockingPort.cs" />
<Compile Include="Source\Items\Inventory.cs" />
<Compile Include="Source\Items\Item.cs" />
<Compile Include="Source\Items\ItemPrefab.cs" />
<Compile Include="Source\Items\Rope.cs" />
<Compile Include="Source\Map\Explosion.cs" />
<Compile Include="Source\Map\FireSource.cs" />
<Compile Include="Source\Map\Gap.cs" />
<Compile Include="Source\Map\Hull.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelObject.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelObjectManager.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelObjectPrefab.cs" />
<Compile Include="Source\Map\Levels\CaveGenerator.cs" />
<Compile Include="Source\Map\Levels\Level.cs" />
<Compile Include="Source\Map\Levels\LevelObjects\LevelTrigger.cs" />
<Compile Include="Source\Map\Levels\LevelRenderer.cs" />
<Compile Include="Source\Map\Levels\Ruins\RuinGenerator.cs" />
<Compile Include="Source\Map\Levels\WaterRenderer.cs" />
<Compile Include="Source\Map\Levels\LevelWall.cs" />
<Compile Include="Source\Map\Lights\ConvexHull.cs" />
<Compile Include="Source\Map\Lights\LightManager.cs" />
<Compile Include="Source\Map\Lights\LightSource.cs" />
<Compile Include="Source\Map\LinkedSubmarine.cs" />
<Compile Include="Source\Map\Map\Location.cs" />
<Compile Include="Source\Map\Map\Map.cs" />
<Compile Include="Source\Map\MapEntity.cs" />
<Compile Include="Source\Map\MapEntityPrefab.cs" />
<Compile Include="Source\Map\Structure.cs" />
<Compile Include="Source\Map\StructurePrefab.cs" />
<Compile Include="Source\Map\Submarine.cs" />
<Compile Include="Source\Map\SubmarineBody.cs" />
<Compile Include="Source\Map\WayPoint.cs" />
<Compile Include="Source\Media\Video.cs" />
<Compile Include="Source\Networking\BanList.cs" />
<Compile Include="Source\Networking\ChatMessage.cs" />
<Compile Include="Source\Networking\Client.cs" />
<Compile Include="Source\Networking\EntitySpawner.cs" />
<Compile Include="Source\Networking\FileTransfer\FileReceiver.cs" />
<Compile Include="Source\Networking\GameClient.cs" />
<Compile Include="Source\Networking\NetEntityEvent\ClientEntityEventManager.cs" />
<Compile Include="Source\Networking\NetEntityEvent\NetEntityEvent.cs" />
<Compile Include="Source\Networking\NetStats.cs" />
<Compile Include="Source\Networking\OrderChatMessage.cs" />
<Compile Include="Source\Networking\RespawnManager.cs" />
<Compile Include="Source\Networking\ServerInfo.cs" />
<Compile Include="Source\Networking\ServerLog.cs" />
<Compile Include="Source\Networking\ServerSettings.cs" />
<Compile Include="Source\Networking\SteamManager.cs" />
<Compile Include="Source\Networking\Voip\VoipCapture.cs" />
<Compile Include="Source\Networking\Voip\VoipClient.cs" />
<Compile Include="Source\Networking\Voip\VoipConfig.cs" />
<Compile Include="Source\Networking\Voting.cs" />
<Compile Include="Source\Networking\WhiteList.cs" />
<Compile Include="Source\Particles\Decal.cs" />
<Compile Include="Source\Particles\DecalManager.cs" />
<Compile Include="Source\Particles\DecalPrefab.cs" />
<Compile Include="Source\Particles\Particle.cs" />
<Compile Include="Source\Particles\ParticleEmitter.cs" />
<Compile Include="Source\Particles\ParticleManager.cs" />
<Compile Include="Source\Particles\ParticlePrefab.cs" />
<Compile Include="Source\Physics\PhysicsBody.cs" />
<Compile Include="Source\PlayerInput.cs" />
<Compile Include="Source\Program.cs" />
<Compile Include="Source\Screens\CharacterEditorScreen.cs" />
<Compile Include="Source\Screens\BlurEffect.cs" />
<Compile Include="Source\Screens\CampaignSetupUI.cs" />
<Compile Include="Source\Screens\CampaignUI.cs" />
<Compile Include="Source\Screens\LevelEditorScreen.cs" />
<Compile Include="Source\Screens\SpriteEditorScreen.cs" />
<Compile Include="Source\Screens\SteamWorkshopScreen.cs" />
<Compile Include="Source\Screens\SubEditorScreen.cs" />
<Compile Include="Source\Screens\GameScreen.cs" />
<Compile Include="Source\Screens\LobbyScreen.cs" />
<Compile Include="Source\Screens\MainMenuScreen.cs" />
<Compile Include="Source\Screens\NetLobbyScreen.cs" />
<Compile Include="Source\Screens\ParticleEditorScreen.cs" />
<Compile Include="Source\Screens\Screen.cs" />
<Compile Include="Source\Screens\ServerListScreen.cs" />
<Compile Include="Source\Serialization\SerializableEntityEditor.cs" />
<Compile Include="Source\Sounds\OggSound.cs" />
<Compile Include="Source\Sounds\Sound.cs" />
<Compile Include="Source\Sounds\SoundChannel.cs" />
<Compile Include="Source\Sounds\SoundFilters.cs" />
<Compile Include="Source\Sounds\SoundManager.cs" />
<Compile Include="Source\Sounds\SoundPlayer.cs" />
<Compile Include="Source\Sounds\VoipSound.cs" />
<Compile Include="Source\Sounds\VideoSound.cs" />
<Compile Include="Source\Sprite\DeformableSprite.cs" />
<Compile Include="Source\Sprite\DeformAnimations\CustomDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\Inflate.cs" />
<Compile Include="Source\Sprite\DeformAnimations\NoiseDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\PositionalDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\JointBendDeformation.cs" />
<Compile Include="Source\Sprite\DeformAnimations\SpriteDeformation.cs" />
<Compile Include="Source\Sprite\Sprite.cs" />
<Compile Include="Source\Sprite\SpriteSheet.cs" />
<Compile Include="Source\Utils\MathUtils.cs" />
<Compile Include="Source\Utils\TextureLoader.cs" />
<Compile Include="Source\Utils\ToolBox.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="Concentus, Version=1.1.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\Concentus.1.1.7\lib\portable-net45+win+wpa81+wp80\Concentus.dll</HintPath>
</Reference>
<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>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" 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>
</Reference>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\NLog.4.3.8\lib\net45\NLog.dll</HintPath>
</Reference>
<Reference Include="nVLC, Version=3.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\nVLC.3.0.0\lib\net40\nVLC.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="NVorbis, Version=0.8.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\NVorbis.0.8.6\lib\net35\NVorbis.dll</HintPath>
</Reference>
<Reference Include="OpenTK, Version=3.0.1.0, Culture=neutral, PublicKeyToken=bad199fe84eb3df4, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\OpenTK.3.0.1\lib\net20\OpenTK.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="PresentationCore" />
<Reference Include="RestSharp, Version=105.2.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\RestSharp.105.2.3\lib\net45\RestSharp.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.4.2.0\lib\net45\SharpDX.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.Direct2D1, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.Direct2D1.4.2.0\lib\net45\SharpDX.Direct2D1.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.Direct3D11, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.Direct3D11.4.2.0\lib\net45\SharpDX.Direct3D11.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.Direct3D9, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.Direct3D9.4.2.0\lib\net45\SharpDX.Direct3D9.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.DXGI, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.DXGI.4.2.0\lib\net45\SharpDX.DXGI.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.Mathematics, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.Mathematics.4.2.0\lib\net45\SharpDX.Mathematics.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.MediaFoundation, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.MediaFoundation.4.2.0\lib\net45\SharpDX.MediaFoundation.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.XAudio2, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.XAudio2.4.2.0\lib\net45\SharpDX.XAudio2.dll</HintPath>
</Reference>
<Reference Condition="$(DefineConstants.Contains('WINDOWS'))" Include="SharpDX.XInput, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b4dcf0f35e5521f1, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\SharpDX.XInput.4.2.0\lib\net45\SharpDX.XInput.dll</HintPath>
</Reference>
<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>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\Libraries\NuGet\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Condition="$(DefineConstants.Contains('LINUX')) OR $(DefineConstants.Contains('OSX'))" Include="MonoGame.Framework.DesktopGL">
<HintPath>..\..\Libraries\NuGet\MonoGame.Framework.DesktopGL.3.7.1.189\lib\net45\MonoGame.Framework.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Content Include="freetype6.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="libvlc.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="libvlccore.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\access\libfilesystem_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\audio_filter\libaudio_format_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\audio_filter\libugly_resampler_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\audio_output\libamem_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\codec\libavcodec_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\demux\libmp4_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\packetizer\libpacketizer_mpeg4audio_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\packetizer\libpacketizer_mpeg4video_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\video_chroma\librv32_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\video_chroma\libswscale_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="plugins\video_output\libvmem_plugin.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="wrap_oal.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="MonoGame.Framework.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="OpenTK.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="SharpFont.dll.config">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
<Visible>False</Visible>
<ProductName>Windows Installer 4.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.csproj">
<Project>{3af0347c-5a9b-4421-868c-8ee3dbfaebc6}</Project>
<Name>Facepunch.Steamworks</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.csproj">
<Project>{3b8f9edb-6e5e-450c-abc2-ec49075d0b50}</Project>
<Name>Hyper.ComponentModel</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.Network.csproj">
<Project>{49ba1c69-6104-41ac-a5d8-b54fa9f696e8}</Project>
<Name>Lidgren.Network</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\SharpFont\Source\SharpFont\SharpFont.csproj">
<Project>{c293db32-fa42-486d-b128-5a12522fae4e}</Project>
<Name>SharpFont</Name>
</ProjectReference>
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer Physics MonoGame.csproj">
<Project>{0AAD36E3-51A5-4A07-AB60-5C8A66BD38B7}</Project>
<Name>Farseer Physics MonoGame</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="libvlc.dylib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
<None Include="libopenal.1.dylib">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup />
<Import Project="..\BarotraumaShared\BarotraumaShared.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.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')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,18 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>
<PropertyGroup>
<ReferencePath>
</ReferencePath>
</PropertyGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
<ProjectView>ShowAllFiles</ProjectView>
</PropertyGroup>
<PropertyGroup>
<ReferencePath>
</ReferencePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugWindows|x64'">
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,8 @@
// This file is used by Code Analysis to maintain SuppressMessage
// attributes that are applied to this project.
// Project-level suppressions either have no target or are given
// a specific target and scoped to a namespace, type, member, etc.
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Potential Code Quality Issues", "RECS0026:Possible unassigned object created by 'new'", Justification = "<Pending>", Scope = "member", Target = "~M:Barotrauma.GameSettings.CreateSettingsFrame")]

View File

@@ -2,8 +2,8 @@
<configuration>
<dllmap dll="SDL2.dll" os="osx" target="libSDL2-2.0.0.dylib" />
<dllmap dll="soft_oal.dll" os="osx" target="libopenal.1.dylib" />
<dllmap dll="SDL2.dll" os="linux" cpu="x86" target="./x86/libSDL2-2.0.so.0" />
<!--<dllmap dll="SDL2.dll" os="linux" cpu="x86" target="./x86/libSDL2-2.0.so.0" />-->
<dllmap dll="soft_oal.dll" os="linux" cpu="x86" target="./x86/libopenal.so.1" />
<dllmap dll="SDL2.dll" os="linux" cpu="x86-64" target="./x64/libSDL2-2.0.so.0" />
<!--<dllmap dll="SDL2.dll" os="linux" cpu="x86-64" target="./x64/libSDL2-2.0.so.0" />-->
<dllmap dll="soft_oal.dll" os="linux" cpu="x86-64" target="./x64/libopenal.so.1" />
</configuration>

View File

@@ -6,7 +6,7 @@
<dllmap os="linux" dll="opencl.dll" target="libOpenCL.so"/>
<dllmap os="linux" dll="libX11" target="libX11.so.6"/>
<dllmap os="linux" dll="libXi" target="libXi.so.6"/>
<dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/>
<!-- <dllmap os="linux" dll="SDL2.dll" target="libSDL2-2.0.so.0"/> -->
<dllmap os="osx" dll="opengl32.dll" target="/System/Library/Frameworks/OpenGL.framework/OpenGL"/>
<dllmap os="osx" dll="openal32.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />
<dllmap os="osx" dll="alut.dll" target="/System/Library/Frameworks/OpenAL.framework/OpenAL" />

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.8.9.3")]
[assembly: AssemblyFileVersion("0.8.9.3")]
[assembly: AssemblyVersion("0.8.9.4")]
[assembly: AssemblyFileVersion("0.8.9.4")]

View File

@@ -14,9 +14,9 @@ namespace Barotrauma
Vector2 pos = Character.WorldPosition;
pos.Y = -pos.Y;
if (selectedAiTarget?.Entity != null)
if (SelectedAiTarget?.Entity != null)
{
GUI.DrawLine(spriteBatch, pos, new Vector2(selectedAiTarget.WorldPosition.X, -selectedAiTarget.WorldPosition.Y), Color.Red * 0.3f, 0, 5);
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.3f, 0, 5);
if (wallTarget != null)
{
@@ -27,7 +27,7 @@ namespace Barotrauma
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
}
GUI.Font.DrawString(spriteBatch, $"{selectedAiTarget.Entity.ToString()} ({targetValue.ToString()})", pos - Vector2.UnitY * 20.0f, Color.Red);
GUI.Font.DrawString(spriteBatch, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.ToString()})", pos - Vector2.UnitY * 20.0f, Color.Red);
}
/*GUI.Font.DrawString(spriteBatch, targetValue.ToString(), pos - Vector2.UnitY * 80.0f, Color.Red);

View File

@@ -1,4 +1,6 @@
using Microsoft.Xna.Framework;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System.Linq;
namespace Barotrauma
{
@@ -21,11 +23,11 @@ namespace Barotrauma
public override void DebugDraw(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch)
{
if (selectedAiTarget?.Entity != null)
if (SelectedAiTarget?.Entity != null)
{
GUI.DrawLine(spriteBatch,
new Vector2(Character.DrawPosition.X, -Character.DrawPosition.Y),
new Vector2(selectedAiTarget.WorldPosition.X, -selectedAiTarget.WorldPosition.Y), Color.Red);
new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red);
}
IndoorsSteeringManager pathSteering = steeringManager as IndoorsSteeringManager;
@@ -50,5 +52,52 @@ namespace Barotrauma
Color.LightGreen);
}
}
//TODO: move this to the shared project, otherwise bots won't be able to report things in multiplayer
partial void ReportProblems()
{
if (GameMain.Client != null) return;
Order newOrder = null;
if (Character.CurrentHull != null)
{
if (Character.CurrentHull.FireSources.Count > 0)
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportfire");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
if (Character.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.ConnectedDoor == null && g.Open > 0.0f))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
foreach (Character c in Character.CharacterList)
{
if (c.CurrentHull == Character.CurrentHull && !c.IsDead &&
(c.AIController is EnemyAIController || c.TeamID != Character.TeamID))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportintruders");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
}
}
if (Character.CurrentHull != null && (Character.Bleeding > 1.0f || Character.Vitality < Character.MaxVitality * 0.1f))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
if (newOrder != null)
{
if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime))
{
Character.Speak(
newOrder.GetChatMessage("", Character.CurrentHull?.RoomName, givingOrderToSelf: false), ChatMessageType.Order);
}
}
}
}
}

View File

@@ -2,38 +2,10 @@
{
partial class AICharacter : Character
{
partial void InitProjSpecific()
{
soundTimer = Rand.Range(0.0f, soundInterval);
}
partial void SoundUpdate(float deltaTime)
{
if (soundTimer > 0)
{
soundTimer -= deltaTime;
}
else
{
switch (aiController.State)
{
case AIController.AIState.Attack:
PlaySound(CharacterSound.SoundType.Attack);
break;
default:
PlaySound(CharacterSound.SoundType.Idle);
break;
}
soundTimer = soundInterval;
}
}
public override void DrawFront(Microsoft.Xna.Framework.Graphics.SpriteBatch spriteBatch, Camera cam)
{
base.DrawFront(spriteBatch, cam);
if (GameMain.DebugDraw && !IsDead) aiController.DebugDraw(spriteBatch);
}
}
}

View File

@@ -0,0 +1,48 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace Barotrauma
{
partial class HumanoidAnimParams : ISerializableEntity
{
private static GUIListBox editor;
public static GUIListBox Editor
{
get
{
if (editor == null)
{
editor = new GUIListBox(new RectTransform(new Vector2(0.3f, 1), GUI.Canvas));
//editor.AddChild(new SerializableEntityEditor(editor.RectTransform, WalkInstance, false, true, elementHeight: 20));
//editor.AddChild(new SerializableEntityEditor(editor.RectTransform, RunInstance, false, true, elementHeight: 20));
}
return editor;
}
}
public void Save()
{
XDocument doc = XMLExtensions.TryLoadXml(filePath);
if (doc == null || doc.Root == null) return;
SerializableProperty.SerializeProperties(this, doc.Root, true);
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
settings.NewLineOnAttributes = true;
using (var writer = XmlWriter.Create(filePath, settings))
{
doc.WriteTo(writer);
writer.Flush();
}
}
}
}

View File

@@ -7,9 +7,9 @@ using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Linq;
using System.Collections.Generic;
using Barotrauma.Particles;
using System.Linq;
namespace Barotrauma
{
@@ -17,6 +17,233 @@ namespace Barotrauma
{
public HashSet<SpriteDeformation> SpriteDeformations { get; protected set; } = new HashSet<SpriteDeformation>();
/// <summary>
/// Inversed draw order, which is used for drawing the limbs in 3d (deformable sprites).
/// </summary>
protected Limb[] inversedLimbDrawOrder;
partial void UpdateNetPlayerPositionProjSpecific(float deltaTime, float lowestSubPos)
{
if (character != GameMain.Client.Character || !character.AllowInput)
{
//remove states without a timestamp (there may still be ID-based states
//in the list when the controlled character switches to timestamp-based interpolation)
character.MemState.RemoveAll(m => m.Timestamp == 0.0f);
//use simple interpolation for other players' characters and characters that can't move
if (character.MemState.Count > 0)
{
CharacterStateInfo serverPos = character.MemState.Last();
if (!character.isSynced)
{
SetPosition(serverPos.Position, false);
Collider.LinearVelocity = Vector2.Zero;
character.MemLocalState.Clear();
character.LastNetworkUpdateID = serverPos.ID;
character.isSynced = true;
return;
}
if (character.MemState[0].Interact == null || character.MemState[0].Interact.Removed)
{
character.DeselectCharacter();
character.SelectedConstruction = null;
}
else if (character.MemState[0].Interact is Character)
{
character.SelectCharacter((Character)character.MemState[0].Interact);
}
else if (character.MemState[0].Interact is Item newSelectedConstruction)
{
if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction)
{
foreach (var ic in newSelectedConstruction.Components)
{
if (ic.CanBeSelected) ic.Select(character);
}
}
character.SelectedConstruction = newSelectedConstruction;
}
if (character.MemState[0].Animation == AnimController.Animation.CPR)
{
character.AnimController.Anim = AnimController.Animation.CPR;
}
else if (character.AnimController.Anim == AnimController.Animation.CPR)
{
character.AnimController.Anim = AnimController.Animation.None;
}
Vector2 newVelocity = Collider.LinearVelocity;
Vector2 newPosition = Collider.SimPosition;
float newRotation = Collider.Rotation;
float newAngularVelocity = Collider.AngularVelocity;
Collider.CorrectPosition(character.MemState, out newPosition, out newVelocity, out newRotation, out newAngularVelocity);
newVelocity = newVelocity.ClampLength(100.0f);
if (!MathUtils.IsValid(newVelocity)) { newVelocity = Vector2.Zero; }
overrideTargetMovement = newVelocity.LengthSquared() > 0.01f ? newVelocity : Vector2.Zero;
Collider.LinearVelocity = newVelocity;
Collider.AngularVelocity = newAngularVelocity;
float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition);
float errorTolerance = character.AllowInput ? 0.01f : 0.1f;
if (distSqrd > errorTolerance)
{
if (distSqrd > 10.0f || !character.AllowInput)
{
Collider.TargetRotation = newRotation;
SetPosition(newPosition, lerp: distSqrd < 1.0f);
}
else
{
Collider.TargetRotation = newRotation;
Collider.TargetPosition = newPosition;
Collider.MoveToTargetPosition(true);
}
}
//unconscious/dead characters can't correct their position using AnimController movement
// -> we need to correct it manually
if (!character.AllowInput)
{
MainLimb.PullJointWorldAnchorB = Collider.SimPosition;
MainLimb.PullJointEnabled = true;
}
}
character.MemLocalState.Clear();
}
else
{
//remove states with a timestamp (there may still timestamp-based states
//in the list if the controlled character switches from timestamp-based interpolation to ID-based)
character.MemState.RemoveAll(m => m.Timestamp > 0.0f);
for (int i = 0; i < character.MemLocalState.Count; i++)
{
if (character.Submarine == null)
{
//transform in-sub coordinates to outside coordinates
if (character.MemLocalState[i].Position.Y > lowestSubPos)
{
character.MemLocalState[i].TransformInToOutside();
}
}
else if (currentHull?.Submarine != null)
{
//transform outside coordinates to in-sub coordinates
if (character.MemLocalState[i].Position.Y < lowestSubPos)
{
character.MemLocalState[i].TransformOutToInside(currentHull.Submarine);
}
}
}
if (character.MemState.Count < 1) return;
overrideTargetMovement = Vector2.Zero;
CharacterStateInfo serverPos = character.MemState.Last();
if (!character.isSynced)
{
SetPosition(serverPos.Position, false);
Collider.LinearVelocity = Vector2.Zero;
character.MemLocalState.Clear();
character.LastNetworkUpdateID = serverPos.ID;
character.isSynced = true;
return;
}
int localPosIndex = character.MemLocalState.FindIndex(m => m.ID == serverPos.ID);
if (localPosIndex > -1)
{
CharacterStateInfo localPos = character.MemLocalState[localPosIndex];
//the entity we're interacting with doesn't match the server's
if (localPos.Interact != serverPos.Interact)
{
if (serverPos.Interact == null || serverPos.Interact.Removed)
{
character.DeselectCharacter();
character.SelectedConstruction = null;
}
else if (serverPos.Interact is Character)
{
character.SelectCharacter((Character)serverPos.Interact);
}
else
{
var newSelectedConstruction = (Item)serverPos.Interact;
if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction)
{
newSelectedConstruction.TryInteract(character, true, true);
}
character.SelectedConstruction = newSelectedConstruction;
}
}
if (localPos.Animation != serverPos.Animation)
{
if (serverPos.Animation == AnimController.Animation.CPR)
{
character.AnimController.Anim = AnimController.Animation.CPR;
}
else if (character.AnimController.Anim == AnimController.Animation.CPR)
{
character.AnimController.Anim = AnimController.Animation.None;
}
}
Hull serverHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(serverPos.Position), character.CurrentHull, serverPos.Position.Y < lowestSubPos);
Hull clientHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(localPos.Position), serverHull, localPos.Position.Y < lowestSubPos);
if (serverHull != null && clientHull != null && serverHull.Submarine != clientHull.Submarine)
{
//hull subs don't match => teleport the camera to the other sub
character.Submarine = serverHull.Submarine;
character.CurrentHull = currentHull = serverHull;
SetPosition(serverPos.Position);
character.MemLocalState.Clear();
}
else
{
Vector2 positionError = serverPos.Position - localPos.Position;
float rotationError = serverPos.Rotation - localPos.Rotation;
for (int i = localPosIndex; i < character.MemLocalState.Count; i++)
{
Hull pointHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(character.MemLocalState[i].Position), clientHull, character.MemLocalState[i].Position.Y < lowestSubPos);
if (pointHull != clientHull && ((pointHull == null) || (clientHull == null) || (pointHull.Submarine == clientHull.Submarine))) break;
character.MemLocalState[i].Translate(positionError, rotationError);
}
float errorMagnitude = positionError.Length();
if (errorMagnitude > 0.01f)
{
Collider.TargetPosition = Collider.SimPosition + positionError;
Collider.TargetRotation = Collider.Rotation + rotationError;
Collider.MoveToTargetPosition(lerp: true);
if (errorMagnitude > 0.5f)
{
character.MemLocalState.Clear();
foreach (Limb limb in Limbs)
{
limb.body.TargetPosition = limb.body.SimPosition + positionError;
limb.body.MoveToTargetPosition(lerp: true);
}
}
}
}
}
if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120);
character.MemState.Clear();
}
}
partial void ImpactProjSpecific(float impact, Body body)
{
float volume = Math.Min(impact - 3.0f, 1.0f);
@@ -42,7 +269,7 @@ namespace Barotrauma
}
else if (body.UserData is Limb || body == Collider.FarseerBody)
{
if (!character.IsRemotePlayer || GameMain.Server != null)
if (!character.IsRemotePlayer)
{
if (impact > ImpactTolerance)
{
@@ -115,7 +342,7 @@ namespace Barotrauma
depthSortedLimbs.Reverse();
inversedLimbDrawOrder = depthSortedLimbs.ToArray();
}
partial void UpdateProjSpecific(float deltaTime)
{
LimbJoints.ForEach(j => j.UpdateDeformations(deltaTime));

View File

@@ -1,5 +1,6 @@
using Barotrauma.Networking;
using Barotrauma.Particles;
using Barotrauma.Sounds;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
@@ -22,6 +23,8 @@ namespace Barotrauma
protected float hudInfoTimer;
protected bool hudInfoVisible;
private float findFocusedTimer;
protected float lastRecvPositionUpdateTime;
private float hudInfoHeight;
@@ -39,7 +42,6 @@ namespace Barotrauma
if (controlled == value) return;
controlled = value;
if (controlled != null) controlled.Enabled = true;
GameMain.GameSession?.CrewManager?.SetCharacterSelected(controlled);
CharacterHealth.OpenHealthWindow = null;
}
@@ -107,13 +109,7 @@ namespace Barotrauma
partial void InitProjSpecific(XDocument doc)
{
soundInterval = doc.Root.GetAttributeFloat("soundinterval", 10.0f);
keys = new Key[Enum.GetNames(typeof(InputType)).Length];
for (int i = 0; i < Enum.GetNames(typeof(InputType)).Length; i++)
{
keys[i] = new Key((InputType)i);
}
soundTimer = Rand.Range(0.0f, soundInterval);
BloodDecalName = doc.Root.GetAttributeString("blooddecal", "");
@@ -140,6 +136,13 @@ namespace Barotrauma
hudProgressBars = new Dictionary<object, HUDProgressBar>();
}
partial void UpdateLimbLightSource(Limb limb)
{
if (limb.LightSource != null)
{
limb.LightSource.Enabled = enabled;
}
}
/// <summary>
/// Control the Character according to player input
@@ -196,7 +199,7 @@ namespace Barotrauma
{
cam.OffsetAmount = 0.0f;
}
else if (SelectedConstruction != null && SelectedConstruction.components.Any(ic => (ic.GuiFrame != null && GUI.IsMouseOn(ic.GuiFrame))))
else if (SelectedConstruction != null && SelectedConstruction.Components.Any(ic => (ic.GuiFrame != null && GUI.IsMouseOn(ic.GuiFrame))))
{
cam.OffsetAmount = 0.0f;
}
@@ -229,7 +232,7 @@ namespace Barotrauma
partial void UpdateControlled(float deltaTime, Camera cam)
{
if (controlled != this) return;
ControlLocalPlayer(deltaTime, cam);
Lights.LightManager.ViewTarget = this;
@@ -257,7 +260,17 @@ namespace Barotrauma
}
}
partial void KillProjSpecific()
partial void OnAttackedProjSpecific(Character attacker, AttackResult attackResult)
{
if (attackResult.Damage <= 0) { return; }
if (soundTimer < soundInterval * 0.5f)
{
PlaySound(CharacterSound.SoundType.Damage);
soundTimer = soundInterval;
}
}
partial void KillProjSpecific(CauseOfDeathType causeOfDeath, Affliction causeOfDeathAffliction)
{
if (GameMain.NetworkMember != null && controlled == this)
{
@@ -285,13 +298,159 @@ namespace Barotrauma
GameMain.GameSession.CrewManager.RemoveCharacter(this);
}
if (GameMain.NetworkMember?.Character == this) GameMain.NetworkMember.Character = null;
if (GameMain.Client?.Character == this) GameMain.Client.Character = null;
if (Lights.LightManager.ViewTarget == this) Lights.LightManager.ViewTarget = null;
}
private List<Item> debugInteractablesInRange = new List<Item>();
private List<Item> debugInteractablesAtCursor = new List<Item>();
private List<Pair<Item, float>> debugInteractablesNearCursor = new List<Pair<Item, float>>();
/// <summary>
/// Finds the front (lowest depth) interactable item at a position. "Interactable" in this case means that the character can "reach" the item.
/// </summary>
/// <param name="character">The Character who is looking for the interactable item, only items that are close enough to this character are returned</param>
/// <param name="simPosition">The item at the simPosition, with the lowest depth, is returned</param>
/// <param name="allowFindingNearestItem">If this is true and an item cannot be found at simPosition then a nearest item will be returned if possible</param>
/// <param name="hull">If a hull is specified, only items within that hull are returned</param>
public Item FindItemAtPosition(Vector2 simPosition, float aimAssistModifier = 0.0f, Item[] ignoredItems = null)
{
if (Submarine != null)
{
simPosition += Submarine.SimPosition;
}
debugInteractablesInRange.Clear();
debugInteractablesAtCursor.Clear();
debugInteractablesNearCursor.Clear();
//reduce the amount of aim assist if an item has been selected
//= can't switch selection to another item without deselecting the current one first UNLESS the cursor is directly on the item
//otherwise it would be too easy to accidentally switch the selected item when rewiring items
float aimAssistAmount = SelectedConstruction == null ? 100.0f * aimAssistModifier : 1.0f;
Vector2 displayPosition = ConvertUnits.ToDisplayUnits(simPosition);
//use the list of visible entities if it exists
var entityList = Submarine.VisibleEntities ?? Item.ItemList;
Item closestItem = null;
float closestItemDistance = aimAssistAmount;
foreach (MapEntity entity in entityList)
{
if (!(entity is Item item))
{
continue;
}
if (item.body != null && !item.body.Enabled) continue;
if (item.ParentInventory != null) continue;
if (ignoredItems != null && ignoredItems.Contains(item)) continue;
float distanceToItem = float.PositiveInfinity;
if (item.IsInsideTrigger(displayPosition, out Rectangle transformedTrigger))
{
debugInteractablesAtCursor.Add(item);
//distance is between 0-1 when the cursor is directly on the item
distanceToItem =
Math.Abs(transformedTrigger.Center.X - displayPosition.X) / transformedTrigger.Width +
Math.Abs((transformedTrigger.Y - transformedTrigger.Height / 2.0f) - displayPosition.Y) / transformedTrigger.Height;
//modify the distance based on the size of the trigger (preferring smaller items)
distanceToItem *= MathHelper.Lerp(0.05f, 2.0f, (transformedTrigger.Width + transformedTrigger.Height) / 250.0f);
}
else
{
Rectangle itemDisplayRect = new Rectangle(item.InteractionRect.X, item.InteractionRect.Y - item.InteractionRect.Height, item.InteractionRect.Width, item.InteractionRect.Height);
if (itemDisplayRect.Contains(displayPosition))
{
debugInteractablesAtCursor.Add(item);
//distance is between 0-1 when the cursor is directly on the item
distanceToItem =
Math.Abs(itemDisplayRect.Center.X - displayPosition.X) / itemDisplayRect.Width +
Math.Abs(itemDisplayRect.Center.Y - displayPosition.Y) / itemDisplayRect.Height;
//modify the distance based on the size of the item (preferring smaller ones)
distanceToItem *= MathHelper.Lerp(0.05f, 2.0f, (itemDisplayRect.Width + itemDisplayRect.Height) / 250.0f);
}
else
{
if (closestItemDistance < 2.0f) { continue; }
//get the point on the itemDisplayRect which is closest to the cursor
Vector2 rectIntersectionPoint = new Vector2(
MathHelper.Clamp(displayPosition.X, itemDisplayRect.X, itemDisplayRect.Right),
MathHelper.Clamp(displayPosition.Y, itemDisplayRect.Y, itemDisplayRect.Bottom));
distanceToItem = 2.0f + Vector2.Distance(rectIntersectionPoint, displayPosition);
}
}
if (distanceToItem > closestItemDistance) { continue; }
if (!CanInteractWith(item)) { continue; }
debugInteractablesNearCursor.Add(new Pair<Item, float>(item, 1.0f - distanceToItem / (100.0f * aimAssistModifier)));
closestItem = item;
closestItemDistance = distanceToItem;
}
return closestItem;
}
private Character FindCharacterAtPosition(Vector2 mouseSimPos, float maxDist = 150.0f)
{
Character closestCharacter = null;
float closestDist = 0.0f;
maxDist = ConvertUnits.ToSimUnits(maxDist);
foreach (Character c in CharacterList)
{
if (!CanInteractWith(c)) continue;
float dist = Vector2.DistanceSquared(mouseSimPos, c.SimPosition);
if (dist < maxDist * maxDist && (closestCharacter == null || dist < closestDist))
{
closestCharacter = c;
closestDist = dist;
}
/*FarseerPhysics.Common.Transform transform;
c.AnimController.Collider.FarseerBody.GetTransform(out transform);
for (int i = 0; i < c.AnimController.Collider.FarseerBody.FixtureList.Count; i++)
{
if (c.AnimController.Collider.FarseerBody.FixtureList[i].Shape.TestPoint(ref transform, ref mouseSimPos))
{
Console.WriteLine("Hit: " + i);
closestCharacter = c;
}
}*/
}
return closestCharacter;
}
partial void UpdateProjSpecific(float deltaTime, Camera cam)
{
if (!IsDead && !IsUnconscious)
{
if (soundTimer > 0)
{
soundTimer -= deltaTime;
}
else if (AIController != null)
{
switch (AIController.State)
{
case AIController.AIState.Attack:
PlaySound(CharacterSound.SoundType.Attack);
break;
default:
PlaySound(CharacterSound.SoundType.Idle);
break;
}
}
}
if (info != null || Vitality < MaxVitality * 0.98f)
{
hudInfoTimer -= deltaTime;
@@ -421,7 +580,7 @@ namespace Barotrauma
float cursorDist = Vector2.Distance(WorldPosition, cam.ScreenToWorld(PlayerInput.MousePosition));
float hudInfoAlpha = MathHelper.Clamp(1.0f - (cursorDist - (hoverRange - fadeOutRange)) / fadeOutRange, 0.2f, 1.0f);
if (hudInfoVisible && info != null &&
if (!GUI.DisableCharacterNames && hudInfoVisible && info != null &&
(controlled == null || this != controlled.focusedCharacter))
{
string name = Info.DisplayName;
@@ -440,7 +599,7 @@ namespace Barotrauma
Color nameColor = Color.White;
if (Controlled != null && TeamID != Controlled.TeamID)
{
nameColor = Color.Red;
nameColor = TeamID == TeamType.FriendlyNPC ? Color.SkyBlue : Color.Red;
}
GUI.Font.DrawString(spriteBatch, name, namePos + new Vector2(1.0f / cam.Zoom, 1.0f / cam.Zoom), Color.Black, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.001f);
GUI.Font.DrawString(spriteBatch, name, namePos, nameColor * hudInfoAlpha, 0.0f, Vector2.Zero, 1.0f / cam.Zoom, SpriteEffects.None, 0.0f);
@@ -471,8 +630,7 @@ namespace Barotrauma
{
if (controlled != this) return null;
HUDProgressBar progressBar = null;
if (!hudProgressBars.TryGetValue(linkedObject, out progressBar))
if (!hudProgressBars.TryGetValue(linkedObject, out HUDProgressBar progressBar))
{
progressBar = new HUDProgressBar(worldPosition, Submarine, emptyColor, fullColor);
hudProgressBars.Add(linkedObject, progressBar);
@@ -485,15 +643,21 @@ namespace Barotrauma
return progressBar;
}
private SoundChannel soundChannel;
public void PlaySound(CharacterSound.SoundType soundType)
{
if (sounds == null || sounds.Count == 0) return;
if (sounds == null || sounds.Count == 0) { return; }
if (soundChannel != null && soundChannel.IsPlaying) { return; }
var matchingSounds = sounds.FindAll(s => s.Type == soundType);
if (matchingSounds.Count == 0) return;
var matchingSounds = sounds.Where(s =>
s.Type == soundType &&
(s.Gender == Gender.None || (info != null && info.Gender == s.Gender)));
if (!matchingSounds.Any()) { return; }
var selectedSound = matchingSounds[Rand.Int(matchingSounds.Count)];
SoundPlayer.PlaySound(selectedSound.Sound, selectedSound.Volume, selectedSound.Range, AnimController.WorldPosition, CurrentHull);
var matchingSoundsList = matchingSounds.ToList();
var selectedSound = matchingSoundsList[Rand.Int(matchingSoundsList.Count)];
soundChannel = SoundPlayer.PlaySound(selectedSound.Sound, selectedSound.Volume, selectedSound.Range, AnimController.WorldPosition, CurrentHull);
soundTimer = soundInterval;
}
partial void ImplodeFX()

View File

@@ -60,7 +60,7 @@ namespace Barotrauma
var item = character.Inventory.Items[i];
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
foreach (ItemComponent ic in item.components)
foreach (ItemComponent ic in item.Components)
{
if (ic.DrawHudWhenEquipped) ic.AddToGUIUpdateList();
}
@@ -94,7 +94,7 @@ namespace Barotrauma
var item = character.Inventory.Items[i];
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
foreach (ItemComponent ic in item.components)
foreach (ItemComponent ic in item.Components)
{
if (ic.DrawHudWhenEquipped) ic.UpdateHUD(character, deltaTime, cam);
}
@@ -188,8 +188,14 @@ namespace Barotrauma
}
Vector2 textPos = startPos;
textPos -= new Vector2(GUI.Font.MeasureString(focusName).X / 2, 20);
Color nameColor = Color.White;
if (character.TeamID != character.FocusedCharacter.TeamID)
{
nameColor = character.FocusedCharacter.TeamID == Character.TeamType.FriendlyNPC ? Color.SkyBlue : Color.Red;
}
GUI.DrawString(spriteBatch, textPos, focusName, Color.White, Color.Black * 0.7f, 2);
GUI.DrawString(spriteBatch, textPos, focusName, nameColor, Color.Black * 0.7f, 2);
textPos.Y += 20;
if (character.FocusedCharacter.CanInventoryBeAccessed)
{
@@ -237,30 +243,35 @@ namespace Barotrauma
scale: scale);
}
var hudTexts = focusedItem.GetHUDTexts(character);
int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);
Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
startPos.Y -= (hudTexts.Count + 1) * 20;
if (focusedItem.Sprite != null)
if (!GUI.DisableItemHighlights)
{
startPos.X += (int)(circleSize * 0.4f * dir);
startPos.Y -= (int)(circleSize * 0.4f);
var hudTexts = focusedItem.GetHUDTexts(character);
int dir = Math.Sign(focusedItem.WorldPosition.X - character.WorldPosition.X);
Vector2 startPos = cam.WorldToScreen(focusedItem.DrawPosition);
startPos.Y -= (hudTexts.Count + 1) * 20;
if (focusedItem.Sprite != null)
{
startPos.X += (int)(circleSize * 0.4f * dir);
startPos.Y -= (int)(circleSize * 0.4f);
}
Vector2 textPos = startPos;
if (dir == -1) textPos.X -= (int)GUI.Font.MeasureString(focusedItem.Name).X;
float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);
GUI.DrawString(spriteBatch, textPos, focusedItem.Name, Color.White * alpha, Color.Black * alpha * 0.7f, 2);
textPos.Y += 20.0f;
foreach (ColoredText coloredText in hudTexts)
{
if (dir == -1) textPos.X = (int)(startPos.X - GUI.SmallFont.MeasureString(coloredText.Text).X);
GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUI.SmallFont);
textPos.Y += 20;
}
}
Vector2 textPos = startPos;
if (dir == -1) textPos.X -= (int)GUI.Font.MeasureString(focusedItem.Name).X;
float alpha = MathHelper.Clamp((focusedItemOverlayTimer - ItemOverlayDelay) * 2.0f, 0.0f, 1.0f);
GUI.DrawString(spriteBatch, textPos, focusedItem.Name, Color.White * alpha, Color.Black * alpha * 0.7f, 2);
textPos.Y += 20.0f;
foreach (ColoredText coloredText in hudTexts)
{
if (dir == -1) textPos.X = (int)(startPos.X - GUI.SmallFont.MeasureString(coloredText.Text).X);
GUI.DrawString(spriteBatch, textPos, coloredText.Text, coloredText.Color * alpha, Color.Black * alpha * 0.7f, 2, GUI.SmallFont);
textPos.Y += 20;
}
}
foreach (HUDProgressBar progressBar in character.HUDProgressBars.Values)
@@ -282,7 +293,7 @@ namespace Barotrauma
var item = character.Inventory.Items[i];
if (item == null || character.Inventory.SlotTypes[i] == InvSlotType.Any) continue;
foreach (ItemComponent ic in item.components)
foreach (ItemComponent ic in item.Components)
{
if (ic.DrawHudWhenEquipped) ic.DrawHUD(spriteBatch, character);
}

View File

@@ -397,9 +397,10 @@ namespace Barotrauma
partial void UpdateOxygenProjSpecific(float prevOxygen)
{
if (prevOxygen > 0.0f && OxygenAmount <= 0.0f && Character.Controlled == Character)
if (prevOxygen > 0.0f && OxygenAmount <= 0.0f &&
Character.Controlled == Character)
{
SoundPlayer.PlaySound("drown");
SoundPlayer.PlaySound(Character.Info != null && Character.Info.Gender == Gender.Female ? "drownfemale" : "drownmale");
}
}
@@ -1110,7 +1111,7 @@ namespace Barotrauma
return medicalItems.Distinct().ToList();
}
private void UpdateLimbIndicators(float deltaTime, Rectangle drawArea)
{
limbIndicatorOverlayAnimState += deltaTime * 8.0f;
@@ -1261,8 +1262,8 @@ namespace Barotrauma
private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, GUIComponentStyle slotStyle, float iconScale, ref Vector2 iconPos)
{
Vector2 iconSize = (affliction.Prefab.Icon.size * iconScale);
if (affliction.Strength < affliction.Prefab.ShowIconThreshold) return;
Vector2 iconSize = (affliction.Prefab.Icon.size * iconScale);
//afflictions that have a strength of less than 10 are faded out slightly
float alpha = MathHelper.Lerp(0.3f, 1.0f,
@@ -1293,10 +1294,10 @@ namespace Barotrauma
byte afflictionCount = inc.ReadByte();
for (int i = 0; i < afflictionCount; i++)
{
int afflictionPrefabIndex = inc.ReadRangedInteger(0, AfflictionPrefab.List.Count - 1);
float afflictionStrength = inc.ReadSingle();
AfflictionPrefab afflictionPrefab = AfflictionPrefab.List[inc.ReadRangedInteger(0, AfflictionPrefab.List.Count - 1)];
float afflictionStrength = inc.ReadRangedSingle(0.0f, afflictionPrefab.MaxStrength, 8);
newAfflictions.Add(new Pair<AfflictionPrefab, float>(AfflictionPrefab.List[afflictionPrefabIndex], afflictionStrength));
newAfflictions.Add(new Pair<AfflictionPrefab, float>(afflictionPrefab, afflictionStrength));
}
foreach (Affliction affliction in afflictions)
@@ -1327,10 +1328,10 @@ namespace Barotrauma
for (int i = 0; i < limbAfflictionCount; i++)
{
int limbIndex = inc.ReadRangedInteger(0, limbHealths.Count - 1);
int afflictionPrefabIndex = inc.ReadRangedInteger(0, AfflictionPrefab.List.Count - 1);
float afflictionStrength = inc.ReadSingle();
AfflictionPrefab afflictionPrefab = AfflictionPrefab.List[inc.ReadRangedInteger(0, AfflictionPrefab.List.Count - 1)];
float afflictionStrength = inc.ReadRangedSingle(0.0f, afflictionPrefab.MaxStrength, 8);
newLimbAfflictions.Add(new Triplet<LimbHealth, AfflictionPrefab, float>(limbHealths[limbIndex], AfflictionPrefab.List[afflictionPrefabIndex], afflictionStrength));
newLimbAfflictions.Add(new Triplet<LimbHealth, AfflictionPrefab, float>(limbHealths[limbIndex], afflictionPrefab, afflictionStrength));
}
foreach (LimbHealth limbHealth in limbHealths)

View File

@@ -1,9 +1,10 @@
using Barotrauma.Extensions;
using Lidgren.Network;
using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -219,5 +220,55 @@ namespace Barotrauma
}
attachment.Sprite.Draw(spriteBatch, drawPos, Color.White, origin, rotate: 0, scale: scale, depth: depth, spriteEffect: spriteEffects);
}
public static CharacterInfo ClientRead(string configPath, NetBuffer inc)
{
ushort infoID = inc.ReadUInt16();
string newName = inc.ReadString();
int gender = inc.ReadByte();
int race = inc.ReadByte();
int headSpriteID = inc.ReadByte();
int hairIndex = inc.ReadByte();
int beardIndex = inc.ReadByte();
int moustacheIndex = inc.ReadByte();
int faceAttachmentIndex = inc.ReadByte();
string ragdollFile = inc.ReadString();
string jobIdentifier = inc.ReadString();
JobPrefab jobPrefab = null;
Dictionary<string, float> skillLevels = new Dictionary<string, float>();
if (!string.IsNullOrEmpty(jobIdentifier))
{
jobPrefab = JobPrefab.List.Find(jp => jp.Identifier == jobIdentifier);
for (int i = 0; i < jobPrefab.Skills.Count; i++)
{
float skillLevel = inc.ReadSingle();
skillLevels.Add(jobPrefab.Skills[i].Identifier, skillLevel);
}
}
// TODO: animations
CharacterInfo ch = new CharacterInfo(configPath, newName, jobPrefab, ragdollFile)
{
ID = infoID,
};
ch.RecreateHead(headSpriteID,(Race)race, (Gender)gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex);
System.Diagnostics.Debug.Assert(skillLevels.Count == ch.Job.Skills.Count);
if (ch.Job != null)
{
foreach (KeyValuePair<string, float> skill in skillLevels)
{
Skill matchingSkill = ch.Job.Skills.Find(s => s.Identifier == skill.Key);
if (matchingSkill == null)
{
DebugConsole.ThrowError("Skill \"" + skill.Key + "\" not found in character \"" + newName + "\"");
continue;
}
matchingSkill.Level = skill.Value;
}
}
return ch;
}
}
}

View File

@@ -9,10 +9,88 @@ namespace Barotrauma
{
partial class Character
{
partial void UpdateNetInput()
{
if (GameMain.Client != null)
{
if (this != Controlled)
{
//freeze AI characters if more than 1 seconds have passed since last update from the server
if (lastRecvPositionUpdateTime < NetTime.Now - 1.0f)
{
AnimController.Frozen = true;
memState.Clear();
//hide after 2 seconds
if (lastRecvPositionUpdateTime < NetTime.Now - 2.0f)
{
Enabled = false;
return;
}
}
}
else
{
var posInfo = new CharacterStateInfo(
SimPosition,
AnimController.Collider.Rotation,
LastNetworkUpdateID,
AnimController.TargetDir,
SelectedCharacter == null ? (Entity)SelectedConstruction : (Entity)SelectedCharacter,
AnimController.Anim);
memLocalState.Add(posInfo);
InputNetFlags newInput = InputNetFlags.None;
if (IsKeyDown(InputType.Left)) newInput |= InputNetFlags.Left;
if (IsKeyDown(InputType.Right)) newInput |= InputNetFlags.Right;
if (IsKeyDown(InputType.Up)) newInput |= InputNetFlags.Up;
if (IsKeyDown(InputType.Down)) newInput |= InputNetFlags.Down;
if (IsKeyDown(InputType.Run)) newInput |= InputNetFlags.Run;
if (IsKeyDown(InputType.Crouch)) newInput |= InputNetFlags.Crouch;
if (IsKeyHit(InputType.Select)) newInput |= InputNetFlags.Select; //TODO: clean up the way this input is registered
if (IsKeyHit(InputType.Health)) newInput |= InputNetFlags.Health;
if (IsKeyHit(InputType.Grab)) newInput |= InputNetFlags.Grab;
if (IsKeyDown(InputType.Use)) newInput |= InputNetFlags.Use;
if (IsKeyDown(InputType.Aim)) newInput |= InputNetFlags.Aim;
if (IsKeyDown(InputType.Attack)) newInput |= InputNetFlags.Attack;
if (IsKeyDown(InputType.Ragdoll)) newInput |= InputNetFlags.Ragdoll;
if (AnimController.TargetDir == Direction.Left) newInput |= InputNetFlags.FacingLeft;
Vector2 relativeCursorPos = cursorPosition - AimRefPosition;
relativeCursorPos.Normalize();
UInt16 intAngle = (UInt16)(65535.0 * Math.Atan2(relativeCursorPos.Y, relativeCursorPos.X) / (2.0 * Math.PI));
NetInputMem newMem = new NetInputMem
{
states = newInput,
intAim = intAngle
};
if (focusedItem != null && (!newMem.states.HasFlag(InputNetFlags.Grab) && !newMem.states.HasFlag(InputNetFlags.Health)))
{
newMem.interact = focusedItem.ID;
}
else if (focusedCharacter != null)
{
newMem.interact = focusedCharacter.ID;
}
memInput.Insert(0, newMem);
LastNetworkUpdateID++;
if (memInput.Count > 60)
{
memInput.RemoveRange(60, memInput.Count - 60);
}
}
}
else //this == Character.Controlled && GameMain.Client == null
{
AnimController.Frozen = false;
}
}
public virtual void ClientWrite(NetBuffer msg, object[] extraData = null)
{
if (GameMain.Server != null) return;
if (extraData != null)
{
switch ((NetEntityEvent.Type)extraData[0])
@@ -63,8 +141,6 @@ namespace Barotrauma
public virtual void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
if (GameMain.Server != null) return;
switch (type)
{
case ServerNetObject.ENTITY_POSITION:
@@ -97,13 +173,9 @@ namespace Barotrauma
keys[(int)InputType.Crouch].SetState(false, crouching);
}
bool hasAttackLimb = msg.ReadBoolean();
if (hasAttackLimb)
{
bool attackInput = msg.ReadBoolean();
keys[(int)InputType.Attack].Held = attackInput;
keys[(int)InputType.Attack].SetState(false, attackInput);
}
bool attackInput = msg.ReadBoolean();
keys[(int)InputType.Attack].Held = attackInput;
keys[(int)InputType.Attack].SetState(false, attackInput);
if (aimInput)
{
@@ -139,28 +211,44 @@ namespace Barotrauma
Vector2 pos = new Vector2(
msg.ReadFloat(),
msg.ReadFloat());
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
Vector2 linearVelocity = new Vector2(
msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
float rotation = msg.ReadFloat();
bool fixedRotation = msg.ReadBoolean();
float rotation = AnimController.Collider.Rotation;
float angularVelocity = AnimController.Collider.AngularVelocity;
if (!fixedRotation)
{
rotation = msg.ReadFloat();
float MaxAngularVel = NetConfig.MaxPhysicsBodyAngularVelocity;
angularVelocity = msg.ReadRangedSingle(-MaxAngularVel, MaxAngularVel, 8);
}
ReadStatus(msg);
bool readStatus = msg.ReadBoolean();
if (readStatus)
{
ReadStatus(msg);
}
msg.ReadPadBits();
int index = 0;
if (GameMain.NetworkMember.Character == this && AllowInput)
if (GameMain.Client.Character == this && AllowInput)
{
var posInfo = new CharacterStateInfo(pos, rotation, networkUpdateID, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation);
while (index < memState.Count && NetIdUtils.IdMoreRecent(posInfo.ID, memState[index].ID))
index++;
memState.Insert(index, posInfo);
}
else
{
var posInfo = new CharacterStateInfo(pos, rotation, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation);
var posInfo = new CharacterStateInfo(pos, rotation, linearVelocity, angularVelocity, sendingTime, facingRight ? Direction.Right : Direction.Left, selectedEntity, animation);
while (index < memState.Count && posInfo.Timestamp > memState[index].Timestamp)
index++;
memState.Insert(index, posInfo);
}
@@ -198,10 +286,13 @@ namespace Barotrauma
GameMain.Client.Character = this;
GameMain.LightManager.LosEnabled = true;
}
else if (controlled == this)
else
{
Controlled = null;
IsRemotePlayer = ownerID > 0;
if (controlled == this)
{
Controlled = null;
IsRemotePlayer = ownerID > 0;
}
}
break;
case 2:
@@ -221,45 +312,59 @@ namespace Barotrauma
break;
}
}
public static Character ReadSpawnData(NetBuffer inc, bool spawn = true)
{
DebugConsole.NewMessage("READING CHARACTER SPAWN DATA", Color.Cyan);
if (GameMain.Server != null) return null;
if (GameMain.Client == null) return null;
bool noInfo = inc.ReadBoolean();
ushort id = inc.ReadUInt16();
string configPath = inc.ReadString();
string seed = inc.ReadString();
bool noInfo = inc.ReadBoolean();
ushort id = inc.ReadUInt16();
string speciesName = inc.ReadString();
string seed = inc.ReadString();
Vector2 position = new Vector2(inc.ReadFloat(), inc.ReadFloat());
bool enabled = inc.ReadBoolean();
DebugConsole.Log("Received spawn data for " + configPath);
DebugConsole.Log("Received spawn data for " + speciesName);
string configPath = GetConfigFile(speciesName);
if (string.IsNullOrEmpty(configPath))
{
throw new Exception("Error in character spawn data - could not find a config file for the character \"" + configPath + "\"!");
}
Character character = null;
if (noInfo)
{
if (!spawn) return null;
character = Character.Create(configPath, position, seed, null, true);
character = Create(configPath, position, seed, null, true);
character.ID = id;
}
else
{
bool hasOwner = inc.ReadBoolean();
int ownerId = hasOwner ? inc.ReadByte() : -1;
byte teamID = inc.ReadByte();
bool hasAi = inc.ReadBoolean();
bool hasOwner = inc.ReadBoolean();
int ownerId = hasOwner ? inc.ReadByte() : -1;
byte teamID = inc.ReadByte();
bool hasAi = inc.ReadBoolean();
string infoSpeciesName = inc.ReadString();
if (!spawn) return null;
CharacterInfo info = CharacterInfo.ClientRead(configPath, inc);
string infoConfigPath = GetConfigFile(infoSpeciesName);
if (string.IsNullOrEmpty(infoConfigPath))
{
throw new Exception("Error in character spawn data - could not find a config file for the character info \"" + configPath + "\"!");
}
CharacterInfo info = CharacterInfo.ClientRead(infoConfigPath, inc);
character = Create(configPath, position, seed, info, GameMain.Client.ID != ownerId, hasAi);
character.ID = id;
character.TeamID = teamID;
character.TeamID = (TeamType)teamID;
if (configPath == HumanConfigFile)
{
@@ -267,7 +372,7 @@ namespace Barotrauma
GameMain.GameSession.CrewManager.RemoveCharacterInfo(duplicateCharacterInfo);
GameMain.GameSession.CrewManager.AddCharacter(character);
}
if (GameMain.Client.ID == ownerId)
{
GameMain.Client.HasSpawned = true;
@@ -286,7 +391,7 @@ namespace Barotrauma
return character;
}
private void ReadStatus(NetBuffer msg)
{
bool isDead = msg.ReadBoolean();
@@ -324,9 +429,6 @@ namespace Barotrauma
if (IsDead) Revive();
CharacterHealth.ClientRead(msg);
bool ragdolled = msg.ReadBoolean();
IsRagdolled = ragdolled;
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Barotrauma
{
public enum SoundType
{
Idle, Attack, Die
Idle, Attack, Die, Damage
}
private readonly RoundSound roundSound;
@@ -28,10 +28,13 @@ namespace Barotrauma
get { return roundSound.Sound; }
}
public readonly Gender Gender;
public CharacterSound(XElement element)
{
roundSound = Submarine.LoadRoundSound(element);
Enum.TryParse<SoundType>(element.GetAttributeString("state", "Idle"), true, out Type);
Enum.TryParse(element.GetAttributeString("state", "Idle"), true, out Type);
Enum.TryParse(element.GetAttributeString("gender", "None"), true, out Gender);
}
}
}

View File

@@ -0,0 +1,34 @@
using Microsoft.Xna.Framework;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
partial class AfflictionHusk : Affliction
{
partial void UpdateMessages(float prevStrength, Character character)
{
if (Strength < Prefab.MaxStrength * 0.5f)
{
if (prevStrength % 10.0f > 0.05f && Strength % 10.0f < 0.05f)
{
GUI.AddMessage(TextManager.Get("HuskDormant"), Color.Red);
}
}
else if (Strength < Prefab.MaxStrength)
{
if (state == InfectionState.Dormant && Character.Controlled == character)
{
GUI.AddMessage(TextManager.Get("HuskCantSpeak"), Color.Red);
}
}
else if (state != InfectionState.Active && Character.Controlled == character)
{
GUI.AddMessage(TextManager.Get("HuskActivate").Replace("[Attack]", GameMain.Config.KeyBind(InputType.Attack).ToString()),
Color.Red);
}
}
}
}

View File

@@ -0,0 +1,22 @@
namespace Barotrauma
{
partial class CharacterHealth
{
partial void UpdateLimbAfflictionOverlays()
{
foreach (Limb limb in Character.AnimController.Limbs)
{
limb.BurnOverlayStrength = 0.0f;
limb.DamageOverlayStrength = 0.0f;
if (limbHealths[limb.HealthIndex].Afflictions.Count == 0) continue;
foreach (Affliction a in limbHealths[limb.HealthIndex].Afflictions)
{
limb.BurnOverlayStrength += a.Strength / a.Prefab.MaxStrength * a.Prefab.BurnOverlayAlpha;
limb.DamageOverlayStrength += a.Strength / a.Prefab.MaxStrength * a.Prefab.DamageOverlayAlpha;
}
limb.BurnOverlayStrength /= limbHealths[limb.HealthIndex].Afflictions.Count;
limb.DamageOverlayStrength /= limbHealths[limb.HealthIndex].Afflictions.Count;
}
}
}
}

View File

@@ -0,0 +1,12 @@
namespace Barotrauma
{
partial class DamageModifier
{
[Serialize("", false)]
public string DamageSound
{
get;
private set;
}
}
}

View File

@@ -110,11 +110,28 @@ namespace Barotrauma
public Sprite Sprite { get; protected set; }
public DeformableSprite DeformSprite { get; protected set; }
public Sprite ActiveSprite => DeformSprite != null ? DeformSprite.Sprite : Sprite;
public Sprite ActiveSprite
{
get
{
// TODO: should we optimize this? No need to check all the conditionals each time the property is accessed.
var conditionalSprite = ConditionalSprites.FirstOrDefault(c => c.IsActive);
if (conditionalSprite != null)
{
return conditionalSprite;
}
else
{
return DeformSprite != null ? DeformSprite.Sprite : Sprite;
}
}
}
public float TextureScale => limbParams.Ragdoll.TextureScale;
public Sprite DamagedSprite { get; set; }
public Sprite DamagedSprite { get; private set; }
public List<ConditionalSprite> ConditionalSprites { get; private set; } = new List<ConditionalSprite>();
public Color InitialLightSourceColor
{
@@ -156,6 +173,9 @@ namespace Barotrauma
case "damagedsprite":
DamagedSprite = new Sprite(subElement, "", GetSpritePath(subElement));
break;
case "conditionalsprite":
ConditionalSprites.Add(new ConditionalSprite(subElement, character, file: GetSpritePath(subElement)));
break;
case "deformablesprite":
DeformSprite = new DeformableSprite(subElement, filePath: GetSpritePath(subElement));
foreach (XElement animationElement in subElement.Elements())
@@ -241,28 +261,28 @@ namespace Barotrauma
DeformSprite?.Sprite.LoadParams(limbParams.deformSpriteParams, isFlipped);
}
partial void AddDamageProjSpecific(Vector2 position, List<Affliction> afflictions, bool playSound, List<DamageModifier> appliedDamageModifiers)
partial void AddDamageProjSpecific(Vector2 simPosition, List<Affliction> afflictions, bool playSound, List<DamageModifier> appliedDamageModifiers)
{
float bleedingDamage = afflictions.FindAll(a => a is AfflictionBleeding).Sum(a => a.GetVitalityDecrease(character.CharacterHealth));
float bleedingDamage = character.CharacterHealth.DoesBleed ? afflictions.FindAll(a => a is AfflictionBleeding).Sum(a => a.GetVitalityDecrease(character.CharacterHealth)) : 0;
float damage = afflictions.FindAll(a => a.Prefab.AfflictionType == "damage").Sum(a => a.GetVitalityDecrease(character.CharacterHealth));
float damageMultiplier = 1;
if (playSound)
{
string damageSoundType = (bleedingDamage > damage) ? "LimbSlash" : "LimbBlunt";
foreach (DamageModifier damageModifier in appliedDamageModifiers)
{
if (!string.IsNullOrWhiteSpace(damageModifier.DamageSound))
{
damageSoundType = damageModifier.DamageSound;
SoundPlayer.PlayDamageSound(damageSoundType, Math.Max(damage, bleedingDamage), WorldPosition);
damageMultiplier *= damageModifier.DamageMultiplier;
break;
}
}
SoundPlayer.PlayDamageSound(damageSoundType, Math.Max(damage, bleedingDamage), position);
}
float damageParticleAmount = Math.Min(damage / 10, 1.0f);
// Always spawn damage particles
float damageParticleAmount = Math.Min(damage / 10, 1.0f) * damageMultiplier;
foreach (ParticleEmitter emitter in character.DamageEmitters)
{
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) continue;
@@ -271,20 +291,25 @@ namespace Barotrauma
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, amountMultiplier: damageParticleAmount);
}
float bloodParticleAmount = Math.Min(bleedingDamage / 5, 1.0f);
float bloodParticleSize = MathHelper.Clamp(bleedingDamage / 5, 0.1f, 1.0f);
foreach (ParticleEmitter emitter in character.BloodEmitters)
if (bleedingDamage > 0)
{
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) continue;
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) continue;
float bloodParticleAmount = Math.Min(bleedingDamage / 5, 1.0f) * damageMultiplier;
float bloodParticleSize = MathHelper.Clamp(bleedingDamage / 5, 0.1f, 1.0f);
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, sizeMultiplier: bloodParticleSize, amountMultiplier: bloodParticleAmount);
foreach (ParticleEmitter emitter in character.BloodEmitters)
{
if (inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Air) continue;
if (!inWater && emitter.Prefab.ParticlePrefab.DrawTarget == ParticlePrefab.DrawTargetType.Water) continue;
emitter.Emit(1.0f, WorldPosition, character.CurrentHull, sizeMultiplier: bloodParticleSize, amountMultiplier: bloodParticleAmount);
}
if (bloodParticleAmount > 0 && character.CurrentHull != null && !string.IsNullOrEmpty(character.BloodDecalName))
{
character.CurrentHull.AddDecal(character.BloodDecalName, WorldPosition, MathHelper.Clamp(bloodParticleSize, 0.5f, 1.0f));
}
}
if (bloodParticleAmount > 0 && character.CurrentHull != null && !string.IsNullOrEmpty(character.BloodDecalName))
{
character.CurrentHull.AddDecal(character.BloodDecalName, WorldPosition, MathHelper.Clamp(bloodParticleSize, 0.5f, 1.0f));
}
}
partial void UpdateProjSpecific(float deltaTime)
@@ -353,7 +378,8 @@ namespace Barotrauma
if (!hideLimb)
{
if (DeformSprite != null)
var activeSprite = ActiveSprite;
if (DeformSprite != null && activeSprite == DeformSprite.Sprite)
{
if (Deformations != null && Deformations.Any())
{
@@ -368,7 +394,7 @@ namespace Barotrauma
}
else
{
body.Draw(spriteBatch, Sprite, color, null, Scale * TextureScale);
body.Draw(spriteBatch, activeSprite, color, null, Scale * TextureScale);
}
}
@@ -401,11 +427,12 @@ namespace Barotrauma
{
float depth = ActiveSprite.Depth - 0.0000015f;
DamagedSprite.Draw(spriteBatch,
new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
color * Math.Min(damageOverlayStrength / 50.0f, 1.0f), ActiveSprite.Origin,
-body.DrawRotation,
1.0f, spriteEffect, depth);
// TODO: enable when the damage overlay textures have been remade.
//DamagedSprite.Draw(spriteBatch,
// new Vector2(body.DrawPosition.X, -body.DrawPosition.Y),
// color * Math.Min(damageOverlayStrength, 1.0f), ActiveSprite.Origin,
// -body.DrawRotation,
// 1.0f, spriteEffect, depth);
}
if (GameMain.DebugDraw)
@@ -415,6 +442,8 @@ namespace Barotrauma
Vector2 pos = ConvertUnits.ToDisplayUnits(pullJoint.WorldAnchorB);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)pos.X, (int)-pos.Y, 5, 5), Color.Red, true);
}
var bodyDrawPos = body.DrawPosition;
bodyDrawPos.Y = -bodyDrawPos.Y;
if (IsStuck)
{
Vector2 from = ConvertUnits.ToDisplayUnits(attachJoint.WorldAnchorA);
@@ -424,9 +453,7 @@ namespace Barotrauma
var localFront = body.GetLocalFront(MathHelper.ToRadians(limbParams.Ragdoll.SpritesheetOrientation));
var front = ConvertUnits.ToDisplayUnits(body.FarseerBody.GetWorldPoint(localFront));
front.Y = -front.Y;
var drawPos = body.DrawPosition;
drawPos.Y = -drawPos.Y;
GUI.DrawLine(spriteBatch, drawPos, front, Color.Yellow, width: 2);
GUI.DrawLine(spriteBatch, bodyDrawPos, front, Color.Yellow, width: 2);
GUI.DrawLine(spriteBatch, from, to, Color.Red, width: 1);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)from.X, (int)from.Y, 12, 12), Color.White, true);
GUI.DrawRectangle(spriteBatch, new Rectangle((int)to.X, (int)to.Y, 12, 12), Color.White, true);
@@ -440,7 +467,19 @@ namespace Barotrauma
//mainLimbDrawPos.Y = -mainLimbDrawPos.Y;
//GUI.DrawLine(spriteBatch, mainLimbDrawPos, mainLimbFront, Color.White, width: 5);
//GUI.DrawRectangle(spriteBatch, new Rectangle((int)mainLimbFront.X, (int)mainLimbFront.Y, 10, 10), Color.Yellow, true);
}
foreach (var modifier in damageModifiers)
{
//float midAngle = MathUtils.GetMidAngle(modifier.ArmorSector.X, modifier.ArmorSector.Y);
//float spritesheetOrientation = MathHelper.ToRadians(limbParams.Ragdoll.SpritesheetOrientation);
//float offset = -body.Rotation - (midAngle + spritesheetOrientation) * Dir;
float offset = GetArmorSectorRotationOffset(modifier.ArmorSector, -body.Rotation);
Vector2 forward = Vector2.Transform(-Vector2.UnitY, Matrix.CreateRotationZ(offset));
float size = ConvertUnits.ToDisplayUnits(body.GetSize().Length() / 2);
color = modifier.DamageMultiplier > 1 ? Color.Red : Color.GreenYellow;
GUI.DrawLine(spriteBatch, bodyDrawPos, bodyDrawPos + Vector2.Normalize(forward) * size, color, width: (int)Math.Round(4 / cam.Zoom));
if (Dir == -1) { offset += MathHelper.Pi; }
ShapeExtensions.DrawSector(spriteBatch, bodyDrawPos, size, GetArmorSectorSize(modifier.ArmorSector) * Dir, 40, color, offset + MathHelper.Pi, thickness: 2 / cam.Zoom);
}
}
}
@@ -521,6 +560,9 @@ namespace Barotrauma
DeformSprite?.Sprite?.Remove();
DeformSprite = null;
ConditionalSprites.ForEach(s => s.Remove());
ConditionalSprites.Clear();
LightSource?.Remove();
LightSource = null;

View File

@@ -7,6 +7,7 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Globalization;
@@ -14,13 +15,43 @@ namespace Barotrauma
{
static partial class DebugConsole
{
public partial class Command
{
/// <summary>
/// Executed when a client uses the command. If not set, the command is relayed to the server as-is.
/// </summary>
public Action<string[]> OnClientExecute;
public bool RelayToServer = true;
public void ClientExecute(string[] args)
{
if (!CheatsEnabled && IsCheat)
{
NewMessage("You need to enable cheats using the command \"enablecheats\" before you can use the command \"" + names[0] + "\".", Color.Red);
if (GameMain.Config.UseSteam)
{
NewMessage("Enabling cheats will disable Steam achievements during this play session.", Color.Red);
}
return;
}
if (OnClientExecute != null)
{
OnClientExecute(args);
}
else
{
OnExecute(args);
}
}
}
private static bool isOpen;
public static bool IsOpen => isOpen;
private static Queue<ColoredText> queuedMessages = new Queue<ColoredText>();
private static GUITextBlock activeQuestionText;
private static GUIFrame frame;
private static GUIListBox listBox;
private static GUITextBox textBox;
@@ -29,7 +60,7 @@ namespace Barotrauma
public static void Init()
{
frame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.45f), GUI.Canvas) { MinSize = new Point(400, 300), AbsoluteOffset = new Point(10, 10) },
frame = new GUIFrame(new RectTransform(new Vector2(0.5f, 0.45f), GUI.Canvas) { MinSize = new Point(400, 300), AbsoluteOffset = new Point(10, 10) },
color: new Color(0.4f, 0.4f, 0.4f, 0.8f));
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), frame.RectTransform, Anchor.Center), style: null);
@@ -116,7 +147,7 @@ namespace Barotrauma
}
else if (PlayerInput.KeyHit(Keys.Tab))
{
textBox.Text = AutoComplete(textBox.Text);
textBox.Text = AutoComplete(textBox.Text, increment: string.IsNullOrEmpty(currentAutoCompletedCommand) ? 0 : 1 );
}
if (PlayerInput.KeyHit(Keys.Enter))
@@ -211,7 +242,7 @@ namespace Barotrauma
selectedIndex = Messages.Count;
}
private static void AddHelpMessage(Command command)
static partial void ShowHelpMessage(Command command)
{
if (listBox.Content.CountChildren > MaxMessages)
{
@@ -233,15 +264,40 @@ namespace Barotrauma
textBlock.SetTextPos();
var nameBlock = new GUITextBlock(new RectTransform(new Point(150, textContainer.Rect.Height), textContainer.RectTransform),
command.names[0], textAlignment: Alignment.TopLeft);
listBox.UpdateScrollBarSize();
listBox.BarScroll = 1.0f;
selectedIndex = Messages.Count;
}
private static void AssignOnClientExecute(string names, Action<string[]> onClientExecute)
{
Command command = commands.First(c => c.names.Intersect(names.Split('|')).Count() > 0);
command.OnClientExecute = onClientExecute;
command.RelayToServer = false;
}
private static void AssignRelayToServer(string names, bool relay)
{
commands.First(c => c.names.Intersect(names.Split('|')).Count() > 0).RelayToServer = relay;
}
private static void InitProjectSpecific()
{
#if WINDOWS
commands.Add(new Command("copyitemnames", "", (string[] args) =>
{
StringBuilder sb = new StringBuilder();
foreach (MapEntityPrefab mp in MapEntityPrefab.List)
{
if (!(mp is ItemPrefab)) continue;
sb.AppendLine(mp.Name);
}
System.Windows.Clipboard.SetText(sb.ToString());
}));
#endif
commands.Add(new Command("autohull", "", (string[] args) =>
{
if (Screen.Selected != GameMain.SubEditorScreen) return;
@@ -249,10 +305,10 @@ namespace Barotrauma
if (MapEntity.mapEntityList.Any(e => e is Hull || e is Gap))
{
ShowQuestionPrompt("This submarine already has hulls and/or gaps. This command will delete them. Do you want to continue? Y/N",
(option) =>
(option) =>
{
ShowQuestionPrompt("The automatic hull generation may not work correctly if your submarine uses curved walls. Do you want to continue? Y/N",
(option2) =>
(option2) =>
{
if (option2.ToLower() == "y") { GameMain.SubEditorScreen.AutoHull(); }
});
@@ -271,8 +327,19 @@ namespace Barotrauma
if (GameMain.Client == null)
{
GameMain.NetworkMember = new GameClient("Name");
GameMain.Client.ConnectToServer(args[0]);
GameMain.Client = new GameClient("Name", args[0]);
}
}));
commands.Add(new Command("enablecheats", "enablecheats: Enables cheat commands and disables Steam achievements during this play session.", (string[] args) =>
{
CheatsEnabled = true;
SteamAchievementManager.CheatsEnabled = true;
NewMessage("Enabled cheat commands.", Color.Red);
if (GameMain.Config.UseSteam)
{
NewMessage("Steam achievements have been disabled during this play session.", Color.Red);
}
}));
@@ -323,41 +390,62 @@ namespace Barotrauma
GameMain.CharacterEditorScreen.Select();
}));
commands.Add(new Command("control|controlcharacter", "control [character name]: Start controlling the specified character.", (string[] args) =>
AssignRelayToServer("kick", false);
AssignRelayToServer("kickid", false);
AssignRelayToServer("ban", false);
AssignRelayToServer("banid", false);
AssignRelayToServer("dumpids", false);
AssignRelayToServer("findentityids", false);
AssignRelayToServer("campaigninfo", false);
AssignRelayToServer("help", false);
AssignRelayToServer("verboselogging", false);
AssignRelayToServer("freecam", false);
commands.Add(new Command("clientlist", "", (string[] args) => { }));
AssignRelayToServer("clientlist", true);
AssignOnExecute("control", (string[] args) =>
{
if (args.Length < 1) return;
var character = FindMatchingCharacter(args, true);
if (character != null)
{
Character.Controlled = character;
}
},
() =>
{
return new string[][]
{
Character.CharacterList.Select(c => c.Name).Distinct().ToArray()
};
}, isCheat: true));
});
AssignRelayToServer("control", true);
commands.Add(new Command("shake", "", (string[] args) =>
{
GameMain.GameScreen.Cam.Shake = 10.0f;
}));
commands.Add(new Command("los", "los: Toggle the line of sight effect on/off.", (string[] args) =>
{
GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
NewMessage("Line of sight effect " + (GameMain.LightManager.LosEnabled ? "enabled" : "disabled"), Color.White);
}, isCheat: true));
AssignOnExecute("los", (string[] args) =>
{
GameMain.LightManager.LosEnabled = !GameMain.LightManager.LosEnabled;
NewMessage("Line of sight effect " + (GameMain.LightManager.LosEnabled ? "enabled" : "disabled"), Color.White);
});
AssignRelayToServer("los", false);
commands.Add(new Command("lighting|lights", "Toggle lighting on/off.", (string[] args) =>
AssignOnExecute("lighting|lights", (string[] args) =>
{
GameMain.LightManager.LightingEnabled = !GameMain.LightManager.LightingEnabled;
NewMessage("Lighting " + (GameMain.LightManager.LightingEnabled ? "enabled" : "disabled"), Color.White);
}, isCheat: true));
});
AssignRelayToServer("lighting|lights", false);
AssignOnExecute("ambientlight", (string[] args) =>
{
if (Level.Loaded == null)
{
ThrowError("Could not set ambient light color (no level loaded).");
return;
}
Color color = XMLExtensions.ParseColor(string.Join("", args));
Level.Loaded.GenerationParams.AmbientLightColor = color;
NewMessage("Set ambient light color to " + color + ".", Color.White);
});
AssignRelayToServer("ambientlight", false);
commands.Add(new Command("multiplylights", "Multiplies the colors of all the static lights in the sub with the given Vector4 value (for example, 1,1,1,0.5).", (string[] args) =>
{
@@ -373,9 +461,9 @@ namespace Barotrauma
{
if (item.ParentInventory != null || item.body != null) continue;
var lightComponent = item.GetComponent<LightComponent>();
if (lightComponent != null) lightComponent.LightColor =
if (lightComponent != null) lightComponent.LightColor =
new Color(
(lightComponent.LightColor.R / 255.0f) * value.X,
(lightComponent.LightColor.R / 255.0f) * value.X,
(lightComponent.LightColor.G / 255.0f) * value.Y,
(lightComponent.LightColor.B / 255.0f) * value.Z,
(lightComponent.LightColor.A / 255.0f) * value.W);
@@ -434,7 +522,7 @@ namespace Barotrauma
}
}
}, isCheat: true));
commands.Add(new Command("alpha", "Change the alpha (as bytes from 0 to 255) of the selected item/structure instances. Applied only in the subeditor.", (string[] args) =>
{
if (Screen.Selected == GameMain.SubEditorScreen)
@@ -548,11 +636,12 @@ namespace Barotrauma
new GUIMessageBox("", string.Join(" ", args));
}));
commands.Add(new Command("debugdraw", "debugdraw: Toggle the debug drawing mode on/off.", (string[] args) =>
AssignOnExecute("debugdraw", (string[] args) =>
{
GameMain.DebugDraw = !GameMain.DebugDraw;
NewMessage("Debug draw mode " + (GameMain.DebugDraw ? "enabled" : "disabled"), Color.White);
}, isCheat: true));
});
AssignRelayToServer("debugdraw", false);
commands.Add(new Command("fpscounter", "fpscounter: Toggle the FPS counter.", (string[] args) =>
{
@@ -565,6 +654,12 @@ namespace Barotrauma
NewMessage("Performance statistics " + (GameMain.ShowPerf ? "enabled" : "disabled"), Color.White);
}));
AssignOnClientExecute("netstats", (string[] args) =>
{
if (GameMain.Client == null) return;
GameMain.Client.ShowNetStats = !GameMain.Client.ShowNetStats;
});
commands.Add(new Command("hudlayoutdebugdraw|debugdrawhudlayout", "hudlayoutdebugdraw: Toggle the debug drawing mode of HUD layout areas on/off.", (string[] args) =>
{
HUDLayoutSettings.DebugDraw = !HUDLayoutSettings.DebugDraw;
@@ -577,24 +672,72 @@ namespace Barotrauma
NewMessage("Interact debug draw mode " + (Character.DebugDrawInteract ? "enabled" : "disabled"), Color.White);
}, isCheat: true));
commands.Add(new Command("togglehud|hud", "togglehud/hud: Toggle the character HUD (inventories, icons, buttons, etc) on/off.", (string[] args) =>
AssignOnExecute("togglehud|hud", (string[] args) =>
{
GUI.DisableHUD = !GUI.DisableHUD;
GameMain.Instance.IsMouseVisible = !GameMain.Instance.IsMouseVisible;
NewMessage(GUI.DisableHUD ? "Disabled HUD" : "Enabled HUD", Color.White);
}));
});
AssignRelayToServer("togglehud|hud", false);
commands.Add(new Command("followsub", "followsub: Toggle whether the camera should follow the nearest submarine.", (string[] args) =>
AssignOnExecute("toggleupperhud", (string[] args) =>
{
GUI.DisableUpperHUD = !GUI.DisableUpperHUD;
NewMessage(GUI.DisableUpperHUD ? "Disabled upper HUD" : "Enabled upper HUD", Color.White);
});
AssignRelayToServer("toggleupperhud", false);
AssignOnExecute("toggleitemhighlights", (string[] args) =>
{
GUI.DisableItemHighlights = !GUI.DisableItemHighlights;
NewMessage(GUI.DisableItemHighlights ? "Disabled item highlights" : "Enabled item highlights", Color.White);
});
AssignRelayToServer("toggleitemhighlights", false);
AssignOnExecute("togglecharacternames", (string[] args) =>
{
GUI.DisableCharacterNames = !GUI.DisableCharacterNames;
NewMessage(GUI.DisableCharacterNames ? "Disabled character names" : "Enabled character names", Color.White);
});
AssignRelayToServer("togglecharacternames", false);
AssignOnExecute("followsub", (string[] args) =>
{
Camera.FollowSub = !Camera.FollowSub;
NewMessage(Camera.FollowSub ? "Set the camera to follow the closest submarine" : "Disabled submarine following.", Color.White);
}));
});
AssignRelayToServer("followsub", false);
commands.Add(new Command("toggleaitargets|aitargets", "toggleaitargets/aitargets: Toggle the visibility of AI targets (= targets that enemies can detect and attack/escape from).", (string[] args) =>
AssignOnExecute("toggleaitargets|aitargets", (string[] args) =>
{
AITarget.ShowAITargets = !AITarget.ShowAITargets;
NewMessage(AITarget.ShowAITargets ? "Enabled AI target drawing" : "Disabled AI target drawing", Color.White);
}, isCheat: true));
});
AssignRelayToServer("toggleaitargets|aitargets", false);
AssignRelayToServer("water|editwater", false);
AssignRelayToServer("fire|editfire", false);
commands.Add(new Command("mute", "mute [name]: Prevent the client from speaking to anyone through the voice chat. Using this command requires a permission from the server host.",
null,
() =>
{
if (GameMain.Client == null) return null;
return new string[][]
{
GameMain.Client.ConnectedClients.Select(c => c.Name).ToArray()
};
}));
commands.Add(new Command("unmute", "unmute [name]: Allow the client to speak to anyone through the voice chat. Using this command requires a permission from the server host.",
null,
() =>
{
if (GameMain.Client == null) return null;
return new string[][]
{
GameMain.Client.ConnectedClients.Select(c => c.Name).ToArray()
};
}));
commands.Add(new Command("checkcrafting", "checkcrafting: Checks item deconstruction & crafting recipes for inconsistencies.", (string[] args) =>
{
@@ -696,7 +839,6 @@ namespace Barotrauma
}
}, isCheat: false));
#if DEBUG
commands.Add(new Command("spamchatmessages", "", (string[] args) =>
{
@@ -707,11 +849,7 @@ namespace Barotrauma
for (int i = 0; i < msgCount; i++)
{
if (GameMain.Server != null)
{
GameMain.Server.SendChatMessage(ToolBox.RandomSeed(msgLength), ChatMessageType.Default);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
GameMain.Client.SendChatMessage(ToolBox.RandomSeed(msgLength));
}
@@ -739,7 +877,7 @@ namespace Barotrauma
Screen.Selected.Cam.MinZoom = minZoom;
Screen.Selected.Cam.MaxZoom = maxZoom;
}));
commands.Add(new Command("waterparams", "waterparams [distortionscalex] [distortionscaley] [distortionstrengthx] [distortionstrengthy] [bluramount]: default 0.5 0.5 0.5 0.5 1", (string[] args) =>
{
float distortScaleX = 0.5f, distortScaleY = 0.5f;
@@ -753,8 +891,7 @@ namespace Barotrauma
WaterRenderer.DistortionScale = new Vector2(distortScaleX, distortScaleY);
WaterRenderer.DistortionStrength = new Vector2(distortStrengthX, distortStrengthY);
WaterRenderer.BlurAmount = blurAmount;
},
null, null));
}));
commands.Add(new Command("refreshrect", "Updates the dimensions of the selected items to match the ones defined in the prefab. Applied only in the subeditor.", (string[] args) =>
@@ -767,13 +904,13 @@ namespace Barotrauma
ThrowError("You have to select item(s) first!");
}
else
{
{
foreach (var mapEntity in MapEntity.SelectedList)
{
if (mapEntity is Item item)
{
item.Rect = new Rectangle(item.Rect.X, item.Rect.Y,
(int)(item.Prefab.sprite.size.X * item.Prefab.Scale),
item.Rect = new Rectangle(item.Rect.X, item.Rect.Y,
(int)(item.Prefab.sprite.size.X * item.Prefab.Scale),
(int)(item.Prefab.sprite.size.Y * item.Prefab.Scale));
}
else if (mapEntity is Structure structure)
@@ -875,7 +1012,7 @@ namespace Barotrauma
destinationElement.AddAfterSelf(element);
}
XNode nextNode = destinationElement.NextNode;
while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode;
while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode;
destinationElement = nextNode as XElement;
}
destinationDoc.Save(destinationPath);
@@ -901,7 +1038,97 @@ namespace Barotrauma
}
File.WriteAllLines(filePath, lines);
}));
#if DEBUG
commands.Add(new Command("checkduplicates", "Checks the given language for duplicate translation keys and writes to file.", (string[] args) =>
{
if (args.Length != 1) return;
TextManager.CheckForDuplicates(args[0]);
}));
commands.Add(new Command("writetocsv", "Writes the default language (English) to a .csv file.", (string[] args) =>
{
TextManager.WriteToCSV();
NPCConversation.WriteToCSV();
}));
commands.Add(new Command("camerasettings", "camerasettings [defaultzoom] [zoomsmoothness] [movesmoothness] [minzoom] [maxzoom]: debug command for testing camera settings. The values default to 1.1, 8.0, 8.0, 0.1 and 2.0.", (string[] args) =>
{
float defaultZoom = Screen.Selected.Cam.DefaultZoom;
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out defaultZoom);
float zoomSmoothness = Screen.Selected.Cam.ZoomSmoothness;
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out zoomSmoothness);
float moveSmoothness = Screen.Selected.Cam.MoveSmoothness;
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out moveSmoothness);
float minZoom = Screen.Selected.Cam.MinZoom;
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out minZoom);
float maxZoom = Screen.Selected.Cam.MaxZoom;
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out maxZoom);
Screen.Selected.Cam.DefaultZoom = defaultZoom;
Screen.Selected.Cam.ZoomSmoothness = zoomSmoothness;
Screen.Selected.Cam.MoveSmoothness = moveSmoothness;
Screen.Selected.Cam.MinZoom = minZoom;
Screen.Selected.Cam.MaxZoom = maxZoom;
}));
commands.Add(new Command("waterparams", "waterparams [distortionscalex] [distortionscaley] [distortionstrengthx] [distortionstrengthy] [bluramount]: default 0.5 0.5 0.5 0.5 1", (string[] args) =>
{
float distortScaleX = 0.5f, distortScaleY = 0.5f;
float distortStrengthX = 0.5f, distortStrengthY = 0.5f;
float blurAmount = 0.0f;
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out distortScaleX);
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out distortScaleY);
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out distortStrengthX);
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out distortStrengthY);
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out blurAmount);
WaterRenderer.DistortionScale = new Vector2(distortScaleX, distortScaleY);
WaterRenderer.DistortionStrength = new Vector2(distortStrengthX, distortStrengthY);
WaterRenderer.BlurAmount = blurAmount;
},
null, null));
commands.Add(new Command("refreshrect", "Updates the dimensions of the selected items to match the ones defined in the prefab. Applied only in the subeditor.", (string[] args) =>
{
//TODO: maybe do this automatically during loading when possible?
if (Screen.Selected == GameMain.SubEditorScreen)
{
if (!MapEntity.SelectedAny)
{
ThrowError("You have to select item(s) first!");
}
else
{
foreach (var mapEntity in MapEntity.SelectedList)
{
if (mapEntity is Item item)
{
item.Rect = new Rectangle(item.Rect.X, item.Rect.Y,
(int)(item.Prefab.sprite.size.X * item.Prefab.Scale),
(int)(item.Prefab.sprite.size.Y * item.Prefab.Scale));
}
else if (mapEntity is Structure structure)
{
if (!structure.ResizeHorizontal)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
(int)structure.Prefab.ScaledSize.X,
structure.Rect.Height);
}
if (!structure.ResizeVertical)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
structure.Rect.Width,
(int)structure.Prefab.ScaledSize.Y);
}
}
}
}
}
}, isCheat: false));
#endif
commands.Add(new Command("cleanbuild", "", (string[] args) =>
{
@@ -924,7 +1151,7 @@ namespace Barotrauma
ThrowError("MasterServerUrl \"" + GameMain.Config.MasterServerUrl + "\"!");
}
GameMain.Config.Save();
GameMain.Config.SaveNewPlayerConfig();
var saveFiles = System.IO.Directory.GetFiles(SaveUtil.SaveFolder);
@@ -970,7 +1197,7 @@ namespace Barotrauma
NewMessage("Deleted TutorialSub from the submarine folder", Color.Green);
}
if (System.IO.File.Exists(GameServer.SettingsFile))
/*if (System.IO.File.Exists(GameServer.SettingsFile))
{
System.IO.File.Delete(GameServer.SettingsFile);
NewMessage("Deleted server settings", Color.Green);
@@ -980,7 +1207,7 @@ namespace Barotrauma
{
System.IO.File.Delete(GameServer.ClientPermissionsFile);
NewMessage("Deleted client permission file", Color.Green);
}
}*/
if (System.IO.File.Exists("crashreport.log"))
{
@@ -993,6 +1220,221 @@ namespace Barotrauma
ThrowError("TutorialSub.sub not found!");
}
}));
AssignOnClientExecute(
"giveperm",
(string[] args) =>
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out int id))
{
ThrowError("\"" + id + "\" is not a valid client ID.");
return;
}
NewMessage("Valid permissions are:", Color.White);
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
{
NewMessage(" - " + permission.ToString(), Color.White);
}
ShowQuestionPrompt("Permission to grant to client #" + id + "?", (perm) =>
{
GameMain.Client.SendConsoleCommand("giveperm " + id + " " + perm);
});
}
);
AssignOnClientExecute(
"revokeperm",
(string[] args) =>
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out int id))
{
ThrowError("\"" + id + "\" is not a valid client ID.");
return;
}
NewMessage("Valid permissions are:", Color.White);
foreach (ClientPermissions permission in Enum.GetValues(typeof(ClientPermissions)))
{
NewMessage(" - " + permission.ToString(), Color.White);
}
ShowQuestionPrompt("Permission to revoke from client #" + id + "?", (perm) =>
{
GameMain.Client.SendConsoleCommand("revokeperm " + id + " " + perm);
});
}
);
AssignOnClientExecute(
"giverank",
(string[] args) =>
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out int id))
{
ThrowError("\"" + id + "\" is not a valid client ID.");
return;
}
NewMessage("Valid ranks are:", Color.White);
foreach (PermissionPreset permissionPreset in PermissionPreset.List)
{
NewMessage(" - " + permissionPreset.Name, Color.White);
}
ShowQuestionPrompt("Rank to grant to client #" + id + "?", (rank) =>
{
GameMain.Client.SendConsoleCommand("giverank " + id + " " + rank);
});
}
);
AssignOnClientExecute(
"givecommandperm",
(string[] args) =>
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out int id))
{
ThrowError("\"" + id + "\" is not a valid client ID.");
return;
}
ShowQuestionPrompt("Console command permissions to grant to client #" + id + "? You may enter multiple commands separated with a space.", (commandNames) =>
{
GameMain.Client.SendConsoleCommand("givecommandperm " + id + " " + commandNames);
});
}
);
AssignOnClientExecute(
"revokecommandperm",
(string[] args) =>
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out int id))
{
ThrowError("\"" + id + "\" is not a valid client ID.");
return;
}
ShowQuestionPrompt("Console command permissions to revoke from client #" + id + "? You may enter multiple commands separated with a space.", (commandNames) =>
{
GameMain.Client.SendConsoleCommand("revokecommandperm " + id + " " + commandNames);
});
}
);
AssignOnClientExecute(
"showperm",
(string[] args) =>
{
if (args.Length < 1) return;
if (!int.TryParse(args[0], out int id))
{
ThrowError("\"" + id + "\" is not a valid client ID.");
return;
}
GameMain.Client.SendConsoleCommand("showperm " + id);
}
);
AssignOnClientExecute(
"banip",
(string[] args) =>
{
if (GameMain.Client == null || args.Length == 0) return;
ShowQuestionPrompt("Reason for banning the ip \"" + args[0] + "\"?", (reason) =>
{
ShowQuestionPrompt("Enter the duration of the ban (leave empty to ban permanently, or use the format \"[days] d [hours] h\")", (duration) =>
{
TimeSpan? banDuration = null;
if (!string.IsNullOrWhiteSpace(duration))
{
if (!TryParseTimeSpan(duration, out TimeSpan parsedBanDuration))
{
ThrowError("\"" + duration + "\" is not a valid ban duration. Use the format \"[days] d [hours] h\", \"[days] d\" or \"[hours] h\".");
return;
}
banDuration = parsedBanDuration;
}
GameMain.Client.SendConsoleCommand(
"banip " +
args[0] + " " +
(banDuration.HasValue ? banDuration.Value.TotalSeconds.ToString() : "0") + " " +
reason);
});
});
}
);
commands.Add(new Command("unban", "unban [name]: Unban a specific client.", (string[] args) =>
{
if (GameMain.Client == null || args.Length == 0) return;
string clientName = string.Join(" ", args);
GameMain.Client.UnbanPlayer(clientName, "");
}));
commands.Add(new Command("unbanip", "unbanip [ip]: Unban a specific IP.", (string[] args) =>
{
if (GameMain.Client == null || args.Length == 0) return;
GameMain.Client.UnbanPlayer("", args[0]);
}));
AssignOnClientExecute(
"campaigndestination|setcampaigndestination",
(string[] args) =>
{
var campaign = GameMain.GameSession?.GameMode as CampaignMode;
if (campaign == null)
{
ThrowError("No campaign active!");
return;
}
if (args.Length == 0)
{
int i = 0;
foreach (LocationConnection connection in campaign.Map.CurrentLocation.Connections)
{
NewMessage(" " + i + ". " + connection.OtherLocation(campaign.Map.CurrentLocation).Name, Color.White);
i++;
}
ShowQuestionPrompt("Select a destination (0 - " + (campaign.Map.CurrentLocation.Connections.Count - 1) + "):", (string selectedDestination) =>
{
int destinationIndex = -1;
if (!int.TryParse(selectedDestination, out destinationIndex)) return;
if (destinationIndex < 0 || destinationIndex >= campaign.Map.CurrentLocation.Connections.Count)
{
NewMessage("Index out of bounds!", Color.Red);
return;
}
GameMain.Client.SendConsoleCommand("campaigndestination " + destinationIndex);
});
}
else
{
int destinationIndex = -1;
if (!int.TryParse(args[0], out destinationIndex)) return;
if (destinationIndex < 0 || destinationIndex >= campaign.Map.CurrentLocation.Connections.Count)
{
NewMessage("Index out of bounds!", Color.Red);
return;
}
GameMain.Client.SendConsoleCommand("campaigndestination " + destinationIndex);
}
}
);
commands.Add(new Command("limbscale", "Define the limbscale for the controlled character. Provide id or name if you want to target another character. Note: the changes are not saved!", (string[] args) =>
{

View File

@@ -178,11 +178,12 @@ namespace EventInput
private static void ReceiveInput(object sender, TextInputEventArgs e)
{
OnCharEntered(e.Character);
KeyDown?.Invoke(sender, new KeyEventArgs(e.Key));
}
public static void OnCharEntered(char character)
{
if (CharEntered != null) CharEntered(null, new CharacterEventArgs(character, 0));
CharEntered?.Invoke(null, new CharacterEventArgs(character, 0));
}
#if WINDOWS
static IntPtr HookProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)

View File

@@ -27,7 +27,7 @@ namespace EventInput
EventInput.KeyDown += EventInput_KeyDown;
}
void EventInput_KeyDown(object sender, KeyEventArgs e)
public void EventInput_KeyDown(object sender, KeyEventArgs e)
{
if (_subscriber == null)
return;
@@ -74,6 +74,7 @@ namespace EventInput
get { return _subscriber; }
set
{
if (_subscriber == value) return;
if (_subscriber != null)
_subscriber.Selected = false;
_subscriber = value;

View File

@@ -17,8 +17,9 @@ namespace Barotrauma
Vector2 drawPos = ev.DebugDrawPos;
drawPos.Y = -drawPos.Y;
GUI.SubmarineIcon.Draw(spriteBatch, drawPos, Color.White * 0.5f, GUI.SubmarineIcon.size / 2, 0.0f, 40.0f);
GUI.DrawString(spriteBatch, drawPos, ev.ToString(), Color.White, Color.Black, 0, GUI.LargeFont);
var textOffset = new Vector2(-150, 0);
ShapeExtensions.DrawCircle(spriteBatch, drawPos, 600, 6, Color.White, thickness: 20);
GUI.DrawString(spriteBatch, drawPos + textOffset, ev.ToString(), Color.White, Color.Black, 0, GUI.LargeFont);
}
}

View File

@@ -0,0 +1,22 @@
namespace Barotrauma
{
partial class CombatMission
{
public override string Description
{
get
{
if (descriptions == null) return "";
if (GameMain.Client?.Character == null)
{
//non-team-specific description
return descriptions[0];
}
//team specific
return descriptions[GameMain.Client.Character.TeamID == Character.TeamType.Team1 ? 1 : 2];
}
}
}
}

View File

@@ -11,7 +11,8 @@ namespace Barotrauma
string header = index < Headers.Count ? Headers[index] : "";
string message = index < Messages.Count ? Messages[index] : "";
GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
//TODO: reimplement
//GameServer.Log(TextManager.Get("MissionInfo") + ": " + header + " - " + message, ServerLog.MessageType.ServerMessage);
new GUIMessageBox(header, message);
}

View File

@@ -9,8 +9,10 @@
var missionMsg = new GUIMessageBox(mission.Name, mission.Description, 400, 400);
missionMsg.UserData = "missionstartmessage";
#if SERVER
Networking.GameServer.Log(TextManager.Get("Mission") + ": " + mission.Name, Networking.ServerLog.MessageType.ServerMessage);
Networking.GameServer.Log(mission.Description, Networking.ServerLog.MessageType.ServerMessage);
#endif
}
}
}

View File

@@ -172,7 +172,7 @@ namespace Barotrauma
float prevSize = chatBox.BarSize;
string displayedText = message.Text;
string displayedText = message.TranslatedText;
string senderName = "";
if (!string.IsNullOrWhiteSpace(message.SenderName))
{
@@ -245,7 +245,7 @@ namespace Barotrauma
if ((prevSize == 1.0f && chatBox.BarScroll == 0.0f) || (prevSize < 1.0f && chatBox.BarScroll == 1.0f)) chatBox.BarScroll = 1.0f;
GUISoundType soundType = GUISoundType.Message;
GUISoundType soundType = GUISoundType.ChatMessage;
if (message.Type == ChatMessageType.Radio)
{
soundType = GUISoundType.RadioMessage;

View File

@@ -13,7 +13,8 @@ namespace Barotrauma
{
public enum GUISoundType
{
Message,
UIMessage,
ChatMessage,
RadioMessage,
DeadMessage,
Click,
@@ -58,7 +59,7 @@ namespace Barotrauma
private static GUIFrame pauseMenu;
private static Sprite arrow, lockIcon, checkmarkIcon, timerIcon;
public static KeyboardDispatcher KeyboardDispatcher { get; private set; }
public static KeyboardDispatcher KeyboardDispatcher { get; set; }
/// <summary>
/// Has the selected Screen changed since the last time the GUI was drawn.
@@ -131,12 +132,11 @@ namespace Barotrauma
set;
}
public static bool DisableHUD;
public static bool DisableHUD, DisableUpperHUD, DisableItemHighlights, DisableCharacterNames;
public static void Init(GameWindow window, IEnumerable<ContentPackage> selectedContentPackages, GraphicsDevice graphicsDevice)
{
GUI.graphicsDevice = graphicsDevice;
KeyboardDispatcher = new KeyboardDispatcher(window);
var uiStyles = ContentPackage.GetFilesOfType(selectedContentPackages, ContentType.UIStyle).ToList();
if (uiStyles.Count == 0)
{
@@ -157,14 +157,15 @@ namespace Barotrauma
{
sounds = new Sound[Enum.GetValues(typeof(GUISoundType)).Length];
sounds[(int)GUISoundType.Message] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/UImsg.ogg", false);
sounds[(int)GUISoundType.RadioMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/radiomsg.ogg", false);
sounds[(int)GUISoundType.DeadMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/deadmsg.ogg", false);
sounds[(int)GUISoundType.Click] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/beep-shinymetal.ogg", false);
sounds[(int)GUISoundType.UIMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/UImsg.ogg", false);
sounds[(int)GUISoundType.ChatMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/ChatMsg.ogg", false);
sounds[(int)GUISoundType.RadioMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/RadioMsg.ogg", false);
sounds[(int)GUISoundType.DeadMessage] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/DeadMsg.ogg", false);
sounds[(int)GUISoundType.Click] = GameMain.SoundManager.LoadSound("Content/Sounds/UI/Click.ogg", false);
sounds[(int)GUISoundType.PickItem] = GameMain.SoundManager.LoadSound("Content/Sounds/pickItem.ogg", false);
sounds[(int)GUISoundType.PickItemFail] = GameMain.SoundManager.LoadSound("Content/Sounds/pickItemFail.ogg", false);
sounds[(int)GUISoundType.DropItem] = GameMain.SoundManager.LoadSound("Content/Sounds/dropItem.ogg", false);
sounds[(int)GUISoundType.PickItem] = GameMain.SoundManager.LoadSound("Content/Sounds/PickItem.ogg", false);
sounds[(int)GUISoundType.PickItemFail] = GameMain.SoundManager.LoadSound("Content/Sounds/PickItemFail.ogg", false);
sounds[(int)GUISoundType.DropItem] = GameMain.SoundManager.LoadSound("Content/Sounds/DropItem.ogg", false);
}
// create 1x1 texture for line drawing
t = new Texture2D(GraphicsDevice, 1, 1);
@@ -290,7 +291,7 @@ namespace Barotrauma
{
Color clr = Color.White;
string soundStr = i + ": ";
SoundChannel playingSoundChannel = GameMain.SoundManager.GetSoundChannelFromIndex(i);
SoundChannel playingSoundChannel = GameMain.SoundManager.GetSoundChannelFromIndex(SoundManager.SourcePoolIndex.Default, i);
if (playingSoundChannel == null)
{
soundStr += "none";
@@ -363,7 +364,7 @@ namespace Barotrauma
if (HUDLayoutSettings.DebugDraw) HUDLayoutSettings.Draw(spriteBatch);
if (GameMain.NetworkMember != null) GameMain.NetworkMember.Draw(spriteBatch);
if (GameMain.Client != null) GameMain.Client.Draw(spriteBatch);
if (Character.Controlled?.Inventory != null)
{
@@ -1527,10 +1528,10 @@ namespace Barotrauma
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
}
if (GameMain.NetworkMember != null)
if (GameMain.Client != null)
{
GameMain.NetworkMember.Disconnect();
GameMain.NetworkMember = null;
GameMain.Client.Disconnect();
GameMain.Client = null;
}
CoroutineManager.StopCoroutines("EndCinematic");
@@ -1563,13 +1564,13 @@ namespace Barotrauma
{
if (messages.Any(msg => msg.Text == message)) { return; }
messages.Add(new GUIMessage(message, color, lifeTime ?? MathHelper.Clamp(message.Length / 5.0f, 3.0f, 10.0f), font ?? LargeFont));
if (playSound) PlayUISound(GUISoundType.Message);
if (playSound) PlayUISound(GUISoundType.UIMessage);
}
public static void AddMessage(string message, Color color, Vector2 worldPos, Vector2 velocity, float lifeTime = 3.0f, bool playSound = true)
{
messages.Add(new GUIMessage(message, color, worldPos, velocity, lifeTime, Alignment.Center, LargeFont));
if (playSound) PlayUISound(GUISoundType.Message);
if (playSound) PlayUISound(GUISoundType.UIMessage);
}
public static void ClearMessages()

View File

@@ -36,6 +36,12 @@ namespace Barotrauma
set { listBox.Enabled = value; }
}
public bool ButtonEnabled
{
get { return button.Enabled; }
set { button.Enabled = value; }
}
public GUIComponent Selected
{
get { return listBox.SelectedComponent; }

View File

@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
namespace Barotrauma
{
public class GUIRadioButtonGroup : GUIComponent
{
private Dictionary<Enum, GUITickBox> radioButtons; //TODO: use children list instead?
public GUIRadioButtonGroup() : base("GUIFrame")
{
radioButtons = new Dictionary<Enum, GUITickBox>();
}
public void AddRadioButton(Enum key, GUITickBox radioButton)
{
if (selected == key) radioButton.Selected = true;
else if (radioButton.Selected) selected = key;
radioButton.SetRadioButtonGroup(this);
radioButtons.Add(key, radioButton);
}
public delegate void RadioButtonGroupDelegate(GUIRadioButtonGroup rbg, Enum val);
public RadioButtonGroupDelegate OnSelect = null;
public void SelectRadioButton(GUITickBox radioButton)
{
foreach (KeyValuePair<Enum, GUITickBox> rbPair in radioButtons)
{
if (radioButton == rbPair.Value)
{
Selected = rbPair.Key;
return;
}
}
}
private Enum selected;
public Enum Selected
{
get
{
return selected;
}
set
{
OnSelect?.Invoke(this, value);
if (selected != null && selected.Equals((Enum)value)) return;
selected = value;
foreach (KeyValuePair<Enum, GUITickBox> radioButton in radioButtons)
{
if (radioButton.Key.Equals((Enum)value))
{
radioButton.Value.Selected = true;
}
else if (radioButton.Value.Selected) radioButton.Value.Selected = false;
}
}
}
public GUITickBox SelectedRadioButton
{
get
{
return radioButtons[selected];
}
}
}
}

View File

@@ -20,6 +20,7 @@ namespace Barotrauma
public delegate bool OnMovedHandler(GUIScrollBar scrollBar, float barScroll);
public OnMovedHandler OnMoved;
public OnMovedHandler OnReleased;
public bool IsBooleanSwitch;
@@ -87,6 +88,39 @@ namespace Barotrauma
}
}
private Vector2 range;
public Vector2 Range
{
get
{
return range;
}
set
{
float oldBarScrollValue = BarScrollValue;
range = value;
BarScrollValue = oldBarScrollValue;
}
}
public delegate float ScrollConversion(GUIScrollBar scrollBar, float f);
public ScrollConversion ScrollToValue = null;
public ScrollConversion ValueToScroll = null;
public float BarScrollValue
{
get
{
if (ScrollToValue==null) return (BarScroll * (Range.Y - Range.X)) + Range.X;
return ScrollToValue(this, BarScroll);
}
set
{
if (ValueToScroll==null) BarScroll = (value - Range.X) / (Range.Y - Range.X);
else BarScroll = ValueToScroll(this, value);
}
}
public float BarScroll
{
get { return step == 0.0f ? barScroll : MathUtils.RoundTowardsClosest(barScroll, step); }
@@ -187,7 +221,11 @@ namespace Barotrauma
if (draggingBar == this)
{
if (!PlayerInput.LeftButtonHeld()) draggingBar = null;
if (!PlayerInput.LeftButtonHeld())
{
OnReleased?.Invoke(this, BarScroll);
draggingBar = null;
}
if ((isHorizontal && PlayerInput.MousePosition.X > Rect.X && PlayerInput.MousePosition.X < Rect.Right) ||
(!isHorizontal && PlayerInput.MousePosition.Y > Rect.Y && PlayerInput.MousePosition.Y < Rect.Bottom))
{
@@ -198,6 +236,7 @@ namespace Barotrauma
{
if (PlayerInput.LeftButtonClicked())
{
draggingBar?.OnReleased?.Invoke(draggingBar, draggingBar.BarScroll);
MoveButton(new Vector2(
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width,
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height));

View File

@@ -1,5 +1,6 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace Barotrauma
{
@@ -216,25 +217,36 @@ namespace Barotrauma
if (autoScale && textScale > 0.1f &&
(TextSize.X * textScale > rect.Width - padding.X - padding.Z || TextSize.Y * textScale > rect.Height - padding.Y - padding.W))
{
TextScale -= 0.05f;
TextScale = Math.Max(0.1f, Math.Min(
(rect.Width - padding.X - padding.Z) / TextSize.X,
(rect.Height - padding.Y - padding.W) / TextSize.Y)) - 0.01f;
return;
}
textPos = new Vector2(rect.Width / 2.0f, rect.Height / 2.0f);
origin = TextSize / textScale * 0.5f;
origin = TextSize * 0.5f;
if (textAlignment.HasFlag(Alignment.Left) && !overflowClipActive)
origin.X += (rect.Width / 2.0f - TextSize.X / 2) / textScale - padding.X;
{
textPos.X = padding.X;
origin.X = 0;
}
if (textAlignment.HasFlag(Alignment.Right) || overflowClipActive)
origin.X -= (rect.Width / 2.0f - TextSize.X / 2) / textScale - padding.Z;
{
textPos.X = rect.Width - padding.Z;
origin.X = TextSize.X;
}
if (textAlignment.HasFlag(Alignment.Top))
origin.Y += (rect.Height / 2.0f - TextSize.Y / 2) / textScale - padding.Y;
{
textPos.Y = padding.Y;
origin.Y = 0;
}
if (textAlignment.HasFlag(Alignment.Bottom))
origin.Y -= (rect.Height / 2.0f - TextSize.Y / 2) / textScale - padding.W;
{
textPos.Y = rect.Height - padding.W;
origin.Y = TextSize.Y;
}
origin.X = (int)(origin.X);
origin.Y = (int)(origin.Y);

View File

@@ -15,7 +15,7 @@ namespace Barotrauma
{
public event TextBoxEvent OnSelected;
public event TextBoxEvent OnDeselected;
bool caretVisible;
float caretTimer;
@@ -76,10 +76,24 @@ namespace Barotrauma
set { textBlock.TextGetter = value; }
}
private bool selected;
public bool Selected
{
get;
set;
get
{
return selected;
}
set
{
if (!selected && value)
{
Select();
}
else if (selected && !value)
{
Deselect();
}
}
}
public bool Wrap
@@ -326,9 +340,9 @@ namespace Barotrauma
{
memento.Store(Text);
}
Selected = true;
CaretIndex = GetCaretIndexFromScreenPos(PlayerInput.MousePosition);
ClearSelection();
selected = true;
GUI.KeyboardDispatcher.Subscriber = this;
OnSelected?.Invoke(this, Keys.None);
}
@@ -336,7 +350,8 @@ namespace Barotrauma
public void Deselect()
{
memento.Clear();
Selected = false;
selected = false;
if (GUI.KeyboardDispatcher.Subscriber == this)
{
GUI.KeyboardDispatcher.Subscriber = null;
@@ -382,6 +397,7 @@ namespace Barotrauma
}
else
{
if (PlayerInput.LeftButtonClicked() && selected) Deselect();
isSelecting = false;
state = ComponentState.None;
}

View File

@@ -14,7 +14,7 @@ namespace Barotrauma
public static int size = 20;
private List<GUITickBox> radioButtonGroup;
private GUIRadioButtonGroup radioButtonGroup;
private bool selected;
@@ -24,30 +24,21 @@ namespace Barotrauma
set
{
if (value == selected) return;
if (radioButtonGroup != null && !value) return;
if (radioButtonGroup != null && radioButtonGroup.SelectedRadioButton == this)
{
selected = true;
return;
}
selected = value;
state = (selected) ? ComponentState.Selected : ComponentState.None;
box.State = state;
if (radioButtonGroup != null)
if (value && radioButtonGroup != null)
{
foreach (GUITickBox tickBox in radioButtonGroup)
{
if (tickBox == this) continue;
tickBox.selected = false;
tickBox.state = tickBox.box.State = ComponentState.None;
}
radioButtonGroup.SelectRadioButton(this);
}
OnSelected?.Invoke(this);
if (radioButtonGroup != null)
{
foreach (GUITickBox tickBox in radioButtonGroup)
{
if (tickBox == this) continue;
tickBox.OnSelected?.Invoke(tickBox);
}
}
}
}
@@ -123,14 +114,10 @@ namespace Barotrauma
rectT.ScaleChanged += ResizeBox;
rectT.SizeChanged += ResizeBox;
}
public static void CreateRadioButtonGroup(IEnumerable<GUITickBox> tickBoxes)
public void SetRadioButtonGroup(GUIRadioButtonGroup rbg)
{
var group = new List<GUITickBox>(tickBoxes);
foreach (GUITickBox tickBox in tickBoxes)
{
tickBox.radioButtonGroup = group;
}
radioButtonGroup = rbg;
}
private void ResizeBox()

View File

@@ -140,8 +140,8 @@ namespace Barotrauma
}
AfflictionAreaRight = new Rectangle(HealthBarAreaRight.X, HealthBarAreaRight.Y - Padding - afflictionAreaHeight, healthBarWidth, afflictionAreaHeight);
int messageAreaPos = GameMain.GraphicsWidth - HealthBarAreaRight.X;
MessageAreaTop = new Rectangle(messageAreaPos + Padding, ButtonAreaTop.Bottom, GameMain.GraphicsWidth - (messageAreaPos + Padding) * 2, ButtonAreaTop.Height);
int messageAreaWidth = GameMain.GraphicsWidth / 3;
MessageAreaTop = new Rectangle((GameMain.GraphicsWidth - messageAreaWidth) / 2, ButtonAreaTop.Bottom, messageAreaWidth, ButtonAreaTop.Height);
//slice for the upper slots of the inventory (clothes, id card, headset)
int inventoryAreaUpperWidth = (int)(GameMain.GraphicsWidth * 0.2f);

View File

@@ -1,10 +1,10 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System;
using System.Collections.Generic;
using System.Xml.Linq;
using Barotrauma.Media;
namespace Barotrauma
{
@@ -14,6 +14,25 @@ namespace Barotrauma
private RenderTarget2D renderTarget;
private Video splashScreen;
public Video SplashScreen
{
get
{
lock (loadMutex)
{
return splashScreen;
}
}
set
{
lock (loadMutex)
{
splashScreen = value;
}
}
}
private float state;
private string selectedTip;
@@ -22,11 +41,9 @@ namespace Barotrauma
public Vector2 TitlePosition;
private object loadMutex = new object();
private float? loadState;
#if !(LINUX || OSX)
Video splashScreenVideo;
VideoPlayer videoPlayer;
#endif
public Vector2 TitleSize
{
get { return new Vector2(titleTexture.Width, titleTexture.Height); }
@@ -40,15 +57,20 @@ namespace Barotrauma
public float? LoadState
{
get { return loadState; }
get
{
lock (loadMutex)
{
return loadState;
}
}
set
{
loadState = value;
if (GameSettings.VerboseLogging)
lock (loadMutex)
{
DebugConsole.NewMessage("Loading: " + value.ToString() + "%", Color.Yellow);
loadState = value;
DrawLoadingText = true;
}
DrawLoadingText = true;
}
}
@@ -60,24 +82,6 @@ namespace Barotrauma
public LoadingScreen(GraphicsDevice graphics)
{
#if !(LINUX || OSX)
if (GameMain.Config.EnableSplashScreen)
{
try
{
splashScreenVideo = GameMain.Instance.Content.Load<Video>("splashscreen");
}
catch (Exception e)
{
DebugConsole.ThrowError("Failed to load splashscreen", e);
GameMain.Config.EnableSplashScreen = false;
}
}
#endif
backgroundTexture = TextureLoader.FromFile("Content/UI/titleBackground.png");
monsterTexture = TextureLoader.FromFile("Content/UI/titleMonster.png");
titleTexture = TextureLoader.FromFile("Content/UI/titleText.png");
@@ -96,14 +100,12 @@ namespace Barotrauma
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
{
#if !(LINUX || OSX)
if (GameMain.Config.EnableSplashScreen && splashScreenVideo != null)
if (GameMain.Config.EnableSplashScreen)
{
try
{
DrawSplashScreen(spriteBatch);
if (videoPlayer != null && videoPlayer.State == MediaState.Playing)
return;
if (SplashScreen!=null && SplashScreen.IsPlaying) return;
}
catch (Exception e)
{
@@ -111,7 +113,6 @@ namespace Barotrauma
GameMain.Config.EnableSplashScreen = false;
}
}
#endif
drawn = true;
@@ -162,16 +163,16 @@ namespace Barotrauma
if (DrawLoadingText)
{
string loadText = "";
if (loadState == 100.0f)
if (LoadState == 100.0f)
{
loadText = TextManager.Get("PressAnyKey");
}
else
{
loadText = TextManager.Get("Loading");
if (loadState != null)
if (LoadState != null)
{
loadText += " " + (int)loadState + " %";
loadText += " " + (int)LoadState + " %";
}
}
@@ -198,56 +199,27 @@ namespace Barotrauma
}
#if !(LINUX || OSX)
private void DrawSplashScreen(SpriteBatch spriteBatch)
{
bool vsync = GameMain.Config.VSyncEnabled;
if (videoPlayer == null)
if (SplashScreen != null)
{
// Enforce the vsync so that the video player doesn't eat all the vram
if (!GameMain.Config.VSyncEnabled)
if (SplashScreen.IsPlaying)
{
GameMain.Config.VSyncEnabled = true;
GameMain.Instance.ApplyGraphicsSettings();
}
videoPlayer = new VideoPlayer();
videoPlayer.Play(splashScreenVideo);
videoPlayer.Volume = GameMain.Config.SoundVolume;
}
else
{
Texture2D videoTexture = null;
if (videoPlayer.State == MediaState.Stopped)
{
videoPlayer.Dispose();
videoPlayer = null;
splashScreenVideo.Dispose();
splashScreenVideo = null;
// If the vsync was enforced, restore the user preference
if (GameMain.Config.VSyncEnabled != vsync)
{
GameMain.Config.VSyncEnabled = vsync;
GameMain.Instance.ApplyGraphicsSettings();
}
}
else
{
videoTexture = videoPlayer.GetTexture();
spriteBatch.Begin();
spriteBatch.Draw(videoTexture, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.Draw(SplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
spriteBatch.End();
if (PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.LeftButtonDown())
{
videoPlayer.Stop();
SplashScreen.Dispose(); SplashScreen = null;
}
}
}
else
{
SplashScreen.Dispose(); SplashScreen = null;
}
}
}
#endif
bool drawn;
public IEnumerable<object> DoLoading(IEnumerable<object> loader)
@@ -270,7 +242,7 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
}
loadState = 100.0f;
LoadState = 100.0f;
yield return CoroutineStatus.Success;
}

View File

@@ -64,7 +64,7 @@ namespace Barotrauma
var length = Vector2.Distance(point1, point2);
var angle = (float)Math.Atan2(point2.Y - point1.Y, point2.X - point1.X);
var scale = new Vector2(length, thickness);
spriteBatch.Draw(texture, point1, color: color, rotation: angle, scale: scale);
spriteBatch.Draw(GetTexture(spriteBatch), point1, null, color, angle, Vector2.Zero, scale, SpriteEffects.None, 0);
}
/// <summary>
@@ -117,7 +117,7 @@ namespace Barotrauma
{
var scale = Vector2.One * size;
var offset = new Vector2(0.5f) - new Vector2(size * 0.5f);
spriteBatch.Draw(GetTexture(spriteBatch), position + offset, color: color, scale: scale);
spriteBatch.Draw(GetTexture(spriteBatch), position + offset, null, color, 0.0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
}
public static void DrawCircle(this SpriteBatch spriteBatch, Vector2 center, float radius, int sides, Color color,

View File

@@ -15,6 +15,7 @@ using GameAnalyticsSDK.Net;
using System.IO;
using System.Threading;
using Barotrauma.Tutorials;
using Barotrauma.Media;
namespace Barotrauma
{
@@ -23,7 +24,7 @@ namespace Barotrauma
public static bool ShowFPS = false;
public static bool ShowPerf = false;
public static bool DebugDraw;
public static bool IsMultiplayer => Client != null || Server != null;
public static bool IsMultiplayer => NetworkMember != null;
public static PerformanceCounter PerformanceCounter;
@@ -37,10 +38,10 @@ namespace Barotrauma
public static ServerListScreen ServerListScreen;
public static SteamWorkshopScreen SteamWorkshopScreen;
public static SubEditorScreen SubEditorScreen;
public static ParticleEditorScreen ParticleEditorScreen;
public static LevelEditorScreen LevelEditorScreen;
public static SpriteEditorScreen SpriteEditorScreen;
public static SubEditorScreen SubEditorScreen;
public static ParticleEditorScreen ParticleEditorScreen;
public static LevelEditorScreen LevelEditorScreen;
public static SpriteEditorScreen SpriteEditorScreen;
public static CharacterEditorScreen CharacterEditorScreen;
public static Lights.LightManager LightManager;
@@ -60,7 +61,7 @@ namespace Barotrauma
if (vanillaContent == null)
{
// TODO: Dynamic method for defining and finding the vanilla content package.
vanillaContent = SelectedPackages.Single(cp => Path.GetFileName(cp.Path).ToLowerInvariant() == "vanilla 0.9.xml");
vanillaContent = SelectedPackages.SingleOrDefault(cp => Path.GetFileName(cp.Path).ToLowerInvariant() == "vanilla 0.9.xml");
}
return vanillaContent;
}
@@ -81,8 +82,6 @@ namespace Barotrauma
}
}
public static NetworkMember NetworkMember;
public static ParticleManager ParticleManager;
public static DecalManager DecalManager;
@@ -115,9 +114,7 @@ namespace Barotrauma
get;
private set;
}
private static bool FullscreenOnTabIn;
public static WindowMode WindowMode
{
get;
@@ -141,15 +138,13 @@ namespace Barotrauma
get { return Instance == null || Instance.IsActive; }
}
public static GameServer Server
public static GameClient Client;
public static NetworkMember NetworkMember
{
get { return NetworkMember as GameServer; }
get { return Client; }
}
public static GameClient Client
{
get { return NetworkMember as GameClient; }
}
public static Process ServerChildProcess;
public static RasterizerState ScissorTestEnable
{
@@ -170,15 +165,9 @@ namespace Barotrauma
Instance = this;
Config = new GameSettings("config.xml");
if (Config.WasGameUpdated)
{
UpdaterUtil.CleanOldFiles();
Config.WasGameUpdated = false;
Config.Save();
}
ApplyGraphicsSettings();
Config = new GameSettings();
GUI.KeyboardDispatcher = new EventInput.KeyboardDispatcher(Window);
Content.RootDirectory = "Content";
@@ -186,9 +175,9 @@ namespace Barotrauma
IsFixedTimeStep = false;
Timing.Accumulator = 0.0f;
GameMain.ResetFrameTime();
fixedTime = new GameTime();
World = new World(new Vector2(0, -9.82f));
FarseerPhysics.Settings.AllowSleep = true;
FarseerPhysics.Settings.ContinuousPhysics = false;
@@ -200,23 +189,17 @@ namespace Barotrauma
{
GraphicsWidth = Config.GraphicsWidth;
GraphicsHeight = Config.GraphicsHeight;
if (Config.WindowMode == WindowMode.BorderlessWindowed)
{
GraphicsWidth = GraphicsDevice.DisplayMode.Width;
GraphicsHeight = GraphicsDevice.DisplayMode.Height;
}
GraphicsDeviceManager.GraphicsProfile = GraphicsProfile.Reach;
GraphicsDeviceManager.PreferredBackBufferFormat = SurfaceFormat.Color;
GraphicsDeviceManager.PreferMultiSampling = false;
GraphicsDeviceManager.SynchronizeWithVerticalRetrace = Config.VSyncEnabled;
if (Config.WindowMode == WindowMode.Windowed)
{
//for whatever reason, window isn't centered automatically
//since MonoGame 3.6 (nuget package might be broken), so
//let's do it manually
Window.Position = new Point((GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width - GraphicsWidth) / 2,
(GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height - GraphicsHeight) / 2);
}
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
SetWindowMode(Config.WindowMode);
defaultViewport = GraphicsDevice.Viewport;
@@ -236,6 +219,9 @@ namespace Barotrauma
GraphicsDeviceManager.IsFullScreen = Config.WindowMode == WindowMode.Fullscreen || Config.WindowMode == WindowMode.BorderlessWindowed;
Window.IsBorderless = !GraphicsDeviceManager.HardwareModeSwitch;
GraphicsDeviceManager.PreferredBackBufferWidth = GraphicsWidth;
GraphicsDeviceManager.PreferredBackBufferHeight = GraphicsHeight;
GraphicsDeviceManager.ApplyChanges();
}
@@ -253,7 +239,9 @@ namespace Barotrauma
protected override void Initialize()
{
base.Initialize();
ApplyGraphicsSettings();
ScissorTestEnable = new RasterizerState() { ScissorTestEnable = true };
Hyper.ComponentModel.HyperTypeDescriptionProvider.Add(typeof(Character));
@@ -270,7 +258,7 @@ namespace Barotrauma
{
GraphicsWidth = GraphicsDevice.Viewport.Width;
GraphicsHeight = GraphicsDevice.Viewport.Height;
ConvertUnits.SetDisplayUnitToSimUnitRatio(Physics.DisplayToSimRation);
spriteBatch = new SpriteBatch(GraphicsDevice);
@@ -279,39 +267,14 @@ namespace Barotrauma
loadingScreenOpen = true;
TitleScreen = new LoadingScreen(GraphicsDevice);
loadingCoroutine = CoroutineManager.StartCoroutine(Load());
bool canLoadInSeparateThread = false;
#if WINDOWS
var myForm = (System.Windows.Forms.Form)System.Windows.Forms.Form.FromHandle(Window.Handle);
myForm.Deactivate += new EventHandler(HandleDefocus);
myForm.Activated += new EventHandler(HandleFocus);
canLoadInSeparateThread = true;
#endif
loadingCoroutine = CoroutineManager.StartCoroutine(Load(), "", canLoadInSeparateThread);
}
private void HandleDefocus(object sender, EventArgs e)
{
if (GraphicsDeviceManager.IsFullScreen && GraphicsDeviceManager.HardwareModeSwitch)
{
GraphicsDeviceManager.IsFullScreen = false;
GraphicsDeviceManager.ApplyChanges();
FullscreenOnTabIn = true;
Thread.Sleep(500);
}
}
private void HandleFocus(object sender, EventArgs e)
{
if (FullscreenOnTabIn)
{
GraphicsDeviceManager.HardwareModeSwitch = true;
GraphicsDeviceManager.IsFullScreen = true;
GraphicsDeviceManager.ApplyChanges();
FullscreenOnTabIn = false;
Thread.Sleep(500);
}
}
private void InitUserStats()
{
if (GameSettings.ShowUserStatisticsPrompt)
@@ -326,6 +289,7 @@ namespace Barotrauma
GameSettings.ShowUserStatisticsPrompt = false;
GameSettings.SendUserStatistics = true;
GameAnalyticsManager.Init();
Config.SaveNewPlayerConfig();
return true;
};
userStatsPrompt.Buttons[0].OnClicked += userStatsPrompt.Close;
@@ -333,6 +297,7 @@ namespace Barotrauma
{
GameSettings.ShowUserStatisticsPrompt = false;
GameSettings.SendUserStatistics = false;
Config.SaveNewPlayerConfig();
return true;
};
userStatsPrompt.Buttons[1].OnClicked += userStatsPrompt.Close;
@@ -349,17 +314,29 @@ namespace Barotrauma
{
DebugConsole.NewMessage("LOADING COROUTINE", Color.Lime);
}
SoundManager = new Sounds.SoundManager();
SoundManager.SetCategoryGainMultiplier("default", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("ui", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("waterambience", Config.SoundVolume);
SoundManager.SetCategoryGainMultiplier("music", Config.MusicVolume);
if (Config.EnableSplashScreen)
{
(TitleScreen as LoadingScreen).SplashScreen = new Video(base.GraphicsDevice, SoundManager, "Content/splashscreen.mp4", 1280, 720);
}
GUI.Init(Window, Config.SelectedContentPackages, GraphicsDevice);
DebugConsole.Init();
SteamManager.Initialize();
if (Config.AutoUpdateWorkshopItems)
{
if (SteamManager.AutoUpdateWorkshopItems())
{
ContentPackage.LoadAll(ContentPackage.Folder);
Config.ReloadContentPackages();
}
}
if (SelectedPackages.Count == 0)
{
@@ -370,10 +347,16 @@ namespace Barotrauma
DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.Select(cp => cp.Name)));
}
#if DEBUG
GameSettings.ShowUserStatisticsPrompt = false;
GameSettings.SendUserStatistics = false;
#endif
InitUserStats();
yield return CoroutineStatus.Running;
LightManager = new Lights.LightManager(base.GraphicsDevice, Content);
WaterRenderer.Instance = new WaterRenderer(base.GraphicsDevice, Content);
@@ -382,6 +365,7 @@ namespace Barotrauma
GUI.LoadContent();
TitleScreen.LoadState = 2.0f;
yield return CoroutineStatus.Running;
MissionPrefab.Init();
@@ -416,20 +400,18 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
Debug.WriteLine("sounds");
var soundLoadingCoroutine = CoroutineManager.StartCoroutine(SoundPlayer.Init());
int i = 0;
while (!SoundPlayer.Initialized)
foreach (object crObj in SoundPlayer.Init())
{
if (soundLoadingCoroutine.Exception != null)
{
throw soundLoadingCoroutine.Exception;
}
CoroutineStatus status = (CoroutineStatus)crObj;
if (status == CoroutineStatus.Success) break;
i++;
TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
TitleScreen.LoadState = SoundPlayer.SoundCount == 0 ?
30.0f :
Math.Min(30.0f + 40.0f * i / Math.Max(SoundPlayer.SoundCount, 1), 70.0f);
yield return CoroutineStatus.Running;
}
@@ -439,15 +421,19 @@ namespace Barotrauma
GameModePreset.Init();
Submarine.RefreshSavedSubs();
TitleScreen.LoadState = 80.0f;
yield return CoroutineStatus.Running;
GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);
GameScreen = new GameScreen(GraphicsDeviceManager.GraphicsDevice, Content);
TitleScreen.LoadState = 90.0f;
yield return CoroutineStatus.Running;
MainMenuScreen = new MainMenuScreen(this);
LobbyScreen = new LobbyScreen();
MainMenuScreen = new MainMenuScreen(this);
LobbyScreen = new LobbyScreen();
ServerListScreen = new ServerListScreen();
if (SteamManager.USE_STEAM)
@@ -463,10 +449,13 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
TitleScreen.LoadState = 95.0f;
ParticleManager = new ParticleManager(GameScreen.Cam);
ParticleManager.LoadPrefabs();
TitleScreen.LoadState = 97.0f;
LevelObjectPrefab.LoadAll();
DecalManager = new DecalManager();
TitleScreen.LoadState = 99.0f;
yield return CoroutineStatus.Running;
LocationType.Init();
@@ -489,7 +478,7 @@ namespace Barotrauma
foreach (ContentPackage contentPackage in Config.SelectedContentPackages)
{
var exePaths = contentPackage.GetFilesOfType(ContentType.Executable);
if (exePaths.Count() > 0 && AppDomain.CurrentDomain.FriendlyName != exePaths.First())
if (exePaths.Any() && AppDomain.CurrentDomain.FriendlyName != exePaths.First())
{
var msgBox = new GUIMessageBox(TextManager.Get("Error"),
TextManager.Get("IncorrectExe")
@@ -515,6 +504,7 @@ namespace Barotrauma
/// </summary>
protected override void UnloadContent()
{
Video.Close();
SoundManager.Dispose();
}
@@ -525,7 +515,7 @@ namespace Barotrauma
{
return ContentPackage.GetFilesOfType(SelectedPackages, type);
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
@@ -547,6 +537,18 @@ namespace Barotrauma
bool paused = true;
if (SoundManager != null)
{
if (WindowActive || !Config.MuteOnFocusLost)
{
SoundManager.ListenerGain = 1.0f;
}
else
{
SoundManager.ListenerGain = 0.0f;
}
}
while (Timing.Accumulator >= Timing.Step)
{
Stopwatch sw = new Stopwatch();
@@ -557,17 +559,17 @@ namespace Barotrauma
fixedTime.ElapsedGameTime = addTime;
fixedTime.TotalGameTime.Add(addTime);
base.Update(fixedTime);
PlayerInput.Update(Timing.Step);
if (loadingScreenOpen)
{
//reset accumulator if loading
// -> less choppy loading screens because the screen is rendered after each update
// -> no pause caused by leftover time in the accumulator when starting a new shift
Timing.Accumulator = 0.0f;
GameMain.ResetFrameTime();
if (TitleScreen.LoadState >= 100.0f &&
if (TitleScreen.LoadState >= 100.0f &&
(!waitForKeyHit || PlayerInput.GetKeyboardState.GetPressedKeys().Length>0 || PlayerInput.LeftButtonClicked()))
{
loadingScreenOpen = false;
@@ -587,7 +589,28 @@ namespace Barotrauma
{
SoundPlayer.Update((float)Timing.Step);
if (PlayerInput.KeyHit(Keys.Escape)) GUI.TogglePauseMenu();
if (PlayerInput.KeyHit(Keys.Escape))
{
// Check if a text input is selected.
if (GUI.KeyboardDispatcher.Subscriber != null)
{
if (GUI.KeyboardDispatcher.Subscriber is GUITextBox textBox)
{
textBox.Deselect();
}
GUI.KeyboardDispatcher.Subscriber = null;
}
//if a verification prompt (are you sure you want to x) is open, close it
else if (GUIMessageBox.VisibleBox as GUIMessageBox != null &&
GUIMessageBox.VisibleBox.UserData as string == "verificationprompt")
{
((GUIMessageBox)GUIMessageBox.VisibleBox).Close();
}
else // Otherwise toggle pausing.
{
GUI.TogglePauseMenu();
}
}
GUI.ClearUpdateList();
paused = (DebugConsole.IsOpen || GUI.PauseMenuOpen || GUI.SettingsMenuOpen || ContextualTutorial.ContentRunning) &&
@@ -595,16 +618,16 @@ namespace Barotrauma
Screen.Selected.AddToGUIUpdateList();
if (NetworkMember != null)
if (Client != null)
{
NetworkMember.AddToGUIUpdateList();
Client.AddToGUIUpdateList();
}
DebugConsole.AddToGUIUpdateList();
DebugConsole.Update(this, (float)Timing.Step);
paused = paused || (DebugConsole.IsOpen && (NetworkMember == null || !NetworkMember.GameStarted));
if (!paused)
{
Screen.Selected.Update(Timing.Step);
@@ -637,6 +660,10 @@ namespace Barotrauma
if (!paused) Timing.Alpha = Timing.Accumulator / Timing.Step;
}
public static void ResetFrameTime()
{
Timing.Accumulator = 0.0f;
}
/// <summary>
/// This is called when the game should draw itself.
@@ -666,6 +693,7 @@ namespace Barotrauma
spriteBatch.End();
}
sw.Stop();
PerformanceCounter.AddElapsedTicks("Draw total", sw.ElapsedTicks);
PerformanceCounter.DrawTimeGraph.Update(sw.ElapsedTicks / (float)TimeSpan.TicksPerMillisecond);

View File

@@ -4,6 +4,7 @@ using Barotrauma.Networking;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -25,10 +26,7 @@ namespace Barotrauma
private List<Character> characters = new List<Character>();
private Point screenResolution;
public int WinningTeam = 1;
#region UI
private GUIFrame guiFrame;
@@ -47,7 +45,7 @@ namespace Barotrauma
private ChatBox chatBox;
private float prevUIScale;
private GUIComponent orderTargetFrame, orderTargetFrameShadow;
public bool ToggleCrewAreaOpen
@@ -76,6 +74,20 @@ namespace Barotrauma
break;
}
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
prevUIScale = GUI.Scale;
}
#endregion
#region Character list management
public Rectangle GetCharacterListArea()
{
return characterListBox.Rect;
}
partial void InitProjectSpecific()
@@ -144,11 +156,20 @@ namespace Barotrauma
msg,
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default,
Character.Controlled);
var headset = GetHeadset(Character.Controlled, true);
if (headset != null && headset.CanTransmit())
{
headset.TransmitSignal(stepsTaken: 0, signal: msg, source: headset.Item, sender: Character.Controlled, sendToChat: false);
}
}
textbox.Deselect();
textbox.Text = "";
return true;
}
}
};
chatBox.InputBox.OnDeselected += (gui, Keys) =>
{
this.chatBox.InputBox.Text = "";
};
chatBox.InputBox.OnTextChanged += chatBox.TypingChatMessage;
}
@@ -328,7 +349,7 @@ namespace Barotrauma
int spacing = (int)(10 * GUI.Scale);
int height = (int)(45 * GUI.Scale);
characterInfoWidth = (int)(170 * GUI.Scale);
characterInfoWidth = (int)(200 * GUI.Scale);
float charactersPerView = characterListBox.Rect.Height / (float)(height + characterListBox.Spacing);
@@ -341,6 +362,7 @@ namespace Barotrauma
int iconSize = (int)(height * 0.8f);
var frame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, height), parent.RectTransform), style: "InnerFrame")
{
UserData = character,
@@ -349,7 +371,16 @@ namespace Barotrauma
frame.Color = character.Info.Job.Prefab.UIColor;
frame.SelectedColor = Color.Lerp(frame.Color, Color.White, 0.5f);
frame.HoverColor = Color.Lerp(frame.Color, Color.White, 0.9f);
new GUIFrame(new RectTransform(new Point(characterInfoWidth, (int)(frame.Rect.Height * 1.3f)), frame.RectTransform, Anchor.CenterLeft), style: "OuterGlow")
{
UserData = "highlight",
Color = frame.SelectedColor,
HoverColor = frame.SelectedColor,
PressedColor = frame.SelectedColor,
SelectedColor = frame.SelectedColor,
CanBeFocused = false
};
//---------------- character area ----------------
string characterToolTip = character.Info.Name;
@@ -365,6 +396,23 @@ namespace Barotrauma
HoverColor = frame.HoverColor,
ToolTip = characterToolTip
};
var soundIcon = new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) },
"GUISoundIcon")
{
UserData = "soundicon",
CanBeFocused = false,
Visible = true
};
soundIcon.Color = new Color(soundIcon.Color, 0.0f);
new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) },
"GUISoundIconDisabled")
{
UserData = "soundicondisabled",
CanBeFocused = true,
Visible = false
};
if (isSinglePlayer)
{
characterArea.OnClicked = CharacterClicked;
@@ -375,7 +423,7 @@ namespace Barotrauma
characterArea.CanBeSelected = false;
}
var characterImage = new GUICustomComponent(new RectTransform(new Point(characterArea.Rect.Height, characterArea.Rect.Height), characterArea.RectTransform, Anchor.CenterLeft),
var characterImage = new GUICustomComponent(new RectTransform(new Point(characterArea.Rect.Height), characterArea.RectTransform, Anchor.CenterLeft),
onDraw: (sb, component) => character.Info.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()))
{
CanBeFocused = false,
@@ -384,7 +432,8 @@ namespace Barotrauma
ToolTip = characterToolTip
};
var characterName = new GUITextBlock(new RectTransform(new Point(characterArea.Rect.Width - characterImage.Rect.Width, characterArea.Rect.Height), characterArea.RectTransform, Anchor.CenterRight),
var characterName = new GUITextBlock(new RectTransform(new Point(characterArea.Rect.Width - characterImage.Rect.Width - soundIcon.Rect.Width - 10, characterArea.Rect.Height),
characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(soundIcon.Rect.Width + 10, 0) },
character.Name, textColor: frame.Color, font: GUI.SmallFont, wrap: true)
{
Color = frame.Color,
@@ -423,8 +472,8 @@ namespace Barotrauma
var order = orders[i];
if (order.TargetAllCharacters) continue;
RectTransform btnParent = (i >= correctOrderCount + neutralOrderCount) ?
wrongOrderList.Content.RectTransform :
RectTransform btnParent = (i >= correctOrderCount + neutralOrderCount) ?
wrongOrderList.Content.RectTransform :
orderButtonFrame.RectTransform;
var btn = new GUIButton(new RectTransform(new Point(iconSize, iconSize), btnParent, Anchor.CenterLeft),
@@ -445,11 +494,11 @@ namespace Barotrauma
img.Color = Color.Lerp(order.Color, frame.Color, 0.5f);
img.ToolTip = order.Name;
img.HoverColor = Color.Lerp(img.Color, Color.White, 0.5f);
btn.OnClicked += (GUIButton button, object userData) =>
{
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
if (btn.GetChildByUserData("selected").Visible)
{
SetCharacterOrder(character, Order.PrefabList.Find(o => o.AITag == "dismissed"), null, Character.Controlled);
@@ -526,23 +575,6 @@ namespace Barotrauma
return true;
}
/// <summary>
/// Sets which character is selected in the crew UI (highlight effect etc)
/// </summary>
public void SetCharacterSelected(Character character)
{
if (character != null && !characters.Contains(character)) return;
//GUIComponent selectedCharacterFrame = null;
foreach (GUIComponent child in characterListBox.Content.Children)
{
GUIButton button = child.Children.FirstOrDefault(c => c.UserData is Character) as GUIButton;
if (button == null) continue;
child.Visible = (Character)button.UserData != character;
}
}
public void ReviveCharacter(Character revivedCharacter)
{
if (characterListBox.Content.GetChildByUserData(revivedCharacter) is GUIComponent characterBlock)
@@ -566,13 +598,14 @@ namespace Barotrauma
if (characterListBox.Content.CountChildren == 0) return false;
int dir = (int)obj;
float step =
(characterListBox.Content.Children.First().Rect.Height + characterListBox.Spacing) /
float step =
(characterListBox.Content.Children.First().Rect.Height + characterListBox.Spacing) /
(characterListBox.TotalSize - characterListBox.Rect.Height);
characterListBox.BarScroll -= characterListBox.BarScroll % step;
characterListBox.BarScroll += dir * step;
return false;
child.Visible = (Character)button.UserData != character;
}
}
private IEnumerable<object> KillCharacterAnim(GUIComponent component)
@@ -583,6 +616,8 @@ namespace Barotrauma
{
comp.Color = Color.DarkRed;
}
if (characterInfos.Contains(revivedCharacter.Info)) AddCharacter(revivedCharacter);
}
yield return new WaitForSeconds(1.0f);
@@ -606,7 +641,6 @@ namespace Barotrauma
#endregion
#region Dialog
/// <summary>
/// Adds the message to the single player chatbox.
/// </summary>
@@ -617,6 +651,7 @@ namespace Barotrauma
DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace);
return;
}
if (string.IsNullOrEmpty(text)) { return; }
chatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender));
}
@@ -632,6 +667,52 @@ namespace Barotrauma
return radioItem.GetComponent<WifiComponent>();
}
partial void CreateRandomConversation()
{
if (GameMain.Client != null)
{
//let the server create random conversations in MP
return;
}
List<Character> availableSpeakers = Character.CharacterList.FindAll(c =>
c.AIController is HumanAIController &&
!c.IsDead &&
c.SpeechImpediment <= 100.0f);
pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers));
}
#endregion
#region Voice chat
public void SetPlayerVoiceIconState(Client client, bool muted, bool mutedLocally)
{
if (client?.Character == null) { return; }
var playerFrame = characterListBox.Content.FindChild(client.Character)?.FindChild(client.Character);
if (playerFrame == null) { return; }
var soundIcon = playerFrame.FindChild("soundicon");
var soundIconDisabled = playerFrame.FindChild("soundicondisabled");
if (!soundIcon.Visible)
{
soundIcon.Color = new Color(soundIcon.Color, 0.0f);
}
soundIcon.Visible = !muted && !mutedLocally;
soundIconDisabled.Visible = muted || mutedLocally;
soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally");
}
public void SetPlayerSpeaking(Client client)
{
if (client?.Character == null) { return; }
var playerFrame = characterListBox.Content.FindChild(client.Character)?.FindChild(client.Character);
if (playerFrame == null) { return; }
var soundIcon = playerFrame.FindChild("soundicon");
soundIcon.Color = new Color(soundIcon.Color, 1.0f);
}
#endregion
/// <summary>
@@ -648,7 +729,7 @@ namespace Barotrauma
if (IsSinglePlayer)
{
orderGiver.Speak(
order.GetChatMessage("", orderGiver.CurrentHull?.RoomName), ChatMessageType.Order);
order.GetChatMessage("", orderGiver.CurrentHull?.RoomName, givingOrderToSelf: character == orderGiver), ChatMessageType.Order);
}
else
{
@@ -657,19 +738,15 @@ namespace Barotrauma
{
GameMain.Client.SendChatMessage(msg);
}
else if (GameMain.Server != null)
{
GameMain.Server.SendOrderChatMessage(msg);
}
}
return;
}
character.SetOrder(order, option, orderGiver);
character.SetOrder(order, option, orderGiver, speak: orderGiver != character);
if (IsSinglePlayer)
{
orderGiver?.Speak(
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.RoomName, option), null);
order.GetChatMessage(character.Name, orderGiver.CurrentHull?.RoomName, givingOrderToSelf: character == orderGiver, orderOption: option), null);
}
else if (orderGiver != null)
{
@@ -678,16 +755,12 @@ namespace Barotrauma
{
GameMain.Client.SendChatMessage(msg);
}
else if (GameMain.Server != null)
{
GameMain.Server.SendOrderChatMessage(msg);
}
}
DisplayCharacterOrder(character, order);
}
/// <summary>
/// Displays the specified order in the crew UI next to the character.
/// Displays the specified order in the crew UI next to the character.
/// </summary>
public void DisplayCharacterOrder(Character character, Order order)
{
@@ -697,7 +770,7 @@ namespace Barotrauma
if (characterFrame == null) continue;
var orderButtonFrame = characterListElement.GetChildByUserData("orderbuttons");
//get all order buttons from the frame
List<GUIButton> orderButtons = new List<GUIButton>();
foreach (GUIComponent child in orderButtonFrame.Children)
@@ -728,13 +801,13 @@ namespace Barotrauma
}
/// <summary>
/// Create the UI panel that's used to select the target and options for a given order
/// Create the UI panel that's used to select the target and options for a given order
/// (which railgun to use, whether to power up the reactor or shut it down...)
/// </summary>
private void CreateOrderTargetFrame(GUIComponent orderButton, Character character, Order order)
{
Submarine submarine = Character.Controlled != null && Character.Controlled.TeamID > 1 && Submarine.MainSubs.Length > 1 ?
Submarine.MainSubs[1] :
Submarine submarine = Character.Controlled != null && Character.Controlled.TeamID == Character.TeamType.Team2 && Submarine.MainSubs.Length > 1 ?
Submarine.MainSubs[1] :
Submarine.MainSub;
List<Item> matchingItems = new List<Item>();
@@ -742,12 +815,12 @@ namespace Barotrauma
{
matchingItems = order.ItemIdentifiers.Length > 0 ?
Item.ItemList.FindAll(it => order.ItemIdentifiers.Contains(it.Prefab.Identifier) || it.HasTag(order.ItemIdentifiers)) :
Item.ItemList.FindAll(it => it.components.Any(ic => ic.GetType() == order.ItemComponentType));
Item.ItemList.FindAll(it => it.Components.Any(ic => ic.GetType() == order.ItemComponentType));
matchingItems.RemoveAll(it => it.Submarine != submarine && !submarine.DockedTo.Contains(it.Submarine));
matchingItems.RemoveAll(it => it.Submarine != null && it.Submarine.IsOutpost);
}
//more than one target item -> create a minimap-like selection with a pic of the sub
if (matchingItems.Count > 1)
{
@@ -819,7 +892,7 @@ namespace Barotrauma
var optionButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.2f), optionContainer.RectTransform),
order.OptionNames[i], style: "GUITextBox")
{
UserData = item == null ? order : new Order(order, item, item.components.Find(ic => ic.GetType() == order.ItemComponentType)),
UserData = item == null ? order : new Order(order, item, item.Components.FirstOrDefault(ic => ic.GetType() == order.ItemComponentType)),
Font = GUI.SmallFont,
OnClicked = (btn, userData) =>
{
@@ -847,7 +920,7 @@ namespace Barotrauma
//line connecting the order button to the option buttons
//TODO: sprite
new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), orderTargetFrame.RectTransform), style: null);
for (int i = 0; i < order.Options.Length; i++)
{
Item item = matchingItems.Count > 0 ? matchingItems[0] : null;
@@ -855,7 +928,7 @@ namespace Barotrauma
var optionButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.5f), orderTargetFrame.RectTransform),
order.OptionNames[i], style: "GUITextBox")
{
UserData = item == null ? order : new Order(order, item, item.components.Find(ic => ic.GetType() == order.ItemComponentType)),
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;
@@ -874,11 +947,13 @@ namespace Barotrauma
}
int shadowSize = (int)(200 * GUI.Scale);
orderTargetFrameShadow = new GUIFrame(new RectTransform(orderTargetFrame.Rect.Size + new Point(shadowSize * 2), GUI.Canvas)
{ AbsoluteOffset = orderTargetFrame.Rect.Location - new Point(shadowSize) },
{ AbsoluteOffset = orderTargetFrame.Rect.Location - new Point(shadowSize) },
style: "OuterGlow",
color: matchingItems.Count > 1 ? Color.Black * 0.9f : Color.Black * 0.7f);
}
#region Updating and drawing the UI
private void DrawMiniMapOverlay(SpriteBatch spriteBatch, GUICustomComponent container)
{
Submarine sub = container.UserData as Submarine;
@@ -895,7 +970,7 @@ namespace Barotrauma
float displayScale = ConvertUnits.ToDisplayUnits(scale);
Vector2 offset = (sub.WorldPosition - new Vector2(dockedBorders.Center.X, dockedBorders.Y - dockedBorders.Height / 2)) * scale;
Vector2 center = container.Rect.Center.ToVector2();
for (int i = 0; i < sub.HullVertices.Count; i++)
{
Vector2 start = (sub.HullVertices[i] * displayScale + offset);
@@ -903,14 +978,12 @@ namespace Barotrauma
Vector2 end = (sub.HullVertices[(i + 1) % sub.HullVertices.Count] * displayScale + offset);
end.Y = -end.Y;
GUI.DrawLine(spriteBatch, center + start, center + end, Color.DarkCyan * Rand.Range(0.3f, 0.35f), width: 10);
}
}
}
#region Updating and drawing the UI
public void AddToGUIUpdateList()
{
if (GUI.DisableHUD) return;
if (GUI.DisableHUD || GUI.DisableUpperHUD) return;
if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y ||
prevUIScale != GUI.Scale)
{
@@ -989,7 +1062,7 @@ namespace Barotrauma
}
}
if (GUI.DisableHUD) return;
if (GUI.DisableHUD || GUI.DisableUpperHUD) return;
if (chatBox != null)
{
chatBox.Update(deltaTime);
@@ -997,23 +1070,17 @@ namespace Barotrauma
if (!DebugConsole.IsOpen && chatBox.InputBox.Visible)
{
if (PlayerInput.KeyHit(InputType.Chat))
if (PlayerInput.KeyHit(InputType.Chat) && !chatBox.InputBox.Selected)
{
if (chatBox.InputBox.Selected)
{
chatBox.InputBox.Text = "";
chatBox.InputBox.Deselect();
}
else
{
chatBox.InputBox.Select();
}
chatBox.GUIFrame.Flash(Color.DarkGreen, 0.5f);
chatBox.InputBox.Select();
}
if (PlayerInput.KeyHit(InputType.RadioChat) && !chatBox.InputBox.Selected)
{
chatBox.GUIFrame.Flash(Color.YellowGreen, 0.5f);
chatBox.InputBox.Select();
chatBox.InputBox.Text = "r; ";
chatBox.InputBox.Text = "r; ";
}
}
}
@@ -1026,12 +1093,22 @@ namespace Barotrauma
foreach (GUIComponent child in characterListBox.Content.Children)
{
child.Visible =
Character.Controlled == null ||
(Character.Controlled != ((Character)child.UserData) && Character.Controlled.TeamID == ((Character)child.UserData).TeamID);
Character character = (Character)child.UserData;
child.Visible =
Character.Controlled == null ||
(Character.Controlled.TeamID == character.TeamID);
if (child.Visible)
{
child.GetChildByUserData("highlight").Visible = character == Character.Controlled;
var soundIcon = child.FindChild(character)?.FindChild("soundicon");
if (soundIcon != null)
{
soundIcon.Color = new Color(soundIcon.Color, (soundIcon.Color.A / 255.0f) - deltaTime);
}
GUIListBox wrongOrderList = child.GetChildByUserData("orderbuttons")?.GetChild<GUIListBox>();
if (wrongOrderList != null)
{
@@ -1046,8 +1123,8 @@ namespace Barotrauma
hoverRect.Inflate((int)(30 * GUI.Scale), (int)(0 * GUI.Scale));
}
bool toggleOpen =
characterListBox.Content.Rect.Contains(PlayerInput.MousePosition) &&
bool toggleOpen =
characterListBox.Content.Rect.Contains(PlayerInput.MousePosition) &&
hoverRect.Contains(PlayerInput.MousePosition);
wrongOrderList.CanBeFocused = toggleOpen;
wrongOrderList.Content.CanBeFocused = toggleOpen;
@@ -1092,7 +1169,6 @@ namespace Barotrauma
}
UpdateReports(deltaTime);
UpdateConversations(deltaTime);
if (orderTargetFrame != null)
{
@@ -1111,16 +1187,16 @@ namespace Barotrauma
}
}
#endregion
#endregion
/// <summary>
/// Creates a listbox that includes all the characters in the crew, can be used externally (round info menus etc)
/// </summary>
public void CreateCrewListFrame(IEnumerable<Character> crew, GUIFrame crewFrame)
{
List<byte> teamIDs = crew.Select(c => c.TeamID).Distinct().ToList();
List<Character.TeamType> teamIDs = crew.Select(c => c.TeamID).Distinct().ToList();
if (!teamIDs.Any()) teamIDs.Add(0);
if (!teamIDs.Any()) teamIDs.Add(Character.TeamType.None);
int listBoxHeight = 300 / teamIDs.Count;
@@ -1151,7 +1227,7 @@ namespace Barotrauma
GUIFrame frame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.15f), crewList.Content.RectTransform), style: "ListBoxElement")
{
UserData = character,
Color = (GameMain.NetworkMember != null && GameMain.NetworkMember.Character == character) ? Color.Gold * 0.2f : Color.Transparent
Color = (GameMain.NetworkMember != null && GameMain.Client.Character == character) ? Color.Gold * 0.2f : Color.Transparent
};
var paddedFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), frame.RectTransform, Anchor.Center), isHorizontal: true)
@@ -1159,7 +1235,7 @@ namespace Barotrauma
RelativeSpacing = 0.05f,
Stretch = true
};
new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), paddedFrame.RectTransform, Anchor.CenterLeft),
onDraw: (sb, component) => character.Info.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()))
{
@@ -1169,7 +1245,7 @@ namespace Barotrauma
};
GUITextBlock textBlock = new GUITextBlock(new RectTransform(Vector2.One, paddedFrame.RectTransform),
ToolBox.LimitString(character.Info.Name + " (" + character.Info.Job.Name + ")", GUI.Font, paddedFrame.Rect.Width - paddedFrame.Rect.Height),
ToolBox.LimitString(character.Info.Name + " (" + character.Info.Job.Name + ")", GUI.Font, paddedFrame.Rect.Width - paddedFrame.Rect.Height),
textColor: character.Info.Job.Prefab.UIColor);
}
}
@@ -1194,12 +1270,12 @@ namespace Barotrauma
character.Info.CreateInfoFrame(previewPlayer);
if (GameMain.NetworkMember != null) GameMain.NetworkMember.SelectCrewCharacter(character, previewPlayer);
if (GameMain.NetworkMember != null) GameMain.Client.SelectCrewCharacter(character, previewPlayer);
return true;
}
#region Reports
#region Reports
/// <summary>
/// Enables/disables report buttons when needed
@@ -1217,7 +1293,7 @@ namespace Barotrauma
{
reportButtonFrame.Visible = true;
var reportButtonParent = chatBox ?? GameMain.NetworkMember.ChatBox;
var reportButtonParent = chatBox ?? GameMain.Client.ChatBox;
reportButtonFrame.RectTransform.AbsoluteOffset = new Point(
Math.Min(reportButtonParent.GUIFrame.Rect.X, reportButtonParent.ToggleButton.Rect.X) - reportButtonFrame.Rect.Width - (int)(10 * GUI.Scale),
reportButtonParent.GUIFrame.Rect.Y);
@@ -1230,7 +1306,7 @@ namespace Barotrauma
bool hasIntruders = Character.CharacterList.Any(c =>
c.CurrentHull == Character.Controlled.CurrentHull && !c.IsDead &&
(c.AIController is EnemyAIController || c.TeamID != Character.Controlled.TeamID));
(c.AIController is EnemyAIController || (c.TeamID != Character.Controlled.TeamID && c.TeamID != Character.TeamType.FriendlyNPC)));
ToggleReportButton("reportintruders", hasIntruders);
@@ -1240,7 +1316,7 @@ namespace Barotrauma
if (highlight.Visible)
{
highlight.RectTransform.LocalScale = new Vector2(1.25f + (float)Math.Sin(Timing.TotalTime * 5.0f) * 0.25f);
}
}
}
}
else
@@ -1256,7 +1332,7 @@ namespace Barotrauma
{
return CharacterHealth.OpenHealthWindow == null;
}
private bool ReportButtonClicked(GUIButton button, object userData)
{
//order targeted to all characters
@@ -1273,7 +1349,7 @@ namespace Barotrauma
private void ToggleReportButton(string orderAiTag, bool enabled)
{
Order order = Order.PrefabList.Find(o => o.AITag == orderAiTag);
//already reported, disable the button
/*if (GameMain.GameSession.CrewManager.ActiveOrders.Any(o =>
o.First.TargetEntity == Character.Controlled.CurrentHull &&
@@ -1286,10 +1362,10 @@ namespace Barotrauma
if (reportButton != null)
{
reportButton.GetChildByUserData("highlighted").Visible = enabled;
}
}
}
#endregion
#endregion
public void InitSinglePlayerRound()
{
@@ -1300,13 +1376,13 @@ namespace Barotrauma
for (int i = 0; i < waypoints.Length; i++)
{
Character character;
Character character;
character = Character.Create(characterInfos[i], waypoints[i].WorldPosition, characterInfos[i].Name);
if (character.Info != null && !character.Info.StartItemsGiven)
{
character.GiveJobItems(waypoints[i]);
character.Info.StartItemsGiven = true;
}
}
if (character.Info?.InventoryData != null)
{

View File

@@ -3,12 +3,15 @@ using Lidgren.Network;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
partial class MultiPlayerCampaign : CampaignMode
{
public static GUIComponent StartCampaignSetup()
private UInt16 startWatchmanID, endWatchmanID;
public static GUIComponent StartCampaignSetup(IEnumerable<string> saveFiles)
{
GUIFrame background = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
@@ -31,7 +34,7 @@ namespace Barotrauma
var newCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null);
var loadCampaignContainer = new GUIFrame(new RectTransform(Vector2.One, campaignContainer.RectTransform, Anchor.BottomLeft), style: null);
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer);
var campaignSetupUI = new CampaignSetupUI(true, newCampaignContainer, loadCampaignContainer, saveFiles);
var newCampaignButton = new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonContainer.RectTransform),
TextManager.Get("NewCampaign"))
@@ -56,55 +59,16 @@ namespace Barotrauma
};
loadCampaignContainer.Visible = false;
campaignSetupUI.StartNewGame = (Submarine sub, string saveName, string mapSeed) =>
{
GameMain.GameSession = new GameSession(new Submarine(sub.FilePath, ""), saveName,
GameModePreset.List.Find(g => g.Identifier == "multiplayercampaign"));
var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
campaign.GenerateMap(mapSeed);
campaign.SetDelegates();
background.Visible = false;
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
campaign.Map.SelectRandomLocation(true);
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
campaign.LastSaveID++;
};
campaignSetupUI.LoadGame = (string fileName) =>
{
SaveUtil.LoadGame(fileName);
if (!(GameMain.GameSession.GameMode is MultiPlayerCampaign))
{
DebugConsole.ThrowError("Failed to load the campaign. The save file appears to be for a single player campaign.");
return;
}
var campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
campaign.LastSaveID++;
background.Visible = false;
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
campaign.Map.SelectRandomLocation(true);
};
campaignSetupUI.StartNewGame = GameMain.Client.SetupNewCampaign;
campaignSetupUI.LoadGame = GameMain.Client.SetupLoadCampaign;
var cancelButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.05f), paddedFrame.RectTransform, Anchor.BottomLeft), TextManager.Get("Cancel"))
{
OnClicked = (btn, obj) =>
{
//find the first mode that's not multiplayer campaign and switch to that
background.Visible = false;
int otherModeIndex = 0;
for (otherModeIndex = 0; otherModeIndex < GameMain.NetLobbyScreen.ModeList.Content.CountChildren; otherModeIndex++)
{
if (GameMain.NetLobbyScreen.ModeList.Content.GetChild(otherModeIndex).UserData is MultiPlayerCampaign) continue;
break;
}
GameMain.NetLobbyScreen.SelectMode(otherModeIndex);
return true;
}
};
@@ -112,6 +76,56 @@ namespace Barotrauma
return background;
}
public override void Update(float deltaTime)
{
base.Update(deltaTime);
if (startWatchmanID > 0 && startWatchman == null)
{
startWatchman = Entity.FindEntityByID(startWatchmanID) as Character;
if (startWatchman != null) { InitializeWatchman(startWatchman); }
}
if (endWatchmanID > 0 && endWatchman == null)
{
endWatchman = Entity.FindEntityByID(endWatchmanID) as Character;
if (endWatchman != null) { InitializeWatchman(endWatchman); }
}
}
protected override void WatchmanInteract(Character watchman, Character interactor)
{
if ((watchman.Submarine == Level.Loaded.StartOutpost && !Submarine.MainSub.AtStartPosition) ||
(watchman.Submarine == Level.Loaded.EndOutpost && !Submarine.MainSub.AtEndPosition))
{
return;
}
if (GUIMessageBox.MessageBoxes.Any(mbox => mbox.UserData as string == "watchmanprompt"))
{
return;
}
if (GameMain.Client != null && interactor == Character.Controlled &&
(GameMain.Client.HasPermission(ClientPermissions.ManageRound) || GameMain.Client.HasPermission(ClientPermissions.ManageCampaign)))
{
var msgBox = new GUIMessageBox("", TextManager.Get("CampaignEnterOutpostPrompt")
.Replace("[locationname]", Submarine.MainSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
UserData = "watchmanprompt"
};
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
{
GameMain.Client.RequestRoundEnd();
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked += msgBox.Close;
}
}
public void ClientWrite(NetBuffer msg)
{
System.Diagnostics.Debug.Assert(map.Locations.Count < UInt16.MaxValue);
@@ -138,6 +152,9 @@ namespace Barotrauma
UInt16 selectedLocIndex = msg.ReadUInt16();
byte selectedMissionIndex = msg.ReadByte();
UInt16 startWatchmanID = msg.ReadUInt16();
UInt16 endWatchmanID = msg.ReadUInt16();
int money = msg.ReadInt32();
UInt16 purchasedItemCount = msg.ReadUInt16();
@@ -167,10 +184,9 @@ namespace Barotrauma
campaign = ((MultiPlayerCampaign)GameMain.GameSession.GameMode);
campaign.CampaignID = campaignID;
campaign.GenerateMap(mapSeed);
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
}
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
if (NetIdUtils.IdMoreRecent(campaign.lastUpdateID, updateID)) return;
//server has a newer save file
if (NetIdUtils.IdMoreRecent(saveID, campaign.PendingSaveID))
@@ -187,19 +203,22 @@ namespace Barotrauma
GameMain.Client.RequestFile(FileTransferType.CampaignSave, null, null);*/
campaign.PendingSaveID = saveID;
}
//we've got the latest save file
else if (!NetIdUtils.IdMoreRecent(saveID, campaign.lastSaveID))
if (NetIdUtils.IdMoreRecent(updateID, campaign.lastUpdateID))
{
campaign.Map.SetLocation(currentLocIndex == UInt16.MaxValue ? -1 : currentLocIndex);
campaign.Map.SelectLocation(selectedLocIndex == UInt16.MaxValue ? -1 : selectedLocIndex);
campaign.Map.SelectMission(selectedMissionIndex);
campaign.startWatchmanID = startWatchmanID;
campaign.endWatchmanID = endWatchmanID;
campaign.Money = money;
campaign.CargoManager.SetPurchasedItems(purchasedItems);
if (myCharacterInfo != null)
{
GameMain.NetworkMember.CharacterInfo = myCharacterInfo;
GameMain.Client.CharacterInfo = myCharacterInfo;
GameMain.NetLobbyScreen.SetCampaignCharacterInfo(myCharacterInfo);
}
else

View File

@@ -38,7 +38,7 @@ namespace Barotrauma
{
for (int i = 0; i < jobPrefab.InitialCount; i++)
{
CrewManager.AddCharacterInfo(new CharacterInfo(Character.HumanConfigFile, "", Gender.None, jobPrefab));
CrewManager.AddCharacterInfo(new CharacterInfo(Character.HumanConfigFile, "", jobPrefab));
}
}
@@ -128,7 +128,7 @@ namespace Barotrauma
public override void Draw(SpriteBatch spriteBatch)
{
if (!isRunning|| GUI.DisableHUD) return;
if (!isRunning|| GUI.DisableHUD || GUI.DisableUpperHUD) return;
if (Submarine.MainSub == null) return;
@@ -180,7 +180,7 @@ namespace Barotrauma
ContextualTutorial.Update(deltaTime);
}
if (!GUI.DisableHUD)
if (!GUI.DisableHUD && !GUI.DisableUpperHUD)
{
endRoundButton.UpdateManually(deltaTime);
}
@@ -206,11 +206,19 @@ namespace Barotrauma
return;
}
CreateDialog(new List<Character> { watchman }, "WatchmanInteract", 1.0f);
if (GUIMessageBox.MessageBoxes.Any(mbox => mbox.UserData as string == "watchmanprompt"))
{
return;
}
var msgBox = new GUIMessageBox("", TextManager.Get("CampaignEnterOutpostPrompt")
.Replace("[locationname]", leavingSub.AtStartPosition ? Map.CurrentLocation.Name : Map.SelectedLocation.Name),
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
{
UserData = "watchmanprompt"
};
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
{
if (!isRunning) { return true; }

View File

@@ -584,7 +584,7 @@ namespace Barotrauma.Tutorials
}
}
if (brokenBox != null && brokenBox.Condition > 50.0f && pump.Voltage < pump.MinVoltage)
if (brokenBox != null && brokenBox.Condition > brokenBox.Prefab.Health / 2.0f && pump.Voltage < pump.MinVoltage)
{
yield return new WaitForSeconds(1.0f);

View File

@@ -152,7 +152,6 @@ namespace Barotrauma.Tutorials
if (!Initialized) return;
PreloadVideoContent();
Completed = true; // Trigger completed at start to prevent the contextual tutorial from automatically activating on starting new campaigns after this one
base.Start();
@@ -194,6 +193,7 @@ namespace Barotrauma.Tutorials
}
crew = GameMain.GameSession.CrewManager.GetCharacters().ToList();
Completed = true; // Trigger completed at start to prevent the contextual tutorial from automatically activating on starting new campaigns after this one
started = true;
}
@@ -325,7 +325,7 @@ namespace Barotrauma.Tutorials
foreach (Item item in Item.ItemList)
{
if (!item.Repairables.Any() || item.Condition > 50.0f) continue;
if (!item.Repairables.Any() || item.Condition > item.Prefab.Health / 2.0f) continue;
degradedEquipmentFound = true;
break;
}
@@ -464,7 +464,7 @@ namespace Barotrauma.Tutorials
spriteSheetPlayer.LoadContent(playableContentPath, activeSegment.Content, activeSegment.Name, true, true, CurrentSegmentStopCallback);
break;
case ContentTypes.Text:
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Name), TextManager.Get(activeSegment.Content.GetAttributeString("tag", ""), false, args),
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Name), TextManager.GetFormatted(activeSegment.Content.GetAttributeString("tag", ""), false, args),
activeSegment.Content.GetAttributeInt("width", 300),
activeSegment.Content.GetAttributeInt("height", 80),
activeSegment.Content.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);

View File

@@ -36,7 +36,7 @@ namespace Barotrauma.Tutorials
}
CharacterInfo charInfo = configElement.Element("Character") == null ?
new CharacterInfo(Character.HumanConfigFile, "", Gender.None, JobPrefab.List.Find(jp => jp.Identifier == "engineer")) :
new CharacterInfo(Character.HumanConfigFile, "", JobPrefab.List.Find(jp => jp.Identifier == "engineer")) :
new CharacterInfo(configElement.Element("Character"));
character = Character.Create(charInfo, wayPoint.WorldPosition, "", false, false);
@@ -101,7 +101,7 @@ namespace Barotrauma.Tutorials
messageBox.Buttons[0].OnClicked += messageBox.Close;
messageBox.Buttons[1].OnClicked = GameMain.MainMenuScreen.SelectTab;
messageBox.Buttons[1].OnClicked = GameMain.MainMenuScreen.ReturnToMainMenu;
messageBox.Buttons[1].OnClicked += messageBox.Close;
yield return CoroutineStatus.Success;

View File

@@ -31,7 +31,7 @@ namespace Barotrauma.Tutorials
{
if (completed == value) return;
completed = value;
GameMain.Config.Save();
GameMain.Config.SaveNewPlayerConfig();
}
}
@@ -105,7 +105,7 @@ namespace Barotrauma.Tutorials
{
configElement = element;
Name = element.GetAttributeString("name", "Unnamed");
Completed = GameMain.Config.CompletedTutorialNames.Contains(Name);
completed = GameMain.Config.CompletedTutorialNames.Contains(Name);
Enum.TryParse(element.GetAttributeString("tutorialtype", "Scenario"), true, out tutorialType);
}
@@ -167,7 +167,7 @@ namespace Barotrauma.Tutorials
};
}
GUI.PlayUISound(GUISoundType.Message);
GUI.PlayUISound(GUISoundType.UIMessage);
return infoBlock;
}
@@ -211,7 +211,7 @@ namespace Barotrauma.Tutorials
};
}
GUI.PlayUISound(GUISoundType.Message);
GUI.PlayUISound(GUISoundType.UIMessage);
return infoBlock;
}

View File

@@ -6,8 +6,11 @@ namespace Barotrauma
partial class GameSession
{
private InfoFrameTab selectedTab;
private GUIButton infoButton;
private GUIButton infoFrame;
/// <summary>
/// Determines whether the hotkey for the info button was held down in the previous frame.
/// </summary>
private bool prevInfoKey;
private GUIFrame infoFrameContent;
@@ -17,7 +20,12 @@ namespace Barotrauma
get { return roundSummary; }
}
private bool ToggleInfoFrame(GUIButton button, object obj)
partial void InitProjSpecific()
{
prevInfoKey = false;
}
private bool ToggleInfoFrame()
{
if (infoFrame == null)
{
@@ -36,10 +44,7 @@ namespace Barotrauma
{
int width = 600, height = 400;
infoFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker")
{
OnClicked = (btn, userdata) => { if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) ToggleInfoFrame(btn, userdata); return true; }
};
infoFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), infoFrame.RectTransform, Anchor.Center) { MinSize = new Point(width,height) });
@@ -63,6 +68,7 @@ namespace Barotrauma
OnClicked = SelectInfoFrameTab
};
/*TODO: fix
if (GameMain.Server != null)
{
var manageButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonArea.RectTransform), TextManager.Get("ManagePlayers"))
@@ -70,12 +76,7 @@ namespace Barotrauma
UserData = InfoFrameTab.ManagePlayers,
OnClicked = SelectInfoFrameTab
};
}
var closeButton = new GUIButton(new RectTransform(new Vector2(0.25f, 0.08f), paddedFrame.RectTransform, Anchor.BottomRight), TextManager.Get("Close"))
{
OnClicked = ToggleInfoFrame
};
}*/
}
@@ -94,7 +95,8 @@ namespace Barotrauma
CreateMissionInfo(infoFrameContent);
break;
case InfoFrameTab.ManagePlayers:
GameMain.Server.ManagePlayersFrame(infoFrameContent);
//TODO: fix
//GameMain.Server.ManagePlayersFrame(infoFrameContent);
break;
}
@@ -125,7 +127,6 @@ namespace Barotrauma
public void AddToGUIUpdateList()
{
if (GUI.DisableHUD) return;
infoButton.AddToGUIUpdateList();
GameMode?.AddToGUIUpdateList();
infoFrame?.AddToGUIUpdateList();
}
@@ -133,8 +134,13 @@ namespace Barotrauma
partial void UpdateProjSpecific(float deltaTime)
{
if (GUI.DisableHUD) return;
infoButton?.UpdateManually(deltaTime);
if (prevInfoKey != (PlayerInput.KeyDown(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber == null))
{
ToggleInfoFrame();
prevInfoKey = PlayerInput.KeyDown(InputType.InfoTab);
}
infoFrame?.UpdateManually(deltaTime);
}
@@ -142,8 +148,6 @@ namespace Barotrauma
{
if (GUI.DisableHUD) return;
infoButton.DrawManually(spriteBatch);
GameMode?.Draw(spriteBatch);
infoFrame?.DrawManually(spriteBatch);
}

View File

@@ -71,21 +71,17 @@ namespace Barotrauma
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)
{
GameMain.Server?.ConnectedClients.ForEach(c => c.Karma += 0.1f);
}
if (GameMain.GameSession.Mission.Completed && singleplayer)
{
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()));
}
}
else
foreach (GUIComponent child in infoTextBox.Content.Children)
{
GameMain.Server?.ConnectedClients.ForEach(c => c.Karma += 0.1f);
child.CanBeFocused = false;
}
foreach (GUIComponent child in infoTextBox.Content.Children)
{
@@ -100,7 +96,7 @@ namespace Barotrauma
foreach (CharacterInfo characterInfo in gameSession.CrewManager.GetCharacterInfos())
{
if (GameMain.GameSession.Mission is CombatMission &&
characterInfo.TeamID != GameMain.GameSession.CrewManager.WinningTeam)
characterInfo.TeamID != GameMain.GameSession.WinningTeam)
{
continue;
}

View File

@@ -1,6 +1,8 @@
using Microsoft.Xna.Framework;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using OpenTK.Audio.OpenAL;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -13,8 +15,10 @@ namespace Barotrauma
{
General,
Graphics,
Audio,
Controls,
}
private GUIFrame settingsFrame;
private GUIButton applyButton;
@@ -40,9 +44,9 @@ namespace Barotrauma
int index = text.Text.IndexOf("%");
string label = text.Text;
//if "%" is found
if(index > 0)
if (index > 0)
{
while(true)
while (true)
{
//search for end of label
index -= 1;
@@ -57,6 +61,10 @@ namespace Barotrauma
public void ResetSettingsFrame()
{
if (GameMain.Client == null)
{
VoipCapture.Instance?.Dispose();
}
settingsFrame = null;
}
@@ -66,12 +74,12 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), settingsFrame.RectTransform),
TextManager.Get("Settings"), textAlignment: Alignment.Center, font: GUI.LargeFont);
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.8f), settingsFrame.RectTransform, Anchor.Center)
{ RelativeOffset = new Vector2(0.0f, 0.06f) }, style: null);
{ RelativeOffset = new Vector2(0.0f, 0.06f) }, style: null);
var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.05f), settingsFrame.RectTransform, Anchor.TopCenter)
{ RelativeOffset = new Vector2(0.0f, 0.1f) }, isHorizontal: true);
{ RelativeOffset = new Vector2(0.0f, 0.11f) }, isHorizontal: true);
tabs = new GUIFrame[Enum.GetValues(typeof(Tab)).Length];
tabButtons = new GUIButton[tabs.Length];
@@ -81,7 +89,8 @@ namespace Barotrauma
{
UserData = tab
};
tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tabButtonHolder.RectTransform), tab.ToString())
tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tabButtonHolder.RectTransform),
TextManager.Get("SettingsTab." + tab.ToString()), style: "GUITabButton")
{
UserData = tab,
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
@@ -89,27 +98,40 @@ namespace Barotrauma
}
var buttonArea = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.08f), paddedFrame.RectTransform, Anchor.BottomCenter), style: null);
/// Graphics tab --------------------------------------------------------------
var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.CenterLeft)
{ RelativeOffset = new Vector2(0.02f, 0.0f) }) { RelativeSpacing = 0.01f, Stretch = true };
{ RelativeOffset = new Vector2(0.02f, 0.0f) })
{ RelativeSpacing = 0.01f, Stretch = true };
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Graphics].RectTransform, Anchor.CenterRight)
{ RelativeOffset = new Vector2(0.02f, 0.0f) }) { RelativeSpacing = 0.01f, Stretch = true };
{ RelativeOffset = new Vector2(0.02f, 0.0f) })
{ RelativeSpacing = 0.01f, Stretch = true };
var supportedDisplayModes = new List<DisplayMode>();
foreach (DisplayMode mode in GraphicsAdapter.DefaultAdapter.SupportedDisplayModes)
{
if (supportedDisplayModes.Any(m => m.Width == mode.Width && m.Height == mode.Height)) continue;
if (supportedDisplayModes.Any(m => m.Width == mode.Width && m.Height == mode.Height)) { continue; }
#if OSX
// Monogame currently doesn't support retina displays
// so we need to disable resolutions above the viewport size.
// In a bundled .app you just disable HiDPI in the info.plist
// but that's probably not gonna happen.
if (mode.Width > GameMain.Instance.GraphicsDevice.DisplayMode.Width || mode.Height > GameMain.Instance.GraphicsDevice.DisplayMode.Height) { continue; }
#endif
supportedDisplayModes.Add(mode);
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("Resolution"));
var resolutionDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), elementCount: supportedDisplayModes.Count)
{
OnSelected = SelectResolution
};
OnSelected = SelectResolution,
#if OSX
ButtonEnabled = GameMain.Config.WindowMode == WindowMode.Windowed
#endif
};
foreach (DisplayMode mode in supportedDisplayModes)
{
resolutionDD.AddItem(mode.Width + "x" + mode.Height, mode);
@@ -120,17 +142,33 @@ namespace Barotrauma
{
resolutionDD.SelectItem(GraphicsAdapter.DefaultAdapter.SupportedDisplayModes.Last());
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("DisplayMode"));
var displayModeDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform));
displayModeDD.AddItem(TextManager.Get("Fullscreen"), WindowMode.Fullscreen);
displayModeDD.AddItem(TextManager.Get("Windowed"), WindowMode.Windowed);
#if (!OSX)
displayModeDD.AddItem(TextManager.Get("BorderlessWindowed"), WindowMode.BorderlessWindowed);
displayModeDD.SelectItem(GameMain.Config.WindowMode);
displayModeDD.OnSelected = (guiComponent, obj) =>
#else
// Fullscreen option will just set itself to borderless on macOS.
if (GameMain.Config.WindowMode == WindowMode.BorderlessWindowed)
{
displayModeDD.SelectItem(WindowMode.Fullscreen);
}
else
{
displayModeDD.SelectItem(GameMain.Config.WindowMode);
}
#endif
displayModeDD.OnSelected = (guiComponent, obj) =>
{
UnsavedSettings = true;
GameMain.Config.WindowMode = (WindowMode)guiComponent.UserData;
#if OSX
resolutionDD.ButtonEnabled = GameMain.Config.WindowMode == WindowMode.Windowed;
#endif
return true;
};
@@ -139,6 +177,7 @@ namespace Barotrauma
GUITickBox vsyncTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("EnableVSync"))
{
ToolTip = TextManager.Get("EnableVSyncToolTip"),
OnSelected = (GUITickBox box) =>
{
VSyncEnabled = box.Selected;
@@ -150,7 +189,7 @@ namespace Barotrauma
},
Selected = VSyncEnabled
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), leftColumn.RectTransform), style: null);
GUITextBlock particleLimitText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("ParticleLimit"));
@@ -188,7 +227,7 @@ namespace Barotrauma
}
return true;
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: null);
GUITextBlock LightText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("LightMapScale"))
@@ -201,7 +240,7 @@ namespace Barotrauma
UserData = LightText,
ToolTip = TextManager.Get("LightMapScaleToolTip"),
BarScroll = MathUtils.InverseLerp(0.2f, 1.0f, LightMapScale),
OnMoved = (scrollBar, barScroll) =>
OnMoved = (scrollBar, barScroll) =>
{
ChangeSliderText(scrollBar, barScroll);
LightMapScale = MathHelper.Lerp(0.2f, 1.0f, barScroll);
@@ -238,7 +277,7 @@ namespace Barotrauma
return true;
}
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: null);
@@ -282,19 +321,258 @@ namespace Barotrauma
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), rightColumn.RectTransform), style: null);
/// Audio tab ----------------------------------------------------------------
var audioSliders = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.4f), tabs[(int)Tab.Audio].RectTransform, Anchor.TopCenter)
{ RelativeOffset = new Vector2(0.0f, 0.02f) })
{ RelativeSpacing = 0.01f, Stretch = true };
GUITextBlock soundVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), audioSliders.RectTransform), TextManager.Get("SoundVolume"));
GUIScrollBar soundScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.2f), audioSliders.RectTransform),
barSize: 0.1f)
{
UserData = soundVolumeText,
BarScroll = SoundVolume,
OnMoved = (scrollBar, scroll) =>
{
ChangeSliderText(scrollBar, scroll);
SoundVolume = scroll;
return true;
},
Step = 0.05f
};
soundScrollBar.OnMoved(soundScrollBar, soundScrollBar.BarScroll);
GUITextBlock musicVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.18f), audioSliders.RectTransform), TextManager.Get("MusicVolume"));
GUIScrollBar musicScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.18f), audioSliders.RectTransform),
barSize: 0.1f)
{
UserData = musicVolumeText,
BarScroll = MusicVolume,
OnMoved = (scrollBar, scroll) =>
{
ChangeSliderText(scrollBar, scroll);
MusicVolume = scroll;
return true;
},
Step = 0.05f
};
musicScrollBar.OnMoved(musicScrollBar, musicScrollBar.BarScroll);
GUITextBlock voiceChatVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.18f), audioSliders.RectTransform), TextManager.Get("VoiceChatVolume"));
GUIScrollBar voiceChatScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.18f), audioSliders.RectTransform),
barSize: 0.1f)
{
UserData = voiceChatVolumeText,
BarScroll = VoiceChatVolume,
OnMoved = (scrollBar, scroll) =>
{
ChangeSliderText(scrollBar, scroll);
VoiceChatVolume = scroll;
return true;
},
Step = 0.05f
};
voiceChatScrollBar.OnMoved(voiceChatScrollBar, voiceChatScrollBar.BarScroll);
GUITickBox muteOnFocusLostBox = new GUITickBox(new RectTransform(new Vector2(0.95f, 0.15f), audioSliders.RectTransform), TextManager.Get("MuteOnFocusLost"));
muteOnFocusLostBox.Selected = MuteOnFocusLost;
muteOnFocusLostBox.ToolTip = TextManager.Get("MuteOnFocusLostToolTip");
muteOnFocusLostBox.OnSelected = (tickBox) =>
{
MuteOnFocusLost = tickBox.Selected;
return true;
};
var voiceSettings = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.5f), tabs[(int)Tab.Audio].RectTransform, Anchor.BottomCenter)
{ RelativeOffset = new Vector2(0.0f, 0.04f) })
{ RelativeSpacing = 0.01f, Stretch = true };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), voiceSettings.RectTransform), TextManager.Get("VoiceChat"));
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.2f), rightColumn.RectTransform), style: null);
IList<string> deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier);
foreach (string name in deviceNames)
{
DebugConsole.NewMessage(name + " " + name.Length.ToString(), Color.Lime);
}
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice)) VoiceCaptureDevice = deviceNames[0];
#if (!OSX)
var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.2f), voiceSettings.RectTransform), VoiceCaptureDevice, deviceNames.Count);
foreach (string name in deviceNames)
{
deviceList.AddItem(name, name);
}
deviceList.OnSelected = (GUIComponent selected, object obj) =>
{
string name = obj as string;
if (VoiceCaptureDevice == name) return true;
VoipCapture.ChangeCaptureDevice(name);
return true;
};
#else
var suavemente = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.2f), voiceSettings.RectTransform), TextManager.Get("CurrentDevice") + ": " + VoiceCaptureDevice)
{
ToolTip = TextManager.Get("CurrentDeviceToolTip.OSX"),
TextAlignment = Alignment.CenterX
};
new GUIButton(new RectTransform(new Vector2(1.0f, 0.25f), voiceSettings.RectTransform), TextManager.Get("RefreshDefaultDevice"))
{
ToolTip = TextManager.Get("RefreshDefaultDeviceToolTip"),
OnClicked = (bt, userdata) =>
{
deviceNames = Alc.GetString((IntPtr)null, AlcGetStringList.CaptureDeviceSpecifier);
if (VoiceCaptureDevice == deviceNames[0]) return true;
VoipCapture.ChangeCaptureDevice(deviceNames[0]);
suavemente.Text = TextManager.Get("CurrentDevice") + ": " + VoiceCaptureDevice;
suavemente.Flash(Color.Blue);
return true;
}
};
#endif
var radioButtonFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), voiceSettings.RectTransform))
{
Stretch = true,
RelativeSpacing = 0.05f
};
GUIRadioButtonGroup voiceMode = new GUIRadioButtonGroup();
for (int i = 0; i < 3; i++)
{
string langStr = "VoiceMode." + ((VoiceMode)i).ToString();
var tick = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.33f), radioButtonFrame.RectTransform), TextManager.Get(langStr))
{
ToolTip = TextManager.Get(langStr + "ToolTip")
};
voiceMode.AddRadioButton((VoiceMode)i, tick);
}
var voiceInputContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.2f), voiceSettings.RectTransform, Anchor.BottomCenter));
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), voiceInputContainer.RectTransform), TextManager.Get("InputType.Voice") + ": ");
var voiceKeyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), voiceInputContainer.RectTransform, Anchor.TopRight),
text: keyMapping[(int)InputType.Voice].ToString())
{
UserData = InputType.Voice
};
voiceKeyBox.OnSelected += KeyBoxSelected;
voiceKeyBox.SelectedColor = Color.Gold * 0.3f;
var voiceActivityGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), voiceSettings.RectTransform));
GUITextBlock noiseGateText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), voiceActivityGroup.RectTransform), TextManager.Get("NoiseGateThreshold"))
{
TextGetter = () =>
{
return TextManager.Get("NoiseGateThreshold") + " " + ((int)NoiseGateThreshold).ToString() + " dB";
}
};
var dbMeter = new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.5f), voiceActivityGroup.RectTransform), 0.0f, Color.Lime);
dbMeter.ProgressGetter = () =>
{
if (VoipCapture.Instance == null) return 0.0f;
dbMeter.Color = VoipCapture.Instance.LastdB > NoiseGateThreshold ? Color.Lime : Color.Orange; //TODO: i'm a filthy hack
return ((float)VoipCapture.Instance.LastdB + 100.0f) / 100.0f;
};
var noiseGateSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 1.0f), dbMeter.RectTransform, Anchor.Center), color: Color.White, barSize: 0.03f);
noiseGateSlider.Frame.Visible = false;
noiseGateSlider.Step = 0.01f;
noiseGateSlider.Range = new Vector2(-100.0f, 0.0f);
noiseGateSlider.BarScrollValue = NoiseGateThreshold;
noiseGateSlider.OnMoved = (GUIScrollBar scrollBar, float barScroll) =>
{
NoiseGateThreshold = scrollBar.BarScrollValue;
UnsavedSettings = true;
return true;
};
voiceMode.OnSelect = (GUIRadioButtonGroup rbg, Enum value) =>
{
if (rbg.Selected != null && rbg.Selected.Equals(value)) return;
VoiceMode vMode = (VoiceMode)value;
VoiceSetting = vMode;
if (vMode == VoiceMode.Activity)
{
voiceActivityGroup.Visible = true;
if (GameMain.Client == null && VoipCapture.Instance == null)
{
VoipCapture.Create(GameMain.Config.VoiceCaptureDevice);
}
}
else
{
voiceActivityGroup.Visible = false;
if (GameMain.Client == null)
{
VoipCapture.Instance?.Dispose();
}
}
voiceInputContainer.Visible = (vMode == VoiceMode.PushToTalk);
UnsavedSettings = true;
};
voiceMode.Selected = VoiceSetting;
/// Controls tab -------------------------------------------------------------
var controlsLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), tabs[(int)Tab.Controls].RectTransform, Anchor.Center)
{ RelativeOffset = new Vector2(0.0f, 0.0f) })
{ RelativeSpacing = 0.01f, Stretch = true };
var inputFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), controlsLayoutGroup.RectTransform))
{
Stretch = true
};
var inputNames = Enum.GetValues(typeof(InputType));
for (int i = 0; i < inputNames.Length; i++)
{
var inputContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), inputContainer.RectTransform), TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont);
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), inputContainer.RectTransform, Anchor.TopRight),
text: keyMapping[i].ToString(), font: GUI.SmallFont)
{
UserData = i
};
keyBox.OnSelected += KeyBoxSelected;
keyBox.SelectedColor = Color.Gold * 0.3f;
}
GUITextBlock aimAssistText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), controlsLayoutGroup.RectTransform), TextManager.Get("AimAssist"));
GUIScrollBar aimAssistSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), controlsLayoutGroup.RectTransform),
barSize: 0.1f)
{
UserData = aimAssistText,
BarScroll = MathUtils.InverseLerp(0.0f, 5.0f, AimAssistAmount),
OnMoved = (scrollBar, scroll) =>
{
ChangeSliderText(scrollBar, scroll);
AimAssistAmount = MathHelper.Lerp(0.0f, 5.0f, scroll);
return true;
},
Step = 0.1f
};
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
/// General tab --------------------------------------------------------------
leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.General].RectTransform, Anchor.CenterLeft)
{ RelativeOffset = new Vector2(0.02f, 0.0f) }) { RelativeSpacing = 0.01f, Stretch = true };
rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.General].RectTransform, Anchor.CenterRight)
{ RelativeOffset = new Vector2(0.02f, 0.0f) }) { RelativeSpacing = 0.01f, Stretch = true };
var generalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), tabs[(int)Tab.General].RectTransform, Anchor.Center)
{ RelativeOffset = new Vector2(0.0f, 0.0f) }) { RelativeSpacing = 0.01f, Stretch = true };
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("ContentPackages"));
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), leftColumn.RectTransform))
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("ContentPackages"));
var contentPackageList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), generalLayoutGroup.RectTransform))
{
CanBeFocused = false
};
foreach (ContentPackage contentPackage in ContentPackage.List)
{
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), contentPackageList.Content.RectTransform, minSize: new Point(0, 15)), contentPackage.Name)
@@ -321,84 +599,6 @@ namespace Barotrauma
.Replace("[missingfiletypes]", string.Join(", ", missingContentTypes));
}
}
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("Language"));
var languageDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform));
foreach (string language in TextManager.AvailableLanguages)
{
languageDD.AddItem(language, language);
}
languageDD.SelectItem(TextManager.Language);
languageDD.OnSelected = (guiComponent, obj) =>
{
string newLanguage = obj as string;
if (newLanguage == Language) return true;
UnsavedSettings = true;
Language = newLanguage;
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
return true;
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), leftColumn.RectTransform), style: null);
GUITextBlock soundVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("SoundVolume"));
GUIScrollBar soundScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform),
barSize: 0.1f)
{
UserData = soundVolumeText,
BarScroll = SoundVolume,
OnMoved = (scrollBar, scroll) =>
{
ChangeSliderText(scrollBar, scroll);
SoundVolume = scroll;
return true;
},
Step = 0.05f
};
soundScrollBar.OnMoved(soundScrollBar, soundScrollBar.BarScroll);
GUITextBlock musicVolumeText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform), TextManager.Get("MusicVolume"));
GUIScrollBar musicScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), leftColumn.RectTransform),
barSize: 0.1f)
{
UserData = musicVolumeText,
BarScroll = MusicVolume,
OnMoved = (scrollBar, scroll) =>
{
ChangeSliderText(scrollBar, scroll);
MusicVolume = scroll;
return true;
},
Step = 0.05f
};
musicScrollBar.OnMoved(musicScrollBar, musicScrollBar.BarScroll);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("Controls"));
var inputFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform))
{
Stretch = true
};
var inputNames = Enum.GetValues(typeof(InputType));
for (int i = 0; i < inputNames.Length; i++)
{
var inputContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.06f), inputFrame.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), inputContainer.RectTransform), TextManager.Get("InputType." + ((InputType)i)) + ": ", font: GUI.SmallFont);
var keyBox = new GUITextBox(new RectTransform(new Vector2(0.4f, 1.0f), inputContainer.RectTransform, Anchor.TopRight),
text: keyMapping[i].ToString(), font: GUI.SmallFont)
{
UserData = i
};
keyBox.OnSelected += KeyBoxSelected;
keyBox.SelectedColor = Color.Gold * 0.3f;
}
GUITextBlock aimAssistText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("AimAssist"));
GUIScrollBar aimAssistSlider = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
barSize: 0.1f)
@@ -415,14 +615,43 @@ namespace Barotrauma
};
aimAssistSlider.OnMoved(aimAssistSlider, aimAssistSlider.BarScroll);
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform), TextManager.Get("Language"));
var languageDD = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), generalLayoutGroup.RectTransform));
foreach (string language in TextManager.AvailableLanguages)
{
languageDD.AddItem(TextManager.Get("Language." + language), language);
}
languageDD.SelectItem(TextManager.Language);
languageDD.OnSelected = (guiComponent, obj) =>
{
string newLanguage = obj as string;
if (newLanguage == Language) return true;
UnsavedSettings = true;
Language = newLanguage;
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
return true;
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft),
TextManager.Get("Cancel"))
{
IgnoreLayoutGroups = true,
OnClicked = (x, y) =>
OnClicked = (x, y) =>
{
if (GameMain.Config.UnsavedSettings) GameMain.Config.Load("config.xml");
if (Screen.Selected == GameMain.MainMenuScreen) GameMain.MainMenuScreen.SelectTab(0);
if (UnsavedSettings)
{
LoadPlayerConfig();
}
if (Screen.Selected == GameMain.MainMenuScreen) GameMain.MainMenuScreen.ReturnToMainMenu(null, null);
GUI.SettingsMenuOpen = false;
return true;
}
@@ -436,11 +665,30 @@ namespace Barotrauma
};
applyButton.OnClicked = ApplyClicked;
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
SelectTab(Tab.General);
}
private void SelectTab(Tab tab)
{
switch (tab)
{
case Tab.Audio:
if (VoiceSetting == VoiceMode.Activity)
{
if (GameMain.Client == null && VoipCapture.Instance == null)
{
VoipCapture.Create(GameMain.Config.VoiceCaptureDevice);
}
}
break;
default:
if (GameMain.Client == null)
{
VoipCapture.Instance?.Dispose();
}
break;
}
for (int i = 0; i < tabs.Length; i++)
{
tabs[i].Visible = (Tab)tabs[i].UserData == tab;
@@ -453,7 +701,7 @@ namespace Barotrauma
textBox.Text = "";
CoroutineManager.StartCoroutine(WaitForKeyPress(textBox));
}
private bool SelectResolution(GUIComponent selected, object userData)
{
DisplayMode mode = selected.UserData as DisplayMode;
@@ -512,14 +760,15 @@ namespace Barotrauma
private IEnumerable<object> WaitForKeyPress(GUITextBox keyBox)
{
yield return CoroutineStatus.Running;
while (PlayerInput.LeftButtonHeld() || PlayerInput.LeftButtonClicked())
{
//wait for the mouse to be released, so that we don't interpret clicking on the textbox as the keybinding
yield return CoroutineStatus.Running;
}
while (keyBox.Selected && PlayerInput.GetKeyboardState.GetPressedKeys().Length == 0 &&
!PlayerInput.LeftButtonClicked() && !PlayerInput.RightButtonClicked() && !PlayerInput.MidButtonClicked())
while (keyBox.Selected && PlayerInput.GetKeyboardState.GetPressedKeys().Length == 0 &&
!PlayerInput.LeftButtonClicked() && !PlayerInput.RightButtonClicked() && !PlayerInput.MidButtonClicked() &&
!PlayerInput.Mouse4ButtonClicked() && !PlayerInput.Mouse5ButtonClicked() && !PlayerInput.MouseWheelUpClicked() && !PlayerInput.MouseWheelDownClicked())
{
if (Screen.Selected != GameMain.MainMenuScreen && !GUI.SettingsMenuOpen) yield return CoroutineStatus.Success;
@@ -545,6 +794,26 @@ namespace Barotrauma
keyMapping[keyIndex] = new KeyOrMouse(2);
keyBox.Text = "Mouse3";
}
else if (PlayerInput.Mouse4ButtonClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(3);
keyBox.Text = "Mouse4";
}
else if (PlayerInput.Mouse5ButtonClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(4);
keyBox.Text = "Mouse5";
}
else if (PlayerInput.MouseWheelUpClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(5);
keyBox.Text = "MouseWheelUp";
}
else if (PlayerInput.MouseWheelDownClicked())
{
keyMapping[keyIndex] = new KeyOrMouse(6);
keyBox.Text = "MouseWheelDown";
}
else if (PlayerInput.GetKeyboardState.GetPressedKeys().Length > 0)
{
Keys key = PlayerInput.GetKeyboardState.GetPressedKeys()[0];
@@ -560,21 +829,28 @@ namespace Barotrauma
yield return CoroutineStatus.Success;
}
private bool ApplyClicked(GUIButton button, object userData)
{
Save();
SaveNewPlayerConfig();
settingsFrame.Flash(Color.Green);
if (GameMain.WindowMode != GameMain.Config.WindowMode)
{
GameMain.Instance.SetWindowMode(GameMain.Config.WindowMode);
GameMain.Instance.ApplyGraphicsSettings();
}
if (GameMain.GraphicsWidth != GameMain.Config.GraphicsWidth || GameMain.GraphicsHeight != GameMain.Config.GraphicsHeight)
{
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredResolution"));
#if OSX
if (GameMain.Config.WindowMode != WindowMode.BorderlessWindowed)
{
#endif
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredResolution"));
#if OSX
}
#endif
}
if (Screen.Selected != GameMain.MainMenuScreen) GUI.SettingsMenuOpen = false;

View File

@@ -458,8 +458,8 @@ namespace Barotrauma
slots[i].QuickUseTimer = Math.Max(0.1f, slots[i].QuickUseTimer + deltaTime);
if (slots[i].QuickUseTimer >= 1.0f)
{
CreateNetworkEvent();
Items[i].Drop(Character.Controlled);
GUI.PlayUISound(GUISoundType.DropItem);
}
}
else

View File

@@ -4,7 +4,6 @@ using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
namespace Barotrauma.Items.Components
{
partial class Door : Pickable, IDrawableComponent, IServerSerializable
@@ -12,6 +11,15 @@ namespace Barotrauma.Items.Components
private ConvexHull convexHull;
private ConvexHull convexHull2;
//openState when the vertices of the convex hull were last calculated
private float lastConvexHullState;
public Vector2 DrawSize
{
//use the extents of the item as the draw size
get { return Vector2.Zero; }
}
private Vector2[] GetConvexHullCorners(Rectangle rect)
{
Vector2[] corners = new Vector2[4];
@@ -32,7 +40,7 @@ namespace Barotrauma.Items.Components
(int)(doorSprite.size.Y * item.Scale));
Rectangle rect = doorRect;
if (isHorizontal)
if (IsHorizontal)
{
rect.Width = (int)(rect.Width * (1.0f - openState));
}
@@ -41,9 +49,9 @@ namespace Barotrauma.Items.Components
rect.Height = (int)(rect.Height * (1.0f - openState));
}
if (window.Height > 0 && window.Width > 0)
if (Window.Height > 0 && Window.Width > 0)
{
rect.Height = -(int)(window.Y * item.Scale);
rect.Height = -(int)(Window.Y * item.Scale);
rect.Y += (int)(doorRect.Height * openState);
rect.Height = Math.Max(rect.Height - (rect.Y - doorRect.Y), 0);
@@ -52,7 +60,7 @@ namespace Barotrauma.Items.Components
if (convexHull2 != null)
{
Rectangle rect2 = doorRect;
rect2.Y = rect2.Y + (int)((window.Y * item.Scale - window.Height * item.Scale));
rect2.Y = rect2.Y + (int)((Window.Y * item.Scale - Window.Height * item.Scale));
rect2.Y += (int)(doorRect.Height * openState);
rect2.Y = Math.Min(doorRect.Y, rect2.Y);
@@ -105,11 +113,11 @@ namespace Barotrauma.Items.Components
if (openState == 1.0f)
{
body.Enabled = false;
Body.Enabled = false;
return;
}
if (isHorizontal)
if (IsHorizontal)
{
Vector2 pos = new Vector2(item.Rect.X, item.Rect.Y - item.Rect.Height / 2);
if (item.Submarine != null) pos += item.Submarine.DrawPosition;
@@ -159,9 +167,49 @@ namespace Barotrauma.Items.Components
(int)brokenSprite.size.X, (int)(brokenSprite.size.Y * (1.0f - openState))),
color * alpha, 0.0f, brokenSprite.Origin, scale * item.Scale, SpriteEffects.None, brokenSprite.Depth);
}
}
}
partial void SetState(bool open, bool isNetworkMessage, bool sendNetworkMessage)
{
if (isStuck ||
(PredictedState == null && isOpen == open) ||
(PredictedState != null && isOpen == PredictedState.Value && isOpen == open))
{
return;
}
if (GameMain.Client != null && !isNetworkMessage)
{
bool stateChanged = open != PredictedState;
//clients can "predict" that the door opens/closes when a signal is received
//the prediction will be reset after 1 second, setting the door to a state
//sent by the server, or reverting it back to its old state if no msg from server was received
PredictedState = open;
resetPredictionTimer = CorrectionDelay;
if (stateChanged) PlaySound(ActionType.OnUse, item.WorldPosition);
}
else
{
isOpen = open;
if (!isNetworkMessage || open != PredictedState) PlaySound(ActionType.OnUse, item.WorldPosition);
}
//opening a partially stuck door makes it less stuck
if (isOpen) stuck = MathHelper.Clamp(stuck - 30.0f, 0.0f, 100.0f);
}
public override void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer msg, float sendingTime)
{
base.ClientRead(type, msg, sendingTime);
SetState(msg.ReadBoolean(), isNetworkMessage: true, sendNetworkMessage: false);
Stuck = msg.ReadRangedSingle(0.0f, 100.0f, 8);
PredictedState = null;
}
}
}

View File

@@ -35,7 +35,15 @@ namespace Barotrauma.Items.Components
get { return RoundSound.Range; }
}
public float VolumeMultiplier
{
get { return RoundSound.Volume; }
}
public float Range
{
get { return RoundSound.Range; }
}
public readonly bool Loop;
@@ -309,15 +317,15 @@ namespace Barotrauma.Items.Components
private float GetSoundVolume(ItemSound sound)
{
if (sound == null) return 0.0f;
if (sound.VolumeProperty == "") return 1.0f;
if (sound == null) { return 0.0f; }
if (sound.VolumeProperty == "") { return sound.VolumeMultiplier; }
if (properties.TryGetValue(sound.VolumeProperty.ToLowerInvariant(), out SerializableProperty property))
if (properties.TryGetValue(sound.VolumeProperty, out SerializableProperty property))
{
float newVolume = 0.0f;
try
{
newVolume = (float)property.GetValue();
newVolume = (float)property.GetValue(this);
}
catch
{
@@ -353,7 +361,7 @@ namespace Barotrauma.Items.Components
{
return null;
}
foreach (ItemComponent component in item.components)
foreach (ItemComponent component in item.Components)
{
if (component.name.ToLower() == LinkUIToComponent.ToLower())
{
@@ -427,9 +435,10 @@ namespace Barotrauma.Items.Components
}
RoundSound sound = Submarine.LoadRoundSound(subElement);
if (sound == null) { break; }
ItemSound itemSound = new ItemSound(sound, type, subElement.GetAttributeBool("loop", false))
{
VolumeProperty = subElement.GetAttributeString("volumeproperty", "")
VolumeProperty = subElement.GetAttributeString("volumeproperty", "").ToLowerInvariant()
};
if (soundSelectionModes == null) soundSelectionModes = new Dictionary<ActionType, SoundSelectionMode>();

View File

@@ -72,7 +72,13 @@ namespace Barotrauma.Items.Components
get;
set;
}
public Vector2 DrawSize
{
//use the extents of the item as the draw size
get { return Vector2.Zero; }
}
partial void InitProjSpecific(XElement element)
{
foreach (XElement subElement in element.Elements())
@@ -169,9 +175,10 @@ namespace Barotrauma.Items.Components
item.IsHighlighted = false;
}
if (containedItem.body != null)
if (containedItem.body != null &&
Math.Abs(containedItem.body.FarseerBody.Rotation - currentRotation) > 0.001f)
{
containedItem.body.FarseerBody.Rotation = currentRotation;
containedItem.body.SetTransformIgnoreContacts(containedItem.body.SimPosition, currentRotation);
}
containedItem.Sprite.Draw(

View File

@@ -209,6 +209,7 @@ namespace Barotrauma.Items.Components
return;
}
textBlock.TextDepth = item.SpriteDepth - 0.0001f;
textBlock.TextOffset = drawPos - textBlock.Rect.Location.ToVector2() + new Vector2(scrollAmount + scrollPadding, 0.0f);
textBlock.DrawManually(spriteBatch);
}

View File

@@ -8,6 +8,11 @@ namespace Barotrauma.Items.Components
{
partial class LightComponent : Powered, IServerSerializable, IDrawableComponent
{
public Vector2 DrawSize
{
get { return new Vector2(light.Range * 2, light.Range * 2); }
}
private LightSource light;
public LightSource Light
{

View File

@@ -8,7 +8,7 @@ namespace Barotrauma.Items.Components
{
if (focusTarget != null && character.ViewTarget == focusTarget)
{
foreach (ItemComponent ic in focusTarget.components)
foreach (ItemComponent ic in focusTarget.Components)
{
ic.DrawHUD(spriteBatch, character);
}

View File

@@ -79,12 +79,8 @@ namespace Barotrauma.Items.Components
SetActive(!IsActive, Character.Controlled);
currPowerConsumption = IsActive ? powerConsumption : 0.0f;
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
item.CreateClientEvent(this);
}

View File

@@ -22,6 +22,12 @@ namespace Barotrauma.Items.Components
private set;
}
public Vector2 DrawSize
{
//use the extents of the item as the draw size
get { return Vector2.Zero; }
}
partial void InitProjSpecific(XElement element)
{
powerIndicator = new GUITickBox(new RectTransform(new Point(30, 30), GuiFrame.RectTransform) { RelativeOffset = new Vector2(0.05f, 0.15f) },
@@ -51,12 +57,8 @@ namespace Barotrauma.Items.Components
if (Math.Abs(newTargetForce - targetForce) < 0.01) return false;
targetForce = newTargetForce;
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
GameServer.Log(Character.Controlled.LogName + " set the force speed of " + item.Name + " to " + (int)(targetForce) + " %", ServerLog.MessageType.ItemInteraction);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
correctionTimer = CorrectionDelay;
item.CreateClientEvent(this);

View File

@@ -306,13 +306,6 @@ namespace Barotrauma.Items.Components
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedFrame.RectTransform), text,
textColor: inadequateSkills.Any() ? Color.Red : Color.LightGreen, font: GUI.SmallFont);
}
if (tooltip != null)
{
GUIComponent.DrawToolTip(spriteBatch, tooltip.Second, tooltip.First);
tooltip = null;
}
}
float degreeOfSuccess = user == null ? 0.0f : DegreeOfSuccess(user, selectedItem.RequiredSkills);
if (degreeOfSuccess > 0.5f) { degreeOfSuccess = 1.0f; }
@@ -343,11 +336,7 @@ namespace Barotrauma.Items.Components
CancelFabricating(Character.Controlled);
}
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
item.CreateClientEvent(this);
}

View File

@@ -79,7 +79,7 @@ namespace Barotrauma.Items.Components
CreateHUD();
}
float distort = 1.0f - item.Condition / 100.0f;
float distort = 1.0f - item.Condition / item.Prefab.Health;
foreach (HullData hullData in hullDatas.Values)
{
hullData.DistortionTimer -= deltaTime;

View File

@@ -59,12 +59,7 @@ namespace Barotrauma.Items.Components
IsActive = active;
if (!IsActive) currPowerConsumption = 0.0f;
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
GameServer.Log(Character.Controlled.LogName + (IsActive ? " turned on " : " turned off ") + item.Name, ServerLog.MessageType.ItemInteraction);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
correctionTimer = CorrectionDelay;
item.CreateClientEvent(this);
@@ -102,12 +97,8 @@ namespace Barotrauma.Items.Components
if (Math.Abs(newValue - FlowPercentage) < 0.1f) return false;
FlowPercentage = newValue;
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
GameServer.Log(Character.Controlled.LogName + " set the pumping speed of " + item.Name + " to " + (int)(flowPercentage) + " %", ServerLog.MessageType.ItemInteraction);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
correctionTimer = CorrectionDelay;
item.CreateClientEvent(this);

View File

@@ -162,10 +162,6 @@ namespace Barotrauma.Items.Components
OnMoved = (GUIScrollBar bar, float scrollAmount) =>
{
LastUser = Character.Controlled;
if (nextServerLogWriteTime == null)
{
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
}
unsentChanges = true;
targetFissionRate = scrollAmount * 100.0f;
@@ -181,10 +177,6 @@ namespace Barotrauma.Items.Components
OnMoved = (GUIScrollBar bar, float scrollAmount) =>
{
LastUser = Character.Controlled;
if (nextServerLogWriteTime == null)
{
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
}
unsentChanges = true;
targetTurbineOutput = scrollAmount * 100.0f;
@@ -209,10 +201,6 @@ namespace Barotrauma.Items.Components
OnMoved = (scrollBar, scrollAmount) =>
{
LastUser = Character.Controlled;
if (nextServerLogWriteTime == null)
{
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
}
unsentChanges = true;
return true;
}
@@ -227,10 +215,6 @@ namespace Barotrauma.Items.Components
OnMoved = (scrollBar, scrollAmount) =>
{
LastUser = Character.Controlled;
if (nextServerLogWriteTime == null)
{
nextServerLogWriteTime = Math.Max(lastServerLogWriteTime + 1.0f, (float)Timing.TotalTime);
}
unsentChanges = true;
return true;
}

View File

@@ -11,6 +11,12 @@ namespace Barotrauma.Items.Components
{
partial class Sonar : Powered, IServerSerializable, IClientSerializable
{
enum Mode
{
Active,
Passive
};
private bool unsentChanges;
private float networkUpdateTimer;
@@ -86,17 +92,12 @@ namespace Barotrauma.Items.Components
ToolTip = TextManager.Get("SonarTipActive"),
OnSelected = (GUITickBox box) =>
{
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
IsActive = box.Selected;
if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
}
IsActive = box.Selected;
return true;
}
};
@@ -111,11 +112,7 @@ namespace Barotrauma.Items.Components
OnMoved = (scrollbar, scroll) =>
{
zoom = MathHelper.Lerp(MinZoom, MaxZoom, scroll);
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
@@ -136,11 +133,7 @@ namespace Barotrauma.Items.Components
OnSelected = (tickBox) =>
{
useDirectionalPing = tickBox.Selected;
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
@@ -154,11 +147,7 @@ namespace Barotrauma.Items.Components
{
float pingAngle = MathHelper.Lerp(0.0f, MathHelper.TwoPi, scroll);
pingDirection = new Vector2((float)Math.Cos(pingAngle), (float)Math.Sin(pingAngle));
if (GameMain.Server != null)
{
unsentChanges = true;
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
unsentChanges = true;
correctionTimer = CorrectionDelay;
@@ -168,9 +157,12 @@ namespace Barotrauma.Items.Components
};
signalWarningText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.15f), paddedControlContainer.RectTransform), "", Color.Orange, textAlignment: Alignment.Center);
GUITickBox.CreateRadioButtonGroup(new List<GUITickBox>() { activeTickBox, passiveTickBox });
GUIRadioButtonGroup sonarMode = new GUIRadioButtonGroup();
sonarMode.AddRadioButton(Mode.Active, activeTickBox);
sonarMode.AddRadioButton(Mode.Passive, passiveTickBox);
sonarMode.Selected = Mode.Passive;
GuiFrame.CanBeFocused = false;
}
@@ -183,27 +175,20 @@ namespace Barotrauma.Items.Components
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
{
if (unsentChanges)
if (GameMain.Client != null)
{
if (networkUpdateTimer <= 0.0f)
if (unsentChanges)
{
#if CLIENT
if (GameMain.Client != null)
if (networkUpdateTimer <= 0.0f)
{
item.CreateClientEvent(this);
correctionTimer = CorrectionDelay;
networkUpdateTimer = 0.1f;
unsentChanges = false;
}
#endif
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
}
networkUpdateTimer = 0.1f;
unsentChanges = false;
}
networkUpdateTimer -= deltaTime;
}
networkUpdateTimer -= deltaTime;
if (sonarView.Rect.Contains(PlayerInput.MousePosition))
{
@@ -215,7 +200,7 @@ namespace Barotrauma.Items.Components
}
}
float distort = 1.0f - item.Condition / 100.0f;
float distort = 1.0f - item.Condition / item.Prefab.Health;
for (int i = sonarBlips.Count - 1; i >= 0; i--)
{
sonarBlips[i].FadeTimer -= deltaTime * MathHelper.Lerp(0.5f, 2.0f, distort);
@@ -304,18 +289,22 @@ namespace Barotrauma.Items.Components
return;
}
float passivePingRadius = (float)Math.Sin(Timing.TotalTime * 10);
float passivePingRadius = (float)(Timing.TotalTime % 1.0f);
if (passivePingRadius > 0.0f)
{
disruptedDirections.Clear();
foreach (AITarget t in AITarget.List)
{
if (t.SoundRange <= 0.0f || !t.Enabled) continue;
if (t.SoundRange <= 0.0f || !t.Enabled) { continue; }
float distSqr = Vector2.DistanceSquared(t.WorldPosition, transducerCenter);
if (distSqr > t.SoundRange * t.SoundRange * 2) { continue; }
if (Vector2.DistanceSquared(t.WorldPosition, transducerCenter) < t.SoundRange * t.SoundRange)
float dist = (float)Math.Sqrt(distSqr);
if (dist > prevPassivePingRadius * Range && dist <= passivePingRadius * Range)
{
Ping(t.WorldPosition, transducerCenter,
t.SoundRange * passivePingRadius * 0.2f, t.SoundRange * prevPassivePingRadius * 0.2f, displayScale, t.SoundRange,
Ping(t.WorldPosition, transducerCenter,
Math.Min(t.SoundRange, range * 0.5f) * displayScale, 0, displayScale, Math.Min(t.SoundRange, range * 0.5f),
passive: true, pingStrength: 0.5f);
sonarBlips.Add(new SonarBlip(t.WorldPosition, 1.0f, 1.0f));
}
@@ -653,25 +642,25 @@ namespace Barotrauma.Items.Components
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y),
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y),
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y),
new Vector2(item.CurrentHull.WorldRect.X, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
CreateBlipsForLine(
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y),
new Vector2(item.CurrentHull.WorldRect.Right, item.CurrentHull.WorldRect.Y - item.CurrentHull.Rect.Height),
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius, 50.0f, 5.0f, range, 2.0f, passive);
return;
@@ -708,7 +697,7 @@ namespace Barotrauma.Items.Components
CreateBlipsForLine(
start + submarine.WorldPosition,
end + submarine.WorldPosition,
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius,
200.0f, 2.0f, range, 1.0f, passive);
}
@@ -721,7 +710,7 @@ namespace Barotrauma.Items.Components
CreateBlipsForLine(
new Vector2(pingSource.X - range, Level.Loaded.Size.Y),
new Vector2(pingSource.X + range, Level.Loaded.Size.Y),
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius,
250.0f, 150.0f, range, pingStrength, passive);
}
@@ -742,7 +731,7 @@ namespace Barotrauma.Items.Components
CreateBlipsForLine(
edge.Point1 + cell.Translation,
edge.Point2 + cell.Translation,
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius,
350.0f, 3.0f * (Math.Abs(facingDot) + 1.0f), range, pingStrength, passive);
}
@@ -763,7 +752,7 @@ namespace Barotrauma.Items.Components
CreateBlipsForLine(
wall.A, wall.B,
transducerPos,
pingSource, transducerPos,
pingRadius, prevPingRadius,
100.0f, 1000.0f, range, pingStrength, passive);
}
@@ -813,7 +802,7 @@ namespace Barotrauma.Items.Components
}
}
private void CreateBlipsForLine(Vector2 point1, Vector2 point2, Vector2 transducerPos, float pingRadius, float prevPingRadius,
private void CreateBlipsForLine(Vector2 point1, Vector2 point2, Vector2 pingSource, Vector2 transducerPos, float pingRadius, float prevPingRadius,
float lineStep, float zStep, float range, float pingStrength, bool passive)
{
lineStep /= zoom;
@@ -824,19 +813,25 @@ namespace Barotrauma.Items.Components
for (float x = 0; x < length; x += lineStep * Rand.Range(0.8f, 1.2f))
{
Vector2 point = point1 + lineDir * x;
//point += cell.Translation;
Vector2 pointDiff = point - transducerPos;
float pointDist = pointDiff.Length();
float displayPointDist = pointDist * displayScale;
//ignore if outside the display
Vector2 transducerDiff = point - transducerPos;
Vector2 transducerDisplayDiff = transducerDiff * displayScale;
if (transducerDisplayDiff.LengthSquared() > DisplayRadius * DisplayRadius) continue;
if (displayPointDist > DisplayRadius) continue;
if (displayPointDist < prevPingRadius || displayPointDist > pingRadius) continue;
//ignore if the point is not within the ping
Vector2 pointDiff = point - pingSource;
Vector2 displayPointDiff = pointDiff * displayScale;
float displayPointDistSqr = displayPointDiff.LengthSquared();
if (displayPointDistSqr < prevPingRadius * prevPingRadius || displayPointDistSqr > pingRadius * pingRadius) continue;
//ignore if direction is disrupted
float transducerDist = transducerDiff.Length();
Vector2 pingDirection = transducerDiff / transducerDist;
bool disrupted = false;
foreach (Pair<Vector2, float> disruptDir in disruptedDirections)
{
float dot = Vector2.Dot(pointDiff / pointDist, disruptDir.First);
float dot = Vector2.Dot(pingDirection, disruptDir.First);
if (dot > 1.0f - disruptDir.Second)
{
disrupted = true;
@@ -845,10 +840,11 @@ namespace Barotrauma.Items.Components
}
if (disrupted) continue;
float displayPointDist = (float)Math.Sqrt(displayPointDistSqr);
float alpha = pingStrength * Rand.Range(1.5f, 2.0f);
for (float z = 0; z < DisplayRadius - displayPointDist; z += zStep)
for (float z = 0; z < DisplayRadius - transducerDist * displayScale; z += zStep)
{
Vector2 pos = point + Rand.Vector(150.0f / zoom) + Vector2.Normalize(point - item.WorldPosition) * z / displayScale;
Vector2 pos = point + Rand.Vector(150.0f / zoom) + pingDirection * z / displayScale;
float fadeTimer = alpha * (1.0f - displayPointDist / range);
int minDist = (int)(200 / zoom);
@@ -902,7 +898,7 @@ namespace Barotrauma.Items.Components
{
strength = MathHelper.Clamp(strength, 0.0f, 1.0f);
float distort = 1.0f - item.Condition / 100.0f;
float distort = 1.0f - item.Condition / item.Prefab.Health;
Vector2 pos = (blip.Position - transducerPos) * displayScale * zoom;
pos.Y = -pos.Y;

View File

@@ -10,7 +10,19 @@ namespace Barotrauma.Items.Components
{
partial class Steering : Powered, IServerSerializable, IClientSerializable
{
enum Mode
{
AutoPilot,
Manual
};
private GUITickBox autopilotTickBox, manualTickBox;
enum Destination
{
MaintainPos,
LevelEnd,
LevelStart
};
private GUITickBox maintainPosTickBox, levelEndTickBox, levelStartTickBox;
private GUIFrame autoPilotControlsDisabler;
@@ -104,8 +116,11 @@ namespace Barotrauma.Items.Components
}
};
GUITickBox.CreateRadioButtonGroup(new List<GUITickBox> { manualTickBox, autopilotTickBox });
GUIRadioButtonGroup modes = new GUIRadioButtonGroup();
modes.AddRadioButton(Mode.AutoPilot, autopilotTickBox);
modes.AddRadioButton(Mode.Manual, manualTickBox);
modes.Selected = Mode.Manual;
var autoPilotControls = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), paddedControlContainer.RectTransform), "InnerFrame");
var paddedAutoPilotControls = new GUILayoutGroup(new RectTransform(new Vector2(0.8f), autoPilotControls.RectTransform, Anchor.Center))
{
@@ -205,7 +220,12 @@ namespace Barotrauma.Items.Components
autoPilotControlsDisabler = new GUIFrame(new RectTransform(Vector2.One, autoPilotControls.RectTransform), "InnerFrame");
GUITickBox.CreateRadioButtonGroup(new List<GUITickBox> { maintainPosTickBox, levelStartTickBox, levelEndTickBox });
GUIRadioButtonGroup destinations = new GUIRadioButtonGroup();
destinations.AddRadioButton(Destination.MaintainPos, maintainPosTickBox);
destinations.AddRadioButton(Destination.LevelStart, levelStartTickBox);
destinations.AddRadioButton(Destination.LevelEnd, levelEndTickBox);
destinations.Selected = maintainPos ? Destination.MaintainPos :
levelStartSelected ? Destination.LevelStart : Destination.LevelEnd;
string steeringVelX = TextManager.Get("SteeringVelocityX");
string steeringVelY = TextManager.Get("SteeringVelocityY");

View File

@@ -11,6 +11,12 @@ namespace Barotrauma.Items.Components
private GUIProgressBar chargeIndicator;
private GUIScrollBar rechargeSpeedSlider;
public Vector2 DrawSize
{
//use the extents of the item as the draw size
get { return Vector2.Zero; }
}
partial void InitProjSpecific()
{
if (GuiFrame == null) return;
@@ -44,12 +50,7 @@ namespace Barotrauma.Items.Components
if (Math.Abs(newRechargeSpeed - rechargeSpeed) < 0.1f) return false;
RechargeSpeed = newRechargeSpeed;
if (GameMain.Server != null)
{
item.CreateServerEvent(this);
GameServer.Log(Character.Controlled.LogName + " set the recharge speed of " + item.Name + " to " + (int)((rechargeSpeed / maxRechargeSpeed) * 100.0f) + " %", ServerLog.MessageType.ItemInteraction);
}
else if (GameMain.Client != null)
if (GameMain.Client != null)
{
item.CreateClientEvent(this);
correctionTimer = CorrectionDelay;

View File

@@ -22,7 +22,8 @@ namespace Barotrauma.Items.Components
powerOnSound = Submarine.LoadRoundSound(subElement, false);
break;
case "sparksound":
sparkSounds.Add(Submarine.LoadRoundSound(subElement, false));
var sparkSound = Submarine.LoadRoundSound(subElement, false);
if (sparkSound != null) { sparkSounds.Add(sparkSound); }
break;
}
}

View File

@@ -73,7 +73,7 @@ namespace Barotrauma.Items.Components
}
var progressBar = user.UpdateHUDProgressBar(
targetStructure,
targetStructure.ID * 1000 + sectionIndex, //unique "identifier" for each wall section
progressBarPos,
1.0f - targetStructure.SectionDamage(sectionIndex) / targetStructure.Health,
Color.Red, Color.Green);
@@ -108,7 +108,7 @@ namespace Barotrauma.Items.Components
var progressBar = user.UpdateHUDProgressBar(
targetItem,
progressBarPos,
targetItem.Condition / 100.0f,
targetItem.Prefab.Health <= 0.0f ? 0.0f : targetItem.Condition / targetItem.Prefab.Health,
Color.Red, Color.Green);
if (progressBar != null) { progressBar.Size = new Vector2(60.0f, 20.0f); }
}

View File

@@ -26,7 +26,7 @@ namespace Barotrauma.Items.Components
public override bool ShouldDrawHUD(Character character)
{
if (!HasRequiredItems(character, false)) return false;
if (!HasRequiredItems(character, false) || character.SelectedConstruction != item) return false;
return (item.Condition < ShowRepairUIThreshold || (currentFixer == character && item.Condition < item.Prefab.Health));
}

View File

@@ -108,10 +108,6 @@ namespace Barotrauma.Items.Components
{
panel.Item.CreateClientEvent(panel);
}
else if (GameMain.Server != null)
{
panel.Item.CreateServerEvent(panel);
}
draggingConnected = null;
}
@@ -173,6 +169,8 @@ namespace Barotrauma.Items.Components
if (draggingConnected.Connect(this, !alreadyConnected, true))
{
var otherConnection = draggingConnected.OtherConnection(this);
#if SERVER
//TODO: ffs
if (otherConnection == null)
{
GameServer.Log(Character.Controlled.LogName + " connected a wire to " +
@@ -183,6 +181,7 @@ namespace Barotrauma.Items.Components
GameServer.Log(Character.Controlled.LogName + " connected a wire from " +
Item.Name + " (" + Name + ") to " + otherConnection.item.Name + " (" + otherConnection.Name + ")", ServerLog.MessageType.ItemInteraction);
}
#endif
SetWire(index, draggingConnected);
}

View File

@@ -54,7 +54,7 @@ namespace Barotrauma.Items.Components
}
else
{
GameMain.Client.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.components.IndexOf(this), userdata as CustomInterfaceElement });
GameMain.Client.CreateEntityEvent(item, new object[] { NetEntityEvent.Type.ComponentState, item.GetComponentIndex(this), userdata as CustomInterfaceElement });
}
return true;
};

View File

@@ -5,6 +5,11 @@ namespace Barotrauma.Items.Components
{
partial class MotionSensor : IDrawableComponent
{
public Vector2 DrawSize
{
get { return new Vector2(rangeX, rangeY) * 2.0f; }
}
public void Draw(SpriteBatch spriteBatch, bool editing)
{
if (!editing || !MapEntity.SelectedList.Contains(item)) return;

View File

@@ -5,6 +5,11 @@ namespace Barotrauma.Items.Components
{
partial class WifiComponent : IDrawableComponent
{
public Vector2 DrawSize
{
get { return new Vector2(range * 2); }
}
public void Draw(SpriteBatch spriteBatch, bool editing)
{
if (!editing || !MapEntity.SelectedList.Contains(item)) return;

View File

@@ -41,7 +41,12 @@ namespace Barotrauma.Items.Components
private static Wire draggingWire;
private static int? selectedNodeIndex;
private static int? highlightedNodeIndex;
public Vector2 DrawSize
{
get { return sectionExtents; }
}
public void Draw(SpriteBatch spriteBatch, bool editing)
{
if (sections.Count == 0 && !IsActive || Hidden)

View File

@@ -73,7 +73,7 @@ namespace Barotrauma.Items.Components
visibleCharacters.Clear();
foreach (Character c in Character.CharacterList)
{
if (c == equipper) continue;
if (c == equipper || !c.Enabled || c.Removed) { continue; }
float dist = Vector2.DistanceSquared(equipper.WorldPosition, c.WorldPosition);
if (dist < Range * Range)
@@ -111,10 +111,9 @@ namespace Barotrauma.Items.Components
Character closestCharacter = null;
float closestDist = float.PositiveInfinity;
foreach (Character c in visibleCharacters)
{
if (c == character) continue;
if (c == character || !c.Enabled || c.Removed) { continue; }
float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition);
if (dist < closestDist)
@@ -175,14 +174,14 @@ namespace Barotrauma.Items.Components
{
int bleedingTextIndex = MathHelper.Clamp((int)Math.Floor(target.Bleeding / 100.0f) * BleedingTexts.Length, 0, BleedingTexts.Length - 1);
texts.Add(BleedingTexts[bleedingTextIndex]);
textColors.Add(Color.Lerp(Color.Red, Color.Green, target.Bleeding / 100.0f));
textColors.Add(Color.Lerp(Color.Orange, Color.Red, target.Bleeding / 100.0f));
}
var allAfflictions = target.CharacterHealth.GetAllAfflictions();
Dictionary<AfflictionPrefab, float> combinedAfflictionStrengths = new Dictionary<AfflictionPrefab, float>();
foreach (Affliction affliction in allAfflictions)
{
if (affliction.Strength < affliction.Prefab.ActivationThreshold || affliction.Strength < affliction.Prefab.ShowIconThreshold) continue;
if (affliction.Strength < affliction.Prefab.ActivationThreshold || affliction.Strength <= 0.0f) continue;
if (combinedAfflictionStrengths.ContainsKey(affliction.Prefab))
{
combinedAfflictionStrengths[affliction.Prefab] += affliction.Strength;
@@ -196,7 +195,7 @@ namespace Barotrauma.Items.Components
foreach (AfflictionPrefab affliction in combinedAfflictionStrengths.Keys)
{
texts.Add(affliction.Name + ": " + ((int)combinedAfflictionStrengths[affliction]).ToString() + " %");
textColors.Add(Color.Lerp(Color.Red, Color.Green, combinedAfflictionStrengths[affliction] / affliction.MaxStrength));
textColors.Add(Color.Lerp(Color.Orange, Color.Red, combinedAfflictionStrengths[affliction] / affliction.MaxStrength));
}
}
@@ -204,6 +203,9 @@ namespace Barotrauma.Items.Components
hudPos.X += 5.0f;
hudPos.Y += 24.0f;
hudPos.X = (int)hudPos.X;
hudPos.Y = (int)hudPos.Y;
for (int i = 1; i < texts.Count; i++)
{
GUI.DrawString(spriteBatch, hudPos, texts[i], textColors[i] * alpha, Color.Black * 0.7f * alpha, 2, GUI.SmallFont);

View File

@@ -61,6 +61,26 @@ namespace Barotrauma.Items.Components
private set;
}
public Vector2 DrawSize
{
get
{
float size = Math.Max(transformedBarrelPos.X, transformedBarrelPos.Y);
if (barrelSprite != null)
{
if (railSprite != null)
{
size += Math.Max(Math.Max(barrelSprite.size.X, barrelSprite.size.Y), Math.Max(railSprite.size.X, railSprite.size.Y)) * item.Scale;
}
else
{
size += Math.Max(barrelSprite.size.X, barrelSprite.size.Y) * item.Scale;
}
}
return Vector2.One * size * 2;
}
}
partial void InitProjSpecific(XElement element)
{
foreach (XElement subElement in element.Elements())

View File

@@ -1,7 +1,6 @@
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Collision;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -9,6 +8,12 @@ namespace Barotrauma.Items.Components
{
partial class DockingPort : ItemComponent, IDrawableComponent, IServerSerializable
{
public Vector2 DrawSize
{
//use the extents of the item as the draw size
get { return Vector2.Zero; }
}
public void Draw(SpriteBatch spriteBatch, bool editing)
{
if (dockingState == 0.0f) return;

View File

@@ -128,12 +128,14 @@ namespace Barotrauma
protected float prevUIScale = UIScale;
protected float prevHUDScale = GUI.Scale;
protected static Sprite slotSpriteSmall, slotSpriteHorizontal, slotSpriteVertical, slotSpriteRound;
public static Sprite EquipIndicator, EquipIndicatorHighlight;
public static Sprite DropIndicator, DropIndicatorHighlight;
public Rectangle BackgroundFrame { get; protected set; }
private ushort[] receivedItemIDs;
private CoroutineHandle syncItemsCoroutine;
public float HideTimer;
@@ -504,7 +506,7 @@ namespace Barotrauma
if (Character.Controlled.SelectedConstruction != null)
{
foreach (ItemComponent ic in Character.Controlled.SelectedConstruction.components)
foreach (ItemComponent ic in Character.Controlled.SelectedConstruction.Components)
{
var itemContainer = ic as ItemContainer;
if (itemContainer?.Inventory?.slots == null) continue;
@@ -596,7 +598,6 @@ namespace Barotrauma
if (selectedSlot == null)
{
draggingItem.ParentInventory?.CreateNetworkEvent();
draggingItem.Drop();
GUI.PlayUISound(GUISoundType.DropItem);
}
@@ -675,7 +676,7 @@ namespace Barotrauma
foreach (var slot in highlightedSubInventorySlots)
{
int slotIndex = Array.IndexOf(slot.ParentInventory.slots, slot.Slot);
if (slotIndex > 0 && slotIndex < slot.ParentInventory.slots.Length)
if (slotIndex > -1 && slotIndex < slot.ParentInventory.slots.Length)
{
slot.ParentInventory.DrawSubInventory(spriteBatch, slotIndex);
}
@@ -788,7 +789,7 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Bottom - 8, rect.Width, 8), Color.Black * 0.8f, true);
GUI.DrawRectangle(spriteBatch,
new Rectangle(rect.X, rect.Bottom - 8, (int)(rect.Width * item.Condition / item.Prefab.Health), 8),
Color.Lerp(Color.Red, Color.Green, item.Condition / 100.0f) * 0.8f, true);
Color.Lerp(Color.Red, Color.Green, item.Condition / item.Prefab.Health) * 0.8f, true);
}
if (itemContainer != null)
@@ -796,12 +797,12 @@ namespace Barotrauma
float containedState = 0.0f;
if (itemContainer.ShowConditionInContainedStateIndicator)
{
containedState = item.Condition / 100.0f;
containedState = item.Condition / item.Prefab.Health;
}
else
{
containedState = itemContainer.Inventory.Capacity == 1 ?
(itemContainer.Inventory.Items[0] == null ? 0.0f : itemContainer.Inventory.Items[0].Condition / 100.0f) :
(itemContainer.Inventory.Items[0] == null ? 0.0f : itemContainer.Inventory.Items[0].Condition / item.Prefab.Health) :
itemContainer.Inventory.Items.Count(i => i != null) / (float)itemContainer.Inventory.capacity;
}
@@ -962,8 +963,7 @@ namespace Barotrauma
{
if (receivedItemIDs[i] > 0)
{
var item = Entity.FindEntityByID(receivedItemIDs[i]) as Item;
if (item == null || Items[i] == item) continue;
if (!(Entity.FindEntityByID(receivedItemIDs[i]) is Item item) || Items[i] == item) continue;
TryPutItem(item, i, true, true, null, false);
for (int j = 0; j < capacity; j++)
@@ -978,5 +978,11 @@ namespace Barotrauma
receivedItemIDs = null;
}
public void ClientWrite(NetBuffer msg, object[] extraData = null)
{
SharedWrite(msg, extraData);
syncItemsDelay = 1.0f;
}
}
}

View File

@@ -15,6 +15,8 @@ namespace Barotrauma
partial class Item : MapEntity, IDamageable, ISerializableEntity, IServerSerializable, IClientSerializable
{
public static bool ShowItems = true;
private readonly List<PosInfo> positionBuffer = new List<PosInfo>();
private List<ItemComponent> activeHUDs = new List<ItemComponent>();
@@ -34,6 +36,8 @@ namespace Barotrauma
{
get { return activeSprite; }
}
public float SpriteRotation;
private GUITextBlock itemInUseWarning;
private GUITextBlock ItemInUseWarning
@@ -127,12 +131,36 @@ namespace Barotrauma
}
}
public override bool IsVisible(Rectangle worldView)
{
//no drawable components and the body has been disabled = nothing to draw
if (drawableComponents.Count == 0 && body != null && !body.Enabled)
{
return false;
}
float padding = 100.0f;
Vector2 size = new Vector2(rect.Width + padding, rect.Height + padding);
foreach (IDrawableComponent drawable in drawableComponents)
{
size.X = Math.Max(drawable.DrawSize.X, size.X);
size.Y = Math.Max(drawable.DrawSize.Y, size.Y);
}
size *= 0.5f;
Vector2 worldPosition = WorldPosition;
if (worldPosition.X - size.X > worldView.Right || worldPosition.X + size.X < worldView.X) return false;
if (worldPosition.Y + size.Y < worldView.Y - worldView.Height || worldPosition.Y - size.Y > worldView.Y) return false;
return true;
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (!Visible || (!editing && hiddenInGame)) return; // TODO: Prevent drawing hiddenInGame objects via cheating with server-side checks
if (!Visible || (!editing && hiddenInGame)) return;
if (editing && !ShowItems) return;
Color color = isHighlighted ? Color.Orange : GetSpriteColor();
Color color = isHighlighted && !GUI.DisableItemHighlights ? Color.Orange : GetSpriteColor();
//if (IsSelected && editing) color = Color.Lerp(color, Color.Gold, 0.5f);
Sprite activeSprite = prefab.sprite;
@@ -816,41 +844,53 @@ namespace Barotrauma
}
msg.WritePadBits();
}
partial void UpdateNetPosition()
{
if (GameMain.Client == null) { return; }
Vector2 newVelocity = body.LinearVelocity;
Vector2 newPosition = body.SimPosition;
float newAngularVelocity = body.AngularVelocity;
float newRotation = body.Rotation;
body.CorrectPosition(positionBuffer, out newPosition, out newVelocity, out newRotation, out newAngularVelocity);
body.LinearVelocity = newVelocity;
body.AngularVelocity = newAngularVelocity;
if (Vector2.DistanceSquared(newPosition, body.SimPosition) > 0.0001f ||
Math.Abs(newRotation - body.Rotation) > 0.01f)
{
body.TargetPosition = newPosition;
body.TargetRotation = newRotation;
body.MoveToTargetPosition(lerp: true);
}
Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition);
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
}
public void ClientReadPosition(ServerNetObject type, NetBuffer msg, float sendingTime)
{
Vector2 newPosition = new Vector2(msg.ReadFloat(), msg.ReadFloat());
float newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 7);
bool awake = msg.ReadBoolean();
Vector2 newVelocity = Vector2.Zero;
if (awake)
{
newVelocity = new Vector2(
msg.ReadRangedSingle(-MaxVel, MaxVel, 12),
msg.ReadRangedSingle(-MaxVel, MaxVel, 12));
}
if (!MathUtils.IsValid(newPosition) || !MathUtils.IsValid(newRotation) || !MathUtils.IsValid(newVelocity))
{
string errorMsg = "Received invalid position data for the item \"" + Name
+ "\" (position: " + newPosition + ", rotation: " + newRotation + ", velocity: " + newVelocity + ")";
#if DEBUG
DebugConsole.ThrowError(errorMsg);
#endif
GameAnalyticsManager.AddErrorEventOnce("Item.ClientReadPosition:InvalidData" + ID,
GameAnalyticsSDK.Net.EGAErrorSeverity.Error,
errorMsg);
return;
}
if (body == null)
{
DebugConsole.ThrowError("Received a position update for an item with no physics body (" + Name + ")");
return;
}
body.FarseerBody.Awake = awake;
var posInfo = body.ClientRead(type, msg, sendingTime, parentDebugName: Name);
msg.ReadPadBits();
if (posInfo != null)
{
int index = 0;
while (index < positionBuffer.Count && sendingTime > positionBuffer[index].Timestamp)
{
index++;
}
positionBuffer.Insert(index, posInfo);
}
/*body.FarseerBody.Awake = awake;
if (body.FarseerBody.Awake)
{
if ((newVelocity - body.LinearVelocity).LengthSquared() > 8.0f * 8.0f) body.LinearVelocity = newVelocity;
@@ -879,7 +919,7 @@ namespace Barotrauma
rect.X = (int)(displayPos.X - rect.Width / 2.0f);
rect.Y = (int)(displayPos.Y + rect.Height / 2.0f);
}
}
}*/
}
public void CreateClientEvent<T>(T ic) where T : ItemComponent, IClientSerializable
@@ -891,6 +931,106 @@ namespace Barotrauma
GameMain.Client.CreateEntityEvent(this, new object[] { NetEntityEvent.Type.ComponentState, index });
}
public static Item ReadSpawnData(NetBuffer msg, bool spawn = true)
{
string itemName = msg.ReadString();
string itemIdentifier = msg.ReadString();
bool descriptionChanged = msg.ReadBoolean();
string itemDesc = "";
if (descriptionChanged)
{
itemDesc = msg.ReadString();
}
ushort itemId = msg.ReadUInt16();
ushort inventoryId = msg.ReadUInt16();
DebugConsole.Log("Received entity spawn message for item " + itemName + ".");
Vector2 pos = Vector2.Zero;
Submarine sub = null;
int itemContainerIndex = -1;
int inventorySlotIndex = -1;
if (inventoryId > 0)
{
itemContainerIndex = msg.ReadByte();
inventorySlotIndex = msg.ReadByte();
}
else
{
pos = new Vector2(msg.ReadSingle(), msg.ReadSingle());
ushort subID = msg.ReadUInt16();
if (subID > 0)
{
sub = Submarine.Loaded.Find(s => s.ID == subID);
}
}
byte teamID = msg.ReadByte();
bool tagsChanged = msg.ReadBoolean();
string tags = "";
if (tagsChanged)
{
tags = msg.ReadString();
}
if (!spawn) return null;
//----------------------------------------
var itemPrefab = MapEntityPrefab.Find(itemName, itemIdentifier) as ItemPrefab;
if (itemPrefab == null) return null;
Inventory inventory = null;
var inventoryOwner = FindEntityByID(inventoryId);
if (inventoryOwner != null)
{
if (inventoryOwner is Character)
{
inventory = (inventoryOwner as Character).Inventory;
}
else if (inventoryOwner is Item)
{
if ((inventoryOwner as Item).components[itemContainerIndex] is ItemContainer container)
{
inventory = container.Inventory;
}
}
}
var item = new Item(itemPrefab, pos, sub)
{
ID = itemId
};
foreach (WifiComponent wifiComponent in item.GetComponents<WifiComponent>())
{
wifiComponent.TeamID = (Character.TeamType)teamID;
}
if (descriptionChanged) item.Description = itemDesc;
if (tagsChanged) item.Tags = tags;
if (sub != null)
{
item.CurrentHull = Hull.FindHull(pos + sub.Position, null, true);
item.Submarine = item.CurrentHull?.Submarine;
}
if (inventory != null)
{
if (inventorySlotIndex >= 0 && inventorySlotIndex < 255 &&
inventory.TryPutItem(item, inventorySlotIndex, false, false, null, false))
{
return null;
}
inventory.TryPutItem(item, null, item.AllowedSlots, false);
}
return item;
}
partial void RemoveProjSpecific()
{

View File

@@ -6,6 +6,8 @@ namespace Barotrauma
{
partial class ItemInventory : Inventory
{
private string uiLabel;
protected override void ControlInput(Camera cam)
{
if (draggingItem == null && HUD.CloseHUD(BackgroundFrame))
@@ -84,13 +86,24 @@ namespace Barotrauma
if (container.InventoryTopSprite == null)
{
Item item = Owner as Item;
string label = container.UILabel ?? item?.Name;
if (!string.IsNullOrEmpty(label) && !subInventory)
if (uiLabel == null || uiLabel == string.Empty)
{
if (container.UILabel != null && container.UILabel.Length > 0)
{
uiLabel = TextManager.Get("UILabel." + container.UILabel);
}
else
{
Item item = Owner as Item;
uiLabel = item?.Name;
}
}
if (!string.IsNullOrEmpty(uiLabel) && !subInventory)
{
GUI.DrawString(spriteBatch,
new Vector2((int)(BackgroundFrame.Center.X - GUI.Font.MeasureString(label).X / 2), (int)BackgroundFrame.Y + 5),
label, Color.White * 0.9f);
new Vector2((int)(BackgroundFrame.Center.X - GUI.Font.MeasureString(uiLabel).X / 2), (int)BackgroundFrame.Y + 5),
uiLabel, Color.White * 0.9f);
}
}
else if (!subInventory)

View File

@@ -7,6 +7,12 @@ namespace Barotrauma.Items.Components
{
partial class Rope : ItemComponent, IDrawableComponent
{
public Vector2 DrawSize
{
//use the extents of the item as the draw size
get { return Vector2.Zero; }
}
public void Draw(SpriteBatch spriteBatch, bool editing = false)
{
if (!IsActive) return;

View File

@@ -16,14 +16,17 @@ namespace Barotrauma
}
}
public override bool IsVisible(Rectangle worldView)
{
return Screen.Selected == GameMain.SubEditorScreen || GameMain.DebugDraw;
}
public override void Draw(SpriteBatch sb, bool editing, bool back = true)
{
if (GameMain.DebugDraw)
{
Vector2 center = new Vector2(WorldRect.X + rect.Width / 2.0f, -(WorldRect.Y - rect.Height / 2.0f));
GUI.DrawLine(sb, center, center + new Vector2(flowForce.X, -flowForce.Y) / 10.0f, Color.Red);
GUI.DrawLine(sb, center + Vector2.One * 5.0f, center + new Vector2(lerpedFlowForce.X, -lerpedFlowForce.Y) / 10.0f + Vector2.One * 5.0f, Color.Orange);
}

View File

@@ -7,15 +7,21 @@ using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;
using System.Linq;
using Lidgren.Network;
namespace Barotrauma
{
partial class Hull : MapEntity, ISerializableEntity, IServerSerializable
partial class Hull : MapEntity, ISerializableEntity, IServerSerializable, IClientSerializable
{
public const int MaxDecalsPerHull = 10;
private List<Decal> decals = new List<Decal>();
private float serverUpdateDelay;
private bool networkUpdatePending;
private float networkUpdateTimer;
public override bool SelectableInEditor
{
get
@@ -39,7 +45,20 @@ namespace Barotrauma
return true;
}
}
public override bool IsVisible(Rectangle worldView)
{
if (Screen.Selected != GameMain.SubEditorScreen && !GameMain.DebugDraw)
{
if (decals.Count == 0) { return false; }
Rectangle worldRect = WorldRect;
if (worldRect.X > worldView.Right || worldRect.Right < worldView.X) { return false; }
if (worldRect.Y < worldView.Y - worldView.Height || worldRect.Y - worldRect.Height > worldView.Y) { return false; }
}
return true;
}
public override bool IsMouseOn(Vector2 position)
{
if (!GameMain.DebugDraw && !ShowHulls) return false;
@@ -118,6 +137,19 @@ namespace Barotrauma
partial void UpdateProjSpecific(float deltaTime, Camera cam)
{
serverUpdateDelay -= deltaTime;
if (networkUpdatePending)
{
networkUpdateTimer += deltaTime;
if (networkUpdateTimer > 0.2f)
{
GameMain.NetworkMember?.CreateEntityEvent(this);
networkUpdatePending = false;
networkUpdateTimer = 0.0f;
}
}
if (EditWater)
{
Vector2 position = cam.ScreenToWorld(PlayerInput.MousePosition);
@@ -126,10 +158,14 @@ namespace Barotrauma
if (PlayerInput.LeftButtonHeld())
{
WaterVolume += 1500.0f;
networkUpdatePending = true;
serverUpdateDelay = 0.5f;
}
else if (PlayerInput.RightButtonHeld())
{
WaterVolume -= 1500.0f;
networkUpdatePending = true;
serverUpdateDelay = 0.5f;
}
}
}
@@ -140,7 +176,9 @@ namespace Barotrauma
{
if (PlayerInput.LeftButtonClicked())
{
new FireSource(position, this);
new FireSource(position, this, isNetworkMessage: true);
networkUpdatePending = true;
serverUpdateDelay = 0.5f;
}
}
}
@@ -189,8 +227,7 @@ namespace Barotrauma
return;
}
Rectangle drawRect;
if (!Visible)
/*if (!Visible)
{
drawRect =
Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
@@ -200,7 +237,7 @@ namespace Barotrauma
new Vector2(rect.Width, rect.Height),
Color.Black, true,
0, (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f));
}
}*/
if (!ShowHulls && !GameMain.DebugDraw) return;
@@ -208,7 +245,7 @@ namespace Barotrauma
if (aiTarget != null) aiTarget.Draw(spriteBatch);
drawRect =
Rectangle drawRect =
Submarine == null ? rect : new Rectangle((int)(Submarine.DrawPosition.X + rect.X), (int)(Submarine.DrawPosition.Y + rect.Y), rect.Width, rect.Height);
GUI.DrawRectangle(spriteBatch,
@@ -483,6 +520,84 @@ namespace Barotrauma
width -= (int)Math.Max((x + WaveWidth) - (Submarine == null ? rect.Right : (rect.Right + Submarine.DrawPosition.X)), 0);
}
}
}
public void ClientWrite(NetBuffer msg, object[] extraData = null)
{
msg.WriteRangedSingle(MathHelper.Clamp(waterVolume / Volume, 0.0f, 1.5f), 0.0f, 1.5f, 8);
msg.Write(FireSources.Count > 0);
if (FireSources.Count > 0)
{
msg.WriteRangedInteger(0, 16, Math.Min(FireSources.Count, 16));
for (int i = 0; i < Math.Min(FireSources.Count, 16); i++)
{
var fireSource = FireSources[i];
Vector2 normalizedPos = new Vector2(
(fireSource.Position.X - rect.X) / rect.Width,
(fireSource.Position.Y - (rect.Y - rect.Height)) / rect.Height);
msg.WriteRangedSingle(MathHelper.Clamp(normalizedPos.X, 0.0f, 1.0f), 0.0f, 1.0f, 8);
msg.WriteRangedSingle(MathHelper.Clamp(normalizedPos.Y, 0.0f, 1.0f), 0.0f, 1.0f, 8);
msg.WriteRangedSingle(MathHelper.Clamp(fireSource.Size.X / rect.Width, 0.0f, 1.0f), 0, 1.0f, 8);
}
}
}
public void ClientRead(ServerNetObject type, NetBuffer message, float sendingTime)
{
float newWaterVolume = message.ReadRangedSingle(0.0f, 1.5f, 8) * Volume;
float newOxygenPercentage = message.ReadRangedSingle(0.0f, 100.0f, 8);
bool hasFireSources = message.ReadBoolean();
int fireSourceCount = 0;
List<Vector3> newFireSources = new List<Vector3>();
if (hasFireSources)
{
fireSourceCount = message.ReadRangedInteger(0, 16);
for (int i = 0; i < fireSourceCount; i++)
{
newFireSources.Add(new Vector3(
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
MathHelper.Clamp(message.ReadRangedSingle(0.0f, 1.0f, 8), 0.05f, 0.95f),
message.ReadRangedSingle(0.0f, 1.0f, 8)));
}
}
if (serverUpdateDelay > 0.0f) { return; }
WaterVolume = newWaterVolume;
OxygenPercentage = newOxygenPercentage;
for (int i = 0; i < fireSourceCount; i++)
{
Vector2 pos = new Vector2(
rect.X + rect.Width * newFireSources[i].X,
rect.Y - rect.Height + (rect.Height * newFireSources[i].Y));
float size = newFireSources[i].Z * rect.Width;
var newFire = i < FireSources.Count ?
FireSources[i] :
new FireSource(Submarine == null ? pos : pos + Submarine.Position, null, true);
newFire.Position = pos;
newFire.Size = new Vector2(size, newFire.Size.Y);
//ignore if the fire wasn't added to this room (invalid position)?
if (!FireSources.Contains(newFire))
{
newFire.Remove();
continue;
}
}
for (int i = FireSources.Count - 1; i >= fireSourceCount; i--)
{
FireSources[i].Remove();
if (i < FireSources.Count)
{
FireSources.RemoveAt(i);
}
}
}
}
}

View File

@@ -93,8 +93,6 @@ namespace Barotrauma
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
if (GameMain.Server != null) return;
foreach (LevelWall levelWall in extraWalls)
{
if (levelWall.Body.BodyType == BodyType.Static) continue;

View File

@@ -194,6 +194,7 @@ namespace Barotrauma
for (int i = 0; i < Sounds.Length; i++)
{
if (Sounds[i] == null) { continue; }
if (SoundTriggers[i] == null || SoundTriggers[i].IsTriggered)
{
RoundSound roundSound = Sounds[i];

View File

@@ -322,8 +322,14 @@ namespace Barotrauma
Matrix transformMatrix = cam.ShaderTransform
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 100) * 0.5f;
wallEdgeEffect.Texture = specular && level.GenerationParams.WallEdgeSpriteSpecular != null ?
level.GenerationParams.WallEdgeSpriteSpecular.Texture :
level.GenerationParams.WallEdgeSprite.Texture;
wallEdgeEffect.World = transformMatrix;
wallCenterEffect.Texture = specular && level.GenerationParams.WallSpriteSpecular != null ?
level.GenerationParams.WallSpriteSpecular.Texture :
level.GenerationParams.WallSprite.Texture;
wallCenterEffect.World = transformMatrix;
graphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

View File

@@ -34,8 +34,8 @@ namespace Barotrauma
public const int DefaultBufferSize = 2000;
public const int DefaultIndoorsBufferSize = 3000;
public static Vector2 DistortionScale = new Vector2(0.5f, 0.5f);
public static Vector2 DistortionStrength = new Vector2(0.5f, 0.5f);
public static Vector2 DistortionScale = new Vector2(2f, 2f);
public static Vector2 DistortionStrength = new Vector2(0.25f, 0.25f);
public static float BlurAmount = 0.0f;
public Vector2 WavePos
@@ -103,7 +103,6 @@ namespace Barotrauma
}
else
{ WaterEffect.CurrentTechnique = WaterEffect.Techniques["WaterShader"];
WaterEffect.Parameters["xBlurDistance"].SetValue(BlurAmount / 100.0f);
}
Vector2 offset = WavePos;

View File

@@ -20,18 +20,11 @@ namespace Barotrauma.Lights
/// the time being because it makes the lighting behave unpredictably and may cause rooms to appear
/// excessively bright if different lighting conditions aren't tested and accounted for.
/// </summary>
private static bool UseHullSpecificAmbientLight = false;
private static readonly bool UseHullSpecificAmbientLight = false;
private static Entity viewTarget;
public static Entity ViewTarget { get; set; }
public static Entity ViewTarget
{
get { return viewTarget; }
set {
if (viewTarget == value) return;
viewTarget = value;
}
}
private float currLightMapScale;
private float currLightMapScale;
@@ -55,10 +48,7 @@ namespace Barotrauma.Lights
private BasicEffect lightEffect;
public Effect LosEffect
{
get; private set;
}
public Effect LosEffect { get; private set; }
private List<LightSource> lights;
@@ -99,11 +89,12 @@ namespace Barotrauma.Lights
if (lightEffect == null)
{
lightEffect = new BasicEffect(GameMain.Instance.GraphicsDevice);
lightEffect.VertexColorEnabled = true;
lightEffect.TextureEnabled = true;
lightEffect.Texture = LightSource.LightTexture;
lightEffect = new BasicEffect(GameMain.Instance.GraphicsDevice)
{
VertexColorEnabled = true,
TextureEnabled = true,
Texture = LightSource.LightTexture
};
}
hullAmbientLights = new Dictionary<Hull, Color>();
@@ -284,11 +275,14 @@ namespace Barotrauma.Lights
Character.Controlled.FocusedCharacter.Draw(spriteBatch, cam);
}
foreach (Item item in Item.ItemList)
if (!GUI.DisableItemHighlights)
{
if (item.IsHighlighted)
foreach (Item item in Item.ItemList)
{
item.Draw(spriteBatch, false, true);
if (item.IsHighlighted)
{
item.Draw(spriteBatch, false, true);
}
}
}
}
@@ -391,7 +385,7 @@ namespace Barotrauma.Lights
graphics.SetRenderTarget(SpecularMap);
//clear the lightmap
graphics.Clear(Color.Gray);
graphics.Clear(Color.Black);
graphics.BlendState = BlendState.AlphaBlend;
spriteBatch.Begin(sortMode: SpriteSortMode.Deferred, blendState: BlendState.AlphaBlend, transformMatrix: spriteBatchTransform);
@@ -400,41 +394,22 @@ namespace Barotrauma.Lights
{
Level.Loaded.LevelObjectManager.DrawObjects(spriteBatch, cam, drawFront: false, specular: true);
}
Dictionary<Hull, Rectangle> visibleHulls = new Dictionary<Hull, Rectangle>();
foreach (Hull hull in Hull.hullList)
{
var drawRect =
hull.Submarine == null ?
hull.Rect :
new Rectangle((int)(hull.Submarine.DrawPosition.X + hull.Rect.X), (int)(hull.Submarine.DrawPosition.Y + hull.Rect.Y), hull.Rect.Width, hull.Rect.Height);
if (drawRect.Right < cam.WorldView.X || drawRect.X > cam.WorldView.Right ||
drawRect.Y - drawRect.Height > cam.WorldView.Y || drawRect.Y < cam.WorldView.Y - cam.WorldView.Height)
{
continue;
}
visibleHulls.Add(hull, drawRect);
}
foreach (Rectangle drawRect in visibleHulls.Values)
{
GUI.DrawRectangle(spriteBatch,
new Vector2(drawRect.X, -drawRect.Y),
new Vector2(drawRect.Width, drawRect.Height),
Color.Gray, true);
}
spriteBatch.End();
//TODO: use renderTargetFront to obstruct the things behind the sub (has to be drawn with a solid gray color)
/*spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
spriteBatch.Draw(renderTargetFront, new Rectangle(0, 0,
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)), Color.White);
spriteBatch.End();*/
//TODO: specular maps for level walls
Level.Loaded?.Renderer?.RenderWalls(graphics, cam, specular: true);
spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend);
if (backgroundObstructor != null)
{
spriteBatch.Draw(backgroundObstructor, new Rectangle(0, 0,
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)), Color.Black);
}
GUI.DrawRectangle(spriteBatch, new Rectangle(0, 0,
(int)(GameMain.GraphicsWidth * currLightMapScale), (int)(GameMain.GraphicsHeight * currLightMapScale)),
Color.White * 0.4f, isFilled: true);
spriteBatch.End();
graphics.SetRenderTarget(null);
graphics.BlendState = BlendState.AlphaBlend;
}
@@ -491,14 +466,14 @@ namespace Barotrauma.Lights
if (LosEnabled && LosMode != LosMode.None && ViewTarget != null)
{
Vector2 pos = ViewTarget.WorldPosition;
Vector2 pos = ViewTarget.DrawPosition;
Rectangle camView = new Rectangle(cam.WorldView.X, cam.WorldView.Y - cam.WorldView.Height, cam.WorldView.Width, cam.WorldView.Height);
Matrix shadowTransform = cam.ShaderTransform
* Matrix.CreateOrthographic(GameMain.GraphicsWidth, GameMain.GraphicsHeight, -1, 1) * 0.5f;
var convexHulls = ConvexHull.GetHullsInRange(viewTarget.Position, cam.WorldView.Width*0.75f, viewTarget.Submarine);
var convexHulls = ConvexHull.GetHullsInRange(ViewTarget.Position, cam.WorldView.Width*0.75f, ViewTarget.Submarine);
if (convexHulls != null)
{
List<VertexPositionColor> shadowVerts = new List<VertexPositionColor>();

View File

@@ -718,7 +718,11 @@ namespace Barotrauma.Lights
if (OverrideLightTexture != null)
{
overrideTextureDims = new Vector2(OverrideLightTexture.SourceRect.Width, OverrideLightTexture.SourceRect.Height);
uvOffset = (OverrideLightTexture.Origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
Vector2 origin = OverrideLightTexture.Origin;
if (LightSpriteEffect == SpriteEffects.FlipHorizontally) origin.X = OverrideLightTexture.SourceRect.Width - origin.X;
if (LightSpriteEffect == SpriteEffects.FlipVertically) origin.Y = (OverrideLightTexture.SourceRect.Height - origin.Y);
uvOffset = (origin / overrideTextureDims) - new Vector2(0.5f, 0.5f);
}
// Add a vertex for the center of the mesh

View File

@@ -258,7 +258,7 @@ namespace Barotrauma
if (change.Messages.Count > 0)
{
mapAnim.EndMessage = change.Messages[Rand.Range(0,change.Messages.Count)]
.Replace("[prevname]", prevName)
.Replace("[previousname]", prevName)
.Replace("[name]", location.Name);
}
mapAnimQueue.Enqueue(mapAnim);
@@ -634,7 +634,7 @@ namespace Barotrauma
GUI.DrawString(spriteBatch, pos,
location.Name, Color.White * hudOpenState * 1.5f, font: GUI.LargeFont);
GUI.DrawString(spriteBatch, pos + Vector2.UnitY * 25,
location.Type.DisplayName, Color.White * hudOpenState * 1.5f);
location.Type.Name, Color.White * hudOpenState * 1.5f);
}
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;

View File

@@ -85,6 +85,11 @@ namespace Barotrauma
get { return selectedList.Contains(this); }
}
public virtual bool IsVisible(Rectangle worldView)
{
return true;
}
public virtual void Draw(SpriteBatch spriteBatch, bool editing, bool back = true) { }
public virtual void DrawDamage(SpriteBatch spriteBatch, Effect damageEffect) { }

View File

@@ -1,10 +1,10 @@
using Barotrauma.Lights;
using Barotrauma.Networking;
using Lidgren.Network;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma
{
@@ -105,7 +105,17 @@ namespace Barotrauma
return editingHUD;
}
public override bool IsVisible(Rectangle worldView)
{
Rectangle worldRect = WorldRect;
if (worldRect.X > worldView.Right || worldRect.Right < worldView.X) return false;
if (worldRect.Y < worldView.Y - worldView.Height || worldRect.Y - worldRect.Height > worldView.Y) return false;
return true;
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (prefab.sprite == null) return;
@@ -159,13 +169,13 @@ namespace Barotrauma
if (back && damageEffect == null)
{
if (prefab.BackgroundSprite != null)
if (Prefab.BackgroundSprite != null)
{
bool drawDropShadow = Submarine != null && HasBody;
Vector2 dropShadowOffset = Vector2.Zero;
if (drawDropShadow)
{
dropShadowOffset = Submarine.WorldPosition - WorldPosition;
dropShadowOffset = Submarine.HiddenSubPosition - Position;
if (dropShadowOffset != Vector2.Zero)
{
if (IsHorizontal)
@@ -182,14 +192,14 @@ namespace Barotrauma
if (DrawTiled)
{
SpriteEffects oldEffects = prefab.BackgroundSprite.effects;
prefab.BackgroundSprite.effects ^= SpriteEffects;
SpriteEffects oldEffects = Prefab.BackgroundSprite.effects;
Prefab.BackgroundSprite.effects ^= SpriteEffects;
Point backGroundOffset = new Point(
MathUtils.PositiveModulo((int)-textureOffset.X, prefab.BackgroundSprite.SourceRect.Width),
MathUtils.PositiveModulo((int)-textureOffset.Y, prefab.BackgroundSprite.SourceRect.Height));
MathUtils.PositiveModulo((int)-textureOffset.X, Prefab.BackgroundSprite.SourceRect.Width),
MathUtils.PositiveModulo((int)-textureOffset.Y, Prefab.BackgroundSprite.SourceRect.Height));
prefab.BackgroundSprite.DrawTiled(
Prefab.BackgroundSprite.DrawTiled(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
new Vector2(rect.Width, rect.Height),
@@ -199,21 +209,21 @@ namespace Barotrauma
if (drawDropShadow)
{
prefab.BackgroundSprite.DrawTiled(
Prefab.BackgroundSprite.DrawTiled(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset,
new Vector2(rect.Width, rect.Height),
color: Color.Black * 0.5f,
textureScale: TextureScale * Scale,
startOffset: backGroundOffset,
depth: (depth + prefab.BackgroundSprite.Depth) / 2.0f);
depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f);
}
prefab.BackgroundSprite.effects = oldEffects;
Prefab.BackgroundSprite.effects = oldEffects;
}
else
{
prefab.BackgroundSprite.Draw(
Prefab.BackgroundSprite.Draw(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)),
color,
@@ -224,7 +234,7 @@ namespace Barotrauma
if (drawDropShadow)
{
prefab.BackgroundSprite.Draw(
Prefab.BackgroundSprite.Draw(
spriteBatch,
new Vector2(rect.X + drawOffset.X, -(rect.Y + drawOffset.Y)) + dropShadowOffset,
Color.Black * 0.5f,
@@ -232,7 +242,7 @@ namespace Barotrauma
scale: Scale,
rotate: 0,
spriteEffect: SpriteEffects,
depth: (depth + prefab.BackgroundSprite.Depth) / 2.0f);
depth: (depth + Prefab.BackgroundSprite.Depth) / 2.0f);
}
}
}
@@ -248,7 +258,7 @@ namespace Barotrauma
if (damageEffect != null)
{
float newCutoff = Sections[i].damage > 0 ?
MathHelper.Lerp(0.2f, 0.65f, Sections[i].damage / prefab.Health) : 0.0f;
MathHelper.Lerp(0.2f, 0.65f, Sections[i].damage / Prefab.Health) : 0.0f;
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f || color != Submarine.DamageEffectColor)
{
@@ -317,5 +327,14 @@ namespace Barotrauma
}
}
}
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
for (int i = 0; i < Sections.Length; i++)
{
float damage = msg.ReadRangedSingle(0.0f, 1.0f, 8) * Health;
SetDamage(i, damage);
}
}
}
}

View File

@@ -1,4 +1,5 @@
using Barotrauma.Networking;
using Barotrauma.RuinGeneration;
using Barotrauma.Sounds;
using FarseerPhysics;
using Lidgren.Network;
@@ -62,7 +63,15 @@ namespace Barotrauma
if (existingSound == null)
{
existingSound = GameMain.SoundManager.LoadSound(filename, stream);
try
{
existingSound = GameMain.SoundManager.LoadSound(filename, stream);
}
catch (FileNotFoundException e)
{
DebugConsole.ThrowError("Failed to load sound file \"" + filename + "\".", e);
return null;
}
}
RoundSound newSound = new RoundSound(element, existingSound);
@@ -91,6 +100,71 @@ namespace Barotrauma
RemoveRoundSound(roundSounds[i]);
}
}
//drawing ----------------------------------------------------
public static void CullEntities(Camera cam)
{
HashSet<Submarine> visibleSubs = new HashSet<Submarine>();
foreach (Submarine sub in Loaded)
{
if (sub.WorldPosition.Y < Level.MaxEntityDepth) continue;
Rectangle worldBorders = new Rectangle(
sub.Borders.X + (int)sub.WorldPosition.X - 500,
sub.Borders.Y + (int)sub.WorldPosition.Y + 500,
sub.Borders.Width + 1000,
sub.Borders.Height + 1000);
if (RectsOverlap(worldBorders, cam.WorldView))
{
visibleSubs.Add(sub);
}
}
HashSet<Ruin> visibleRuins = new HashSet<Ruin>();
if (Level.Loaded != null)
{
foreach (Ruin ruin in Level.Loaded.Ruins)
{
Rectangle worldBorders = new Rectangle(
ruin.Area.X - 500,
ruin.Area.Y + ruin.Area.Height + 500,
ruin.Area.Width + 1000,
ruin.Area.Height + 1000);
if (RectsOverlap(worldBorders, cam.WorldView))
{
visibleRuins.Add(ruin);
}
}
}
if (visibleEntities == null)
{
visibleEntities = new List<MapEntity>(MapEntity.mapEntityList.Count);
}
else
{
visibleEntities.Clear();
}
Rectangle worldView = cam.WorldView;
foreach (MapEntity entity in MapEntity.mapEntityList)
{
if (entity.Submarine != null)
{
if (!visibleSubs.Contains(entity.Submarine)) { continue; }
}
else if (entity.ParentRuin != null)
{
if (!visibleRuins.Contains(entity.ParentRuin)) { continue; }
}
if (entity.IsVisible(worldView)) { visibleEntities.Add(entity); }
}
}
public static void Draw(SpriteBatch spriteBatch, bool editing = false)
{
@@ -128,14 +202,14 @@ namespace Barotrauma
GUI.DrawRectangle(spriteBatch, worldBorders, Color.White, false, 0, 5);
if (sub.subBody.MemPos.Count < 2) continue;
if (sub.subBody.PositionBuffer.Count < 2) continue;
Vector2 prevPos = ConvertUnits.ToDisplayUnits(sub.subBody.MemPos[0].Position);
Vector2 prevPos = ConvertUnits.ToDisplayUnits(sub.subBody.PositionBuffer[0].Position);
prevPos.Y = -prevPos.Y;
for (int i = 1; i < sub.subBody.MemPos.Count; i++)
for (int i = 1; i < sub.subBody.PositionBuffer.Count; i++)
{
Vector2 currPos = ConvertUnits.ToDisplayUnits(sub.subBody.MemPos[i].Position);
Vector2 currPos = ConvertUnits.ToDisplayUnits(sub.subBody.PositionBuffer[i].Position);
currPos.Y = -currPos.Y;
GUI.DrawRectangle(spriteBatch, new Rectangle((int)currPos.X - 10, (int)currPos.Y - 10, 20, 20), Color.Blue * 0.6f, true, 0.01f);
@@ -372,30 +446,19 @@ namespace Barotrauma
public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime)
{
var newTargetPosition = new Vector2(
msg.ReadFloat(),
msg.ReadFloat());
//already interpolating with more up-to-date data -> ignore
if (subBody.MemPos.Count > 1 && subBody.MemPos[0].Timestamp > sendingTime)
{
return;
}
var posInfo = PhysicsBody.ClientRead(type, msg, sendingTime, parentDebugName: Name);
msg.ReadPadBits();
int index = 0;
while (index < subBody.MemPos.Count && sendingTime > subBody.MemPos[index].Timestamp)
if (posInfo != null)
{
index++;
}
int index = 0;
while (index < subBody.PositionBuffer.Count && sendingTime > subBody.PositionBuffer[index].Timestamp)
{
index++;
}
//position with the same timestamp already in the buffer (duplicate packet?)
// -> no need to add again
if (index < subBody.MemPos.Count && sendingTime == subBody.MemPos[index].Timestamp)
{
return;
subBody.PositionBuffer.Insert(index, posInfo);
}
subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, 0.0f, sendingTime));
}
}
}

View File

@@ -0,0 +1,61 @@
using FarseerPhysics;
using Microsoft.Xna.Framework;
using System.Collections.Generic;
namespace Barotrauma
{
partial class SubmarineBody
{
partial void ClientUpdatePosition(float deltaTime)
{
if (GameMain.Client == null) { return; }
Vector2 newVelocity = Body.LinearVelocity;
Vector2 newPosition = Body.SimPosition;
Body.CorrectPosition(positionBuffer, out newPosition, out newVelocity, out _, out _);
Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition);
newVelocity = newVelocity.ClampLength(100.0f);
if (!MathUtils.IsValid(newVelocity) || moveAmount.LengthSquared() < 0.0001f)
{
return;
}
List<Submarine> subsToMove = submarine.GetConnectedSubs();
foreach (Submarine dockedSub in subsToMove)
{
if (dockedSub == submarine) continue;
//clear the position buffer of the docked subs to prevent unnecessary position corrections
dockedSub.SubBody.positionBuffer.Clear();
}
Submarine closestSub = null;
if (Character.Controlled == null)
{
closestSub = Submarine.FindClosest(GameMain.GameScreen.Cam.Position);
}
else
{
closestSub = Character.Controlled.Submarine;
}
bool displace = moveAmount.LengthSquared() > 100.0f * 100.0f;
foreach (Submarine sub in subsToMove)
{
sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f);
sub.PhysicsBody.LinearVelocity = newVelocity;
if (displace) sub.SubBody.DisplaceCharacters(moveAmount);
}
if (closestSub != null && subsToMove.Contains(closestSub))
{
GameMain.GameScreen.Cam.Position += moveAmount;
if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += moveAmount;
if (Character.Controlled != null) Character.Controlled.CursorPosition += moveAmount;
}
}
}
}

View File

@@ -10,6 +10,11 @@ namespace Barotrauma
private const int IconSize = 32;
private static int[] iconIndices = { 3, 0, 1, 2 };
public override bool IsVisible(Rectangle worldView)
{
return Screen.Selected == GameMain.SubEditorScreen || GameMain.DebugDraw;
}
public override void Draw(SpriteBatch spriteBatch, bool editing, bool back = true)
{
if (!editing && !GameMain.DebugDraw) return;

View File

@@ -0,0 +1,298 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Barotrauma.Sounds;
namespace Barotrauma.Media
{
public class Video : IDisposable
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate IntPtr LibVLCVideoLockCb(IntPtr opaque, IntPtr planes);
private static LibVLCVideoLockCb VideoLockDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVideoUnlockCb(IntPtr opaque, IntPtr picture, IntPtr planes);
private static LibVLCVideoUnlockCb VideoUnlockDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCVideoDisplayCb(IntPtr opaque, IntPtr picture);
private static LibVLCVideoDisplayCb VideoDisplayDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioPlayCb(IntPtr data, IntPtr samples, uint count, long pts);
private static LibVLCAudioPlayCb AudioPlayDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioPauseCb(IntPtr data, long pts);
private static LibVLCAudioPauseCb AudioPauseDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioResumeCb(IntPtr data, long pts);
private static LibVLCAudioResumeCb AudioResumeDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioFlushCb(IntPtr data, long pts);
private static LibVLCAudioFlushCb AudioFlushDelegate;
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void LibVLCAudioDrainCb(IntPtr data);
private static LibVLCAudioDrainCb AudioDrainDelegate;
private static IntPtr lib = IntPtr.Zero;
private static Dictionary<int, Video> videos;
private static int latestVideoId;
public static void Init()
{
if (lib == IntPtr.Zero)
{
string[] parameters = {
//"--no-xlib"
};
lib = LibVlcWrapper.LibVlcMethods.libvlc_new(parameters.Length, parameters);
videos = new Dictionary<int, Video>();
latestVideoId = 0;
VideoLockDelegate = VideoLockCallback;
VideoUnlockDelegate = VideoUnlockCallback;
VideoDisplayDelegate = VideoDisplayCallback;
AudioPlayDelegate = AudioPlayCallback;
AudioPauseDelegate = AudioPauseCallback;
AudioResumeDelegate = AudioResumeCallback;
AudioFlushDelegate = AudioFlushCallback;
AudioDrainDelegate = AudioDrainCallback;
}
}
public static void Close()
{
if (lib != IntPtr.Zero)
{
List<int> keys = videos.Keys.ToList();
foreach (int key in keys)
{
videos[key].Dispose();
}
LibVlcWrapper.LibVlcMethods.libvlc_free(lib);
lib = IntPtr.Zero;
}
}
private int videoId;
private IntPtr unmanagedData;
private IntPtr media;
private IntPtr mediaPlayer;
private Texture2D texture;
private byte[] textureData;
private object mutex;
private VideoSound sound;
/*private IntPtr videoLockDelegate;
private IntPtr videoUnlockDelegate;
private IntPtr videoDisplayDelegate;*/
public uint Width { get; private set; }
public uint Height { get; private set; }
public Video(GraphicsDevice graphicsDevice,SoundManager soundManager,string filename,uint width,uint height)
{
Init();
mutex = new object();
sound = new VideoSound(soundManager, filename, 44100, this);
videos.Add(latestVideoId, this);
videoId = latestVideoId; latestVideoId++;
/*using (var stream = File.OpenRead(filename))
{*/
byte[] filenameBytes = Encoding.UTF8.GetBytes(filename);
byte[] filenameBytesNullTerminated = new byte[filenameBytes.Length + 1];
filenameBytesNullTerminated[filenameBytes.Length] = 0;
Array.Copy(filenameBytes, filenameBytesNullTerminated, filenameBytes.Length);
media = LibVlcWrapper.LibVlcMethods.libvlc_media_new_path(lib, filenameBytesNullTerminated);
LibVlcWrapper.LibVlcMethods.libvlc_media_parse(media);
mediaPlayer = LibVlcWrapper.LibVlcMethods.libvlc_media_player_new(lib);
LibVlcWrapper.LibVlcMethods.libvlc_media_player_set_media(mediaPlayer, media);
//LibVlcWrapper.LibVlcMethods.libvlc_media_release(media);
//LibVlcWrapper.LibVlcMethods.libvlc_video_get_size(mediaPlayer, 0, out width, out height);
texture = new Texture2D(graphicsDevice, (int)width, (int)height);
Width = width; Height = height;
unmanagedData = Marshal.AllocHGlobal(sizeof(int)*2+(int)(width*height*3));
int[] arr = { videoId, 1 };
Marshal.Copy(arr, 0, unmanagedData, 2);
textureData = new byte[width * height * 3];
for (int i = 0; i < width*height*3; i++)
{
textureData[i] = 0;
}
IntPtr videoLockDelegatePtr = Marshal.GetFunctionPointerForDelegate(VideoLockDelegate);
IntPtr videoUnlockDelegatePtr = Marshal.GetFunctionPointerForDelegate(VideoUnlockDelegate);
IntPtr videoDisplayDelegatePtr = Marshal.GetFunctionPointerForDelegate(VideoDisplayDelegate);
LibVlcWrapper.LibVlcMethods.libvlc_video_set_callbacks(mediaPlayer, videoLockDelegatePtr, videoUnlockDelegatePtr, videoDisplayDelegatePtr, unmanagedData);
LibVlcWrapper.LibVlcMethods.libvlc_video_set_format(mediaPlayer, Encoding.UTF8.GetBytes("RV24"), (int)width, (int)height, (int)width * 3);
IntPtr audioPlayDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioPlayDelegate);
IntPtr audioPauseDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioPauseDelegate);
IntPtr audioResumeDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioResumeDelegate);
IntPtr audioFlushDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioFlushDelegate);
IntPtr audioDrainDelegatePtr = Marshal.GetFunctionPointerForDelegate(AudioDrainDelegate);
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_callbacks(mediaPlayer, audioPlayDelegatePtr, audioPauseDelegatePtr, audioResumeDelegatePtr, audioFlushDelegatePtr, audioDrainDelegatePtr, unmanagedData);
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_format(mediaPlayer, Encoding.UTF8.GetBytes("S16N"), 44100, 2);
LibVlcWrapper.LibVlcMethods.libvlc_audio_set_delay(mediaPlayer, 0);
LibVlcWrapper.LibVlcMethods.libvlc_media_player_play(mediaPlayer);
//}
}
public void Dispose()
{
LibVlcWrapper.LibVlcMethods.libvlc_media_player_stop(mediaPlayer);
Monitor.Enter(mutex);
//just waiting for callbacks to be done
Monitor.Exit(mutex);
Marshal.FreeHGlobal(unmanagedData);
sound.Dispose();
LibVlcWrapper.LibVlcMethods.libvlc_media_release(media);
LibVlcWrapper.LibVlcMethods.libvlc_media_player_release(mediaPlayer);
texture.Dispose();
videos.Remove(videoId);
}
public bool IsPlaying
{
get
{
return LibVlcWrapper.LibVlcMethods.libvlc_media_player_is_playing(mediaPlayer)!=0;
}
}
public Texture2D GetTexture()
{
Monitor.Enter(mutex);
int[] arr = { -1 };
IntPtr changedPtr = (IntPtr)(unmanagedData.ToInt64() + sizeof(int));
Marshal.Copy(changedPtr, arr, 0, 1);
if (arr[0]!=0)
{
IntPtr colorLocation = (IntPtr)(unmanagedData.ToInt64() + sizeof(int) * 2);
Marshal.Copy(colorLocation, textureData, 0, (int)(Width * Height * 3));
Color[] colors = new Color[Width * Height];
for (int y = 0; y < Height;y++)
{
for (int x = 0; x < Width;x++)
{
colors[x + y * Width] = new Color(textureData[3 * (x + y * Width) + 0],
textureData[3 * (x + y * Width) + 1],
textureData[3 * (x + y * Width) + 2],
(byte)255);
}
}
texture.SetData(colors);
arr[0] = 0;
Marshal.Copy(arr, 0, changedPtr, 1);
}
if (!sound.IsPlaying()) videos[videoId].sound.Play();
Monitor.Exit(mutex);
return texture;
}
static IntPtr VideoLockCallback(IntPtr opaque, IntPtr planes)
{
int[] arr = { -1 };
Marshal.Copy(opaque, arr, 0, 1);
int mutexIndex = arr[0];
Monitor.Enter(videos[mutexIndex].mutex);
IntPtr unmanagedData = (IntPtr)(opaque.ToInt64() + sizeof(int) * 2);
IntPtr[] ptrPtr = { unmanagedData };
Marshal.Copy(ptrPtr, 0, planes, 1);
return IntPtr.Zero;
}
static void VideoUnlockCallback(IntPtr opaque, IntPtr picture, IntPtr planes)
{
int[] arr = { -1 };
Marshal.Copy(opaque, arr, 0, 1);
int mutexIndex = arr[0];
arr[0] = 1;
IntPtr changedPtr = (IntPtr)(opaque.ToInt64() + sizeof(int));
Marshal.Copy(arr, 0, changedPtr, 1);
Monitor.Exit(videos[mutexIndex].mutex);
}
static void VideoDisplayCallback(IntPtr opaque,IntPtr picture)
{
//Assert(picture == IntPtr.Zero);
}
static void AudioPlayCallback(IntPtr data, IntPtr samples, uint count, long pts)
{
short[] buf = new short[count*2];
Marshal.Copy(samples, buf, 0, (int)count*2);
int[] arr = { -1 };
Marshal.Copy(data, arr, 0, 1);
int mutexIndex = arr[0];
Monitor.Enter(videos[mutexIndex].mutex);
videos[mutexIndex].sound.Enqueue(buf);
Monitor.Exit(videos[mutexIndex].mutex);
}
static void AudioPauseCallback(IntPtr data, long pts)
{
}
static void AudioResumeCallback(IntPtr data, long pts)
{
}
static void AudioFlushCallback(IntPtr data, long pts)
{
}
static void AudioDrainCallback(IntPtr data)
{
}
}
}

View File

@@ -1,7 +1,22 @@
using Microsoft.Xna.Framework;
using Lidgren.Network;
using System;
using System.Collections.Generic;
namespace Barotrauma.Networking
{
partial class BannedPlayer
{
public BannedPlayer(string name, UInt16 uniqueIdentifier, bool isRangeBan, string ip, ulong steamID)
{
this.Name = name;
this.SteamID = steamID;
this.IsRangeBan = isRangeBan;
this.IP = ip;
this.UniqueIdentifier = uniqueIdentifier;
}
}
partial class BanList
{
private GUIComponent banFrame;
@@ -11,12 +26,27 @@ namespace Barotrauma.Networking
get { return banFrame; }
}
public List<UInt16> localRemovedBans = new List<UInt16>();
public List<UInt16> localRangeBans = new List<UInt16>();
private void RecreateBanFrame()
{
if (banFrame != null)
{
var parent = banFrame.Parent;
parent.RemoveChild(banFrame);
CreateBanFrame(parent);
}
}
public GUIComponent CreateBanFrame(GUIComponent parent)
{
banFrame = new GUIListBox(new RectTransform(Vector2.One, parent.RectTransform, Anchor.Center));
foreach (BannedPlayer bannedPlayer in bannedPlayers)
{
if (localRemovedBans.Contains(bannedPlayer.UniqueIdentifier)) continue;
var playerFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.25f), ((GUIListBox)banFrame).Content.RectTransform) { MinSize = new Point(0, 70) }, style: null)
{
UserData = banFrame
@@ -28,8 +58,10 @@ namespace Barotrauma.Networking
RelativeSpacing = 0.05f
};
string ip = bannedPlayer.IP;
if (localRangeBans.Contains(bannedPlayer.UniqueIdentifier)) ip = ToRange(ip);
GUITextBlock textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.3f), paddedPlayerFrame.RectTransform),
bannedPlayer.IP + " (" + bannedPlayer.Name + ")");
bannedPlayer.Name + " (" + ip + ")");
var removeButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.4f), paddedPlayerFrame.RectTransform, Anchor.TopRight), TextManager.Get("BanListRemove"))
{
@@ -71,14 +103,9 @@ namespace Barotrauma.Networking
BannedPlayer banned = obj as BannedPlayer;
if (banned == null) return false;
RemoveBan(banned);
localRemovedBans.Add(banned.UniqueIdentifier);
if (banFrame != null)
{
var parent = banFrame.Parent;
parent.RemoveChild(banFrame);
CreateBanFrame(parent);
}
RecreateBanFrame();
return true;
}
@@ -88,14 +115,9 @@ namespace Barotrauma.Networking
BannedPlayer banned = obj as BannedPlayer;
if (banned == null) return false;
RangeBan(banned);
localRangeBans.Add(banned.UniqueIdentifier);
if (banFrame != null)
{
var parent = banFrame.Parent;
parent.RemoveChild(banFrame);
CreateBanFrame(parent);
}
RecreateBanFrame();
return true;
}
@@ -106,5 +128,66 @@ namespace Barotrauma.Networking
return true;
}
public void ClientAdminRead(NetBuffer incMsg)
{
bool hasPermission = incMsg.ReadBoolean();
if (!hasPermission)
{
incMsg.ReadPadBits();
return;
}
bool isOwner = incMsg.ReadBoolean();
incMsg.ReadPadBits();
bannedPlayers.Clear();
Int32 bannedPlayerCount = incMsg.ReadVariableInt32();
for (int i = 0; i < bannedPlayerCount; i++)
{
string name = incMsg.ReadString();
UInt16 uniqueIdentifier = incMsg.ReadUInt16();
bool isRangeBan = incMsg.ReadBoolean(); incMsg.ReadPadBits();
string ip = "";
UInt64 steamID = 0;
if (isOwner)
{
ip = incMsg.ReadString();
steamID = incMsg.ReadUInt64();
}
else
{
ip = "IP concealed by host";
steamID = 0;
}
bannedPlayers.Add(new BannedPlayer(name, uniqueIdentifier, isRangeBan, ip, steamID));
}
if (banFrame != null)
{
var parent = banFrame.Parent;
parent.RemoveChild(banFrame);
CreateBanFrame(parent);
}
}
public void ClientAdminWrite(NetBuffer outMsg)
{
outMsg.Write((UInt16)localRemovedBans.Count);
foreach (UInt16 uniqueId in localRemovedBans)
{
outMsg.Write(uniqueId);
}
outMsg.Write((UInt16)localRangeBans.Count);
foreach (UInt16 uniqueId in localRangeBans)
{
outMsg.Write(uniqueId);
}
localRemovedBans.Clear();
localRangeBans.Clear();
}
}
}

View File

@@ -60,7 +60,7 @@ namespace Barotrauma.Networking
{
orderOption = order.Options[optionIndex];
}
txt = order.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.RoomName, orderOption);
txt = order.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.RoomName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
if (order.TargetAllCharacters)
{
@@ -99,7 +99,7 @@ namespace Barotrauma.Networking
{
return;
}
GameMain.Client.ServerLog?.WriteLine(txt, messageType);
GameMain.Client.ServerSettings.ServerLog?.WriteLine(txt, messageType);
break;
default:
GameMain.Client.AddChatMessage(txt, type, senderName, senderCharacter);

View File

@@ -0,0 +1,137 @@
using Barotrauma.Sounds;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Barotrauma.Networking
{
struct TempClient
{
public string Name;
public byte ID;
public UInt16 CharacterID;
public bool Muted;
}
partial class Client : IDisposable
{
public VoipSound VoipSound
{
get;
set;
}
private bool mutedLocally;
public bool MutedLocally
{
get { return mutedLocally; }
set
{
if (mutedLocally == value) { return; }
mutedLocally = value;
#if CLIENT
GameMain.NetLobbyScreen.SetPlayerVoiceIconState(this, muted, mutedLocally);
GameMain.GameSession?.CrewManager?.SetPlayerVoiceIconState(this, muted, mutedLocally);
#endif
}
}
public void UpdateSoundPosition()
{
if (VoipSound != null)
{
if (!VoipSound.IsPlaying)
{
DebugConsole.Log("Destroying voipsound");
VoipSound.Dispose();
VoipSound = null;
return;
}
if (character != null)
{
VoipSound.SetPosition(new Vector3(character.WorldPosition.X, character.WorldPosition.Y, 0.0f));
}
else
{
VoipSound.SetPosition(null);
}
}
}
partial void InitProjSpecific()
{
VoipQueue = null; VoipSound = null;
if (ID == GameMain.Client.ID) return;
VoipQueue = new VoipQueue(ID, false, true);
GameMain.Client.VoipClient.RegisterQueue(VoipQueue);
VoipSound = null;
}
public void SetPermissions(ClientPermissions permissions, List<string> permittedConsoleCommands)
{
List<DebugConsole.Command> permittedCommands = new List<DebugConsole.Command>();
foreach (string commandName in permittedConsoleCommands)
{
var consoleCommand = DebugConsole.Commands.Find(c => c.names.Contains(commandName));
if (consoleCommand != null)
{
permittedCommands.Add(consoleCommand);
}
}
SetPermissions(permissions, permittedCommands);
}
public void SetPermissions(ClientPermissions permissions, List<DebugConsole.Command> permittedConsoleCommands)
{
if (GameMain.Client == null)
{
return;
}
Permissions = permissions;
PermittedConsoleCommands = new List<DebugConsole.Command>(permittedConsoleCommands);
}
public void GivePermission(ClientPermissions permission)
{
if (GameMain.Client == null || !GameMain.Client.HasPermission(ClientPermissions.ManagePermissions))
{
return;
}
if (!Permissions.HasFlag(permission)) Permissions |= permission;
}
public void RemovePermission(ClientPermissions permission)
{
if (GameMain.Client == null || !GameMain.Client.HasPermission(ClientPermissions.ManagePermissions))
{
return;
}
if (Permissions.HasFlag(permission)) Permissions &= ~permission;
}
public bool HasPermission(ClientPermissions permission)
{
if (GameMain.Client == null)
{
return false;
}
return Permissions.HasFlag(permission);
}
partial void DisposeProjSpecific()
{
if (VoipQueue != null)
{
GameMain.Client.VoipClient.UnregisterQueue(VoipQueue);
}
if (VoipSound != null)
{
VoipSound.Dispose();
VoipSound = null;
}
}
}
}

View File

@@ -6,8 +6,6 @@ namespace Barotrauma
{
public void ClientRead(ServerNetObject type, Lidgren.Network.NetBuffer message, float sendingTime)
{
if (GameMain.Server != null) return;
bool remove = message.ReadBoolean();
if (remove)

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