Adds IThrowCollide, Creaming people with cream pies and tactical stun baton throws (#2122)

This commit is contained in:
Víctor Aguilera Puerto
2020-09-22 15:34:30 +02:00
committed by GitHub
parent db32180942
commit 4c34a12c67
33 changed files with 285 additions and 2 deletions

View File

@@ -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,
}
}

View File

@@ -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);
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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))
{

View File

@@ -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);
}
}
}

View File

@@ -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.

View File

@@ -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,
}
}

View File

@@ -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;
}
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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:

View File

@@ -231,6 +231,7 @@
components:
- type: Food
trash: TrashPlate
- type: CreamPie
- type: SolutionContainer
contents:
reagents:

View 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

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 429 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 386 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 374 B

View 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]]}]}