OBT/1.2.1(Summer update)
Sync with upstream
This commit is contained in:
@@ -168,6 +168,9 @@ namespace Barotrauma.Items.Components
|
||||
set { attachedByDefault = value; }
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
[Editable]
|
||||
#endif
|
||||
[Serialize("0.0,0.0", IsPropertySaveable.No, description: "The position the character holds the item at (in pixels, as an offset from the character's shoulder)."+
|
||||
" For example, a value of 10,-100 would make the character hold the item 100 pixels below the shoulder and 10 pixels forwards.")]
|
||||
public Vector2 HoldPos
|
||||
@@ -177,8 +180,10 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
//the distance from the holding characters elbow to center of the physics body of the item
|
||||
protected Vector2 holdPos;
|
||||
|
||||
|
||||
#if DEBUG
|
||||
[Editable]
|
||||
#endif
|
||||
[Serialize("0.0,0.0", IsPropertySaveable.No, description: "The position the character holds the item at when aiming (in pixels, as an offset from the character's shoulder)."+
|
||||
" Works similarly as HoldPos, except that the position is rotated according to the direction the player is aiming at. For example, a value of 10,-100 would make the character hold the item 100 pixels below the shoulder and 10 pixels forwards when aiming directly to the right.")]
|
||||
public Vector2 AimPos
|
||||
@@ -279,6 +284,9 @@ namespace Barotrauma.Items.Components
|
||||
/// <summary>
|
||||
/// For setting the handle positions using status effects
|
||||
/// </summary>
|
||||
#if DEBUG
|
||||
[Editable]
|
||||
#endif
|
||||
public Vector2 Handle1
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(handlePos[0]); }
|
||||
@@ -299,6 +307,9 @@ namespace Barotrauma.Items.Components
|
||||
/// <summary>
|
||||
/// For setting the handle positions using status effects
|
||||
/// </summary>
|
||||
#if DEBUG
|
||||
[Editable]
|
||||
#endif
|
||||
public Vector2 Handle2
|
||||
{
|
||||
get { return ConvertUnits.ToDisplayUnits(handlePos[1]); }
|
||||
|
||||
@@ -119,7 +119,7 @@ namespace Barotrauma.Items.Components
|
||||
return OnPicked(picker, pickDroppedStack: true);
|
||||
}
|
||||
|
||||
public virtual bool OnPicked(Character picker, bool pickDroppedStack)
|
||||
public bool OnPicked(Character picker, bool pickDroppedStack, bool playSound = true)
|
||||
{
|
||||
//if the item has multiple Pickable components (e.g. Holdable and Wearable, check that we don't equip it in hands when the item is worn or vice versa)
|
||||
if (item.GetComponents<Pickable>().Any())
|
||||
@@ -156,7 +156,7 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnPicked, 1.0f, picker);
|
||||
#if CLIENT
|
||||
if (!GameMain.Instance.LoadingScreenOpen && picker == Character.Controlled) { SoundPlayer.PlayUISound(GUISoundType.PickItem); }
|
||||
if (!GameMain.Instance.LoadingScreenOpen && playSound && picker == Character.Controlled) { SoundPlayer.PlayUISound(GUISoundType.PickItem); }
|
||||
PlaySound(ActionType.OnPicked, picker);
|
||||
#endif
|
||||
if (pickDroppedStack)
|
||||
@@ -164,7 +164,7 @@ namespace Barotrauma.Items.Components
|
||||
foreach (var droppedItem in droppedStack)
|
||||
{
|
||||
if (droppedItem == item) { continue; }
|
||||
droppedItem.GetComponent<Pickable>().OnPicked(picker, pickDroppedStack: false);
|
||||
droppedItem.GetComponent<Pickable>().OnPicked(picker, pickDroppedStack: false, playSound: false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
+15
@@ -42,6 +42,9 @@ namespace Barotrauma.Items.Components
|
||||
set;
|
||||
}
|
||||
|
||||
[Serialize(true, IsPropertySaveable.No, description: $"Should this item be removed if the linked character is null?")]
|
||||
public bool RemoveItemIfCharacterNull { get; set; }
|
||||
|
||||
public Character? Character { get; private set; }
|
||||
|
||||
public bool DoesBleed => Character?.DoesBleed == true;
|
||||
@@ -50,6 +53,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
public LinkedControllerCharacterComponent(Item item, ContentXElement element) : base(item, element)
|
||||
{
|
||||
IsActive = true;
|
||||
|
||||
#if CLIENT
|
||||
spriteOverrides = element.Elements()
|
||||
.Where(static e => e.Name.LocalName.ToLowerInvariant() == "spriteoverride")
|
||||
@@ -58,6 +63,16 @@ namespace Barotrauma.Items.Components
|
||||
#endif
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime, Camera cam)
|
||||
{
|
||||
base.Update(deltaTime, cam);
|
||||
|
||||
if (RemoveItemIfCharacterNull && GameMain.NetworkMember is not { IsClient: true } && (Character == null || Character.Removed))
|
||||
{
|
||||
Entity.Spawner?.AddEntityToRemoveQueue(Item);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateLinkedCharacter(Character? character)
|
||||
{
|
||||
Character = character;
|
||||
|
||||
@@ -525,7 +525,7 @@ namespace Barotrauma.Items.Components
|
||||
return true;
|
||||
}
|
||||
|
||||
if (containerToSpawnOnSelectedItem.Inventory.AllItems.Any(x => x.Prefab == spawnItemOnSelectedPrefab))
|
||||
if (containerToSpawnOnSelectedItem.Inventory.AllItems.Any(item => item == spawnedItemOnSelected))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -345,6 +345,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
if (targetItem.AllowDeconstruct && allowRemove)
|
||||
{
|
||||
ApplyDeconstructionStatusEffects(targetItem, ActionType.OnDeconstructed, 1f);
|
||||
|
||||
//drop all items that are inside the deconstructed item
|
||||
foreach (ItemContainer ic in targetItem.GetComponents<ItemContainer>())
|
||||
{
|
||||
@@ -480,6 +482,7 @@ namespace Barotrauma.Items.Components
|
||||
// Move items again since the status effect could have spawned additional items in the character inventory
|
||||
MoveItemsFromCharacterToOutput();
|
||||
|
||||
character.Kill(CauseOfDeathType.Unknown, causeOfDeathAffliction: null);
|
||||
Entity.Spawner?.AddEntityToRemoveQueue(character);
|
||||
}, 0.1f);
|
||||
}
|
||||
|
||||
@@ -732,6 +732,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
|
||||
private readonly HashSet<Item> usedIngredients = new HashSet<Item>();
|
||||
private readonly Dictionary<ItemPrefab, int> ingredientFlexibilityCache = new Dictionary<ItemPrefab, int>();
|
||||
|
||||
public bool MissingRequiredRecipe(FabricationRecipe fabricableItem, Character character)
|
||||
{
|
||||
@@ -786,10 +787,24 @@ namespace Barotrauma.Items.Components
|
||||
//maintain a list of used ingredients so we don't end up considering the same item a suitable for multiple required ingredients
|
||||
usedIngredients.Clear();
|
||||
|
||||
return fabricableItem.RequiredItems.All(requiredItem =>
|
||||
// Items are considered more flexible if they can be used in many different requirements
|
||||
ingredientFlexibilityCache.Clear();
|
||||
foreach (var prefab in fabricableItem.RequiredItems.SelectMany(static r => r.ItemPrefabs))
|
||||
{
|
||||
ingredientFlexibilityCache[prefab] = fabricableItem.RequiredItems.Count(r => r.ItemPrefabs.Contains(prefab));
|
||||
}
|
||||
|
||||
return fabricableItem.RequiredItems
|
||||
// Match the most restrictive requirements to least restrictive first, while we still have items that we can use
|
||||
.OrderBy(static r => r.ItemPrefabs.Count())
|
||||
.ThenByDescending(static requiredItem => requiredItem.Amount)
|
||||
.All(requiredItem =>
|
||||
{
|
||||
int availableItemsAmount = 0;
|
||||
foreach (ItemPrefab requiredPrefab in requiredItem.ItemPrefabs)
|
||||
foreach (ItemPrefab requiredPrefab in requiredItem.ItemPrefabs
|
||||
// Fill in the least flexible and more abundant items first, so we don't end up using unique items first
|
||||
.OrderBy(GetItemFlexibility)
|
||||
.ThenByDescending(GetAvailableItemsCount))
|
||||
{
|
||||
if (!availableIngredients.TryGetValue(requiredPrefab.Identifier, out var availableItems)) { continue; }
|
||||
|
||||
@@ -811,6 +826,16 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
int GetAvailableItemsCount(ItemPrefab itemPrefab)
|
||||
{
|
||||
return availableIngredients.TryGetValue(itemPrefab.Identifier, out var list) ? list.Count : 0;
|
||||
}
|
||||
|
||||
int GetItemFlexibility(ItemPrefab itemPrefab)
|
||||
{
|
||||
return ingredientFlexibilityCache[itemPrefab];
|
||||
}
|
||||
}
|
||||
|
||||
private float GetRequiredTime(FabricationRecipe fabricableItem, Character user)
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
}
|
||||
|
||||
public LocalizedString? DisplayName { get; private set; }
|
||||
public LocalizedString DisplayName { get; private set; }
|
||||
|
||||
private float supplyRatio = 1f;
|
||||
public float SupplyRatio
|
||||
@@ -80,6 +80,7 @@ namespace Barotrauma.Items.Components
|
||||
SupplyRatio = element.GetAttributeFloat("ratio", SupplyRatio);
|
||||
}
|
||||
|
||||
DisplayName = TextManager.Get(name).Fallback(name);
|
||||
#if CLIENT
|
||||
CreateGUI();
|
||||
if (Screen.Selected is not { IsEditor: true })
|
||||
|
||||
@@ -252,7 +252,7 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
PhysicsBody = new PhysicsBody(currentWidth, currentHeight, radius: 0.0f, density: 1.5f, BodyType.Static, Physics.CollisionWall, LevelTrigger.GetCollisionCategories(triggeredBy))
|
||||
{
|
||||
UserData = item
|
||||
UserData = this
|
||||
};
|
||||
}
|
||||
else
|
||||
@@ -260,7 +260,7 @@ namespace Barotrauma.Items.Components
|
||||
currentRadius = Math.Max(ConvertUnits.ToSimUnits(Radius * item.Scale), 0.01f);
|
||||
PhysicsBody = new PhysicsBody(width: 0.0f, height: 0.0f, radius: currentRadius, density: 1.5f, BodyType.Static, Physics.CollisionWall, LevelTrigger.GetCollisionCategories(triggeredBy))
|
||||
{
|
||||
UserData = item
|
||||
UserData = this
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user