From e7b7c1a748ae2ce94e26d9362fa16bd1d9936503 Mon Sep 17 00:00:00 2001 From: Markus Isberg <3e849f2e5c@pm.me> Date: Fri, 3 Sep 2021 21:56:31 +0900 Subject: [PATCH] Unstable 0.1500.1.0 (BaroDev edition) --- .../ClientSource/Characters/CharacterInfo.cs | 1 + .../Characters/Health/AfflictionHusk.cs | 8 +- .../Characters/Health/CharacterHealth.cs | 723 ++++++------------ .../ClientSource/Characters/Limb.cs | 8 +- .../ClientSource/DebugConsole.cs | 8 +- .../ClientSource/GUI/GUIListBox.cs | 7 +- .../ClientSource/GUI/GUIProgressBar.cs | 6 +- .../ClientSource/GUI/TabMenu.cs | 22 +- .../ClientSource/GameSession/CrewManager.cs | 32 +- .../ClientSource/Items/CharacterInventory.cs | 46 +- .../Items/Components/GeneticMaterial.cs | 74 ++ .../Items/Components/ItemComponent.cs | 2 +- .../Items/Components/ItemContainer.cs | 3 + .../Components/Machines/Deconstructor.cs | 110 ++- .../Items/Components/Machines/MiniMap.cs | 74 +- .../Items/Components/RemoteController.cs | 22 + .../Items/Components/Signal/Connection.cs | 5 + .../Items/Components/Signal/Terminal.cs | 4 +- .../Items/Components/StatusHUD.cs | 92 ++- .../ClientSource/Items/Components/Wearable.cs | 2 +- .../ClientSource/Items/Inventory.cs | 15 +- .../ClientSource/Items/Item.cs | 9 +- .../ClientSource/Map/MapEntity.cs | 28 +- .../ClientSource/Map/Submarine.cs | 27 +- .../ClientSource/Particles/ParticleManager.cs | 2 +- .../ClientSource/Screens/NetLobbyScreen.cs | 1 + .../ClientSource/Screens/TestScreen.cs | 7 +- .../ClientSource/Sounds/SoundPlayer.cs | 3 +- .../ClientSource/Utils/SpreadsheetExport.cs | 4 +- .../BarotraumaClient/LinuxClient.csproj | 2 +- Barotrauma/BarotraumaClient/MacClient.csproj | 2 +- .../BarotraumaClient/WindowsClient.csproj | 2 +- .../BarotraumaServer/LinuxServer.csproj | 2 +- Barotrauma/BarotraumaServer/MacServer.csproj | 2 +- .../ServerSource/Characters/Character.cs | 9 + .../ServerSource/Characters/CharacterInfo.cs | 1 + .../GameModes/MultiPlayerCampaign.cs | 56 ++ .../Items/Components/GeneticMaterial.cs | 20 + .../Items/Components/Signal/Terminal.cs | 4 +- .../ServerSource/Networking/GameServer.cs | 6 + .../ServerSource/Networking/RespawnManager.cs | 6 + .../BarotraumaServer/WindowsServer.csproj | 2 +- .../Data/ContentPackages/Vanilla 0.9.xml | 3 + .../Characters/AI/EnemyAIController.cs | 12 +- .../AI/Objectives/AIObjectiveCombat.cs | 5 +- .../Characters/Animation/AnimController.cs | 2 +- .../Animation/FishAnimController.cs | 8 +- .../Animation/HumanoidAnimController.cs | 15 +- .../Characters/Animation/Ragdoll.cs | 6 + .../SharedSource/Characters/Attack.cs | 19 +- .../SharedSource/Characters/Character.cs | 43 +- .../SharedSource/Characters/CharacterInfo.cs | 33 +- .../Health/Afflictions/Affliction.cs | 64 +- .../Health/Afflictions/AfflictionHusk.cs | 12 +- .../Health/Afflictions/AfflictionPrefab.cs | 37 +- .../Characters/Health/CharacterHealth.cs | 72 +- .../SharedSource/Characters/Jobs/Job.cs | 4 +- .../SharedSource/Characters/Jobs/Skill.cs | 9 +- .../SharedSource/Characters/Limb.cs | 9 +- .../AbilityConditionAttackData.cs | 6 +- .../AbilityConditionAttackResult.cs | 2 +- .../AbilityConditionData.cs | 5 +- .../AbilityConditionHandsomeStranger.cs | 27 - .../AbilityConditionIsAiming.cs | 54 ++ .../AbilityConditionItem.cs | 5 +- .../AbilityConditionReduceAffliction.cs | 8 +- .../AbilityConditionSkill.cs | 32 + .../AbilityConditionAboveVitality.cs | 5 +- .../AbilityConditionCoauthor.cs | 26 + .../AbilityConditionDataless.cs | 6 +- .../AbilityConditionHasPermanentStat.cs | 23 + .../AbilityConditionHasStatusTag.cs | 31 + .../AbilityConditionInFriendlySubmarine.cs | 15 + .../AbilityConditionInHull.cs | 15 + .../AbilityConditionLevelsBehindHighest.cs | 20 + .../AbilityConditionMission.cs | 6 +- .../AbilityConditionServerRandom.cs | 8 +- .../Talents/Abilities/AbilityInterfaces.cs | 32 + .../Talents/Abilities/AbilityObjects.cs | 85 ++ .../Talents/Abilities/CharacterAbility.cs | 13 +- .../CharacterAbilityApplyStatusEffects.cs | 37 +- ...racterAbilityApplyStatusEffectsToAllies.cs | 30 + ...cterAbilityApplyStatusEffectsToAttacker.cs | 20 + ...rAbilityApplyStatusEffectsToNearestAlly.cs | 7 +- ...erAbilityApplyStatusEffectsToRandomAlly.cs | 7 +- .../Abilities/CharacterAbilityGiveMoney.cs | 29 +- .../CharacterAbilityGivePermanentStat.cs | 8 +- .../CharacterAbilityGiveResistance.cs | 13 +- .../Abilities/CharacterAbilityGiveStat.cs | 5 +- .../CharacterAbilityModifyAttackData.cs | 15 +- .../CharacterAbilityModifyResistance.cs | 9 +- .../CharacterAbilityModifyStatToSkill.cs | 52 ++ .../Abilities/CharacterAbilityModifyValue.cs | 31 +- .../CharacterAbilityResetPermanentStat.cs | 2 +- .../Abilities/CharacterAbilityRevive.cs | 29 + .../CharacterAbilityAlienHoarder.cs | 41 + .../CharacterAbilityApprenticeship.cs | 4 +- .../CharacterAbilityByTheBook.cs | 36 + .../CharacterAbilityInsurancePolicy.cs | 31 +- .../CharacterAbilityPsychoClown.cs | 6 +- .../CharacterAbilityRegenerateLoot.cs | 2 + .../CharacterAbilityStonewall.cs | 8 +- .../CharacterAbilityTandemFire.cs | 1 + .../AbilityGroups/CharacterAbilityGroup.cs | 6 +- .../CharacterAbilityGroupEffect.cs | 1 + .../CharacterAbilityGroupInterval.cs | 2 + .../Characters/Talents/CharacterTalent.cs | 3 +- .../Characters/Talents/TalentPrefab.cs | 57 +- .../Characters/Talents/TalentTree.cs | 32 +- .../SharedSource/DebugConsole.cs | 77 +- .../BarotraumaShared/SharedSource/Enums.cs | 19 +- .../SharedSource/Events/Missions/Mission.cs | 13 +- .../GameSession/GameModes/CampaignMode.cs | 1 + .../GameModes/MultiPlayerCampaign.cs | 6 + .../SharedSource/GameSession/GameSession.cs | 17 +- .../SharedSource/Items/CharacterInventory.cs | 2 +- .../Items/Components/GeneticMaterial.cs | 179 +++++ .../Items/Components/Holdable/MeleeWeapon.cs | 3 +- .../Items/Components/Holdable/RangedWeapon.cs | 4 +- .../Items/Components/ItemComponent.cs | 2 +- .../Items/Components/ItemContainer.cs | 213 ++++-- .../Components/Machines/Deconstructor.cs | 287 +++++-- .../Items/Components/Machines/Fabricator.cs | 23 +- .../Items/Components/Machines/Steering.cs | 5 +- .../Items/Components/Power/PowerTransfer.cs | 10 + .../Items/Components/RemoteController.cs | 96 +++ .../Items/Components/Repairable.cs | 2 +- .../Components/Signal/ConnectionPanel.cs | 36 +- .../Items/Components/Signal/Terminal.cs | 10 +- .../Items/Components/Signal/Wire.cs | 6 +- .../SharedSource/Items/Components/Turret.cs | 24 +- .../SharedSource/Items/Components/Wearable.cs | 3 + .../SharedSource/Items/Inventory.cs | 2 +- .../SharedSource/Items/Item.cs | 27 +- .../SharedSource/Items/ItemInventory.cs | 10 +- .../SharedSource/Items/ItemPrefab.cs | 21 +- .../SharedSource/Map/Explosion.cs | 15 +- .../SharedSource/Map/Levels/Level.cs | 5 +- .../SharedSource/Map/Structure.cs | 4 +- .../StatusEffects/StatusEffect.cs | 328 +++++--- .../SharedSource/TextManager.cs | 37 + .../BarotraumaShared/Submarines/Humpback.sub | Bin 207745 -> 207565 bytes Barotrauma/BarotraumaShared/changelog.txt | 37 + 143 files changed, 2928 insertions(+), 1356 deletions(-) create mode 100644 Barotrauma/BarotraumaClient/ClientSource/Items/Components/GeneticMaterial.cs create mode 100644 Barotrauma/BarotraumaClient/ClientSource/Items/Components/RemoteController.cs create mode 100644 Barotrauma/BarotraumaServer/ServerSource/Items/Components/GeneticMaterial.cs delete mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionHandsomeStranger.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionIsAiming.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionSkill.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionCoauthor.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasPermanentStat.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasStatusTag.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInFriendlySubmarine.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInHull.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionLevelsBehindHighest.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityInterfaces.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityObjects.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAllies.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAttacker.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyStatToSkill.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityRevive.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityAlienHoarder.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityByTheBook.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Items/Components/GeneticMaterial.cs create mode 100644 Barotrauma/BarotraumaShared/SharedSource/Items/Components/RemoteController.cs diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs index c27aab975..c5b38a31e 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/CharacterInfo.cs @@ -623,6 +623,7 @@ namespace Barotrauma bool removeOnDeath = inc.ReadBoolean(); ch.ChangeSavedStatValue((StatTypes)statType, statValue, statIdentifier, removeOnDeath); } + ch.ExperiencePoints = inc.ReadUInt16(); return ch; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/AfflictionHusk.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/AfflictionHusk.cs index 5835cd675..f4a5f282c 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/AfflictionHusk.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/AfflictionHusk.cs @@ -1,10 +1,4 @@ -using Microsoft.Xna.Framework; -using System.Collections.Generic; -using Barotrauma.IO; -using System.Linq; -using System.Xml.Linq; - -namespace Barotrauma +namespace Barotrauma { partial class AfflictionHusk : Affliction { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/CharacterHealth.cs index d7b75bbd3..73e11cd6a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/CharacterHealth.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/Health/CharacterHealth.cs @@ -30,7 +30,7 @@ namespace Barotrauma get { return alignment; } set { - if (alignment == value) return; + if (alignment == value) { return; } alignment = value; UpdateAlignment(); } @@ -48,108 +48,18 @@ namespace Barotrauma private float bloodParticleTimer; - // healing interface - private GUIFrame healthInterfaceFrame; - private GUIFrame healthWindow; private GUITextBlock deadIndicator; - private GUIComponent lowSkillIndicator; + //private GUIComponent lowSkillIndicator; - private GUILayoutGroup cprLayout; - private GUIFrame cprFrame; private GUIButton cprButton; private GUIListBox afflictionTooltip; private static readonly Color oxygenLowGrainColor = new Color(0.1f, 0.1f, 0.1f, 1f); - private struct HeartratePosition - { - public float Time; - public float Height; - - public HeartratePosition ScaleHeight(float scale) - { - return new HeartratePosition - { - Time = this.Time, - Height = this.Height * scale - }; - } - - public HeartratePosition ScaleTime(float scale) - { - return new HeartratePosition - { - Time = this.Time * scale, - Height = this.Height - }; - } - - public HeartratePosition AddTime(float time) - { - return new HeartratePosition - { - Time = this.Time + time, - Height = this.Height - }; - } - - public static IEnumerable ScaleAndDisplace(IEnumerable positions, float heightScale, float timeScale, float timeAdd) - { - HeartratePosition prevPos = new HeartratePosition - { - Time = 0.0f, - Height = 0.0f - }; - bool wrapped = false; - foreach (HeartratePosition pos in positions) - { - HeartratePosition newPos = pos.ScaleHeight(heightScale).ScaleTime(timeScale).AddTime(timeAdd); - if (newPos.Time > 1.0f) - { - if (!wrapped) - { - yield return new HeartratePosition - { - Time = 1.0f, - Height = (newPos.Height - prevPos.Height) / (newPos.Time - prevPos.Time) * (1.0f - prevPos.Time) + prevPos.Height - }; - yield return new HeartratePosition - { - Time = 0.0f, - Height = (newPos.Height - prevPos.Height) / (newPos.Time - prevPos.Time) * (1.0f - prevPos.Time) + prevPos.Height - }; - wrapped = true; - } - newPos.Time -= 1.0f; - } - prevPos = newPos; - yield return newPos; - } - } - } - private List heartratePositions; - private float currentHeartrateTime; - private float heartbeatTimer; - private static Texture2D heartrateFade; - - private readonly HeartratePosition[] heartbeatPattern = - { - new HeartratePosition() { Time = 0.0f, Height = 0.0f }, - new HeartratePosition() { Time = 0.15f, Height = 0.2f }, - new HeartratePosition() { Time = 0.2f, Height = -0.2f }, - new HeartratePosition() { Time = 0.36f, Height = 0.0f }, - new HeartratePosition() { Time = 0.43f, Height = 0.8f }, - new HeartratePosition() { Time = 0.57f, Height = -0.8f }, - new HeartratePosition() { Time = 0.64f, Height = 0.0f }, - new HeartratePosition() { Time = 0.8f, Height = 0.2f }, - new HeartratePosition() { Time = 0.85f, Height = -0.2f }, - new HeartratePosition() { Time = 1.0f, Height = 0.0f }, - }; - private SpriteSheet limbIndicatorOverlay; private float limbIndicatorOverlayAnimState; @@ -166,12 +76,9 @@ namespace Barotrauma private GUIProgressBar healthWindowHealthBarShadow; private GUITextBlock characterName; - private GUIFrame afflictionInfoFrame; private GUIListBox afflictionIconContainer; - private GUIListBox afflictionInfoContainer; private GUILayoutGroup treatmentLayout; private GUIListBox recommendedTreatmentContainer; - private GUITextBlock selectedLimbText; private float distortTimer; @@ -255,6 +162,12 @@ namespace Barotrauma get { return cprButton; } } + public GUIComponent InventorySlotContainer + { + get; + private set; + } + public float HealthBarPulsateTimer { get { return healthBarPulsateTimer; } @@ -279,56 +192,90 @@ namespace Barotrauma character.OnAttacked += OnAttacked; - bool horizontal = true; + healthWindow = new GUIFrame(new RectTransform(new Vector2(0.35f, 0.6f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "GUIFrameListBox"); - healthBarHolder = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas), style: null) + var healthWindowVerticalLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), healthWindow.RectTransform, Anchor.Center)) { - HoverCursor = CursorState.Hand + Stretch = true }; - healthBarHolder.RectTransform.AbsoluteOffset = HUDLayoutSettings.HealthBarArea.Location; - healthBarHolder.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarArea.Size; - healthBarHolder.RectTransform.RelativeOffset = Vector2.Zero; - - healthBarShadow = new GUIProgressBar(new RectTransform(Vector2.One, healthBarHolder.RectTransform, Anchor.BottomRight), - barSize: 1.0f, color: Color.Green, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical", showFrame: false) + var nameContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), healthWindowVerticalLayout.RectTransform) { MinSize = new Point(0, 20) }, isHorizontal: true) { - IsHorizontal = horizontal - }; - healthBarShadow.Visible = false; - healthShadowSize = 1.0f; - - healthBar = new GUIProgressBar(new RectTransform(Vector2.One, healthBarHolder.RectTransform, Anchor.BottomRight), - barSize: 1.0f, color: GUI.Style.HealthBarColorHigh, style: horizontal ? "CharacterHealthBar" : "GUIProgressBarVertical") - { - HoverCursor = CursorState.Hand, - ToolTip = TextManager.GetWithVariable("hudbutton.healthinterface", "[key]", GameMain.Config.KeyBindText(InputType.Health)), - Enabled = true, - IsHorizontal = horizontal + Stretch = true }; - healthInterfaceFrame = new GUIFrame(new RectTransform(new Vector2(0.7f, 0.55f), GUI.Canvas, anchor: Anchor.Center, scaleBasis: ScaleBasis.Smallest), style: "ItemUI"); + new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform, Anchor.CenterLeft), + onDraw: (spriteBatch, component) => + { + character.Info?.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), Vector2.Zero, component.Rect.Width, false, openHealthWindow?.Character != Character.Controlled); + }); + characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) + { + AutoScaleHorizontal = true + }; + new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform), + onDraw: (spriteBatch, component) => + { + character.Info?.DrawJobIcon(spriteBatch, component.Rect, openHealthWindow?.Character != Character.Controlled); + }); - var healthInterfaceLayout = new GUILayoutGroup(new RectTransform(Vector2.One / 1.05f, healthInterfaceFrame.RectTransform, anchor: Anchor.Center), true); - var healthWindowContainer = new GUIFrame(new RectTransform(new Vector2(0.45f, 1.0f), healthInterfaceLayout.RectTransform), style: null); + var healthBarContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.07f), healthWindowVerticalLayout.RectTransform), style: null); + var healthBarIcon = new GUIFrame(new RectTransform(new Vector2(0.095f, 1.0f), healthBarContainer.RectTransform), style: "GUIHealthBarIcon"); + healthWindowHealthBarShadow = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight), + barSize: 1.0f, color: GUI.Style.Green, style: "GUIHealthBar") + { + IsHorizontal = true + }; + healthWindowHealthBar = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight), + barSize: 1.0f, color: GUI.Style.Green, style: "GUIHealthBar") + { + IsHorizontal = true + }; - //limb selection frame - healthWindow = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), healthWindowContainer.RectTransform, Anchor.CenterRight, Pivot.CenterRight), style: "GUIFrameListBox"); + //spacing + new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), healthWindowVerticalLayout.RectTransform), style: null); - var healthWindowVerticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One * 0.95f, healthWindow.RectTransform, Anchor.Center)) + var characterIndicatorArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.95f), healthWindowVerticalLayout.RectTransform), isHorizontal: true) { Stretch = true, - RelativeSpacing = 0.03f + //RelativeSpacing = 0.05f }; - var paddedHealthWindow = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.95f), healthWindowVerticalLayout.RectTransform), isHorizontal: true) - { - Stretch = true, - RelativeSpacing = 0.03f - }; + InventorySlotContainer = new GUICustomComponent(new RectTransform(new Vector2(0.1f, 1.0f), characterIndicatorArea.RectTransform, Anchor.TopLeft, Pivot.TopRight), + (spriteBatch, component) => + { + for (int i = 0; i < character.Inventory.Capacity; i++) + { + if (character.Inventory.SlotTypes[i] != InvSlotType.HealthInterface || Character.Controlled != Character) { continue; } - var limbSelection = new GUICustomComponent(new RectTransform(new Vector2(0.6f, 1.0f), paddedHealthWindow.RectTransform), + //don't draw the item if it's being dragged out of the slot + bool drawItem = !Inventory.DraggingItems.Any() || !Character.Inventory.GetItemsAt(i).All(it => Inventory.DraggingItems.Contains(it)) || character.Inventory.visualSlots[i].MouseOn(); + + Inventory.DrawSlot(spriteBatch, Character.Inventory, Character.Inventory.visualSlots[i], Character.Inventory.GetItemAt(i), i, drawItem, Character.Inventory.SlotTypes[i]); + + if (medUIExtra != null) + { + float overlayScale = Math.Min( + Character.Inventory.visualSlots[i].Rect.Width / (float)medUIExtra.FrameSize.X, + Character.Inventory.visualSlots[i].Rect.Height / (float)medUIExtra.FrameSize.Y); + + int frame = (int)medUIExtraAnimState; + + medUIExtra.Draw(spriteBatch, frame, Character.Inventory.visualSlots[i].Rect.Center.ToVector2(), Color.Gray, origin: medUIExtra.FrameSize.ToVector2() / 2, rotate: 0.0f, + scale: Vector2.One * overlayScale); + } + } + }, + (dt, component) => + { + if (!GameMain.Instance.Paused) + { + medUIExtraAnimState = (medUIExtraAnimState + dt * 10.0f) % 16.0f; + } + }); + + var limbSelection = new GUICustomComponent(new RectTransform(new Vector2(0.4f, 1.0f), characterIndicatorArea.RectTransform), (spriteBatch, component) => { DrawHealthWindow(spriteBatch, component.RectTransform.Rect, true); @@ -353,149 +300,31 @@ namespace Barotrauma deadIndicator.AutoScaleHorizontal = true; } - var rightSide = new GUIFrame(new RectTransform(new Vector2(0.4f, 1.0f), paddedHealthWindow.RectTransform), style: null); + afflictionIconContainer = new GUIListBox(new RectTransform(new Vector2(0.25f, 0.7f), characterIndicatorArea.RectTransform), style: null); - new GUICustomComponent(new RectTransform(new Vector2(1.0f, 0.3f), rightSide.RectTransform, Anchor.BottomRight, Pivot.BottomRight), - (sb, component) => - { - if (medUIExtra == null) { return; } - float overlayScale = Math.Min( - component.Rect.Width / (float)medUIExtra.FrameSize.X, - component.Rect.Height / (float)medUIExtra.FrameSize.Y); + new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), healthWindowVerticalLayout.RectTransform), + TextManager.Get("SuitableTreatments"), font: GUI.SubHeadingFont, textAlignment: Alignment.BottomCenter); - int frame = (int)medUIExtraAnimState; - - medUIExtra.Draw(sb, frame, component.Rect.Center.ToVector2(), Color.Gray, origin: medUIExtra.FrameSize.ToVector2() / 2, rotate: 0.0f, - scale: Vector2.One * overlayScale); - }, - (dt, component) => - { - if (!GameMain.Instance.Paused) - { - medUIExtraAnimState = (medUIExtraAnimState + dt * 10.0f) % 16.0f; - } - }); - - GUILayoutGroup selectedLimbLayout = new GUILayoutGroup(new RectTransform(Vector2.One, rightSide.RectTransform)); - - selectedLimbText = new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.08f), selectedLimbLayout.RectTransform), "", font: GUI.SubHeadingFont, textAlignment: Alignment.Center) - { - AutoScaleHorizontal = true - }; - - afflictionIconContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.92f), selectedLimbLayout.RectTransform), style: null) - { - KeepSpaceForScrollBar = true - }; - - var healthBarContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.07f), healthWindowVerticalLayout.RectTransform), style: null); - - var healthBarIcon = new GUIFrame(new RectTransform(new Vector2(0.095f, 1.0f), healthBarContainer.RectTransform), style: "GUIHealthBarIcon"); - - healthWindowHealthBarShadow = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight), - barSize: 1.0f, color: GUI.Style.Green, style: "GUIHealthBar") - { - IsHorizontal = true - }; - healthWindowHealthBar = new GUIProgressBar(new RectTransform(new Vector2(0.91f, 1.0f), healthBarContainer.RectTransform, Anchor.CenterRight), - barSize: 1.0f, color: GUI.Style.Green, style: "GUIHealthBar") - { - IsHorizontal = true - }; - - //affliction info frame - afflictionInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.55f, 1.0f), healthInterfaceLayout.RectTransform), style: null); - var paddedInfoFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), afflictionInfoFrame.RectTransform, Anchor.Center), style: null); - - var infoLayout = new GUILayoutGroup(new RectTransform(Vector2.One, paddedInfoFrame.RectTransform)) - { - Stretch = true, - RelativeSpacing = 0.03f - }; - - var textContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), infoLayout.RectTransform), style: "GUIFrameListBox"); - - var textLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.98f), textContainer.RectTransform, Anchor.Center, Pivot.Center)) - { - Stretch = true, - RelativeSpacing = 0.03f, - CanBeFocused = true - }; - - textLayout.RectTransform.RelativeOffset = new Vector2(0, 0.025f); - - var nameContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), textLayout.RectTransform) { MinSize = new Point(0, 20) }, isHorizontal: true) - { - Stretch = true - }; - - new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform, Anchor.CenterLeft), - onDraw: (spriteBatch, component) => - { - character.Info?.DrawPortrait(spriteBatch, new Vector2(component.Rect.X, component.Rect.Center.Y - component.Rect.Width / 2), Vector2.Zero, component.Rect.Width, false, openHealthWindow?.Character != Character.Controlled); - }); - characterName = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f), nameContainer.RectTransform), "", textAlignment: Alignment.CenterLeft, font: GUI.SubHeadingFont) - { - AutoScaleHorizontal = true - }; - new GUICustomComponent(new RectTransform(new Vector2(0.2f, 1.0f), nameContainer.RectTransform), - onDraw: (spriteBatch, component) => - { - character.Info?.DrawJobIcon(spriteBatch, component.Rect, openHealthWindow?.Character != Character.Controlled); - }); - - - new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), textLayout.RectTransform), style: "HorizontalLine"); - - afflictionInfoContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.4f), textLayout.RectTransform, Anchor.TopLeft), style: null); - - new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), textLayout.RectTransform), style: "HorizontalLine"); - - new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), textLayout.RectTransform, Anchor.TopLeft), TextManager.Get("SuitableTreatments"), font: GUI.SubHeadingFont); - - treatmentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), textLayout.RectTransform), true) + treatmentLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), healthWindowVerticalLayout.RectTransform), true) { Stretch = false }; - recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(0.9f, 1.0f), treatmentLayout.RectTransform, Anchor.Center, Pivot.Center), isHorizontal: true, style: null) + recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(1.0f, 1.0f), treatmentLayout.RectTransform, Anchor.Center, Pivot.Center), isHorizontal: true, style: null) { - KeepSpaceForScrollBar = false + Spacing = GUI.IntScale(4), + KeepSpaceForScrollBar = false, + ScrollBarVisible = false, + AutoHideScrollBar = false + }; + new GUITextBlock(new RectTransform(Vector2.One, recommendedTreatmentContainer.Content.RectTransform), TextManager.Get("none"), textAlignment: Alignment.Center) + { + CanBeFocused = false }; - lowSkillIndicator = new GUIImage(new RectTransform(new Vector2(0.1f, 1.0f), treatmentLayout.RectTransform, Anchor.TopLeft, Pivot.Center), - style: "GUINotificationButton") - { - ToolTip = TextManager.Get("lowmedicalskillwarning"), - Color = GUI.Style.Orange, - HoverColor = Color.Lerp(GUI.Style.Orange, Color.White, 0.5f), - PressedColor = Color.Lerp(GUI.Style.Orange, Color.White, 0.5f), - Visible = false - }; - lowSkillIndicator.RectTransform.MaxSize = new Point(lowSkillIndicator.Rect.Height); + characterIndicatorArea.Recalculate(); - var tempFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.01f), textLayout.RectTransform), style: null); - - cprLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), infoLayout.RectTransform), true) - { - Stretch = true - }; - - cprFrame = new GUIFrame(new RectTransform(new Vector2(0.7f, 1.0f), cprLayout.RectTransform), style: "GUIFrameListBox"); - - heartrateFade ??= TextureLoader.FromFile("Content/UI/Health/HeartrateFade.png"); - - new GUICustomComponent(new RectTransform(Vector2.One * 0.95f, cprFrame.RectTransform, Anchor.Center), DrawHeartrate, UpdateHeartrate); - - heartbeatTimer = 0.46f; - - heartratePositions = new List - { - heartbeatPattern.First(), - heartbeatPattern.Last() - }; - - cprButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), cprLayout.RectTransform, scaleBasis: ScaleBasis.Smallest), text: "", style: "CPRButton") + cprButton = new GUIButton(new RectTransform(new Vector2(afflictionIconContainer.RectTransform.RelativeSize.X, 0.3f), characterIndicatorArea.RectTransform, Anchor.BottomRight, scaleBasis: ScaleBasis.Smallest), text: "", style: "CPRButton") { OnClicked = (button, userData) => { @@ -518,9 +347,34 @@ namespace Barotrauma return true; }, ToolTip = TextManager.Get("doctor.cprobjective"), + IgnoreLayoutGroups = true, Visible = false }; + healthBarHolder = new GUIFrame(new RectTransform(Point.Zero, GUI.Canvas), style: null) + { + HoverCursor = CursorState.Hand + }; + + healthBarHolder.RectTransform.AbsoluteOffset = HUDLayoutSettings.HealthBarArea.Location; + healthBarHolder.RectTransform.NonScaledSize = HUDLayoutSettings.HealthBarArea.Size; + healthBarHolder.RectTransform.RelativeOffset = Vector2.Zero; + + healthBarShadow = new GUIProgressBar(new RectTransform(Vector2.One, healthBarHolder.RectTransform, Anchor.BottomRight), + barSize: 1.0f, color: Color.Green, style: "CharacterHealthBar", showFrame: false) + { + Visible = false + }; + healthShadowSize = 1.0f; + + healthBar = new GUIProgressBar(new RectTransform(Vector2.One, healthBarHolder.RectTransform, Anchor.BottomRight), + barSize: 1.0f, color: GUI.Style.HealthBarColorHigh, style: "CharacterHealthBar") + { + HoverCursor = CursorState.Hand, + ToolTip = TextManager.GetWithVariable("hudbutton.healthinterface", "[key]", GameMain.Config.KeyBindText(InputType.Health)), + Enabled = true + }; + UpdateAlignment(); SuicideButton = new GUIButton(new RectTransform(new Vector2(0.1f, 0.02f), GUI.Canvas, Anchor.TopCenter) @@ -542,8 +396,8 @@ namespace Barotrauma } else { - var causeOfDeath = GetCauseOfDeath(); - Character.Controlled.Kill(causeOfDeath.type, causeOfDeath.affliction); + var (type, affliction) = GetCauseOfDeath(); + Character.Controlled.Kill(type, affliction); Character.Controlled = null; } } @@ -598,15 +452,15 @@ namespace Barotrauma switch (alignment) { case Alignment.Left: - healthInterfaceFrame.RectTransform.SetPosition(Anchor.BottomLeft); + healthWindow.RectTransform.SetPosition(Anchor.BottomLeft); break; case Alignment.Right: - healthInterfaceFrame.RectTransform.SetPosition(Anchor.BottomRight); + healthWindow.RectTransform.SetPosition(Anchor.BottomRight); break; } - healthInterfaceFrame.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.Padding, screenResolution.Y - HUDLayoutSettings.ChatBoxArea.Y + HUDLayoutSettings.Padding); - healthInterfaceFrame.RectTransform.RecalculateChildren(false); + healthWindow.RectTransform.AbsoluteOffset = new Point(HUDLayoutSettings.Padding, screenResolution.Y - HUDLayoutSettings.ChatBoxArea.Y + HUDLayoutSettings.Padding); + healthWindow.RectTransform.RecalculateChildren(false); } public void UpdateClientSpecific(float deltaTime) @@ -799,7 +653,8 @@ namespace Barotrauma if (afflictionGrainStrength > 0.0f) { grainStrength = Math.Max(grainStrength, affliction.GetScreenGrainStrength()); - grainColor = Color.Lerp(grainColor, Color.White, (float)Math.Pow(1.0f - oxygenLowStrength, 2)); + Color afflictionGrainColor = affliction.GetActiveEffect()?.GrainColor ?? Color.White; + grainColor = Color.Lerp(grainColor, afflictionGrainColor, (float)Math.Pow(1.0f - oxygenLowStrength, 2)); } } foreach (LimbHealth limbHealth in limbHealths) @@ -846,7 +701,7 @@ namespace Barotrauma } else if (openHealthWindow == this) { - if (HUD.CloseHUD(healthInterfaceFrame.Rect)) + if (HUD.CloseHUD(healthWindow.Rect)) { //emulate a Health input to get the character to deselect the item server-side if (GameMain.Client != null) @@ -856,6 +711,20 @@ namespace Barotrauma OpenHealthWindow = null; } + foreach (GUIComponent afflictionIcon in afflictionIconContainer.Content.Children) + { + if (!(afflictionIcon.UserData is Affliction affliction)) { continue; } + var btn = afflictionIcon.GetChild(); + if (affliction.AppliedAsFailedTreatmentTime > Timing.TotalTime - 1.0 && btn.FlashTimer <= 0.0f) + { + btn.Flash(GUI.Style.Red); + } + else if (affliction.AppliedAsSuccessfulTreatmentTime > Timing.TotalTime - 1.0 && btn.FlashTimer <= 0.0f) + { + btn.Flash(GUI.Style.Green); + } + } + if (GUI.MouseOn != null && GUI.MouseOn.UserData is string str && str == "selectaffliction") { Affliction affliction = GUI.MouseOn.Parent.UserData as Affliction; @@ -872,7 +741,17 @@ namespace Barotrauma int height = afflictionTooltip.Content.Children.Sum(c => c.Rect.Height) + 10; afflictionTooltip.RectTransform.Resize(new Point(afflictionTooltip.Rect.Width, height), true); - afflictionTooltip.RectTransform.AbsoluteOffset = new Point(GUI.MouseOn.Rect.Right, GUI.MouseOn.Rect.Y); + if (Alignment == Alignment.Right) + { + afflictionTooltip.RectTransform.AbsoluteOffset = new Point(GUI.MouseOn.Rect.X, GUI.MouseOn.Rect.Y); + afflictionTooltip.RectTransform.Pivot = Pivot.TopRight; + } + else + { + afflictionTooltip.RectTransform.AbsoluteOffset = new Point(GUI.MouseOn.Rect.Right, GUI.MouseOn.Rect.Y); + afflictionTooltip.RectTransform.Anchor = Anchor.TopLeft; + } + afflictionTooltip.ScrollBarVisible = false; var labelContainer = afflictionTooltip.Content.GetChildByUserData("label"); @@ -915,6 +794,13 @@ namespace Barotrauma UpdateAfflictionContainer(selectedLimb); currentDisplayedLimb = selectedLimb; } + + foreach (GUIComponent component in recommendedTreatmentContainer.Content.Children) + { + var treatmentButton = component.GetChild(); + if (!(treatmentButton?.UserData is ItemPrefab itemPrefab)) { continue; } + treatmentButton.Enabled = Character.Controlled.Inventory.AllItems.Any(it => it.prefab == itemPrefab); + } } if (Character.IsDead) @@ -953,16 +839,6 @@ namespace Barotrauma openHealthWindow = null; } - lowSkillIndicator.Visible = Character.Controlled != null && Character.Controlled.GetSkillLevel("medical") < 50.0f; - lowSkillIndicator.IgnoreLayoutGroups = !lowSkillIndicator.Visible; - - recommendedTreatmentContainer.RectTransform.Resize(new Vector2(0.9f, 1.0f)); - lowSkillIndicator.RectTransform.Resize(new Vector2(0.1f, 1.0f)); - - treatmentLayout.Recalculate(); - - lowSkillIndicator.Color = new Color(lowSkillIndicator.Color, MathHelper.Lerp(0.5f, 1.0f, (float)(Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) / 2.0f)); - if (Inventory.DraggingItems.Any()) { if (highlightedLimbIndex > -1) @@ -979,11 +855,6 @@ namespace Barotrauma draggingMed = null; } } - - /*if (GUI.MouseOn?.UserData is Affliction affliction) - { - ShowAfflictionInfo(affliction, afflictionInfoContainer); - }*/ } else { @@ -1038,17 +909,11 @@ namespace Barotrauma && !Character.IsDead && Character.IsKnockedDown && openHealthWindow == this; - cprButton.IgnoreLayoutGroups = !cprButton.Visible; cprButton.Selected = Character.Controlled != null && Character == Character.Controlled.SelectedCharacter && Character.Controlled.AnimController.Anim == AnimController.Animation.CPR; - cprFrame.RectTransform.Resize(new Vector2(0.7f, 1.0f)); - cprButton.RectTransform.Resize(new Vector2(1.0f, 1.0f)); - - cprLayout.Recalculate(); - deadIndicator.Visible = Character.IsDead; } @@ -1057,7 +922,7 @@ namespace Barotrauma if (GUI.DisableHUD) { return; } if (OpenHealthWindow == this) { - healthInterfaceFrame.AddToGUIUpdateList(); + healthWindow.AddToGUIUpdateList(); afflictionTooltip?.AddToGUIUpdateList(); } else if (Character.Controlled == Character && !CharacterHUD.IsCampaignInterfaceOpen) @@ -1114,22 +979,22 @@ namespace Barotrauma } - private Pair highlightedAfflictionIcon = null; + private (Affliction affliction, string text)? highlightedAfflictionIcon; public void DrawStatusHUD(SpriteBatch spriteBatch) { highlightedAfflictionIcon = null; //Rectangle interactArea = healthBar.Rect; if (Character.Controlled?.SelectedCharacter == null && openHealthWindow == null) { - List> statusIcons = new List>(); + List<(Affliction affliction, string text)> statusIcons = new List<(Affliction affliction, string text)>(); if (Character.CurrentHull == null || Character.CurrentHull.LethalPressure > 5.0f) - statusIcons.Add(new Pair(pressureAffliction, TextManager.Get("PressureHUDWarning"))); + statusIcons.Add((pressureAffliction, TextManager.Get("PressureHUDWarning"))); if (Character.CurrentHull != null && Character.OxygenAvailable < LowOxygenThreshold && oxygenLowAffliction.Strength < oxygenLowAffliction.Prefab.ShowIconThreshold) - statusIcons.Add(new Pair(oxygenLowAffliction, TextManager.Get("OxygenHUDWarning"))); + statusIcons.Add((oxygenLowAffliction, TextManager.Get("OxygenHUDWarning"))); foreach (Affliction affliction in currentDisplayedAfflictions) { - statusIcons.Add(new Pair(affliction, affliction.Prefab.Name)); + statusIcons.Add((affliction, affliction.Prefab.Name)); } Vector2 highlightedIconPos = Vector2.Zero; @@ -1146,9 +1011,9 @@ namespace Barotrauma Point pos = new Point(afflictionArea.Right - iconSize, afflictionArea.Top); - foreach (Pair statusIcon in statusIcons) + foreach (var statusIcon in statusIcons) { - Affliction affliction = statusIcon.First; + Affliction affliction = statusIcon.affliction; AfflictionPrefab afflictionPrefab = affliction.Prefab; Rectangle afflictionIconRect = new Rectangle(pos, new Point(iconSize)); @@ -1168,12 +1033,6 @@ namespace Barotrauma GUI.Style.Red * (float)((Math.Sin(affliction.DamagePerSecondTimer * MathHelper.TwoPi - MathHelper.PiOver2) + 1.0f) * 0.5f)); } - /*var slot = GUI.Style.GetComponentStyle("AfflictionIconSlot"); - slot.Sprites[highlightedIcon == statusIcon ? GUIComponent.ComponentState.Hover : GUIComponent.ComponentState.None][0].Draw( - spriteBatch, afflictionIconRect, - highlightedIcon == statusIcon ? slot.HoverColor : slot.Color);*/ - - float alphaMultiplier = highlightedAfflictionIcon == statusIcon ? 1f : 0.8f; afflictionPrefab.Icon?.Draw(spriteBatch, @@ -1191,7 +1050,7 @@ namespace Barotrauma if (highlightedAfflictionIcon != null) { - string nameTooltip = highlightedAfflictionIcon.Second; + string nameTooltip = highlightedAfflictionIcon.Value.text; Vector2 offset = GUI.Font.MeasureString(nameTooltip); GUI.DrawString(spriteBatch, @@ -1258,8 +1117,6 @@ namespace Barotrauma private void UpdateAfflictionContainer(LimbHealth selectedLimb) { - selectedLimbText.Text = selectedLimb == null ? "" : selectedLimb.Name; - if (selectedLimb == null) { afflictionIconContainer.Content.ClearChildren(); @@ -1279,28 +1136,30 @@ namespace Barotrauma private void CreateAfflictionInfos(IEnumerable afflictions) { afflictionIconContainer.ClearChildren(); - afflictionInfoContainer.ClearChildren(); - afflictionInfoContainer.UserData = null; recommendedTreatmentContainer.Content.ClearChildren(); float characterSkillLevel = Character.Controlled == null ? 0.0f : Character.Controlled.GetSkillLevel("medical"); - //random variance is 200% when the skill is 0 - //no random variance if the skill is 50 or more - float randomVariance = MathHelper.Lerp(2.0f, 0.0f, characterSkillLevel / 50.0f); - //key = item identifier //float = suitability Dictionary treatmentSuitability = new Dictionary(); - GetSuitableTreatments(treatmentSuitability, normalize: true, randomization: randomVariance); + GetSuitableTreatments(treatmentSuitability, normalize: true, limb: selectedLimbIndex == -1 ? null : Character.AnimController.Limbs.Find(l => l.HealthIndex == selectedLimbIndex)); + + foreach (string treatment in treatmentSuitability.Keys.ToList()) + { + //prefer suggestions for items the player has + if (Character.Controlled.Inventory.FindItemByIdentifier(treatment) != null) + { + treatmentSuitability[treatment] *= 10.0f; + } + } - //Affliction mostSevereAffliction = afflictions.FirstOrDefault(a => !a.Prefab.IsBuff && !afflictions.Any(a2 => !a2.Prefab.IsBuff && a2.Strength > a.Strength)) ?? afflictions.FirstOrDefault(); Affliction mostSevereAffliction = SortAfflictionsBySeverity(afflictions).FirstOrDefault(); GUIButton buttonToSelect = null; foreach (Affliction affliction in afflictions) { - var child = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), afflictionIconContainer.Content.RectTransform, Anchor.TopCenter)) + var child = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), afflictionIconContainer.Content.RectTransform, Anchor.TopCenter)) { Stretch = true, UserData = affliction @@ -1345,8 +1204,9 @@ namespace Barotrauma var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), child.RectTransform), affliction.Prefab.Name, font: GUI.SmallFont, textAlignment: Alignment.Center, style: "GUIToolTip"); nameText.Text = ToolBox.LimitString(nameText.Text, nameText.Font, nameText.Rect.Width); + nameText.RectTransform.MinSize = new Point(0, (int)(nameText.TextSize.Y * 1.25f)); - new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.1f), child.RectTransform), 0.0f, afflictionEffectColor, style: "GUIAfflictionBar") + new GUIProgressBar(new RectTransform(new Vector2(1.0f, 0.15f), child.RectTransform), 0.0f, afflictionEffectColor, style: "GUIAfflictionBar") { UserData = "afflictionstrength" }; @@ -1354,6 +1214,21 @@ namespace Barotrauma child.Recalculate(); } + if (!treatmentSuitability.Any()) + { + new GUITextBlock(new RectTransform(Vector2.One, recommendedTreatmentContainer.Content.RectTransform), TextManager.Get("none"), textAlignment: Alignment.Center) + { + CanBeFocused = false + }; + recommendedTreatmentContainer.ScrollBarVisible = false; + recommendedTreatmentContainer.AutoHideScrollBar = false; + } + else + { + recommendedTreatmentContainer.ScrollBarVisible = true; + recommendedTreatmentContainer.AutoHideScrollBar = true; + } + buttonToSelect?.OnClicked(buttonToSelect, "selectaffliction"); afflictionIconContainer.RecalculateChildren(); @@ -1367,15 +1242,25 @@ namespace Barotrauma if (count > 5) { break; } if (!(MapEntityPrefab.Find(name: null, identifier: treatment.Key, showErrorMessages: false) is ItemPrefab item)) { continue; } - var itemSlot = new GUIFrame(new RectTransform(new Vector2(1.0f / 7.0f, 1.0f), recommendedTreatmentContainer.Content.RectTransform, Anchor.TopLeft), + var itemSlot = new GUIFrame(new RectTransform(new Vector2(1.0f / 6.0f, 1.0f), recommendedTreatmentContainer.Content.RectTransform, Anchor.TopLeft), style: null) { UserData = item }; - var innerFrame = new GUIFrame(new RectTransform(Vector2.One, itemSlot.RectTransform, Anchor.Center, Pivot.Center, scaleBasis: ScaleBasis.Smallest), style: "GUIFrameListBox") + var innerFrame = new GUIButton(new RectTransform(Vector2.One, itemSlot.RectTransform, Anchor.Center, Pivot.Center, scaleBasis: ScaleBasis.Smallest), style: "GUIButtonRound") { - CanBeFocused = false + UserData = item, + ToolTip = $"‖color:255,255,255,255‖{item.Name}‖color:end‖" + '\n' + item.Description, + OnClicked = (btn, userdata) => + { + if (!(userdata is ItemPrefab itemPrefab)) { return false; } + var item = Character.Controlled.Inventory.AllItems.FirstOrDefault(it => it.prefab == itemPrefab); + if (item == null) { return false; } + Limb targetLimb = Character.AnimController.Limbs.FirstOrDefault(l => l.HealthIndex == selectedLimbIndex); + item.ApplyTreatment(Character.Controlled, Character, targetLimb); + return true; + } }; Sprite itemSprite = item.InventoryIcon ?? item.sprite; Color itemColor = itemSprite == item.sprite ? item.SpriteColor : item.InventoryIconColor; @@ -1383,11 +1268,11 @@ namespace Barotrauma itemSprite, scaleToFit: true) { CanBeFocused = false, - Color = itemColor, + Color = itemColor * 0.9f, HoverColor = itemColor, - SelectedColor = itemColor + SelectedColor = itemColor, + DisabledColor = itemColor * 0.7f }; - itemSlot.ToolTip = item.Name; } recommendedTreatmentContainer.RecalculateChildren(); @@ -1399,11 +1284,6 @@ namespace Barotrauma int dmgPerSecond = Math.Sign(second.DamagePerSecond - first.DamagePerSecond); return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(second.Strength - first.Strength); }); - - //afflictionIconContainer.Content.RectTransform.SortChildren((r1, r2) => - //{ - // return Math.Sign(((Affliction)r2.GUIComponent.UserData).GetVitalityDecrease(this) - ((Affliction)r1.GUIComponent.UserData).GetVitalityDecrease(this)); - //}); } private void CreateAfflictionInfoElements(GUIComponent parent, Affliction affliction) @@ -1460,7 +1340,6 @@ namespace Barotrauma affliction.Strength / affliction.Prefab.MaxStrength); description.RectTransform.Resize(new Point(description.Rect.Width, (int)(description.TextSize.Y + 10))); - //labelContainer.Recalculate(); int vitalityDecrease = (int)affliction.GetVitalityDecrease(this); if (vitalityDecrease == 0) @@ -1480,21 +1359,7 @@ namespace Barotrauma private bool SelectAffliction(GUIButton button, object userData) { - Affliction affliction = button.Parent.UserData as Affliction; - bool selected = button.Selected; - - afflictionInfoContainer.UserData = null; - afflictionInfoContainer.ClearChildren(); - if (!selected) - { - afflictionInfoContainer.UserData = affliction; - - CreateAfflictionInfoElements(afflictionInfoContainer.Content, affliction); - - afflictionInfoContainer.RecalculateChildren(); - } - foreach (var child in afflictionIconContainer.Content.Children) { GUIButton btn = child.GetChild(); @@ -1507,126 +1372,6 @@ namespace Barotrauma return false; } - private void UpdateHeartrate(float deltaTime, GUICustomComponent component) - { - if (GameMain.Instance.Paused) { return; } - - heartbeatTimer -= deltaTime * 0.5f; - - if (heartbeatTimer <= 0.0f) - { - while (heartbeatTimer <= 0.0f) { heartbeatTimer += 0.5f; } - - IEnumerable newPositions; - if (Character == null || Character.IsDead || Character.IsUnconscious) - { - newPositions = Enumerable.Repeat(new HeartratePosition { Time = currentHeartrateTime, Height = 0.0f }, 1); - } - else - { - newPositions = HeartratePosition.ScaleAndDisplace(heartbeatPattern, 1.0f, 0.1f, currentHeartrateTime); - } - - float visibleRangeStart = currentHeartrateTime - 0.35f; - if (visibleRangeStart < 0.0f) - { - visibleRangeStart += 1.0f; - } - heartratePositions.RemoveAll(hp => (hp.Time < visibleRangeStart || hp.Time > currentHeartrateTime) && - ((hp.Time < visibleRangeStart && hp.Time > currentHeartrateTime) || visibleRangeStart < currentHeartrateTime)); - - heartratePositions.AddRange(newPositions); - - if (!heartratePositions.Any(hp => hp.Time >= 1.0f)) - { - heartratePositions.Add(new HeartratePosition { Time = 1.0f, Height = 0.0f }); - } - if (!heartratePositions.Any(hp => hp.Time <= 0.0f)) - { - heartratePositions.Add(new HeartratePosition { Time = 0.0f, Height = 0.0f }); - } - } - - currentHeartrateTime += deltaTime * 0.5f; - while (currentHeartrateTime >= 1.0f) - { - currentHeartrateTime -= 1.0f; - } - } - - private void DrawHeartrate(SpriteBatch spriteBatch, GUICustomComponent component) - { - Rectangle targetRect = component.Parent.Rect; - targetRect.Location += new Point(6, 6); - targetRect.Size -= new Point(12, 12); - - //GUI.DrawRectangle(spriteBatch, targetRect, Color.Black, true); - - bool first = true; - Vector2 prevPos = Vector2.Zero; - foreach (var heartratePosition in heartratePositions.OrderBy(hp => hp.Time)) - { - Vector2 pos = new Vector2(heartratePosition.Time, -heartratePosition.Height * 0.5f + 0.5f) * targetRect.Size.ToVector2() + targetRect.Location.ToVector2(); - - if (pos.X < targetRect.Left + 1) { pos.X = targetRect.Left + 1; } - if (pos.X > targetRect.Right - 1) { pos.X = targetRect.Right - 1; } - - if (first) - { - first = false; - } - else - { - int thickness = (int)(GUI.Scale * 2.5f); - if (thickness < 1) { thickness = 1; } - GUI.DrawLine(spriteBatch, prevPos, pos, Color.Lime, 0, thickness); - GUI.DrawLine(spriteBatch, prevPos + new Vector2(0.0f, 1.0f), pos + new Vector2(0.0f, 1.0f), Color.Lime * 0.5f, 0, thickness); - GUI.DrawLine(spriteBatch, prevPos - new Vector2(0.0f, 1.0f), pos - new Vector2(0.0f, 1.0f), Color.Lime * 0.5f, 0, thickness); - } - - prevPos = pos; - } - - Rectangle sourceRect = heartrateFade.Bounds; - - Rectangle destinationRectangle = new Rectangle( - new Point((int)(currentHeartrateTime * targetRect.Width) + targetRect.Left - targetRect.Height, targetRect.Top), - new Point((int)(targetRect.Height * ((float)sourceRect.Width / (float)sourceRect.Height)), targetRect.Height)); - - if (destinationRectangle.Left < targetRect.Left) - { - Rectangle destinationRectangle2 = new Rectangle(); - destinationRectangle2.Location = new Point(targetRect.Right - (targetRect.Left - destinationRectangle.Left), targetRect.Top); - destinationRectangle2.Size = new Point(targetRect.Right - destinationRectangle2.Left, targetRect.Height); - - int originalWidth = sourceRect.Width; - sourceRect.Width = (int)(sourceRect.Width * ((float)(destinationRectangle.Right - targetRect.Left) / (float)targetRect.Height)); - sourceRect.X += originalWidth - sourceRect.Width; - - Rectangle sourceRect2 = heartrateFade.Bounds; - sourceRect2.Width -= sourceRect.Width; - spriteBatch.Draw(heartrateFade, destinationRectangle2, sourceRect2, Color.White); - - originalWidth = destinationRectangle.Width; - int newWidth = destinationRectangle.Right - targetRect.Left; - - destinationRectangle.Size = new Point(newWidth, targetRect.Height); - destinationRectangle.X += originalWidth - newWidth; - - GUI.DrawRectangle(spriteBatch, new Rectangle(destinationRectangle.Right, destinationRectangle.Top, - destinationRectangle2.Left - destinationRectangle.Right, destinationRectangle2.Height), Color.Black, true); - } - else - { - GUI.DrawRectangle(spriteBatch, new Rectangle(destinationRectangle.Right, destinationRectangle.Top, - targetRect.Right - destinationRectangle.Right, destinationRectangle.Height), Color.Black, true); - GUI.DrawRectangle(spriteBatch, new Rectangle(targetRect.Left, destinationRectangle.Top, - destinationRectangle.Left - targetRect.Left, destinationRectangle.Height), Color.Black, true); - } - - spriteBatch.Draw(heartrateFade, destinationRectangle, sourceRect, Color.White); - } - private void UpdateAfflictionInfos(IEnumerable afflictions) { foreach (Affliction affliction in afflictions) @@ -1634,12 +1379,6 @@ namespace Barotrauma var child = afflictionIconContainer.Content.FindChild(affliction); var afflictionStrengthBar = child.GetChildByUserData("afflictionstrength") as GUIProgressBar; afflictionStrengthBar.BarSize = affliction.Strength / affliction.Prefab.MaxStrength; - - if (afflictionInfoContainer.UserData == affliction) - { - UpdateAfflictionInfo(afflictionInfoContainer.Content, affliction); - } - if (afflictionTooltip != null && afflictionTooltip.UserData == affliction) { UpdateAfflictionInfo(afflictionTooltip.Content, affliction); @@ -1678,8 +1417,7 @@ namespace Barotrauma { //items can be dropped outside the health window if (!ignoreMousePos && - !healthWindow.Rect.Contains(PlayerInput.MousePosition) && - !afflictionInfoFrame.Rect.Contains(PlayerInput.MousePosition)) + !healthWindow.Rect.Contains(PlayerInput.MousePosition) ) { return false; } @@ -1701,35 +1439,6 @@ namespace Barotrauma return true; } - - private List GetAvailableMedicalItems() - { - List allInventoryItems = new List(); - allInventoryItems.AddRange(Character.Inventory.AllItems); - if (Character.SelectedCharacter?.Inventory != null && Character.CanAccessInventory(Character.SelectedCharacter.Inventory)) - { - allInventoryItems.AddRange(Character.SelectedCharacter.Inventory.AllItems); - } - if (Character.SelectedBy?.Inventory != null) - { - allInventoryItems.AddRange(Character.SelectedBy.Inventory.AllItems); - } - List medicalItems = new List(); - foreach (Item item in allInventoryItems) - { - foreach (Item containedItem in item.ContainedItems) - { - if (!containedItem.HasTag("medical") && !containedItem.HasTag("chem")) { continue; } - medicalItems.Add(containedItem); - } - - if (!item.HasTag("medical") && !item.HasTag("chem")) { continue; } - medicalItems.Add(item); - } - - return medicalItems.Distinct().ToList(); - } - private void UpdateLimbIndicators(float deltaTime, Rectangle drawArea) { if (!GameMain.Instance.Paused) @@ -1757,10 +1466,6 @@ namespace Barotrauma if (PlayerInput.PrimaryMouseButtonClicked() && highlightedLimbIndex > -1) { selectedLimbIndex = highlightedLimbIndex; - //afflictionContainer.ClearChildren(); - afflictionIconContainer.ClearChildren(); - afflictionInfoContainer.ClearChildren(); - afflictionInfoContainer.UserData = null; } } @@ -1931,14 +1636,14 @@ namespace Barotrauma i++; } - if (selectedLimbIndex > -1 && selectedLimbText != null) + if (selectedLimbIndex > -1 && afflictionIconContainer.Content.CountChildren > 0) { LimbHealth limbHealth = limbHealths[selectedLimbIndex]; if (limbHealth?.IndicatorSprite != null) { Rectangle selectedLimbArea = GetLimbHighlightArea(limbHealth, drawArea); GUI.DrawLine(spriteBatch, - new Vector2(selectedLimbText.Rect.X, selectedLimbText.Rect.Center.Y), + new Vector2(afflictionIconContainer.Rect.X, afflictionIconContainer.Rect.Y), selectedLimbArea.Center.ToVector2(), Color.LightGray * 0.5f, width: 4); } @@ -1954,7 +1659,7 @@ namespace Barotrauma private void DrawLimbAfflictionIcon(SpriteBatch spriteBatch, Affliction affliction, float iconScale, ref Vector2 iconPos) { - if (!affliction.ShouldShowIcon(Character)) { return; } + if (!affliction.ShouldShowIcon(Character) || affliction.Prefab.Icon == null) { return; } Vector2 iconSize = affliction.Prefab.Icon.size * iconScale; float showIconThreshold = Character.Controlled?.CharacterHealth == this ? affliction.Prefab.ShowIconThreshold : affliction.Prefab.ShowIconToOthersThreshold; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs b/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs index f4c76ac1f..c9c4d7300 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Characters/Limb.cs @@ -632,7 +632,7 @@ namespace Barotrauma RefreshDeformations(); } - public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null) + public void Draw(SpriteBatch spriteBatch, Camera cam, Color? overrideColor = null, bool disableDeformations = false) { float brightness = 1.0f - (burnOverLayStrength / 100.0f) * 0.5f; var spriteParams = Params.GetSprite(); @@ -678,7 +678,7 @@ namespace Barotrauma if (!hideLimb) { var deformSprite = DeformSprite; - if (deformSprite != null) + if (deformSprite != null && !disableDeformations) { if (ActiveDeformations.Any()) { @@ -999,10 +999,12 @@ namespace Barotrauma } float textureScale = wearable.InheritTextureScale ? TextureScale : wearable.Scale; + float rotation = -body.DrawRotation - wearable.Rotation * Dir; + wearable.Sprite.Draw(spriteBatch, new Vector2(body.DrawPosition.X, -body.DrawPosition.Y), new Color((color.R * wearableColor.R) / (255.0f * 255.0f), (color.G * wearableColor.G) / (255.0f * 255.0f), (color.B * wearableColor.B) / (255.0f * 255.0f)) * ((color.A * wearableColor.A) / (255.0f * 255.0f)), - origin, -body.DrawRotation, + origin, rotation, Scale * textureScale, spriteEffect, depth); } diff --git a/Barotrauma/BarotraumaClient/ClientSource/DebugConsole.cs b/Barotrauma/BarotraumaClient/ClientSource/DebugConsole.cs index 69c8a1836..d8cb533ed 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/DebugConsole.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/DebugConsole.cs @@ -1320,11 +1320,13 @@ namespace Barotrauma continue; } + float avgOutCondition = (deconstructItem.OutConditionMin + deconstructItem.OutConditionMax) / 2; + int? deconstructProductPrice = targetItem.GetMinPrice(); if (deconstructProductPrice.HasValue) { if (!deconstructProductCost.HasValue) { deconstructProductCost = 0; } - deconstructProductCost += (int)(deconstructProductPrice * deconstructItem.OutCondition); + deconstructProductCost += (int)(deconstructProductPrice * avgOutCondition); } if (fabricationRecipe != null) @@ -1334,9 +1336,9 @@ namespace Barotrauma { NewMessage("Deconstructing \"" + itemPrefab.Name + "\" produces \"" + deconstructItem.ItemIdentifier + "\", which isn't required in the fabrication recipe of the item.", Color.Red); } - else if (ingredient.UseCondition && ingredient.MinCondition < deconstructItem.OutCondition) + else if (ingredient.UseCondition && ingredient.MinCondition < avgOutCondition) { - NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {targetItem.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(deconstructItem.OutCondition * 100)}%)", Color.Red); + NewMessage($"Deconstructing \"{itemPrefab.Name}\" produces more \"{deconstructItem.ItemIdentifier}\", than what's required to fabricate the item (required: {targetItem.Name} {(int)(ingredient.MinCondition * 100)}%, output: {deconstructItem.ItemIdentifier} {(int)(avgOutCondition * 100)}%)", Color.Red); } } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs index ff2d3c4a7..2d0e44691 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIListBox.cs @@ -251,6 +251,11 @@ namespace Barotrauma private readonly bool isHorizontal; + /// + /// Setting this to true and CanBeFocused to false allows the list background to be unfocusable while the elements can still be interacted with. + /// + public bool CanInteractWhenUnfocusable { get; set; } = false; + /// For horizontal listbox, default side is on the bottom. For vertical, it's on the right. public GUIListBox(RectTransform rectT, bool isHorizontal = false, Color? color = null, string style = "", bool isScrollBarOnDefaultSide = true, bool useMouseDownToSelect = false) : base(style, rectT) { @@ -570,7 +575,7 @@ namespace Barotrauma if (child == null || !child.Visible) { continue; } // selecting - if (Enabled && CanBeFocused && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child)) + if (Enabled && (CanBeFocused || CanInteractWhenUnfocusable) && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child)) { child.State = ComponentState.Hover; diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIProgressBar.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIProgressBar.cs index 0c373187d..33f42b55d 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIProgressBar.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/GUIProgressBar.cs @@ -79,14 +79,14 @@ namespace Barotrauma new Rectangle( sliderArea.X + (int)sliceBorderSizes.X, sliderArea.Y, - (int)((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount), + (int)Math.Round((sliderArea.Width - sliceBorderSizes.X - sliceBorderSizes.Z) * fillAmount), sliderArea.Height) : new Rectangle( sliderArea.X, - (int)(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W), + (int)Math.Round(sliderArea.Bottom - (sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount - sliceBorderSizes.W), sliderArea.Width, - (int)((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount)); + (int)Math.Round((sliderArea.Height - sliceBorderSizes.Y - sliceBorderSizes.W) * fillAmount)); sliderRect.Width = Math.Max(sliderRect.Width, 1); sliderRect.Height = Math.Max(sliderRect.Height, 1); diff --git a/Barotrauma/BarotraumaClient/ClientSource/GUI/TabMenu.cs b/Barotrauma/BarotraumaClient/ClientSource/GUI/TabMenu.cs index 57c248466..70c0e9f76 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GUI/TabMenu.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GUI/TabMenu.cs @@ -1219,7 +1219,11 @@ namespace Barotrauma GUIFrame characterInfoFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.3f), talentInfoLayoutGroup.RectTransform, Anchor.TopLeft), style: null); GUILayoutGroup characterInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), characterInfoFrame.RectTransform, anchor: Anchor.TopLeft), childAnchor: Anchor.TopLeft, isHorizontal: true); - CreateCharacterSheet(characterInfoColumn); + // move to a different tab menu + if (GameSettings.VerboseLogging) + { + CreateCharacterSheet(characterInfoColumn); + } if (!TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree)) { return; } @@ -1254,7 +1258,7 @@ namespace Barotrauma Stretch = true, }; - foreach (Talent talent in talentOption.Talents) + foreach (TalentPrefab talent in talentOption.Talents) { int optionPadding = GUI.IntScale(10); GUIFrame talentFrame = new GUIFrame(new RectTransform(new Point(talentOptionFrame.Rect.Width, talentOptionFrame.Rect.Height - optionPadding), talentOptionLayoutGroup.RectTransform), style: null) @@ -1269,13 +1273,13 @@ namespace Barotrauma GUIButton talentButton = new GUIButton(new RectTransform(Vector2.One, talentFrame.RectTransform, anchor: Anchor.Center), style: "TalentFrame") { - ToolTip = $"{TextManager.Get("talentname." + talent.Identifier, returnNull: true) ?? talent.Identifier} \n\n{TextManager.Get("talentdescription." + talent.Identifier, returnNull: true) ?? string.Empty}", + ToolTip = $"{talent.DisplayName}\n\n{talent.Description}", UserData = talent.Identifier, PressedColor = pressedColor, OnClicked = (button, userData) => { - talentTitleText.Text = TextManager.Get("talentname." + talent.Identifier, returnNull: true) ?? string.Empty; - talentDescriptionText.Text = TextManager.Get("talentdescription." + talent.Identifier, returnNull: true) ?? string.Empty; + talentTitleText.Text = talent.DisplayName; + talentDescriptionText.Text = talent.Description; // deselect other buttons in tier by removing their selected talents from pool foreach (GUIButton guiButton in talentOptionLayoutGroup.GetAllChildren()) @@ -1440,10 +1444,10 @@ namespace Barotrauma private readonly StatTypes[] combatStats = new StatTypes[] { - StatTypes.MaximumHealthMultiplier, - StatTypes.MovementSpeed, - StatTypes.SwimmingSpeed, - StatTypes.RepairSpeed, + StatTypes.MeleeAttackMultiplier, + StatTypes.MeleeAttackSpeed, + StatTypes.RangedAttackSpeed, + StatTypes.TurretAttackSpeed, }; private readonly StatTypes[] miscStats = new StatTypes[] diff --git a/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs index ac4b7ed69..520e873f5 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/GameSession/CrewManager.cs @@ -99,7 +99,9 @@ namespace Barotrauma crewList = new GUIListBox(new RectTransform(Vector2.One, crewArea.RectTransform), style: null, isScrollBarOnDefaultSide: false) { AutoHideScrollBar = false, + CanBeFocused = false, CanDragElements = true, + CanInteractWhenUnfocusable = true, OnSelected = (component, userData) => false, SelectMultiple = false, Spacing = (int)(GUI.Scale * 10), @@ -770,7 +772,7 @@ namespace Barotrauma if (IsSinglePlayer) { character.SetOrder(order, option, priority, orderGiver, speak: orderGiver != character); - string message = order?.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority); + string message = order?.GetChatMessage(character.Name, orderGiver?.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option, priority: priority); orderGiver?.Speak(message); } else if (orderGiver != null) @@ -1905,13 +1907,23 @@ namespace Barotrauma } } - private bool CanSomeoneHearCharacter() + private bool CanCharacterBeHeard() { #if DEBUG if (Character.Controlled == null) { return true; } #endif - return Character.Controlled != null && - (characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled))); + if (Character.Controlled != null) + { + if (characterContext == null) + { + return characters.Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)) || GetOrderableFriendlyNPCs().Any(c => c != Character.Controlled && c.CanHearCharacter(Character.Controlled)); + } + else + { + return characterContext.CanHearCharacter(Character.Controlled); + } + } + return false; } private Entity FindEntityContext() @@ -2580,7 +2592,7 @@ namespace Barotrauma for (int i = 0; i < orders.Count; i++) { order = orders[i]; - disableNode = !CanSomeoneHearCharacter() || + disableNode = !CanCharacterBeHeard() || (order.MustSetTarget && (order.ItemComponentType != null || order.TargetItems.Length > 0) && order.GetMatchingItems(true, interactableFor: characterContext ?? Character.Controlled).None()); optionNodes.Add(new Tuple( @@ -2728,7 +2740,7 @@ namespace Barotrauma } var offsets = MathUtils.GetPointsOnCircumference(Vector2.Zero, nodeDistance, contextualOrders.Count, MathHelper.ToRadians(90f + 180f / contextualOrders.Count)); - bool disableNode = !CanSomeoneHearCharacter(); + bool disableNode = !CanCharacterBeHeard(); for (int i = 0; i < contextualOrders.Count; i++) { optionNodes.Add(new Tuple( @@ -2766,7 +2778,7 @@ namespace Barotrauma if (checkIfOrderCanBeHeard && !disableNode) { - disableNode = !CanSomeoneHearCharacter(); + disableNode = !CanCharacterBeHeard(); } var mustSetOptionOrTarget = order.HasOptions; @@ -2827,7 +2839,7 @@ namespace Barotrauma if (disableNode) { node.CanBeFocused = icon.CanBeFocused = false; - CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get("nocharactercanhear")); + CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get(characterContext == null ? "nocharactercanhear" : "thischaractercanthear")); } else if (hotkey >= 0) { @@ -2999,11 +3011,11 @@ namespace Barotrauma "\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.leftmouse") : TextManager.Get("input.rightmouse")) + ": " + TextManager.Get("commandui.quickassigntooltip") + "\n" + (!PlayerInput.MouseButtonsSwapped() ? TextManager.Get("input.rightmouse") : TextManager.Get("input.leftmouse")) + ": " + TextManager.Get("commandui.manualassigntooltip")); } - if (!CanSomeoneHearCharacter()) + if (!CanCharacterBeHeard()) { node.CanBeFocused = false; if (icon != null) { icon.CanBeFocused = false; } - CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get("nocharactercanhear")); + CreateBlockIcon(node.RectTransform, tooltip: TextManager.Get(characterContext == null ? "nocharactercanhear" : "thischaractercanthear")); } else if (hotkey >= 0) { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs index 953594247..919a36ab8 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/CharacterInventory.cs @@ -174,6 +174,12 @@ namespace Barotrauma (int)SlotPositions[i].X, (int)SlotPositions[i].Y, (int)(slotSprite.size.X * multiplier), (int)(slotSprite.size.Y * multiplier)); + + if (SlotTypes[i] == InvSlotType.HealthInterface && + character.CharacterHealth?.InventorySlotContainer != null) + { + slotRect.Width = slotRect.Height = (int)(character.CharacterHealth.InventorySlotContainer.Rect.Width * 1.2f); + } ItemContainer itemContainer = slots[i].FirstOrDefault()?.GetComponent(); if (itemContainer != null) @@ -238,6 +244,8 @@ namespace Barotrauma { if (visualSlots[i].Disabled || (slots[i].HideIfEmpty && slots[i].Empty())) { return true; } + if (CharacterHealth.OpenHealthWindow != Character.Controlled?.CharacterHealth && SlotTypes[i] == InvSlotType.HealthInterface) { return true; } + if (layout == Layout.Default) { if (PersonalSlots.HasFlag(SlotTypes[i]) && !personalSlotArea.Contains(visualSlots[i].Rect.Center + visualSlots[i].DrawOffset.ToPoint())) { return true; } @@ -359,7 +367,7 @@ namespace Barotrauma int personalSlotX = HUDLayoutSettings.InventoryAreaLower.Right - SlotSize.X - Spacing; for (int i = 0; i < visualSlots.Length; i++) { - if (HideSlot(i)) { continue; } + if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; } if (PersonalSlots.HasFlag(SlotTypes[i])) { @@ -383,7 +391,7 @@ namespace Barotrauma continue; } - if (HideSlot(i)) { continue; } + if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } if (PersonalSlots.HasFlag(SlotTypes[i])) { SlotPositions[i] = new Vector2(personalSlotX, personalSlotY); @@ -399,7 +407,7 @@ namespace Barotrauma x = lowerX; for (int i = 0; i < SlotPositions.Length; i++) { - if (!HideSlot(i)) { continue; } + if (!HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; } x -= visualSlots[i].Rect.Width + Spacing; SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset); @@ -414,7 +422,7 @@ namespace Barotrauma for (int i = 0; i < SlotPositions.Length; i++) { - if (HideSlot(i)) { continue; } + if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } if (SlotTypes[i] == InvSlotType.RightHand || SlotTypes[i] == InvSlotType.LeftHand) { continue; } if (PersonalSlots.HasFlag(SlotTypes[i])) { @@ -436,7 +444,7 @@ namespace Barotrauma SlotPositions[i] = new Vector2(rightSlot ? handSlotX : handSlotX - visualSlots[0].Rect.Width - Spacing, personalSlotY); continue; } - if (!HideSlot(i)) { continue; } + if (!HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } SlotPositions[i] = new Vector2(x, GameMain.GraphicsHeight - bottomOffset); x += visualSlots[i].Rect.Width + Spacing; } @@ -450,7 +458,7 @@ namespace Barotrauma int x = startX, y = startY; for (int i = 0; i < SlotPositions.Length; i++) { - if (HideSlot(i)) continue; + if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } if (SlotTypes[i] == InvSlotType.Card || SlotTypes[i] == InvSlotType.Headset || SlotTypes[i] == InvSlotType.InnerClothes) { SlotPositions[i] = new Vector2(x, y); @@ -462,7 +470,7 @@ namespace Barotrauma int n = 0; for (int i = 0; i < SlotPositions.Length; i++) { - if (HideSlot(i)) continue; + if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } if (SlotTypes[i] != InvSlotType.Card && SlotTypes[i] != InvSlotType.Headset && SlotTypes[i] != InvSlotType.InnerClothes) { SlotPositions[i] = new Vector2(x, y); @@ -479,13 +487,23 @@ namespace Barotrauma } break; } - + + if (character.CharacterHealth?.UseHealthWindow ?? false) + { + Vector2 pos = character.CharacterHealth.InventorySlotContainer.Rect.Location.ToVector2(); + for (int i = 0; i < capacity; i++) + { + if (SlotTypes[i] != InvSlotType.HealthInterface) { continue; } + SlotPositions[i] = pos; + pos.Y += visualSlots[i].Rect.Height + Spacing; + } + } + CreateSlots(); if (layout == Layout.Default) { HUDLayoutSettings.InventoryTopY = visualSlots[0].EquipButtonRect.Y - (int)(15 * GUI.Scale); } - } protected override void ControlInput(Camera cam) @@ -679,7 +697,7 @@ namespace Barotrauma if (item != null) { var slot = visualSlots[i]; - if (item.AllowedSlots.Any(a => a != InvSlotType.Any)) + if (item.AllowedSlots.Any(a => a != InvSlotType.Any && a != InvSlotType.HealthInterface)) { HandleButtonEquipStates(item, slot, deltaTime); } @@ -858,7 +876,9 @@ namespace Barotrauma private QuickUseAction GetQuickUseAction(Item item, bool allowEquip, bool allowInventorySwap, bool allowApplyTreatment) { - if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null) + if (allowApplyTreatment && CharacterHealth.OpenHealthWindow != null && + //if the item can be equipped in the health interface slot, don't use it as a treatment but try to equip it + !item.AllowedSlots.Contains(InvSlotType.HealthInterface)) { return QuickUseAction.UseTreatment; } @@ -1153,7 +1173,7 @@ namespace Barotrauma for (int i = 0; i < capacity; i++) { - if (HideSlot(i)) { continue; } + if (HideSlot(i) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } //don't draw the item if it's being dragged out of the slot bool drawItem = !DraggingItems.Any() || !slots[i].Items.All(it => DraggingItems.Contains(it)) || visualSlots[i].MouseOn(); @@ -1207,7 +1227,7 @@ namespace Barotrauma highlightedQuickUseSlot = visualSlots[i]; } - if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any)) + if (!slots[i].First().AllowedSlots.Any(a => a == InvSlotType.Any) || SlotTypes[i] == InvSlotType.HealthInterface) { continue; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/GeneticMaterial.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/GeneticMaterial.cs new file mode 100644 index 000000000..981c388a2 --- /dev/null +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/GeneticMaterial.cs @@ -0,0 +1,74 @@ +using Barotrauma.Networking; +using Microsoft.Xna.Framework; +using System.Linq; + +namespace Barotrauma.Items.Components +{ + partial class GeneticMaterial : ItemComponent + { + [Serialize(0.0f, false)] + public float TooltipValueMin { get; set; } + + [Serialize(0.0f, false)] + public float TooltipValueMax { get; set; } + + public override void AddTooltipInfo(ref string name, ref string description) + { + if (!string.IsNullOrEmpty(materialName)) + { + string mergedMaterialName = materialName; + foreach (Item containedItem in item.ContainedItems) + { + var containedMaterial = containedItem.GetComponent(); + if (containedMaterial == null) { continue; } + mergedMaterialName += ", " + containedMaterial.materialName; + } + name = TextManager.GetWithVariable("entityname.geneticmaterial", "[type]", mergedMaterialName); + } + + if (Tainted) + { + name = TextManager.GetWithVariable("entityname.taintedgeneticmaterial", "[geneticmaterialname]", name); + } + + if (TextManager.ContainsTag("entitydescription."+Item.prefab.Identifier)) + { + int value = (int)MathHelper.Lerp(TooltipValueMin, TooltipValueMax, item.ConditionPercentage / 100.0f); + description = TextManager.GetWithVariable("entitydescription." + Item.prefab.Identifier, "[value]", value.ToString()); + } + } + + public void ModifyDeconstructInfo(Deconstructor deconstructor, ref string buttonText, ref string infoText) + { + if (deconstructor.InputContainer.Inventory.AllItems.Count() == 2) + { + if (!deconstructor.InputContainer.Inventory.AllItems.All(it => it.prefab == item.prefab)) + { + buttonText = TextManager.Get("researchstation.combine"); + infoText = TextManager.Get("researchstation.combine.infotext"); + } + else + { + buttonText = TextManager.Get("researchstation.refine"); + int taintedProbability = (int)(GetTaintedProbabilityOnRefine(Character.Controlled) * 100); + infoText = TextManager.GetWithVariable("researchstation.refine.infotext", "[taintedprobability]", taintedProbability.ToString()); + } + } + } + + public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) + { + Tainted = msg.ReadBoolean(); + if (Tainted) + { + uint selectedTaintedEffectId = msg.ReadUInt32(); + selectedTaintedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedTaintedEffectId); + } + else + { + uint selectedEffectId = msg.ReadUInt32(); + selectedEffect = AfflictionPrefab.Prefabs.Find(a => a.UIntIdentifier == selectedEffectId); + } + } + } +} diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemComponent.cs index faaa76c27..5e5a9357a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemComponent.cs @@ -621,6 +621,6 @@ namespace Barotrauma.Items.Components } OnResolutionChanged(); } - public virtual void AddTooltipInfo(ref string description) { } + public virtual void AddTooltipInfo(ref string name, ref string description) { } } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemContainer.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemContainer.cs index 4da1bb77e..4a1049947 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemContainer.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/ItemContainer.cs @@ -58,6 +58,9 @@ namespace Barotrauma.Items.Components [Serialize(null, false)] public string ContainedStateIndicatorStyle { get; set; } + [Serialize(-1, false, description: "Can be used to make the contained state indicator display the condition of the item in a specific slot even when the container's capacity is more than 1.")] + public int ContainedStateIndicatorSlot { get; set; } + [Serialize(true, false, description: "Should an indicator displaying the state of the contained items be displayed on this item's inventory slot. "+ "If this item can only contain one item, the indicator will display the condition of the contained item, otherwise it will indicate how full the item is.")] public bool ShowContainedStateIndicator { get; set; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Deconstructor.cs index 24149ae69..62c485a67 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Deconstructor.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/Deconstructor.cs @@ -14,12 +14,19 @@ namespace Barotrauma.Items.Components } private GUIButton activateButton; private GUIComponent inputInventoryHolder, outputInventoryHolder; - private GUICustomComponent inputInventoryOverlay; private GUIComponent inSufficientPowerWarning; private bool pendingState; + private GUITextBlock infoArea; + + [Serialize("DeconstructorDeconstruct", true)] + public string ActivateButtonText { get; set; } + + [Serialize(0.0f, true)] + public float InfoAreaWidth { get; set; } + partial void InitProjSpecific(XElement element) { CreateGUI(); @@ -39,6 +46,12 @@ namespace Barotrauma.Items.Components RelativeSpacing = 0.08f }; + new GUITextBlock(new RectTransform(new Vector2(1f, 0.07f), paddedFrame.RectTransform), item.Name, font: GUI.SubHeadingFont) + { + TextAlignment = Alignment.Center, + AutoScaleHorizontal = true + }; + var topFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.5f), paddedFrame.RectTransform), style: null); // === INPUT LABEL === // @@ -55,22 +68,23 @@ namespace Barotrauma.Items.Components // === INPUT SLOTS === // inputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(0.7f, 1f), inputArea.RectTransform), style: null); - inputInventoryOverlay = new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false }; + new GUICustomComponent(new RectTransform(Vector2.One, inputInventoryHolder.RectTransform), DrawOverLay, null) { CanBeFocused = false }; // === ACTIVATE BUTTON === // - var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.7f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft); + var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.8f), inputArea.RectTransform), childAnchor: Anchor.CenterLeft); activateButton = new GUIButton(new RectTransform(new Vector2(0.95f, 0.8f), buttonContainer.RectTransform), TextManager.Get("DeconstructorDeconstruct"), style: "DeviceButton") { TextBlock = { AutoScaleHorizontal = true }, OnClicked = ToggleActive }; inSufficientPowerWarning = new GUITextBlock(new RectTransform(Vector2.One, activateButton.RectTransform), - TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow") + TextManager.Get("DeconstructorNoPower"), textColor: GUI.Style.Orange, textAlignment: Alignment.Center, color: Color.Black, style: "OuterGlow", wrap: true) { HoverColor = Color.Black, IgnoreLayoutGroups = true, Visible = false, - CanBeFocused = false + CanBeFocused = false, + AutoScaleHorizontal = true }; // === OUTPUT AREA === // @@ -86,8 +100,62 @@ namespace Barotrauma.Items.Components outputLabel.RectTransform.Resize(new Point((int) outputLabel.Font.MeasureString(outputLabel.Text).X, outputLabel.RectTransform.Rect.Height)); new GUIFrame(new RectTransform(Vector2.One, outputLabelArea.RectTransform), style: "HorizontalLine"); + var outputArea = new GUILayoutGroup(new RectTransform(new Vector2(1f, 1f), bottomFrame.RectTransform, Anchor.CenterLeft), childAnchor: Anchor.BottomLeft, isHorizontal: true) { Stretch = true, RelativeSpacing = 0.05f }; + // === OUTPUT SLOTS === // - outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f, 1f), bottomFrame.RectTransform, Anchor.CenterLeft), style: null); + outputInventoryHolder = new GUIFrame(new RectTransform(new Vector2(1f - InfoAreaWidth, 1f), outputArea.RectTransform, Anchor.CenterLeft), style: null); + + if (InfoAreaWidth >= 0.0f) + { + var infoAreaContainer = new GUILayoutGroup(new RectTransform(new Vector2(InfoAreaWidth, 0.8f), outputArea.RectTransform), childAnchor: Anchor.CenterLeft); + infoArea = new GUITextBlock(new RectTransform(new Vector2(0.95f, 0.95f), infoAreaContainer.RectTransform), string.Empty, wrap: true); + } + + ActivateButton.OnAddedToGUIUpdateList += (GUIComponent component) => + { + activateButton.Enabled = true; + infoArea.Text = string.Empty; + if (IsActive) + { + activateButton.Text = TextManager.Get("DeconstructorCancel"); + return; + } + bool outputsFound = false; + foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: true)) + { + outputsFound = true; + if (!string.IsNullOrEmpty(deconstructItem.ActivateButtonText)) + { + string buttonText = TextManager.Get(deconstructItem.ActivateButtonText, returnNull: true) ?? deconstructItem.ActivateButtonText; + string infoText = string.Empty; + if (!string.IsNullOrEmpty(deconstructItem.InfoText)) + { + infoText = TextManager.Get(deconstructItem.InfoText, returnNull: true) ?? deconstructItem.InfoText; + } + inputItem.GetComponent()?.ModifyDeconstructInfo(this, ref buttonText, ref infoText); + activateButton.Text = buttonText; + if (infoArea != null) + { + infoArea.Text = infoText; + } + return; + } + } + //no valid outputs found: check if we're missing some required items from the input slots and display a message about it if possible + if (!outputsFound && infoArea != null) + { + foreach (var (inputItem, deconstructItem) in GetAvailableOutputs(checkRequiredOtherItems: false)) + { + if (deconstructItem.RequiredOtherItem.Any() && !string.IsNullOrEmpty(deconstructItem.InfoTextOnOtherItemMissing)) + { + string missingItemName = TextManager.Get("entityname." + deconstructItem.RequiredOtherItem.First(), returnNull: true); + infoArea.Text = TextManager.GetWithVariable(deconstructItem.InfoTextOnOtherItemMissing, "[itemname]", missingItemName); + } + } + } + activateButton.Enabled = inputContainer.Inventory.AllItems.Any(); + activateButton.Text = TextManager.Get(ActivateButtonText); + }; } public override bool Select(Character character) @@ -126,14 +194,30 @@ namespace Barotrauma.Items.Components private void DrawOverLay(SpriteBatch spriteBatch, GUICustomComponent overlayComponent) { overlayComponent.RectTransform.SetAsLastChild(); - if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) { return; } - var lastSlot = visualSlots.Last(); - GUI.DrawRectangle(spriteBatch, - new Rectangle( - lastSlot.Rect.X, lastSlot.Rect.Y + (int)(lastSlot.Rect.Height * (1.0f - progressState)), - lastSlot.Rect.Width, (int)(lastSlot.Rect.Height * progressState)), - GUI.Style.Green * 0.5f, isFilled: true); + if (!(inputContainer?.Inventory?.visualSlots is { } visualSlots)) { return; } + + if (DeconstructItemsSimultaneously) + { + for (int i = 0; i < InputContainer.Inventory.Capacity; i++) + { + if (InputContainer.Inventory.GetItemAt(i) == null) { continue; } + DrawProgressBar(InputContainer.Inventory.visualSlots[i]); + } + } + else + { + DrawProgressBar(inputContainer.Inventory.visualSlots.Last()); + } + + void DrawProgressBar(VisualSlot slot) + { + GUI.DrawRectangle(spriteBatch, + new Rectangle( + slot.Rect.X, slot.Rect.Y + (int)(slot.Rect.Height * (1.0f - progressState)), + slot.Rect.Width, (int)(slot.Rect.Height * progressState)), + GUI.Style.Green * 0.5f, isFilled: true); + } } public override void UpdateHUD(Character character, float deltaTime, Camera cam) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/MiniMap.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/MiniMap.cs index 0e9e7b897..b0aee591b 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/MiniMap.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Machines/MiniMap.cs @@ -403,7 +403,7 @@ namespace Barotrauma.Items.Components scissorComponent = new GUIScissorComponent(new RectTransform(Vector2.One, submarineContainer.RectTransform, Anchor.Center)); miniMapContainer = new GUIFrame(new RectTransform(Vector2.One, scissorComponent.Content.RectTransform, Anchor.Center), style: null) { CanBeFocused = false }; - miniMapFrame = CreateMiniMap(item.Submarine, miniMapContainer, MiniMapSettings.Default, null, out hullStatusComponents); + miniMapFrame = CreateMiniMap(item.Submarine, submarineContainer, MiniMapSettings.Default, null, out hullStatusComponents); IEnumerable pointsOfInterest = Item.ItemList.Where(it => it.Submarine == item.Submarine && !it.HiddenInGame && !it.NonInteractable && it.GetComponent() != null); electricalFrame = CreateMiniMap(item.Submarine, miniMapContainer, new MiniMapSettings(createHullElements: false), pointsOfInterest, out electricalMapComponents); @@ -458,7 +458,7 @@ namespace Barotrauma.Items.Components CreateHUD(); } - if (PlayerInput.PrimaryMouseButtonDown()) + if (PlayerInput.PrimaryMouseButtonDown() && currentMode != MiniMapMode.HullStatus) { if (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn)) { @@ -466,20 +466,16 @@ namespace Barotrauma.Items.Components } } - float newZoom = Zoom; - if (Math.Abs(PlayerInput.ScrollWheelSpeed) > 0 && (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn))) + if (currentMode != MiniMapMode.HullStatus && Math.Abs(PlayerInput.ScrollWheelSpeed) > 0 && (GUI.MouseOn == scissorComponent || scissorComponent.IsParentOf(GUI.MouseOn))) { - newZoom = Math.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f * Zoom, minZoom, maxZoom); + float newZoom = Math.Clamp(Zoom + PlayerInput.ScrollWheelSpeed / 1000.0f * Zoom, minZoom, maxZoom); float distanceScale = newZoom / Zoom; mapOffset *= distanceScale; + recalculate |= !MathUtils.NearlyEqual(Zoom, newZoom); + Zoom = newZoom; } - recalculate |= !MathUtils.NearlyEqual(Zoom, newZoom); - Zoom = newZoom; - - Vector2 elementScale = new Vector2(Zoom); - if (dragMapStart is { } dragStart) { if (dragMap || Vector2.DistanceSquared(dragStart, PlayerInput.MousePosition) > GUI.IntScale(dragTreshold * dragTreshold)) @@ -487,16 +483,11 @@ namespace Barotrauma.Items.Components mapOffset.X += PlayerInput.MouseSpeed.X; mapOffset.Y += PlayerInput.MouseSpeed.Y; - recalculate |= PlayerInput.MouseSpeed != Vector2.Zero; + recalculate = true; dragMap = true; } } - var (maxWidth, maxHeight) = miniMapContainer.Rect.Size.ToVector2() / 2f / Zoom; - - mapOffset.X = Math.Clamp(mapOffset.X, -maxWidth, maxWidth); - mapOffset.Y = Math.Clamp(mapOffset.Y, -maxHeight, maxHeight); - if (!PlayerInput.PrimaryMouseButtonHeld()) { dragMapStart = null; @@ -505,10 +496,15 @@ namespace Barotrauma.Items.Components if (recalculate) { - miniMapContainer.RectTransform.LocalScale = elementScale; + miniMapContainer.RectTransform.LocalScale = new Vector2(Zoom); miniMapContainer.RectTransform.RecalculateChildren(true, true); miniMapContainer.RectTransform.AbsoluteOffset = mapOffset.ToPoint(); recalculate = false; + + var (maxWidth, maxHeight) = miniMapContainer.Rect.Size.ToVector2() / 2f / Zoom; + + mapOffset.X = Math.Clamp(mapOffset.X, -maxWidth, maxWidth); + mapOffset.Y = Math.Clamp(mapOffset.Y, -maxHeight, maxHeight); } // is there a better way to do this? @@ -583,6 +579,7 @@ namespace Barotrauma.Items.Components private void DrawHUDFront(SpriteBatch spriteBatch, GUICustomComponent container) { // TODO remove + #warning remove if (currentMode == MiniMapMode.HullCondition) { const string wipText = "work in progress"; @@ -757,7 +754,7 @@ namespace Barotrauma.Items.Components foreach (Item foundItem in foundItems) { RelativeEntityRect scaledRect = new RelativeEntityRect(dockedBorders, foundItem.WorldRect); - Vector2 pos = (scaledRect.PositionRelativeTo(parentRect, skipOffset: true) + scaledRect.SizeRelativeTo(parentRect) / 2f) / Zoom; + Vector2 pos = scaledRect.PositionRelativeTo(parentRect, skipOffset: true) + scaledRect.SizeRelativeTo(parentRect) / 2f; positions.Add(pos); } @@ -873,10 +870,14 @@ namespace Barotrauma.Items.Components string line1 = gapOpenSum > 0.1f ? TextManager.Get("MiniMapHullBreach") : string.Empty; Color line1Color = GUI.Style.Red; - string line2 = oxygenAmount == null ? TextManager.Get("MiniMapAirQualityUnavailable") : TextManager.AddPunctuation(':', TextManager.Get("MiniMapAirQuality"), +(int)oxygenAmount + " %"); + string line2 = oxygenAmount == null ? + TextManager.Get("MiniMapAirQualityUnavailable") : + TextManager.AddPunctuation(':', TextManager.Get("MiniMapAirQuality"), (int)Math.Round(oxygenAmount.Value) + "%"); Color line2Color = oxygenAmount == null ? GUI.Style.Red : Color.Lerp(GUI.Style.Red, Color.LightGreen, (float)oxygenAmount / 100.0f); - string line3 = waterAmount == null ? TextManager.Get("MiniMapWaterLevelUnavailable") : TextManager.AddPunctuation(':', TextManager.Get("MiniMapWaterLevel"), (int)(waterAmount * 100.0f) + " %"); + string line3 = waterAmount == null ? + TextManager.Get("MiniMapWaterLevelUnavailable") : + TextManager.AddPunctuation(':', TextManager.Get("MiniMapWaterLevel"), (int)Math.Round(waterAmount.Value * 100.0f) + "%"); Color line3Color = waterAmount == null ? GUI.Style.Red : Color.Lerp(Color.LightGreen, GUI.Style.Red, (float)waterAmount); SetTooltip(borderComponent.Rect.Center, header, line1, line2, line3, line1Color, line2Color, line3Color); @@ -958,7 +959,7 @@ namespace Barotrauma.Items.Components Rectangle parentRect = container.Rect; if (miniMapFrame is { } miniMap) { parentRect = miniMap.Rect; } - DrawSubmarine(spriteBatch, parentRect); + DrawSubmarine(spriteBatch); } if (Voltage < MinVoltage) { return; } @@ -979,7 +980,7 @@ namespace Barotrauma.Items.Components Vector2 spriteScale = targetSize / pingCircle.size; float scale = Math.Min(blipState, maxBlipState / 2f); float alpha = 1.0f - Math.Clamp((blipState - maxBlipState * 0.25f) * 2f, 0f, 1f); - pingCircle.Draw(spriteBatch, miniMapFrame.Rect.Location.ToVector2() + (blip * Zoom), GUI.Style.Red * alpha, pingCircle.Origin, 0f, spriteScale * scale, SpriteEffects.None); + pingCircle.Draw(spriteBatch, electricalFrame.Rect.Location.ToVector2() + blip * Zoom, GUI.Style.Red * alpha, pingCircle.Origin, 0f, spriteScale * scale, SpriteEffects.None); } } } @@ -1002,8 +1003,15 @@ namespace Barotrauma.Items.Components { RectangleF waterRect = new RectangleF(hullFrame.Rect.X, hullFrame.Rect.Y + hullFrame.Rect.Height * (1.0f - waterAmount), hullFrame.Rect.Width, hullFrame.Rect.Height * waterAmount); + const float width = 1f; + GUI.DrawFilledRectangle(spriteBatch, waterRect, HullWaterColor); - GUI.DrawLine(spriteBatch, waterRect.Location, new Vector2(waterRect.Right, waterRect.Y), HullWaterLineColor); + + if (!MathUtils.NearlyEqual(waterAmount, 1.0f)) + { + Vector2 offset = new Vector2(0, width); + GUI.DrawLine(spriteBatch, waterRect.Location + offset, new Vector2(waterRect.Right, waterRect.Y) + offset, HullWaterLineColor, width: width); + } } } @@ -1079,7 +1087,7 @@ namespace Barotrauma.Items.Components submarinePreview = rt; } - private void DrawSubmarine(SpriteBatch spriteBatch, Rectangle parentRect) + private void DrawSubmarine(SpriteBatch spriteBatch) { Rectangle prevScissorRect = spriteBatch.GraphicsDevice.ScissorRectangle; spriteBatch.End(); @@ -1094,7 +1102,8 @@ namespace Barotrauma.Items.Components Color blueprintBlue = BlueprintBlue * currentMode switch { MiniMapMode.HullStatus => 0.1f, MiniMapMode.ElectricalView => 0.1f, _ => 0.5f }; Vector2 origin = new Vector2(texture.Width / 2f, texture.Height / 2f); - spriteBatch.Draw(texture, parentRect.Center.ToVector2(), null, blueprintBlue, 0f, origin, Zoom, SpriteEffects.None, 0f); + float scale = currentMode == MiniMapMode.HullStatus ? 1.0f : Zoom; + spriteBatch.Draw(texture, miniMapContainer.Center, null, blueprintBlue, 0f, origin, scale, SpriteEffects.None, 0f); spriteBatch.End(); } @@ -1281,12 +1290,12 @@ namespace Barotrauma.Items.Components GUIFrame hullContainer = new GUIFrame(new RectTransform(containerScale * elementPadding, parent.RectTransform, Anchor.Center), style: null); ImmutableHashSet connectedSubs = sub.GetConnectedSubs().ToImmutableHashSet(); - ImmutableHashSet hullList = ImmutableHashSet.Empty; - ImmutableDictionary> combinedHulls = ImmutableDictionary>.Empty; + ImmutableArray hullList = ImmutableArray.Empty; + ImmutableDictionary> combinedHulls = ImmutableDictionary>.Empty; if (settings.CreateHullElements) { - hullList = Hull.hullList.Where(IsPartofSub).ToImmutableHashSet(); + hullList = Hull.hullList.Where(IsPartofSub).ToImmutableArray(); combinedHulls = CombinedHulls(hullList); } @@ -1436,7 +1445,7 @@ namespace Barotrauma.Items.Components } } - private static ImmutableDictionary> CombinedHulls(ImmutableHashSet hulls) + private static ImmutableDictionary> CombinedHulls(ImmutableArray hulls) { Dictionary> combinedHulls = new Dictionary>(); @@ -1460,10 +1469,10 @@ namespace Barotrauma.Items.Components } } - return combinedHulls.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableHashSet()); + return combinedHulls.ToImmutableDictionary(pair => pair.Key, pair => pair.Value.ToImmutableArray()); } - private static MiniMapHullData ConstructHullPolygon(Hull mainHull, ImmutableHashSet linkedHulls, GUIComponent parent, RectangleF worldBorders) + private static MiniMapHullData ConstructHullPolygon(Hull mainHull, ImmutableArray linkedHulls, GUIComponent parent, RectangleF worldBorders) { Rectangle parentRect = parent.Rect; @@ -1500,6 +1509,8 @@ namespace Barotrauma.Items.Components hullRefs.Add(hull); } + hullRefs.Reverse(); // I have no idea why this is required + ImmutableArray snappedRectangles = ToolBox.SnapRectangles(normalizedRects, treshold: 1); List> polygon = ToolBox.CombineRectanglesIntoShape(snappedRectangles); @@ -1508,6 +1519,7 @@ namespace Barotrauma.Items.Components foreach (List list in polygon) { + // scale down the polygon just a tiny bit var (polySizeX, polySizeY) = ToolBox.GetPolygonBoundingBoxSize(list); float sizeX = polySizeX - 1f, sizeY = polySizeY - 1f; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/RemoteController.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/RemoteController.cs new file mode 100644 index 000000000..bf5405474 --- /dev/null +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/RemoteController.cs @@ -0,0 +1,22 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace Barotrauma.Items.Components +{ + partial class RemoteController : ItemComponent + { + public override void DrawHUD(SpriteBatch spriteBatch, Character character) + { + currentTarget?.DrawHUD(spriteBatch, Screen.Selected.Cam, character); + } + + public override void UpdateHUD(Character character, float deltaTime, Camera cam) + { + currentTarget?.UpdateHUD(cam, character,deltaTime); + } + + public override void AddToGUIUpdateList() + { + currentTarget?.AddToGUIUpdateList(); + } + } +} diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Connection.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Connection.cs index 4efc832fc..336769480 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Connection.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Connection.cs @@ -54,6 +54,11 @@ namespace Barotrauma.Items.Components if (wireComponent != null) { equippedWire = wireComponent; + var connectedEnd = equippedWire.OtherConnection(null); + if (connectedEnd?.Item.Submarine != null && panel.Item.Submarine != connectedEnd.Item.Submarine) + { + equippedWire = null; + } } } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Terminal.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Terminal.cs index fe20dca85..e13440e0e 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Terminal.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Signal/Terminal.cs @@ -63,11 +63,11 @@ namespace Barotrauma.Items.Components } OutputValue = input; - ShowOnDisplay(input); + ShowOnDisplay(input, addToHistory: true); item.SendSignal(input, "signal_out"); } - partial void ShowOnDisplay(string input, bool addToHistory = true) + partial void ShowOnDisplay(string input, bool addToHistory) { if (addToHistory) { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/StatusHUD.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/StatusHUD.cs index 04313fee8..f9a7b5e9a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/StatusHUD.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/StatusHUD.cs @@ -39,6 +39,34 @@ namespace Barotrauma.Items.Components private set; } + [Serialize(false, false)] + public bool SeeThroughWalls + { + get; + private set; + } + + [Serialize(true, false)] + public bool ShowDeadCharacters + { + get; + private set; + } + + [Serialize(true, false)] + public bool ShowTexts + { + get; + private set; + } + + [Serialize("72,119,72,120", false)] + public Color OverlayColor + { + get; + private set; + } + private readonly List visibleCharacters = new List(); private const float UpdateInterval = 0.5f; @@ -91,12 +119,13 @@ namespace Barotrauma.Items.Components foreach (Character c in Character.CharacterList) { if (c == equipper || !c.Enabled || c.Removed) { continue; } + if (!ShowDeadCharacters && c.IsDead) { continue; } float dist = Vector2.DistanceSquared(refEntity.WorldPosition, c.WorldPosition); if (dist < Range * Range) { Vector2 diff = c.WorldPosition - refEntity.WorldPosition; - if (Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null) + if (SeeThroughWalls || Submarine.CheckVisibility(refEntity.SimPosition, refEntity.SimPosition + ConvertUnits.ToSimUnits(diff)) == null) { visibleCharacters.Add(c); } @@ -123,27 +152,54 @@ namespace Barotrauma.Items.Components { if (character == null) { return; } - GUI.UIGlow.Draw(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), - Color.LightGreen * 0.5f); - - Character closestCharacter = null; - float closestDist = float.PositiveInfinity; - foreach (Character c in visibleCharacters) + if (OverlayColor.A > 0) { - if (c == character || !c.Enabled || c.Removed) { continue; } - - float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition); - if (dist < closestDist) - { - closestCharacter = c; - closestDist = dist; - } + GUI.UIGlow.Draw(spriteBatch, new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), OverlayColor); } - if (closestCharacter != null) + if (ShowTexts) { - float dist = Vector2.Distance(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), closestCharacter.WorldPosition); - DrawCharacterInfo(spriteBatch, closestCharacter, 1.0f - MathHelper.Max((dist - (Range - FadeOutRange)) / FadeOutRange, 0.0f)); + Character closestCharacter = null; + float closestDist = float.PositiveInfinity; + foreach (Character c in visibleCharacters) + { + if (c == character || !c.Enabled || c.Removed) { continue; } + + float dist = Vector2.DistanceSquared(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), c.WorldPosition); + if (dist < closestDist) + { + closestCharacter = c; + closestDist = dist; + } + } + + if (closestCharacter != null) + { + float dist = Vector2.Distance(GameMain.GameScreen.Cam.ScreenToWorld(PlayerInput.MousePosition), closestCharacter.WorldPosition); + DrawCharacterInfo(spriteBatch, closestCharacter, 1.0f - MathHelper.Max((dist - (Range - FadeOutRange)) / FadeOutRange, 0.0f)); + } + } + + if (SeeThroughWalls) + { + spriteBatch.End(); + GameMain.LightManager.SolidColorEffect.Parameters["color"].SetValue(Color.Red.ToVector4() * (0.35f + (float)Math.Sin(Timing.TotalTime * 1.6f) * 0.05f)); + GameMain.LightManager.SolidColorEffect.CurrentTechnique = GameMain.LightManager.SolidColorEffect.Techniques["SolidColorBlur"]; + GameMain.LightManager.SolidColorEffect.Parameters["blurDistance"].SetValue(0.03f + (float)Math.Sin(Timing.TotalTime) * 0.01f); + GameMain.LightManager.SolidColorEffect.CurrentTechnique.Passes[0].Apply(); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive, transformMatrix: Screen.Selected.Cam.Transform, effect: GameMain.LightManager.SolidColorEffect); + + foreach (Character c in visibleCharacters) + { + if (c == character || !c.Enabled || c.Removed) { continue; } + foreach (Limb limb in c.AnimController.Limbs) + { + limb.Draw(spriteBatch, Screen.Selected.Cam, disableDeformations: true); + } + } + + spriteBatch.End(); + spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.NonPremultiplied); } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs index 9692249c8..b489954a0 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Components/Wearable.cs @@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components description += $"\n ‖color:{colorStr}‖{roundedValue.ToString("-0;+#")}%‖color:end‖ {AfflictionPrefab.List.FirstOrDefault(ap => ap.Identifier.Equals(afflictionIdentifier, StringComparison.OrdinalIgnoreCase))?.Name ?? afflictionIdentifier}"; } - public override void AddTooltipInfo(ref string description) + public override void AddTooltipInfo(ref string name, ref string description) { if (damageModifiers.Any(d => !MathUtils.NearlyEqual(d.DamageMultiplier, 1f)) || SkillModifiers.Any()) { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Inventory.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Inventory.cs index 21ac893a5..a4cc3788d 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Inventory.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Inventory.cs @@ -297,9 +297,10 @@ namespace Barotrauma } } + string name = item.Name; foreach (ItemComponent component in item.Components) { - component.AddTooltipInfo(ref description); + component.AddTooltipInfo(ref name, ref description); } if (item.Prefab.ShowContentsInTooltip && item.OwnInventory != null) @@ -315,7 +316,7 @@ namespace Barotrauma string colorStr = XMLExtensions.ColorToString(!item.AllowStealing ? GUI.Style.Red : Color.White); - toolTip = $"‖color:{colorStr}‖{item.Name}‖color:end‖"; + toolTip = $"‖color:{colorStr}‖{name}‖color:end‖"; if (itemsInSlot.All(it => it.NonInteractable || it.NonPlayerTeamInteractable)) { toolTip += " " + TextManager.Get("connectionlocked"); @@ -719,7 +720,7 @@ namespace Barotrauma spacing = new Vector2(10 * UIScale, (10 + UnequippedIndicator.size.Y) * UIScale); } - int columns = (int)Math.Max(Math.Floor(Math.Sqrt(itemCapacity)), 1); + int columns = MathHelper.Clamp((int)Math.Floor(Math.Sqrt(itemCapacity)), 1, container.SlotsPerRow); while (itemCapacity / columns * (subRect.Height + spacing.Y) > GameMain.GraphicsHeight * 0.5f) { columns++; @@ -1543,13 +1544,13 @@ namespace Barotrauma } else { - var containedItem = itemContainer.Inventory.slots[0].FirstOrDefault(); - containedState = itemContainer.Inventory.Capacity == 1 ? + var containedItem = itemContainer.Inventory.slots[Math.Max(itemContainer.ContainedStateIndicatorSlot, 0)].FirstOrDefault(); + containedState = itemContainer.Inventory.Capacity == 1 || itemContainer.ContainedStateIndicatorSlot > -1 ? (containedItem == null ? 0.0f : containedItem.Condition / containedItem.MaxCondition) : itemContainer.Inventory.slots.Count(i => !i.Empty()) / (float)itemContainer.Inventory.capacity; if (containedItem != null && itemContainer.Inventory.Capacity == 1) { - int maxStackSize = Math.Min(containedItem.Prefab.MaxStackSize, itemContainer.MaxStackSize); + int maxStackSize = Math.Min(containedItem.Prefab.MaxStackSize, itemContainer.GetMaxStackSize(0)); if (maxStackSize > 1) { containedState = itemContainer.Inventory.slots[0].ItemCount / (float)maxStackSize; @@ -1631,7 +1632,7 @@ namespace Barotrauma int maxStackSize = item.Prefab.MaxStackSize; if (item.Container != null) { - maxStackSize = Math.Min(maxStackSize, item.Container.GetComponent()?.MaxStackSize ?? maxStackSize); + maxStackSize = Math.Min(maxStackSize, item.Container.GetComponent()?.GetMaxStackSize(slotIndex) ?? maxStackSize); } if (maxStackSize > 1 && inventory != null) { diff --git a/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs b/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs index 237c062d3..1ed06add7 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Items/Item.cs @@ -1194,7 +1194,14 @@ namespace Barotrauma } } - if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this) { return; } + if (Character.Controlled != null && Character.Controlled.SelectedConstruction != this) + { + if (Character.Controlled.SelectedConstruction?.GetComponent()?.TargetItem != this && + !Character.Controlled.HeldItems.Any(it => it.GetComponent()?.TargetItem == this)) + { + return; + } + } bool needsLayoutUpdate = false; foreach (ItemComponent ic in activeHUDs) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Map/MapEntity.cs b/Barotrauma/BarotraumaClient/ClientSource/Map/MapEntity.cs index 9fad6fc1c..a6244b448 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Map/MapEntity.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Map/MapEntity.cs @@ -423,20 +423,24 @@ namespace Barotrauma //select wire if both items it's connected to are selected var selectedItems = SelectedList.Where(e => e is Item).Cast().ToList(); - foreach (Item item in selectedItems) + foreach (Item item in Item.ItemList) { - if (item.Connections == null) continue; - foreach (Connection c in item.Connections) - { - foreach (Wire w in c.Wires) - { - if (w == null || SelectedList.Contains(w.Item)) continue; + var wire = item.GetComponent(); + if (wire == null) { continue; } + Item item0 = wire.Connections[0]?.Item; + Item item1 = wire.Connections[1]?.Item; - if (w.OtherConnection(c) != null && SelectedList.Contains(w.OtherConnection(c).Item)) - { - SelectedList.Add(w.Item); - } - } + if (item0 == null && item1 != null) + { + item0 = Item.ItemList.Find(it => it.GetComponent()?.DisconnectedWires.Contains(wire) ?? false); + } + else if (item0 != null && item1 == null) + { + item1 = Item.ItemList.Find(it => it.GetComponent()?.DisconnectedWires.Contains(wire) ?? false); + } + if (item0 != null && item1 != null && SelectedList.Contains(item0) && SelectedList.Contains(item1)) + { + SelectedList.Add(item); } } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs b/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs index 04701beb5..9d19ccf5a 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Map/Submarine.cs @@ -326,7 +326,7 @@ namespace Barotrauma depthSortedDamageable.Insert(i, structure); } } - + foreach (Structure s in depthSortedDamageable) { s.DrawDamage(spriteBatch, damageEffect, editing); @@ -418,8 +418,8 @@ namespace Barotrauma float scale = 0.9f; GUIFrame hullContainer = new GUIFrame(new RectTransform( - (parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale, - parent.RectTransform, Anchor.Center), + (parentAspectRatio > aspectRatio ? new Vector2(aspectRatio / parentAspectRatio, 1.0f) : new Vector2(1.0f, parentAspectRatio / aspectRatio)) * scale, + parent.RectTransform, Anchor.Center), style: null) { UserData = "hullcontainer" @@ -444,9 +444,9 @@ namespace Barotrauma { if (!combinedHulls.ContainsKey(hull)) { - combinedHulls.Add(hull, new HashSet()); + combinedHulls.Add(hull, new HashSet()); } - + combinedHulls[hull].Add(linkedHull); } } @@ -454,14 +454,14 @@ namespace Barotrauma foreach (Hull hull in hullList) { Vector2 relativeHullPos = new Vector2( - (hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width, + (hull.WorldRect.X - worldBorders.X) / (float)worldBorders.Width, (worldBorders.Y - hull.WorldRect.Y) / (float)worldBorders.Height); Vector2 relativeHullSize = new Vector2(hull.Rect.Width / (float)worldBorders.Width, hull.Rect.Height / (float)worldBorders.Height); bool hideHull = combinedHulls.ContainsKey(hull) || combinedHulls.Values.Any(hh => hh.Contains(hull)); if (hideHull) { continue; } - + Color color = Color.DarkCyan * 0.8f; var hullFrame = new GUIFrame(new RectTransform(relativeHullSize, hullContainer.RectTransform) { RelativeOffset = relativeHullPos }, style: "MiniMapRoom", color: color) @@ -477,7 +477,7 @@ namespace Barotrauma MiniMapHullData data = ConstructLinkedHulls(mainHull, linkedHulls, hullContainer, worldBorders); Vector2 relativeHullPos = new Vector2( - (data.Bounds.X - worldBorders.X) / worldBorders.Width, + (data.Bounds.X - worldBorders.X) / worldBorders.Width, (worldBorders.Y - data.Bounds.Y) / worldBorders.Height); Vector2 relativeHullSize = new Vector2(data.Bounds.Width / worldBorders.Width, data.Bounds.Height / worldBorders.Height); @@ -507,9 +507,6 @@ namespace Barotrauma var (parentW, parentH) = hullContainer.Rect.Size.ToVector2(); Vector2 size = new Vector2(rect.Width / parentW, rect.Height / parentH); // TODO this won't be required if we some day switch RectTransform to use RectangleF - const float padding = 0.001f; - size.X += padding; - size.Y += padding; Vector2 pos = new Vector2(rect.X / parentW, rect.Y / parentH); GUIFrame hullFrame = new GUIFrame(new RectTransform(size, hullContainer.RectTransform) { RelativeOffset = pos }, style: "ScanLinesSeamless", color: color) @@ -586,7 +583,7 @@ namespace Barotrauma wRect.Y = -wRect.Y; var (posX, posY) = new Vector2( - (wRect.X - worldBorders.X) / (float)worldBorders.Width, + (wRect.X - worldBorders.X) / (float)worldBorders.Width, (worldBorders.Y - wRect.Y) / (float)worldBorders.Height); var (scaleX, scaleY) = new Vector2(wRect.Width / (float)worldBorders.Width, wRect.Height / (float)worldBorders.Height); @@ -629,7 +626,7 @@ namespace Barotrauma } } - if (Info.Type != SubmarineType.OutpostModule || + if (Info.Type != SubmarineType.OutpostModule || (Info.OutpostModuleInfo?.ModuleFlags.Any(f => !f.Equals("hallwayvertical", StringComparison.OrdinalIgnoreCase) && !f.Equals("hallwayhorizontal", StringComparison.OrdinalIgnoreCase)) ?? true)) { if (!WayPoint.WayPointList.Any(wp => wp.ShouldBeSaved && wp.SpawnType == SpawnType.Path)) @@ -697,7 +694,7 @@ namespace Barotrauma int wireCount = item.Connections[i].Wires.Count(w => w != null); if (doorLinks + wireCount > item.Connections[i].MaxWires) { - errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning", + errorMsgs.Add(TextManager.GetWithVariables("InsufficientFreeConnectionsWarning", new string[] { "[doorcount]", "[freeconnectioncount]" }, new string[] { doorLinks.ToString(), (item.Connections[i].MaxWires - wireCount).ToString() })); break; @@ -794,7 +791,7 @@ namespace Barotrauma return SubEditorScreen.SuppressedWarnings.Contains(type); } } - + public void ClientRead(ServerNetObject type, IReadMessage msg, float sendingTime) { if (type != ServerNetObject.ENTITY_POSITION) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs index 182e826f9..1b5c3fdc0 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Particles/ParticleManager.cs @@ -184,7 +184,7 @@ namespace Barotrauma.Particles public ParticlePrefab FindPrefab(string prefabName) { - return Prefabs.Find(p => p.Identifier == prefabName); + return Prefabs.Find(p => p.Identifier.Equals(prefabName, StringComparison.OrdinalIgnoreCase)); } private void RemoveParticle(int index) diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs index 071349710..29699b746 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/NetLobbyScreen.cs @@ -1366,6 +1366,7 @@ namespace Barotrauma LogButtons.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog); GameMain.Client.ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog); roundControlsHolder.Children.ForEach(c => c.IgnoreLayoutGroups = !c.Visible); + roundControlsHolder.Children.ForEach(c => c.RectTransform.RelativeSize = Vector2.One); roundControlsHolder.Recalculate(); ReadyToStartBox.Parent.Visible = !GameMain.Client.GameStarted; diff --git a/Barotrauma/BarotraumaClient/ClientSource/Screens/TestScreen.cs b/Barotrauma/BarotraumaClient/ClientSource/Screens/TestScreen.cs index 0deb694c4..050fd29eb 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Screens/TestScreen.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Screens/TestScreen.cs @@ -51,11 +51,16 @@ namespace Barotrauma } // ???????? - submarine = new Submarine(SubmarineInfo.SavedSubmarines.FirstOrDefault(info => info.Name.Equals("Kastrull", StringComparison.OrdinalIgnoreCase))); + submarine = new Submarine(SubmarineInfo.SavedSubmarines.FirstOrDefault(info => info.Name.Equals("Crescent", StringComparison.OrdinalIgnoreCase))); miniMapItem = new Item(ItemPrefab.Find(null, "statusmonitor"), Vector2.Zero, submarine); MiniMap miniMap = miniMapItem.GetComponent(); miniMap.PowerConsumption = 0; + foreach (var hull in Hull.hullList) + { + hull.WaterVolume = hull.Volume / 2f; + } + dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false); dummyCharacter.Info.Name = "Galldren"; dummyCharacter.Inventory.CreateSlots(); diff --git a/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs b/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs index f6e679850..fbd068958 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Sounds/SoundPlayer.cs @@ -1012,7 +1012,8 @@ namespace Barotrauma Screen.Selected == GameMain.SpriteEditorScreen || Screen.Selected == GameMain.SubEditorScreen || Screen.Selected == GameMain.EventEditorScreen || - (Screen.Selected == GameMain.GameScreen && GameMain.GameSession?.GameMode is TestGameMode)) + (Screen.Selected == GameMain.GameScreen && GameMain.GameSession?.GameMode is TestGameMode) || + Screen.Selected == GameMain.NetLobbyScreen) { return "editor"; } diff --git a/Barotrauma/BarotraumaClient/ClientSource/Utils/SpreadsheetExport.cs b/Barotrauma/BarotraumaClient/ClientSource/Utils/SpreadsheetExport.cs index 403a70475..6327b9e26 100644 --- a/Barotrauma/BarotraumaClient/ClientSource/Utils/SpreadsheetExport.cs +++ b/Barotrauma/BarotraumaClient/ClientSource/Utils/SpreadsheetExport.cs @@ -110,14 +110,14 @@ namespace Barotrauma foreach (StatusEffect statusEffect in successEffects) { float duration = statusEffect.Duration; - onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.First), -pair.Second, duration))); + onSuccessAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration))); onSuccessAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration))); } foreach (StatusEffect statusEffect in failureEffects) { float duration = statusEffect.Duration; - onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.First), -pair.Second, duration))); + onFailureAfflictions.AddRange(statusEffect.ReduceAffliction.Select(pair => Tuple.Create(GetAfflictionName(pair.affliction), -pair.amount, duration))); onFailureAfflictions.AddRange(statusEffect.Afflictions.Select(affliction => Tuple.Create(affliction.Prefab.Name, affliction.NonClampedStrength, duration))); } } diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj index dac5130ed..1c1a72de1 100644 --- a/Barotrauma/BarotraumaClient/LinuxClient.csproj +++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1500.0.0 + 0.1500.1.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/MacClient.csproj b/Barotrauma/BarotraumaClient/MacClient.csproj index 6d8757d5b..34e9c17cd 100644 --- a/Barotrauma/BarotraumaClient/MacClient.csproj +++ b/Barotrauma/BarotraumaClient/MacClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1500.0.0 + 0.1500.1.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaClient/WindowsClient.csproj b/Barotrauma/BarotraumaClient/WindowsClient.csproj index bc67e5f17..72f5373d5 100644 --- a/Barotrauma/BarotraumaClient/WindowsClient.csproj +++ b/Barotrauma/BarotraumaClient/WindowsClient.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma - 0.1500.0.0 + 0.1500.1.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 Barotrauma diff --git a/Barotrauma/BarotraumaServer/LinuxServer.csproj b/Barotrauma/BarotraumaServer/LinuxServer.csproj index d563f8dfa..98e625016 100644 --- a/Barotrauma/BarotraumaServer/LinuxServer.csproj +++ b/Barotrauma/BarotraumaServer/LinuxServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1500.0.0 + 0.1500.1.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/MacServer.csproj b/Barotrauma/BarotraumaServer/MacServer.csproj index 79640545b..bcaa8358d 100644 --- a/Barotrauma/BarotraumaServer/MacServer.csproj +++ b/Barotrauma/BarotraumaServer/MacServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1500.0.0 + 0.1500.1.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs b/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs index f9f51b713..c0998cfbc 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Characters/Character.cs @@ -28,6 +28,15 @@ namespace Barotrauma } } + if (HasAbilityFlag(AbilityFlags.RetainExperienceForNewCharacter)) + { + var ownerClient = GameMain.Server.ConnectedClients.Find(c => c.Character == this); + if (ownerClient != null) + { + (GameMain.GameSession?.GameMode as MultiPlayerCampaign)?.SaveExperiencePoints(ownerClient); + } + } + healthUpdateTimer = 0.0f; if (CauseOfDeath.Killer != null && CauseOfDeath.Killer.IsTraitor && CauseOfDeath.Killer != this) diff --git a/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterInfo.cs b/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterInfo.cs index 148bfeda3..e5863ea30 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterInfo.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Characters/CharacterInfo.cs @@ -73,6 +73,7 @@ namespace Barotrauma msg.Write(savedStatValue.RemoveOnDeath); } } + msg.Write((ushort)ExperiencePoints); } } } diff --git a/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs b/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs index 3996fdbeb..fef8b769a 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/GameSession/GameModes/MultiPlayerCampaign.cs @@ -27,6 +27,29 @@ namespace Barotrauma public bool GameOver { get; private set; } + class SavedExperiencePoints + { + public readonly ulong SteamID; + public readonly string EndPoint; + public readonly int ExperiencePoints; + + public SavedExperiencePoints(Client client) + { + SteamID = client.SteamID; + EndPoint = client.Connection.EndPointString; + ExperiencePoints = client.Character?.Info?.ExperiencePoints ?? 0; + } + + public SavedExperiencePoints(XElement element) + { + SteamID = element.GetAttributeUInt64("steamid", 0); + EndPoint = element.GetAttributeString("endpoint", string.Empty); + ExperiencePoints = element.GetAttributeInt("points", 0); + } + } + + private readonly List savedExperiencePoints = new List(); + public override bool Paused { get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"); } @@ -155,6 +178,20 @@ namespace Barotrauma c.InGame && (IsOwner(c) || c.HasPermission(ClientPermissions.ManageCampaign))); } + public void SaveExperiencePoints(Client client) + { + ClearSavedExperiencePoints(client); + savedExperiencePoints.Add(new SavedExperiencePoints(client)); + } + public int GetSavedExperiencePoints(Client client) + { + return savedExperiencePoints.Find(s => s.SteamID != 0 && client.SteamID == s.SteamID || client.EndpointMatches(s.EndPoint))?.ExperiencePoints ?? 0; + } + public void ClearSavedExperiencePoints(Client client) + { + savedExperiencePoints.RemoveAll(s => s.SteamID != 0 && client.SteamID == s.SteamID || client.EndpointMatches(s.EndPoint)); + } + public void LoadPets() { if (petsElement != null) @@ -259,6 +296,16 @@ namespace Barotrauma Map.ProgressWorld(transitionType, (float)(Timing.TotalTime - GameMain.GameSession.RoundStartTime)); bool success = GameMain.Server.ConnectedClients.Any(c => c.InGame && c.Character != null && !c.Character.IsDead); + if (success) + { + foreach (Client c in GameMain.Server.ConnectedClients) + { + if (c.Character?.HasAbilityFlag(AbilityFlags.RetainExperienceForNewCharacter) ?? false) + { + (GameMain.GameSession?.GameMode as MultiPlayerCampaign)?.SaveExperiencePoints(c); + } + } + } GameMain.GameSession.EndRound("", traitorResults, transitionType); @@ -965,6 +1012,15 @@ namespace Barotrauma // save bots CrewManager.SaveMultiplayer(modeElement); + XElement savedExperiencePointsElement = new XElement("SavedExperiencePoints"); + foreach (var savedExperiencePoint in savedExperiencePoints) + { + savedExperiencePointsElement.Add(new XElement("Point", + new XAttribute("steamid", savedExperiencePoint.SteamID), + new XAttribute("endpoint", savedExperiencePoint?.EndPoint ?? string.Empty), + new XAttribute("points", savedExperiencePoint.ExperiencePoints))); + } + // save available submarines XElement availableSubsElement = new XElement("AvailableSubs"); for (int i = 0; i < GameMain.NetLobbyScreen.CampaignSubmarines.Count; i++) diff --git a/Barotrauma/BarotraumaServer/ServerSource/Items/Components/GeneticMaterial.cs b/Barotrauma/BarotraumaServer/ServerSource/Items/Components/GeneticMaterial.cs new file mode 100644 index 000000000..460c5ec46 --- /dev/null +++ b/Barotrauma/BarotraumaServer/ServerSource/Items/Components/GeneticMaterial.cs @@ -0,0 +1,20 @@ +using Barotrauma.Networking; + +namespace Barotrauma.Items.Components +{ + partial class GeneticMaterial : ItemComponent + { + public void ServerWrite(IWriteMessage msg, Client c, object[] extraData = null) + { + msg.Write(tainted); + if (tainted) + { + msg.Write(selectedTaintedEffect?.UIntIdentifier ?? 0); + } + else + { + msg.Write(selectedEffect?.UIntIdentifier ?? 0); + } + } + } +} diff --git a/Barotrauma/BarotraumaServer/ServerSource/Items/Components/Signal/Terminal.cs b/Barotrauma/BarotraumaServer/ServerSource/Items/Components/Signal/Terminal.cs index 1382bdc27..517f51201 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Items/Components/Signal/Terminal.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Items/Components/Signal/Terminal.cs @@ -19,13 +19,13 @@ namespace Barotrauma.Items.Components GameServer.Log(GameServer.CharacterLogName(c.Character) + " entered \"" + newOutputValue + "\" on " + item.Name, ServerLog.MessageType.ItemInteraction); OutputValue = newOutputValue; - ShowOnDisplay(newOutputValue); + ShowOnDisplay(newOutputValue, addToHistory: true); item.SendSignal(newOutputValue, "signal_out"); item.CreateServerEvent(this); } } - partial void ShowOnDisplay(string input, bool addToHistory = true) + partial void ShowOnDisplay(string input, bool addToHistory) { if (addToHistory) { diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs index 2df0be84f..575f5c157 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/GameServer.cs @@ -2358,6 +2358,12 @@ namespace Barotrauma.Networking characterData.HasSpawned = true; } + if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign && spawnedCharacter.Info != null) + { + spawnedCharacter.Info.SetExperience(Math.Max(spawnedCharacter.Info.ExperiencePoints, mpCampaign.GetSavedExperiencePoints(teamClients[i]))); + mpCampaign.ClearSavedExperiencePoints(teamClients[i]); + } + spawnedCharacter.OwnerClientEndPoint = teamClients[i].Connection.EndPointString; spawnedCharacter.OwnerClientName = teamClients[i].Name; } diff --git a/Barotrauma/BarotraumaServer/ServerSource/Networking/RespawnManager.cs b/Barotrauma/BarotraumaServer/ServerSource/Networking/RespawnManager.cs index d162db6f0..5430e285c 100644 --- a/Barotrauma/BarotraumaServer/ServerSource/Networking/RespawnManager.cs +++ b/Barotrauma/BarotraumaServer/ServerSource/Networking/RespawnManager.cs @@ -379,6 +379,12 @@ namespace Barotrauma.Networking } else { + if (GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign && character.Info != null) + { + character.Info.SetExperience(Math.Max(character.Info.ExperiencePoints, mpCampaign.GetSavedExperiencePoints(clients[i]))); + mpCampaign.ClearSavedExperiencePoints(clients[i]); + } + //tell the respawning client they're no longer a traitor if (GameMain.Server.TraitorManager?.Traitors != null && clients[i].Character != null) { diff --git a/Barotrauma/BarotraumaServer/WindowsServer.csproj b/Barotrauma/BarotraumaServer/WindowsServer.csproj index 879a52022..e4aa06d3c 100644 --- a/Barotrauma/BarotraumaServer/WindowsServer.csproj +++ b/Barotrauma/BarotraumaServer/WindowsServer.csproj @@ -6,7 +6,7 @@ Barotrauma FakeFish, Undertow Games Barotrauma Dedicated Server - 0.1500.0.0 + 0.1500.1.0 Copyright © FakeFish 2018-2020 AnyCPU;x64 DedicatedServer diff --git a/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml b/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml index f5c2f7d19..a7a1728a0 100644 --- a/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml +++ b/Barotrauma/BarotraumaShared/Data/ContentPackages/Vanilla 0.9.xml @@ -23,6 +23,7 @@ + @@ -63,6 +64,7 @@ + @@ -152,6 +154,7 @@ + diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs index 6a86228e6..a448481c0 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/EnemyAIController.cs @@ -1915,12 +1915,12 @@ namespace Barotrauma #if SERVER GameMain.NetworkMember.CreateEntityEvent(Character, new object[] { - Networking.NetEntityEvent.Type.SetAttackTarget, - attackingLimb, - (damageTarget as Entity)?.ID ?? Entity.NullEntityID, - damageTarget is Character character && targetLimb != null ? Array.IndexOf(character.AnimController.Limbs, targetLimb) : 0, - SimPosition.X, - SimPosition.Y + Networking.NetEntityEvent.Type.SetAttackTarget, + attackingLimb, + (damageTarget as Entity)?.ID ?? Entity.NullEntityID, + damageTarget is Character character && targetLimb != null ? Array.IndexOf(character.AnimController.Limbs, targetLimb) : 0, + SimPosition.X, + SimPosition.Y }); #else Character.PlaySound(CharacterSound.SoundType.Attack, maxInterval: 3); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveCombat.cs index 79842539a..e554fb317 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -588,8 +588,9 @@ namespace Barotrauma // assume that it's required for the stun effect // as we can't check the status effect conditions here. var mobileBatteryTag = "mobilebattery"; - var containers = weapon.Item.Components.Where(ic => ic is ItemContainer container && - container.ContainableItems.Any(containable => containable.Identifiers.Any(id => id.Equals(mobileBatteryTag)))); + var containers = weapon.Item.Components.Where(ic => + ic is ItemContainer container && + container.ContainableItemIdentifiers.Contains(mobileBatteryTag)); // If there's no such container, assume that the melee weapon can stun without a battery. return containers.None() || containers.Any(container => (container as ItemContainer)?.Inventory.AllItems.Any(i => i != null && i.HasTag(mobileBatteryTag) && i.Condition > 0.0f) ?? false); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/AnimController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/AnimController.cs index 702670425..8d490a3fa 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/AnimController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/AnimController.cs @@ -148,7 +148,7 @@ namespace Barotrauma public virtual void UpdateAnim(float deltaTime) { } - public virtual void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f) { } + public virtual void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f, bool aimingMelee = false) { } public virtual void DragCharacter(Character target, float deltaTime) { } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/FishAnimController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/FishAnimController.cs index 475a16a08..a057b932d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/FishAnimController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/FishAnimController.cs @@ -390,11 +390,17 @@ namespace Barotrauma } if (eatTimer % 1.0f < 0.5f && (eatTimer - deltaTime * eatSpeed) % 1.0f > 0.5f) { - bool CanBeSevered(LimbJoint j) => !j.IsSevered && j.CanBeSevered && j.LimbA != null && !j.LimbA.IsSevered && j.LimbB != null && !j.LimbB.IsSevered; + static bool CanBeSevered(LimbJoint j) => !j.IsSevered && j.CanBeSevered && j.LimbA != null && !j.LimbA.IsSevered && j.LimbB != null && !j.LimbB.IsSevered; //keep severing joints until there is only one limb left var nonSeveredJoints = target.AnimController.LimbJoints.Where(CanBeSevered); if (nonSeveredJoints.None()) { + //small monsters don't eat the contents of the character's inventory + if (Mass < target.AnimController.Mass) + { + target.Inventory?.AllItemsMod.ForEach(it => it?.Drop(dropper: null)); + } + //only one limb left, the character is now full eaten Entity.Spawner?.AddToRemoveQueue(target); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs index 1e910d566..5032d2a2e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/HumanoidAnimController.cs @@ -150,6 +150,13 @@ namespace Barotrauma private float upperLegLength = 0.0f, lowerLegLength = 0.0f; private bool aiming; + private bool wasAiming; + + private bool aimingMelee; + private bool wasAimingMelee; + + public bool IsAiming => wasAiming; + public bool IsAimingMelee => wasAimingMelee; private readonly float movementLerp; @@ -532,7 +539,10 @@ namespace Barotrauma limb.Disabled = false; } + wasAiming = aiming; aiming = false; + wasAimingMelee = aimingMelee; + aimingMelee = false; if (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer) return; } @@ -1718,7 +1728,7 @@ namespace Barotrauma } //TODO: refactor this method, it's way too convoluted - public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f) + public override void HoldItem(float deltaTime, Item item, Vector2[] handlePos, Vector2 holdPos, Vector2 aimPos, bool aim, float holdAngle, float itemAngleRelativeToHoldAngle = 0.0f, bool aimingMelee = false) { if (character.Stun > 0.0f || character.IsIncapacitated) { @@ -1748,6 +1758,8 @@ namespace Barotrauma Holdable holdable = item.GetComponent(); + this.aimingMelee = aimingMelee; + if (!isClimbing && !usingController && character.Stun <= 0.0f && aim && itemPos != Vector2.Zero && !character.IsIncapacitated) { Vector2 mousePos = ConvertUnits.ToSimUnits(character.SmoothedCursorPosition); @@ -1771,7 +1783,6 @@ namespace Barotrauma aiming = true; } - } else { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs index 43d9dc327..3bbb32214 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Animation/Ragdoll.cs @@ -395,12 +395,18 @@ namespace Barotrauma if (character.IsHusk && character.Params.UseHuskAppendage) { + bool inEditor = false; +#if CLIENT + inEditor = Screen.Selected == GameMain.CharacterEditorScreen; +#endif + var characterPrefab = CharacterPrefab.FindByFilePath(character.ConfigPath); if (characterPrefab?.XDocument != null) { var mainElement = characterPrefab.XDocument.Root.IsOverride() ? characterPrefab.XDocument.Root.FirstElement() : characterPrefab.XDocument.Root; foreach (var huskAppendage in mainElement.GetChildElements("huskappendage")) { + if (!inEditor && huskAppendage.GetAttributeBool("onlyfromafflictions", false)) { continue; } AfflictionHusk.AttachHuskAppendage(character, huskAppendage.GetAttributeString("affliction", string.Empty), huskAppendage, ragdoll: this); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs index dc2f44f07..e07f73f0c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Attack.cs @@ -8,7 +8,8 @@ namespace Barotrauma public enum HitDetection { Distance, - Contact + Contact, + None } public enum AttackContext @@ -74,20 +75,6 @@ namespace Barotrauma } } - class AttackData - { - public float DamageMultiplier { get; set; } = 1f; - public float AddedPenetration { get; set; } = 0f; - public List Afflictions { get; set; } - public Attack SourceAttack { get; } - - public AttackData(Attack sourceAttack) - { - SourceAttack = sourceAttack; - } - - } - partial class Attack : ISerializableEntity { [Serialize(AttackContext.Any, true, description: "The attack will be used only in this context."), Editable] @@ -466,7 +453,7 @@ namespace Barotrauma DamageParticles(deltaTime, worldPosition); - var attackResult = target.AddDamage(attacker, worldPosition, this, deltaTime, playSound); + var attackResult = target?.AddDamage(attacker, worldPosition, this, deltaTime, playSound) ?? new AttackResult(); var effectType = attackResult.Damage > 0.0f ? ActionType.OnUse : ActionType.OnFailure; if (targetCharacter != null && targetCharacter.IsDead) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs index c97e76569..f442f7cc1 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Character.cs @@ -9,6 +9,7 @@ using System.Xml.Linq; using Barotrauma.Items.Components; using FarseerPhysics.Dynamics; using Barotrauma.Extensions; +using Barotrauma.Abilities; #if SERVER using System.Text; #endif @@ -1366,7 +1367,6 @@ namespace Barotrauma } } } - private List wearableItems = new List(); public float GetSkillLevel(string skillIdentifier) { @@ -2075,11 +2075,10 @@ namespace Barotrauma return SelectedCharacter == owner && owner.CanInventoryBeAccessed; } - if (inventory.Owner is Item) + if (inventory.Owner is Item item) { - var owner = (Item)inventory.Owner; - if (!CanInteractWith(owner) && !owner.linkedTo.Any(lt => lt is Item item && item.DisplaySideBySideWhenLinked && CanInteractWith(item))) { return false; } - ItemContainer container = owner.GetComponents().FirstOrDefault(ic => ic.Inventory == inventory); + if (!CanInteractWith(item) && !item.linkedTo.Any(lt => lt is Item item && item.DisplaySideBySideWhenLinked && CanInteractWith(item))) { return false; } + ItemContainer container = item.GetComponents().FirstOrDefault(ic => ic.Inventory == inventory); if (container != null && !container.HasRequiredItems(this, addMessage: false)) { return false; } } return true; @@ -2218,6 +2217,12 @@ namespace Barotrauma } } + if (SelectedConstruction?.GetComponent()?.TargetItem == item || + HeldItems.Any(it => it.GetComponent()?.TargetItem == item)) + { + return true; + } + if (item.InteractDistance == 0.0f && !item.Prefab.Triggers.Any()) { return false; } Pickable pickableComponent = item.GetComponent(); @@ -3355,10 +3360,18 @@ namespace Barotrauma float attackImpulse = attack.TargetImpulse + attack.TargetForce * deltaTime; - AttackData attackData = new AttackData(attack); - attacker.CheckTalents(AbilityEffectType.OnAttack, attackData); - CheckTalents(AbilityEffectType.OnAttacked, attackData); - attackData.DamageMultiplier *= (1 + attacker.GetStatValue(StatTypes.AttackMultiplier)); + AbilityAttackData attackData = new AbilityAttackData(attack, this); + if (attacker != null) + { + attackData.Attacker = attacker; + attacker.CheckTalents(AbilityEffectType.OnAttack, attackData); + CheckTalents(AbilityEffectType.OnAttacked, attackData); + attackData.DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.AttackMultiplier); + if (attacker.TeamID == TeamID) + { + attackData.DamageMultiplier *= 1 + attacker.GetStatValue(StatTypes.TeamAttackMultiplier); + } + } IEnumerable attackAfflictions; @@ -3495,6 +3508,7 @@ namespace Barotrauma { attackerCrewmember.CheckTalents(AbilityEffectType.OnCrewKillCharacter, target); } + CheckTalents(AbilityEffectType.OnKillCharacter, target); if (!IsOnPlayerTeam) { return; } if (GameMain.Config.KilledCreatures.Any(name => name.Equals(target.SpeciesName, StringComparison.OrdinalIgnoreCase))) { return; } @@ -3653,10 +3667,7 @@ namespace Barotrauma if (statusEffect.type != actionType) { continue; } if (statusEffect.type == ActionType.OnDamaged) { - if (statusEffect.AllowedAfflictions != null && (LastDamage.Afflictions == null || LastDamage.Afflictions.None(a => statusEffect.AllowedAfflictions.Contains(a.Prefab.AfflictionType) || statusEffect.AllowedAfflictions.Contains(a.Prefab.Identifier)))) - { - continue; - } + if (!statusEffect.HasRequiredAfflictions(LastDamage)) { continue; } if (statusEffect.OnlyPlayerTriggered) { if (LastAttacker == null || !LastAttacker.IsPlayer) @@ -3719,7 +3730,7 @@ namespace Barotrauma } } - private void Implode(bool isNetworkMessage = false) + public void Implode(bool isNetworkMessage = false) { if (CharacterHealth.Unkillable || GodMode || IsDead) { return; } @@ -3829,7 +3840,7 @@ namespace Barotrauma if (info != null) { info.CauseOfDeath = CauseOfDeath; - info.ResetSavedStatValues(); + info.MissionsCompletedSinceDeath = 0; } AnimController.movement = Vector2.Zero; AnimController.TargetMovement = Vector2.Zero; @@ -4434,7 +4445,7 @@ namespace Barotrauma } } - private StatTypes GetSkillStatType(string skillIdentifier) + public static StatTypes GetSkillStatType(string skillIdentifier) { // Using this method to translate between skill identifiers and stat types. Feel free to replace it if there's a better way switch (skillIdentifier) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/CharacterInfo.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/CharacterInfo.cs index 9526ce3a4..b4b617328 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/CharacterInfo.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/CharacterInfo.cs @@ -462,6 +462,9 @@ namespace Barotrauma public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1; + // talent-relevant values + public int MissionsCompletedSinceDeath = 0; + // Used for creating the data public CharacterInfo(string speciesName, string name = "", string originalName = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced, string npcIdentifier = "") { @@ -605,7 +608,10 @@ namespace Barotrauma if (!string.IsNullOrEmpty(personalityName)) { personalityTrait = NPCPersonalityTrait.List.Find(p => p.Name == personalityName); - } + } + + MissionsCompletedSinceDeath = infoElement.GetAttributeInt("missionscompletedsincedeath", 0); + foreach (XElement subElement in infoElement.Elements()) { bool jobCreated = false; @@ -973,16 +979,17 @@ namespace Barotrauma } float prevLevel = Job.GetSkillLevel(skillIdentifier); - Job.IncreaseSkillLevel(skillIdentifier, increase); + Job.IncreaseSkillLevel(skillIdentifier, increase, Character.HasAbilityFlag(AbilityFlags.GainSkillPastMaximum)); float newLevel = Job.GetSkillLevel(skillIdentifier); + if ((int)newLevel > (int)prevLevel) { Character.CheckTalents(AbilityEffectType.OnGainSkillPoint, skillIdentifier); - foreach (Character character in Character.GetFriendlyCrew(Character)) { - character.CheckTalents(AbilityEffectType.OnAllyGainSkillPoint, (skillIdentifier, Character)); + var abilityStringCharacter = new AbilityStringCharacter(skillIdentifier, Character); + character.CheckTalents(AbilityEffectType.OnAllyGainSkillPoint, abilityStringCharacter); } } @@ -1139,9 +1146,10 @@ namespace Barotrauma new XAttribute("startitemsgiven", StartItemsGiven), new XAttribute("ragdoll", ragdollFileName), new XAttribute("personality", personalityTrait == null ? "" : personalityTrait.Name)); - // TODO: animations? + charElement.Add(new XAttribute("missionscompletedsincedeath", MissionsCompletedSinceDeath)); + if (Character != null) { if (Character.AnimController.CurrentHull != null) @@ -1158,6 +1166,7 @@ namespace Barotrauma foreach (var savedStat in statValuePair.Value) { if (savedStat.StatValue == 0f) { continue; } + if (savedStat.RemoveAfterRound) { continue; } savedStatElement.Add(new XElement("savedstatvalue", new XAttribute("stattype", statValuePair.Key.ToString()), @@ -1168,6 +1177,8 @@ namespace Barotrauma } } + + charElement.Add(savedStatElement); parentElement.Add(charElement); @@ -1496,7 +1507,6 @@ namespace Barotrauma } } } - public void ResetSavedStatValue(string statIdentifier) { savedStatValues.SelectMany(s => s.Value).Where(s => s.StatIdentifier == statIdentifier).ForEach(v => v.StatValue = 0f); @@ -1514,7 +1524,7 @@ namespace Barotrauma } } - public void ChangeSavedStatValue(StatTypes statType, float value, string statIdentifier, bool removeOnDeath) + public void ChangeSavedStatValue(StatTypes statType, float value, string statIdentifier, bool removeOnDeath, bool removeAfterRound = false, float maxValue = float.MaxValue) { if (!savedStatValues.ContainsKey(statType)) { @@ -1523,12 +1533,11 @@ namespace Barotrauma if (savedStatValues[statType].FirstOrDefault(s => s.StatIdentifier == statIdentifier) is SavedStatValue savedStat) { - savedStat.StatValue += value; - savedStat.RemoveOnDeath = removeOnDeath; + savedStat.StatValue = MathHelper.Min(savedStat.StatValue + value, maxValue); } else { - savedStatValues[statType].Add(new SavedStatValue(statIdentifier, value, removeOnDeath)); + savedStatValues[statType].Add(new SavedStatValue(statIdentifier, MathHelper.Min(value, maxValue), removeOnDeath, removeAfterRound)); } } } @@ -1538,12 +1547,14 @@ namespace Barotrauma public string StatIdentifier { get; set; } public float StatValue { get; set; } public bool RemoveOnDeath { get; set; } + public bool RemoveAfterRound { get; set; } - public SavedStatValue(string statIdentifier, float value, bool removeOnDeath) + public SavedStatValue(string statIdentifier, float value, bool removeOnDeath, bool retainAfterRound) { StatValue = value; RemoveOnDeath = removeOnDeath; StatIdentifier = statIdentifier; + RemoveAfterRound = retainAfterRound; } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs index 96b550b47..d67a18fde 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/Affliction.cs @@ -17,6 +17,8 @@ namespace Barotrauma public float PendingAdditionStrength { get; set; } public float AdditionStrength { get; set; } + private float fluctuationTimer; + protected float _strength; [Serialize(0f, true), Editable] @@ -56,6 +58,8 @@ namespace Barotrauma public readonly Dictionary PeriodicEffectTimers = new Dictionary(); + public double AppliedAsSuccessfulTreatmentTime, AppliedAsFailedTreatmentTime; + /// /// Which character gave this affliction /// @@ -123,7 +127,7 @@ namespace Barotrauma float amount = MathHelper.Lerp( currentEffect.MinGrainStrength, currentEffect.MaxGrainStrength, - (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)); + (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect); if (Prefab.GrainBurst > 0 && AdditionStrength > amount) { @@ -138,12 +142,12 @@ namespace Barotrauma if (Strength < Prefab.ActivationThreshold) { return 0.0f; } AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return 0.0f; } - if (currentEffect.MaxScreenDistortStrength - currentEffect.MinScreenDistortStrength < 0.0f) { return 0.0f; } + if (currentEffect.MaxScreenDistort - currentEffect.MinScreenDistort < 0.0f) { return 0.0f; } return MathHelper.Lerp( - currentEffect.MinScreenDistortStrength, - currentEffect.MaxScreenDistortStrength, - (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)); + currentEffect.MinScreenDistort, + currentEffect.MaxScreenDistort, + (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect); } public float GetRadialDistortStrength() @@ -151,12 +155,12 @@ namespace Barotrauma if (Strength < Prefab.ActivationThreshold) { return 0.0f; } AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return 0.0f; } - if (currentEffect.MaxRadialDistortStrength - currentEffect.MinRadialDistortStrength < 0.0f) { return 0.0f; } + if (currentEffect.MaxRadialDistort - currentEffect.MinRadialDistort < 0.0f) { return 0.0f; } return MathHelper.Lerp( - currentEffect.MinRadialDistortStrength, - currentEffect.MaxRadialDistortStrength, - (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)); + currentEffect.MinRadialDistort, + currentEffect.MaxRadialDistort, + (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect); } public float GetChromaticAberrationStrength() @@ -164,12 +168,12 @@ namespace Barotrauma if (Strength < Prefab.ActivationThreshold) { return 0.0f; } AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return 0.0f; } - if (currentEffect.MaxChromaticAberrationStrength - currentEffect.MinChromaticAberrationStrength < 0.0f) { return 0.0f; } + if (currentEffect.MaxChromaticAberration - currentEffect.MinChromaticAberration < 0.0f) { return 0.0f; } return MathHelper.Lerp( - currentEffect.MinChromaticAberrationStrength, - currentEffect.MaxChromaticAberrationStrength, - (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)); + currentEffect.MinChromaticAberration, + currentEffect.MaxChromaticAberration, + (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect); } public float GetScreenBlurStrength() @@ -177,12 +181,18 @@ namespace Barotrauma if (Strength < Prefab.ActivationThreshold) { return 0.0f; } AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return 0.0f; } - if (currentEffect.MaxScreenBlurStrength - currentEffect.MinScreenBlurStrength < 0.0f) { return 0.0f; } + if (currentEffect.MaxScreenBlur - currentEffect.MinScreenBlur < 0.0f) { return 0.0f; } return MathHelper.Lerp( - currentEffect.MinScreenBlurStrength, - currentEffect.MaxScreenBlurStrength, - (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)); + currentEffect.MinScreenBlur, + currentEffect.MaxScreenBlur, + (Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect); + } + + private float GetScreenEffectFluctuation(AfflictionPrefab.Effect currentEffect) + { + if (currentEffect == null || currentEffect.ScreenEffectFluctuationFrequency <= 0.0f) { return 1.0f; } + return ((float)Math.Sin(fluctuationTimer * MathHelper.TwoPi) + 1.0f) * 0.5f; } public float GetSkillMultiplier() @@ -210,14 +220,17 @@ namespace Barotrauma } } - public float GetResistance(string afflictionId) + public float GetResistance(AfflictionPrefab affliction) { if (Strength < Prefab.ActivationThreshold) { return 0.0f; } AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return 0.0f; } - if (currentEffect.MaxResistance - currentEffect.MinResistance <= 0.0f) { return 0.0f; } - if (afflictionId != null && afflictionId != currentEffect.ResistanceFor) { return 0.0f; } - + if (!currentEffect.ResistanceFor.Any(r => + r.Equals(affliction.Identifier, StringComparison.OrdinalIgnoreCase) || + r.Equals(affliction.AfflictionType, StringComparison.OrdinalIgnoreCase))) + { + return 0.0f; + } return MathHelper.Lerp( currentEffect.MinResistance, currentEffect.MaxResistance, @@ -229,8 +242,6 @@ namespace Barotrauma if (Strength < Prefab.ActivationThreshold) { return 1.0f; } AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return 1.0f; } - if (currentEffect.MaxSpeedMultiplier - currentEffect.MinSpeedMultiplier <= 0.0f) { return 1.0f; } - return MathHelper.Lerp( currentEffect.MinSpeedMultiplier, currentEffect.MaxSpeedMultiplier, @@ -282,6 +293,9 @@ namespace Barotrauma AfflictionPrefab.Effect currentEffect = GetActiveEffect(); if (currentEffect == null) { return; } + fluctuationTimer += deltaTime * currentEffect.ScreenEffectFluctuationFrequency; + fluctuationTimer %= 1.0f; + if (currentEffect.StrengthChange < 0) // Reduce diminishing of buffs if boosted { float durationMultiplier = 1 / (1 + (Prefab.IsBuff ? characterHealth.Character.GetStatValue(StatTypes.BuffDurationMultiplier) @@ -290,9 +304,9 @@ namespace Barotrauma _strength += currentEffect.StrengthChange * deltaTime * StrengthDiminishMultiplier * durationMultiplier; } - else // Reduce strengthening of afflictions if resistant + else if (currentEffect.StrengthChange > 0) // Reduce strengthening of afflictions if resistant { - _strength += currentEffect.StrengthChange * deltaTime * (1f - characterHealth.GetResistance(Prefab.Identifier)); + _strength += currentEffect.StrengthChange * deltaTime * (1f - characterHealth.GetResistance(Prefab)); } // Don't use the property, because it's virtual and some afflictions like husk overload it for external use. _strength = MathHelper.Clamp(_strength, 0.0f, Prefab.MaxStrength); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs index 82f12e892..72c3dfae7 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionHusk.cs @@ -34,6 +34,10 @@ namespace Barotrauma float threshold = _strength > ActiveThreshold ? ActiveThreshold + 1 : DormantThreshold - 1; float max = Math.Max(threshold, previousValue); _strength = Math.Clamp(value, 0, max); + if (previousValue > 0.0f && value <= 0.0f) + { + DeactivateHusk(); + } } } @@ -51,8 +55,10 @@ namespace Barotrauma } } - private float DormantThreshold => Prefab.MaxStrength * 0.5f; - private float ActiveThreshold => Prefab.MaxStrength * 0.75f; + private float DormantThreshold => (Prefab as AfflictionPrefabHusk)?.DormantThreshold ?? Prefab.MaxStrength * 0.5f; + private float ActiveThreshold => (Prefab as AfflictionPrefabHusk)?.ActiveThreshold ?? Prefab.MaxStrength * 0.75f; + + private float TransitionThreshold => (Prefab as AfflictionPrefabHusk)?.TransitionThreshold ?? Prefab.MaxStrength * 0.75f; public AfflictionHusk(AfflictionPrefab prefab, float strength) : base(prefab, strength) { } @@ -83,7 +89,7 @@ namespace Barotrauma } State = InfectionState.Transition; } - else if (Strength < Prefab.MaxStrength) + else if (Strength < TransitionThreshold) { if (State != InfectionState.Active) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs index 619fb81f0..5028df129 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/Afflictions/AfflictionPrefab.cs @@ -97,6 +97,10 @@ namespace Barotrauma CauseSpeechImpediment = element.GetAttributeBool("causespeechimpediment", true); NeedsAir = element.GetAttributeBool("needsair", false); ControlHusk = element.GetAttributeBool("controlhusk", false); + + DormantThreshold = element.GetAttributeFloat("dormantthreshold", MaxStrength * 0.5f); + ActiveThreshold = element.GetAttributeFloat("activethreshold", MaxStrength * 0.75f); + TransitionThreshold = element.GetAttributeFloat("transitionthreshold", MaxStrength); } // Use any of these to define which limb the appendage is attached to. @@ -105,6 +109,8 @@ namespace Barotrauma public readonly string AttachLimbName; public readonly LimbType AttachLimbType; + public float ActiveThreshold, DormantThreshold, TransitionThreshold; + public readonly string HuskedSpeciesName; public readonly string[] TargetSpecies; public const string Tag = "[speciesname]"; @@ -141,28 +147,31 @@ namespace Barotrauma public bool MultiplyByMaxVitality { get; private set; } [Serialize(0.0f, false)] - public float MinScreenBlurStrength { get; private set; } + public float MinScreenBlur { get; private set; } [Serialize(0.0f, false)] - public float MaxScreenBlurStrength { get; private set; } + public float MaxScreenBlur { get; private set; } [Serialize(0.0f, false)] - public float MinScreenDistortStrength { get; private set; } + public float MinScreenDistort { get; private set; } [Serialize(0.0f, false)] - public float MaxScreenDistortStrength { get; private set; } + public float MaxScreenDistort { get; private set; } [Serialize(0.0f, false)] - public float MinRadialDistortStrength { get; private set; } + public float MinRadialDistort { get; private set; } [Serialize(0.0f, false)] - public float MaxRadialDistortStrength { get; private set; } + public float MaxRadialDistort { get; private set; } [Serialize(0.0f, false)] - public float MinChromaticAberrationStrength { get; private set; } + public float MinChromaticAberration { get; private set; } [Serialize(0.0f, false)] - public float MaxChromaticAberrationStrength { get; private set; } + public float MaxChromaticAberration { get; private set; } + + [Serialize("255,255,255,255", false)] + public Color GrainColor { get; private set; } [Serialize(0.0f, false)] public float MinGrainStrength { get; private set; } @@ -170,6 +179,9 @@ namespace Barotrauma [Serialize(0.0f, false)] public float MaxGrainStrength { get; private set; } + [Serialize(0.0f, false)] + public float ScreenEffectFluctuationFrequency { get; private set; } + [Serialize(1.0f, false)] public float MinBuffMultiplier { get; private set; } @@ -188,8 +200,11 @@ namespace Barotrauma [Serialize(1.0f, false)] public float MaxSkillMultiplier { get; private set; } - [Serialize("", false)] - public string ResistanceFor { get; private set; } + private readonly string[] resistanceFor; + public IEnumerable ResistanceFor + { + get { return resistanceFor; } + } [Serialize(0.0f, false)] public float MinResistance { get; private set; } @@ -209,6 +224,8 @@ namespace Barotrauma { SerializableProperty.DeserializeProperties(this, element); + resistanceFor = element.GetAttributeStringArray("resistancefor", new string[0], convertToLowerInvariant: true); + foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs index a4908115e..a195d5620 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Health/CharacterHealth.cs @@ -266,6 +266,12 @@ namespace Barotrauma private LimbHealth GetMatchingLimbHealth(Limb limb) => limb == null ? null : limbHealths[limb.HealthIndex]; private LimbHealth GetMatchingLimbHealth(Affliction affliction) => GetMatchingLimbHealth(Character.AnimController.GetLimb(affliction.Prefab.IndicatorLimb, excludeSevered: false)); + /// + /// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb. + /// + private IEnumerable GetMatchingAfflictions(LimbHealth limb) + => limb.Afflictions.Union(afflictions.Where(a => GetMatchingLimbHealth(a) == limb)); + /// /// Returns the limb afflictions and non-limbspecific afflictions that are set to be displayed on this limb. /// @@ -426,18 +432,14 @@ namespace Barotrauma } } - public float GetResistance(string resistanceId) + public float GetResistance(AfflictionPrefab affliction) { float resistance = 0.0f; for (int i = 0; i < afflictions.Count; i++) { - if (!afflictions[i].Prefab.IsBuff) continue; - float temp = afflictions[i].GetResistance(resistanceId); - if (temp > resistance) resistance = temp; + resistance += afflictions[i].GetResistance(affliction); } - resistance = 1 - ((1 - resistance) * Character.GetAbilityResistance(resistanceId)); - - return resistance; + return 1 - ((1 - resistance) * Character.GetAbilityResistance(affliction.Identifier)); } public float GetStatValue(StatTypes statType) @@ -451,7 +453,7 @@ namespace Barotrauma } private readonly List matchingAfflictions = new List(); - public void ReduceAffliction(Limb targetLimb, string affliction, float amount) + public void ReduceAffliction(Limb targetLimb, string affliction, float amount, ActionType? treatmentAction = null) { matchingAfflictions.Clear(); matchingAfflictions.AddRange(afflictions); @@ -499,6 +501,17 @@ namespace Barotrauma { matchingAffliction.Strength -= reduceAmount; amount -= reduceAmount; + if (treatmentAction != null) + { + if (treatmentAction.Value == ActionType.OnUse) + { + matchingAffliction.AppliedAsSuccessfulTreatmentTime = Timing.TotalTime; + } + else if (treatmentAction.Value == ActionType.OnFailure) + { + matchingAffliction.AppliedAsFailedTreatmentTime = Timing.TotalTime; + } + } } } CalculateVitality(); @@ -610,7 +623,7 @@ namespace Barotrauma { if (newAffliction.Prefab == affliction.Prefab) { - float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier)); + float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab)); if (allowStacking) { // Add the existing strength @@ -632,7 +645,7 @@ namespace Barotrauma //create a new instance of the affliction to make sure we don't use the same instance for multiple characters //or modify the affliction instance of an Attack or a StatusEffect var copyAffliction = newAffliction.Prefab.Instantiate( - Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab.Identifier))), + Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))), newAffliction.Source); limbHealth.Afflictions.Add(copyAffliction); @@ -666,7 +679,7 @@ namespace Barotrauma { if (newAffliction.Prefab == affliction.Prefab) { - float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab.Identifier)); + float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(affliction.Prefab)); if (allowStacking) { // Add the existing strength @@ -688,7 +701,7 @@ namespace Barotrauma //create a new instance of the affliction to make sure we don't use the same instance for multiple characters //or modify the affliction instance of an Attack or a StatusEffect afflictions.Add(newAffliction.Prefab.Instantiate( - Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab.Identifier))), + Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))), source: newAffliction.Source)); Character.HealthUpdateInterval = 0.0f; @@ -700,8 +713,6 @@ namespace Barotrauma } } - partial void UpdateProjSpecific(float deltaTime); - partial void UpdateLimbAfflictionOverlays(); public void Update(float deltaTime) @@ -741,7 +752,7 @@ namespace Barotrauma for (int i = afflictions.Count - 1; i >= 0; i--) { var affliction = afflictions[i]; - if (irremovableAfflictions.Contains(affliction)) continue; + if (irremovableAfflictions.Contains(affliction)) { continue; } if (affliction.Strength <= 0.0f) { SteamAchievementManager.OnAfflictionRemoved(affliction, Character); @@ -763,6 +774,10 @@ namespace Barotrauma { Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.SwimmingSpeed)); } + else + { + Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.WalkingSpeed)); + } UpdateLimbAfflictionOverlays(); @@ -786,7 +801,12 @@ namespace Barotrauma } else { - OxygenAmount = MathHelper.Clamp(OxygenAmount + deltaTime * (Character.OxygenAvailable < InsufficientOxygenThreshold ? -5.0f : 10.0f), -100.0f, 100.0f); + float decreaseSpeed = -5.0f; + float increaseSpeed = 10.0f; + float oxygenlowResistance = GetResistance(oxygenLowAffliction.Prefab); + decreaseSpeed *= (1f - oxygenlowResistance); + increaseSpeed *= (1f + oxygenlowResistance); + OxygenAmount = MathHelper.Clamp(OxygenAmount + deltaTime * (Character.OxygenAvailable < InsufficientOxygenThreshold ? decreaseSpeed : increaseSpeed), -100.0f, 100.0f); } UpdateOxygenProjSpecific(prevOxygen, deltaTime); @@ -807,8 +827,6 @@ namespace Barotrauma Vitality = MaxVitality; if (Unkillable || Character.GodMode) { return; } - float damageResistanceMultiplier = 1f - GetResistance("damage"); - foreach (LimbHealth limbHealth in limbHealths) { foreach (Affliction affliction in limbHealth.Afflictions) @@ -824,7 +842,6 @@ namespace Barotrauma { vitalityDecrease *= limbHealth.VitalityTypeMultipliers[type]; } - vitalityDecrease *= damageResistanceMultiplier; Vitality -= vitalityDecrease; affliction.CalculateDamagePerSecond(vitalityDecrease); } @@ -833,7 +850,6 @@ namespace Barotrauma foreach (Affliction affliction in afflictions) { float vitalityDecrease = affliction.GetVitalityDecrease(this); - vitalityDecrease *= damageResistanceMultiplier; Vitality -= vitalityDecrease; affliction.CalculateDamagePerSecond(vitalityDecrease); } @@ -951,13 +967,13 @@ namespace Barotrauma /// A dictionary where the key is the identifier of the item and the value the suitability /// If true, the suitability values are normalized between 0 and 1. If not, they're arbitrary values defined in the medical item XML, where negative values are unsuitable, and positive ones suitable. /// Amount of randomization to apply to the values (0 = the values are accurate, 1 = the values are completely random) - public void GetSuitableTreatments(Dictionary treatmentSuitability, bool normalize, float randomization = 0.0f) + public void GetSuitableTreatments(Dictionary treatmentSuitability, bool normalize, Limb limb = null, float randomization = 0.0f) { //key = item identifier //float = suitability treatmentSuitability.Clear(); float minSuitability = -10, maxSuitability = 10; - foreach (Affliction affliction in GetAllAfflictions()) + foreach (Affliction affliction in getAfflictions(limb)) { if (affliction.Strength < affliction.Prefab.TreatmentThreshold) { continue; } foreach (KeyValuePair treatment in affliction.Prefab.TreatmentSuitability) @@ -990,6 +1006,18 @@ namespace Barotrauma treatmentSuitability[treatment] += Rand.Range(-100.0f, 100.0f) * randomization; } } + + IEnumerable getAfflictions(Limb limb) + { + if (limb == null) + { + return GetAllAfflictions(); + } + else + { + return GetMatchingAfflictions(GetMatchingLimbHealth(limb)); + } + } } private readonly List activeAfflictions = new List(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Job.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Job.cs index d8cd67162..2841d305e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Job.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Job.cs @@ -89,11 +89,11 @@ namespace Barotrauma return (skill == null) ? 0.0f : skill.Level; } - public void IncreaseSkillLevel(string skillIdentifier, float increase) + public void IncreaseSkillLevel(string skillIdentifier, float increase, bool increasePastMax) { if (skills.TryGetValue(skillIdentifier, out Skill skill)) { - skill.Level += increase; + skill.IncreaseSkill(increase, increasePastMax); } else { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Skill.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Skill.cs index f439cefff..f3a502403 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Skill.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Jobs/Skill.cs @@ -7,11 +7,18 @@ namespace Barotrauma private float level; public string Identifier { get; } + + public const float MaximumSkill = 100.0f; public float Level { get { return level; } - set { level = MathHelper.Clamp(value, 0.0f, 100.0f); } + set { level = value; } + } + + public void IncreaseSkill(float value, bool increasePastMax) + { + level = MathHelper.Clamp(level + value, 0.0f, increasePastMax ? float.MaxValue : MaximumSkill); } private Sprite icon; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs index ed33edcd9..9afd742bb 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Limb.cs @@ -868,7 +868,7 @@ namespace Barotrauma /// public bool UpdateAttack(float deltaTime, Vector2 attackSimPos, IDamageable damageTarget, out AttackResult attackResult, float distance = -1, Limb targetLimb = null) { - attackResult = default(AttackResult); + attackResult = default; Vector2 simPos = ragdoll.SimplePhysicsEnabled ? character.SimPosition : SimPosition; float dist = distance > -1 ? distance : ConvertUnits.ToDisplayUnits(Vector2.Distance(simPos, attackSimPos)); bool wasRunning = attack.IsRunning; @@ -971,7 +971,7 @@ namespace Barotrauma wasHit = damageTarget != null; } - if (wasHit) + if (wasHit || attack.HitDetectionType == HitDetection.None) { if (character == Character.Controlled || GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) { @@ -1132,10 +1132,7 @@ namespace Barotrauma if (statusEffect.type != actionType) { continue; } if (statusEffect.type == ActionType.OnDamaged) { - if (statusEffect.AllowedAfflictions != null && (character.LastDamage.Afflictions == null || character.LastDamage.Afflictions.None(a => statusEffect.AllowedAfflictions.Contains(a.Prefab.AfflictionType) || statusEffect.AllowedAfflictions.Contains(a.Prefab.Identifier)))) - { - continue; - } + if (!statusEffect.HasRequiredAfflictions(character.LastDamage)) { continue; } if (statusEffect.OnlyPlayerTriggered) { if (character.LastAttacker == null || !character.LastAttacker.IsPlayer) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackData.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackData.cs index 2a80e9122..3288b0b7a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackData.cs @@ -15,7 +15,7 @@ namespace Barotrauma.Abilities private readonly string itemIdentifier; private readonly string[] tags; - private WeaponType weapontype; + private readonly WeaponType weapontype; public AbilityConditionAttackData(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { itemIdentifier = conditionElement.GetAttributeString("itemidentifier", ""); @@ -33,7 +33,7 @@ namespace Barotrauma.Abilities protected override bool MatchesConditionSpecific(object abilityData) { - if (abilityData is AttackData attackData) + if (abilityData is AbilityAttackData attackData) { Item item = attackData?.SourceAttack?.SourceItem; @@ -71,7 +71,7 @@ namespace Barotrauma.Abilities } else { - LogAbilityConditionError(abilityData, typeof(AttackData)); + LogAbilityConditionError(abilityData, typeof(AbilityAttackData)); return false; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackResult.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackResult.cs index 909c694f2..ac9eb34df 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackResult.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionAttackResult.cs @@ -30,7 +30,7 @@ namespace Barotrauma.Abilities } else { - LogAbilityConditionError(abilityData, typeof(AttackData)); + LogAbilityConditionError(abilityData, typeof(AbilityAttackData)); return false; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionData.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionData.cs index d80a6257d..5135b0924 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionData.cs @@ -1,7 +1,4 @@ -using Microsoft.Xna.Framework; -using System; -using System.Collections.Generic; -using System.Linq; +using System; using System.Xml.Linq; namespace Barotrauma.Abilities diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionHandsomeStranger.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionHandsomeStranger.cs deleted file mode 100644 index 55ee4fa06..000000000 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionHandsomeStranger.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Xml.Linq; - -namespace Barotrauma.Abilities -{ - class AbilityConditionHandsomeStranger : AbilityConditionData - { - string skillIdentifier; - - public AbilityConditionHandsomeStranger(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) - { - skillIdentifier = conditionElement.GetAttributeString("skillidentifier", "").ToLowerInvariant(); - } - - protected override bool MatchesConditionSpecific(object abilityData) - { - if (abilityData is string skillIdentifier) - { - return this.skillIdentifier == skillIdentifier; - } - else - { - LogAbilityConditionError(abilityData, typeof(string)); - return false; - } - } - } -} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionIsAiming.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionIsAiming.cs new file mode 100644 index 000000000..324676a98 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionIsAiming.cs @@ -0,0 +1,54 @@ +using Barotrauma.Items.Components; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionIsAiming : AbilityConditionDataless + { + private enum WeaponType + { + Any = 0, + Melee = 1, + Ranged = 2 + }; + + private WeaponType weapontype; + public AbilityConditionIsAiming(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) + { + switch (conditionElement.GetAttributeString("weapontype", "")) + { + case "melee": + weapontype = WeaponType.Melee; + break; + case "ranged": + weapontype = WeaponType.Ranged; + break; + } + } + + protected override bool MatchesConditionSpecific() + { + bool aimingCorrectItem = false; + if (character.AnimController is HumanoidAnimController animController) + { + foreach (Item item in character.HeldItems) + { + switch (weapontype) + { + case WeaponType.Melee: + aimingCorrectItem |= item.GetComponent() != null && animController.IsAimingMelee; + break; + case WeaponType.Ranged: + aimingCorrectItem |= item.GetComponent() != null && animController.IsAiming; + break; + default: + aimingCorrectItem |= animController.IsAiming || animController.IsAimingMelee; + break; + } + } + } + + return aimingCorrectItem; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionItem.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionItem.cs index cfa1db21c..4e6b530cd 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionItem.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionItem.cs @@ -22,10 +22,9 @@ namespace Barotrauma.Abilities { item = tempItem.Prefab; } - // this and other instances of this type of casting will be refactored - else if (abilityData is (ItemPrefab itemPrefab, object _)) + else if (abilityData is IAbilityItemPrefab abilityItemPrefab) { - item = itemPrefab; + item = abilityItemPrefab.ItemPrefab; } if (item != null) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionReduceAffliction.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionReduceAffliction.cs index 24044dc0e..888217b9f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionReduceAffliction.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionReduceAffliction.cs @@ -15,17 +15,17 @@ namespace Barotrauma.Abilities protected override bool MatchesConditionSpecific(object abilityData) { - if (abilityData is (Affliction affliction, float reduceAmount)) + if (abilityData is IAbilityAffliction abilityAffliction) { - if (allowedTypes.Find(c => c == affliction.Prefab.AfflictionType) == null) { return false; } + if (allowedTypes.Find(c => c == abilityAffliction.Affliction.Prefab.AfflictionType) == null) { return false; } - if (!string.IsNullOrEmpty(identifier) && affliction.Prefab.Identifier != identifier) { return false; } + if (!string.IsNullOrEmpty(identifier) && abilityAffliction.Affliction.Prefab.Identifier != identifier) { return false; } return true; } else { - LogAbilityConditionError(abilityData, typeof((Affliction, float))); + LogAbilityConditionError(abilityData, typeof(IAbilityAffliction)); return false; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionSkill.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionSkill.cs new file mode 100644 index 000000000..37fd19923 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionData/AbilityConditionSkill.cs @@ -0,0 +1,32 @@ +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionSkill : AbilityConditionData + { + private readonly string skillIdentifier; + + public AbilityConditionSkill(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) + { + skillIdentifier = conditionElement.GetAttributeString("skillidentifier", "").ToLowerInvariant(); + } + + private bool MatchesConditionSpecific(string skillIdentifier) + { + return this.skillIdentifier == skillIdentifier; + } + + protected override bool MatchesConditionSpecific(object abilityData) + { + if ((abilityData as string ?? (abilityData as IAbilityString)?.String) is string skillIdentifier) + { + return MatchesConditionSpecific(skillIdentifier); + } + else + { + LogAbilityConditionError(abilityData, typeof(string)); + return false; + } + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionAboveVitality.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionAboveVitality.cs index 6543c7b32..9fe8fa1a4 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionAboveVitality.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionAboveVitality.cs @@ -1,11 +1,10 @@ -using System.Linq; -using System.Xml.Linq; +using System.Xml.Linq; namespace Barotrauma.Abilities { class AbilityConditionAboveVitality : AbilityConditionDataless { - float vitalityPercentage; + private readonly float vitalityPercentage; public AbilityConditionAboveVitality(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionCoauthor.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionCoauthor.cs new file mode 100644 index 000000000..7525427eb --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionCoauthor.cs @@ -0,0 +1,26 @@ +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionCoauthor : AbilityConditionDataless + { + private readonly string jobIdentifier; + + public AbilityConditionCoauthor(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) + { + jobIdentifier = conditionElement.GetAttributeString("jobidentifier", string.Empty); + } + + protected override bool MatchesConditionSpecific() + { + if (character.SelectedCharacter is Character otherCharacter) + { + if (!otherCharacter.HasJob(jobIdentifier)) { return false; } + if (!(character.SelectedBy == otherCharacter)) { return false; } + return true; + } + return false; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionDataless.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionDataless.cs index 023fe029f..de8bccced 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionDataless.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionDataless.cs @@ -1,8 +1,4 @@ -using Microsoft.Xna.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; +using System.Xml.Linq; namespace Barotrauma.Abilities { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasPermanentStat.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasPermanentStat.cs new file mode 100644 index 000000000..0fee25880 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasPermanentStat.cs @@ -0,0 +1,23 @@ +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionHasPermanentStat : AbilityConditionDataless + { + private readonly StatTypes statType; + private readonly float min; + + public AbilityConditionHasPermanentStat(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) + { + statType = CharacterAbilityGroup.ParseStatType(conditionElement.GetAttributeString("stattype", ""), characterTalent.DebugIdentifier); + min = conditionElement.GetAttributeFloat("min", 0f); + } + + protected override bool MatchesConditionSpecific() + { + // should consider decoupling this from stat values entirely + return character.Info.GetSavedStatValue(statType) >= min; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasStatusTag.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasStatusTag.cs new file mode 100644 index 000000000..2a22f2098 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionHasStatusTag.cs @@ -0,0 +1,31 @@ +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionHasStatusTag : AbilityConditionDataless + { + private readonly string tag; + + + public AbilityConditionHasStatusTag(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) + { + tag = conditionElement.GetAttributeString("tag", ""); + if (string.IsNullOrEmpty(tag)) + { + DebugConsole.AddWarning($"Error in talent \"{characterTalent.Prefab.OriginalName}\" - tag not defined in AbilityConditionHasStatusTag."); + } + } + + protected override bool MatchesConditionSpecific() + { + if (!string.IsNullOrEmpty(tag)) + { + return + StatusEffect.DurationList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag)) || + DelayedEffect.DelayList.Any(d => d.Targets.Contains(character) && d.Parent.HasTag(tag)); + } + return false; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInFriendlySubmarine.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInFriendlySubmarine.cs new file mode 100644 index 000000000..28f27ed9b --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInFriendlySubmarine.cs @@ -0,0 +1,15 @@ + +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionInFriendlySubmarine : AbilityConditionDataless + { + public AbilityConditionInFriendlySubmarine(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { } + + protected override bool MatchesConditionSpecific() + { + return character.Submarine?.TeamID == character.TeamID; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInHull.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInHull.cs new file mode 100644 index 000000000..e08291e6b --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionInHull.cs @@ -0,0 +1,15 @@ + +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionInHull : AbilityConditionDataless + { + public AbilityConditionInHull(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) { } + + protected override bool MatchesConditionSpecific() + { + return character.CurrentHull != null; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionLevelsBehindHighest.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionLevelsBehindHighest.cs new file mode 100644 index 000000000..f2c4b2fb7 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionLevelsBehindHighest.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class AbilityConditionLevelsBehindHighest : AbilityConditionDataless + { + private readonly int levelsBehind; + public AbilityConditionLevelsBehindHighest(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) + { + levelsBehind = conditionElement.GetAttributeInt("levelsbehind", 0); + } + + protected override bool MatchesConditionSpecific() + { + return Character.GetFriendlyCrew(character).Where(c => c.Info != null && (c.Info.GetCurrentLevel() - character.Info.GetCurrentLevel() >= levelsBehind)).Any(); + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionMission.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionMission.cs index f27ecf4c1..29cab2f45 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionMission.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionMission.cs @@ -24,13 +24,13 @@ namespace Barotrauma.Abilities protected override bool MatchesConditionSpecific(object abilityData) { - if (abilityData is (Mission mission, AbilityValue missionAbilityValue)) + if (abilityData is IAbilityMission abilityMission) { - return mission.Prefab.Type == missionType; + return abilityMission.Mission.Prefab.Type == missionType; } else { - LogAbilityConditionError(abilityData, typeof((Mission, AbilityValue))); + LogAbilityConditionError(abilityData, typeof(IAbilityMission)); return false; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionServerRandom.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionServerRandom.cs index 3cc8ae4f5..5b582f799 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionServerRandom.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityConditionals/AbilityConditionDataless/AbilityConditionServerRandom.cs @@ -1,14 +1,10 @@ -using Microsoft.Xna.Framework; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Xml.Linq; +using System.Xml.Linq; namespace Barotrauma.Abilities { class AbilityConditionServerRandom : AbilityConditionDataless { - private float randomChance = 0f; + private readonly float randomChance = 0f; public override bool AllowClientSimulation => false; public AbilityConditionServerRandom(CharacterTalent characterTalent, XElement conditionElement) : base(characterTalent, conditionElement) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityInterfaces.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityInterfaces.cs new file mode 100644 index 000000000..46478b7b7 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityInterfaces.cs @@ -0,0 +1,32 @@ +namespace Barotrauma.Abilities +{ + interface IAbilityItemPrefab + { + public ItemPrefab ItemPrefab { get; set; } + } + + interface IAbilityValue + { + public float Value { get; set; } + } + + interface IAbilityMission + { + public Mission Mission { get; set; } + } + + interface IAbilityCharacter + { + public Character Character { get; set; } + } + + interface IAbilityString + { + public string String { get; set; } + } + + interface IAbilityAffliction + { + public Affliction Affliction { get; set; } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityObjects.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityObjects.cs new file mode 100644 index 000000000..9247ad159 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/AbilityObjects.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; + +namespace Barotrauma.Abilities +{ + + class AbilityValue : IAbilityValue + { + public AbilityValue(float value) + { + Value = value; + } + public float Value { get; set; } + } + + class AbilityValueItem : IAbilityValue, IAbilityItemPrefab + { + public AbilityValueItem(float value, ItemPrefab itemPrefab) + { + Value = value; + ItemPrefab = itemPrefab; + } + public float Value { get; set; } + public ItemPrefab ItemPrefab { get; set; } + } + + class AbilityValueString : IAbilityValue, IAbilityString + { + public AbilityValueString(float value, string abilityString) + { + Value = value; + String = abilityString; + } + public float Value { get; set; } + public string String { get; set; } + } + + class AbilityStringCharacter : IAbilityCharacter, IAbilityString + { + public AbilityStringCharacter(string abilityString, Character character) + { + String = abilityString; + Character = character; + } + public Character Character { get; set; } + public string String { get; set; } + } + + class AbilityValueAffliction : IAbilityValue, IAbilityAffliction + { + public AbilityValueAffliction(float value, Affliction affliction) + { + Value = value; + Affliction = affliction; + } + public float Value { get; set; } + public Affliction Affliction { get; set; } + } + + class AbilityValueMission : IAbilityValue, IAbilityMission + { + public AbilityValueMission(float value, Mission mission) + { + Value = value; + Mission = mission; + } + public float Value { get; set; } + public Mission Mission { get; set; } + } + + class AbilityAttackData : IAbilityCharacter + { + public float DamageMultiplier { get; set; } = 1f; + public float AddedPenetration { get; set; } = 0f; + public List Afflictions { get; set; } + public Attack SourceAttack { get; } + public Character Character { get; set; } + public Character Attacker { get; set; } + + public AbilityAttackData(Attack sourceAttack, Character character) + { + SourceAttack = sourceAttack; + Character = character; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbility.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbility.cs index 739e7ced1..9b4414901 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbility.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbility.cs @@ -12,12 +12,16 @@ namespace Barotrauma.Abilities public CharacterTalent CharacterTalent { get; } public Character Character { get; } - public virtual bool RequiresAlive => true; + public bool RequiresAlive { get; } + public virtual bool AllowClientSimulation => false; public virtual bool AppliesEffectOnIntervalUpdate => false; private const float DefaultEffectTime = 1.0f; + // currently resets if the character dies. would need to be stored in a dictionary of sorts to maintain through death + + /// /// Used primarily for StatusEffects. Default to constant outside interval abilities. /// @@ -28,6 +32,7 @@ namespace Barotrauma.Abilities CharacterAbilityGroup = characterAbilityGroup; CharacterTalent = characterAbilityGroup.CharacterTalent; Character = CharacterTalent.Character; + RequiresAlive = abilityElement.GetAttributeBool("requiresalive", true); } public bool IsViable() @@ -132,11 +137,5 @@ namespace Barotrauma.Abilities } return flagType; } - - public static float DistanceToSquaredDistance(float distance) - { - return distance * distance; - } - } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffects.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffects.cs index e370e94b3..773992306 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffects.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffects.cs @@ -10,16 +10,41 @@ namespace Barotrauma.Abilities protected readonly List statusEffects; + private readonly bool applyToSelected; + + readonly List targets = new List(); + public CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects")); + applyToSelected = abilityElement.GetAttributeBool("applytoselected", false); } protected void ApplyEffectSpecific(Character targetCharacter) { foreach (var statusEffect in statusEffects) { - statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter); + if (statusEffect.HasTargetType(StatusEffect.TargetType.UseTarget)) + { + // currently used this to spawn items on the targeted character + statusEffect.SetUser(targetCharacter); + statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targetCharacter); + } + else if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters)) + { + targets.Clear(); + targets.AddRange(statusEffect.GetNearbyTargets(targetCharacter.WorldPosition, targets)); + statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targets); + } + else if (statusEffect.HasTargetType(StatusEffect.TargetType.This)) + { + statusEffect.SetUser(Character); + statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, Character); + } + else + { + statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter); + } } } @@ -30,13 +55,17 @@ namespace Barotrauma.Abilities protected override void ApplyEffect(object abilityData) { - if (abilityData is Character targetCharacter) + if (applyToSelected && Character.SelectedCharacter is Character selectedCharacter) + { + ApplyEffectSpecific(selectedCharacter); + } + else if ((abilityData as Character ?? (abilityData as IAbilityCharacter)?.Character) is Character targetCharacter) { ApplyEffectSpecific(targetCharacter); } - else + else { - ApplyEffect(); + ApplyEffect(); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAllies.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAllies.cs new file mode 100644 index 000000000..2b1115068 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAllies.cs @@ -0,0 +1,30 @@ +using Barotrauma.Extensions; +using Microsoft.Xna.Framework; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class CharacterAbilityApplyStatusEffectsToAllies : CharacterAbilityApplyStatusEffects + { + private readonly bool allowSelf; + + public CharacterAbilityApplyStatusEffectsToAllies(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) + { + allowSelf = abilityElement.GetAttributeBool("allowself", true); + } + + + protected override void ApplyEffect() + { + IEnumerable chosenCharacters = Character.GetFriendlyCrew(Character).Where(c => allowSelf || c != Character); + + foreach (Character character in chosenCharacters) + { + ApplyEffectSpecific(character); + } + } + + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAttacker.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAttacker.cs new file mode 100644 index 000000000..1f346accd --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToAttacker.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class CharacterAbilityApplyStatusEffectsToAttacker : CharacterAbilityApplyStatusEffects + { + public CharacterAbilityApplyStatusEffectsToAttacker(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) + { + } + + protected override void ApplyEffect(object abilityData) + { + if ((abilityData as AbilityAttackData)?.Attacker is Character attacker) + { + ApplyEffectSpecific(attacker); + } + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToNearestAlly.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToNearestAlly.cs index a12622816..a0701c782 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToNearestAlly.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToNearestAlly.cs @@ -1,6 +1,5 @@ using Microsoft.Xna.Framework; -using System.Collections.Generic; -using System.Linq; +using System; using System.Xml.Linq; namespace Barotrauma.Abilities @@ -10,7 +9,7 @@ namespace Barotrauma.Abilities protected float squaredMaxDistance; public CharacterAbilityApplyStatusEffectsToNearestAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { - squaredMaxDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue)); + squaredMaxDistance = MathF.Pow(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue), 2); } protected override void ApplyEffect() @@ -20,7 +19,7 @@ namespace Barotrauma.Abilities foreach (Character crewCharacter in Character.GetFriendlyCrew(Character)) { - if (crewCharacter != Character && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(crewCharacter)) is float tempDistance && tempDistance < closestDistance) + if (crewCharacter != Character && Vector2.DistanceSquared(Character.WorldPosition, crewCharacter.WorldPosition) is float tempDistance && tempDistance < closestDistance) { closestCharacter = crewCharacter; closestDistance = tempDistance; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToRandomAlly.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToRandomAlly.cs index 8fe1ea29d..0f1fd20b2 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToRandomAlly.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityApplyStatusEffectsToRandomAlly.cs @@ -1,5 +1,6 @@ using Barotrauma.Extensions; using Microsoft.Xna.Framework; +using System; using System.Collections.Generic; using System.Linq; using System.Xml.Linq; @@ -16,7 +17,7 @@ namespace Barotrauma.Abilities public CharacterAbilityApplyStatusEffectsToRandomAlly(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { - squaredMaxDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue)); + squaredMaxDistance = MathF.Pow(abilityElement.GetAttributeFloat("maxdistance", float.MaxValue), 2); allowDifferentSub = abilityElement.GetAttributeBool("mustbeonsamesub", true); allowSelf = abilityElement.GetAttributeBool("allowself", true); } @@ -26,9 +27,9 @@ namespace Barotrauma.Abilities Character chosenCharacter = null; chosenCharacter = Character.GetFriendlyCrew(Character).Where(c => - (allowSelf ||c != Character) && + (allowSelf || c != Character) && (allowDifferentSub || c.Submarine == Character.Submarine) && - Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(c)) is float tempDistance && + Vector2.DistanceSquared(Character.WorldPosition, c.WorldPosition) is float tempDistance && tempDistance < squaredMaxDistance).GetRandom(); if (chosenCharacter == null) { return; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveMoney.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveMoney.cs index 86e1cb093..4ac33d7c7 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveMoney.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveMoney.cs @@ -7,16 +7,41 @@ namespace Barotrauma.Abilities { public override bool AppliesEffectOnIntervalUpdate => true; - private int amount; + private readonly int amount; + private StatTypes scalingStatType; public CharacterAbilityGiveMoney(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { amount = abilityElement.GetAttributeInt("amount", 0); + scalingStatType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("scalingstattype", "None"), CharacterTalent.DebugIdentifier); + } + + private void ApplyEffectSpecific(Character targetCharacter) + { + float multiplier = 1f; + if (scalingStatType != StatTypes.None) + { + multiplier = 0 + Character.Info.GetSavedStatValue(scalingStatType); + } + + targetCharacter.GiveMoney((int)(multiplier * amount)); + } + + protected override void ApplyEffect(object abilityData) + { + if ((abilityData as Character ?? (abilityData as IAbilityCharacter)?.Character) is Character targetCharacter) + { + ApplyEffectSpecific(targetCharacter); + } + else + { + ApplyEffectSpecific(Character); + } } protected override void ApplyEffect() { - Character.GiveMoney(amount); + ApplyEffectSpecific(Character); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGivePermanentStat.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGivePermanentStat.cs index 2a8797b4e..c8147397c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGivePermanentStat.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGivePermanentStat.cs @@ -8,8 +8,10 @@ namespace Barotrauma.Abilities private readonly string statIdentifier; private readonly StatTypes statType; private readonly float value; + private readonly float maxValue; private readonly bool targetAllies; private readonly bool removeOnDeath; + private readonly bool removeAfterRound; //private readonly float maximumValue; public override bool AppliesEffectOnIntervalUpdate => true; @@ -19,8 +21,10 @@ namespace Barotrauma.Abilities statIdentifier = abilityElement.GetAttributeString("statidentifier", "").ToLowerInvariant(); statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier); value = abilityElement.GetAttributeFloat("value", 0f); + maxValue = abilityElement.GetAttributeFloat("maxvalue", float.MaxValue); targetAllies = abilityElement.GetAttributeBool("targetallies", false); removeOnDeath = abilityElement.GetAttributeBool("removeondeath", true); + removeAfterRound = abilityElement.GetAttributeBool("removeafterround", false); //maximumValue = abilityElement.GetAttributeFloat("maximumvalue", float.MaxValue); } @@ -38,11 +42,11 @@ namespace Barotrauma.Abilities { if (targetAllies) { - Character.GetFriendlyCrew(Character).ForEach(c => c?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath)); + Character.GetFriendlyCrew(Character).ForEach(c => c?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath, removeAfterRound, maxValue)); } else { - Character?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath); + Character?.Info.ChangeSavedStatValue(statType, value, statIdentifier, removeOnDeath, removeAfterRound, maxValue); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveResistance.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveResistance.cs index 5d9cd7fee..707d31449 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveResistance.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveResistance.cs @@ -4,18 +4,23 @@ namespace Barotrauma.Abilities { class CharacterAbilityGiveResistance : CharacterAbility { - private string resistanceId; - private float resistance; + private readonly string resistanceId; + private readonly float multiplier; public CharacterAbilityGiveResistance(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { resistanceId = abilityElement.GetAttributeString("resistanceid", ""); - resistance = abilityElement.GetAttributeFloat("resistance", 1f); + multiplier = abilityElement.GetAttributeFloat("multiplier", 1f); + + if (string.IsNullOrEmpty(resistanceId)) + { + DebugConsole.ThrowError("Error in CharacterAbilityGiveResistance - resistance identifier not set."); + } } public override void InitializeAbility(bool addingFirstTime) { - Character.ChangeAbilityResistance(resistanceId, resistance); + Character.ChangeAbilityResistance(resistanceId, multiplier); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveStat.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveStat.cs index 3b55618d7..c999d3999 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveStat.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityGiveStat.cs @@ -4,10 +4,9 @@ namespace Barotrauma.Abilities { class CharacterAbilityGiveStat : CharacterAbility { - private StatTypes statType; - private float value; + private readonly StatTypes statType; + private readonly float value; - // this and resistance giving should probably be moved directly to charactertalent attributes, as they don't need to interact with either ability group types public CharacterAbilityGiveStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyAttackData.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyAttackData.cs index 6ee9dc1dc..1d32acc85 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyAttackData.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyAttackData.cs @@ -7,8 +7,9 @@ namespace Barotrauma.Abilities { private readonly List afflictions; - float addedDamageMultiplier; - float addedPenetration; + private readonly float addedDamageMultiplier; + private readonly float addedPenetration; + private readonly bool implode; public CharacterAbilityModifyAttackData(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { @@ -18,11 +19,12 @@ namespace Barotrauma.Abilities } addedDamageMultiplier = abilityElement.GetAttributeFloat("addeddamagemultiplier", 0f); addedPenetration = abilityElement.GetAttributeFloat("addedpenetration", 0f); + implode = abilityElement.GetAttributeBool("implode", false); } protected override void ApplyEffect(object abilityData) { - if (abilityData is AttackData attackData) + if (abilityData is AbilityAttackData attackData) { if (attackData.Afflictions == null) { @@ -34,6 +36,13 @@ namespace Barotrauma.Abilities } attackData.DamageMultiplier += addedDamageMultiplier; attackData.AddedPenetration += addedPenetration; + + if (implode) + { + // might have issues, as the method used to be private and only used for pressure death + attackData.Character?.Implode(); + } + } else { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyResistance.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyResistance.cs index 4e44403d7..4317f6745 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyResistance.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyResistance.cs @@ -4,8 +4,8 @@ namespace Barotrauma.Abilities { class CharacterAbilityModifyResistance : CharacterAbility { - private string resistanceId; - private float resistance; + private readonly string resistanceId; + private readonly float resistance; bool lastState; // should probably be split to different classes @@ -13,6 +13,11 @@ namespace Barotrauma.Abilities { resistanceId = abilityElement.GetAttributeString("resistanceid", ""); resistance = abilityElement.GetAttributeFloat("resistance", 1f); + + if (string.IsNullOrEmpty(resistanceId)) + { + DebugConsole.ThrowError("Error in CharacterAbilityModifyResistance - resistance identifier not set."); + } } public override void UpdateCharacterAbility(bool conditionsMatched, float timeSinceLastUpdate) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyStatToSkill.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyStatToSkill.cs new file mode 100644 index 000000000..44435e95d --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyStatToSkill.cs @@ -0,0 +1,52 @@ +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class CharacterAbilityModifyStatToSkill : CharacterAbility + { + private readonly StatTypes statType; + private readonly float maxValue; + private readonly string skillIdentifier; + private readonly bool useAll; + private float lastValue = 0f; + + public CharacterAbilityModifyStatToSkill(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) + { + statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier); + maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f); + skillIdentifier = abilityElement.GetAttributeString("skillidentifier", string.Empty); + useAll = skillIdentifier == "all"; + } + + protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate) + { + Character.ChangeStat(statType, -lastValue); + + if (conditionsMatched) + { + float skillTotal = 0f; + + if (useAll && Character.Info?.Job != null) + { + foreach (Skill skill in Character.Info.Job.Skills) + { + skillTotal += Character.GetSkillLevel(skill.Identifier); + } + skillTotal /= Character.Info.Job.Skills.Count; + } + else + { + skillTotal = Character.GetSkillLevel(skillIdentifier); + } + + lastValue = skillTotal / 100f * maxValue; + Character.ChangeStat(statType, lastValue); + } + else + { + lastValue = 0f; + } + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyValue.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyValue.cs index 7f27c334f..b4e15f0b3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyValue.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityModifyValue.cs @@ -5,42 +5,21 @@ namespace Barotrauma.Abilities class CharacterAbilityModifyValue : CharacterAbility { private float addedValue; - private float multiplierValue; + private float multiplyValue; public CharacterAbilityModifyValue(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { addedValue = abilityElement.GetAttributeFloat("addedvalue", 0f); - multiplierValue = abilityElement.GetAttributeFloat("multipliervalue", 1f); + multiplyValue = abilityElement.GetAttributeFloat("multiplyvalue", 1f); } protected override void ApplyEffect(object abilityData) { - if (abilityData is AbilityValue abilityValue) + if (abilityData is IAbilityValue abilityValue) { - ApplyEffectSpecific(abilityValue); + abilityValue.Value += addedValue; + abilityValue.Value *= multiplyValue; } - else if (abilityData is (object _, AbilityValue tupleAbilityValue)) - { - ApplyEffectSpecific(tupleAbilityValue); - } - } - - private void ApplyEffectSpecific(AbilityValue abilityValue) - { - abilityValue.Value += addedValue; - abilityValue.Value *= multiplierValue; - } - - } - - // this seems like a real silly way to have to pass values by reference into these same interfaces - // if more of these are required, maybe there should be an additional set of interfaces to easily pass values by reference instead - class AbilityValue - { - public float Value { get; set; } - public AbilityValue(float value) - { - Value = value; } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityResetPermanentStat.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityResetPermanentStat.cs index eb57809e5..06706568c 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityResetPermanentStat.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityResetPermanentStat.cs @@ -5,7 +5,7 @@ namespace Barotrauma.Abilities class CharacterAbilityResetPermanentStat : CharacterAbility { private readonly string statIdentifier; - public override bool RequiresAlive => false; + public override bool AppliesEffectOnIntervalUpdate => true; public CharacterAbilityResetPermanentStat(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityRevive.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityRevive.cs new file mode 100644 index 000000000..15772796c --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CharacterAbilityRevive.cs @@ -0,0 +1,29 @@ +using Microsoft.Xna.Framework; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class CharacterAbilityRevive : CharacterAbility + { + public override bool AppliesEffectOnIntervalUpdate => true; + + public CharacterAbilityRevive(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) + { + } + + private void ApplyEffectSpecific() + { + Character.Revive(); + } + + protected override void ApplyEffect() + { + ApplyEffectSpecific(); + } + + protected override void ApplyEffect(object abilityData) + { + ApplyEffectSpecific(); + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityAlienHoarder.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityAlienHoarder.cs new file mode 100644 index 000000000..9b498a085 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityAlienHoarder.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class CharacterAbilityAlienHoarder : CharacterAbility + { + private readonly float addedDamageMultiplierPerItem; + private readonly int maxAmount; + private readonly string[] tags; + + public CharacterAbilityAlienHoarder(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) + { + addedDamageMultiplierPerItem = abilityElement.GetAttributeFloat("addeddamagemultiplierperitem", 0f); + maxAmount = abilityElement.GetAttributeInt("maxamount", 0); + tags = abilityElement.GetAttributeStringArray("tags", Array.Empty(), convertToLowerInvariant: true); + } + + protected override void ApplyEffect(object abilityData) + { + if (abilityData is AbilityAttackData attackData) + { + float totalAddedDamageMultiplier = 0f; + foreach (Item item in Character.Inventory.AllItems) + { + if (tags.Any(t => item.Prefab.Tags.Any(p => t == p))) + { + totalAddedDamageMultiplier += addedDamageMultiplierPerItem; + } + } + attackData.DamageMultiplier += addedDamageMultiplierPerItem; + } + else + { + LogAbilityDataMismatch(); + } + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityApprenticeship.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityApprenticeship.cs index 808ca4b0b..8196229ff 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityApprenticeship.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityApprenticeship.cs @@ -12,9 +12,9 @@ namespace Barotrauma.Abilities protected override void ApplyEffect(object abilityData) { - if (abilityData is (string skillIdentifier, Character character) && character != Character) + if (abilityData is AbilityStringCharacter abilityStringCharacter && abilityStringCharacter.Character != Character) { - character.Info?.IncreaseSkillLevel(skillIdentifier, 1.0f, character.Position + Vector2.UnitY * 175.0f); + Character.Info?.IncreaseSkillLevel(abilityStringCharacter.String, 1.0f, abilityStringCharacter.Character.Position + Vector2.UnitY * 175.0f); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityByTheBook.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityByTheBook.cs new file mode 100644 index 000000000..de83bf9a9 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityByTheBook.cs @@ -0,0 +1,36 @@ +using System.Collections.Generic; +using System.Linq; +using System.Xml.Linq; + +namespace Barotrauma.Abilities +{ + class CharacterAbilityByTheBook : CharacterAbility + { + private int moneyAmount; + private int max; + + public CharacterAbilityByTheBook(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) + { + moneyAmount = abilityElement.GetAttributeInt("moneyamount", 0); + max = abilityElement.GetAttributeInt("max", 0); + } + + protected override void ApplyEffect() + { + IEnumerable enemyCharacters = Character.CharacterList.Where(c => c.TeamID == CharacterTeamType.None); + + int timesGiven = 0; + foreach (Character enemyCharacter in enemyCharacters) + { + if (!enemyCharacter.IsHuman) { continue; } + if (enemyCharacter.Submarine == null || enemyCharacter.Submarine != Submarine.MainSub) { continue; } + if (enemyCharacter.IsDead) { continue; } + if (!enemyCharacter.LockHands) { continue; } + if (timesGiven > max) { continue; } + Character.GiveMoney(moneyAmount); + timesGiven++; + } + + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityInsurancePolicy.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityInsurancePolicy.cs index 9241769e4..1583bd53b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityInsurancePolicy.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityInsurancePolicy.cs @@ -9,45 +9,22 @@ namespace Barotrauma.Abilities class CharacterAbilityInsurancePolicy : CharacterAbility { public override bool AppliesEffectOnIntervalUpdate => true; - public override bool RequiresAlive => false; - private readonly int moneyPerLevel; - private bool hasOccurred = false; + private readonly int moneyPerMission; private static List clientsAlreadyUsed = new List(); public CharacterAbilityInsurancePolicy(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { - moneyPerLevel = abilityElement.GetAttributeInt("moneyperlevel", 0); + moneyPerMission = abilityElement.GetAttributeInt("moneypermission", 0); } protected override void ApplyEffect() { - if (Character?.Info is CharacterInfo info && !hasOccurred) + if (Character?.Info is CharacterInfo info) { - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) - { - foreach (Client client in GameMain.NetworkMember.ConnectedClients) - { - if (client.Character == Character && clientsAlreadyUsed.Contains(client)) { return; } - } - } - Character.GiveMoney(moneyPerLevel * info.GetCurrentLevel()); - hasOccurred = true; - - // this is an ugly way to do this, but this effect should not occur more than once per round for a client - // this seemed like the simplest way to do it since characters are instantiated from scratch each time - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsServer) - { - foreach (Client client in GameMain.NetworkMember.ConnectedClients) - { - if (client.Character == Character) - { - clientsAlreadyUsed.Add(client); - } - } - } + Character.GiveMoney(moneyPerMission * info.MissionsCompletedSinceDeath); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityPsychoClown.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityPsychoClown.cs index 4e7ac7225..61e9d9cf6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityPsychoClown.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityPsychoClown.cs @@ -5,14 +5,14 @@ namespace Barotrauma.Abilities class CharacterAbilityPsychoClown : CharacterAbility { private StatTypes statType; - private float value; + private float maxValue; private string afflictionIdentifier; private float lastValue = 0f; public CharacterAbilityPsychoClown(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { statType = CharacterAbilityGroup.ParseStatType(abilityElement.GetAttributeString("stattype", ""), CharacterTalent.DebugIdentifier); - value = abilityElement.GetAttributeFloat("value", 0f); + maxValue = abilityElement.GetAttributeFloat("maxvalue", 0f); afflictionIdentifier = abilityElement.GetAttributeString("afflictionidentifier", ""); } @@ -32,7 +32,7 @@ namespace Barotrauma.Abilities afflictionStrength = affliction.Strength / affliction.Prefab.MaxStrength; } - lastValue = afflictionStrength * value; + lastValue = afflictionStrength * maxValue; Character.ChangeStat(statType, lastValue); } else diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityRegenerateLoot.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityRegenerateLoot.cs index 5a2ff174e..cb82641f5 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityRegenerateLoot.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityRegenerateLoot.cs @@ -8,6 +8,8 @@ namespace Barotrauma.Abilities { class CharacterAbilityRegenerateLoot : CharacterAbility { + // not maintained through death, so it's possible for players to respawn and re-loot chests + // seems like a minor issue for now List openedContainers = new List(); public CharacterAbilityRegenerateLoot(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityStonewall.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityStonewall.cs index 6597c6973..cc2aa51c0 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityStonewall.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityStonewall.cs @@ -10,20 +10,20 @@ namespace Barotrauma.Abilities { private readonly List statusEffects; private readonly List statusEffectsReset; - private int maxEnemyCount; - private float squaredDistance; + private readonly int maxEnemyCount; + private readonly float squaredDistance; public CharacterAbilityStonewall(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { statusEffects = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffects")); statusEffectsReset = CharacterAbilityGroup.ParseStatusEffects(CharacterTalent, abilityElement.GetChildElement("statuseffectsreset")); maxEnemyCount = abilityElement.GetAttributeInt("maxenemycount", 0); - squaredDistance = DistanceToSquaredDistance(abilityElement.GetAttributeFloat("distance", 0)); + squaredDistance = MathF.Pow(abilityElement.GetAttributeFloat("distance", 0), 2); } protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate) { - int numberOfEnemiesInRange = Character.CharacterList.Where(c => !HumanAIController.IsFriendly(Character, c) && !c.IsDead && Vector2.DistanceSquared(Character.SimPosition, Character.GetRelativeSimPosition(c)) < squaredDistance).Count(); + int numberOfEnemiesInRange = Character.CharacterList.Count(c => !HumanAIController.IsFriendly(Character, c) && !c.IsDead && Vector2.DistanceSquared(Character.WorldPosition, c.WorldPosition) < squaredDistance); foreach (var statusEffect in statusEffectsReset) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityTandemFire.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityTandemFire.cs index 284ec4ae6..e3b3ba0c3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityTandemFire.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/Abilities/CustomAbilities/CharacterAbilityTandemFire.cs @@ -8,6 +8,7 @@ namespace Barotrauma.Abilities { class CharacterAbilityTandemFire : CharacterAbilityApplyStatusEffectsToNearestAlly { + // this should just be its own class, misleading to inherit here private string tag; public CharacterAbilityTandemFire(CharacterAbilityGroup characterAbilityGroup, XElement abilityElement) : base(characterAbilityGroup, abilityElement) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroup.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroup.cs index c49fa439c..1c5471f24 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroup.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroup.cs @@ -14,6 +14,10 @@ namespace Barotrauma.Abilities // currently only used to turn off simulation if random conditions are in use public bool IsActive { get; private set; } = true; + protected int maxTriggerCount { get; } + protected int timesTriggered = 0; + + // add support for OR conditions? protected readonly List abilityConditions = new List(); @@ -24,7 +28,7 @@ namespace Barotrauma.Abilities { CharacterTalent = characterTalent; Character = CharacterTalent.Character; - + maxTriggerCount = abilityElementGroup.GetAttributeInt("maxtriggercount", int.MaxValue); foreach (XElement subElement in abilityElementGroup.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupEffect.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupEffect.cs index f49851390..184c5e8a9 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupEffect.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupEffect.cs @@ -27,6 +27,7 @@ namespace Barotrauma.Abilities private bool IsApplicable(object abilityData) { + if (timesTriggered >= maxTriggerCount) { return false; } return abilityConditions.All(c => c.MatchesCondition(abilityData)); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupInterval.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupInterval.cs index 6597bbcd6..4e3d0896f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupInterval.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/AbilityGroups/CharacterAbilityGroupInterval.cs @@ -14,6 +14,7 @@ namespace Barotrauma.Abilities private float effectDelay; private float effectDelayTimer; + public CharacterAbilityGroupInterval(CharacterTalent characterTalent, XElement abilityElementGroup) : base(characterTalent, abilityElementGroup) { // too many overlapping intervals could cause hitching? maybe randomize a little @@ -42,6 +43,7 @@ namespace Barotrauma.Abilities } private bool IsApplicable() { + if (timesTriggered >= maxTriggerCount) { return false; } return abilityConditions.All(c => c.MatchesCondition()); } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/CharacterTalent.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/CharacterTalent.cs index 9c64f85ea..e9ac4347a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/CharacterTalent.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/CharacterTalent.cs @@ -111,8 +111,7 @@ namespace Barotrauma public static AbilityEffectType ParseAbilityEffectType(CharacterTalent characterTalent, string abilityEffectTypeString) { - AbilityEffectType abilityEffectType = AbilityEffectType.Undefined; - if (!Enum.TryParse(abilityEffectTypeString, true, out abilityEffectType)) + if (!Enum.TryParse(abilityEffectTypeString, true, out AbilityEffectType abilityEffectType)) { DebugConsole.ThrowError("Invalid ability effect type \"" + abilityEffectTypeString + "\" in CharacterTalent (" + characterTalent.DebugIdentifier + ")"); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentPrefab.cs index 5c42eb8e7..277af65b0 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentPrefab.cs @@ -1,7 +1,5 @@ -using Microsoft.Xna.Framework; -using System; +using System; using System.Collections.Generic; -using System.Linq; using System.Xml.Linq; namespace Barotrauma @@ -13,6 +11,12 @@ namespace Barotrauma public ContentPackage ContentPackage { get; private set; } public string FilePath { get; private set; } + public string DisplayName { get; private set; } + + public string Description { get; private set; } + + public readonly Sprite Icon; + public static readonly PrefabCollection TalentPrefabs = new PrefabCollection(); public XElement ConfigElement @@ -26,7 +30,51 @@ namespace Barotrauma FilePath = filePath; ConfigElement = element; Identifier = element.GetAttributeString("identifier", "noidentifier"); + DisplayName = TextManager.Get("talentname." + Identifier, returnNull: true) ?? Identifier; this.CalculatePrefabUIntIdentifier(TalentPrefabs); + + foreach (XElement subElement in element.Elements()) + { + switch (subElement.Name.ToString().ToLowerInvariant()) + { + case "icon": + Icon = new Sprite(subElement); + break; + case "description": + string tempDescription = Description; + TextManager.ConstructDescription(ref tempDescription, subElement); + Description = tempDescription; + break; + } + } + + if (string.IsNullOrEmpty(Description)) + { + if (element.Attribute("description") != null) + { + string description = element.GetAttributeString("description", string.Empty); + Description = TextManager.Get(description, returnNull: true) ?? description; + } + else + { + Description = TextManager.Get("talentdescription." + Identifier, returnNull: true) ?? string.Empty; + } + } + +#if DEBUG + if (!TextManager.ContainsTag("talentname." + Identifier)) + { + DebugConsole.AddWarning($"Name for the talent \"{Identifier}\" not found in the text files."); + } + if (string.IsNullOrEmpty(Description)) + { + DebugConsole.AddWarning($"Description for the talent \"{Identifier}\" not configured"); + } + if (Description.Contains('[')) + { + DebugConsole.ThrowError($"Description for the talent \"{Identifier}\" contains brackets - was some variable not replaced correctly? ({Description})"); + } +#endif } private bool disposed = false; @@ -94,9 +142,6 @@ namespace Barotrauma { LoadFromFile(file); } - } - - } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentTree.cs b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentTree.cs index 2a2f67bdf..6483edaa1 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentTree.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Characters/Talents/TalentTree.cs @@ -14,6 +14,7 @@ namespace Barotrauma private static HashSet subtreeTalents = new HashSet(); + private const string PlaceholderTalent = "placeholder"; public XElement ConfigElement { get; @@ -41,6 +42,7 @@ namespace Barotrauma HashSet duplicateSet = new HashSet(); foreach (string talent in TalentSubTrees.SelectMany(s => s.TalentOptionStages.SelectMany(o => o.Talents.Select(t => t.Identifier)))) { + if (talent == PlaceholderTalent) { continue; } TalentPrefab talentPrefab = TalentPrefab.TalentPrefabs.Find(c => c.Identifier.Equals(talent, StringComparison.OrdinalIgnoreCase)); if (talentPrefab == null) { @@ -118,6 +120,7 @@ namespace Barotrauma public static bool IsViableTalentForCharacter(Character character, string talentIdentifier, IEnumerable selectedTalents) { + if (talentIdentifier == PlaceholderTalent) { return false; } if (character?.Info?.Job.Prefab == null) { return false; } if (character.Info.GetTotalTalentPoints() - selectedTalents.Count() <= 0) { return false; } @@ -178,7 +181,7 @@ namespace Barotrauma foreach (XElement talentOptionsElement in subTreeElement.GetChildElements("talentoptions")) { - TalentOptionStages.Add(new TalentOption(talentOptionsElement)); + TalentOptionStages.Add(new TalentOption(talentOptionsElement, Identifier)); } } @@ -186,32 +189,19 @@ namespace Barotrauma class TalentOption { - public readonly List Talents = new List(); + public readonly List Talents = new List(); - public TalentOption(XElement talentOptionsElement) + public TalentOption(XElement talentOptionsElement, string debugIdentifier) { foreach (XElement talentOptionElement in talentOptionsElement.GetChildElements("talentoption")) { - Talents.Add(new Talent(talentOptionElement)); - } - } - } - - class Talent - { - public readonly string Identifier; - public readonly Sprite Icon; - public Talent(XElement talentOptionElement) - { - Identifier = talentOptionElement.GetAttributeString("identifier", ""); - foreach (XElement subElement in talentOptionElement.Elements()) - { - switch (subElement.Name.ToString().ToLowerInvariant()) + string identifier = talentOptionElement.GetAttributeString("identifier", string.Empty); + if (!TalentPrefab.TalentPrefabs.ContainsKey(identifier)) { - case "icon": - Icon = new Sprite(subElement); - break; + DebugConsole.ThrowError($"Error in talent tree \"{debugIdentifier}\" - could not find a talent with the identifier \"{identifier}\"."); + return; } + Talents.Add(TalentPrefab.TalentPrefabs[identifier]); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs b/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs index e768d963d..39810a12f 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/DebugConsole.cs @@ -212,7 +212,7 @@ namespace Barotrauma }; }, isCheat: true)); - commands.Add(new Command("spawnitem", "spawnitem [itemname/itemidentifier] [cursor/inventory/cargo/random/[name]]: Spawn an item at the position of the cursor, in the inventory of the controlled character, in the inventory of the client with the given name, or at a random spawnpoint if the last parameter is omitted or \"random\".", + commands.Add(new Command("spawnitem", "spawnitem [itemname/itemidentifier] [cursor/inventory/cargo/random/[name]] [amount]: Spawn an item at the position of the cursor, in the inventory of the controlled character, in the inventory of the client with the given name, or at a random spawnpoint if the last parameter is omitted or \"random\".", (string[] args) => { try @@ -841,8 +841,8 @@ namespace Barotrauma commands.Add(new Command("givetalent", "give [player] testing [talent]", (string[] args) => { - if (args.Length < 2) return; - var character = FindMatchingCharacter(args.Skip(1).ToArray()) ?? Character.Controlled; + if (args.Length == 0) { return; } + var character = args.Length >= 2 ? FindMatchingCharacter(args.Skip(1).ToArray()) : Character.Controlled; if (character != null) { character.GiveTalent(args[0]); @@ -858,8 +858,8 @@ namespace Barotrauma return new string[][] { - talentNames.ToArray(), - Character.CharacterList.Select(c => c.Name).Distinct().ToArray() + talentNames.ToArray(), + Character.CharacterList.Select(c => c.Name).Distinct().ToArray() }; }, isCheat: true)); @@ -2033,9 +2033,17 @@ namespace Barotrauma return; } + int amount = 1; if (args.Length > 1) { - switch (args.Last()) + string spawnLocation = args.Last(); + if (args.Length > 2) + { + spawnLocation = args[^2]; + if (!int.TryParse(args[^1], NumberStyles.Any, CultureInfo.InvariantCulture, out amount)) { amount = 1; } + } + + switch (spawnLocation) { case "cursor": spawnPos = cursorPos; @@ -2063,37 +2071,40 @@ namespace Barotrauma spawnPos = wp == null ? Vector2.Zero : wp.WorldPosition; } - if (spawnPos != null) + for (int i = 0; i < amount; i++) { - if (Entity.Spawner == null) + if (spawnPos != null) { - new Item(itemPrefab, spawnPos.Value, null); - } - else - { - Entity.Spawner?.AddToSpawnQueue(itemPrefab, spawnPos.Value); - } - } - else if (spawnInventory != null) - { - if (Entity.Spawner == null) - { - var spawnedItem = new Item(itemPrefab, Vector2.Zero, null); - spawnInventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots); - onItemSpawned(spawnedItem); - } - else - { - Entity.Spawner?.AddToSpawnQueue(itemPrefab, spawnInventory, onSpawned: onItemSpawned); - } - - static void onItemSpawned(Item item) - { - if (item.ParentInventory?.Owner is Character character) + if (Entity.Spawner == null) { - foreach (WifiComponent wifiComponent in item.GetComponents()) + new Item(itemPrefab, spawnPos.Value, null); + } + else + { + Entity.Spawner?.AddToSpawnQueue(itemPrefab, spawnPos.Value); + } + } + else if (spawnInventory != null) + { + if (Entity.Spawner == null) + { + var spawnedItem = new Item(itemPrefab, Vector2.Zero, null); + spawnInventory.TryPutItem(spawnedItem, null, spawnedItem.AllowedSlots); + onItemSpawned(spawnedItem); + } + else + { + Entity.Spawner?.AddToSpawnQueue(itemPrefab, spawnInventory, onSpawned: onItemSpawned); + } + + static void onItemSpawned(Item item) + { + if (item.ParentInventory?.Owner is Character character) { - wifiComponent.TeamID = character.TeamID; + foreach (WifiComponent wifiComponent in item.GetComponents()) + { + wifiComponent.TeamID = character.TeamID; + } } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Enums.cs b/Barotrauma/BarotraumaShared/SharedSource/Enums.cs index c127555da..346ceb31e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Enums.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Enums.cs @@ -45,14 +45,18 @@ OnReduceAffliction, OnAddDamageAffliction, OnSelfRagdoll, + OnRoundEnd, OnAnyMissionCompleted, OnAllMissionsCompleted, OnGiveOrder, OnCrewKillCharacter, + OnKillCharacter, OnDieToCharacter, OnAllyGainMissionExperience, OnGainMissionExperience, OnGainMissionMoney, + OnItemDeconstructed, + OnItemDeconstructedMaterial, AfterSubmarineAttacked, } @@ -68,23 +72,32 @@ // Character attributes MaximumHealthMultiplier, MovementSpeed, + WalkingSpeed, SwimmingSpeed, BuffDurationMultiplier, DebuffDurationMultiplier, + MedicalItemEffectivenessMultiplier, // Combat AttackMultiplier, + TeamAttackMultiplier, RangedAttackSpeed, TurretAttackSpeed, + TurretPowerCostReduction, MeleeAttackSpeed, - SpreadMultiplier, + MeleeAttackMultiplier, + RangedSpreadReduction, // Utility RepairSpeed, + DeconstructorSpeedMultiplier, // Misc ReputationGainMultiplier, MissionMoneyGainMultiplier, ExperienceGainMultiplier, MissionExperienceGainMultiplier, - + // these should be deprecated and moved to their own implementation, no sense making them share space with stat values + Coathor, + WarriorPoetMissionRuns, + WarriorPoetEnemiesKilled, } public enum AbilityFlags @@ -95,6 +108,8 @@ IgnoredByEnemyAI, MoveNormallyWhileDragging, CanTinker, + GainSkillPastMaximum, + RetainExperienceForNewCharacter } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/Mission.cs b/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/Mission.cs index 47b9637e2..d6adbf7b5 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/Mission.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Events/Missions/Mission.cs @@ -362,11 +362,16 @@ namespace Barotrauma } // apply money gains afterwards to prevent them from affecting XP gains - var moneyGainMultiplier = new AbilityValue(1f); - crewCharacters.ForEach(c => c.CheckTalents(AbilityEffectType.OnGainMissionMoney, (this, moneyGainMultiplier))); - crewCharacters.ForEach(c => moneyGainMultiplier.Value += c.GetStatValue(StatTypes.MissionMoneyGainMultiplier)); + var moneyGainMission = new AbilityValueMission(1f, this); + crewCharacters.ForEach(c => c.CheckTalents(AbilityEffectType.OnGainMissionMoney, moneyGainMission)); + crewCharacters.ForEach(c => moneyGainMission.Value += c.GetStatValue(StatTypes.MissionMoneyGainMultiplier)); - campaign.Money += (int)(reward * moneyGainMultiplier.Value); + campaign.Money += (int)(reward * moneyGainMission.Value); + + foreach (Character character in crewCharacters) + { + character.Info.MissionsCompletedSinceDeath++; + } foreach (KeyValuePair reputationReward in ReputationRewards) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs index fdf7fa68a..4f941e847 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/CampaignMode.cs @@ -531,6 +531,7 @@ namespace Barotrauma if (Level.Loaded.EndOutpost == null) { Submarine closestSub = Submarine.FindClosest(Level.Loaded.EndExitPosition, ignoreOutposts: true, ignoreRespawnShuttle: true, teamType: leavingPlayers.FirstOrDefault()?.TeamID); + if (closestSub == null) { return null; } return closestSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : closestSub; } else diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/MultiPlayerCampaign.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/MultiPlayerCampaign.cs index b5bb43eca..739f6f112 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/MultiPlayerCampaign.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameModes/MultiPlayerCampaign.cs @@ -173,6 +173,12 @@ namespace Barotrauma if (matchingSub != null) { availableSubs.Add(matchingSub); } } break; + case "savedexperiencepoints": + foreach (XElement savedExp in subElement.Elements()) + { + savedExperiencePoints.Add(new SavedExperiencePoints(savedExp)); + } + break; #endif } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs index 0a2e0bdd3..8b6cbeb36 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/GameSession/GameSession.cs @@ -661,7 +661,7 @@ namespace Barotrauma #if SERVER return GameMain.Server.ConnectedClients.Select(c => c.Character).Where(c => c.Info != null); #else - return GameMain.GameSession.CrewManager.CharacterInfos.Select(i => i.Character).Where(c => c != null); + return GameMain.GameSession.CrewManager.GetCharacters().Where(c => c.Info != null); #endif } @@ -671,28 +671,33 @@ namespace Barotrauma try { - IEnumerable crewCharacters = GameSession.GetSessionCrewCharacters(); + IEnumerable crewCharacters = GetSessionCrewCharacters(); foreach (Mission mission in missions) { mission.End(); } + foreach (Character character in crewCharacters) + { + character.CheckTalents(AbilityEffectType.OnRoundEnd); + } + if (missions.Any()) { if (missions.Any(m => m.Completed)) { - foreach (CharacterInfo characterInfo in GameMain.GameSession.CrewManager.CharacterInfos) + foreach (Character character in crewCharacters) { - characterInfo.Character?.CheckTalents(AbilityEffectType.OnAnyMissionCompleted); + character.CheckTalents(AbilityEffectType.OnAnyMissionCompleted); } } if (missions.All(m => m.Completed)) { - foreach (CharacterInfo characterInfo in GameMain.GameSession.CrewManager.CharacterInfos) + foreach (Character character in crewCharacters) { - characterInfo.Character?.CheckTalents(AbilityEffectType.OnAllMissionsCompleted); + character.CheckTalents(AbilityEffectType.OnAllMissionsCompleted); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/CharacterInventory.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/CharacterInventory.cs index 49bfdb3e8..8b65d6f30 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/CharacterInventory.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/CharacterInventory.cs @@ -9,7 +9,7 @@ namespace Barotrauma [Flags] public enum InvSlotType { - None = 0, Any = 1, RightHand = 2, LeftHand = 4, Head = 8, InnerClothes = 16, OuterClothes = 32, Headset = 64, Card = 128, Bag = 256 + None = 0, Any = 1, RightHand = 2, LeftHand = 4, Head = 8, InnerClothes = 16, OuterClothes = 32, Headset = 64, Card = 128, Bag = 256, HealthInterface = 512 }; partial class CharacterInventory : Inventory diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/GeneticMaterial.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/GeneticMaterial.cs new file mode 100644 index 000000000..e9aa55e2b --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/GeneticMaterial.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Generic; +using System.Xml.Linq; +using System.Linq; +using Barotrauma.Extensions; +using Barotrauma.Networking; +using Microsoft.Xna.Framework; + +namespace Barotrauma.Items.Components +{ + partial class GeneticMaterial : ItemComponent, IServerSerializable + { + private readonly string materialName; + + private Character targetCharacter; + private AfflictionPrefab selectedEffect, selectedTaintedEffect; + + [Serialize("", false)] + public string Effect + { + get; + set; + } + + [Serialize("geneticmaterialdebuff", false)] + public string TaintedEffect + { + get; + set; + } + + private bool tainted; + [Serialize(false, false)] + public bool Tainted + { + get { return tainted; } + private set + { + if (!value) { return; } + tainted = true; + item.AllowDeconstruct = false; + if (!string.IsNullOrEmpty(TaintedEffect)) + { + selectedTaintedEffect = AfflictionPrefab.Prefabs.Where(a => + a.Identifier.Equals(TaintedEffect, StringComparison.OrdinalIgnoreCase) || + a.AfflictionType.Equals(TaintedEffect, StringComparison.OrdinalIgnoreCase)).GetRandom(); + } + } + } + + //only for saving the selected tainted effect + [Serialize("", false)] + public string SelectedTaintedEffect + { + get { return selectedTaintedEffect?.Identifier ?? string.Empty; } + private set + { + if (string.IsNullOrEmpty(value)) { return; } + selectedTaintedEffect = AfflictionPrefab.Prefabs.Find(a => a.Identifier == value); + } + } + + + public GeneticMaterial(Item item, XElement element) + : base(item, element) + { + string nameId = element.GetAttributeString("nameidentifier", ""); + if (!string.IsNullOrEmpty(nameId)) + { + materialName = TextManager.Get(nameId); + } + if (!string.IsNullOrEmpty(Effect)) + { + selectedEffect = AfflictionPrefab.Prefabs.Where(a => + a.Identifier.Equals(Effect, StringComparison.OrdinalIgnoreCase) || + a.AfflictionType.Equals(Effect, StringComparison.OrdinalIgnoreCase)).GetRandom(); + } + } + + [Serialize(3.0f, false)] + public float ConditionIncreaseOnCombineMin { get; set; } + + [Serialize(8.0f, false)] + public float ConditionIncreaseOnCombineMax { get; set; } + + public bool CanBeCombinedWith(GeneticMaterial otherGeneticMaterial) + { + return !tainted && otherGeneticMaterial != null && !otherGeneticMaterial.tainted; + } + + public override void Equip(Character character) + { + if (character == null) { return; } + IsActive = true; + + if (targetCharacter != null) { return; } + + if (tainted) + { + if (selectedTaintedEffect != null) + { + float selectedTaintedEffectStrength = item.ConditionPercentage / 100.0f * selectedTaintedEffect.MaxStrength; + character.CharacterHealth.ApplyAffliction(null, selectedTaintedEffect.Instantiate(selectedTaintedEffectStrength)); + targetCharacter = character; +#if SERVER + item.CreateServerEvent(this); +#endif + } + } + if (selectedEffect != null) + { + ApplyStatusEffects(ActionType.OnWearing, 1.0f); + float selectedEffectStrength = item.ConditionPercentage / 100.0f * selectedEffect.MaxStrength; + character.CharacterHealth.ApplyAffliction(null, selectedEffect.Instantiate(selectedEffectStrength)); + targetCharacter = character; +#if SERVER + item.CreateServerEvent(this); +#endif + } + } + + public override void Update(float deltaTime, Camera cam) + { + base.Update(deltaTime, cam); + if (targetCharacter != null) + { + if (!targetCharacter.HasEquippedItem(item) && + (item.Container == null || !targetCharacter.HasEquippedItem(item.Container) || !(item.Container.GetComponent()?.AutoInject ?? false))) + { + item.ApplyStatusEffects(ActionType.OnSevered, 1.0f, targetCharacter); + var currentEffect = tainted ? selectedTaintedEffect : selectedEffect; + targetCharacter.CharacterHealth.ReduceAffliction(null, currentEffect.Identifier, currentEffect.MaxStrength); + targetCharacter = null; + IsActive = false; + } + } + } + + public bool Combine(GeneticMaterial otherGeneticMaterial, Character user) + { + if (!CanBeCombinedWith(otherGeneticMaterial)) { return false; } + if (item.Prefab == otherGeneticMaterial.item.Prefab) + { + item.Condition = Math.Max(item.Condition, otherGeneticMaterial.item.Condition) + Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax); + float taintedProbability = GetTaintedProbabilityOnRefine(user); + if (taintedProbability >= Rand.Range(0.0f, 1.0f)) + { + MakeTainted(); + } + return true; + } + else + { + item.Condition = otherGeneticMaterial.Item.Condition = + (item.Condition + otherGeneticMaterial.Item.Condition) / 2.0f + Rand.Range(ConditionIncreaseOnCombineMin, ConditionIncreaseOnCombineMax); + item.OwnInventory?.TryPutItem(otherGeneticMaterial.Item, user: null); + MakeTainted(); + return false; + } + } + + private float GetTaintedProbabilityOnRefine(Character user) + { + if (user == null) { return 1.0f; } + float probability = MathHelper.Lerp(0.0f, 0.99f, item.Condition / 100.0f); + probability *= MathHelper.Lerp(1.0f, 0.25f, DegreeOfSuccess(user)); + return probability; + } + + private void MakeTainted() + { + if (GameMain.NetworkMember?.IsClient ?? false) { return; } + Tainted = true; +#if SERVER + item.CreateServerEvent(this); +#endif + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs index b7174abdf..312df8e44 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/MeleeWeapon.cs @@ -181,7 +181,7 @@ namespace Barotrauma.Items.Components if (aim) { hitPos = MathUtils.WrapAnglePi(Math.Min(hitPos + deltaTime * 5f, MathHelper.PiOver4)); - ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, false, hitPos, holdAngle + hitPos); + ac.HoldItem(deltaTime, item, handlePos, aimPos, Vector2.Zero, false, hitPos, holdAngle + hitPos, aimingMelee: true); } else { @@ -356,6 +356,7 @@ namespace Barotrauma.Items.Components if (Attack != null) { Attack.SetUser(User); + Attack.DamageMultiplier = 1 + User.GetStatValue(StatTypes.MeleeAttackMultiplier); if (targetLimb != null) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RangedWeapon.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RangedWeapon.cs index d628c5d40..14d626d16 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RangedWeapon.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Holdable/RangedWeapon.cs @@ -107,7 +107,7 @@ namespace Barotrauma.Items.Components if (ReloadTimer < 0.0f) { ReloadTimer = 0.0f; - // was this an optimization or related to something else? currently disabled for charge-type weapons + // was this an optimization or related to something else? it cannot occur for charge-type weapons //IsActive = false; if (MaxChargeTime == 0.0f) { @@ -118,7 +118,7 @@ namespace Barotrauma.Items.Components float previousChargeTime = currentChargeTime; - float chargeDeltaTime = tryingToCharge ? deltaTime : -deltaTime; + float chargeDeltaTime = tryingToCharge && ReloadTimer <= 0f ? deltaTime : -deltaTime; currentChargeTime = Math.Clamp(currentChargeTime + chargeDeltaTime, 0f, MaxChargeTime); tryingToCharge = false; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemComponent.cs index 90fd92739..c146ae67e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemComponent.cs @@ -982,7 +982,7 @@ namespace Barotrauma.Items.Components AIObjectiveContainItem containObjective = null; if (character.AIController is HumanAIController aiController) { - containObjective = new AIObjectiveContainItem(character, container.GetContainableItemIdentifiers.ToArray(), container, currentObjective.objectiveManager, spawnItemIfNotFound: spawnItemIfNotFound) + containObjective = new AIObjectiveContainItem(character, container.ContainableItemIdentifiers.ToArray(), container, currentObjective.objectiveManager, spawnItemIfNotFound: spawnItemIfNotFound) { targetItemCount = itemCount, Equip = equip, diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemContainer.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemContainer.cs index 336a5b183..76093809d 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemContainer.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/ItemContainer.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Xml.Linq; using Barotrauma.Extensions; using FarseerPhysics; +using System.Collections.Immutable; namespace Barotrauma.Items.Components { @@ -23,6 +24,28 @@ namespace Barotrauma.Items.Components } } + class SlotRestrictions + { + public readonly int MaxStackSize; + public readonly List ContainableItems; + + public SlotRestrictions(int maxStackSize, List containableItems) + { + MaxStackSize = maxStackSize; + ContainableItems = containableItems; + } + + public bool MatchesItem(Item item) + { + return ContainableItems == null || ContainableItems.Count == 0 || ContainableItems.Any(c => c.MatchesItem(item)); + } + + public bool MatchesItem(ItemPrefab itemPrefab) + { + return ContainableItems == null || ContainableItems.Count == 0 || ContainableItems.Any(c => c.MatchesItem(itemPrefab)); + } + } + private bool alwaysContainedItemsSpawned; public ItemInventory Inventory; @@ -73,6 +96,7 @@ namespace Barotrauma.Items.Components #endif [Serialize("0.0,0.0", false, description: "The interval at which the contained items are spaced apart from each other (in pixels).")] public Vector2 ItemInterval { get; set; } + [Serialize(100, false, description: "How many items are placed in a row before starting a new row.")] public int ItemsPerRow { get; set; } @@ -90,7 +114,6 @@ namespace Barotrauma.Items.Components set; } - [Serialize(false, false, description: "If set to true, interacting with this item will make the character interact with the contained item(s), automatically picking them up if they can be picked up.")] public bool AutoInteractWithContained { @@ -98,6 +121,9 @@ namespace Barotrauma.Items.Components set; } + [Serialize(true, false)] + public bool AllowAccess { get; set; } + [Serialize(false, false)] public bool AccessOnlyWhenBroken { get; set; } @@ -147,7 +173,7 @@ namespace Barotrauma.Items.Components set; } - [Serialize(0.5f, false, description: "The rotation in which the contained sprites are drawn (in degrees).")] + [Serialize(0.5f, false, description: "The health threshold that the user must reach in order to activate the autoinjection.")] public float AutoInjectThreshold { get; @@ -157,10 +183,12 @@ namespace Barotrauma.Items.Components [Serialize(false, false)] public bool RemoveContainedItemsOnDeconstruct { get; set; } + private SlotRestrictions[] slotRestrictions; + public bool ShouldBeContained(string[] identifiersOrTags, out bool isRestrictionsDefined) { isRestrictionsDefined = containableRestrictions.Any(); - if (ContainableItems.None(ri => ri.MatchesItem(item))) { return false; } + if (slotRestrictions.None(s => s.MatchesItem(item))) { return false; } if (!isRestrictionsDefined) { return true; } return identifiersOrTags.Any(id => containableRestrictions.Any(r => r == id)); } @@ -168,22 +196,22 @@ namespace Barotrauma.Items.Components public bool ShouldBeContained(Item item, out bool isRestrictionsDefined) { isRestrictionsDefined = containableRestrictions.Any(); - if (ContainableItems.None(ri => ri.MatchesItem(item))) { return false; } + if (slotRestrictions.None(s => s.MatchesItem(item))) { return false; } if (!isRestrictionsDefined) { return true; } return containableRestrictions.Any(id => item.Prefab.Identifier == id || item.HasTag(id)); } - public List ContainableItems { get; private set; } = new List(); - - public IEnumerable GetContainableItemIdentifiers => ContainableItems.SelectMany(ri => ri.Identifiers); + private ImmutableHashSet containableItemIdentifiers; + public IEnumerable ContainableItemIdentifiers => containableItemIdentifiers; public override bool RecreateGUIOnResolutionChange => true; public ItemContainer(Item item, XElement element) - : base (item, element) + : base(item, element) { - Inventory = new ItemInventory(item, this, capacity, SlotsPerRow); - + int totalCapacity = capacity; + + List containableItems = null; foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString().ToLowerInvariant()) @@ -195,34 +223,92 @@ namespace Barotrauma.Items.Components DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - containable with no identifiers."); continue; } - ContainableItems.Add(containable); + containableItems ??= new List(); + containableItems.Add(containable); + break; + case "subcontainer": + totalCapacity += subElement.GetAttributeInt("capacity", 1); break; } } + Inventory = new ItemInventory(item, this, totalCapacity, SlotsPerRow); + slotRestrictions = new SlotRestrictions[totalCapacity]; + for (int i = 0; i < capacity; i++) + { + slotRestrictions[i] = new SlotRestrictions(maxStackSize, containableItems); + } + int subContainerIndex = capacity; + foreach (XElement subElement in element.Elements()) + { + if (subElement.Name.ToString().ToLowerInvariant() != "subcontainer") { continue; } + + int subCapacity = subElement.GetAttributeInt("capacity", 1); + int subMaxStackSize = subElement.GetAttributeInt("maxstacksize", maxStackSize); + + List subContainableItems = null; + foreach (XElement subSubElement in subElement.Elements()) + { + if (subSubElement.Name.ToString().ToLowerInvariant() != "containable") { continue; } + + RelatedItem containable = RelatedItem.Load(subSubElement, returnEmpty: false, parentDebugName: item.Name); + if (containable == null) + { + DebugConsole.ThrowError("Error in item config \"" + item.ConfigFile + "\" - containable with no identifiers."); + continue; + } + subContainableItems ??= new List(); + subContainableItems.Add(containable); + } + + for (int i = subContainerIndex; i < subContainerIndex + subCapacity; i++) + { + slotRestrictions[i] = new SlotRestrictions(subMaxStackSize, subContainableItems); + } + subContainerIndex += subCapacity; + } + capacity = totalCapacity; InitProjSpecific(element); } + public int GetMaxStackSize(int slotIndex) + { + if (slotIndex < 0 || slotIndex >= capacity) + { + return 0; + } + return slotRestrictions[slotIndex].MaxStackSize; + } + partial void InitProjSpecific(XElement element); public void OnItemContained(Item containedItem) { item.SetContainedItemPositions(); - - RelatedItem ri = ContainableItems.Find(x => x.MatchesItem(containedItem)); - if (ri != null) + + int index = Inventory.FindIndex(containedItem); + if (index >= 0 && index < slotRestrictions.Length) { - activeContainedItems.RemoveAll(i => i.Item == containedItem); - foreach (StatusEffect effect in ri.statusEffects) + RelatedItem ri = slotRestrictions[index].ContainableItems?.Find(ci => ci.MatchesItem(containedItem)); + if (ri != null) { - activeContainedItems.Add(new ActiveContainedItem(containedItem, effect, ri.ExcludeBroken)); + activeContainedItems.RemoveAll(i => i.Item == containedItem); + foreach (StatusEffect effect in ri.statusEffects) + { + activeContainedItems.Add(new ActiveContainedItem(containedItem, effect, ri.ExcludeBroken)); + } } - } + } //no need to Update() if this item has no statuseffects and no physics body IsActive = activeContainedItems.Count > 0 || Inventory.AllItems.Any(it => it.body != null); } + public override void Move(Vector2 amount) + { + SetContainedItemPositions(); + } + public void OnItemRemoved(Item containedItem) { activeContainedItems.RemoveAll(i => i.Item == containedItem); @@ -233,13 +319,11 @@ namespace Barotrauma.Items.Components public bool CanBeContained(Item item) { - if (ContainableItems.Count == 0) { return true; } - return ContainableItems.Find(c => c.MatchesItem(item)) != null; + return slotRestrictions.Any(s => s.MatchesItem(item)); } public bool CanBeContained(ItemPrefab itemPrefab) { - if (ContainableItems.Count == 0) { return true; } - return ContainableItems.Find(c => c.MatchesItem(itemPrefab)) != null; + return slotRestrictions.Any(s => s.MatchesItem(itemPrefab)); } readonly List targets = new List(); @@ -264,6 +348,7 @@ namespace Barotrauma.Items.Components foreach (Item item in Inventory.AllItemsMod) { item.ApplyStatusEffects(ActionType.OnUse, 1.0f, ownerCharacter); + item.GetComponent()?.Equip(ownerCharacter); } } } @@ -304,11 +389,12 @@ namespace Barotrauma.Items.Components public override bool HasRequiredItems(Character character, bool addMessage, string msg = null) { - return (!AccessOnlyWhenBroken || Item.Condition <= 0) && base.HasRequiredItems(character, addMessage, msg); + return AllowAccess && (!AccessOnlyWhenBroken || Item.Condition <= 0) && base.HasRequiredItems(character, addMessage, msg); } public override bool Select(Character character) { + if (!AllowAccess) { return false; } if (item.Container != null) { return false; } if (AccessOnlyWhenBroken) { @@ -335,6 +421,7 @@ namespace Barotrauma.Items.Components public override bool Pick(Character picker) { + if (!AllowAccess) { return false; } if (AccessOnlyWhenBroken) { if (item.Condition > 0) @@ -362,7 +449,7 @@ namespace Barotrauma.Items.Components public override bool Combine(Item item, Character user) { if (!AllowDragAndDrop && user != null) { return false; } - if (!ContainableItems.Any(it => it.MatchesItem(item))) { return false; } + if (!slotRestrictions.Any(s => s.MatchesItem(item))) { return false; } if (user != null && !user.CanAccessInventory(Inventory)) { return false; } if (Inventory.TryPutItem(item, user)) @@ -392,50 +479,59 @@ namespace Barotrauma.Items.Components Vector2 transformedItemInterval = ItemInterval * item.Scale; Vector2 transformedItemIntervalHorizontal = new Vector2(transformedItemInterval.X, 0.0f); Vector2 transformedItemIntervalVertical = new Vector2(0.0f, transformedItemInterval.Y); - if (item.body == null) + + if (ItemPos == Vector2.Zero && ItemInterval == Vector2.Zero) { - if (item.FlippedX) - { - transformedItemPos.X = -transformedItemPos.X; - transformedItemPos.X += item.Rect.Width; - transformedItemInterval.X = -transformedItemInterval.X; - transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X; - } - if (item.FlippedY) - { - transformedItemPos.Y = -transformedItemPos.Y; - transformedItemPos.Y -= item.Rect.Height; - transformedItemInterval.Y = -transformedItemInterval.Y; - transformedItemIntervalVertical.Y = -transformedItemIntervalVertical.Y; - } - transformedItemPos += new Vector2(item.Rect.X, item.Rect.Y); - if (Math.Abs(item.Rotation) > 0.01f) - { - Matrix transform = Matrix.CreateRotationZ(MathHelper.ToRadians(-item.Rotation)); - transformedItemPos = Vector2.Transform(transformedItemPos, transform); - transformedItemInterval = Vector2.Transform(transformedItemInterval, transform); - transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform); - transformedItemIntervalVertical = Vector2.Transform(transformedItemIntervalVertical, transform); - } + transformedItemPos = item.Position; } else { - Matrix transform = Matrix.CreateRotationZ(item.body.Rotation); - if (item.body.Dir == -1.0f) + if (item.body == null) { - transformedItemPos.X = -transformedItemPos.X; - transformedItemInterval.X = -transformedItemInterval.X; - transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X; + if (item.FlippedX) + { + transformedItemPos.X = -transformedItemPos.X; + transformedItemPos.X += item.Rect.Width; + transformedItemInterval.X = -transformedItemInterval.X; + transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X; + } + if (item.FlippedY) + { + transformedItemPos.Y = -transformedItemPos.Y; + transformedItemPos.Y -= item.Rect.Height; + transformedItemInterval.Y = -transformedItemInterval.Y; + transformedItemIntervalVertical.Y = -transformedItemIntervalVertical.Y; + } + transformedItemPos += new Vector2(item.Rect.X, item.Rect.Y); + if (Math.Abs(item.Rotation) > 0.01f) + { + Matrix transform = Matrix.CreateRotationZ(MathHelper.ToRadians(-item.Rotation)); + transformedItemPos = Vector2.Transform(transformedItemPos, transform); + transformedItemInterval = Vector2.Transform(transformedItemInterval, transform); + transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform); + transformedItemIntervalVertical = Vector2.Transform(transformedItemIntervalVertical, transform); + } } - transformedItemPos = Vector2.Transform(transformedItemPos, transform); - transformedItemInterval = Vector2.Transform(transformedItemInterval, transform); - transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform); - transformedItemPos += item.Position; - } + else + { + Matrix transform = Matrix.CreateRotationZ(item.body.Rotation); + if (item.body.Dir == -1.0f) + { + transformedItemPos.X = -transformedItemPos.X; + transformedItemInterval.X = -transformedItemInterval.X; + transformedItemIntervalHorizontal.X = -transformedItemIntervalHorizontal.X; + } + transformedItemPos = Vector2.Transform(transformedItemPos, transform); + transformedItemInterval = Vector2.Transform(transformedItemInterval, transform); + transformedItemIntervalHorizontal = Vector2.Transform(transformedItemIntervalHorizontal, transform); + transformedItemPos += item.Position; + } + } float currentRotation = itemRotation; if (item.body != null) { + currentRotation *= item.body.Dir; currentRotation += item.body.Rotation; } @@ -492,6 +588,7 @@ namespace Barotrauma.Items.Components public override void OnItemLoaded() { + containableItemIdentifiers = slotRestrictions.SelectMany(s => s.ContainableItems?.SelectMany(ri => ri.Identifiers) ?? Enumerable.Empty()).ToImmutableHashSet(); if (item.Submarine == null || !item.Submarine.Loading) { SpawnAlwaysContainedItems(); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Deconstructor.cs index 575401584..3fe8d3b74 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Deconstructor.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Deconstructor.cs @@ -1,4 +1,5 @@ -using Barotrauma.Extensions; +using Barotrauma.Abilities; +using Barotrauma.Extensions; using Barotrauma.Networking; using System; using System.Collections.Generic; @@ -14,6 +15,10 @@ namespace Barotrauma.Items.Components private bool hasPower; + private Character user; + + private float userDeconstructorSpeedMultiplier = 1.0f; + private ItemContainer inputContainer, outputContainer; public ItemContainer InputContainer @@ -25,7 +30,10 @@ namespace Barotrauma.Items.Components { get { return outputContainer; } } - + + [Serialize(false, true)] + public bool DeconstructItemsSimultaneously { get; set; } + [Editable, Serialize(1.0f, true)] public float DeconstructionSpeed { get; set; } @@ -81,65 +89,149 @@ namespace Barotrauma.Items.Components if (powerConsumption <= 0.0f) { Voltage = 1.0f; } progressTimer += deltaTime * Math.Min(Voltage, 1.0f); - var targetItem = inputContainer.Inventory.LastOrDefault(); - if (targetItem == null) { return; } - - float deconstructTime = targetItem.Prefab.DeconstructItems.Any() ? targetItem.Prefab.DeconstructTime / DeconstructionSpeed : 1.0f; - - progressState = Math.Min(progressTimer / deconstructTime, 1.0f); - if (progressTimer > deconstructTime) + if (DeconstructItemsSimultaneously) { - // In multiplayer, the server handles the deconstruction into new items - if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } - - if (targetItem.Prefab.RandomDeconstructionOutput) + float deconstructTime = 0.0f; + foreach (Item targetItem in inputContainer.Inventory.AllItems) { - int amount = targetItem.Prefab.RandomDeconstructionOutputAmount; - List deconstructItemIndexes = new List(); - for (int i = 0; i < targetItem.Prefab.DeconstructItems.Count; i++) - { - deconstructItemIndexes.Add(i); - } - List commonness = targetItem.Prefab.DeconstructItems.Select(i => i.Commonness).ToList(); - List products = new List(); - - for (int i = 0; i < amount; i++) - { - if (deconstructItemIndexes.Count < 1) { break; } - var itemIndex = ToolBox.SelectWeightedRandom(deconstructItemIndexes, commonness, Rand.RandSync.Unsynced); - products.Add(targetItem.Prefab.DeconstructItems[itemIndex]); - var removeIndex = deconstructItemIndexes.IndexOf(itemIndex); - deconstructItemIndexes.RemoveAt(removeIndex); - commonness.RemoveAt(removeIndex); - } - foreach (DeconstructItem deconstructProduct in products) - { - CreateDeconstructProduct(deconstructProduct); - } - } - else - { - foreach (DeconstructItem deconstructProduct in targetItem.Prefab.DeconstructItems) - { - CreateDeconstructProduct(deconstructProduct); - } + deconstructTime += targetItem.Prefab.DeconstructTime / (DeconstructionSpeed * userDeconstructorSpeedMultiplier); } - void CreateDeconstructProduct(DeconstructItem deconstructProduct) + progressState = Math.Min(progressTimer / deconstructTime, 1.0f); + if (progressTimer > deconstructTime) { - float percentageHealth = targetItem.Condition / targetItem.Prefab.Health; - if (percentageHealth <= deconstructProduct.MinCondition || percentageHealth > deconstructProduct.MaxCondition) { return; } - - if (!(MapEntityPrefab.Find(null, deconstructProduct.ItemIdentifier) is ItemPrefab itemPrefab)) + List items = inputContainer.Inventory.AllItems.ToList(); + foreach (Item targetItem in items) { - DebugConsole.ThrowError("Tried to deconstruct item \"" + targetItem.Name + "\" but couldn't find item prefab \"" + deconstructProduct.ItemIdentifier + "\"!"); - return; + if ((Entity.Spawner?.IsInRemoveQueue(targetItem) ?? false) || !inputContainer.Inventory.AllItems.Contains(targetItem)) { continue; } + var validDeconstructItems = targetItem.Prefab.DeconstructItems.FindAll(it => + (it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))) && + (it.RequiredOtherItem.Length == 0 || it.RequiredOtherItem.Any(r => items.Any(it => it.HasTag(r) || it.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))))); + + ProcessItem(targetItem, items, validDeconstructItems, allowRemove: validDeconstructItems.Any() || !targetItem.Prefab.DeconstructItems.Any()); } +#if SERVER + item.CreateServerEvent(this); +#endif + progressTimer = 0.0f; + progressState = 0.0f; - float condition = deconstructProduct.CopyCondition ? - percentageHealth * itemPrefab.Health : - itemPrefab.Health * deconstructProduct.OutCondition; + } + } + else + { + var targetItem = inputContainer.Inventory.LastOrDefault(); + if (targetItem == null) { return; } + var validDeconstructItems = targetItem.Prefab.DeconstructItems.FindAll(it => + it.RequiredDeconstructor.Length == 0 || it.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))); + + float deconstructTime = validDeconstructItems.Any() ? targetItem.Prefab.DeconstructTime / DeconstructionSpeed : 1.0f; + + progressState = Math.Min(progressTimer / deconstructTime, 1.0f); + if (progressTimer > deconstructTime) + { + ProcessItem(targetItem, inputContainer.Inventory.AllItemsMod, validDeconstructItems, allowRemove: validDeconstructItems.Any() || !targetItem.Prefab.DeconstructItems.Any()); + +#if SERVER + item.CreateServerEvent(this); +#endif + progressTimer = 0.0f; + progressState = 0.0f; + + } + } + } + + private void ProcessItem(Item targetItem, IEnumerable inputItems, List validDeconstructItems, bool allowRemove = true) + { + // In multiplayer, the server handles the deconstruction into new items + if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } + + if (targetItem.Prefab.RandomDeconstructionOutput) + { + int amount = targetItem.Prefab.RandomDeconstructionOutputAmount; + List deconstructItemIndexes = new List(); + for (int i = 0; i < validDeconstructItems.Count; i++) + { + deconstructItemIndexes.Add(i); + } + List commonness = validDeconstructItems.Select(i => i.Commonness).ToList(); + List products = new List(); + + for (int i = 0; i < amount; i++) + { + if (deconstructItemIndexes.Count < 1) { break; } + var itemIndex = ToolBox.SelectWeightedRandom(deconstructItemIndexes, commonness, Rand.RandSync.Unsynced); + products.Add(validDeconstructItems[itemIndex]); + var removeIndex = deconstructItemIndexes.IndexOf(itemIndex); + deconstructItemIndexes.RemoveAt(removeIndex); + commonness.RemoveAt(removeIndex); + } + + user.CheckTalents(AbilityEffectType.OnItemDeconstructed, targetItem); + + foreach (DeconstructItem deconstructProduct in products) + { + CreateDeconstructProduct(deconstructProduct, inputItems); + } + } + else + { + foreach (DeconstructItem deconstructProduct in validDeconstructItems) + { + CreateDeconstructProduct(deconstructProduct, inputItems); + } + } + + void CreateDeconstructProduct(DeconstructItem deconstructProduct, IEnumerable inputItems) + { + float percentageHealth = targetItem.Condition / targetItem.Prefab.Health; + if (percentageHealth <= deconstructProduct.MinCondition || percentageHealth > deconstructProduct.MaxCondition) { return; } + + if (!(MapEntityPrefab.Find(null, deconstructProduct.ItemIdentifier) is ItemPrefab itemPrefab)) + { + DebugConsole.ThrowError("Tried to deconstruct item \"" + targetItem.Name + "\" but couldn't find item prefab \"" + deconstructProduct.ItemIdentifier + "\"!"); + return; + } + + float condition = deconstructProduct.CopyCondition ? + percentageHealth * itemPrefab.Health : + itemPrefab.Health * Rand.Range(deconstructProduct.OutConditionMin, deconstructProduct.OutConditionMax); + + if (DeconstructItemsSimultaneously && deconstructProduct.RequiredOtherItem.Length > 0) + { + foreach (Item otherItem in inputItems) + { + if (targetItem == otherItem) { continue; } + if (deconstructProduct.RequiredOtherItem.Any(r => otherItem.HasTag(r) || r.Equals(otherItem.Prefab.Identifier, StringComparison.OrdinalIgnoreCase))) + { + var geneticMaterial1 = targetItem.GetComponent(); + var geneticMaterial2 = otherItem.GetComponent(); + if (geneticMaterial1 != null && geneticMaterial2 != null) + { + if (geneticMaterial1.Combine(geneticMaterial2, user)) + { + inputContainer.Inventory.RemoveItem(otherItem); + OutputContainer.Inventory.RemoveItem(otherItem); + Entity.Spawner.AddToRemoveQueue(otherItem); + } + allowRemove = false; + return; + } + inputContainer.Inventory.RemoveItem(otherItem); + OutputContainer.Inventory.RemoveItem(otherItem); + Entity.Spawner.AddToRemoveQueue(otherItem); + } + } + } + var itemsCreated = new AbilityValue(1f); + user.CheckTalents(AbilityEffectType.OnItemDeconstructedMaterial, (targetItem.Prefab, itemsCreated)); + + int amount = (int)itemsCreated.Value; + + for (int i = 0; i < amount; i++) + { Entity.Spawner.AddToSpawnQueue(itemPrefab, outputContainer.Inventory, condition, onSpawned: (Item spawnedItem) => { for (int i = 0; i < outputContainer.Capacity; i++) @@ -153,36 +245,31 @@ namespace Barotrauma.Items.Components PutItemsToLinkedContainer(); }); } + } - if (targetItem.Prefab.AllowDeconstruct) + if (targetItem.AllowDeconstruct && allowRemove) + { + //drop all items that are inside the deconstructed item + foreach (ItemContainer ic in targetItem.GetComponents()) { - //drop all items that are inside the deconstructed item - foreach (ItemContainer ic in targetItem.GetComponents()) - { - if (ic?.Inventory == null || ic.RemoveContainedItemsOnDeconstruct) { continue; } - ic.Inventory.AllItemsMod.ForEach(containedItem => outputContainer.Inventory.TryPutItem(containedItem, user: null)); - } - inputContainer.Inventory.RemoveItem(targetItem); - Entity.Spawner.AddToRemoveQueue(targetItem); - MoveInputQueue(); - PutItemsToLinkedContainer(); + if (ic?.Inventory == null || ic.RemoveContainedItemsOnDeconstruct) { continue; } + ic.Inventory.AllItemsMod.ForEach(containedItem => outputContainer.Inventory.TryPutItem(containedItem, user: null)); + } + inputContainer.Inventory.RemoveItem(targetItem); + Entity.Spawner.AddToRemoveQueue(targetItem); + MoveInputQueue(); + PutItemsToLinkedContainer(); + } + else + { + if (!outputContainer.Inventory.CanBePut(targetItem) || (Entity.Spawner?.IsInRemoveQueue(targetItem) ?? false)) + { + targetItem.Drop(dropper: null); } else { - if (!outputContainer.Inventory.CanBePut(targetItem)) - { - targetItem.Drop(dropper: null); - } - else - { - outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true); - } + outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true); } -#if SERVER - item.CreateServerEvent(this); -#endif - progressTimer = 0.0f; - progressState = 0.0f; } } @@ -190,7 +277,7 @@ namespace Barotrauma.Items.Components { if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) { return; } if (outputContainer.Inventory.IsEmpty()) { return; } - + foreach (MapEntity linkedTo in item.linkedTo) { if (linkedTo is Item linkedItem) @@ -201,7 +288,7 @@ namespace Barotrauma.Items.Components if (itemContainer == null) { continue; } outputContainer.Inventory.AllItemsMod.ForEach(containedItem => itemContainer.Inventory.TryPutItem(containedItem, user: null, createNetworkEvent: true)); } - } + } } /// @@ -221,14 +308,54 @@ namespace Barotrauma.Items.Components } } + private IEnumerable<(Item item, DeconstructItem output)> GetAvailableOutputs(bool checkRequiredOtherItems = true) + { + var items = inputContainer.Inventory.AllItems; + foreach (Item inputItem in items) + { + if (!inputItem.AllowDeconstruct) { continue; } + foreach (var deconstructItem in inputItem.Prefab.DeconstructItems) + { + if (deconstructItem.RequiredDeconstructor.Length > 0) + { + if (!deconstructItem.RequiredDeconstructor.Any(r => item.HasTag(r) || item.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))) { continue; } + } + if (deconstructItem.RequiredOtherItem.Length > 0 && checkRequiredOtherItems) + { + if (!deconstructItem.RequiredOtherItem.Any(r => items.Any(it => it.HasTag(r) || it.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase)))) { continue; } + bool validOtherItemFound = false; + foreach (Item otherInputItem in items) + { + if (otherInputItem == inputItem) { continue; } + if (!deconstructItem.RequiredOtherItem.Any(r => otherInputItem.HasTag(r) || otherInputItem.Prefab.Identifier.Equals(r, StringComparison.OrdinalIgnoreCase))) { continue; } + + var geneticMaterial1 = inputItem.GetComponent(); + var geneticMaterial2 = otherInputItem.GetComponent(); + if (geneticMaterial1 != null && geneticMaterial2 != null) + { + if (!geneticMaterial1.CanBeCombinedWith(geneticMaterial2)) { continue; } + } + validOtherItemFound = true; + } + if (!validOtherItemFound) { continue; } + } + yield return (inputItem, deconstructItem); + } + } + } + private void SetActive(bool active, Character user = null) { PutItemsToLinkedContainer(); + this.user = user; + if (inputContainer.Inventory.IsEmpty()) { active = false; } IsActive = active; currPowerConsumption = IsActive ? powerConsumption : 0.0f; + userDeconstructorSpeedMultiplier = user != null ? 1f + user.GetStatValue(StatTypes.DeconstructorSpeedMultiplier) : 1f; + #if SERVER if (user != null) { @@ -241,10 +368,6 @@ namespace Barotrauma.Items.Components progressState = 0.0f; } -#if CLIENT - activateButton.Text = TextManager.Get(IsActive ? "DeconstructorCancel" : "DeconstructorDeconstruct"); -#endif - inputContainer.Inventory.Locked = IsActive; } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Fabricator.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Fabricator.cs index 8d84d9d26..1ea32a0f3 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Fabricator.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Fabricator.cs @@ -316,7 +316,7 @@ namespace Barotrauma.Items.Components availablePrefab.Condition -= availablePrefab.Prefab.Health * requiredItem.MinCondition; continue; } - + availablePrefabs.Remove(availablePrefab); Entity.Spawner.AddToRemoveQueue(availablePrefab); inputContainer.Inventory.RemoveItem(availablePrefab); @@ -324,18 +324,20 @@ namespace Barotrauma.Items.Components } }); - Character tempUser = user; - int amountFittingContainer = outputContainer.Inventory.HowManyCanBePut(fabricatedItem.TargetItem, fabricatedItem.OutCondition * fabricatedItem.TargetItem.Health); - var itemsCreated = new AbilityValue(fabricatedItem.Amount); - foreach (Character character in Character.CharacterList.Where(c => c.TeamID == user.TeamID)) + + var fabricationValueItem = new AbilityValueItem(fabricatedItem.Amount, fabricatedItem.TargetItem); + if (user != null) { - character.CheckTalents(AbilityEffectType.OnAllyItemFabricatedAmount, (fabricatedItem.TargetItem, itemsCreated)); + foreach (Character character in Character.CharacterList.Where(c => c.TeamID == user.TeamID)) + { + character.CheckTalents(AbilityEffectType.OnAllyItemFabricatedAmount, fabricationValueItem); + } + user.CheckTalents(AbilityEffectType.OnItemFabricatedAmount, fabricationValueItem); } - tempUser.CheckTalents(AbilityEffectType.OnItemFabricatedAmount, (fabricatedItem.TargetItem, itemsCreated)); - - for (int i = 0; i < (int)itemsCreated.Value; i++) + var tempUser = user; + for (int i = 0; i < (int)fabricationValueItem.Value; i++) { if (i < amountFittingContainer) { @@ -359,14 +361,13 @@ namespace Barotrauma.Items.Components } } } - if (user?.Info != null && !user.Removed) { foreach (Skill skill in fabricatedItem.RequiredSkills) { float userSkill = user.GetSkillLevel(skill.Identifier); float addedSkill = skill.Level * SkillSettings.Current.SkillIncreasePerFabricatorRequiredSkill / Math.Max(userSkill, 1.0f); - var addedSkillValue = new AbilityValue(0f); + var addedSkillValue = new AbilityValueString(0f, skill.Identifier); user.CheckTalents(AbilityEffectType.OnItemFabricationSkillGain, addedSkillValue); user.Info.IncreaseSkillLevel( diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs index 543e9bc1b..5c8e7e70e 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Machines/Steering.cs @@ -365,16 +365,13 @@ namespace Barotrauma.Items.Components item.SendSignal(new Signal(velY.ToString(CultureInfo.InvariantCulture), sender: user), "velocity_y_out"); // converts the controlled sub's velocity to km/h and sends it. - // TODO: add current_velocity_x and current_velocity_y pins on the navigation terminals and shuttle terminals - // TODO: increase the size of the connection panels of both navigation terminals - if (controlledSub is { } sub) { item.SendSignal(new Signal((ConvertUnits.ToDisplayUnits(sub.Velocity.X * Physics.DisplayToRealWorldRatio) * 3.6f).ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_velocity_x"); item.SendSignal(new Signal((ConvertUnits.ToDisplayUnits(sub.Velocity.Y * Physics.DisplayToRealWorldRatio) * -3.6f).ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_velocity_y"); item.SendSignal(new Signal(sub.WorldPosition.X.ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_position_x"); - item.SendSignal(new Signal(sub.RealWorldDepth.ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_depth"); + item.SendSignal(new Signal(sub.RealWorldDepth.ToString("0.0000", CultureInfo.InvariantCulture), sender: user), "current_position_y"); } // if our tactical AI pilot has left, revert back to maintaining position diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/PowerTransfer.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/PowerTransfer.cs index a587d47ff..52c065e75 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/PowerTransfer.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Power/PowerTransfer.cs @@ -15,6 +15,9 @@ namespace Barotrauma.Items.Components //a list of connections a given connection is connected to, either directly or via other power transfer components private readonly Dictionary> connectedRecipients = new Dictionary>(); + private float overloadCooldownTimer; + private const float OverloadCooldown = 5.0f; + protected float powerLoad; protected bool isBroken; @@ -173,12 +176,19 @@ namespace Barotrauma.Items.Components Overload = -currPowerConsumption > Math.Max(powerLoad, 200.0f) * maxOverVoltage; if (Overload && (GameMain.NetworkMember == null || GameMain.NetworkMember.IsServer)) { + if (overloadCooldownTimer > 0.0f) + { + overloadCooldownTimer -= deltaTime; + return; + } + //damage the item if voltage is too high (except if running as a client) float prevCondition = item.Condition; item.Condition -= deltaTime * 10.0f; if (item.Condition <= 0.0f && prevCondition > 0.0f) { + overloadCooldownTimer = OverloadCooldown; #if CLIENT SoundPlayer.PlaySound("zap", item.WorldPosition, hullGuess: item.CurrentHull); Vector2 baseVel = Rand.Vector(300.0f); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/RemoteController.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/RemoteController.cs new file mode 100644 index 000000000..783253c89 --- /dev/null +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/RemoteController.cs @@ -0,0 +1,96 @@ +using Microsoft.Xna.Framework; +using System.Xml.Linq; + +namespace Barotrauma.Items.Components +{ + partial class RemoteController : ItemComponent + { + [Serialize("", false, description: "Tag or identifier of the item that should be controlled.")] + public string Target + { + get; + private set; + } + + [Serialize(false, false)] + public bool OnlyInOwnSub + { + get; + private set; + } + + [Serialize(10000.0f, false)] + public float Range + { + get; + private set; + } + + public Item TargetItem { get => currentTarget; } + + private Item currentTarget; + private Character currentUser; + private Submarine currentSub; + + public RemoteController(Item item, XElement element) + : base(item, element) + { + } + + public override bool Select(Character character) + { + if (base.Select(character)) + { + FindTarget(character); + return true; + } + return false; + } + + public override void Equip(Character character) + { + FindTarget(character); + } + + public override void Update(float deltaTime, Camera cam) + { + base.Update(deltaTime, cam); + if (currentTarget.Removed || + item.Submarine != currentSub || + Vector2.DistanceSquared(currentTarget.WorldPosition, item.WorldPosition) > Range * Range) + { + FindTarget(currentUser); + } + } + + private void FindTarget(Character user) + { + currentTarget = null; + if (user == null || (item.Submarine == null && OnlyInOwnSub)) + { + IsActive = false; + return; + } + + float closestDist = float.PositiveInfinity; + foreach (Item targetItem in Item.ItemList) + { + if (OnlyInOwnSub) + { + if (targetItem.Submarine != item.Submarine) { continue; } + if (targetItem.Submarine.TeamID != user.TeamID) { continue; } + } + if (!targetItem.HasTag(Target) && targetItem.prefab.Identifier != Target) { continue; } + + float distSqr = Vector2.DistanceSquared(item.WorldPosition, targetItem.WorldPosition); + if (distSqr > Range * Range || distSqr > closestDist) { continue; } + + currentTarget = targetItem; + currentSub = item.Submarine; + closestDist = distSqr; + currentUser = user; + } + IsActive = currentTarget != null; + } + } +} diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs index 2b474213b..37f5833fc 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Repairable.cs @@ -339,7 +339,7 @@ namespace Barotrauma.Items.Components if (currentFixerAction == FixActions.Tinker) { - // this is a bit code rotty to interject it here, should be less reliant on returning + // not great to interject it here, should be less reliant on returning if (!CanTinker(CurrentFixer)) { StopRepairing(CurrentFixer); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/ConnectionPanel.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/ConnectionPanel.cs index e7648c9ac..a52a9600b 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/ConnectionPanel.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/ConnectionPanel.cs @@ -134,20 +134,30 @@ namespace Barotrauma.Items.Components foreach (Wire wire in c.Wires) { if (wire == null) { continue; } -#if CLIENT - if (wire.Item.IsSelected) { continue; } -#endif - var wireNodes = wire.GetNodes(); - if (wireNodes.Count == 0) { continue; } + TryMoveWire(wire); + } + } - if (Submarine.RectContains(item.Rect, wireNodes[0] + wireNodeOffset)) - { - wire.MoveNode(0, amount); - } - else if (Submarine.RectContains(item.Rect, wireNodes[wireNodes.Count - 1] + wireNodeOffset)) - { - wire.MoveNode(wireNodes.Count - 1, amount); - } + foreach (var wire in DisconnectedWires) + { + TryMoveWire(wire); + } + + void TryMoveWire(Wire wire) + { +#if CLIENT + if (wire.Item.IsSelected) { return; } +#endif + var wireNodes = wire.GetNodes(); + if (wireNodes.Count == 0) { return; } + + if (Submarine.RectContains(item.Rect, wireNodes[0] + wireNodeOffset)) + { + wire.MoveNode(0, amount); + } + else if (Submarine.RectContains(item.Rect, wireNodes[wireNodes.Count - 1] + wireNodeOffset)) + { + wire.MoveNode(wireNodes.Count - 1, amount); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Terminal.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Terminal.cs index 540284013..335827046 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Terminal.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Terminal.cs @@ -41,7 +41,7 @@ namespace Barotrauma.Items.Components set { if (string.IsNullOrEmpty(value)) { return; } - ShowOnDisplay(value); + ShowOnDisplay(value, addToHistory: true); } } @@ -59,7 +59,7 @@ namespace Barotrauma.Items.Components partial void InitProjSpecific(XElement element); - partial void ShowOnDisplay(string input, bool addToHistory = true); + partial void ShowOnDisplay(string input, bool addToHistory); public override void ReceiveSignal(Signal signal, Connection connection) { @@ -70,14 +70,14 @@ namespace Barotrauma.Items.Components } string inputSignal = signal.value.Replace("\\n", "\n"); - ShowOnDisplay(inputSignal); + ShowOnDisplay(inputSignal, addToHistory: true); } public override void OnItemLoaded() { bool isSubEditor = false; #if CLIENT - isSubEditor = Screen.Selected != GameMain.SubEditorScreen || GameMain.GameSession?.GameMode is TestGameMode; + isSubEditor = Screen.Selected == GameMain.SubEditorScreen || GameMain.GameSession?.GameMode is TestGameMode; #endif base.OnItemLoaded(); @@ -110,7 +110,7 @@ namespace Barotrauma.Items.Components { string msg = componentElement.GetAttributeString("msg" + i, null); if (msg == null) { break; } - ShowOnDisplay(msg); + ShowOnDisplay(msg, addToHistory: true); } } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Wire.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Wire.cs index 3a054c4e1..2b80a81c8 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Wire.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Signal/Wire.cs @@ -133,15 +133,15 @@ namespace Barotrauma.Items.Components public bool IsConnectedTo(Item item) { - if (connections[0] != null && connections[0].Item == item) return true; - return (connections[1] != null && connections[1].Item == item); + if (connections[0] != null && connections[0].Item == item) { return true; } + return connections[1] != null && connections[1].Item == item; } public void RemoveConnection(Item item) { for (int i = 0; i < 2; i++) { - if (connections[i] == null || connections[i].Item != item) continue; + if (connections[i] == null || connections[i].Item != item) { continue; } foreach (Wire wire in connections[i].Wires) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs index 0bed7d299..ecb5d1cf4 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Turret.cs @@ -64,6 +64,8 @@ namespace Barotrauma.Items.Components private Character currentTarget; const float aiFindTargetInterval = 5.0f; + private const float TinkeringPowerCostReduction = 1.25f; + public float Rotation { get { return rotation; } @@ -504,9 +506,19 @@ namespace Barotrauma.Items.Components return TryLaunch(deltaTime, character); } + public float GetPowerRequiredToShoot() + { + float powerCost = powerConsumption; + if (user != null) + { + powerCost /= (1 + user.GetStatValue(StatTypes.TurretPowerCostReduction)); + } + return powerCost; + } + public bool HasPowerToShoot() { - return GetAvailableBatteryPower() >= powerConsumption; + return GetAvailableBatteryPower() >= GetPowerRequiredToShoot(); } private bool TryLaunch(float deltaTime, Character character = null, bool ignorePower = false) @@ -617,10 +629,12 @@ namespace Barotrauma.Items.Components if (!ignorePower) { var batteries = item.GetConnectedComponents(); - float neededPower = powerConsumption; + float neededPower = GetPowerRequiredToShoot(); + // tinkering is currently not factored into the common method as it is checked only when shooting + // but this is a minor issue that causes mostly cosmetic woes. might still be worth refactoring later if (isTinkering) { - neededPower /= 1.25f; + neededPower /= TinkeringPowerCostReduction; } while (neededPower > 0.0001f && batteries.Count > 0) { @@ -1022,7 +1036,7 @@ namespace Barotrauma.Items.Components container = containerItem.GetComponent(); if (container != null) { break; } } - if (container == null || container.ContainableItems.Count == 0) + if (container == null || !container.ContainableItemIdentifiers.Any()) { if (character.IsOnPlayerTeam) { @@ -1046,7 +1060,7 @@ namespace Barotrauma.Items.Components { if (!character.IsOnPlayerTeam) { return; } if (character.Submarine != Submarine.MainSub) { return; } - string ammoType = container.ContainableItems.First().Identifiers.FirstOrDefault() ?? "ammobox"; + string ammoType = container.ContainableItemIdentifiers.FirstOrDefault() ?? "ammobox"; int remainingAmmo = Submarine.MainSub.GetItems(false).Count(i => i.HasTag(ammoType) && i.Condition > 1); if (remainingAmmo == 0) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Wearable.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Wearable.cs index baec2c0b0..be1b859b6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Wearable.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Components/Wearable.cs @@ -55,6 +55,8 @@ namespace Barotrauma public float Scale { get; private set; } + public float Rotation { get; private set; } + public LimbType DepthLimb { get; private set; } private Wearable _wearableComponent; public Wearable WearableComponent @@ -177,6 +179,7 @@ namespace Barotrauma DepthLimb = (LimbType)Enum.Parse(typeof(LimbType), SourceElement.GetAttributeString("depthlimb", "None"), true); Sound = SourceElement.GetAttributeString("sound", ""); Scale = SourceElement.GetAttributeFloat("scale", 1.0f); + Rotation = MathHelper.ToRadians(SourceElement.GetAttributeFloat("rotation", 0.0f)); var index = SourceElement.GetAttributePoint("sheetindex", new Point(-1, -1)); if (index.X > -1 && index.Y > -1) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs index a259d4246..f422df2e8 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Inventory.cs @@ -496,7 +496,7 @@ namespace Barotrauma var itemInSlot = slots[i].First(); if (itemInSlot.OwnInventory != null && !itemInSlot.OwnInventory.Contains(item) && - (itemInSlot.GetComponent()?.MaxStackSize ?? 0) == 1 && + (itemInSlot.GetComponent()?.GetMaxStackSize(0) ?? 0) == 1 && itemInSlot.OwnInventory.TrySwapping(0, item, user, createNetworkEvent, swapWholeStack: false)) { return true; diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs index db66ce9f0..14fb5af13 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/Item.cs @@ -540,6 +540,12 @@ namespace Barotrauma set => indestructible = value; } + public bool AllowDeconstruct + { + get; + set; + } + [Editable, Serialize(false, isSaveable: true, "When enabled will prevent the item from taking damage from all sources")] public bool InvulnerableToDamage { get; set; } @@ -767,6 +773,8 @@ namespace Barotrauma condition = MaxCondition; lastSentCondition = condition; + AllowDeconstruct = itemPrefab.AllowDeconstruct; + allPropertyObjects.Add(this); XElement element = itemPrefab.ConfigElement; @@ -1431,7 +1439,7 @@ namespace Barotrauma bool hasTargets = effect.TargetIdentifiers == null; targets.Clear(); - + if (effect.HasTargetType(StatusEffect.TargetType.Contained)) { foreach (Item containedItem in ContainedItems) @@ -1443,6 +1451,11 @@ namespace Barotrauma continue; } + if (effect.TargetSlot > -1) + { + if (OwnInventory.FindIndex(containedItem) != effect.TargetSlot) { continue; } + } + hasTargets = true; targets.Add(containedItem); } @@ -1500,8 +1513,8 @@ namespace Barotrauma { targets.Add(limb); } - - if (Container != null && effect.HasTargetType(StatusEffect.TargetType.Parent)) targets.Add(Container); + + if (Container != null && effect.HasTargetType(StatusEffect.TargetType.Parent)) { targets.Add(Container); } effect.Apply(type, deltaTime, this, targets, worldPosition); } @@ -2298,8 +2311,8 @@ namespace Barotrauma public void ApplyTreatment(Character user, Character character, Limb targetLimb) { //can't apply treatment to dead characters - if (character.IsDead) return; - if (!UseInHealthInterface) return; + if (character.IsDead) { return; } + if (!UseInHealthInterface) { return; } #if CLIENT if (GameMain.Client != null) @@ -2312,7 +2325,7 @@ namespace Barotrauma bool remove = false; foreach (ItemComponent ic in components) { - if (!ic.HasRequiredContainedItems(user, addMessage: user == Character.Controlled)) continue; + if (!ic.HasRequiredContainedItems(user, addMessage: user == Character.Controlled)) { continue; } bool success = Rand.Range(0.0f, 0.5f) < ic.DegreeOfSuccess(user); ActionType actionType = success ? ActionType.OnUse : ActionType.OnFailure; @@ -2331,7 +2344,7 @@ namespace Barotrauma }); } - if (ic.DeleteOnUse) remove = true; + if (ic.DeleteOnUse) { remove = true; } } if (remove) { Spawner?.AddToRemoveQueue(this); } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemInventory.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemInventory.cs index d449ad8c9..bcefbec04 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemInventory.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemInventory.cs @@ -9,7 +9,7 @@ namespace Barotrauma { partial class ItemInventory : Inventory { - private ItemContainer container; + private readonly ItemContainer container; public ItemContainer Container { get { return container; } @@ -48,14 +48,14 @@ namespace Barotrauma if (ItemOwnsSelf(item)) { return false; } if (i < 0 || i >= slots.Length) { return false; } if (!container.CanBeContained(item)) { return false; } - return item != null && slots[i].CanBePut(item, ignoreCondition) && slots[i].ItemCount < container.MaxStackSize; + return item != null && slots[i].CanBePut(item, ignoreCondition) && slots[i].ItemCount < container.GetMaxStackSize(i); } public override bool CanBePutInSlot(ItemPrefab itemPrefab, int i, float? condition) { if (i < 0 || i >= slots.Length) { return false; } if (!container.CanBeContained(itemPrefab)) { return false; } - return itemPrefab != null && slots[i].CanBePut(itemPrefab, condition) && slots[i].ItemCount < container.MaxStackSize; + return itemPrefab != null && slots[i].CanBePut(itemPrefab, condition) && slots[i].ItemCount < container.GetMaxStackSize(i); } public override int HowManyCanBePut(ItemPrefab itemPrefab, int i, float? condition) @@ -63,7 +63,7 @@ namespace Barotrauma if (itemPrefab == null) { return 0; } if (i < 0 || i >= slots.Length) { return 0; } if (!container.CanBeContained(itemPrefab)) { return 0; } - return slots[i].HowManyCanBePut(itemPrefab, maxStackSize: Math.Min(itemPrefab.MaxStackSize, container.MaxStackSize), condition); + return slots[i].HowManyCanBePut(itemPrefab, maxStackSize: Math.Min(itemPrefab.MaxStackSize, container.GetMaxStackSize(i)), condition); } public override bool IsFull(bool takeStacksIntoAccount = false) @@ -74,7 +74,7 @@ namespace Barotrauma { if (!slots[i].Any()) { return false; } var item = slots[i].FirstOrDefault(); - if (slots[i].ItemCount < Math.Min(item.Prefab.MaxStackSize, container.MaxStackSize)) { return false; } + if (slots[i].ItemCount < Math.Min(item.Prefab.MaxStackSize, container.GetMaxStackSize(i))) { return false; } } } else diff --git a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs index e2c81690d..67a117dde 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Items/ItemPrefab.cs @@ -18,9 +18,18 @@ namespace Barotrauma //maxCondition does > check, meaning that above this max the deconstruct item will be skipped. public readonly float MaxCondition; //Condition of item on creation - public readonly float OutCondition; + public readonly float OutConditionMin, OutConditionMax; //should the condition of the deconstructed item be copied to the output items public readonly bool CopyCondition; + //tag/identifier of the deconstructor(s) that can be used to deconstruct the item into this + public readonly string[] RequiredDeconstructor; + //tag/identifier of other item(s) that that need to be present in the deconstructor to deconstruct the item into this + public readonly string[] RequiredOtherItem; + //text to display on the deconstructor's activate button when this output is available + public readonly string ActivateButtonText; + public readonly string InfoText; + public readonly string InfoTextOnOtherItemMissing; + public float Commonness { get; } public DeconstructItem(XElement element, string parentDebugName) @@ -28,14 +37,20 @@ namespace Barotrauma ItemIdentifier = element.GetAttributeString("identifier", "notfound"); MinCondition = element.GetAttributeFloat("mincondition", -0.1f); MaxCondition = element.GetAttributeFloat("maxcondition", 1.0f); - OutCondition = element.GetAttributeFloat("outcondition", 1.0f); + OutConditionMin = element.GetAttributeFloat("outconditionmin", element.GetAttributeFloat("outcondition", 1.0f)); + OutConditionMax = element.GetAttributeFloat("outconditionmax", element.GetAttributeFloat("outcondition", 1.0f)); CopyCondition = element.GetAttributeBool("copycondition", false); Commonness = element.GetAttributeFloat("commonness", 1.0f); - if (element.Attribute("copycondition") != null && element.Attribute("outcondition") != null) { DebugConsole.AddWarning($"Invalid deconstruction output in \"{parentDebugName}\": the output item \"{ItemIdentifier}\" has the out condition set, but is also set to copy the condition of the deconstructed item. Ignoring the out condition."); } + RequiredDeconstructor = element.GetAttributeStringArray("requireddeconstructor", new string[0]); + RequiredOtherItem = element.GetAttributeStringArray("requiredotheritem", new string[0]); + ActivateButtonText = element.GetAttributeString("activatebuttontext", string.Empty); + InfoText = element.GetAttributeString("infotext", string.Empty); + InfoTextOnOtherItemMissing = element.GetAttributeString("infotextonotheritemmissing", string.Empty); + } } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs index a1958db8e..4b657de2a 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Explosion.cs @@ -33,6 +33,9 @@ namespace Barotrauma private readonly float? flashRange; private readonly string decal; private readonly float decalSize; + // used to apply friendly afflictions in an area without effects displaying + private readonly bool abilityExplosion; + private readonly bool applyToSelf; private readonly float itemRepairStrength; @@ -63,8 +66,10 @@ namespace Barotrauma force = element.GetAttributeFloat("force", 0.0f); - bool showEffects = element.GetAttributeBool("showeffects", true); + abilityExplosion = element.GetAttributeBool("abilityexplosion", false); + applyToSelf = element.GetAttributeBool("applytoself", true); + bool showEffects = !abilityExplosion; sparks = element.GetAttributeBool("sparks", showEffects); shockwave = element.GetAttributeBool("shockwave", showEffects); flames = element.GetAttributeBool("flames", showEffects); @@ -191,12 +196,12 @@ namespace Barotrauma } } - if (MathUtils.NearlyEqual(force, 0.0f) && MathUtils.NearlyEqual(Attack.Stun, 0.0f) && MathUtils.NearlyEqual(Attack.GetTotalDamage(false), 0.0f)) + if (MathUtils.NearlyEqual(force, 0.0f) && MathUtils.NearlyEqual(Attack.Stun, 0.0f) && MathUtils.NearlyEqual(Attack.GetTotalDamage(false), 0.0f) && !abilityExplosion) { return; } - DamageCharacters(worldPosition, Attack, force, damageSource, attacker); + DamageCharacters(worldPosition, Attack, force, damageSource, attacker, applyToSelf); if (GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) { @@ -250,7 +255,7 @@ namespace Barotrauma partial void ExplodeProjSpecific(Vector2 worldPosition, Hull hull); - private void DamageCharacters(Vector2 worldPosition, Attack attack, float force, Entity damageSource, Character attacker) + private void DamageCharacters(Vector2 worldPosition, Attack attack, float force, Entity damageSource, Character attacker, bool applyToSelf) { if (attack.Range <= 0.0f) { return; } @@ -265,6 +270,8 @@ namespace Barotrauma { continue; } + if (c == attacker && !applyToSelf) { continue; } + if (onlyInside && c.Submarine == null) { continue; } else if (onlyOutside && c.Submarine != null) { continue; } diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs index afb5f6086..e32aa7ed7 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Levels/Level.cs @@ -3641,9 +3641,10 @@ namespace Barotrauma } if (LevelData.IsBeaconActive) { - if (reactorContainer != null && reactorContainer.Inventory.IsEmpty()) + if (reactorContainer != null && reactorContainer.Inventory.IsEmpty() && + reactorContainer.ContainableItemIdentifiers.Any() && ItemPrefab.Prefabs.ContainsKey(reactorContainer.ContainableItemIdentifiers.FirstOrDefault())) { - ItemPrefab fuelPrefab = ItemPrefab.Prefabs[reactorContainer.ContainableItems[0].Identifiers[0]]; + ItemPrefab fuelPrefab = ItemPrefab.Prefabs[reactorContainer.ContainableItemIdentifiers.FirstOrDefault()]; Spawner.AddToSpawnQueue( fuelPrefab, reactorContainer.Inventory, onSpawned: (it) => reactorComponent.PowerUpImmediately()); diff --git a/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs b/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs index 80ba583ee..f099563c6 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/Map/Structure.cs @@ -203,8 +203,8 @@ namespace Barotrauma if (!ResizeHorizontal || !ResizeVertical) { - int newWidth = ResizeHorizontal ? rect.Width : (int)(defaultRect.Width * relativeScale); - int newHeight = ResizeVertical ? rect.Height : (int)(defaultRect.Height * relativeScale); + int newWidth = Math.Max(ResizeHorizontal ? rect.Width : (int)(defaultRect.Width * relativeScale), 1); + int newHeight = Math.Max(ResizeVertical ? rect.Height : (int)(defaultRect.Height * relativeScale), 1); Rect = new Rectangle(rect.X, rect.Y, newWidth, newHeight); if (StairDirection != Direction.None) { diff --git a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs index faa57d7b1..d9ae32ee1 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/StatusEffects/StatusEffect.cs @@ -223,6 +223,11 @@ namespace Barotrauma private readonly TargetType targetTypes; protected HashSet targetIdentifiers; + /// + /// Index of the slot the target must be in when targeting a Contained item + /// + public int TargetSlot = -1; + private readonly List requiredItems; public readonly string[] propertyNames; @@ -262,7 +267,9 @@ namespace Barotrauma public readonly List Explosions; private readonly List spawnItems; + private readonly bool spawnItemRandomly; private readonly List spawnCharacters; + private readonly List aiTriggers; private readonly List triggeredEvents; @@ -294,7 +301,10 @@ namespace Barotrauma get { return targetIdentifiers; } } - public HashSet AllowedAfflictions { get; private set; } + /// + /// Which type of afflictions the target must receive for the StatusEffect to be applied. Only valid when the type of the effect is OnDamaged. + /// + private readonly HashSet<(string affliction, float strength)> requiredAfflictions; public List Afflictions { @@ -307,7 +317,7 @@ namespace Barotrauma get { return spawnCharacters; } } - public readonly List> ReduceAffliction; + public readonly List<(string affliction, float amount)> ReduceAffliction; private readonly List giveExperiences; private readonly List<(string identifier, float amount)> giveSkills; @@ -354,12 +364,13 @@ namespace Barotrauma { requiredItems = new List(); spawnItems = new List(); + spawnItemRandomly = element.GetAttributeBool("spawnitemrandomly", false); spawnCharacters = new List(); aiTriggers = new List(); Afflictions = new List(); Explosions = new List(); triggeredEvents = new List(); - ReduceAffliction = new List>(); + ReduceAffliction = new List<(string affliction, float amount)>(); giveExperiences = new List(); giveSkills = new List<(string, float)>(); @@ -369,6 +380,8 @@ namespace Barotrauma OnlyPlayerTriggered = element.GetAttributeBool("onlyplayertriggered", false); AllowWhenBroken = element.GetAttributeBool("allowwhenbroken", false); + TargetSlot = element.GetAttributeInt("targetslot", -1); + Range = element.GetAttributeFloat("range", 0.0f); Offset = element.GetAttributeVector2("offset", Vector2.Zero); string[] targetLimbNames = element.GetAttributeStringArray("targetlimb", null) ?? element.GetAttributeStringArray("targetlimbs", null); @@ -436,11 +449,12 @@ namespace Barotrauma } break; case "allowedafflictions": + case "requiredafflictions": string[] types = attribute.Value.Split(','); - AllowedAfflictions = new HashSet(); + requiredAfflictions ??= new HashSet<(string, float)>(); for (int i = 0; i < types.Length; i++) { - AllowedAfflictions.Add(types[i].Trim().ToLowerInvariant()); + requiredAfflictions.Add((types[i].Trim().ToLowerInvariant(), 0.0f)); } break; case "duration": @@ -551,6 +565,13 @@ namespace Barotrauma } requiredItems.Add(newRequiredItem); break; + case "requiredaffliction": + + requiredAfflictions ??= new HashSet<(string, float)>(); + requiredAfflictions.Add(( + subElement.GetAttributeString("identifier", string.Empty), + subElement.GetAttributeFloat("minstrength", 0.0f))); + break; case "conditional": foreach (XAttribute attribute in subElement.Attributes()) { @@ -593,7 +614,7 @@ namespace Barotrauma if (subElement.Attribute("name") != null) { DebugConsole.ThrowError("Error in StatusEffect (" + parentDebugName + ") - define afflictions using identifiers or types instead of names."); - ReduceAffliction.Add(new Pair( + ReduceAffliction.Add(( subElement.GetAttributeString("name", "").ToLowerInvariant(), subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount"))); } @@ -604,9 +625,7 @@ namespace Barotrauma if (AfflictionPrefab.List.Any(ap => ap.Identifier == name || ap.AfflictionType == name)) { - ReduceAffliction.Add(new Pair( - name, - subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount"))); + ReduceAffliction.Add((name, subElement.GetAttributeFloat(1.0f, "amount", "strength", "reduceamount"))); } else { @@ -672,6 +691,17 @@ namespace Barotrauma return false; } + public bool HasRequiredAfflictions(AttackResult attackResult) + { + if (requiredAfflictions == null) { return true; } + if (attackResult.Afflictions == null) { return false; } + if (attackResult.Afflictions.None(a => requiredAfflictions.Any(a2 => a.Strength >= a2.strength && a.Identifier == a2.affliction || a.Prefab.AfflictionType == a2.affliction))) + { + return false; + } + return true; + } + public virtual bool HasRequiredItems(Entity entity) { if (entity == null) { return true; } @@ -1118,13 +1148,10 @@ namespace Barotrauma { if (Rand.Value(Rand.RandSync.Unsynced) > affliction.Probability) { continue; } Affliction newAffliction = affliction; - if (!disableDeltaTime && !setValue) - { - newAffliction = affliction.CreateMultiplied(deltaTime); - } if (target is Character character) { if (character.Removed) { continue; } + newAffliction = GetMultipliedAffliction(affliction, entity, character, deltaTime); character.LastDamageSource = entity; foreach (Limb limb in character.AnimController.Limbs) { @@ -1133,6 +1160,7 @@ namespace Barotrauma if (targetLimbs != null && !targetLimbs.Contains(limb.type)) { continue; } AttackResult result = limb.character.DamageLimb(position, limb, newAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source, allowStacking: !setValue); limb.character.TrySeverLimbJoints(limb, SeverLimbsProbability, disableDeltaTime ? result.Damage : result.Damage / deltaTime, allowBeheading: true); + RegisterTreatmentResults(entity, limb, affliction, result); //only apply non-limb-specific afflictions to the first limb if (!affliction.Prefab.LimbSpecific) { break; } } @@ -1141,14 +1169,15 @@ namespace Barotrauma { if (limb.IsSevered) { continue; } if (limb.character.Removed || limb.Removed) { continue; } + newAffliction = GetMultipliedAffliction(affliction, entity, limb.character, deltaTime); AttackResult result = limb.character.DamageLimb(position, limb, newAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: affliction.Source, allowStacking: !setValue); limb.character.TrySeverLimbJoints(limb, SeverLimbsProbability, disableDeltaTime ? result.Damage : result.Damage / deltaTime, allowBeheading: true); + RegisterTreatmentResults(entity, limb, affliction, result); } } - foreach (Pair reduceAffliction in ReduceAffliction) + foreach (var (affliction, amount) in ReduceAffliction) { - float reduceAmount = disableDeltaTime || setValue ? reduceAffliction.Second : reduceAffliction.Second * deltaTime; Limb targetLimb = null; Character targetCharacter = null; if (target is Character character) @@ -1162,8 +1191,11 @@ namespace Barotrauma } if (targetCharacter != null && !targetCharacter.Removed) { + ActionType? actionType = null; + if (entity is Item item && item.UseInHealthInterface) { actionType = type; } + float reduceAmount = amount * GetAfflictionMultiplier(entity, targetCharacter, deltaTime); float prevVitality = targetCharacter.Vitality; - targetCharacter.CharacterHealth.ReduceAffliction(targetLimb, reduceAffliction.First, reduceAmount); + targetCharacter.CharacterHealth.ReduceAffliction(targetLimb, affliction, reduceAmount, treatmentAction: actionType); if (user != null && user != targetCharacter) { if (!targetCharacter.IsDead) @@ -1305,111 +1337,124 @@ namespace Barotrauma }); } } - foreach (ItemSpawnInfo itemSpawnInfo in spawnItems) + if (spawnItemRandomly) { - for (int i = 0; i < itemSpawnInfo.Count; i++) + SpawnItem(spawnItems.GetRandom()); + } + else + { + foreach (ItemSpawnInfo itemSpawnInfo in spawnItems) { - switch (itemSpawnInfo.SpawnPosition) + for (int i = 0; i < itemSpawnInfo.Count; i++) { - case ItemSpawnInfo.SpawnPositionType.This: - Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, position + Rand.Vector(itemSpawnInfo.Spread, Rand.RandSync.Server), onSpawned: newItem => - { - Projectile projectile = newItem.GetComponent(); - if (projectile != null && user != null && sourceBody != null && entity != null) - { - var rope = newItem.GetComponent(); - if (rope != null && sourceBody.UserData is Limb sourceLimb) - { - rope.Attach(sourceLimb, newItem); - } - - float spread = MathHelper.ToRadians(Rand.Range(-itemSpawnInfo.AimSpread, itemSpawnInfo.AimSpread)); - var worldPos = sourceBody.Position; - float rotation = itemSpawnInfo.Rotation; - if (user.Submarine != null) - { - worldPos += user.Submarine.Position; - } - switch (itemSpawnInfo.RotationType) - { - case ItemSpawnInfo.SpawnRotationType.Fixed: - rotation = sourceBody.TransformRotation(itemSpawnInfo.Rotation); - break; - case ItemSpawnInfo.SpawnRotationType.Target: - rotation = MathUtils.VectorToAngle(entity.WorldPosition - worldPos); - break; - case ItemSpawnInfo.SpawnRotationType.Limb: - rotation = sourceBody.TransformedRotation; - break; - case ItemSpawnInfo.SpawnRotationType.Collider: - rotation = user.AnimController.Collider.Rotation; - break; - case ItemSpawnInfo.SpawnRotationType.MainLimb: - rotation = user.AnimController.MainLimb.body.TransformedRotation; - break; - default: - throw new NotImplementedException("Not implemented: " + itemSpawnInfo.RotationType); - } - rotation += MathHelper.ToRadians(itemSpawnInfo.Rotation * user.AnimController.Dir); - projectile.Shoot(user, ConvertUnits.ToSimUnits(worldPos), ConvertUnits.ToSimUnits(worldPos), rotation + spread, ignoredBodies: user.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: true); - } - else - { - newItem.body?.ApplyLinearImpulse(Rand.Vector(1) * itemSpawnInfo.Speed); - newItem.Rotation = itemSpawnInfo.Rotation; - } - }); - break; - case ItemSpawnInfo.SpawnPositionType.ThisInventory: - { - Inventory inventory = null; - if (entity is Character character && character.Inventory != null) - { - inventory = character.Inventory; - } - else if (entity is Item item) - { - inventory = item?.GetComponent()?.Inventory; - } - if (inventory != null && inventory.CanBePut(itemSpawnInfo.ItemPrefab)) - { - Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, inventory, spawnIfInventoryFull: false); - } - } - break; - case ItemSpawnInfo.SpawnPositionType.ContainedInventory: - { - Inventory thisInventory = null; - if (entity is Character character) - { - thisInventory = character.Inventory; - } - else if (entity is Item item) - { - thisInventory = item?.GetComponent()?.Inventory; - } - if (thisInventory != null) - { - foreach (Item item in thisInventory.AllItems) - { - Inventory containedInventory = item.GetComponent()?.Inventory; - if (containedInventory != null && containedInventory.CanBePut(itemSpawnInfo.ItemPrefab)) - { - Entity.Spawner.AddToSpawnQueue(itemSpawnInfo.ItemPrefab, containedInventory, spawnIfInventoryFull: false); - } - break; - } - } - } - break; + SpawnItem(itemSpawnInfo); } } } + + + void SpawnItem(ItemSpawnInfo chosenItemSpawnInfo) + { + switch (chosenItemSpawnInfo.SpawnPosition) + { + case ItemSpawnInfo.SpawnPositionType.This: + Entity.Spawner.AddToSpawnQueue(chosenItemSpawnInfo.ItemPrefab, position + Rand.Vector(chosenItemSpawnInfo.Spread, Rand.RandSync.Server), onSpawned: newItem => + { + Projectile projectile = newItem.GetComponent(); + if (projectile != null && user != null && sourceBody != null && entity != null) + { + var rope = newItem.GetComponent(); + if (rope != null && sourceBody.UserData is Limb sourceLimb) + { + rope.Attach(sourceLimb, newItem); + } + + float spread = MathHelper.ToRadians(Rand.Range(-chosenItemSpawnInfo.AimSpread, chosenItemSpawnInfo.AimSpread)); + var worldPos = sourceBody.Position; + float rotation = chosenItemSpawnInfo.Rotation; + if (user.Submarine != null) + { + worldPos += user.Submarine.Position; + } + switch (chosenItemSpawnInfo.RotationType) + { + case ItemSpawnInfo.SpawnRotationType.Fixed: + rotation = sourceBody.TransformRotation(chosenItemSpawnInfo.Rotation); + break; + case ItemSpawnInfo.SpawnRotationType.Target: + rotation = MathUtils.VectorToAngle(entity.WorldPosition - worldPos); + break; + case ItemSpawnInfo.SpawnRotationType.Limb: + rotation = sourceBody.TransformedRotation; + break; + case ItemSpawnInfo.SpawnRotationType.Collider: + rotation = user.AnimController.Collider.Rotation; + break; + case ItemSpawnInfo.SpawnRotationType.MainLimb: + rotation = user.AnimController.MainLimb.body.TransformedRotation; + break; + default: + throw new NotImplementedException("Not implemented: " + chosenItemSpawnInfo.RotationType); + } + rotation += MathHelper.ToRadians(chosenItemSpawnInfo.Rotation * user.AnimController.Dir); + projectile.Shoot(user, ConvertUnits.ToSimUnits(worldPos), ConvertUnits.ToSimUnits(worldPos), rotation + spread, ignoredBodies: user.AnimController.Limbs.Where(l => !l.IsSevered).Select(l => l.body.FarseerBody).ToList(), createNetworkEvent: true); + } + else + { + newItem.body?.ApplyLinearImpulse(Rand.Vector(1) * chosenItemSpawnInfo.Speed); + newItem.Rotation = chosenItemSpawnInfo.Rotation; + } + }); + break; + case ItemSpawnInfo.SpawnPositionType.ThisInventory: + { + Inventory inventory = null; + if (entity is Character character && character.Inventory != null) + { + inventory = character.Inventory; + } + else if (entity is Item item) + { + inventory = item?.GetComponent()?.Inventory; + } + if (inventory != null && inventory.CanBePut(chosenItemSpawnInfo.ItemPrefab)) + { + Entity.Spawner.AddToSpawnQueue(chosenItemSpawnInfo.ItemPrefab, inventory, spawnIfInventoryFull: false); + } + } + break; + case ItemSpawnInfo.SpawnPositionType.ContainedInventory: + { + Inventory thisInventory = null; + if (entity is Character character) + { + thisInventory = character.Inventory; + } + else if (entity is Item item) + { + thisInventory = item?.GetComponent()?.Inventory; + } + if (thisInventory != null) + { + foreach (Item item in thisInventory.AllItems) + { + Inventory containedInventory = item.GetComponent()?.Inventory; + if (containedInventory != null && containedInventory.CanBePut(chosenItemSpawnInfo.ItemPrefab)) + { + Entity.Spawner.AddToSpawnQueue(chosenItemSpawnInfo.ItemPrefab, containedInventory, spawnIfInventoryFull: false); + } + break; + } + } + } + break; + } + } } ApplyProjSpecific(deltaTime, entity, targets, hull, position, playSound: true); - Character CharacterFromTarget(ISerializableEntity target) + static Character CharacterFromTarget(ISerializableEntity target) { Character targetCharacter = target as Character; if (targetCharacter == null) @@ -1494,22 +1539,24 @@ namespace Barotrauma foreach (Affliction affliction in element.Parent.Afflictions) { - Affliction multipliedAffliction = affliction; - if (!element.Parent.disableDeltaTime && !element.Parent.setValue) { multipliedAffliction = affliction.CreateMultiplied(deltaTime); } - + Affliction newAffliction = affliction; if (target is Character character) { if (character.Removed) { continue; } - character.AddDamage(character.WorldPosition, multipliedAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attacker: element.User); + newAffliction = element.Parent.GetMultipliedAffliction(affliction, element.Entity, character, deltaTime); + var result = character.AddDamage(character.WorldPosition, newAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attacker: element.User); + element.Parent.RegisterTreatmentResults(element.Entity, result.HitLimb, affliction, result); } else if (target is Limb limb) { if (limb.character.Removed || limb.Removed) { continue; } - limb.character.DamageLimb(limb.WorldPosition, limb, multipliedAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: element.User); + newAffliction = element.Parent.GetMultipliedAffliction(affliction, element.Entity, limb.character, deltaTime); + var result = limb.character.DamageLimb(limb.WorldPosition, limb, newAffliction.ToEnumerable(), stun: 0.0f, playSound: false, attackImpulse: 0.0f, attacker: element.User); + element.Parent.RegisterTreatmentResults(element.Entity, limb, affliction, result); } } - foreach (Pair reduceAffliction in element.Parent.ReduceAffliction) + foreach (var (affliction, amount) in element.Parent.ReduceAffliction) { Limb targetLimb = null; Character targetCharacter = null; @@ -1524,8 +1571,11 @@ namespace Barotrauma } if (targetCharacter != null && !targetCharacter.Removed) { + ActionType? actionType = null; + if (element.Entity is Item item && item.UseInHealthInterface) { actionType = element.Parent.type; } + float reduceAmount = amount * element.Parent.GetAfflictionMultiplier(element.Entity, targetCharacter, deltaTime); float prevVitality = targetCharacter.Vitality; - targetCharacter.CharacterHealth.ReduceAffliction(targetLimb, reduceAffliction.First, reduceAffliction.Second * deltaTime); + targetCharacter.CharacterHealth.ReduceAffliction(targetLimb, affliction, reduceAmount, treatmentAction: actionType); if (element.User != null && element.User != targetCharacter) { if (!targetCharacter.IsDead) @@ -1554,6 +1604,48 @@ namespace Barotrauma } } + private float GetAfflictionMultiplier(Entity entity, Character targetCharacter, float deltaTime) + { + float multiplier = !setValue && !disableDeltaTime ? deltaTime : 1.0f; + if (entity is Item sourceItem && sourceItem.HasTag("medical")) + { + multiplier *= 1 + targetCharacter.GetStatValue(StatTypes.MedicalItemEffectivenessMultiplier); + } + return multiplier; + } + + private Affliction GetMultipliedAffliction(Affliction affliction, Entity entity, Character targetCharacter, float deltaTime) + { + float afflictionMultiplier = GetAfflictionMultiplier(entity, targetCharacter, deltaTime); + if (!MathUtils.NearlyEqual(afflictionMultiplier, 1.0f)) + { + return affliction.CreateMultiplied(afflictionMultiplier); + } + return affliction; + } + + private void RegisterTreatmentResults(Entity entity, Limb limb, Affliction affliction, AttackResult result) + { + if (entity is Item item && item.UseInHealthInterface) + { + foreach (Affliction limbAffliction in limb.character.CharacterHealth.GetAllAfflictions()) + { + if (result.Afflictions.Any(a => a.Prefab == limbAffliction.Prefab) && + (!affliction.Prefab.LimbSpecific || limb.character.CharacterHealth.GetAfflictionLimb(affliction) == limb)) + { + if (type == ActionType.OnUse) + { + limbAffliction.AppliedAsSuccessfulTreatmentTime = Timing.TotalTime; + } + else if (type == ActionType.OnFailure) + { + limbAffliction.AppliedAsFailedTreatmentTime = Timing.TotalTime; + } + } + } + } + } + static partial void UpdateAllProjSpecific(float deltaTime); public static void StopAll() diff --git a/Barotrauma/BarotraumaShared/SharedSource/TextManager.cs b/Barotrauma/BarotraumaShared/SharedSource/TextManager.cs index c7aa407ea..06710d345 100644 --- a/Barotrauma/BarotraumaShared/SharedSource/TextManager.cs +++ b/Barotrauma/BarotraumaShared/SharedSource/TextManager.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Text.RegularExpressions; using Barotrauma.Extensions; +using System.Xml.Linq; namespace Barotrauma { @@ -443,6 +444,42 @@ namespace Barotrauma } } + /// + /// Constructs a string from XML in a way that allows replacing one or more variables with hard-coded or localized values. Usage example in the method's comments. + /// + public static void ConstructDescription(ref string Description, XElement descriptionElement) + { + /* + + + + + + */ + + string extraDescriptionLine = Get(descriptionElement.GetAttributeString("tag", string.Empty)); + if (string.IsNullOrEmpty(extraDescriptionLine)) { return; } + foreach (XElement replaceElement in descriptionElement.Elements()) + { + if (replaceElement.Name.ToString().ToLowerInvariant() != "replace") { continue; } + + string tag = replaceElement.GetAttributeString("tag", string.Empty); + string[] replacementValues = replaceElement.GetAttributeStringArray("value", new string[0]); + string replacementValue = string.Empty; + for (int i = 0; i < replacementValues.Length; i++) + { + replacementValue += Get(replacementValues[i], returnNull: true) ?? replacementValues[i]; + if (i < replacementValues.Length - 1) + { + replacementValue += ", "; + } + } + extraDescriptionLine = extraDescriptionLine.Replace(tag, replacementValue); + } + if (!string.IsNullOrEmpty(Description)) { Description += "\n"; } + Description += extraDescriptionLine; + } + public static string FormatServerMessage(string textId) { return $"{textId}~"; diff --git a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub index 79b880af6f902f324c992d577e9839c294cf4c78..90a86631d98d15bfee734d435ae17ca89fb03908 100644 GIT binary patch delta 190025 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 z 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%0Apy<^XB~oZw5Eq(ex4wEw43<^cR%c8JPg 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 TPbE1pM*sQ$f$BtnEj0}QYH+H| delta 190236 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 pWPZC2;^M0*TIyh@sc{i?@EWCC_!Uzl>) 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