Build 0.20.16.1

This commit is contained in:
Regalis11
2022-12-20 17:05:53 +02:00
parent 9466d2245b
commit b8fa677148
22 changed files with 217 additions and 106 deletions
@@ -13,6 +13,11 @@
value = abilityElement.GetAttributeFloat("value", 0f);
}
public override void InitializeAbility(bool addingFirstTime)
{
VerifyState(conditionsMatched: true, timeSinceLastUpdate: 0.0f);
}
protected override void VerifyState(bool conditionsMatched, float timeSinceLastUpdate)
{
if (conditionsMatched != lastState)
@@ -168,7 +168,7 @@ namespace Barotrauma
PumpSpeed,
PumpMaxFlow,
ReactorMaxOutput,
ReactorFuelEfficiency,
ReactorFuelConsumption,
DeconstructorSpeed,
FabricationSpeed
}
@@ -366,7 +366,6 @@ namespace Barotrauma.Items.Components
for (int i = 0; i < entitiesInRange.Count; i++)
{
float dist = float.MaxValue;
if (entitiesInRange[i] is Structure structure)
{
if (structure.IsHorizontal)
@@ -388,7 +387,7 @@ namespace Barotrauma.Items.Components
}
else if (entitiesInRange[i] is Character character)
{
dist = MathUtils.LineSegmentToPointDistanceSquared(currPos, nodes[parentNodeIndex].WorldPosition, character.WorldPosition);
dist = MathF.Sqrt(MathUtils.LineSegmentToPointDistanceSquared(currPos, nodes[parentNodeIndex].WorldPosition, character.WorldPosition));
}
if (dist < closestDist)
@@ -874,6 +874,6 @@ namespace Barotrauma.Items.Components
}
private float GetMaxOutput() => item.StatManager.GetAdjustedValue(ItemTalentStats.ReactorMaxOutput, MaxPowerOutput);
private float GetFuelConsumption() => item.StatManager.GetAdjustedValue(ItemTalentStats.ReactorFuelEfficiency, fuelConsumptionRate);
private float GetFuelConsumption() => item.StatManager.GetAdjustedValue(ItemTalentStats.ReactorFuelConsumption, fuelConsumptionRate);
}
}
@@ -775,7 +775,13 @@ namespace Barotrauma.Items.Components
else if (target.Body.UserData is Item item)
{
if (item.Condition <= 0.0f) { return false; }
if (!item.Prefab.DamagedByProjectiles) { return false; }
if (!item.Prefab.DamagedByProjectiles)
{
if (item.GetComponent<Door>() == null)
{
return false;
}
}
}
else if (target.Body.UserData is Holdable { CanPush: false })
{
@@ -85,15 +85,6 @@ namespace Barotrauma.Steam
return Steamworks.SteamUGC.NumSubscribedItems;
}
public static PublishedFileId[] GetSubscribedItems()
{
if (!IsInitialized || !Steamworks.SteamClient.IsValid)
{
return Array.Empty<PublishedFileId>();
}
return Steamworks.SteamUGC.GetSubscribedItems();
}
public static bool UnlockAchievement(string achievementIdentifier) =>
UnlockAchievement(achievementIdentifier.ToIdentifier());
@@ -1,26 +1,20 @@
#nullable enable
using Barotrauma.IO;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Barotrauma.Extensions;
using Steamworks.Data;
using WorkshopItemSet = System.Collections.Generic.ISet<Steamworks.Ugc.Item>;
namespace Barotrauma.Steam
{
static partial class SteamManager
{
public const string WorkshopItemPreviewImageFolder = "Workshop";
public const string PreviewImageName = "PreviewImage.png";
public const string DefaultPreviewImagePath = "Content/DefaultWorkshopPreviewImage.png";
public static bool TryExtractSteamWorkshopId(this ContentPackage contentPackage, [NotNullWhen(true)]out SteamWorkshopId? workshopId)
{
workshopId = null;
@@ -47,16 +41,22 @@ namespace Barotrauma.Steam
private static async Task<WorkshopItemSet> GetWorkshopItems(Steamworks.Ugc.Query query, int? maxPages = null)
{
if (!IsInitialized) { return new HashSet<Steamworks.Ugc.Item>(); }
await Task.Yield();
query = query.WithKeyValueTags(true).WithLongDescription(true);
var set = new HashSet<Steamworks.Ugc.Item>(ItemEqualityComparer.Instance);
int prevSize = 0;
for (int i = 1; maxPages is null || i <= maxPages; i++)
for (int i = 1; i <= (maxPages ?? int.MaxValue); i++)
{
Steamworks.Ugc.ResultPage? page = await query.GetPageAsync(i);
if (page is null || !page.Value.Entries.Any()) { break; }
set.UnionWith(page.Value.Entries);
if (page is not { Entries: var entries }) { break; }
// This queries the results on the i-th page and stores them,
// using page.Entries directly would result in two GetQueryUGCResult calls
entries = entries.ToArray();
if (entries.None()) { break; }
set.UnionWith(entries);
if (set.Count == prevSize) { break; }
prevSize = set.Count;
@@ -66,10 +66,17 @@ namespace Barotrauma.Steam
// which can happen on items that are not visible to the currently
// logged in player (i.e. private & friends-only items)
set.RemoveWhere(it => it.ConsumerApp != AppID);
return set;
}
public static ImmutableHashSet<Steamworks.Data.PublishedFileId> GetSubscribedItemIds()
{
return IsInitialized
? Steamworks.SteamUGC.GetSubscribedItems().ToImmutableHashSet()
: ImmutableHashSet<Steamworks.Data.PublishedFileId>.Empty;
}
public static async Task<WorkshopItemSet> GetAllSubscribedItems()
{
if (!IsInitialized) { return new HashSet<Steamworks.Ugc.Item>(); }
@@ -98,14 +105,86 @@ namespace Barotrauma.Steam
.WhereUserPublished());
}
public static async Task<Steamworks.Ugc.Item?> GetItem(UInt64 itemId)
private static class SingleItemRequestPool
{
private static readonly object mutex = new();
private static readonly TimeSpan delayAfterNewRequest = TimeSpan.FromSeconds(0.5);
private static readonly HashSet<UInt64> ids = new();
private static Task<WorkshopItemSet>? currentBatch = null;
private static async Task<WorkshopItemSet> PrepareNewBatch()
{
// Wait for a bunch of requests to be made
await Task.Delay(delayAfterNewRequest);
Task<WorkshopItemSet> queryTask;
lock (mutex)
{
DebugConsole.Log(
$"{nameof(SteamManager)}.{nameof(Workshop)}.{nameof(SingleItemRequestPool)}: " +
$"Running batch of {ids.Count} requests");
queryTask = GetWorkshopItems(
Steamworks.Ugc.Query.All
.WithFileId(
ids
.Select(id => (Steamworks.Data.PublishedFileId)id)
.ToArray()));
ids.Clear();
// Immediately clear the current batch so the next request starts a new one
currentBatch = null;
}
return await queryTask;
}
public static async Task<Steamworks.Ugc.Item?> MakeRequest(UInt64 id)
{
Task<WorkshopItemSet> ourTask;
lock (mutex)
{
ids.Add(id);
if (currentBatch is not { IsCompleted: false })
{
// There is no currently pending batch, start a new one
currentBatch = Task.Run(PrepareNewBatch);
}
ourTask = currentBatch;
}
var items = await ourTask;
var result = items.FirstOrNull(it => it.Id == id);
return result;
}
}
/// <summary>
/// Fetches a Workshop item's metadata. This is batched to minimize Steamworks API calls.
/// The description of the returned item is truncated to save bandwidth.
/// </summary>
/// <param name="itemId">Workshop Item ID</param>
public static Task<Steamworks.Ugc.Item?> GetItem(UInt64 itemId)
=> SingleItemRequestPool.MakeRequest(itemId);
/// <summary>
/// Fetches a Workshop item's metadata in its own API call instead of batching.
/// This minimizes delay but needs to be used with caution to prevent rate limiting.
/// </summary>
/// <param name="itemId">Workshop Item ID</param>
/// <param name="withLongDescription">
/// If true, ask for the item's entire description, otherwise it'll be truncated.
/// </param>
public static async Task<Steamworks.Ugc.Item?> GetItemAsap(UInt64 itemId, bool withLongDescription = false)
{
if (!IsInitialized) { return null; }
var items = await GetWorkshopItems(
Steamworks.Ugc.Query.All
.WithFileId(itemId));
return items.Any() ? items.First() : (Steamworks.Ugc.Item?)null;
.WithFileId(itemId)
.WithLongDescription(withLongDescription));
return items.Any() ? items.First() : null;
}
public static async Task ForceRedownload(UInt64 itemId)
@@ -11,10 +11,10 @@ namespace Barotrauma
public abstract bool IsSuccess { get; }
public bool IsFailure => !IsSuccess;
public static Success<T, TError> Success(T value)
public static Result<T, TError> Success(T value)
=> new Success<T, TError>(value);
public static Failure<T, TError> Failure(TError error)
public static Result<T, TError> Failure(TError error)
=> new Failure<T, TError>(error);
public abstract bool TryUnwrapSuccess([MaybeNullWhen(returnValue: false)] out T value);