From 74da38bd1099e1b3168840a714e7609fdafd4640 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Wed, 10 Apr 2019 13:26:56 +0300 Subject: [PATCH] (3315662d5) Implement optional required items (lol) and fix the doors. It's a bit confusing, but should work. --- .../Source/Items/Components/Door.cs | 28 ++++++-- .../Source/Items/Components/ItemComponent.cs | 71 ++++++++++++------- .../Source/Items/RelatedItem.cs | 8 ++- 3 files changed, 75 insertions(+), 32 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs index 43c08904d..9e95085aa 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs @@ -211,24 +211,32 @@ namespace Barotrauma.Items.Components #endif } - private string text = TextManager.Get("DoorMsgCannotOpen"); + private string accessDeniedTxt = TextManager.Get("AccessDenied"); + private bool hasIdCard; public override bool HasRequiredItems(Character character, bool addMessage, string msg = null) { if (item.Condition <= RepairThreshold) return true; //For repairing + var idCard = character.Inventory.FindItemByIdentifier("idcard"); + hasIdCard = requiredItems.Any(ri => ri.Value.Any(r => r.MatchesItem(idCard))); + Msg = hasIdCard ? "ItemMsgOpen" : "ItemMsgForceOpenCrowbar"; + ParseMsg(); + //this is a bit pointless atm because if canBePicked is false it won't allow you to do Pick() anyway, however it's still good for future-proofing. - return requiredItems.Any() ? base.HasRequiredItems(character, addMessage, msg ?? text) : canBePicked; + return requiredItems.Any() ? base.HasRequiredItems(character, addMessage, msg ?? accessDeniedTxt) : canBePicked; } public override bool Pick(Character picker) { - return item.Condition <= RepairThreshold ? true : base.Pick(picker); + if (item.Condition <= RepairThreshold) { return true; } + if (HasRequiredItems(picker, false) && hasIdCard) { return false; } + return base.Pick(picker); } public override bool OnPicked(Character picker) { if (item.Condition <= RepairThreshold) return true; //repairs - if (requiredItems.Any()) + if (requiredItems.Any() && !hasIdCard) { ForceOpen(ActionType.OnPicked); } @@ -247,9 +255,19 @@ namespace Barotrauma.Items.Components { //can only be selected if the item is broken if (item.Condition <= RepairThreshold) return true; //repairs - if (requiredItems.None()) + bool hasRequiredItems = HasRequiredItems(character, false); + if (requiredItems.None() || hasRequiredItems && hasIdCard) { + float originalPickingTime = PickingTime; + PickingTime = 0; ForceOpen(ActionType.OnUse); + PickingTime = originalPickingTime; + } + else if (hasRequiredItems) + { +#if CLIENT + GUI.AddMessage(accessDeniedTxt, Color.Red); +#endif } return false; } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs index e53053186..7a0027a89 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/ItemComponent.cs @@ -581,43 +581,63 @@ namespace Barotrauma.Items.Components { if (!requiredItems.Any()) return true; if (character.Inventory == null) return false; - + bool hasRequiredItems = false; + bool canContinue = true; if (requiredItems.ContainsKey(RelatedItem.RelationType.Equipped)) { foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Equipped]) { - if (character.SelectedItems.FirstOrDefault(it => it != null && it.Condition > 0.0f && ri.MatchesItem(it)) == null) - { -#if CLIENT - msg = msg ?? ri.Msg; - if (addMessage && !string.IsNullOrEmpty(msg)) - { - GUI.AddMessage(msg, Color.Red); - } -#endif - return false; - } + canContinue = CheckItems(ri, character.SelectedItems); + if (!canContinue) { break; } } } - if (requiredItems.ContainsKey(RelatedItem.RelationType.Picked)) + if (canContinue) { - foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Picked]) + if (requiredItems.ContainsKey(RelatedItem.RelationType.Picked)) { - if (character.Inventory.Items.FirstOrDefault(it => it != null && it.Condition > 0.0f && ri.MatchesItem(it)) == null) + foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Picked]) { -#if CLIENT - msg = msg ?? ri.Msg; - if (addMessage && !string.IsNullOrEmpty(msg)) - { - GUI.AddMessage(msg, Color.Red); - } -#endif - return false; + if (!CheckItems(ri, character.Inventory.Items)) { break; } } } } - - return true; + +#if CLIENT + if (!hasRequiredItems && addMessage && !string.IsNullOrEmpty(msg)) + { + GUI.AddMessage(msg, Color.Red); + } +#endif + return hasRequiredItems; + + bool CheckItems(RelatedItem relatedItem, IEnumerable itemList) + { + bool Predicate(Item it) => it != null && it.Condition > 0.0f && relatedItem.MatchesItem(it); + bool shouldBreak = false; + if (relatedItem.IsOptional) + { + if (!hasRequiredItems) + { + hasRequiredItems = itemList.Any(Predicate); + } + } + else + { + hasRequiredItems = itemList.Any(Predicate); + if (!hasRequiredItems) + { + shouldBreak = true; + } + } + if (!hasRequiredItems) + { + if (msg == null && !string.IsNullOrEmpty(relatedItem.Msg)) + { + msg = relatedItem.Msg; + } + } + return !shouldBreak; + } } public void ApplyStatusEffects(ActionType type, float deltaTime, Character character = null, Limb targetLimb = null, Character user = null) @@ -762,6 +782,7 @@ namespace Barotrauma.Items.Components { newRequiredItem.statusEffects = prevRequiredItem.statusEffects; newRequiredItem.Msg = prevRequiredItem.Msg; + newRequiredItem.IsOptional = prevRequiredItem.IsOptional; } if (!requiredItems.ContainsKey(newRequiredItem.Type)) diff --git a/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs b/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs index 6a7839e25..bbbfc6705 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/RelatedItem.cs @@ -16,6 +16,8 @@ namespace Barotrauma Container } + public bool IsOptional { get; set; } + private string[] identifiers; private string[] excludedIdentifiers; @@ -138,7 +140,8 @@ namespace Barotrauma { element.Add( new XAttribute("identifiers", JoinedIdentifiers), - new XAttribute("type", type.ToString())); + new XAttribute("type", type.ToString()), + new XAttribute("optional", IsOptional)); if (excludedIdentifiers.Length > 0) { @@ -218,7 +221,8 @@ namespace Barotrauma if (subElement.Name.ToString().ToLowerInvariant() != "statuseffect") continue; ri.statusEffects.Add(StatusEffect.Load(subElement, parentDebugName)); } - + + ri.IsOptional = element.GetAttributeBool("optional", false); return ri; } }