Add moon boots (#29009)

This commit is contained in:
Nemanja
2024-06-14 23:43:23 -04:00
committed by GitHub
parent 06c8238164
commit 748e5831e8
23 changed files with 211 additions and 124 deletions

View File

@@ -1,8 +0,0 @@
using Content.Shared.Clothing;
namespace Content.Client.Clothing;
public sealed class MagbootsSystem : SharedMagbootsSystem
{
}

View File

@@ -1,31 +0,0 @@
namespace Content.Server.Atmos.Components
{
// Unfortunately can't be friends yet due to magboots.
[RegisterComponent]
public sealed partial class MovedByPressureComponent : Component
{
public const float MoveForcePushRatio = 1f;
public const float MoveForceForcePushRatio = 1f;
public const float ProbabilityOffset = 25f;
public const float ProbabilityBasePercent = 10f;
public const float ThrowForce = 100f;
/// <summary>
/// Accumulates time when yeeted by high pressure deltas.
/// </summary>
[DataField("accumulator")]
public float Accumulator = 0f;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("enabled")]
public bool Enabled { get; set; } = true;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("pressureResistance")]
public float PressureResistance { get; set; } = 1f;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("moveResist")]
public float MoveResist { get; set; } = 100f;
[ViewVariables(VVAccess.ReadWrite)]
public int LastHighPressureMovementAirCycle { get; set; } = 0;
}
}

View File

@@ -1,5 +1,6 @@
using Content.Server.Atmos.Components; using Content.Server.Atmos.Components;
using Content.Shared.Atmos; using Content.Shared.Atmos;
using Content.Shared.Atmos.Components;
using Content.Shared.Mobs.Components; using Content.Shared.Mobs.Components;
using Content.Shared.Physics; using Content.Shared.Physics;
using Robust.Shared.Audio; using Robust.Shared.Audio;

View File

@@ -1,49 +0,0 @@
using Content.Server.Atmos.Components;
using Content.Shared.Alert;
using Content.Shared.Clothing;
namespace Content.Server.Clothing;
public sealed class MagbootsSystem : SharedMagbootsSystem
{
[Dependency] private readonly AlertsSystem _alerts = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<MagbootsComponent, ClothingGotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<MagbootsComponent, ClothingGotUnequippedEvent>(OnGotUnequipped);
}
protected override void UpdateMagbootEffects(EntityUid parent, EntityUid uid, bool state, MagbootsComponent? component)
{
if (!Resolve(uid, ref component))
return;
state = state && component.On;
if (TryComp(parent, out MovedByPressureComponent? movedByPressure))
{
movedByPressure.Enabled = !state;
}
if (state)
{
_alerts.ShowAlert(parent, component.MagbootsAlert);
}
else
{
_alerts.ClearAlert(parent, component.MagbootsAlert);
}
}
private void OnGotUnequipped(EntityUid uid, MagbootsComponent component, ref ClothingGotUnequippedEvent args)
{
UpdateMagbootEffects(args.Wearer, uid, false, component);
}
private void OnGotEquipped(EntityUid uid, MagbootsComponent component, ref ClothingGotEquippedEvent args)
{
UpdateMagbootEffects(args.Wearer, uid, true, component);
}
}

View File

@@ -1,4 +1,4 @@
using Content.Server.Atmos.Components; using Content.Shared.Atmos.Components;
using Content.Shared.Damage.Components; using Content.Shared.Damage.Components;
using Content.Shared.Damage.Systems; using Content.Shared.Damage.Systems;

View File

