Unstable v0.1300.0.0 (February 19th 2021)
This commit is contained in:
@@ -235,6 +235,12 @@ namespace Barotrauma.Items.Components
|
||||
[Serialize(0f, false, description: "How useful the item is in combat? Used by AI to decide which item it should use as a weapon. For the sake of clarity, use a value between 0 and 100 (not enforced).")]
|
||||
public float CombatPriority { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Which sound should be played when manual sound selection type is selected? Not [Editable] because we don't want this visible in the editor for every component.
|
||||
/// </summary>
|
||||
[Serialize(0, true, alwaysUseInstanceValues: true)]
|
||||
public int ManuallySelectedSound { get; private set; }
|
||||
|
||||
public ItemComponent(Item item, XElement element)
|
||||
{
|
||||
this.item = item;
|
||||
@@ -394,7 +400,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
//called when isActive is true and condition > 0.0f
|
||||
public virtual void Update(float deltaTime, Camera cam) { }
|
||||
public virtual void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime);
|
||||
}
|
||||
|
||||
//called when isActive is true and condition == 0.0f
|
||||
public virtual void UpdateBroken(float deltaTime, Camera cam)
|
||||
@@ -450,22 +459,20 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public virtual bool Combine(Item item, Character user)
|
||||
{
|
||||
if (canBeCombined && this.item.Prefab == item.Prefab && item.Condition > 0.0f && this.item.Condition > 0.0f)
|
||||
if (canBeCombined && this.item.Prefab == item.Prefab &&
|
||||
item.Condition > 0.0f && this.item.Condition > 0.0f &&
|
||||
!item.IsFullCondition && !this.item.IsFullCondition)
|
||||
{
|
||||
float transferAmount = 0.0f;
|
||||
if (this.Item.Condition <= item.Condition)
|
||||
transferAmount = Math.Min(item.Condition, this.item.MaxCondition - this.item.Condition);
|
||||
else
|
||||
transferAmount = -Math.Min(this.item.Condition, item.MaxCondition - item.Condition);
|
||||
float transferAmount = Math.Min(item.Condition, this.item.MaxCondition - this.item.Condition);
|
||||
|
||||
if (transferAmount == 0.0f) { return false; }
|
||||
if (MathUtils.NearlyEqual(transferAmount, 0.0f)) { return false; }
|
||||
if (removeOnCombined)
|
||||
{
|
||||
if (item.Condition - transferAmount <= 0.0f)
|
||||
{
|
||||
if (item.ParentInventory != null)
|
||||
{
|
||||
if (item.ParentInventory.Owner is Character owner && owner.HasSelectedItem(item))
|
||||
if (item.ParentInventory.Owner is Character owner && owner.HeldItems.Contains(item))
|
||||
{
|
||||
item.Unequip(owner);
|
||||
}
|
||||
@@ -481,7 +488,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (this.Item.ParentInventory != null)
|
||||
{
|
||||
if (this.Item.ParentInventory.Owner is Character owner && owner.HasSelectedItem(this.Item))
|
||||
if (this.Item.ParentInventory.Owner is Character owner && owner.HeldItems.Contains(this.Item))
|
||||
{
|
||||
this.Item.Unequip(owner);
|
||||
}
|
||||
@@ -651,16 +658,18 @@ namespace Barotrauma.Items.Components
|
||||
/// <summary>
|
||||
/// Only checks if any of the Picked requirements are matched (used for checking id card(s)). Much simpler and a bit different than HasRequiredItems.
|
||||
/// </summary>
|
||||
public bool HasAccess(Character character)
|
||||
public virtual bool HasAccess(Character character)
|
||||
{
|
||||
if (character.Inventory == null) { return false; }
|
||||
if (!item.IsInteractable(character)) { return false; }
|
||||
if (requiredItems.None()) { return true; }
|
||||
|
||||
foreach (Item item in character.Inventory.Items)
|
||||
if (character.Inventory != null)
|
||||
{
|
||||
if (requiredItems.Any(ri => ri.Value.Any(r => r.Type == RelatedItem.RelationType.Picked && r.MatchesItem(item))))
|
||||
foreach (Item item in character.Inventory.AllItems)
|
||||
{
|
||||
return true;
|
||||
if (requiredItems.Any(ri => ri.Value.Any(r => r.Type == RelatedItem.RelationType.Picked && r.MatchesItem(item))))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -669,6 +678,7 @@ namespace Barotrauma.Items.Components
|
||||
public virtual bool HasRequiredItems(Character character, bool addMessage, string msg = null)
|
||||
{
|
||||
if (requiredItems.None()) { return true; }
|
||||
if (!character.IsPlayer && character.Params.AI != null && character.Params.AI.Infiltrate) { return true; }
|
||||
if (character.Inventory == null) { return false; }
|
||||
bool hasRequiredItems = false;
|
||||
bool canContinue = true;
|
||||
@@ -676,7 +686,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Equipped])
|
||||
{
|
||||
canContinue = CheckItems(ri, character.SelectedItems);
|
||||
canContinue = CheckItems(ri, character.HeldItems);
|
||||
if (!canContinue) { break; }
|
||||
}
|
||||
}
|
||||
@@ -686,7 +696,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
foreach (RelatedItem ri in requiredItems[RelatedItem.RelationType.Picked])
|
||||
{
|
||||
if (!CheckItems(ri, character.Inventory.Items)) { break; }
|
||||
if (!CheckItems(ri, character.Inventory.AllItems)) { break; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -942,33 +952,13 @@ namespace Barotrauma.Items.Components
|
||||
#region AI related
|
||||
protected const float AIUpdateInterval = 0.2f;
|
||||
protected float aiUpdateTimer;
|
||||
private int itemIndex;
|
||||
private Character previousUser;
|
||||
protected bool FindSuitableContainer(Character character, Func<Item, float> priority, out Item suitableContainer)
|
||||
{
|
||||
suitableContainer = null;
|
||||
if (character.AIController is HumanAIController aiController)
|
||||
{
|
||||
if (previousUser != character)
|
||||
{
|
||||
previousUser = character;
|
||||
itemIndex = 0;
|
||||
}
|
||||
if (character.FindItem(ref itemIndex, out Item targetContainer, ignoredItems: aiController.IgnoredItems, customPriorityFunction: priority))
|
||||
{
|
||||
suitableContainer = targetContainer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected AIObjectiveContainItem AIContainItems<T>(ItemContainer container, Character character, AIObjective objective, int itemCount, bool equip, bool removeEmpty, bool spawnItemIfNotFound = false) where T : ItemComponent
|
||||
protected AIObjectiveContainItem AIContainItems<T>(ItemContainer container, Character character, AIObjective currentObjective, int itemCount, bool equip, bool removeEmpty, bool spawnItemIfNotFound = false, bool dropItemOnDeselected = false) where T : ItemComponent
|
||||
{
|
||||
AIObjectiveContainItem containObjective = null;
|
||||
if (character.AIController is HumanAIController aiController)
|
||||
{
|
||||
containObjective = new AIObjectiveContainItem(character, container.GetContainableItemIdentifiers.ToArray(), container, objective.objectiveManager, spawnItemIfNotFound: spawnItemIfNotFound)
|
||||
containObjective = new AIObjectiveContainItem(character, container.GetContainableItemIdentifiers.ToArray(), container, currentObjective.objectiveManager, spawnItemIfNotFound: spawnItemIfNotFound)
|
||||
{
|
||||
targetItemCount = itemCount,
|
||||
Equip = equip,
|
||||
@@ -986,91 +976,24 @@ namespace Barotrauma.Items.Components
|
||||
return 1.0f;
|
||||
}
|
||||
};
|
||||
containObjective.Abandoned += () =>
|
||||
containObjective.Abandoned += () => aiController.IgnoredItems.Add(container.Item);
|
||||
if (dropItemOnDeselected)
|
||||
{
|
||||
aiController.IgnoredItems.Add(container.Item);
|
||||
};
|
||||
objective.AddSubObjective(containObjective);
|
||||
currentObjective.Deselected += () =>
|
||||
{
|
||||
if (containObjective == null) { return; }
|
||||
if (containObjective.IsCompleted) { return; }
|
||||
Item item = containObjective.ItemToContain;
|
||||
if (item != null && character.CanInteractWith(item, checkLinked: false))
|
||||
{
|
||||
item.Drop(character);
|
||||
}
|
||||
};
|
||||
}
|
||||
currentObjective.AddSubObjective(containObjective);
|
||||
}
|
||||
return containObjective;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true when done seeking the suitable container.
|
||||
/// </summary>
|
||||
protected bool AIDecontainEmptyItems(Character character, AIObjective objective, bool equip, ItemContainer sourceContainer = null)
|
||||
{
|
||||
if (character.AIController is HumanAIController aiController)
|
||||
{
|
||||
ItemContainer sourceC = sourceContainer ?? (item.OwnInventory?.Owner is Item it ? it.GetComponent<ItemContainer>() : null);
|
||||
var containedItems = sourceContainer != null ? sourceContainer.Inventory.Items : item.OwnInventory.Items;
|
||||
foreach (Item containedItem in containedItems)
|
||||
{
|
||||
if (containedItem != null && containedItem.Condition <= 0.0f)
|
||||
{
|
||||
if (FindSuitableContainer(character,
|
||||
i =>
|
||||
{
|
||||
if (i.IsThisOrAnyContainerIgnoredByAI()) { return 0; }
|
||||
var container = i.GetComponent<ItemContainer>();
|
||||
if (container == null) { return 0; }
|
||||
if (container.Inventory.IsFull()) { return 0; }
|
||||
// Ignore containers that are identical to the source container
|
||||
if (sourceC != null && container.Item.Prefab == sourceC.Item.Prefab) { return 0; }
|
||||
if (container.ShouldBeContained(containedItem, out bool isRestrictionsDefined))
|
||||
{
|
||||
if (isRestrictionsDefined)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (containedItem.Prefab.IsContainerPreferred(container, out bool isPreferencesDefined, out bool isSecondary))
|
||||
{
|
||||
return isPreferencesDefined ? isSecondary ? 2 : 3 : 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return isPreferencesDefined ? 0 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}, out Item targetContainer))
|
||||
{
|
||||
var decontainObjective = new AIObjectiveDecontainItem(character, containedItem, objective.objectiveManager, sourceC, targetContainer?.GetComponent<ItemContainer>())
|
||||
{
|
||||
Equip = equip
|
||||
};
|
||||
decontainObjective.Abandoned += () =>
|
||||
{
|
||||
itemIndex = 0;
|
||||
if (targetContainer != null)
|
||||
{
|
||||
aiController.IgnoredItems.Add(targetContainer);
|
||||
}
|
||||
};
|
||||
decontainObjective.Completed += () =>
|
||||
{
|
||||
if (targetContainer == null)
|
||||
{
|
||||
itemIndex = 0;
|
||||
}
|
||||
};
|
||||
objective.AddSubObjectiveInQueue(decontainObjective);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user