Adds IThrowCollide, Creaming people with cream pies and tactical stun baton throws (#2122)
@@ -0,0 +1,33 @@
|
||||
using Content.Shared.GameObjects.Components.Nutrition;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Interfaces.GameObjects.Components;
|
||||
|
||||
namespace Content.Client.GameObjects.Components.Nutrition
|
||||
{
|
||||
[UsedImplicitly]
|
||||
public class CreamPiedVisualizer : AppearanceVisualizer
|
||||
{
|
||||
public override void OnChangeData(AppearanceComponent component)
|
||||
{
|
||||
base.OnChangeData(component);
|
||||
|
||||
if (component.TryGetData<bool>(CreamPiedVisuals.Creamed, out var pied))
|
||||
{
|
||||
SetPied(component, pied);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPied(AppearanceComponent component, bool pied)
|
||||
{
|
||||
var sprite = component.Owner.GetComponent<ISpriteComponent>();
|
||||
|
||||
sprite.LayerSetVisible(CreamPiedVisualLayers.Pie, pied);
|
||||
}
|
||||
}
|
||||
|
||||
public enum CreamPiedVisualLayers
|
||||
{
|
||||
Pie,
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Content.Server.GameObjects.Components.Fluids
|
||||
{
|
||||
[RegisterComponent]
|
||||
class SprayComponent : SharedSprayComponent, IAfterInteract, IUse, IActivate
|
||||
class SprayComponent : SharedSprayComponent, IAfterInteract, IUse, IActivate, IDropped
|
||||
{
|
||||
public const float SprayDistance = 3f;
|
||||
|
||||
@@ -211,5 +211,11 @@ namespace Content.Server.GameObjects.Components.Fluids
|
||||
if(Owner.TryGetComponent(out AppearanceComponent appearance))
|
||||
appearance.SetData(SprayVisuals.Safety, _safety);
|
||||
}
|
||||
|
||||
public void Dropped(DroppedEventArgs eventArgs)
|
||||
{
|
||||
if(_hasSafety && Owner.TryGetComponent(out AppearanceComponent appearance))
|
||||
appearance.SetData(SprayVisuals.Safety, _safety);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using Content.Server.GameObjects.Components.Chemistry;
|
||||
using Content.Server.GameObjects.Components.Fluids;
|
||||
using Content.Shared.Audio;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Nutrition
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class CreamPieComponent : Component, ILand
|
||||
{
|
||||
public override string Name => "CreamPie";
|
||||
|
||||
public void PlaySound()
|
||||
{
|
||||
EntitySystem.Get<AudioSystem>()
|
||||
.PlayFromEntity(AudioHelpers.GetRandomFileFromSoundCollection("desecration"), Owner,
|
||||
AudioHelpers.WithVariation(0.125f));
|
||||
}
|
||||
|
||||
public void Land(LandEventArgs eventArgs)
|
||||
{
|
||||
PlaySound();
|
||||
|
||||
if (Owner.TryGetComponent(out SolutionContainerComponent solution))
|
||||
{
|
||||
solution.Solution.SpillAt(Owner, "PuddleSmear", false);
|
||||
}
|
||||
|
||||
Owner.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
using Content.Server.GameObjects.Components.Mobs;
|
||||
using Content.Server.Utility;
|
||||
using Content.Shared.Chemistry;
|
||||
using Content.Shared.GameObjects.Components.Nutrition;
|
||||
using Content.Shared.Interfaces;
|
||||
using Content.Shared.Interfaces.GameObjects.Components;
|
||||
using Robust.Server.GameObjects;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Localization;
|
||||
using Robust.Shared.ViewVariables;
|
||||
using Serilog;
|
||||
|
||||
namespace Content.Server.GameObjects.Components.Nutrition
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class CreamPiedComponent : SharedCreamPiedComponent, IReagentReaction, IThrowCollide
|
||||
{
|
||||
private bool _creamPied;
|
||||
|
||||
[ViewVariables]
|
||||
public bool CreamPied
|
||||
{
|
||||
get => _creamPied;
|
||||
private set
|
||||
{
|
||||
_creamPied = value;
|
||||
if (Owner.TryGetComponent(out AppearanceComponent appearance))
|
||||
{
|
||||
appearance.SetData(CreamPiedVisuals.Creamed, CreamPied);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Wash()
|
||||
{
|
||||
if(CreamPied)
|
||||
CreamPied = false;
|
||||
}
|
||||
|
||||
public ReagentUnit ReagentReactTouch(ReagentPrototype reagent, ReagentUnit volume)
|
||||
{
|
||||
switch (reagent.ID)
|
||||
{
|
||||
case "chem.SpaceCleaner":
|
||||
case "chem.H2O":
|
||||
Wash();
|
||||
break;
|
||||
}
|
||||
|
||||
return ReagentUnit.Zero;
|
||||
}
|
||||
|
||||
public void HitBy(ThrowCollideEventArgs eventArgs)
|
||||
{
|
||||
if (!eventArgs.Thrown.TryGetComponent(out CreamPieComponent creamPie) || CreamPied) return;
|
||||
|
||||
CreamPied = true;
|
||||
Owner.PopupMessage(Loc.GetString("You have been creamed by {0:theName}!", eventArgs.Thrown));
|
||||
Owner.PopupMessageOtherClients(Loc.GetString("{0:theName} has been creamed by {1:theName}!", Owner, eventArgs.Thrown));
|
||||
|
||||
if (Owner.TryGetComponent(out StunnableComponent stun))
|
||||
{
|
||||
stun.Paralyze(1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,9 @@ namespace Content.Server.GameObjects.Components.Projectiles
|
||||
return;
|
||||
|
||||
_shouldStop = true; // hit something hard => stop after this collision
|
||||
|
||||
// Raise an event.
|
||||
EntitySystem.Get<InteractionSystem>().ThrowCollideInteraction(User, Owner, entity, Owner.Transform.Coordinates);
|
||||
}
|
||||
if (entity.TryGetComponent(out IDamageableComponent damage))
|
||||
{
|
||||
|
||||
@@ -28,7 +28,7 @@ using Robust.Shared.ViewVariables;
|
||||
namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
{
|
||||
[RegisterComponent]
|
||||
public class StunbatonComponent : MeleeWeaponComponent, IUse, IExamine, IMapInit, IInteractUsing
|
||||
public class StunbatonComponent : MeleeWeaponComponent, IUse, IExamine, IMapInit, IInteractUsing, IThrowCollide
|
||||
{
|
||||
[Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
|
||||
@@ -282,5 +282,15 @@ namespace Content.Server.GameObjects.Components.Weapon.Melee
|
||||
component.EjectCell(user);
|
||||
}
|
||||
}
|
||||
|
||||
public void DoHit(ThrowCollideEventArgs eventArgs)
|
||||
{
|
||||
if (!Activated || Cell == null || !Cell.TryUseCharge(EnergyPerUse) || !eventArgs.Target.TryGetComponent(out StunnableComponent stunnable))
|
||||
return;
|
||||
|
||||
EntitySystem.Get<AudioSystem>().PlayAtCoords("/Audio/Weapons/egloves.ogg", Owner.Transform.Coordinates, AudioHelpers.WithVariation(0.25f));
|
||||
|
||||
stunnable.Paralyze(_paralyzeTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -625,6 +625,32 @@ namespace Content.Server.GameObjects.EntitySystems.Click
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls ThrowCollide on all components that implement the IThrowCollide interface
|
||||
/// on a thrown entity and the target entity it hit.
|
||||
/// </summary>
|
||||
public void ThrowCollideInteraction(IEntity user, IEntity thrown, IEntity target, EntityCoordinates location)
|
||||
{
|
||||
var collideMsg = new ThrowCollideMessage(user, thrown, target, location);
|
||||
RaiseLocalEvent(collideMsg);
|
||||
if (collideMsg.Handled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var eventArgs = new ThrowCollideEventArgs(user, thrown, target, location);
|
||||
|
||||
foreach (var comp in thrown.GetAllComponents<IThrowCollide>().ToArray())
|
||||
{
|
||||
comp.DoHit(eventArgs);
|
||||
}
|
||||
|
||||
foreach (var comp in target.GetAllComponents<IThrowCollide>().ToArray())
|
||||
{
|
||||
comp.HitBy(eventArgs);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Equipped on all components that implement the IEquipped interface
|
||||
/// on an entity that has been equipped.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.GameObjects.Components.Nutrition
|
||||
{
|
||||
public class SharedCreamPiedComponent : Component
|
||||
{
|
||||
public override string Name => "CreamPied";
|
||||
}
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public enum CreamPiedVisuals
|
||||
{
|
||||
Creamed,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Map;
|
||||
|
||||
namespace Content.Shared.Interfaces.GameObjects.Components
|
||||
{
|
||||
public interface IThrowCollide
|
||||
{
|
||||
void HitBy(ThrowCollideEventArgs eventArgs) {}
|
||||
void DoHit(ThrowCollideEventArgs eventArgs) {}
|
||||
}
|
||||
|
||||
public class ThrowCollideEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// The entity that threw <see cref="Thrown"/> and hit <see cref="Target"/>.
|
||||
/// </summary>
|
||||
public IEntity User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity thrown by <see cref="User"/> that hit <see cref="Target"/>
|
||||
/// </summary>
|
||||
public IEntity Thrown { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity hit with <see cref="Thrown"/> by <see cref="User"/>
|
||||
/// </summary>
|
||||
public IEntity Target { get; }
|
||||
public EntityCoordinates Location { get; }
|
||||
|
||||
public ThrowCollideEventArgs(IEntity user, IEntity thrown, IEntity target, EntityCoordinates location)
|
||||
{
|
||||
User = user;
|
||||
Thrown = thrown;
|
||||
Target = target;
|
||||
Location = location;
|
||||
}
|
||||
}
|
||||
|
||||
public class ThrowCollideMessage : EntitySystemMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// If this message has already been "handled" by a previous system.
|
||||
/// </summary>
|
||||
public bool Handled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity that threw <see cref="Thrown"/>.
|
||||
/// </summary>
|
||||
public IEntity User { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity thrown by <see cref="User"/> that hit <see cref="Target"/>
|
||||
/// </summary>
|
||||
public IEntity Thrown { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The entity hit with <see cref="Thrown"/> by <see cref="User"/>
|
||||
/// </summary>
|
||||
public IEntity Target { get; }
|
||||
public EntityCoordinates Location { get; }
|
||||
|
||||
public ThrowCollideMessage(IEntity user, IEntity thrown, IEntity target, EntityCoordinates location)
|
||||
{
|
||||
User = user;
|
||||
Thrown = thrown;
|
||||
Target = target;
|
||||
Location = location;
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
Resources/Audio/Effects/desecration-01.ogg
Normal file
BIN
Resources/Audio/Effects/desecration-02.ogg
Normal file
BIN
Resources/Audio/Effects/desecration-03.ogg
Normal file
@@ -112,6 +112,10 @@
|
||||
sprite: Mobs/Customization/human_hair.rsi
|
||||
- map: ["enum.Slots.MASK"]
|
||||
- map: ["enum.Slots.HEAD"]
|
||||
- map: ["enum.CreamPiedVisualLayers.Pie"]
|
||||
sprite: Effects/creampie.rsi
|
||||
state: creampie_human
|
||||
visible: false
|
||||
- type: Icon
|
||||
sprite: Mobs/Species/Human/parts.rsi
|
||||
state: full
|
||||
@@ -159,6 +163,7 @@
|
||||
visuals:
|
||||
- type: RotationVisualizer
|
||||
- type: BuckleVisualizer
|
||||
- type: CreamPiedVisualizer
|
||||
- type: CombatMode
|
||||
- type: Climbing
|
||||
- type: Cuffable
|
||||
@@ -176,6 +181,7 @@
|
||||
proper: true
|
||||
- type: Pullable
|
||||
- type: DoAfter
|
||||
- type: CreamPied
|
||||
- type: Strippable
|
||||
- type: UserInterface
|
||||
interfaces:
|
||||
|
||||
@@ -231,6 +231,7 @@
|
||||
components:
|
||||
- type: Food
|
||||
trash: TrashPlate
|
||||
- type: CreamPie
|
||||
- type: SolutionContainer
|
||||
contents:
|
||||
reagents:
|
||||
|
||||
6
Resources/Prototypes/SoundCollections/desceration.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
- type: soundCollection
|
||||
id: desecration
|
||||
files:
|
||||
- /Audio/Effects/desecration-01.ogg
|
||||
- /Audio/Effects/desecration-02.ogg
|
||||
- /Audio/Effects/desecration-03.ogg
|
||||
BIN
Resources/Textures/Effects/creampie.rsi/creampie_ai.png
Normal file
|
After Width: | Height: | Size: 613 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_corgi.png
Normal file
|
After Width: | Height: | Size: 478 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_drone.png
Normal file
|
After Width: | Height: | Size: 558 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_engborg.png
Normal file
|
After Width: | Height: | Size: 429 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_hardsuit.png
Normal file
|
After Width: | Height: | Size: 452 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_helmet.png
Normal file
|
After Width: | Height: | Size: 386 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_human.png
Normal file
|
After Width: | Height: | Size: 412 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_janborg.png
Normal file
|
After Width: | Height: | Size: 575 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_lizard.png
Normal file
|
After Width: | Height: | Size: 412 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_medborg.png
Normal file
|
After Width: | Height: | Size: 361 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_monkey.png
Normal file
|
After Width: | Height: | Size: 368 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_secborg.png
Normal file
|
After Width: | Height: | Size: 372 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_standborg.png
Normal file
|
After Width: | Height: | Size: 445 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_xeno_crit.png
Normal file
|
After Width: | Height: | Size: 225 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_xeno_dead.png
Normal file
|
After Width: | Height: | Size: 225 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_xeno_sleep.png
Normal file
|
After Width: | Height: | Size: 292 B |
BIN
Resources/Textures/Effects/creampie.rsi/creampie_xenomorph.png
Normal file
|
After Width: | Height: | Size: 374 B |
1
Resources/Textures/Effects/creampie.rsi/meta.json
Normal file
@@ -0,0 +1 @@
|
||||
{"version": 1, "size": {"x": 32, "y": 32}, "license": "CC-BY-SA 3.0", "copyright": "Taken from https://github.com/tgstation/tgstation at 0d9c9a8233dfc3fc55edc538955a761a6328bee0", "states": [{"name": "creampie_ai", "directions": 1, "delays": [[1.0]]}, {"name": "creampie_corgi", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_drone", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_engborg", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_hardsuit", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_helmet", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_human", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_janborg", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_lizard", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_medborg", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_monkey", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_secborg", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_standborg", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_xeno_crit", "directions": 1, "delays": [[1.0]]}, {"name": "creampie_xeno_dead", "directions": 1, "delays": [[1.0]]}, {"name": "creampie_xeno_sleep", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "creampie_xenomorph", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]}
|
||||