@@ -1,7 +1,6 @@
using Content.Shared.Gravity; using Content.Shared.Gravity;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.Map.Components; using Robust.Shared.Map.Components;
using Robust.Shared.Utility;
namespace Content.Server.Gravity namespace Content.Server.Gravity
{ {

View File

@@ -1,6 +1,6 @@
using System.Numerics; using System.Numerics;
using Content.Server.Atmos.Components;
using Content.Server.Singularity.Components; using Content.Server.Singularity.Components;
using Content.Shared.Atmos.Components;
using Content.Shared.Ghost; using Content.Shared.Ghost;
using Content.Shared.Singularity.EntitySystems; using Content.Shared.Singularity.EntitySystems;
using Robust.Shared.Map; using Robust.Shared.Map;

View File

@@ -0,0 +1,31 @@
namespace Content.Shared.Atmos.Components;
// Unfortunately can't be friends yet due to magboots.
[RegisterComponent]
public sealed partial class MovedByPressureComponent : Component
{
public const float MoveForcePushRatio = 1f;
public const float MoveForceForcePushRatio = 1f;
public const float ProbabilityOffset = 25f;
public const float ProbabilityBasePercent = 10f;
public const float ThrowForce = 100f;
/// <summary>
/// Accumulates time when yeeted by high pressure deltas.
/// </summary>
[DataField]
public float Accumulator;
[DataField]
public bool Enabled { get; set; } = true;
[DataField]
public float PressureResistance { get; set; } = 1f;
[DataField]
public float MoveResist { get; set; } = 100f;
[ViewVariables(VVAccess.ReadWrite)]
public int LastHighPressureMovementAirCycle { get; set; } = 0;
}

View File

@@ -0,0 +1,9 @@
using Robust.Shared.GameStates;
namespace Content.Shared.Clothing.Components;
/// <summary>
/// This is used for clothing that makes an entity weightless when worn.
/// </summary>
[RegisterComponent, NetworkedComponent]
public sealed partial class AntiGravityClothingComponent : Component;

View File

@@ -0,0 +1,23 @@
using Content.Shared.Clothing.Components;
using Content.Shared.Gravity;
using Content.Shared.Inventory;
namespace Content.Shared.Clothing.EntitySystems;
public sealed class AntiGravityClothingSystem : EntitySystem
{
/// <inheritdoc/>
public override void Initialize()
{
SubscribeLocalEvent<AntiGravityClothingComponent, InventoryRelayedEvent<IsWeightlessEvent>>(OnIsWeightless);
}
private void OnIsWeightless(Entity<AntiGravityClothingComponent> ent, ref InventoryRelayedEvent<IsWeightlessEvent> args)
{
if (args.Args.Handled)
return;
args.Args.Handled = true;
args.Args.IsWeightless = true;
}
}

View File

@@ -1,5 +1,8 @@
using Content.Shared.Actions; using Content.Shared.Actions;
using Content.Shared.Alert;
using Content.Shared.Atmos.Components;
using Content.Shared.Clothing.EntitySystems; using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Gravity;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Item; using Content.Shared.Item;
using Content.Shared.Slippery; using Content.Shared.Slippery;
@@ -9,8 +12,9 @@ using Robust.Shared.Containers;
namespace Content.Shared.Clothing; namespace Content.Shared.Clothing;
public abstract class SharedMagbootsSystem : EntitySystem public sealed class SharedMagbootsSystem : EntitySystem
{ {
[Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly ClothingSpeedModifierSystem _clothingSpeedModifier = default!; [Dependency] private readonly ClothingSpeedModifierSystem _clothingSpeedModifier = default!;
[Dependency] private readonly ClothingSystem _clothing = default!; [Dependency] private readonly ClothingSystem _clothing = default!;
[Dependency] private readonly InventorySystem _inventory = default!; [Dependency] private readonly InventorySystem _inventory = default!;
@@ -29,6 +33,11 @@ public abstract class SharedMagbootsSystem : EntitySystem
SubscribeLocalEvent<MagbootsComponent, GetItemActionsEvent>(OnGetActions); SubscribeLocalEvent<MagbootsComponent, GetItemActionsEvent>(OnGetActions);
SubscribeLocalEvent<MagbootsComponent, ToggleMagbootsEvent>(OnToggleMagboots); SubscribeLocalEvent<MagbootsComponent, ToggleMagbootsEvent>(OnToggleMagboots);
SubscribeLocalEvent<MagbootsComponent, MapInitEvent>(OnMapInit); SubscribeLocalEvent<MagbootsComponent, MapInitEvent>(OnMapInit);
SubscribeLocalEvent<MagbootsComponent, ClothingGotEquippedEvent>(OnGotEquipped);
SubscribeLocalEvent<MagbootsComponent, ClothingGotUnequippedEvent>(OnGotUnequipped);
SubscribeLocalEvent<MagbootsComponent, InventoryRelayedEvent<IsWeightlessEvent>>(OnIsWeightless);
} }
private void OnMapInit(EntityUid uid, MagbootsComponent component, MapInitEvent args) private void OnMapInit(EntityUid uid, MagbootsComponent component, MapInitEvent args)
@@ -37,6 +46,16 @@ public abstract class SharedMagbootsSystem : EntitySystem
Dirty(uid, component); Dirty(uid, component);
} }
private void OnGotUnequipped(EntityUid uid, MagbootsComponent component, ref ClothingGotUnequippedEvent args)
{
UpdateMagbootEffects(args.Wearer, uid, false, component);
}
private void OnGotEquipped(EntityUid uid, MagbootsComponent component, ref ClothingGotEquippedEvent args)
{
UpdateMagbootEffects(args.Wearer, uid, true, component);
}
private void OnToggleMagboots(EntityUid uid, MagbootsComponent component, ToggleMagbootsEvent args) private void OnToggleMagboots(EntityUid uid, MagbootsComponent component, ToggleMagbootsEvent args)
{ {
if (args.Handled) if (args.Handled)
@@ -51,9 +70,11 @@ public abstract class SharedMagbootsSystem : EntitySystem
{ {
magboots.On = !magboots.On; magboots.On = !magboots.On;
if (_sharedContainer.TryGetContainingContainer(uid, out var container) && if (_sharedContainer.TryGetContainingContainer((uid, Transform(uid)), out var container) &&
_inventory.TryGetSlotEntity(container.Owner, "shoes", out var entityUid) && entityUid == uid) _inventory.TryGetSlotEntity(container.Owner, "shoes", out var entityUid) && entityUid == uid)
{
UpdateMagbootEffects(container.Owner, uid, true, magboots); UpdateMagbootEffects(container.Owner, uid, true, magboots);
}
if (TryComp<ItemComponent>(uid, out var item)) if (TryComp<ItemComponent>(uid, out var item))
{ {
@@ -66,9 +87,28 @@ public abstract class SharedMagbootsSystem : EntitySystem
Dirty(uid, magboots); Dirty(uid, magboots);
} }
protected virtual void UpdateMagbootEffects(EntityUid parent, EntityUid uid, bool state, MagbootsComponent? component) { } public void UpdateMagbootEffects(EntityUid parent, EntityUid uid, bool state, MagbootsComponent? component)
{
if (!Resolve(uid, ref component))
return;
state = state && component.On;
protected void OnChanged(EntityUid uid, MagbootsComponent component) if (TryComp(parent, out MovedByPressureComponent? movedByPressure))
{
movedByPressure.Enabled = !state;
}
if (state)
{
_alerts.ShowAlert(parent, component.MagbootsAlert);
}
else
{
_alerts.ClearAlert(parent, component.MagbootsAlert);
}
}
private void OnChanged(EntityUid uid, MagbootsComponent component)
{ {
_sharedActions.SetToggled(component.ToggleActionEntity, component.On); _sharedActions.SetToggled(component.ToggleActionEntity, component.On);
_clothingSpeedModifier.SetClothingSpeedModifierEnabled(uid, component.On); _clothingSpeedModifier.SetClothingSpeedModifierEnabled(uid, component.On);
@@ -79,10 +119,12 @@ public abstract class SharedMagbootsSystem : EntitySystem
if (!args.CanAccess || !args.CanInteract) if (!args.CanAccess || !args.CanInteract)
return; return;
ActivationVerb verb = new(); ActivationVerb verb = new()
verb.Text = Loc.GetString("toggle-magboots-verb-get-data-text"); {
verb.Act = () => ToggleMagboots(uid, component); Text = Loc.GetString("toggle-magboots-verb-get-data-text"),
Act = () => ToggleMagboots(uid, component),
// TODO VERB ICON add toggle icon? maybe a computer on/off symbol? // TODO VERB ICON add toggle icon? maybe a computer on/off symbol?
};
args.Verbs.Add(verb); args.Verbs.Add(verb);
} }
@@ -96,6 +138,18 @@ public abstract class SharedMagbootsSystem : EntitySystem
{ {
args.AddAction(ref component.ToggleActionEntity, component.ToggleAction); args.AddAction(ref component.ToggleActionEntity, component.ToggleAction);
} }
private void OnIsWeightless(Entity<MagbootsComponent> ent, ref InventoryRelayedEvent<IsWeightlessEvent> args)
{
if (args.Args.Handled)
return;
if (!ent.Comp.On)
return;
args.Args.IsWeightless = false;
args.Args.Handled = true;
}
} }
public sealed partial class ToggleMagbootsEvent : InstantActionEvent {} public sealed partial class ToggleMagbootsEvent : InstantActionEvent;

View File

@@ -1,9 +1,7 @@
using Content.Shared.Alert; using Content.Shared.Alert;
using Content.Shared.Clothing;
using Content.Shared.Inventory; using Content.Shared.Inventory;
using Content.Shared.Movement.Components; using Content.Shared.Movement.Components;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -15,7 +13,6 @@ namespace Content.Shared.Gravity
{ {
[Dependency] protected readonly IGameTiming Timing = default!; [Dependency] protected readonly IGameTiming Timing = default!;
[Dependency] private readonly AlertsSystem _alerts = default!; [Dependency] private readonly AlertsSystem _alerts = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[ValidatePrototypeId<AlertPrototype>] [ValidatePrototypeId<AlertPrototype>]
public const string WeightlessAlert = "Weightless"; public const string WeightlessAlert = "Weightless";
@@ -30,6 +27,11 @@ namespace Content.Shared.Gravity
if (TryComp<MovementIgnoreGravityComponent>(uid, out var ignoreGravityComponent)) if (TryComp<MovementIgnoreGravityComponent>(uid, out var ignoreGravityComponent))
return ignoreGravityComponent.Weightless; return ignoreGravityComponent.Weightless;
var ev = new IsWeightlessEvent(uid);
RaiseLocalEvent(uid, ref ev);
if (ev.Handled)
return ev.IsWeightless;
if (!Resolve(uid, ref xform)) if (!Resolve(uid, ref xform))
return true; return true;
@@ -40,18 +42,6 @@ namespace Content.Shared.Gravity
return false; return false;
} }
var hasGrav = gravity != null || mapGravity != null;
// Check for something holding us down
// If the planet has gravity component and no gravity it will still give gravity
// If there's no gravity comp at all (i.e. space) then they don't work.
if (hasGrav && _inventory.TryGetSlotEntity(uid, "shoes", out var ent))
{
// TODO this should just be a event that gets relayed instead of a specific slot & component check.
if (TryComp<MagbootsComponent>(ent, out var boots) && boots.On)
return false;
}
return true; return true;
} }
@@ -74,9 +64,11 @@ namespace Content.Shared.Gravity
private void OnHandleState(EntityUid uid, GravityComponent component, ref ComponentHandleState args) private void OnHandleState(EntityUid uid, GravityComponent component, ref ComponentHandleState args)
{ {
if (args.Current is not GravityComponentState state) return; if (args.Current is not GravityComponentState state)
return;
if (component.EnabledVV == state.Enabled) return; if (component.EnabledVV == state.Enabled)
return;
component.EnabledVV = state.Enabled; component.EnabledVV = state.Enabled;
var ev = new GravityChangedEvent(uid, component.EnabledVV); var ev = new GravityChangedEvent(uid, component.EnabledVV);
RaiseLocalEvent(uid, ref ev, true); RaiseLocalEvent(uid, ref ev, true);
@@ -90,9 +82,10 @@ namespace Content.Shared.Gravity
private void OnGravityChange(ref GravityChangedEvent ev) private void OnGravityChange(ref GravityChangedEvent ev)
{ {
var alerts = AllEntityQuery<AlertsComponent, TransformComponent>(); var alerts = AllEntityQuery<AlertsComponent, TransformComponent>();
while(alerts.MoveNext(out var uid, out var comp, out var xform)) while(alerts.MoveNext(out var uid, out _, out var xform))
{ {
if (xform.GridUid != ev.ChangedGridIndex) continue; if (xform.GridUid != ev.ChangedGridIndex)
continue;
if (!ev.HasGravity) if (!ev.HasGravity)
{ {
@@ -145,4 +138,10 @@ namespace Content.Shared.Gravity
} }
} }
} }
[ByRefEvent]
public record struct IsWeightlessEvent(EntityUid Entity, bool IsWeightless = false, bool Handled = false) : IInventoryRelayEvent
{
SlotFlags IInventoryRelayEvent.TargetSlots => ~SlotFlags.POCKET;
}
} }

View File

@@ -3,6 +3,7 @@ using Content.Shared.Damage;
using Content.Shared.Electrocution; using Content.Shared.Electrocution;
using Content.Shared.Explosion; using Content.Shared.Explosion;
using Content.Shared.Eye.Blinding.Systems; using Content.Shared.Eye.Blinding.Systems;
using Content.Shared.Gravity;
using Content.Shared.IdentityManagement.Components; using Content.Shared.IdentityManagement.Components;
using Content.Shared.Inventory.Events; using Content.Shared.Inventory.Events;
using Content.Shared.Movement.Systems; using Content.Shared.Movement.Systems;
@@ -30,6 +31,7 @@ public partial class InventorySystem
// by-ref events // by-ref events
SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, GetExplosionResistanceEvent>(RefRelayInventoryEvent);
SubscribeLocalEvent<InventoryComponent, IsWeightlessEvent>(RefRelayInventoryEvent);
// Eye/vision events // Eye/vision events
SubscribeLocalEvent<InventoryComponent, CanSeeAttemptEvent>(RelayInventoryEvent); SubscribeLocalEvent<InventoryComponent, CanSeeAttemptEvent>(RelayInventoryEvent);

View File

@@ -134,3 +134,21 @@
event: !type:ToggleClothingSpeedEvent event: !type:ToggleClothingSpeedEvent
icon: { sprite: Clothing/Shoes/Boots/speedboots.rsi, state: icon } icon: { sprite: Clothing/Shoes/Boots/speedboots.rsi, state: icon }
iconOn: { sprite: Clothing/Shoes/Boots/speedboots.rsi, state: icon-on } iconOn: { sprite: Clothing/Shoes/Boots/speedboots.rsi, state: icon-on }
- type: entity
parent: ClothingShoesBase
id: ClothingShoesBootsMoon
name: moon boots
description: Special anti-gravity boots developed with a speciality blend of lunar rock gel. Shipped from the Netherlands.
components:
- type: Sprite
sprite: Clothing/Shoes/Boots/moonboots.rsi
layers:
- state: icon
- type: Clothing
sprite: Clothing/Shoes/Boots/moonboots.rsi
- type: AntiGravityClothing
- type: StaticPrice
price: 75
- type: Tag
tags: [ ]

View File

@@ -308,6 +308,7 @@
- WeaponGauntletGorilla - WeaponGauntletGorilla
- SynthesizerInstrument - SynthesizerInstrument
- ClothingShoesBootsMagSci - ClothingShoesBootsMagSci
- ClothingShoesBootsMoon
- ClothingShoesBootsSpeed - ClothingShoesBootsSpeed
- NodeScanner - NodeScanner
- HolofanProjector - HolofanProjector

View File

@@ -126,6 +126,13 @@
Steel: 1000 Steel: 1000
Plastic: 500 Plastic: 500
- type: latheRecipe
id: ClothingShoesBootsMoon
result: ClothingShoesBootsMoon
completetime: 2
materials:
Steel: 600
- type: latheRecipe - type: latheRecipe
id: ClothingShoesBootsSpeed id: ClothingShoesBootsSpeed
result: ClothingShoesBootsSpeed result: ClothingShoesBootsSpeed

View File

@@ -68,6 +68,7 @@
cost: 7500 cost: 7500
recipeUnlocks: recipeUnlocks:
- ClothingShoesBootsMagSci - ClothingShoesBootsMagSci
- ClothingShoesBootsMoon
- type: technology - type: technology
id: AnomalyCoreHarnessing id: AnomalyCoreHarnessing

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

View File

@@ -0,0 +1,30 @@
{
"version": 1,
"license": "CC-BY-SA-3.0",
"copyright": "Taken from Tau Ceti Station at commit https://github.com/TauCetiStation/TauCetiClassic/blob/HEAD/icons/obj/clothing/shoes.dmi",
"size": {
"x": 32,
"y": 32
},
"states": [
{
"name": "icon"
},
{
"name": "equipped-FEET",
"directions": 4
},
{
"name": "equipped-FEET-vox",
"directions": 4
},
{
"name": "inhand-left",
"directions": 4
},
{
"name": "inhand-right",
"directions": 4
}
]
}