Merge remote-tracking branch 'space-station-14/master'

This commit is contained in:
Ed
2024-04-13 18:59:09 +03:00
74 changed files with 1038 additions and 503 deletions

View File

@@ -301,7 +301,9 @@ public sealed class PullingSystem : EntitySystem
return false;
}
if (pullerComp.NeedsHands && !_handsSystem.TryGetEmptyHand(puller, out _))
if (pullerComp.NeedsHands
&& !_handsSystem.TryGetEmptyHand(puller, out _)
&& pullerComp.Pulling == null)
{
return false;
}
@@ -365,7 +367,7 @@ public sealed class PullingSystem : EntitySystem
return TogglePull(puller.Pulling.Value, pullerUid, pullable);
}
public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid, EntityUid? user = null,
public bool TryStartPull(EntityUid pullerUid, EntityUid pullableUid,
PullerComponent? pullerComp = null, PullableComponent? pullableComp = null)
{
if (!Resolve(pullerUid, ref pullerComp, false) ||
@@ -387,23 +389,18 @@ public sealed class PullingSystem : EntitySystem
}
// Ensure that the puller is not currently pulling anything.
var oldPullable = pullerComp.Pulling;
if (TryComp<PullableComponent>(pullerComp.Pulling, out var oldPullable)
&& !TryStopPull(pullerComp.Pulling.Value, oldPullable, pullerUid))
return false;
if (oldPullable != null)
{
// Well couldn't stop the old one.
if (!TryStopPull(oldPullable.Value, pullableComp, user))
return false;
}
// Is the pullable currently being pulled by something else?
// Stop anyone else pulling the entity we want to pull
if (pullableComp.Puller != null)
{
// Uhhh
// We're already pulling this item
if (pullableComp.Puller == pullerUid)
return false;
if (!TryStopPull(pullableUid, pullableComp, pullerUid))
if (!TryStopPull(pullableUid, pullableComp, pullableComp.Puller))
return false;
}
@@ -469,7 +466,7 @@ public sealed class PullingSystem : EntitySystem
var pullerUidNull = pullable.Puller;
if (pullerUidNull == null)
return false;
return true;
var msg = new AttemptStopPullingEvent(user);
RaiseLocalEvent(pullableUid, msg, true);

View File

@@ -31,7 +31,7 @@ namespace Content.Shared.Plants
if (args.Handled)
return;
Rustle(uid, component);
Rustle(uid, component, args.User);
args.Handled = _stashSystem.TryHideItem(uid, args.User, args.Used);
}
@@ -40,24 +40,24 @@ namespace Content.Shared.Plants
if (args.Handled)
return;
Rustle(uid, component);
Rustle(uid, component, args.User);
var gotItem = _stashSystem.TryGetItem(uid, args.User);
if (!gotItem)
{
var msg = Loc.GetString("potted-plant-hide-component-interact-hand-got-no-item-message");
_popupSystem.PopupEntity(msg, uid, args.User);
_popupSystem.PopupClient(msg, uid, args.User);
}
args.Handled = gotItem;
}
private void Rustle(EntityUid uid, PottedPlantHideComponent? component = null)
private void Rustle(EntityUid uid, PottedPlantHideComponent? component = null, EntityUid? user = null)
{
if (!Resolve(uid, ref component))
return;
_audio.PlayPvs(component.RustleSound, uid, AudioParams.Default.WithVariation(0.25f));
_audio.PlayPredicted(component.RustleSound, uid, user, AudioParams.Default.WithVariation(0.25f));
}
}
}

View File

