Build 0.20.16.1
This commit is contained in:
+5
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user