From 23687fbf2fc46f138cfb55ccc359e11c747e0136 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Mon, 18 Mar 2019 22:57:05 +0200 Subject: [PATCH] aeafa16...4d3cf73 --- .../BarotraumaClient/ClientCode.projitems | 3 + .../BarotraumaClient/Content/Content.mgcb | 51 -- .../Content/Content_opengl.mgcb | 51 -- .../Content/Effects/deformshader.xnb | Bin 7613 -> 8220 bytes .../Content/Effects/deformshader_opengl.xnb | Bin 7997 -> 8469 bytes .../Content/Effects/solidcolor.xnb | Bin 0 -> 1876 bytes .../Content/Effects/solidcolor_opengl.xnb | Bin 0 -> 1500 bytes .../BarotraumaClient/LinuxClient.csproj | 9 +- Barotrauma/BarotraumaClient/MacClient.csproj | 7 + .../Effects => Shaders}/blurshader.fx | 0 .../Effects => Shaders}/blurshader_opengl.fx | 0 .../Effects => Shaders}/damageshader.fx | 0 .../damageshader_opengl.fx | 0 .../Effects => Shaders}/deformshader.fx | 15 + .../deformshader_opengl.fx | 15 + .../{Content/Effects => Shaders}/losshader.fx | 0 .../Effects => Shaders}/losshader_opengl.fx | 0 .../Effects => Shaders}/postprocess.fx | 0 .../Effects => Shaders}/postprocess_opengl.fx | 0 .../Effects => Shaders}/watershader.fx | 0 .../Effects => Shaders}/watershader_opengl.fx | 0 .../Source/Characters/AI/HumanAIController.cs | 47 -- .../Source/Characters/Character.cs | 2 +- .../Source/Characters/CharacterHUD.cs | 11 +- .../Source/Characters/CharacterNetworking.cs | 5 +- .../BarotraumaClient/Source/DebugConsole.cs | 203 ++++- Barotrauma/BarotraumaClient/Source/GUI/GUI.cs | 6 +- .../Source/GameSession/CrewManager.cs | 50 +- .../Source/GameSession/GameSession.cs | 25 +- .../BarotraumaClient/Source/GameSettings.cs | 22 - .../Source/Items/Components/ItemComponent.cs | 57 -- .../Source/Items/Inventory.cs | 4 +- .../BarotraumaClient/Source/Items/Item.cs | 5 + .../Source/Networking/GameClient.cs | 16 +- .../Source/Screens/CampaignUI.cs | 13 +- .../Source/Screens/CharacterEditorScreen.cs | 37 + .../Source/Screens/MainMenuScreen.cs | 24 +- .../Source/Screens/SubEditorScreen.cs | 13 +- .../Source/Sounds/SoundManager.cs | 10 + .../Source/Utils/LocalizationCSVtoXML.cs | 246 ++++++ .../BarotraumaClient/WindowsClient.csproj | 7 + .../Source/Characters/CharacterNetworking.cs | 12 +- .../Source/Items/Inventory.cs | 2 +- .../Source/Networking/GameServer.cs | 749 +++++++++++++++++- .../Source/Networking/GameServerLogin.cs | 4 +- .../BarotraumaShared/SharedContent.projitems | 35 +- .../Source/Characters/AI/HumanAIController.cs | 91 ++- .../Characters/AI/Objectives/AIObjective.cs | 11 +- .../AI/Objectives/AIObjectiveCombat.cs | 338 +++++--- .../Objectives/AIObjectiveExtinguishFire.cs | 2 +- .../Objectives/AIObjectiveFindDivingGear.cs | 2 +- .../AI/Objectives/AIObjectiveFindSafety.cs | 79 +- .../AI/Objectives/AIObjectiveFixLeak.cs | 1 + .../AI/Objectives/AIObjectiveFixLeaks.cs | 1 + .../AI/Objectives/AIObjectiveGetItem.cs | 2 +- .../AI/Objectives/AIObjectiveGoTo.cs | 29 +- .../AI/Objectives/AIObjectiveIdle.cs | 33 +- .../AI/Objectives/AIObjectiveManager.cs | 38 - .../AI/Objectives/AIObjectiveOperateItem.cs | 2 +- .../AI/Objectives/AIObjectiveRepairItem.cs | 31 +- .../Characters/Health/CharacterHealth.cs | 3 +- .../Source/Events/EventManager.cs | 18 +- .../BarotraumaShared/Source/GameSettings.cs | 463 ++++++++--- .../Items/Components/Holdable/Holdable.cs | 2 +- .../Items/Components/Holdable/RepairTool.cs | 5 +- .../Items/Components/Holdable/Throwable.cs | 2 +- .../Source/Items/Components/ItemContainer.cs | 2 +- .../Items/Components/Machines/Fabricator.cs | 2 +- .../Items/Components/Machines/Reactor.cs | 2 +- .../Source/Items/Components/Projectile.cs | 4 +- .../Source/Items/Components/Turret.cs | 2 +- .../BarotraumaShared/Source/Items/Item.cs | 2 +- .../BarotraumaShared/Source/Map/Map/Map.cs | 7 - .../BarotraumaShared/Source/Map/Submarine.cs | 52 +- .../BarotraumaShared/Source/PlayerInput.cs | 10 - .../BarotraumaShared/Submarines/Dugong.sub | Bin 66437 -> 69867 bytes .../BarotraumaShared/Submarines/Venture.sub | Bin 0 -> 72405 bytes 77 files changed, 2275 insertions(+), 717 deletions(-) delete mode 100644 Barotrauma/BarotraumaClient/Content/Content.mgcb delete mode 100644 Barotrauma/BarotraumaClient/Content/Content_opengl.mgcb create mode 100644 Barotrauma/BarotraumaClient/Content/Effects/solidcolor.xnb create mode 100644 Barotrauma/BarotraumaClient/Content/Effects/solidcolor_opengl.xnb rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/blurshader.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/blurshader_opengl.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/damageshader.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/damageshader_opengl.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/deformshader.fx (87%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/deformshader_opengl.fx (87%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/losshader.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/losshader_opengl.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/postprocess.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/postprocess_opengl.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/watershader.fx (100%) rename Barotrauma/BarotraumaClient/{Content/Effects => Shaders}/watershader_opengl.fx (100%) create mode 100644 Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs create mode 100644 Barotrauma/BarotraumaShared/Submarines/Venture.sub diff --git a/Barotrauma/BarotraumaClient/ClientCode.projitems b/Barotrauma/BarotraumaClient/ClientCode.projitems index 3864fe96e..a5cc964a4 100644 --- a/Barotrauma/BarotraumaClient/ClientCode.projitems +++ b/Barotrauma/BarotraumaClient/ClientCode.projitems @@ -214,6 +214,9 @@ + + Never + diff --git a/Barotrauma/BarotraumaClient/Content/Content.mgcb b/Barotrauma/BarotraumaClient/Content/Content.mgcb deleted file mode 100644 index b23f45db0..000000000 --- a/Barotrauma/BarotraumaClient/Content/Content.mgcb +++ /dev/null @@ -1,51 +0,0 @@ - -#----------------------------- Global Properties ----------------------------# - -/outputDir:bin/$(Platform) -/intermediateDir:obj/$(Platform) -/platform:Windows -/config: -/profile:Reach -/compress:False - -#-------------------------------- References --------------------------------# - - -#---------------------------------- Content ---------------------------------# - -#begin Effects/blurshader.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/blurshader.fx - -#begin Effects/damageshader.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/damageshader.fx - -#begin Effects/deformshader.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/deformshader.fx - -#begin Effects/losshader.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/losshader.fx - -#begin Effects/postprocess.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/postprocess.fx - -#begin Effects/watershader.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/watershader.fx - diff --git a/Barotrauma/BarotraumaClient/Content/Content_opengl.mgcb b/Barotrauma/BarotraumaClient/Content/Content_opengl.mgcb deleted file mode 100644 index d89dd6e4e..000000000 --- a/Barotrauma/BarotraumaClient/Content/Content_opengl.mgcb +++ /dev/null @@ -1,51 +0,0 @@ - -#----------------------------- Global Properties ----------------------------# - -/outputDir:bin/$(Platform) -/intermediateDir:obj/$(Platform) -/platform:DesktopGL -/config: -/profile:Reach -/compress:False - -#-------------------------------- References --------------------------------# - - -#---------------------------------- Content ---------------------------------# - -#begin Effects/blurshader_opengl.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/blurshader_opengl.fx - -#begin Effects/damageshader_opengl.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/damageshader_opengl.fx - -#begin Effects/deformshader_opengl.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/deformshader_opengl.fx - -#begin Effects/losshader_opengl.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/losshader_opengl.fx - -#begin Effects/postprocess_opengl.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/postprocess_opengl.fx - -#begin Effects/watershader_opengl.fx -/importer:EffectImporter -/processor:EffectProcessor -/processorParam:DebugMode=Auto -/build:Effects/watershader_opengl.fx - diff --git a/Barotrauma/BarotraumaClient/Content/Effects/deformshader.xnb b/Barotrauma/BarotraumaClient/Content/Effects/deformshader.xnb index d40fbb2203f7475e760b9a24c3b4e19d31217ad8..35b0ae81bddd7029e438a6eb0d18c3f1c8f6496b 100644 GIT binary patch delta 400 zcmdmMJ;#A3!q2Ikl|e>jzYmZy0b)i54JgY5$X0=}ffU0FARh{V z>VZxJ+RD(t$S~QAQN#Fu0|Ud81waK%3>^F*cEkVw3=F{@E$ThADY5xt~XVvIdjtWOrVP$**~oCwDNJv2p@! z;o98H%PYXa$jnuopOcv~xl~rik%`A8H7&m=H#j3PCAElwku@N(xY!WlXfb4|V2~E) M{G5CwMIgTb02}&O^#A|> delta 84 zcmbQ^u-BR=!q2Ikm0_?b@b3H>nLkr7^2|B`hKtW%3w+If#V@z$|{Act;w?)C3p-J%0f~rob&UGQVb^N zG0IOq$Y@|=pjT0;2{eWis6XG?K*1JdM3I4BIS?plK}-co*Ya}laxpRh0V`0x*noqP zk%4ow2>)At4n}6K;{2Sl8zl3I=I$ N&dWhN@@+*<+L;a?{Th!k#MD)7|Wve&5KF`%koqs$iA+zMWs zV8gZ<6G;MwF(TS z@FmaZ9=JaqUC~j$Umj(*N5&;*w8;*%_zu=^eXhsH%ID2Fg>~=XD(oKz(mLEO^L0X2@Yrasp5MJa|_0y+7hayN?)xy$6toYhCVG zc~9s54}0|Cb2xeBFEyCc-&F%4r#@p`pM^OrIQ}inj|mfu*yEj_hM?cufB$KaNE#?< zbu(G5S&Cj(F~R&|Ac7Pq8=7Il;?F~uNWG!8yt>B!RxTp;=M1g7m~gfTfqA7?8zOws PiT1aFI4V&KB2I`sSl*f0nQ!O&W=Ee+g9iE0AjG;KO5f;MhY1@gkDVKDDl%>ESWl}& zsDzz`q41N>!V84y(4kg(03lUihkg+zmRfb+vSY@XbL_tF&|VrPsS#Zz(!_XChhC<) zk@P=`#kIZ@s;kl{BDkyzKrtMgj}FMopY0E|!&y8|l?=6+#^bs0-yISQ!uHIR)CxPP zkpO;5-Y_4)n*ep984z3D6x#_eNRjECo*Sx7Zm7Mov-yr;DZcGAu{tz26L zb&u0YGzQWpJsoL-_~%*%bm~dfYB%j~P5T+tGMsj4B66g}?YD~R9RxAwEMK$%2u5MH zE?Ny|87%q=H$I~Ij+wFFqyeUw7rn37|6Si*?7Od3oRq})E}%s!TAZQeIOEj^@3ciz zxp6i`nn_-E?KC+c|--kcclW@+-DH@rr`eJ zMA-R<EL)@bLy|lzlRTzeELAEOFHn|R-F&lDaxZIE?VNJ;90DS@q|)QEK`!PCVrc2r9;kkowbu l93B81(dCJneWfEA6oXBy#-$g>4*7+?7nS1_a#c=D^&9FDy*~f| literal 0 HcmV?d00001 diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj index fe0c40067..5bfa817fa 100644 --- a/Barotrauma/BarotraumaClient/LinuxClient.csproj +++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj @@ -152,7 +152,14 @@ - + + + + + + + + PreserveNewest diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index a12706abe..5fbe31943 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -153,6 +153,13 @@ + + + + + + + PreserveNewest diff --git a/Barotrauma/BarotraumaClient/Content/Effects/blurshader.fx b/Barotrauma/BarotraumaClient/Shaders/blurshader.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/blurshader.fx rename to Barotrauma/BarotraumaClient/Shaders/blurshader.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/blurshader_opengl.fx b/Barotrauma/BarotraumaClient/Shaders/blurshader_opengl.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/blurshader_opengl.fx rename to Barotrauma/BarotraumaClient/Shaders/blurshader_opengl.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/damageshader.fx b/Barotrauma/BarotraumaClient/Shaders/damageshader.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/damageshader.fx rename to Barotrauma/BarotraumaClient/Shaders/damageshader.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/damageshader_opengl.fx b/Barotrauma/BarotraumaClient/Shaders/damageshader_opengl.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/damageshader_opengl.fx rename to Barotrauma/BarotraumaClient/Shaders/damageshader_opengl.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/deformshader.fx b/Barotrauma/BarotraumaClient/Shaders/deformshader.fx similarity index 87% rename from Barotrauma/BarotraumaClient/Content/Effects/deformshader.fx rename to Barotrauma/BarotraumaClient/Shaders/deformshader.fx index bf621efe0..dcf54addd 100644 --- a/Barotrauma/BarotraumaClient/Content/Effects/deformshader.fx +++ b/Barotrauma/BarotraumaClient/Shaders/deformshader.fx @@ -14,6 +14,7 @@ float2 uvTopLeft; float2 uvBottomRight; float4 tintColor; +float4 solidColor; struct VertexShaderInput { @@ -74,6 +75,11 @@ float4 mainPS(VertexShaderOutput input) : COLOR return xTexture.Sample(TextureSampler, input.TexCoords) * input.Color; } +float4 solidColorPS(VertexShaderOutput input) : COLOR +{ + return solidColor * xTexture.Sample(TextureSampler, input.TexCoords).a; +} + technique DeformShader { pass Pass1 @@ -81,4 +87,13 @@ technique DeformShader VertexShader = compile vs_4_0_level_9_1 mainVS(); PixelShader = compile ps_4_0_level_9_1 mainPS(); } +} + +technique DeformShaderSolidColor +{ + pass Pass1 + { + VertexShader = compile vs_4_0_level_9_1 mainVS(); + PixelShader = compile ps_4_0_level_9_1 solidColorPS(); + } } \ No newline at end of file diff --git a/Barotrauma/BarotraumaClient/Content/Effects/deformshader_opengl.fx b/Barotrauma/BarotraumaClient/Shaders/deformshader_opengl.fx similarity index 87% rename from Barotrauma/BarotraumaClient/Content/Effects/deformshader_opengl.fx rename to Barotrauma/BarotraumaClient/Shaders/deformshader_opengl.fx index fbf640ede..c77904ffe 100644 --- a/Barotrauma/BarotraumaClient/Content/Effects/deformshader_opengl.fx +++ b/Barotrauma/BarotraumaClient/Shaders/deformshader_opengl.fx @@ -14,6 +14,7 @@ float2 uvTopLeft; float2 uvBottomRight; float4 tintColor; +float4 solidColor; struct VertexShaderInput { @@ -74,6 +75,11 @@ float4 mainPS(VertexShaderOutput input) : COLOR return xTexture.Sample(TextureSampler, input.TexCoords) * input.Color; } +float4 solidColorPS(VertexShaderOutput input) : COLOR +{ + return solidColor * xTexture.Sample(TextureSampler, input.TexCoords).a; +} + technique DeformShader { pass Pass1 @@ -81,4 +87,13 @@ technique DeformShader VertexShader = compile vs_3_0 mainVS(); PixelShader = compile ps_3_0 mainPS(); } +} + +technique DeformShaderSolidColor +{ + pass Pass1 + { + VertexShader = compile vs_3_0 mainVS(); + PixelShader = compile ps_3_0 solidColorPS(); + } } \ No newline at end of file diff --git a/Barotrauma/BarotraumaClient/Content/Effects/losshader.fx b/Barotrauma/BarotraumaClient/Shaders/losshader.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/losshader.fx rename to Barotrauma/BarotraumaClient/Shaders/losshader.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/losshader_opengl.fx b/Barotrauma/BarotraumaClient/Shaders/losshader_opengl.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/losshader_opengl.fx rename to Barotrauma/BarotraumaClient/Shaders/losshader_opengl.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/postprocess.fx b/Barotrauma/BarotraumaClient/Shaders/postprocess.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/postprocess.fx rename to Barotrauma/BarotraumaClient/Shaders/postprocess.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/postprocess_opengl.fx b/Barotrauma/BarotraumaClient/Shaders/postprocess_opengl.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/postprocess_opengl.fx rename to Barotrauma/BarotraumaClient/Shaders/postprocess_opengl.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/watershader.fx b/Barotrauma/BarotraumaClient/Shaders/watershader.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/watershader.fx rename to Barotrauma/BarotraumaClient/Shaders/watershader.fx diff --git a/Barotrauma/BarotraumaClient/Content/Effects/watershader_opengl.fx b/Barotrauma/BarotraumaClient/Shaders/watershader_opengl.fx similarity index 100% rename from Barotrauma/BarotraumaClient/Content/Effects/watershader_opengl.fx rename to Barotrauma/BarotraumaClient/Shaders/watershader_opengl.fx diff --git a/Barotrauma/BarotraumaClient/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaClient/Source/Characters/AI/HumanAIController.cs index 9f108885f..b588b93a4 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/AI/HumanAIController.cs @@ -87,52 +87,5 @@ namespace Barotrauma // GUI.DrawLine(spriteBatch, pos, new Vector2(Character.CursorWorldPosition.X, -Character.CursorWorldPosition.Y), Color.Yellow, width: 4); //} } - - //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); - } - } - } } } diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs index 390c10936..615423b53 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs @@ -338,7 +338,7 @@ namespace Barotrauma var entityList = Submarine.VisibleEntities ?? Item.ItemList; Item closestItem = null; - float closestItemDistance = aimAssistAmount; + float closestItemDistance = Math.Max(aimAssistAmount, 2.0f); foreach (MapEntity entity in entityList) { if (!(entity is Item item)) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs index 7c5967485..86c88a3e0 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs @@ -1,4 +1,5 @@ using Barotrauma.Items.Components; +using FarseerPhysics; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; @@ -136,10 +137,14 @@ namespace Barotrauma brokenItemsCheckTimer = 1.0f; foreach (Item item in Item.ItemList) { - if (item.CurrentHull == character.CurrentHull && item.Repairables.Any(r => item.Condition < r.ShowRepairUIThreshold)) + if (!item.Repairables.Any(r => item.Condition < r.ShowRepairUIThreshold)) { continue; } + if (!Submarine.VisibleEntities.Contains(item)) { continue; } + + Vector2 diff = item.WorldPosition - character.WorldPosition; + if (Submarine.CheckVisibility(character.SimPosition, character.SimPosition + ConvertUnits.ToSimUnits(diff)) == null) { - brokenItems.Add(item); - } + brokenItems.Add(item); + } } } } diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs index 983ffb1a5..4aac62ef9 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterNetworking.cs @@ -123,10 +123,7 @@ namespace Barotrauma for (int i = 0; i < inputCount; i++) { msg.WriteRangedInteger(0, (int)InputNetFlags.MaxVal, (int)memInput[i].states); - if (memInput[i].states.HasFlag(InputNetFlags.Aim)) - { - msg.Write(memInput[i].intAim); - } + msg.Write(memInput[i].intAim); if (memInput[i].states.HasFlag(InputNetFlags.Select) || memInput[i].states.HasFlag(InputNetFlags.Use) || memInput[i].states.HasFlag(InputNetFlags.Health) || diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs index 81342069c..6345fd8d7 100644 --- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs @@ -436,13 +436,15 @@ namespace Barotrauma 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; + if (Level.Loaded != null) + { + Level.Loaded.GenerationParams.AmbientLightColor = color; + } + else + { + GameMain.LightManager.AmbientLight = color; + } NewMessage("Set ambient light color to " + color + ".", Color.White); }); AssignRelayToServer("ambientlight", false); @@ -1050,6 +1052,195 @@ namespace Barotrauma TextManager.WriteToCSV(); NPCConversation.WriteToCSV(); })); + + commands.Add(new Command("csvtoxml", "csvtoxml [language] -> Converts .csv localization files in Content/NPCConversations & Content/Texts to .xml for use in-game.", (string[] args) => + { + if (args.Length == 0) return; + LocalizationCSVtoXML.Convert(args[0]); + })); +#endif + + commands.Add(new Command("cleanbuild", "", (string[] args) => + { + GameMain.Config.MusicVolume = 0.5f; + GameMain.Config.SoundVolume = 0.5f; + NewMessage("Music and sound volume set to 0.5", Color.Green); + + 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; + })); + + + 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 + + GameMain.Config.SaveNewPlayerConfig(); + + commands.Add(new Command("loadtexts", "loadtexts [sourcefile] [destinationfile]: Loads all lines of text from a given .txt file and inserts them sequientially into the elements of an xml file. If the file paths are omitted, EnglishVanilla.txt and EnglishVanilla.xml are used.", (string[] args) => + { + string sourcePath = args.Length > 0 ? args[0] : "Content/Texts/EnglishVanilla.txt"; + string destinationPath = args.Length > 1 ? args[1] : "Content/Texts/EnglishVanilla.xml"; + + string[] lines; + try + { + lines = File.ReadAllLines(sourcePath); + } + catch (Exception e) + { + ThrowError("Reading the file \"" + sourcePath + "\" failed.", e); + return; + } + var doc = XMLExtensions.TryLoadXml(destinationPath); + int i = 0; + foreach (XElement element in doc.Root.Elements()) + { + if (i >= lines.Length) + { + ThrowError("Error while loading texts to the xml file. The xml has more elements than the number of lines in the text file."); + return; + } + element.Value = lines[i]; + i++; + } + doc.Save(destinationPath); + }, + () => + { + var files = TextManager.GetTextFiles().Select(f => f.Replace("\\", "/")); + return new string[][] + { + files.Where(f => Path.GetExtension(f)==".txt").ToArray(), + files.Where(f => Path.GetExtension(f)==".xml").ToArray() + }; + })); + + commands.Add(new Command("updatetextfile", "updatetextfile [sourcefile] [destinationfile]: Inserts all the xml elements that are only present in the source file into the destination file. Can be used to update outdated translation files more easily.", (string[] args) => + { + if (args.Length < 2) return; + string sourcePath = args[0]; + string destinationPath = args[1]; + + var sourceDoc = XMLExtensions.TryLoadXml(sourcePath); + var destinationDoc = XMLExtensions.TryLoadXml(destinationPath); + + XElement destinationElement = destinationDoc.Root.Elements().First(); + foreach (XElement element in sourceDoc.Root.Elements()) + { + if (destinationDoc.Root.Element(element.Name) == null) + { + element.Value = "!!!!!!!!!!!!!" + element.Value; + destinationElement.AddAfterSelf(element); + } + XNode nextNode = destinationElement.NextNode; + while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode; + destinationElement = nextNode as XElement; + } + destinationDoc.Save(destinationPath); + }, + () => + { + var files = TextManager.GetTextFiles().Where(f => Path.GetExtension(f) == ".xml").Select(f => f.Replace("\\", "/")).ToArray(); + return new string[][] + { + files, + files + }; + })); + + commands.Add(new Command("dumpentitytexts", "dumpentitytexts [filepath]: gets the names and descriptions of all entity prefabs and writes them into a file along with xml tags that can be used in translation files. If the filepath is omitted, the file is written to Content/Texts/EntityTexts.txt", (string[] args) => + { + string filePath = args.Length > 0 ? args[0] : "Content/Texts/EntityTexts.txt"; + List lines = new List(); + foreach (MapEntityPrefab me in MapEntityPrefab.List) + { + lines.Add("" + me.Name + ""); + lines.Add("" + me.Description + ""); + } + 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(); + })); #endif commands.Add(new Command("cleanbuild", "", (string[] args) => diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs index 7d0daa696..cd8a792c0 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs @@ -384,12 +384,12 @@ namespace Barotrauma Cursor.Draw(spriteBatch, PlayerInput.LatestMousePosition); } - public static void DrawBackgroundSprite(SpriteBatch spriteBatch, Sprite backgroundSprite) + public static void DrawBackgroundSprite(SpriteBatch spriteBatch, Sprite backgroundSprite, float blurAmount = 1.0f, float aberrationStrength = 1.0f) { double aberrationT = (Timing.TotalTime * 0.5f); - GameMain.GameScreen.PostProcessEffect.Parameters["blurDistance"].SetValue(0.001f); + GameMain.GameScreen.PostProcessEffect.Parameters["blurDistance"].SetValue(0.001f * aberrationStrength); GameMain.GameScreen.PostProcessEffect.Parameters["chromaticAberrationStrength"].SetValue(new Vector3(-0.025f, -0.01f, -0.05f) * - (float)(PerlinNoise.CalculatePerlin(aberrationT, aberrationT, 0) + 0.5f)); + (float)(PerlinNoise.CalculatePerlin(aberrationT, aberrationT, 0) + 0.5f) * aberrationStrength); GameMain.GameScreen.PostProcessEffect.CurrentTechnique = GameMain.GameScreen.PostProcessEffect.Techniques["BlurChromaticAberration"]; GameMain.GameScreen.PostProcessEffect.CurrentTechnique.Passes[0].Apply(); diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 202dc9965..a5968ce0f 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -107,14 +107,37 @@ namespace Barotrauma }; scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically); - var characterInfo = new CharacterInfo(subElement); - characterInfos.Add(characterInfo); - foreach (XElement invElement in subElement.Elements()) + if (isSinglePlayer) + { + chatBox = new ChatBox(guiFrame, isSinglePlayer: true) { - if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue; - characterInfo.InventoryData = invElement; - break; - } + OnEnterMessage = (textbox, text) => + { + if (Character.Controlled == null) { return true; } + + textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default]; + + if (!string.IsNullOrWhiteSpace(text)) + { + string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg); + AddSinglePlayerChatMessage( + Character.Controlled.Info.Name, + 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.OnTextChanged += chatBox.TypingChatMessage; } var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null); @@ -136,6 +159,7 @@ namespace Barotrauma { if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false; SetCharacterOrder(null, order, null, Character.Controlled); + HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull); return true; }, UserData = order, @@ -152,12 +176,14 @@ namespace Barotrauma Visible = false }; - var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true) + var characterInfo = new CharacterInfo(subElement); + characterInfos.Add(characterInfo); + foreach (XElement invElement in subElement.Elements()) { - Color = order.Color, - HoverColor = Color.Lerp(order.Color, Color.White, 0.5f), - ToolTip = order.Name - }; + if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue; + characterInfo.InventoryData = invElement; + break; + } } screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs index fc3e1c8f8..16a57092d 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameSession.cs @@ -7,10 +7,6 @@ namespace Barotrauma { private InfoFrameTab selectedTab; private GUIButton infoFrame; - /// - /// Determines whether the hotkey for the info button was held down in the previous frame. - /// - private bool prevInfoKey; private GUIFrame infoFrameContent; @@ -19,12 +15,7 @@ namespace Barotrauma { get { return roundSummary; } } - - partial void InitProjSpecific() - { - prevInfoKey = false; - } - + private bool ToggleInfoFrame() { if (infoFrame == null) @@ -45,8 +36,7 @@ namespace Barotrauma int width = 600, height = 400; 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) }); var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), innerFrame.RectTransform, Anchor.Center), style:null); @@ -135,10 +125,17 @@ namespace Barotrauma { if (GUI.DisableHUD) return; - if (prevInfoKey != (PlayerInput.KeyDown(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber == null)) + if (PlayerInput.KeyDown(InputType.InfoTab) && + (GUI.KeyboardDispatcher.Subscriber == null || GUI.KeyboardDispatcher.Subscriber is GUIListBox)) + { + if (infoFrame == null) + { + ToggleInfoFrame(); + } + } + else if (infoFrame != null) { ToggleInfoFrame(); - prevInfoKey = PlayerInput.KeyDown(InputType.InfoTab); } infoFrame?.UpdateManually(deltaTime); diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs index a111ddc03..00085898f 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs @@ -626,28 +626,6 @@ namespace Barotrauma 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) => - { - if (UnsavedSettings) - { - LoadPlayerConfig(); - } - if (Screen.Selected == GameMain.MainMenuScreen) GameMain.MainMenuScreen.ReturnToMainMenu(null, null); - GUI.SettingsMenuOpen = false; - return true; - } - }; - //spacing new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null); diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs index 94a9eee32..72589ccf5 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs @@ -184,63 +184,6 @@ namespace Barotrauma.Items.Components } } } - - public void ApplyTo(RectTransform target) - { - if (RelativeOffset.HasValue) - { - target.RelativeOffset = RelativeOffset.Value; - } - else if (AbsoluteOffset.HasValue) - { - target.AbsoluteOffset = AbsoluteOffset.Value; - } - if (RelativeSize.HasValue) - { - target.RelativeSize = RelativeSize.Value; - } - else if (AbsoluteSize.HasValue) - { - target.NonScaledSize = AbsoluteSize.Value; - } - if (Anchor.HasValue) - { - target.Anchor = Anchor.Value; - } - if (Pivot.HasValue) - { - target.Pivot = Pivot.Value; - } - else - { - target.Pivot = RectTransform.MatchPivotToAnchor(target.Anchor); - } - target.RecalculateChildren(true, true); - } - } - - public GUIFrame GuiFrame { get; protected set; } - - [Serialize(false, false)] - public bool AllowUIOverlap - { - get; - set; - } - - private ItemComponent linkToUIComponent; - [Serialize("", false)] - public string LinkUIToComponent - { - get; - set; - } - - [Serialize(0, false)] - public int HudPriority - { - get; - private set; } private bool shouldMuffleLooping; diff --git a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs index 96adb2e97..44c39061f 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs @@ -598,7 +598,7 @@ namespace Barotrauma if (selectedSlot == null) { - draggingItem.Drop(); + draggingItem.Drop(Character.Controlled); GUI.PlayUISound(GUISoundType.DropItem); } else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem) @@ -954,7 +954,7 @@ namespace Barotrauma { if (receivedItemIDs[i] == 0 || (Entity.FindEntityByID(receivedItemIDs[i]) as Item != Items[i])) { - if (Items[i] != null) Items[i].Drop(); + if (Items[i] != null) Items[i].Drop(null); System.Diagnostics.Debug.Assert(Items[i] == null); } } diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index 9c7b97434..2f1a0c511 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -849,6 +849,11 @@ namespace Barotrauma { if (GameMain.Client == null) { return; } + if (parentInventory != null || body == null || !body.Enabled || Removed) + { + return; + } + Vector2 newVelocity = body.LinearVelocity; Vector2 newPosition = body.SimPosition; float newAngularVelocity = body.AngularVelocity; diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 1abfdefb6..98b7cd3bc 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -202,6 +202,12 @@ namespace Barotrauma.Networking private void ConnectToServer(string hostIP) { + chatBox.InputBox.Enabled = false; + if (GameMain.NetLobbyScreen?.TextBox != null) + { + GameMain.NetLobbyScreen.TextBox.Enabled = false; + } + string[] address = hostIP.Split(':'); if (address.Length == 1) { @@ -259,7 +265,11 @@ namespace Barotrauma.Networking { DebugConsole.ThrowError("Couldn't connect to " + hostIP + ". Error message: " + e.Message); Disconnect(); - + chatBox.InputBox.Enabled = true; + if (GameMain.NetLobbyScreen?.TextBox != null) + { + GameMain.NetLobbyScreen.TextBox.Enabled = true; + } GameMain.ServerListScreen.Select(); return; } @@ -530,6 +540,10 @@ namespace Barotrauma.Networking GameMain.NetLobbyScreen.Select(); } connected = true; + if (GameMain.NetLobbyScreen?.TextBox != null) + { + GameMain.NetLobbyScreen.TextBox.Enabled = true; + } } yield return CoroutineStatus.Success; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs index 258eb60de..12d87cf51 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs @@ -118,7 +118,18 @@ namespace Barotrauma CanBeFocused = false }; - characterList = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.95f), tabs[(int)Tab.Crew].RectTransform, Anchor.Center)) + var crewContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), tabs[(int)Tab.Crew].RectTransform, Anchor.Center)) + { + Stretch = true, + RelativeSpacing = 0.02f + }; + + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), crewContent.RectTransform), "", font: GUI.LargeFont) + { + TextGetter = GetMoney + }; + + characterList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.9f), crewContent.RectTransform)) { OnSelected = SelectCharacter }; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs index 523b82cc7..ce3420604 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs @@ -438,6 +438,43 @@ namespace Barotrauma UpdateSourceRect(limb, newRect); } } + UpdateJointCreation(); + if (PlayerInput.KeyHit(Keys.Left)) + { + foreach (var limb in selectedLimbs) + { + var newRect = limb.ActiveSprite.SourceRect; + newRect.X--; + UpdateSourceRect(limb, newRect); + } + } + if (PlayerInput.KeyHit(Keys.Right)) + { + foreach (var limb in selectedLimbs) + { + var newRect = limb.ActiveSprite.SourceRect; + newRect.X++; + UpdateSourceRect(limb, newRect); + } + } + if (PlayerInput.KeyHit(Keys.Down)) + { + foreach (var limb in selectedLimbs) + { + var newRect = limb.ActiveSprite.SourceRect; + newRect.Y++; + UpdateSourceRect(limb, newRect); + } + } + if (PlayerInput.KeyHit(Keys.Up)) + { + foreach (var limb in selectedLimbs) + { + var newRect = limb.ActiveSprite.SourceRect; + newRect.Y--; + UpdateSourceRect(limb, newRect); + } + } } if (!isFreezed) { diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index ca9b6c880..bb123c052 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -38,9 +38,18 @@ namespace Barotrauma #region Creation public MainMenuScreen(GameMain game) { + new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) + { RelativeOffset = new Vector2(0.05f, 0.05f), AbsoluteOffset = new Point(-5, -5) }, + style: "TitleText") + { + Color = Color.Black * 0.5f, + CanBeFocused = false + }; + new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.05f, 0.05f) }, + style: "TitleText"); + buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft, pivot: Pivot.BottomLeft) { - RelativeOffset = new Vector2(0, 0), AbsoluteOffset = new Point(50, 0) }) { @@ -66,7 +75,7 @@ namespace Barotrauma var campaignButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: campaignNavigation.RectTransform), style: "MainMenuGUIFrame"); - var campaignList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: campaignButtons.RectTransform)) + var campaignList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: campaignButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f @@ -112,7 +121,7 @@ namespace Barotrauma var multiplayerButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: multiplayerNavigation.RectTransform), style: "MainMenuGUIFrame"); - var multiplayerList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: multiplayerButtons.RectTransform)) + var multiplayerList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: multiplayerButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f @@ -157,7 +166,7 @@ namespace Barotrauma var customizeButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: customizeNavigation.RectTransform), style: "MainMenuGUIFrame"); - var customizeList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: customizeButtons.RectTransform)) + var customizeList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: customizeButtons.RectTransform)) { Stretch = false, RelativeSpacing = 0.035f @@ -673,7 +682,12 @@ namespace Barotrauma backgroundSprite = (LocationType.List.Where(l => l.UseInMainMenu).GetRandom()).GetPortrait(0); } - if (backgroundSprite != null) { GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite); } + if (backgroundSprite != null) + { + GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite, + blurAmount: 0.0f, + aberrationStrength: 0.0f); + } } public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs index 4469d6211..022395eb3 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SubEditorScreen.cs @@ -625,8 +625,7 @@ namespace Barotrauma { foreach (Item item in itemInventory.Items) { - if (item == null) continue; - item.Drop(); + item?.Drop(null); } } else // If current screen is not subeditor, delete anyway to avoid lingering objects @@ -671,8 +670,7 @@ namespace Barotrauma { foreach (Item item in itemInventory.Items) { - if (item == null) continue; - item.Drop(); + item?.Drop(null); } } else // If current screen is not subeditor, delete anyway to avoid lingering objects @@ -703,8 +701,7 @@ namespace Barotrauma { foreach (Item item in itemInventory.Items) { - if (item == null) continue; - item.Drop(); + item?.Drop(null); } } else // If current screen is not subeditor, delete anyway to avoid lingering objects @@ -1457,7 +1454,7 @@ namespace Barotrauma Item existingWire = dummyCharacter.SelectedItems.FirstOrDefault(i => i != null && i.Prefab == userData as ItemPrefab); if (existingWire != null) { - existingWire.Drop(); + existingWire.Drop(null); existingWire.Remove(); return false; } @@ -1470,7 +1467,7 @@ namespace Barotrauma existingWire = dummyCharacter.Inventory.Items[slotIndex]; if (existingWire != null && existingWire.Prefab != userData as ItemPrefab) { - existingWire.Drop(); + existingWire.Drop(null); existingWire.Remove(); } diff --git a/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs b/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs index e299e79cd..4256482ea 100644 --- a/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Sounds/SoundManager.cs @@ -109,6 +109,12 @@ namespace Barotrauma.Sounds { get { return loadedSounds.Select(s => s.Filename).Distinct().Count(); } } + public int UniqueLoadedSoundCount + { + get { return loadedSounds.Select(s => s.Filename).Distinct().Count(); } + } + + private Dictionary> categoryModifiers; private Dictionary> categoryModifiers; @@ -418,6 +424,10 @@ namespace Barotrauma.Sounds { categoryModifiers[category].Second = muffle; } + else + { + categoryModifiers[category].Second = muffle; + } } for (int i = 0; i < playingChannels.Length; i++) diff --git a/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs b/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs new file mode 100644 index 000000000..e908621bc --- /dev/null +++ b/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs @@ -0,0 +1,246 @@ +#if DEBUG +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Text.RegularExpressions; + +namespace Barotrauma +{ + class LocalizationCSVtoXML + { + private static Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"])*\"|[^,]*)", RegexOptions.Compiled); // Handling commas inside data fields surrounded by "" + private static List conversationClosingIndent = new List(); + private static char[] separator = new char[1] { ',' }; + + private const string conversationsPath = "Content/NPCConversations"; + private const string infoTextPath = "Content/Texts"; + private const string xmlHeader = ""; + + public static void Convert(string language) + { + List conversationFiles = new List(); + List infoTextFiles = new List(); + + language = language.CapitaliseFirstInvariant(); + + foreach (string filePath in Directory.GetFiles(conversationsPath, "*.csv", SearchOption.AllDirectories)) + { + conversationFiles.Add(filePath); + } + + foreach (string filePath in Directory.GetFiles(infoTextPath, "*.csv", SearchOption.AllDirectories)) + { + infoTextFiles.Add(filePath); + } + + for (int i = 0; i < conversationFiles.Count; i++) + { + List xmlContent = ConvertConversationsToXML(File.ReadAllLines(conversationFiles[i], Encoding.UTF8), language); + string xmlFileFullPath = $"{conversationsPath}/NPCConversations_{language}_NEW.xml"; + File.WriteAllLines(xmlFileFullPath, xmlContent); + DebugConsole.NewMessage("Conversation localization .xml file successfully created at: " + xmlFileFullPath); + } + + for (int i = 0; i < infoTextFiles.Count; i++) + { + List xmlContent = ConvertInfoTextToXML(File.ReadAllLines(infoTextFiles[i], Encoding.UTF8), language); + string xmlFileFullPath = $"{infoTextPath}/{language}Vanilla_NEW.xml"; + File.WriteAllLines(xmlFileFullPath, xmlContent); + DebugConsole.NewMessage("InfoText localization .xml file successfully created at: " + xmlFileFullPath); + } + + if (conversationFiles.Count == 0 && infoTextFiles.Count == 0) + { + DebugConsole.ThrowError("No .csv files found to convert."); + } + } + + private static List ConvertInfoTextToXML(string[] csvContent, string language) + { + List xmlContent = new List(); + xmlContent.Add(xmlHeader); + + xmlContent.Add($""); + xmlContent.Add(string.Empty); + + for (int i = 0; i < csvContent.Length; i++) + { + csvContent[i] = csvContent[i].Trim(separator); + + if (csvContent[i].Length == 0) + { + xmlContent.Add(string.Empty); + } + else + { + string[] split = csvContent[i].Split(separator, 2); + + if (split.Length == 2) + { + split[1] = split[1].Replace("\"", ""); // Replaces quotation marks around data that are added when exporting via excel + xmlContent.Add($"<{split[0]}>{split[1]}"); + } + else if (split[0].Contains(".")) // An empty field + { + xmlContent.Add($"<{split[0]}>"); + } + else // A header + { + xmlContent.Add($""); + } + } + } + + xmlContent.Add(string.Empty); + xmlContent.Add(""); + + return xmlContent; + } + + private static List ConvertConversationsToXML(string[] csvContent, string language) + { + List xmlContent = new List(); + xmlContent.Add(xmlHeader); + + xmlContent.Add($""); + xmlContent.Add(string.Empty); + + for (int i = 0; i < csvContent.Length; i++) + { + string[] split = SplitCSV(csvContent[i]); + + int emptyFields = 0; + + for (int j = 0; j < split.Length; j++) + { + if (split[j] == string.Empty) emptyFields++; + } + + if (emptyFields == split.Length) // Empty line with only commas, indicates the end of the previous conversation + { + HandleClosingElements(xmlContent, 0); + xmlContent.Add(string.Empty); + continue; + } + else if (emptyFields == split.Length - 1 && split[0] != string.Empty) // A header + { + xmlContent.Add($""); + continue; + } + + string speaker = split[1]; + int depthIndex = int.Parse(split[2]); + // 3 = original line + string line = split[4].Replace("\"", ""); + string flags = split[5].Replace("\"", ""); + string allowedJobs = split[6].Replace("\"", ""); + string speakerTags = split[7].Replace("\"", ""); + string minIntensity = split[8].Replace("\"", ""); + string maxIntensity = split[9].Replace("\"", ""); + + string element = + $"{GetIndenting(depthIndex)}" + + $" depthIndex; + } + + if (!nextIsSubConvo) + { + xmlContent.Add(element.TrimEnd() + "/>"); + if (nextDepth < depthIndex) + { + HandleClosingElements(xmlContent, nextDepth); + } + } + else + { + xmlContent.Add(element.TrimEnd() + ">"); + conversationClosingIndent.Add(depthIndex); + } + } + else + { + xmlContent.Add(element.TrimEnd() + "/>"); + } + } + + xmlContent.Add(string.Empty); + xmlContent.Add(""); + + return xmlContent; + } + + private static void HandleClosingElements(List xmlContent, int targetDepth) + { + if (conversationClosingIndent.Count == 0) return; + + for (int k = conversationClosingIndent.Count - 1; k >= 0; k--) + { + int currentIndent = conversationClosingIndent[k]; + if (currentIndent < targetDepth) break; + xmlContent.Add($"{GetIndenting(currentIndent)}"); + conversationClosingIndent.RemoveAt(k); + } + } + + private static string[] SplitCSV(string input) // Splits the .csv with regex, leaving commas inside quotation marks intact + { + List list = new List(); + string curr = null; + foreach (Match match in csvSplit.Matches(input)) + { + curr = match.Value; + if (0 == curr.Length) + { + list.Add(""); + } + + list.Add(curr.TrimStart(',')); + } + + return list.ToArray(); + } + + private static string GetIndenting(int depthIndex) + { + string indenting = string.Empty; + + for (int i = 0; i < depthIndex; i++) + { + indenting += "\t"; + } + + return indenting; + } + + private static string GetVariable(string name, string value) + { + if (value == string.Empty) + { + return string.Empty; + } + else + { + return $"{name}=\"{value}\" "; + } + } + } +} +#endif diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index 0ace19fec..2c4bc8e82 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -169,6 +169,12 @@ PreserveNewest + + + + + + PreserveNewest @@ -250,6 +256,7 @@ PreserveNewest + diff --git a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs index 3c37eb862..95f9d1e53 100644 --- a/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs +++ b/Barotrauma/BarotraumaServer/Source/Characters/CharacterNetworking.cs @@ -166,11 +166,8 @@ namespace Barotrauma //character changed the direction they're facing c.KickAFKTimer = 0.0f; } - - if (newInput.HasFlag(InputNetFlags.Aim)) - { - newAim = msg.ReadUInt16(); - } + + newAim = msg.ReadUInt16(); if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Use) || newInput.HasFlag(InputNetFlags.Health) || @@ -181,12 +178,15 @@ namespace Barotrauma if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60)) { + if ((i > 0 && memInput[i - 1].intAim != newAim)) + { + c.KickAFKTimer = 0.0f; + } NetInputMem newMem = new NetInputMem { states = newInput, intAim = newAim, interact = newInteract, - networkUpdateID = (ushort)(networkUpdateID - i) }; memInput.Insert(i, newMem); diff --git a/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs b/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs index 3dd111358..6d13e1aaf 100644 --- a/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs +++ b/Barotrauma/BarotraumaServer/Source/Items/Inventory.cs @@ -62,7 +62,7 @@ namespace Barotrauma if (newItemIDs[i] == 0 || (newItem != Items[i])) { - if (Items[i] != null) Items[i].Drop(); + if (Items[i] != null) Items[i].Drop(null); System.Diagnostics.Debug.Assert(Items[i] == null); } } diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs index 9eb5a5e2f..666aad960 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs @@ -355,8 +355,10 @@ namespace Barotrauma.Networking entityEventManager.Update(connectedClients); - foreach (Character character in Character.CharacterList) + //go through the characters backwards to give rejoining clients control of the latest created character + for (int i = Character.CharacterList.Count - 1; i >= 0; i--) { + Character character = Character.CharacterList[i]; if (character.IsDead || !character.ClientDisconnected) continue; character.KillDisconnectedTimer += deltaTime; @@ -1957,8 +1959,8 @@ namespace Barotrauma.Networking if (client == null) return; if (client.Connection == OwnerConnection) return; - string msg = DisconnectReason.Banned.ToString(); - DisconnectClient(client, $"ServerMessage.BannedFromServer~[client]={client.Name}", msg, reason); + string targetMsg = DisconnectReason.Banned.ToString(); + DisconnectClient(client, $"ServerMessage.BannedFromServer~[client]={client.Name}", targetMsg, reason); if (client.SteamID == 0 || range) { @@ -2764,6 +2766,747 @@ namespace Barotrauma.Networking } } + public override void Disconnect() + { + serverSettings.BanList.Save(); + serverSettings.SaveSettings(); + SteamManager.CloseServer(); + + if (registeredToMaster) + { + if (restClient != null) + { + var request = new RestRequest("masterserver2.php", Method.GET); + request.AddParameter("action", "removeserver"); + request.AddParameter("serverport", Port); + restClient.Execute(request); + restClient = null; + } + } + + if (serverSettings.SaveServerLogs) + { + Log("Shutting down the server...", ServerLog.MessageType.ServerMessage); + serverSettings.ServerLog.Save(); + } + + GameAnalyticsManager.AddDesignEvent("GameServer:ShutDown"); + server.Shutdown(DisconnectReason.ServerShutdown.ToString()); + } + + public void SendConsoleMessage(string txt, Client recipient) + { + ChatMessage msg = ChatMessage.Create("", txt, ChatMessageType.Console, null); + SendDirectChatMessage(msg, recipient); + } + + public void SendDirectChatMessage(ChatMessage msg, Client recipient) + { + if (recipient == null) + { + string errorMsg = "Attempted to send a chat message to a null client.\n" + Environment.StackTrace; + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("GameServer.SendDirectChatMessage:ClientNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + return; + } + + msg.NetStateID = recipient.ChatMsgQueue.Count > 0 ? + (ushort)(recipient.ChatMsgQueue.Last().NetStateID + 1) : + (ushort)(recipient.LastRecvChatMsgID + 1); + + recipient.ChatMsgQueue.Add(msg); + recipient.LastChatMsgQueueID = msg.NetStateID; + } + + /// + /// Add the message to the chatbox and pass it to all clients who can receive it + /// + public void SendChatMessage(string message, ChatMessageType? type = null, Client senderClient = null, Character senderCharacter = null) + { + string senderName = ""; + + Client targetClient = null; + + if (type == null) + { + string command = ChatMessage.GetChatMessageCommand(message, out string tempStr); + switch (command.ToLowerInvariant()) + { + case "r": + case "radio": + type = ChatMessageType.Radio; + break; + case "d": + case "dead": + type = ChatMessageType.Dead; + break; + default: + if (command != "") + { + if (command == name.ToLowerInvariant()) + { + //a private message to the host + } + else + { + targetClient = connectedClients.Find(c => + command == c.Name.ToLowerInvariant() || + (c.Character != null && command == c.Character.Name.ToLowerInvariant())); + + if (targetClient == null) + { + if (senderClient != null) + { + var chatMsg = ChatMessage.Create( + "", $"ServerMessage.PlayerNotFound~[player]={command}", + ChatMessageType.Error, null); + + chatMsg.NetStateID = senderClient.ChatMsgQueue.Count > 0 ? + (ushort)(senderClient.ChatMsgQueue.Last().NetStateID + 1) : + (ushort)(senderClient.LastRecvChatMsgID + 1); + + senderClient.ChatMsgQueue.Add(chatMsg); + senderClient.LastChatMsgQueueID = chatMsg.NetStateID; + } + else + { + AddChatMessage($"ServerMessage.PlayerNotFound~[player]={command}", ChatMessageType.Error); + } + + return; + } + } + + type = ChatMessageType.Private; + } + else + { + type = ChatMessageType.Default; + } + break; + } + + message = tempStr; + } + + if (gameStarted) + { + if (senderClient == null) + { + //msg sent by the server + if (senderCharacter == null) + { + senderName = name; + } + else //msg sent by an AI character + { + senderName = senderCharacter.Name; + } + } + else //msg sent by a client + { + senderCharacter = senderClient.Character; + senderName = senderCharacter == null ? senderClient.Name : senderCharacter.Name; + + //sender doesn't have a character or the character can't speak -> only ChatMessageType.Dead allowed + if (senderCharacter == null || senderCharacter.IsDead || senderCharacter.SpeechImpediment >= 100.0f) + { + type = ChatMessageType.Dead; + } + else if (type == ChatMessageType.Private) + { + //sender has an alive character, sending private messages not allowed + return; + } + + } + } + else + { + if (senderClient == null) + { + //msg sent by the server + if (senderCharacter == null) + { + senderName = name; + } + else //sent by an AI character, not allowed when the game is not running + { + return; + } + } + else //msg sent by a client + { + //game not started -> clients can only send normal and private chatmessages + if (type != ChatMessageType.Private) type = ChatMessageType.Default; + senderName = senderClient.Name; + } + } + + //check if the client is allowed to send the message + WifiComponent senderRadio = null; + switch (type) + { + case ChatMessageType.Radio: + case ChatMessageType.Order: + if (senderCharacter == null) return; + + //return if senderCharacter doesn't have a working radio + var radio = senderCharacter.Inventory?.Items.FirstOrDefault(i => i != null && i.GetComponent() != null); + if (radio == null || !senderCharacter.HasEquippedItem(radio)) return; + + senderRadio = radio.GetComponent(); + if (!senderRadio.CanTransmit()) return; + break; + case ChatMessageType.Dead: + //character still alive and capable of speaking -> dead chat not allowed + if (senderClient != null && senderCharacter != null && !senderCharacter.IsDead && senderCharacter.SpeechImpediment < 100.0f) + { + return; + } + break; + } + + if (type == ChatMessageType.Server) + { + senderName = null; + senderCharacter = null; + } + else if (type == ChatMessageType.Radio) + { + //send to chat-linked wifi components + senderRadio.TransmitSignal(0, message, senderRadio.Item, senderCharacter, false); + } + + //check which clients can receive the message and apply distance effects + foreach (Client client in ConnectedClients) + { + string modifiedMessage = message; + + switch (type) + { + case ChatMessageType.Default: + case ChatMessageType.Radio: + case ChatMessageType.Order: + if (senderCharacter != null && + client.Character != null && !client.Character.IsDead) + { + modifiedMessage = ChatMessage.ApplyDistanceEffect(message, (ChatMessageType)type, senderCharacter, client.Character); + + //too far to hear the msg -> don't send + if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; + } + break; + case ChatMessageType.Dead: + //character still alive -> don't send + if (client != senderClient && client.Character != null && !client.Character.IsDead) continue; + break; + case ChatMessageType.Private: + //private msg sent to someone else than this client -> don't send + if (client != targetClient && client != senderClient) continue; + break; + } + + var chatMsg = ChatMessage.Create( + senderName, + modifiedMessage, + (ChatMessageType)type, + senderCharacter); + + SendDirectChatMessage(chatMsg, client); + } + + if (type.Value != ChatMessageType.MessageBox) + { + string myReceivedMessage = type == ChatMessageType.Server || type == ChatMessageType.Error ? TextManager.GetServerMessage(message) : message; + if (!string.IsNullOrWhiteSpace(myReceivedMessage) && + (targetClient == null || senderClient == null)) + { + AddChatMessage(myReceivedMessage, (ChatMessageType)type, senderName, senderCharacter); + } + } + } + + public void SendOrderChatMessage(OrderChatMessage message) + { + if (message.Sender == null || message.Sender.SpeechImpediment >= 100.0f) return; + ChatMessageType messageType = ChatMessage.CanUseRadio(message.Sender) ? ChatMessageType.Radio : ChatMessageType.Default; + + //check which clients can receive the message and apply distance effects + foreach (Client client in ConnectedClients) + { + string modifiedMessage = message.Text; + + if (message.Sender != null && + client.Character != null && !client.Character.IsDead) + { + modifiedMessage = ChatMessage.ApplyDistanceEffect(message.Text, messageType, message.Sender, client.Character); + + //too far to hear the msg -> don't send + if (string.IsNullOrWhiteSpace(modifiedMessage)) continue; + } + + SendDirectChatMessage(message, client); + } + + string myReceivedMessage = message.Text; + + if (!string.IsNullOrWhiteSpace(myReceivedMessage)) + { + AddChatMessage(new OrderChatMessage(message.Order, message.OrderOption, myReceivedMessage, message.TargetEntity, message.TargetCharacter, message.Sender)); + } + } + + private void FileTransferChanged(FileSender.FileTransferOut transfer) + { + Client recipient = connectedClients.Find(c => c.Connection == transfer.Connection); + if (transfer.FileType == FileTransferType.CampaignSave && + (transfer.Status == FileTransferStatus.Sending || transfer.Status == FileTransferStatus.Finished) && + recipient.LastCampaignSaveSendTime != null) + { + recipient.LastCampaignSaveSendTime.Second = (float)NetTime.Now; + } + } + + public void SendCancelTransferMsg(FileSender.FileTransferOut transfer) + { + NetOutgoingMessage msg = server.CreateMessage(); + msg.Write((byte)ServerPacketHeader.FILE_TRANSFER); + msg.Write((byte)FileTransferMessageType.Cancel); + msg.Write((byte)transfer.SequenceChannel); + CompressOutgoingMessage(msg); + server.SendMessage(msg, transfer.Connection, NetDeliveryMethod.ReliableOrdered, transfer.SequenceChannel); + } + + public void UpdateVoteStatus() + { + if (server.Connections.Count == 0 || connectedClients.Count == 0) return; + + Client.UpdateKickVotes(connectedClients); + + var clientsToKick = connectedClients.FindAll(c => + c.Connection != OwnerConnection && + c.KickVoteCount >= connectedClients.Count * serverSettings.KickVoteRequiredRatio); + foreach (Client c in clientsToKick) + { + SendChatMessage($"ServerMessage.KickedFromServer~[client]={c.Name}", ChatMessageType.Server, null); + KickClient(c, "ServerMessage.KickedByVote"); + BanClient(c, "ServerMessage.KickedByVoteAutoBan", duration: TimeSpan.FromSeconds(serverSettings.AutoBanTime)); + } + + GameMain.NetLobbyScreen.LastUpdateID++; + + SendVoteStatus(connectedClients); + + if (serverSettings.Voting.AllowEndVoting && EndVoteMax > 0 && + ((float)EndVoteCount / (float)EndVoteMax) >= serverSettings.EndVoteRequiredRatio) + { + Log("Ending round by votes (" + EndVoteCount + "/" + (EndVoteMax - EndVoteCount) + ")", ServerLog.MessageType.ServerMessage); + EndGame(); + } + } + + public void SendVoteStatus(List recipients) + { + NetOutgoingMessage msg = server.CreateMessage(); + msg.Write((byte)ServerPacketHeader.UPDATE_LOBBY); + msg.Write((byte)ServerNetObject.VOTE); + serverSettings.Voting.ServerWrite(msg); + msg.Write((byte)ServerNetObject.END_OF_MESSAGE); + + CompressOutgoingMessage(msg); + + server.SendMessage(msg, recipients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0); + } + + public void UpdateClientPermissions(Client client) + { + if (client.SteamID > 0) + { + serverSettings.ClientPermissions.RemoveAll(cp => cp.SteamID == client.SteamID); + if (client.Permissions != ClientPermissions.None) + { + serverSettings.ClientPermissions.Add(new ServerSettings.SavedClientPermission( + client.Name, + client.SteamID, + client.Permissions, + client.PermittedConsoleCommands)); + } + } + else + { + serverSettings.ClientPermissions.RemoveAll(cp => client.IPMatches(cp.IP)); + if (client.Permissions != ClientPermissions.None) + { + serverSettings.ClientPermissions.Add(new ServerSettings.SavedClientPermission( + client.Name, + client.Connection.RemoteEndPoint.Address, + client.Permissions, + client.PermittedConsoleCommands)); + } + } + + var msg = server.CreateMessage(); + msg.Write((byte)ServerPacketHeader.PERMISSIONS); + client.WritePermissions(msg); + CompressOutgoingMessage(msg); + + //send the message to the client whose permissions are being modified and the clients who are allowed to modify permissions + List recipients = new List() { client.Connection }; + foreach (Client otherClient in connectedClients) + { + if (otherClient.HasPermission(ClientPermissions.ManagePermissions) && !recipients.Contains(otherClient.Connection)) + { + recipients.Add(otherClient.Connection); + } + } + server.SendMessage(msg, recipients, NetDeliveryMethod.ReliableUnordered, 0); + + serverSettings.SaveClientPermissions(); + } + + public void GiveAchievement(Character character, string achievementIdentifier) + { + achievementIdentifier = achievementIdentifier.ToLowerInvariant(); + foreach (Client client in connectedClients) + { + if (client.Character == character) + { + GiveAchievement(client, achievementIdentifier); + return; + } + } + } + + public void GiveAchievement(Client client, string achievementIdentifier) + { + if (client.GivenAchievements.Contains(achievementIdentifier)) return; + client.GivenAchievements.Add(achievementIdentifier); + + var msg = server.CreateMessage(); + msg.Write((byte)ServerPacketHeader.ACHIEVEMENT); + msg.Write(achievementIdentifier); + + CompressOutgoingMessage(msg); + + server.SendMessage(msg, client.Connection, NetDeliveryMethod.ReliableUnordered); + } + + public void UpdateCheatsEnabled() + { + var msg = server.CreateMessage(); + msg.Write((byte)ServerPacketHeader.CHEATS_ENABLED); + msg.Write(DebugConsole.CheatsEnabled); + msg.WritePadBits(); + + CompressOutgoingMessage(msg); + + server.SendMessage(msg, connectedClients.Select(c => c.Connection).ToList(), NetDeliveryMethod.ReliableUnordered, 0); + } + + public void SetClientCharacter(Client client, Character newCharacter) + { + if (client == null) return; + + //the client's previous character is no longer a remote player + if (client.Character != null) + { + client.Character.IsRemotePlayer = false; + client.Character.OwnerClientIP = null; + client.Character.OwnerClientName = null; + } + + if (newCharacter == null) + { + if (client.Character != null) //removing control of the current character + { + CreateEntityEvent(client.Character, new object[] { NetEntityEvent.Type.Control, null }); + client.Character = null; + } + } + else //taking control of a new character + { + newCharacter.ClientDisconnected = false; + newCharacter.KillDisconnectedTimer = 0.0f; + newCharacter.ResetNetState(); + if (client.Character != null) + { + newCharacter.LastNetworkUpdateID = client.Character.LastNetworkUpdateID; + } + + newCharacter.OwnerClientIP = client.Connection.RemoteEndPoint.Address.ToString(); + newCharacter.OwnerClientName = client.Name; + newCharacter.IsRemotePlayer = true; + newCharacter.Enabled = true; + client.Character = newCharacter; + CreateEntityEvent(newCharacter, new object[] { NetEntityEvent.Type.Control, client }); + } + } + + private void UpdateCharacterInfo(NetIncomingMessage message, Client sender) + { + sender.SpectateOnly = message.ReadBoolean() && (serverSettings.AllowSpectating || sender.Connection == OwnerConnection); + if (sender.SpectateOnly) + { + return; + } + + Gender gender = Gender.Male; + Race race = Race.White; + int headSpriteId = 0; + try + { + gender = (Gender)message.ReadByte(); + race = (Race)message.ReadByte(); + headSpriteId = message.ReadByte(); + } + catch (Exception e) + { + //gender = Gender.Male; + //race = Race.White; + //headSpriteId = 0; + DebugConsole.Log("Received invalid characterinfo from \"" + sender.Name + "\"! { " + e.Message + " }"); + } + int hairIndex = message.ReadByte(); + int beardIndex = message.ReadByte(); + int moustacheIndex = message.ReadByte(); + int faceAttachmentIndex = message.ReadByte(); + + List jobPreferences = new List(); + int count = message.ReadByte(); + for (int i = 0; i < Math.Min(count, 3); i++) + { + string jobIdentifier = message.ReadString(); + + JobPrefab jobPrefab = JobPrefab.List.Find(jp => jp.Identifier == jobIdentifier); + if (jobPrefab != null) jobPreferences.Add(jobPrefab); + } + + sender.CharacterInfo = new CharacterInfo(Character.HumanConfigFile, sender.Name); + sender.CharacterInfo.RecreateHead(headSpriteId, race, gender, hairIndex, beardIndex, moustacheIndex, faceAttachmentIndex); + + //if the client didn't provide job preferences, we'll use the preferences that are randomly assigned in the Client constructor + Debug.Assert(sender.JobPreferences.Count > 0); + if (jobPreferences.Count > 0) + { + sender.JobPreferences = jobPreferences; + } + } + + public void AssignJobs(List unassigned) + { + unassigned = new List(unassigned); + + Dictionary assignedClientCount = new Dictionary(); + foreach (JobPrefab jp in JobPrefab.List) + { + assignedClientCount.Add(jp, 0); + } + + Character.TeamType teamID = Character.TeamType.None; + if (unassigned.Count > 0) { teamID = unassigned[0].TeamID; } + + //if we're playing a multiplayer campaign, check which clients already have a character and a job + //(characters are persistent in campaigns) + if (GameMain.GameSession.GameMode is MultiPlayerCampaign multiplayerCampaign) + { + var campaignAssigned = multiplayerCampaign.GetAssignedJobs(connectedClients); + //remove already assigned clients from unassigned + unassigned.RemoveAll(u => campaignAssigned.ContainsKey(u)); + //add up to assigned client count + foreach (KeyValuePair clientJob in campaignAssigned) + { + assignedClientCount[clientJob.Value.Prefab]++; + clientJob.Key.AssignedJob = clientJob.Value.Prefab; + } + } + + //count the clients who already have characters with an assigned job + foreach (Client c in connectedClients) + { + if (c.TeamID != teamID || unassigned.Contains(c)) continue; + if (c.Character?.Info?.Job != null && !c.Character.IsDead) + { + assignedClientCount[c.Character.Info.Job.Prefab]++; + } + } + + //if any of the players has chosen a job that is Always Allowed, give them that job + for (int i = unassigned.Count - 1; i >= 0; i--) + { + if (unassigned[i].JobPreferences.Count == 0) continue; + if (!unassigned[i].JobPreferences[0].AllowAlways) continue; + unassigned[i].AssignedJob = unassigned[i].JobPreferences[0]; + unassigned.RemoveAt(i); + } + + //go throught the jobs whose MinNumber>0 (i.e. at least one crew member has to have the job) + bool unassignedJobsFound = true; + while (unassignedJobsFound && unassigned.Count > 0) + { + unassignedJobsFound = false; + + foreach (JobPrefab jobPrefab in JobPrefab.List) + { + if (unassigned.Count == 0) break; + if (jobPrefab.MinNumber < 1 || assignedClientCount[jobPrefab] >= jobPrefab.MinNumber) continue; + + //find the client that wants the job the most, or force it to random client if none of them want it + Client assignedClient = FindClientWithJobPreference(unassigned, jobPrefab, true); + + assignedClient.AssignedJob = jobPrefab; + assignedClientCount[jobPrefab]++; + unassigned.Remove(assignedClient); + + //the job still needs more crew members, set unassignedJobsFound to true to keep the while loop running + if (assignedClientCount[jobPrefab] < jobPrefab.MinNumber) unassignedJobsFound = true; + } + } + + //attempt to give the clients a job they have in their job preferences + for (int i = unassigned.Count - 1; i >= 0; i--) + { + foreach (JobPrefab preferredJob in unassigned[i].JobPreferences) + { + //the maximum number of players that can have this job hasn't been reached yet + // -> assign it to the client + if (assignedClientCount[preferredJob] < preferredJob.MaxNumber && unassigned[i].Karma >= preferredJob.MinKarma) + { + unassigned[i].AssignedJob = preferredJob; + assignedClientCount[preferredJob]++; + unassigned.RemoveAt(i); + break; + } + } + } + + //give random jobs to rest of the clients + foreach (Client c in unassigned) + { + //find all jobs that are still available + var remainingJobs = JobPrefab.List.FindAll(jp => assignedClientCount[jp] < jp.MaxNumber && c.Karma >= jp.MinKarma); + + //all jobs taken, give a random job + if (remainingJobs.Count == 0) + { + DebugConsole.ThrowError("Failed to assign a suitable job for \"" + c.Name + "\" (all jobs already have the maximum numbers of players). Assigning a random job..."); + int jobIndex = Rand.Range(0, JobPrefab.List.Count); + int skips = 0; + while (c.Karma < JobPrefab.List[jobIndex].MinKarma) + { + jobIndex++; + skips++; + if (jobIndex >= JobPrefab.List.Count) jobIndex -= JobPrefab.List.Count; + if (skips >= JobPrefab.List.Count) break; + } + c.AssignedJob = JobPrefab.List[jobIndex]; + assignedClientCount[c.AssignedJob]++; + } + else //some jobs still left, choose one of them by random + { + c.AssignedJob = remainingJobs[Rand.Range(0, remainingJobs.Count)]; + assignedClientCount[c.AssignedJob]++; + } + } + } + + public void AssignBotJobs(List bots, Character.TeamType teamID) + { + Dictionary assignedPlayerCount = new Dictionary(); + foreach (JobPrefab jp in JobPrefab.List) + { + assignedPlayerCount.Add(jp, 0); + } + + //count the clients who already have characters with an assigned job + foreach (Client c in connectedClients) + { + if (c.TeamID != teamID) continue; + if (c.Character?.Info?.Job != null && !c.Character.IsDead) + { + assignedPlayerCount[c.Character.Info.Job.Prefab]++; + } + else if (c.CharacterInfo?.Job != null) + { + assignedPlayerCount[c.CharacterInfo?.Job.Prefab]++; + } + } + + List unassignedBots = new List(bots); + foreach (CharacterInfo bot in bots) + { + foreach (JobPrefab jobPrefab in JobPrefab.List) + { + if (jobPrefab.MinNumber < 1 || assignedPlayerCount[jobPrefab] >= jobPrefab.MinNumber) continue; + bot.Job = new Job(jobPrefab); + assignedPlayerCount[jobPrefab]++; + unassignedBots.Remove(bot); + break; + } + } + + //find a suitable job for the rest of the players + foreach (CharacterInfo c in unassignedBots) + { + //find all jobs that are still available + var remainingJobs = JobPrefab.List.FindAll(jp => assignedPlayerCount[jp] < jp.MaxNumber); + //all jobs taken, give a random job + if (remainingJobs.Count == 0) + { + DebugConsole.ThrowError("Failed to assign a suitable job for bot \"" + c.Name + "\" (all jobs already have the maximum numbers of players). Assigning a random job..."); + c.Job = new Job(JobPrefab.List[Rand.Range(0, JobPrefab.List.Count)]); + assignedPlayerCount[c.Job.Prefab]++; + } + else //some jobs still left, choose one of them by random + { + c.Job = new Job(remainingJobs[Rand.Range(0, remainingJobs.Count)]); + assignedPlayerCount[c.Job.Prefab]++; + } + } + } + + private Client FindClientWithJobPreference(List clients, JobPrefab job, bool forceAssign = false) + { + int bestPreference = 0; + Client preferredClient = null; + foreach (Client c in clients) + { + if (c.Karma < job.MinKarma) continue; + int index = c.JobPreferences.IndexOf(job); + if (index == -1) index = 1000; + + if (preferredClient == null || index < bestPreference) + { + bestPreference = index; + preferredClient = c; + } + } + + //none of the clients wants the job, assign it to random client + if (forceAssign && preferredClient == null) + { + preferredClient = clients[Rand.Int(clients.Count)]; + } + + return preferredClient; + } + + public static void Log(string line, ServerLog.MessageType messageType) + { + if (GameMain.Server == null || !GameMain.Server.ServerSettings.SaveServerLogs) return; + + GameMain.Server.ServerSettings.ServerLog.WriteLine(line, messageType); + + foreach (Client client in GameMain.Server.ConnectedClients) + { + if (!client.HasPermission(ClientPermissions.ServerLog)) continue; + //use sendername as the message type + GameMain.Server.SendDirectChatMessage( + ChatMessage.Create(messageType.ToString(), line, ChatMessageType.ServerLog, null), + client); + } + } + public override void Disconnect() { serverSettings.BanList.Save(); diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs index e657f8a7f..fe0b66db2 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServerLogin.cs @@ -140,7 +140,7 @@ namespace Barotrauma.Networking if (GameMain.Config.RequireSteamAuthentication) { Log("Disconnected unauthenticated client (Steam ID: " + steamID + "). Steam authentication failed, (" + status + ").", ServerLog.MessageType.ServerMessage); - unauthClient.Connection.Disconnect(DisconnectReason.SteamAuthenticationFailed.ToString() + "; (" + status.ToString() + ")"); + unauthClient.Connection.Disconnect(DisconnectReason.SteamAuthenticationFailed.ToString() + "/ (" + status.ToString() + ")"); } else { @@ -500,7 +500,7 @@ namespace Barotrauma.Networking private void DisconnectUnauthClient(NetIncomingMessage inc, UnauthenticatedClient unauthClient, DisconnectReason reason, string message) { - inc.SenderConnection.Disconnect(reason.ToString() + "; " + message); + inc.SenderConnection.Disconnect(reason.ToString() + "/ " + message); if (unauthClient.SteamID > 0) { Steam.SteamManager.StopAuthSession(unauthClient.SteamID); } if (unauthClient != null) { diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems index d5ac9408f..bec8045ae 100644 --- a/Barotrauma/BarotraumaShared/SharedContent.projitems +++ b/Barotrauma/BarotraumaShared/SharedContent.projitems @@ -1029,25 +1029,34 @@ PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + PreserveNewest - + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + PreserveNewest @@ -1298,15 +1307,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -3108,5 +3108,8 @@ PreserveNewest + + PreserveNewest + \ No newline at end of file diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs index 73c7d98f4..898af1d9a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs @@ -22,7 +22,6 @@ namespace Barotrauma public const float HULL_SAFETY_THRESHOLD = 50; - // TODO: update the list when someone gives a report public HashSet UnsafeHulls { get; private set; } = new HashSet(); private SteeringManager outsideSteering, insideSteering; @@ -136,10 +135,11 @@ namespace Barotrauma Character.AnimController.IgnorePlatforms = ignorePlatforms; - if (Character.IsClimbing) - { - Character.AnimController.TargetMovement = new Vector2(0.0f, Math.Sign(Character.AnimController.TargetMovement.Y)); - } + // Suspect that this causes issues when trying to exit from the ladders -> could try to check if the next node is ladder? + //if (Character.IsClimbing) + //{ + // Character.AnimController.TargetMovement = new Vector2(0.0f, Math.Sign(Character.AnimController.TargetMovement.Y)); + //} Vector2 targetMovement = AnimController.TargetMovement; @@ -187,7 +187,7 @@ namespace Barotrauma // Try to put the mask in an Any slot, and drop it if that fails if (!mask.AllowedSlots.Contains(InvSlotType.Any) || !Character.Inventory.TryPutItem(mask, Character, new List() { InvSlotType.Any })) { - mask.Drop(); + mask.Drop(Character); } } } @@ -198,7 +198,7 @@ namespace Barotrauma if (extinguisherItem != null && Character.HasEquippedItem(extinguisherItem)) { // TODO: take the item where it was taken from? - extinguisherItem.Drop(); + extinguisherItem.Drop(Character); } } @@ -227,6 +227,10 @@ namespace Barotrauma PropagateHullSafety(Character, Character.CurrentHull); } } + + private void ReportProblems() + { + if (GameMain.Client != null) return; protected void ReportProblems() { @@ -271,10 +275,6 @@ namespace Barotrauma } } } - - private void ReportProblems() - { - if (GameMain.Client != null) return; private void UpdateSpeaking() { @@ -293,41 +293,68 @@ namespace Barotrauma Character.Speak(TextManager.Get("DialogPressure").Replace("[roomname]", Character.CurrentHull.RoomName), null, 0, "pressure", 30.0f); } } - + public override void OnAttacked(Character attacker, AttackResult attackResult) { - float totalDamage = attackResult.Damage; - if (totalDamage <= 0.0f || attacker == null) return; - - if (attacker.SpeciesName == Character.SpeciesName) + float damage = attackResult.Damage; + if (damage < 0) { return; } + if (attacker == null || attacker.IsDead || attacker.Removed) + { + objectiveManager.GetObjective().Priority = 100; + return; + } + if (IsFriendly(attacker)) { - if (!attacker.IsRemotePlayer && Character.Controlled != attacker && attacker.AIController != null && attacker.AIController.Enabled) - { - // Don't react to damage done by friendly ai, because we know that it's accidental - return; - } if (attacker.AnimController.Anim == Barotrauma.AnimController.Animation.CPR && attacker.SelectedCharacter == Character) { // Don't attack characters that damage you while doing cpr, because let's assume that they are helping you. // Should not cancel any existing ai objectives (so that if the character attacked you and then helped, we still would want to retaliate). return; } + if (!attacker.IsRemotePlayer && Character.Controlled != attacker && attacker.AIController != null && attacker.AIController.Enabled) + { + // Don't react to damage done by friendly ai, because we know that it's accidental + objectiveManager.GetObjective().Priority = 100; + return; + } float currentVitality = Character.CharacterHealth.Vitality; - float dmgPercentage = totalDamage / currentVitality * 100; + float dmgPercentage = damage / currentVitality * 100; if (dmgPercentage < currentVitality / 10) { // Don't react to a minor amount of (accidental) dmg done by friendly characters + objectiveManager.GetObjective().Priority = 100; return; } + if (ObjectiveManager.CurrentObjective is AIObjectiveCombat combatObjective) + { + if (combatObjective.Enemy != attacker) + { + // Replace the old objective with the new. + ObjectiveManager.Objectives.Remove(combatObjective); + objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker)); + } + } + else + { + objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker), Rand.Range(0.5f, 1f, Rand.RandSync.Unsynced)); + } } - - objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker), Rand.Range(0.5f, 1, Rand.RandSync.Unsynced), () => + else { - //the objective in the manager is not necessarily the same as the one we just instantiated, - //because the objective isn't added if there's already an identical objective in the manager - var combatObjective = objectiveManager.GetObjective(); - combatObjective.MaxEnemyDamage = Math.Max(totalDamage, combatObjective.MaxEnemyDamage); - }); + if (ObjectiveManager.CurrentObjective is AIObjectiveCombat combatObjective) + { + if (combatObjective.Enemy != attacker) + { + // Replace the old objective with the new. + ObjectiveManager.Objectives.Remove(combatObjective); + objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker)); + } + } + else + { + objectiveManager.AddObjective(new AIObjectiveCombat(Character, attacker)); + } + } } public void SetOrder(Order order, string option, Character orderGiver, bool speak = true) @@ -420,7 +447,8 @@ namespace Barotrauma bool ignoreFire = ObjectiveManager.CurrentObjective is AIObjectiveExtinguishFire || ObjectiveManager.CurrentOrder is AIObjectiveExtinguishFires; bool ignoreWater = HasDivingSuit(Character); bool ignoreOxygen = ignoreWater || HasDivingGear(Character); - return GetHullSafety(hull, Character, ignoreWater, ignoreOxygen, ignoreFire, ignoreEnemies: false); + bool ignoreEnemies = ObjectiveManager.CurrentObjective is AIObjectiveCombat || ObjectiveManager.CurrentOrder is AIObjectiveCombat; + return GetHullSafety(hull, Character, ignoreWater, ignoreOxygen, ignoreFire, ignoreEnemies); } public static float GetHullSafety(Hull hull, Character character, bool ignoreWater = false, bool ignoreOxygen = false, bool ignoreFire = false, bool ignoreEnemies = false) @@ -443,5 +471,8 @@ namespace Barotrauma float safety = oxygenFactor * waterFactor * fireFactor * enemyFactor; return MathHelper.Clamp(safety * 100, 0, 100); } + + // TODO: If the aliens are quaranteed to be in another team than the player, we wouldn't need to check the species. + public bool IsFriendly(Character other) => other.TeamID == Character.TeamID && other.SpeciesName == Character.SpeciesName; } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs index eb5aa57bd..a4ae023a2 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs @@ -15,7 +15,7 @@ namespace Barotrauma public virtual bool KeepDivingGearOn => false; protected readonly List subObjectives = new List(); - protected float priority; + public float Priority { get; set; } protected readonly Character character; protected string option; protected bool abandon; @@ -26,6 +26,7 @@ namespace Barotrauma protected HumanAIController HumanAIController => character.AIController as HumanAIController; protected IndoorsSteeringManager PathSteering => HumanAIController.PathSteering; + protected SteeringManager SteeringManager => HumanAIController.SteeringManager; public string Option { @@ -103,20 +104,20 @@ namespace Barotrauma CurrentSubObjective.SortSubObjectives(objectiveManager); } - public virtual float GetPriority(AIObjectiveManager objectiveManager) => priority; + public virtual float GetPriority(AIObjectiveManager objectiveManager) => Priority; public virtual void Update(AIObjectiveManager objectiveManager, float deltaTime) { var subObjective = objectiveManager.CurrentObjective?.CurrentSubObjective; if (objectiveManager.CurrentOrder == this) { - priority = AIObjectiveManager.OrderPriority; + Priority = AIObjectiveManager.OrderPriority; } else if (objectiveManager.CurrentObjective == this || subObjective == this) { - priority += Devotion * deltaTime; + Priority += Devotion * deltaTime; } - priority = MathHelper.Clamp(priority, 0, 100); + Priority = MathHelper.Clamp(Priority, 0, 100); subObjectives.ForEach(so => so.Update(objectiveManager, deltaTime)); } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs index 0463c7ef2..1f8813858 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -1,194 +1,268 @@ using Barotrauma.Items.Components; using Microsoft.Xna.Framework; -using System; using System.Collections.Generic; using System.Linq; +using Barotrauma.Extensions; namespace Barotrauma { class AIObjectiveCombat : AIObjective { public override string DebugTag => "combat"; - public override bool ForceRun => true; public override bool KeepDivingGearOn => true; const float CoolDown = 10.0f; - //the largest amount of damage the enemy has inflicted on this character - //(may be higher than enemyStrength if the enemy is e.g. a human using items) - public float MaxEnemyDamage; - - private Character enemy; - - private AIObjectiveFindSafety escapeObjective; - + public Character Enemy { get; private set; } + + private Item _weapon; + private Item Weapon + { + get { return _weapon; } + set + { + _weapon = value; + _weaponComponent = null; + reloadWeaponObjective = null; + } + } + private ItemComponent _weaponComponent; + private ItemComponent WeaponComponent + { + get + { + if (_weaponComponent == null) + { + _weaponComponent = + Weapon.GetComponent() as ItemComponent ?? + Weapon.GetComponent() as ItemComponent ?? + Weapon.GetComponent() as ItemComponent; + } + return _weaponComponent; + } + } private AIObjectiveContainItem reloadWeaponObjective; + private Hull retreatTarget; + private AIObjectiveGoTo retreatObjective; private float coolDownTimer; public AIObjectiveCombat(Character character, Character enemy) : base(character, "") { - this.enemy = enemy; + Enemy = enemy; coolDownTimer = CoolDown; + HumanAIController.ObjectiveManager.GetObjective().Priority = 0; } protected override void Act(float deltaTime) { coolDownTimer -= deltaTime; - - var weapon = character.Inventory.FindItemByTag("weapon"); - if (weapon == null) + if (Weapon != null && character.Inventory.Items.Contains(_weapon)) + { + Weapon = null; + } + if (Weapon == null) + { + Weapon = GetWeapon(); + } + if (Weapon == null) { Escape(deltaTime); } - else + else if (Equip(deltaTime)) { - if (!character.SelectedItems.Contains(weapon)) + if (Reload(deltaTime)) { - if (character.Inventory.TryPutItem(weapon, 3, true, false, character)) - { - weapon.Equip(character); - } - else - { - //couldn't equip the item, escape - Escape(deltaTime); - return; - } + Attack(deltaTime); } + } + if (!abandon) + { + Move(deltaTime); + } + } - //make sure the weapon is loaded - var weaponComponent = - weapon.GetComponent() as ItemComponent ?? - weapon.GetComponent() as ItemComponent ?? - weapon.GetComponent() as ItemComponent; - if (weaponComponent != null && weaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) + private Item GetWeapon() + { + _weaponComponent = null; + var weapon = character.Inventory.FindItemByTag("weapon"); + if (weapon == null) + { + foreach (var item in character.Inventory.Items) { - var containedItems = weapon.ContainedItems; - foreach (RelatedItem requiredItem in weaponComponent.requiredItems[RelatedItem.RelationType.Contained]) + if (item == null) { continue; } + foreach (var component in item.Components) { - Item containedItem = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); - if (containedItem == null) + if (component is MeleeWeapon || component is RangedWeapon) { - var newReloadWeaponObjective = new AIObjectiveContainItem(character, requiredItem.Identifiers, weapon.GetComponent()); - if (!newReloadWeaponObjective.IsDuplicate(reloadWeaponObjective)) + return item; + } + var effects = component.statusEffectLists; + if (effects != null) + { + foreach (var statusEffects in effects.Values) { - reloadWeaponObjective = newReloadWeaponObjective; + foreach (var statusEffect in statusEffects) + { + if (statusEffect.Afflictions.Any()) + { + return item; + } + } } } } } + } + return weapon; + } - if (reloadWeaponObjective != null) + private bool Equip(float deltaTime) + { + if (!character.SelectedItems.Contains(Weapon)) + { + if (character.Inventory.TryPutItem(Weapon, 3, true, false, character)) { - if (reloadWeaponObjective.IsCompleted()) - { - reloadWeaponObjective = null; - } - else if (!reloadWeaponObjective.CanBeCompleted) - { - Escape(deltaTime); - } - else - { - reloadWeaponObjective.TryComplete(deltaTime); - } - return; + Weapon.Equip(character); } - - character.CursorPosition = enemy.Position; - character.SetInput(InputType.Aim, false, true); - - Vector2 enemyDiff = Vector2.Normalize(enemy.Position - character.Position); - if (!MathUtils.IsValid(enemyDiff)) enemyDiff = Rand.Vector(1.0f); - float weaponAngle = ((weapon.body.Dir == 1.0f) ? weapon.body.Rotation : weapon.body.Rotation - MathHelper.Pi); - Vector2 weaponDir = new Vector2((float)Math.Cos(weaponAngle), (float)Math.Sin(weaponAngle)); - - if (Vector2.Dot(enemyDiff, weaponDir) < 0.9f) return; - - List ignoredBodies = new List(); - foreach (Limb limb in character.AnimController.Limbs) + else { - ignoredBodies.Add(limb.body.FarseerBody); + //couldn't equip the item, escape + Escape(deltaTime); + return false; } + } + return true; + } - var pickedBody = Submarine.PickBody(character.SimPosition, enemy.SimPosition, ignoredBodies); - if (pickedBody != null && !(pickedBody.UserData is Limb)) return; + private void Move(float deltaTime) + { + // Retreat to safety + // TODO: aggressive behaviour, chasing? + if (retreatTarget == null || (retreatObjective != null && !retreatObjective.CanBeCompleted)) + { + retreatTarget = HumanAIController.ObjectiveManager.GetObjective().FindBestHull(); + } + if (retreatTarget != null) + { + if (retreatObjective == null || retreatObjective.Target != retreatTarget) + { + retreatObjective = new AIObjectiveGoTo(retreatTarget, character, false, true); + } + retreatObjective.TryComplete(deltaTime); + } + } - weapon.Use(deltaTime, character); + private bool Reload(float deltaTime) + { + if (WeaponComponent != null && WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) + { + var containedItems = Weapon.ContainedItems; + foreach (RelatedItem requiredItem in WeaponComponent.requiredItems[RelatedItem.RelationType.Contained]) + { + Item containedItem = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); + if (containedItem == null) + { + if (reloadWeaponObjective == null) + { + reloadWeaponObjective = new AIObjectiveContainItem(character, requiredItem.Identifiers, Weapon.GetComponent()); + } + } + } + } + if (reloadWeaponObjective != null) + { + if (reloadWeaponObjective.IsCompleted()) + { + reloadWeaponObjective = null; + } + else if (!reloadWeaponObjective.CanBeCompleted) + { + Escape(deltaTime); + } + else + { + reloadWeaponObjective.TryComplete(deltaTime); + } + return false; + } + return true; + } + + private IEnumerable myBodies; + private void Attack(float deltaTime) + { + character.CursorPosition = Enemy.Position; + character.SetInput(InputType.Aim, false, true); + if (WeaponComponent is MeleeWeapon meleeWeapon) + { + if (Vector2.DistanceSquared(character.Position, Enemy.Position) <= meleeWeapon.Range * meleeWeapon.Range) + { + Weapon.Use(deltaTime, character); + } + } + else + { + if (WeaponComponent is RepairTool repairTool) + { + if (Vector2.DistanceSquared(character.Position, Enemy.Position) > repairTool.Range * repairTool.Range) { return; } + } + if (VectorExtensions.Angle(VectorExtensions.Forward(Weapon.body.TransformedRotation), Enemy.Position - character.Position) < MathHelper.PiOver4) + { + if (myBodies == null) + { + myBodies = character.AnimController.Limbs.Select(l => l.body.FarseerBody); + } + var pickedBody = Submarine.PickBody(character.SimPosition, Enemy.SimPosition, myBodies); + if (pickedBody != null) + { + Character target = null; + if (pickedBody.UserData is Character c) + { + target = c; + } + else if (pickedBody.UserData is Limb limb) + { + target = limb.character; + } + if (target != null && target == Enemy) + { + Weapon.Use(deltaTime, character); + } + } + } } } private void Escape(float deltaTime) { - // TODO: just let the find safety run? - if (escapeObjective == null) - { - escapeObjective = new AIObjectiveFindSafety(character); - } - - if (enemy.AnimController.CurrentHull == character.AnimController.CurrentHull) - { - escapeObjective.OverrideCurrentHullSafety = 0.0f; - } - else - { - escapeObjective.OverrideCurrentHullSafety = null; - } - - escapeObjective.TryComplete(deltaTime); + abandon = true; + SteeringManager.Reset(); + HumanAIController.ObjectiveManager.GetObjective().Priority = 100; } - public override bool IsCompleted() - { - return enemy == null || enemy.Removed || enemy.IsDead || coolDownTimer <= 0.0f; - } - - public override float GetPriority(AIObjectiveManager objectiveManager) - { - if (enemy == null || enemy.Removed) - { - return 0.0f; - } - - if (objectiveManager.CurrentOrder == this) - { - return AIObjectiveManager.OrderPriority; - } - - //clamp the strength to the health of this character - //(it doesn't make a difference whether the enemy does 200 or 600 damage, it's one hit kill anyway) - - float enemyDanger = Math.Min(Math.Max(CalculateEnemyStrength(), MaxEnemyDamage), character.Health) + enemy.Health / 10.0f; - - if (enemy.AIController is EnemyAIController enemyAI) - { - if (enemyAI.SelectedAiTarget == character.AiTarget) enemyDanger *= 2.0f; - } - - return Math.Max(enemyDanger, AIObjectiveManager.OrderPriority); - } + public override bool IsCompleted() => Enemy == null || Enemy.Removed || Enemy.IsDead || coolDownTimer <= 0.0f; + public override bool CanBeCompleted => !abandon && (reloadWeaponObjective == null || reloadWeaponObjective.CanBeCompleted) && (retreatObjective == null || retreatObjective.CanBeCompleted); + public override float GetPriority(AIObjectiveManager objectiveManager) => Enemy == null || Enemy.Removed || Enemy.IsDead ? 0 : 100; public override bool IsDuplicate(AIObjective otherObjective) { - AIObjectiveCombat objective = otherObjective as AIObjectiveCombat; - if (objective == null) return false; - - return objective.enemy == enemy; + if (!(otherObjective is AIObjectiveCombat objective)) return false; + return objective.Enemy == Enemy; } - private float CalculateEnemyStrength() - { - float enemyStrength = 0; - AttackContext currentContext = character.GetAttackContext(); - foreach (Limb limb in enemy.AnimController.Limbs) - { - if (limb.attack == null) continue; - if (!limb.attack.IsValidContext(currentContext)) { continue; } - if (!limb.attack.IsValidTarget(AttackTarget.Character)) { continue; } - enemyStrength += limb.attack.GetTotalDamage(false); - } - return enemyStrength; - } + //private float CalculateEnemyStrength() + //{ + // float enemyStrength = 0; + // AttackContext currentContext = character.GetAttackContext(); + // foreach (Limb limb in Enemy.AnimController.Limbs) + // { + // if (limb.attack == null) continue; + // if (!limb.attack.IsValidContext(currentContext)) { continue; } + // if (!limb.attack.IsValidTarget(AttackTarget.Character)) { continue; } + // enemyStrength += limb.attack.GetTotalDamage(false); + // } + // return enemyStrength; + //} } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs index fd208bb1a..ad375e55e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveExtinguishFire.cs @@ -32,7 +32,7 @@ namespace Barotrauma float dist = Math.Abs(character.WorldPosition.X - targetHull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - targetHull.WorldPosition.Y) * 2.0f; float distanceFactor = MathHelper.Lerp(1, 0.1f, MathUtils.InverseLerp(0, 10000, dist)); float severityFactor = MathHelper.Lerp(0, 1, MathHelper.Clamp(targetHull.FireSources.Sum(fs => fs.Size.X) / targetHull.Size.X, 0, 1)); - return MathHelper.Clamp(priority * severityFactor * distanceFactor, 0, 100); + return MathHelper.Clamp(Priority * severityFactor * distanceFactor, 0, 100); } public override bool IsCompleted() diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindDivingGear.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindDivingGear.cs index 51569bd04..b2158a614 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindDivingGear.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindDivingGear.cs @@ -62,7 +62,7 @@ namespace Barotrauma if (containedItem == null) continue; if (containedItem.Condition <= 0.0f) { - containedItem.Drop(); + containedItem.Drop(character); } else if (containedItem.Prefab.Identifier == "oxygentank" || containedItem.HasTag("oxygensource")) { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs index e7beb84bf..6ad1eeca8 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFindSafety.cs @@ -16,18 +16,17 @@ namespace Barotrauma const float priorityIncrease = 25; const float priorityDecrease = 10; const float SearchHullInterval = 3.0f; + const float clearUnreachableInterval = 30; private List unreachable = new List(); private float currenthullSafety; - + private float unreachableClearTimer; private float searchHullTimer; private AIObjectiveGoTo goToObjective; private AIObjective divingGearObjective; - public float? OverrideCurrentHullSafety; - public AIObjectiveFindSafety(Character character) : base(character, "") { } public override bool IsCompleted() => false; @@ -52,7 +51,7 @@ namespace Barotrauma if (divingGearObjective.IsCompleted()) { divingGearObjective = null; - priority = 0; + Priority = 0; } else if (divingGearObjective.CanBeCompleted) { @@ -61,6 +60,16 @@ namespace Barotrauma } } + if (unreachableClearTimer > 0) + { + unreachableClearTimer -= deltaTime; + } + else + { + unreachableClearTimer = clearUnreachableInterval; + unreachable.Clear(); + } + if (searchHullTimer > 0.0f) { searchHullTimer -= deltaTime; @@ -147,16 +156,35 @@ namespace Barotrauma } } - private Hull FindBestHull() + public Hull FindBestHull() { Hull bestHull = character.CurrentHull; float bestValue = currenthullSafety; foreach (Hull hull in Hull.hullList) { - if (unreachable.Contains(hull)) { continue; } if (hull.Submarine == null) { continue; } float hullSafety = 0; - if (character.Submarine == null) + if (character.Submarine != null && SteeringManager == PathSteering) + { + // Inside or outside near the sub + if (unreachable.Contains(hull)) { continue; } + if (!character.Submarine.IsConnectedTo(hull.Submarine)) { continue; } + hullSafety = HumanAIController.GetHullSafety(hull, character); + var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition); + int unsafeNodes = path.Nodes.Count(n => n.CurrentHull != character.CurrentHull && HumanAIController.UnsafeHulls.Contains(n.CurrentHull)); + // Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally) + float dist = Math.Abs(character.WorldPosition.X - hull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - hull.WorldPosition.Y) * 2.0f; + float distanceFactor = MathHelper.Lerp(1, 0.9f, MathUtils.InverseLerp(0, 10000, dist)); + hullSafety *= distanceFactor; + // Each unsafe node reduces the hull safety value. + hullSafety /= 1 + unsafeNodes; + // If the target is not inside a friendly submarine, considerably reduce the hull safety. + if (!character.Submarine.IsEntityFoundOnThisSub(hull, true)) + { + hullSafety /= 10; + } + } + else { // Outside if (hull.RoomName?.ToLowerInvariant() == "airlock") @@ -177,7 +205,8 @@ namespace Barotrauma } // Huge preference for closer targets - float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, 100000, Vector2.Distance(character.WorldPosition, hull.WorldPosition))); + float distance = Vector2.DistanceSquared(character.WorldPosition, hull.WorldPosition); + float distanceFactor = MathHelper.Lerp(1, 0.2f, MathUtils.InverseLerp(0, MathUtils.Pow(100000, 2), distance)); hullSafety *= distanceFactor; // If the target is not inside a friendly submarine, considerably reduce the hull safety. if (hull.Submarine.TeamID != character.TeamID && hull.Submarine.TeamID != Character.TeamType.FriendlyNPC) @@ -185,26 +214,6 @@ namespace Barotrauma hullSafety /= 10; } } - else - { - // Inside - // Not connected. - if (!character.Submarine.GetConnectedSubs().Contains(hull.Submarine)) { continue; } - hullSafety = HumanAIController.GetHullSafety(hull, character); - var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition); - int unsafeNodes = path.Nodes.Count(n => n.CurrentHull != character.CurrentHull && HumanAIController.UnsafeHulls.Contains(n.CurrentHull)); - // Vertical distance matters more than horizontal (climbing up/down is harder than moving horizontally) - float dist = Math.Abs(character.WorldPosition.X - hull.WorldPosition.X) + Math.Abs(character.WorldPosition.Y - hull.WorldPosition.Y) * 2.0f; - float distanceFactor = MathHelper.Lerp(1, 0.9f, MathUtils.InverseLerp(0, 10000, dist)); - hullSafety *= distanceFactor; - // Each unsafe node reduces the hull safety value. - hullSafety /= 1 + unsafeNodes; - // If the target is not inside a friendly submarine, considerably reduce the hull safety. - if (!character.Submarine.IsEntityFoundOnThisSub(hull, true)) - { - hullSafety /= 10; - } - } if (hullSafety > bestValue) { bestHull = hull; @@ -224,24 +233,24 @@ namespace Barotrauma if (character.CurrentHull == null) { currenthullSafety = 0; - priority = 5; + Priority = 5; return; } - if (character.OxygenAvailable < CharacterHealth.LowOxygenThreshold) { priority = 100; } - currenthullSafety = OverrideCurrentHullSafety ?? HumanAIController.GetHullSafety(character.CurrentHull); + if (character.OxygenAvailable < CharacterHealth.LowOxygenThreshold) { Priority = 100; } + currenthullSafety = HumanAIController.GetHullSafety(character.CurrentHull); if (currenthullSafety > HumanAIController.HULL_SAFETY_THRESHOLD) { - priority -= priorityDecrease * deltaTime; + Priority -= priorityDecrease * deltaTime; } else { float dangerFactor = (100 - currenthullSafety) / 100; - priority += dangerFactor * priorityIncrease * deltaTime; + Priority += dangerFactor * priorityIncrease * deltaTime; } - priority = MathHelper.Clamp(priority, 0, 100); + Priority = MathHelper.Clamp(Priority, 0, 100); if (divingGearObjective != null && !divingGearObjective.IsCompleted() && divingGearObjective.CanBeCompleted) { - priority = Math.Max(priority, AIObjectiveManager.OrderPriority + 10); + Priority = Math.Max(Priority, AIObjectiveManager.OrderPriority + 10); } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs index 517076479..8a29fefcd 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs @@ -11,6 +11,7 @@ namespace Barotrauma public override string DebugTag => "fix leak"; public override bool KeepDivingGearOn => true; + public override bool ForceRun => true; private readonly Gap leak; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs index 690db42c8..0e814171e 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeaks.cs @@ -10,6 +10,7 @@ namespace Barotrauma { public override string DebugTag => "fix leaks"; public override bool KeepDivingGearOn => true; + public override bool ForceRun => true; public AIObjectiveFixLeaks(Character character) : base (character, "") { } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs index d3ded6a94..68428100b 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGetItem.cs @@ -144,7 +144,7 @@ namespace Barotrauma if (character.Inventory.TryPutItem(character.Inventory.Items[i], character, new List() { InvSlotType.Any })) continue; //if everything else fails, simply drop the existing item - character.Inventory.Items[i].Drop(); + character.Inventory.Items[i].Drop(character); } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs index 5a88f2646..f4a2ab366 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs @@ -45,17 +45,22 @@ namespace Barotrauma get { bool canComplete = !cannotReach && !abandon; - if (FollowControlledCharacter && Character.Controlled == null) { canComplete = false; } - else if (Target != null && Target.Removed) { canComplete = false; } - else if (repeat || waitUntilPathUnreachable > 0.0f) { canComplete = true; } - else if (character.AIController.SteeringManager is IndoorsSteeringManager pathSteering) + if (canComplete) { - //path doesn't exist (= hasn't been searched for yet), assume for now that the target is reachable TODO: add a timer? - if (pathSteering.CurrentPath == null) { canComplete = true; } - else if (!AllowGoingOutside && pathSteering.CurrentPath.HasOutdoorsNodes) { canComplete = false; } - if (canComplete) + if (FollowControlledCharacter && Character.Controlled == null) { - canComplete = !pathSteering.CurrentPath.Unreachable; + canComplete = false; + } + else if (Target != null && Target.Removed) + { + canComplete = false; + } + else if (!repeat && waitUntilPathUnreachable < 0) + { + if (SteeringManager == PathSteering && PathSteering.CurrentPath != null) + { + canComplete = !PathSteering.CurrentPath.Unreachable; + } } } if (!canComplete) @@ -144,9 +149,9 @@ namespace Barotrauma } else { - var indoorSteering = character.AIController.SteeringManager as IndoorsSteeringManager; - bool targetIsOutside = (Target != null && Target.Submarine == null) || (indoorSteering != null && indoorSteering.CurrentPath != null && indoorSteering.CurrentPath.HasOutdoorsNodes); - if (targetIsOutside && !AllowGoingOutside) + bool targetIsOutside = (Target != null && Target.Submarine == null) || + (SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.HasOutdoorsNodes); + if (targetIsOutside && character.CurrentHull != null && !AllowGoingOutside) { cannotReach = true; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs index 8c2fd39ac..7d0794a5a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -11,6 +11,12 @@ namespace Barotrauma public override string DebugTag => "idle"; const float WallAvoidDistance = 150.0f; + private readonly float newTargetIntervalMin = 5; + private readonly float newTargetIntervalMax = 15; + private readonly float standStillMin = 1; + private readonly float standStillMax = 10; + private readonly float walkDurationMin = 3; + private readonly float walkDurationMax = 10; private Hull currentTarget; private float newTargetTimer; @@ -46,7 +52,10 @@ namespace Barotrauma character.SelectedConstruction = null; } - if (currentTarget == null && (IsForbidden(character.CurrentHull) || HumanAIController.UnsafeHulls.Contains(character.CurrentHull))) + bool currentTargetIsInvalid = currentTarget == null || IsForbidden(currentTarget) || + (PathSteering.CurrentPath != null && PathSteering.CurrentPath.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull))); + + if (currentTargetIsInvalid || (currentTarget == null && IsForbidden(character.CurrentHull))) { newTargetTimer = 0; standStillTimer = 0; @@ -70,7 +79,7 @@ namespace Barotrauma PathSteering.SetPath(path); } - newTargetTimer = currentTarget == null ? 5.0f : 15.0f; + newTargetTimer = currentTarget != null && character.AnimController.InWater ? newTargetIntervalMin : Rand.Range(newTargetIntervalMin, newTargetIntervalMax); } newTargetTimer -= deltaTime; @@ -79,20 +88,20 @@ namespace Barotrauma // - if reached the end of the path // - if the target is unreachable // - if the path requires going outside - if (PathSteering == null || (PathSteering.CurrentPath != null && + if (SteeringManager != PathSteering || (PathSteering.CurrentPath != null && (PathSteering.CurrentPath.NextNode == null || PathSteering.CurrentPath.Unreachable || PathSteering.CurrentPath.HasOutdoorsNodes))) { standStillTimer -= deltaTime; if (standStillTimer > 0.0f) { - walkDuration = Rand.Range(1.0f, 5.0f); + walkDuration = Rand.Range(walkDurationMin, walkDurationMax); PathSteering.Reset(); return; } if (standStillTimer < -walkDuration) { - standStillTimer = Rand.Range(1.0f, 10.0f); + standStillTimer = Rand.Range(standStillMin, standStillMax); } //steer away from edges of the hull @@ -128,12 +137,11 @@ namespace Barotrauma } character.AIController.SteeringManager.SteeringWander(); - if (!character.IsClimbing) + if (!character.IsClimbing && !character.AnimController.InWater) { //reset vertical steering to prevent dropping down from platforms etc character.AIController.SteeringManager.ResetY(); } - return; } @@ -150,6 +158,7 @@ namespace Barotrauma { var idCard = character.Inventory.FindItemByIdentifier("idcard"); Hull targetHull = null; + bool isCurrentHullOK = !HumanAIController.UnsafeHulls.Contains(character.CurrentHull) && !IsForbidden(character.CurrentHull); //random chance of navigating back to the room where the character spawned if (Rand.Int(5) == 1 && idCard != null) { @@ -186,9 +195,13 @@ namespace Barotrauma continue; } } - // Check that there is no unsafe or forbidden hulls on the way to the target - var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition); - if (path.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull) || IsForbidden(n.CurrentHull))) { continue; } + if (isCurrentHullOK) + { + // Check that there is no unsafe or forbidden hulls on the way to the target + // Only do this when the current hull is ok, because otherwise the would block all paths from the current hull to the target hull. + var path = PathSteering.PathFinder.FindPath(character.SimPosition, hull.SimPosition); + if (path.Nodes.Any(n => HumanAIController.UnsafeHulls.Contains(n.CurrentHull) || IsForbidden(n.CurrentHull))) { continue; } + } // If we want to do a steering check, we should do it here, before setting the path //if (path.Cost > 1000.0f) { continue; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs index b456d9f62..31b2a9015 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs @@ -56,23 +56,6 @@ namespace Barotrauma DelayedObjectives.Add(objective, coroutine); } - public Dictionary DelayedObjectives { get; private set; } = new Dictionary(); - public void AddObjective(AIObjective objective, float delay, Action callback = null) - { - if (DelayedObjectives.TryGetValue(objective, out CoroutineHandle coroutine)) - { - CoroutineManager.StopCoroutines(coroutine); - DelayedObjectives.Remove(objective); - } - coroutine = CoroutineManager.InvokeAfter(() => - { - DelayedObjectives.Remove(objective); - AddObjective(objective); - callback?.Invoke(); - }, delay); - DelayedObjectives.Add(objective, coroutine); - } - public T GetObjective() where T : AIObjective { foreach (AIObjective objective in Objectives) @@ -200,27 +183,6 @@ namespace Barotrauma if (order.TargetItemComponent == null) return; CurrentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController); break; - case "chargebatteries": - currentOrder = new AIObjectiveChargeBatteries(character, option); - break; - case "rescue": - currentOrder = new AIObjectiveRescueAll(character); - break; - case "repairsystems": - currentOrder = new AIObjectiveRepairItems(character) { RequireAdequateSkills = option != "all" }; - break; - case "pumpwater": - currentOrder = new AIObjectivePumpWater(character, option); - break; - case "extinguishfires": - currentOrder = new AIObjectiveExtinguishFires(character); - break; - case "steer": - var steering = (order?.TargetEntity as Item)?.GetComponent(); - if (steering != null) steering.PosToMaintain = steering.Item.Submarine?.WorldPosition; - if (order.TargetItemComponent == null) return; - currentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController); - break; default: if (order.TargetItemComponent == null) return; CurrentOrder = new AIObjectiveOperateItem(order.TargetItemComponent, character, option, false, null, order.UseController); diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs index 6b244961a..369ad5b5c 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs @@ -135,7 +135,7 @@ namespace Barotrauma if (!character.Inventory.Items[i].AllowedSlots.Contains(InvSlotType.Any) || !character.Inventory.TryPutItem(character.Inventory.Items[i], character, new List() { InvSlotType.Any })) { - character.Inventory.Items[i].Drop(); + character.Inventory.Items[i].Drop(character); } } if (character.Inventory.TryPutItem(component.Item, i, true, false, character)) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs index 8a6b47f1f..fe0730eff 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs @@ -35,7 +35,7 @@ namespace Barotrauma float damagePriority = MathHelper.Lerp(1, 0, (Item.Condition + 10) / Item.MaxCondition); float successFactor = MathHelper.Lerp(0, 1, Item.Repairables.Average(r => r.DegreeOfSuccess(character))); float isSelected = character.SelectedConstruction == Item ? 50 : 0; - float baseLevel = Math.Max(priority + isSelected, 1); + float baseLevel = Math.Max(Priority + isSelected, 1); return MathHelper.Clamp(baseLevel * damagePriority * distanceFactor * successFactor, 0, 100); } @@ -84,6 +84,7 @@ namespace Barotrauma } if (character.CanInteractWith(Item)) { + OperateRepairTool(deltaTime); foreach (Repairable repairable in Item.Repairables) { if (repairable.CurrentFixer != null && repairable.CurrentFixer != character) @@ -123,5 +124,33 @@ namespace Barotrauma AddSubObjective(goToObjective); } } + + private void OperateRepairTool(float deltaTime) + { + // Operate repair tool, if required. + foreach (Repairable repairable in Item.Repairables) + { + foreach (var kvp in repairable.requiredItems) + { + foreach (RelatedItem requiredItem in kvp.Value) + { + foreach (var item in character.Inventory.Items) + { + if (requiredItem.MatchesItem(item)) + { + var repairTool = item.GetComponent(); + if (repairTool != null) + { + character.CursorPosition = Item.Position; + character.SetInput(InputType.Aim, false, true); + repairTool.Use(deltaTime, character); + return; + } + } + } + } + } + } + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs index 17a67ca3f..dff106cfb 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Health/CharacterHealth.cs @@ -549,8 +549,9 @@ namespace Barotrauma limbHealths[i].Afflictions.RemoveAt(j); } } - foreach (Affliction affliction in limbHealths[i].Afflictions) + for (int j = limbHealths[i].Afflictions.Count - 1; j >= 0; j--) { + var affliction = limbHealths[i].Afflictions[j]; Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == i); affliction.Update(this, targetLimb, deltaTime); affliction.DamagePerSecondTimer += deltaTime; diff --git a/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs b/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs index 13c0a8d55..b75f7012e 100644 --- a/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Events/EventManager.cs @@ -120,18 +120,30 @@ namespace Barotrauma private void CreateEvents() { + //don't create new events if docked to the start oupost + if (Level.Loaded?.StartOutpost != null && + Submarine.MainSub.DockedTo.Contains(Level.Loaded.StartOutpost)) + { + return; + } + for (int i = selectedEventSets.Count - 1; i >= 0; i--) { ScriptedEventSet eventSet = selectedEventSets[i]; + float distFromStart = Vector2.Distance(Submarine.MainSub.WorldPosition, level.StartPosition); + float distFromEnd = Vector2.Distance(Submarine.MainSub.WorldPosition, level.EndPosition); + float distanceTraveled = MathHelper.Clamp( (Submarine.MainSub.WorldPosition.X - level.StartPosition.X) / (level.EndPosition.X - level.StartPosition.X), 0.0f, 1.0f); - if (Level.Loaded?.StartOutpost != null && - Submarine.MainSub.DockedTo.Contains(Level.Loaded.StartOutpost)) + //don't create new events if within 50 meters of the start/end of the level + if (distanceTraveled <= 0.0f || + distFromStart * Physics.DisplayToRealWorldRatio < 50.0f || + distFromEnd * Physics.DisplayToRealWorldRatio < 50.0f) { - distanceTraveled = 0.0f; + continue; } if ((Submarine.MainSub == null || distanceTraveled < eventSet.MinDistanceTraveled) && diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs index 49e1ca3b0..e8b625621 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs @@ -65,12 +65,6 @@ namespace Barotrauma public int ParticleLimit { get; set; } - public float LightMapScale { get; set; } - public bool SpecularityEnabled { get; set; } - public bool ChromaticAberrationEnabled { get; set; } - - public bool MuteOnFocusLost { get; set; } - public int ParticleLimit { get; set; } public float LightMapScale { get; set; } @@ -405,8 +399,6 @@ namespace Barotrauma AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f); - AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f); - AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f); keyMapping = new KeyOrMouse[Enum.GetNames(typeof(InputType)).Length]; @@ -620,98 +612,6 @@ namespace Barotrauma } } - TextManager.LoadTextPacks(SelectedContentPackages); - - //display error messages after all content packages have been loaded - //to make sure the package that contains text files has been loaded before we attempt to use TextManager - foreach (string missingPackagePath in missingPackagePaths) - { - DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath)); - } - foreach (ContentPackage incompatiblePackage in incompatiblePackages) - { - DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage") - .Replace("[packagename]", incompatiblePackage.Name) - .Replace("[packageversion]", incompatiblePackage.GameVersion.ToString()) - .Replace("[gameversion]", GameMain.Version.ToString())); - } - foreach (ContentPackage contentPackage in SelectedContentPackages) - { - foreach (ContentFile file in contentPackage.Files) - { - if (!System.IO.File.Exists(file.Path)) - { - DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found."); - continue; - } - ToolBox.IsProperFilenameCase(file.Path); - } - } - - TextManager.LoadTextPacks(SelectedContentPackages); - - //display error messages after all content packages have been loaded - //to make sure the package that contains text files has been loaded before we attempt to use TextManager - foreach (string missingPackagePath in missingPackagePaths) - { - DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath)); - } - foreach (ContentPackage incompatiblePackage in incompatiblePackages) - { - DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage") - .Replace("[packagename]", incompatiblePackage.Name) - .Replace("[packageversion]", incompatiblePackage.GameVersion.ToString()) - .Replace("[gameversion]", GameMain.Version.ToString())); - } - foreach (ContentPackage contentPackage in SelectedContentPackages) - { - foreach (ContentFile file in contentPackage.Files) - { - if (!System.IO.File.Exists(file.Path)) - { - DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found."); - continue; - } - ToolBox.IsProperFilenameCase(file.Path); - } - } - - TextManager.LoadTextPacks(SelectedContentPackages); - - //display error messages after all content packages have been loaded - //to make sure the package that contains text files has been loaded before we attempt to use TextManager - foreach (string missingPackagePath in missingPackagePaths) - { - DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath)); - } - foreach (ContentPackage incompatiblePackage in incompatiblePackages) - { - DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage") - .Replace("[packagename]", incompatiblePackage.Name) - .Replace("[packageversion]", incompatiblePackage.GameVersion.ToString()) - .Replace("[gameversion]", GameMain.Version.ToString())); - } - foreach (ContentPackage contentPackage in SelectedContentPackages) - { - foreach (ContentFile file in contentPackage.Files) - { - if (!System.IO.File.Exists(file.Path)) - { - DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found."); - continue; - } - ToolBox.IsProperFilenameCase(file.Path); - } - } - if (!SelectedContentPackages.Any()) - { - var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage); - if (availablePackage != null) - { - SelectedContentPackages.Add(availablePackage); - } - } - //save to get rid of the invalid selected packages in the config file if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); } } @@ -1084,6 +984,369 @@ namespace Barotrauma } #endregion + #region Save PlayerConfig + public void SaveNewPlayerConfig() + { + XDocument doc = new XDocument(); + UnsavedSettings = false; + + if (doc.Root == null) + { + doc.Add(new XElement("config")); + } + + doc.Root.Add( + new XAttribute("language", TextManager.Language), + new XAttribute("masterserverurl", MasterServerUrl), + new XAttribute("autocheckupdates", AutoCheckUpdates), + new XAttribute("musicvolume", musicVolume), + new XAttribute("soundvolume", soundVolume), + new XAttribute("verboselogging", VerboseLogging), + new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs), + new XAttribute("enablesplashscreen", EnableSplashScreen), + new XAttribute("usesteammatchmaking", useSteamMatchmaking), + new XAttribute("quickstartsub", QuickStartSubmarineName), + new XAttribute("requiresteamauthentication", requireSteamAuthentication), + new XAttribute("autoupdateworkshopitems", AutoUpdateWorkshopItems), + new XAttribute("aimassistamount", aimAssistAmount)); + + if (!ShowUserStatisticsPrompt) + { + doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics)); + } + + XElement gMode = doc.Root.Element("graphicsmode"); + if (gMode == null) + { + gMode = new XElement("graphicsmode"); + doc.Root.Add(gMode); + } + if (GraphicsWidth == 0 || GraphicsHeight == 0) + { + gMode.ReplaceAttributes(new XAttribute("displaymode", windowMode)); + } + else + { + gMode.ReplaceAttributes( + new XAttribute("width", GraphicsWidth), + new XAttribute("height", GraphicsHeight), + new XAttribute("vsync", VSyncEnabled), + new XAttribute("displaymode", windowMode)); + } + + XElement gSettings = doc.Root.Element("graphicssettings"); + if (gSettings == null) + { + gSettings = new XElement("graphicssettings"); + doc.Root.Add(gSettings); + } + + gSettings.ReplaceAttributes( + new XAttribute("particlelimit", ParticleLimit), + new XAttribute("lightmapscale", LightMapScale), + new XAttribute("specularity", SpecularityEnabled), + new XAttribute("chromaticaberration", ChromaticAberrationEnabled), + new XAttribute("losmode", LosMode), + new XAttribute("hudscale", HUDScale), + new XAttribute("inventoryscale", InventoryScale)); + + foreach (ContentPackage contentPackage in SelectedContentPackages) + { + if (contentPackage.Path.Contains(vanillaContentPackagePath)) + { + doc.Root.Add(new XElement("contentpackage", new XAttribute("path", contentPackage.Path))); + break; + } + } + + var keyMappingElement = new XElement("keymapping"); + doc.Root.Add(keyMappingElement); + for (int i = 0; i < keyMapping.Length; i++) + { + if (keyMapping[i].MouseButton == null) + { + keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].Key)); + } + else + { + keyMappingElement.Add(new XAttribute(((InputType)i).ToString(), keyMapping[i].MouseButton)); + } + } + + var gameplay = new XElement("gameplay"); + var jobPreferences = new XElement("jobpreferences"); + foreach (string jobName in JobPreferences) + { + jobPreferences.Add(new XElement("job", new XAttribute("identifier", jobName))); + } + gameplay.Add(jobPreferences); + doc.Root.Add(gameplay); + + var playerElement = new XElement("player", + new XAttribute("name", defaultPlayerName ?? ""), + new XAttribute("headindex", CharacterHeadIndex), + new XAttribute("gender", CharacterGender), + new XAttribute("race", CharacterRace), + new XAttribute("hairindex", CharacterHairIndex), + new XAttribute("beardindex", CharacterBeardIndex), + new XAttribute("moustacheindex", CharacterMoustacheIndex), + new XAttribute("faceattachmentindex", CharacterFaceAttachmentIndex)); + doc.Root.Add(playerElement); + + XmlWriterSettings settings = new XmlWriterSettings + { + Indent = true, + OmitXmlDeclaration = true, + NewLineOnAttributes = true + }; + + try + { + using (var writer = XmlWriter.Create(savePath, settings)) + { + doc.WriteTo(writer); + writer.Flush(); + } + } + catch (Exception e) + { + DebugConsole.ThrowError("Saving game settings failed.", e); + GameAnalyticsManager.AddErrorEventOnce("GameSettings.Save:SaveFailed", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + "Saving game settings failed.\n" + e.Message + "\n" + e.StackTrace); + } + } + #endregion + + #region Load PlayerConfig + // TODO: DRY + public void LoadPlayerConfig() + { + XDocument doc = XMLExtensions.LoadXml(playerSavePath); + + if (doc == null || doc.Root == null) + { + ShowUserStatisticsPrompt = true; + SaveNewPlayerConfig(); + return; + } + + Language = doc.Root.GetAttributeString("language", Language); + AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", AutoCheckUpdates); + sendUserStatistics = doc.Root.GetAttributeBool("senduserstatistics", true); + + XElement graphicsMode = doc.Root.Element("graphicsmode"); + GraphicsWidth = graphicsMode.GetAttributeInt("width", GraphicsWidth); + GraphicsHeight = graphicsMode.GetAttributeInt("height", GraphicsHeight); + VSyncEnabled = graphicsMode.GetAttributeBool("vsync", VSyncEnabled); + + XElement graphicsSettings = doc.Root.Element("graphicssettings"); + ParticleLimit = graphicsSettings.GetAttributeInt("particlelimit", ParticleLimit); + LightMapScale = MathHelper.Clamp(graphicsSettings.GetAttributeFloat("lightmapscale", LightMapScale), 0.1f, 1.0f); + SpecularityEnabled = graphicsSettings.GetAttributeBool("specularity", SpecularityEnabled); + ChromaticAberrationEnabled = graphicsSettings.GetAttributeBool("chromaticaberration", ChromaticAberrationEnabled); + HUDScale = graphicsSettings.GetAttributeFloat("hudscale", HUDScale); + InventoryScale = graphicsSettings.GetAttributeFloat("inventoryscale", InventoryScale); + var losModeStr = graphicsSettings.GetAttributeString("losmode", "Transparent"); + if (!Enum.TryParse(losModeStr, out losMode)) + { + losMode = LosMode.Transparent; + } + +#if CLIENT + if (GraphicsWidth == 0 || GraphicsHeight == 0) + { + GraphicsWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width; + GraphicsHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height; + } +#endif + + var windowModeStr = graphicsMode.GetAttributeString("displaymode", "Fullscreen"); + if (!Enum.TryParse(windowModeStr, out windowMode)) + { + windowMode = WindowMode.Fullscreen; + } + + XElement audioSettings = doc.Root.Element("audio"); + if (audioSettings != null) + { + SoundVolume = audioSettings.GetAttributeFloat("soundvolume", SoundVolume); + MusicVolume = audioSettings.GetAttributeFloat("musicvolume", MusicVolume); + VoiceChatVolume = audioSettings.GetAttributeFloat("voicechatvolume", VoiceChatVolume); + string voiceSettingStr = audioSettings.GetAttributeString("voicesetting", "Disabled"); + VoiceCaptureDevice = audioSettings.GetAttributeString("voicecapturedevice", ""); + NoiseGateThreshold = audioSettings.GetAttributeFloat("noisegatethreshold", -45); + var voiceSetting = VoiceMode.Disabled; + if (Enum.TryParse(voiceSettingStr, out voiceSetting)) + { + VoiceSetting = voiceSetting; + } + } + + useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking); + requireSteamAuthentication = doc.Root.GetAttributeBool("requiresteamauthentication", requireSteamAuthentication); + + EnableSplashScreen = doc.Root.GetAttributeBool("enablesplashscreen", EnableSplashScreen); + + AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", AimAssistAmount); + + foreach (XElement subElement in doc.Root.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "keymapping": + foreach (XAttribute attribute in subElement.Attributes()) + { + if (Enum.TryParse(attribute.Name.ToString(), true, out InputType inputType)) + { + if (int.TryParse(attribute.Value.ToString(), out int mouseButton)) + { + keyMapping[(int)inputType] = new KeyOrMouse(mouseButton); + } + else + { + if (Enum.TryParse(attribute.Value.ToString(), true, out Keys key)) + { + keyMapping[(int)inputType] = new KeyOrMouse(key); + } + } + } + } + break; + case "gameplay": + jobPreferences = new List(); + foreach (XElement ele in subElement.Element("jobpreferences").Elements("job")) + { + string jobIdentifier = ele.GetAttributeString("identifier", ""); + if (string.IsNullOrEmpty(jobIdentifier)) continue; + jobPreferences.Add(jobIdentifier); + } + break; + case "player": + defaultPlayerName = subElement.GetAttributeString("name", defaultPlayerName); + CharacterHeadIndex = subElement.GetAttributeInt("headindex", CharacterHeadIndex); + if (Enum.TryParse(subElement.GetAttributeString("gender", "none"), true, out Gender g)) + { + CharacterGender = g; + } + if (Enum.TryParse(subElement.GetAttributeString("race", "white"), true, out Race r)) + { + CharacterRace = r; + } + else + { + CharacterRace = Race.White; + } + CharacterHairIndex = subElement.GetAttributeInt("hairindex", CharacterHairIndex); + CharacterBeardIndex = subElement.GetAttributeInt("beardindex", CharacterBeardIndex); + CharacterMoustacheIndex = subElement.GetAttributeInt("moustacheindex", CharacterMoustacheIndex); + CharacterFaceAttachmentIndex = subElement.GetAttributeInt("faceattachmentindex", CharacterFaceAttachmentIndex); + break; + case "tutorials": + foreach (XElement tutorialElement in subElement.Elements()) + { + CompletedTutorialNames.Add(tutorialElement.GetAttributeString("name", "")); + } + break; + } + } + + foreach (InputType inputType in Enum.GetValues(typeof(InputType))) + { + if (keyMapping[(int)inputType] == null) + { + DebugConsole.ThrowError("Key binding for the input type \"" + inputType + " not set!"); + keyMapping[(int)inputType] = new KeyOrMouse(Keys.D1); + } + } + + UnsavedSettings = false; + + selectedContentPackagePaths = new HashSet(); + + foreach (XElement subElement in doc.Root.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "contentpackage": + string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", "")); + selectedContentPackagePaths.Add(path); + break; + } + } + + LoadContentPackages(selectedContentPackagePaths); + } + + public void ReloadContentPackages() + { + LoadContentPackages(selectedContentPackagePaths); + } + + private void LoadContentPackages(IEnumerable contentPackagePaths) + { + var missingPackagePaths = new List(); + var incompatiblePackages = new List(); + SelectedContentPackages.Clear(); + foreach (string path in contentPackagePaths) + { + var matchingContentPackage = ContentPackage.List.Find(cp => System.IO.Path.GetFullPath(cp.Path) == path); + + if (matchingContentPackage == null) + { + missingPackagePaths.Add(path); + } + else if (!matchingContentPackage.IsCompatible()) + { + incompatiblePackages.Add(matchingContentPackage); + } + else + { + SelectedContentPackages.Add(matchingContentPackage); + } + } + + TextManager.LoadTextPacks(SelectedContentPackages); + + foreach (ContentPackage contentPackage in SelectedContentPackages) + { + foreach (ContentFile file in contentPackage.Files) + { + if (!System.IO.File.Exists(file.Path)) + { + DebugConsole.ThrowError("Error in content package \"" + contentPackage.Name + "\" - file \"" + file.Path + "\" not found."); + continue; + } + ToolBox.IsProperFilenameCase(file.Path); + } + } + if (!SelectedContentPackages.Any()) + { + var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage); + if (availablePackage != null) + { + SelectedContentPackages.Add(availablePackage); + } + } + + //save to get rid of the invalid selected packages in the config file + if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); } + + //display error messages after all content packages have been loaded + //to make sure the package that contains text files has been loaded before we attempt to use TextManager + foreach (string missingPackagePath in missingPackagePaths) + { + DebugConsole.ThrowError(TextManager.Get("ContentPackageNotFound").Replace("[packagepath]", missingPackagePath)); + } + foreach (ContentPackage incompatiblePackage in incompatiblePackages) + { + DebugConsole.ThrowError(TextManager.Get(incompatiblePackage.GameVersion <= new Version(0, 0, 0, 0) ? "IncompatibleContentPackageUnknownVersion" : "IncompatibleContentPackage") + .Replace("[packagename]", incompatiblePackage.Name) + .Replace("[packageversion]", incompatiblePackage.GameVersion.ToString()) + .Replace("[gameversion]", GameMain.Version.ToString())); + } + } + #endregion + #region Save PlayerConfig public void SaveNewPlayerConfig() { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Holdable.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Holdable.cs index 593b02460..5d3f4dcfc 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Holdable.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Holdable.cs @@ -438,7 +438,7 @@ namespace Barotrauma.Items.Components GameServer.Log(character.LogName + " attached " + item.Name + " to a wall", ServerLog.MessageType.ItemInteraction); } #endif - item.Drop(); + item.Drop(character); } AttachToWall(); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs index 400e69223..2885ca95f 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs @@ -294,9 +294,10 @@ namespace Barotrauma.Items.Components character.CursorPosition = leak.Position; character.SetInput(InputType.Aim, false, true); - if (VectorExtensions.Angle(VectorExtensions.Forward(item.body.TransformedRotation), fromItemToLeak) < MathHelper.PiOver4) + // Press the trigger only when the tool is approximately facing the target. + // If the character is climbing, ignore the check, because we cannot aim while climbing. + if (character.IsClimbing || VectorExtensions.Angle(VectorExtensions.Forward(item.body.TransformedRotation), fromItemToLeak) < MathHelper.PiOver4) { - // Press the trigger only when the tool is approximately facing the target. Use(deltaTime, character); } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Throwable.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Throwable.cs index 9fd196905..b6107eada 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Throwable.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/Throwable.cs @@ -105,7 +105,7 @@ namespace Barotrauma.Items.Components GameServer.Log(picker.LogName + " threw " + item.Name, ServerLog.MessageType.ItemInteraction); #endif - item.Drop(); + item.Drop(picker); item.body.ApplyLinearImpulse(throwVector * throwForce * item.body.Mass * 3.0f); ac.GetLimb(LimbType.Head).body.ApplyLinearImpulse(throwVector*10.0f); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs index 97c950c1c..11a3ea4e0 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemContainer.cs @@ -279,7 +279,7 @@ namespace Barotrauma.Items.Components foreach (Item item in Inventory.Items) { if (item == null) continue; - item.Drop(); + item.Drop(null); } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs index 49e2b38a0..a3af545f4 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Fabricator.cs @@ -420,7 +420,7 @@ namespace Barotrauma.Items.Components if (inputContainer.Inventory.Items.All(it => it != null)) { var unneededItem = inputContainer.Inventory.Items.FirstOrDefault(it => !usedItems.Contains(it)); - unneededItem?.Drop(); + unneededItem?.Drop(null); } inputContainer.Inventory.TryPutItem(matchingItem, user: null, createNetworkEvent: true); } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs index 741306c51..660bc5dd8 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Reactor.cs @@ -437,7 +437,7 @@ namespace Barotrauma.Items.Components { if (item != null && item.Condition <= 0.0f) { - item.Drop(); + item.Drop(character); } } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs index d8f76c924..320adf9ab 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Projectile.cs @@ -173,7 +173,7 @@ namespace Barotrauma.Items.Components private void Launch(Vector2 impulse) { - item.Drop(); + item.Drop(null); item.body.Enabled = true; item.body.ApplyLinearImpulse(impulse); @@ -213,7 +213,7 @@ namespace Barotrauma.Items.Components { float rotation = item.body.Rotation; Vector2 simPositon = item.SimPosition; - item.Drop(); + item.Drop(null); item.body.Enabled = true; //set the velocity of the body because the OnProjectileCollision method diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs index 968e06ea2..a74c4f4e2 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Turret.cs @@ -350,7 +350,7 @@ namespace Barotrauma.Items.Components { reload = reloadTime; - projectile.Drop(); + projectile.Drop(null); projectile.body.Dir = 1.0f; projectile.body.ResetDynamics(); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index 2290db26a..29915b1d1 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1563,7 +1563,7 @@ namespace Barotrauma return isCombined; } - public void Drop(Character dropper = null) + public void Drop(Character dropper) { if (parentInventory != null && !parentInventory.Owner.Removed && !Removed && GameMain.NetworkMember != null && (GameMain.NetworkMember.IsServer || Character.Controlled == dropper)) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs index 5e0b5c4dc..c3d5d2926 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs @@ -430,13 +430,6 @@ namespace Barotrauma } CurrentLocation.SelectedMissionIndex = missionIndex; - //the destination must be the same as the destination of the mission - if (CurrentLocation.SelectedMission != null && - CurrentLocation.SelectedMission.Locations[1] != SelectedLocation) - { - SelectLocation(CurrentLocation.SelectedMission.Locations[1]); - } - SelectedLocation = location; SelectedConnection = connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation)); OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection); diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 92e6c3a45..44fbb7299 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -467,6 +467,7 @@ namespace Barotrauma public List GetConnectedSubs() { connectedSubs.Clear(); + connectedSubs.Add(this); GetConnectedSubsRecursive(connectedSubs); return connectedSubs; @@ -522,6 +523,30 @@ namespace Barotrauma { maxX = Math.Min(maxX, ruin.Area.X - 100.0f); } + else + { + maxX = Math.Min(maxX, ruin.Area.X - 100.0f); + } + } + + if (minX < 0.0f && maxX > Level.Loaded.Size.X) + { + //no walls found at either side, just use the initial spawnpos and hope for the best + } + else if (minX < 0) + { + //no wall found at the left side, spawn to the left from the right-side wall + spawnPos.X = maxX - minWidth - 100.0f; + } + else if (maxX > Level.Loaded.Size.X) + { + //no wall found at right side, spawn to the right from the left-side wall + spawnPos.X = minX + minWidth + 100.0f; + } + else + { + //walls found at both sides, use their midpoint + spawnPos.X = (minX + maxX) / 2; } if (minX < 0.0f && maxX > Level.Loaded.Size.X) @@ -655,7 +680,7 @@ namespace Barotrauma } } - public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, List ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate customPredicate = null) + public static Body PickBody(Vector2 rayStart, Vector2 rayEnd, IEnumerable ignoredBodies = null, Category? collisionCategory = null, bool ignoreSensors = true, Predicate customPredicate = null) { if (Vector2.DistanceSquared(rayStart, rayEnd) < 0.00001f) { @@ -1011,6 +1036,31 @@ namespace Barotrauma return false; } + /// + /// Returns true if the sub is same as the other. + /// + public bool IsConnectedTo(Submarine otherSub) => this == otherSub || GetConnectedSubs().Contains(otherSub); + + public List GetHulls(bool alsoFromConnectedSubs) => GetEntities(alsoFromConnectedSubs, Hull.hullList); + public List GetGaps(bool alsoFromConnectedSubs) => GetEntities(alsoFromConnectedSubs, Gap.GapList); + public List GetItems(bool alsoFromConnectedSubs) => GetEntities(alsoFromConnectedSubs, Item.ItemList); + + public List GetEntities(bool includingConnectedSubs, List list) where T : MapEntity + { + return list.FindAll(e => IsEntityFoundOnThisSub(e, includingConnectedSubs)); + } + + public bool IsEntityFoundOnThisSub(MapEntity entity, bool includingConnectedSubs) + { + if (entity.Submarine == this) { return true; } + if (entity.Submarine == null) { return false; } + if (includingConnectedSubs) + { + return GetConnectedSubs().Any(s => s == entity.Submarine && entity.Submarine.TeamID == TeamID); + } + return false; + } + /// /// Finds the sub whose borders contain the position /// diff --git a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs index fc56c8fc7..dac0e7d44 100644 --- a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs +++ b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs @@ -160,16 +160,6 @@ namespace Barotrauma } #endif - public void SetState() - { - hit = binding.IsHit(); - if (hit) hitQueue = true; - - held = binding.IsDown(); - if (held) heldQueue = true; - } -#endif - public bool Hit { get diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub index e6b2f571a4c223e1778cca8cbea189dd15ee4e8b..97196e8ece1593cbec71e27d30674de1ebf3b5af 100644 GIT binary patch literal 69867 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 z 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

S;JG$ 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 literal 0 HcmV?d00001