@@ -175,7 +175,7 @@ public class RCDSystem : EntitySystem
else
{
var deconstructedTile = _mapSystem.GetTileRef(mapGridData.Value.GridUid, mapGridData.Value.Component, mapGridData.Value.Location);
var protoName = deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
var protoName = !deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
if (_protoManager.TryIndex(protoName, out var deconProto))
{

View File

@@ -11,15 +11,14 @@ public static class ListingLocalisationHelpers
/// </summary>
public static string GetLocalisedNameOrEntityName(ListingData listingData, IPrototypeManager prototypeManager)
{
bool wasLocalised = Loc.TryGetString(listingData.Name, out string? listingName);
var name = string.Empty;
if (!wasLocalised && listingData.ProductEntity != null)
{
var proto = prototypeManager.Index<EntityPrototype>(listingData.ProductEntity);
listingName = proto.Name;
}
if (listingData.Name != null)
name = Loc.GetString(listingData.Name);
else if (listingData.ProductEntity != null)
name = prototypeManager.Index(listingData.ProductEntity.Value).Name;
return listingName ?? listingData.Name;
return name;
}
/// <summary>
@@ -29,14 +28,13 @@ public static class ListingLocalisationHelpers
/// </summary>
public static string GetLocalisedDescriptionOrEntityDescription(ListingData listingData, IPrototypeManager prototypeManager)
{
bool wasLocalised = Loc.TryGetString(listingData.Description, out string? listingDesc);
var desc = string.Empty;
if (!wasLocalised && listingData.ProductEntity != null)
{
var proto = prototypeManager.Index<EntityPrototype>(listingData.ProductEntity);
listingDesc = proto.Description;
}
if (listingData.Description != null)
desc = Loc.GetString(listingData.Description);
else if (listingData.ProductEntity != null)
desc = prototypeManager.Index(listingData.ProductEntity.Value).Description;
return listingDesc ?? listingData.Description;
return desc;
}
}

View File

@@ -2,10 +2,6 @@ using System.Linq;
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Dictionary;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.List;
using Robust.Shared.Utility;
namespace Content.Shared.Store;
@@ -26,57 +22,57 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
/// <summary>
/// The name of the listing. If empty, uses the entity's name (if present)
/// </summary>
[DataField("name")]
public string Name = string.Empty;
[DataField]
public string? Name;
/// <summary>
/// The description of the listing. If empty, uses the entity's description (if present)
/// </summary>
[DataField("description")]
public string Description = string.Empty;
[DataField]
public string? Description;
/// <summary>
/// The categories that this listing applies to. Used for filtering a listing for a store.
/// </summary>
[DataField("categories", required: true, customTypeSerializer: typeof(PrototypeIdListSerializer<StoreCategoryPrototype>))]
public List<string> Categories = new();
[DataField]
public List<ProtoId<StoreCategoryPrototype>> Categories = new();
/// <summary>
/// The cost of the listing. String represents the currency type while the FixedPoint2 represents the amount of that currency.
/// </summary>
[DataField("cost", customTypeSerializer: typeof(PrototypeIdDictionarySerializer<FixedPoint2, CurrencyPrototype>))]
public Dictionary<string, FixedPoint2> Cost = new();
[DataField]
public Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> Cost = new();
/// <summary>
/// Specific customizeable conditions that determine whether or not the listing can be purchased.
/// Specific customizable conditions that determine whether or not the listing can be purchased.
/// </summary>
[NonSerialized]
[DataField("conditions", serverOnly: true)]
[DataField(serverOnly: true)]
public List<ListingCondition>? Conditions;
/// <summary>
/// The icon for the listing. If null, uses the icon for the entity or action.
/// </summary>
[DataField("icon")]
[DataField]
public SpriteSpecifier? Icon;
/// <summary>
/// The priority for what order the listings will show up in on the menu.
/// </summary>
[DataField("priority")]
public int Priority = 0;
[DataField]
public int Priority;
/// <summary>
/// The entity that is given when the listing is purchased.
/// </summary>
[DataField("productEntity", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? ProductEntity;
[DataField]
public EntProtoId? ProductEntity;
/// <summary>
/// The action that is given when the listing is purchased.
/// </summary>
[DataField("productAction", customTypeSerializer: typeof(PrototypeIdSerializer<EntityPrototype>))]
public string? ProductAction;
[DataField]
public EntProtoId? ProductAction;
/// <summary>
/// The listing ID of the related upgrade listing. Can be used to link a <see cref="ProductAction"/> to an
@@ -95,7 +91,7 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
/// <summary>
/// The event that is broadcast when the listing is purchased.
/// </summary>
[DataField("productEvent")]
[DataField]
public object? ProductEvent;
[DataField]
@@ -104,13 +100,14 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
/// <summary>
/// used internally for tracking how many times an item was purchased.
/// </summary>
public int PurchaseAmount = 0;
[DataField]
public int PurchaseAmount;
/// <summary>
/// Used to delay purchase of some items.
/// </summary>
[DataField("restockTime")]
public int RestockTime;
[DataField]
public TimeSpan RestockTime = TimeSpan.Zero;
public bool Equals(ListingData? listing)
{
@@ -173,14 +170,10 @@ public partial class ListingData : IEquatable<ListingData>, ICloneable
}
}
//<inheritdoc>
/// <summary>
/// Defines a set item listing that is available in a store
/// </summary>
[Prototype("listing")]
[Serializable, NetSerializable]
[DataDefinition]
public sealed partial class ListingPrototype : ListingData, IPrototype
{
}
public sealed partial class ListingPrototype : ListingData, IPrototype;

View File

@@ -1,4 +1,5 @@
using Content.Shared.FixedPoint;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization;
namespace Content.Shared.Store;
@@ -14,13 +15,13 @@ public sealed class StoreUpdateState : BoundUserInterfaceState
{
public readonly HashSet<ListingData> Listings;
public readonly Dictionary<string, FixedPoint2> Balance;
public readonly Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> Balance;
public readonly bool ShowFooter;
public readonly bool AllowRefund;
public StoreUpdateState(HashSet<ListingData> listings, Dictionary<string, FixedPoint2> balance, bool showFooter, bool allowRefund)
public StoreUpdateState(HashSet<ListingData> listings, Dictionary<ProtoId<CurrencyPrototype>, FixedPoint2> balance, bool showFooter, bool allowRefund)
{
Listings = listings;
Balance = balance;
@@ -46,9 +47,7 @@ public sealed class StoreInitializeState : BoundUserInterfaceState
[Serializable, NetSerializable]
public sealed class StoreRequestUpdateInterfaceMessage : BoundUserInterfaceMessage
{
public StoreRequestUpdateInterfaceMessage()
{
}
}
[Serializable, NetSerializable]

View File

@@ -43,7 +43,8 @@ public abstract class SharedStrippableSystem : EntitySystem
args.Handled = true;
args.CanDrop |= uid == args.User &&
HasComp<StrippableComponent>(args.Dragged) &&
HasComp<HandsComponent>(args.User);
HasComp<HandsComponent>(args.User) &&
HasComp<StrippingComponent>(args.User);
}
private void OnCanDrop(EntityUid uid, StrippableComponent component, ref CanDropDraggedEvent args)

View File

@@ -34,7 +34,7 @@ public sealed class WieldableSystem : EntitySystem
{
base.Initialize();
SubscribeLocalEvent<WieldableComponent, UseInHandEvent>(OnUseInHand);
SubscribeLocalEvent<WieldableComponent, UseInHandEvent>(OnUseInHand, before: [typeof(SharedGunSystem)]);
SubscribeLocalEvent<WieldableComponent, ItemUnwieldedEvent>(OnItemUnwielded);
SubscribeLocalEvent<WieldableComponent, GotUnequippedHandEvent>(OnItemLeaveHand);
SubscribeLocalEvent<WieldableComponent, VirtualItemDeletedEvent>(OnVirtualItemDeleted);