Adds slippery items (#1321)

* Start work on Slippery Component

* Slips work

* Add banana peel

* Add required slip speed

* Add slip sound

* Adds soap

* Make soapnt, soapsyndie and soapdeluxe inherit soap

* Adds homemade soap and omega soap

* Fix slipping not taking into account the entity being in a container
This commit is contained in:
Víctor Aguilera Puerto
2020-07-09 17:00:37 +02:00
committed by GitHub
parent 8938d96402
commit 626c8c51a1
18 changed files with 354 additions and 0 deletions

View File

@@ -0,0 +1,115 @@
using System.Collections.Generic;
using System.Timers;
using Content.Server.GameObjects.Components.Mobs;
using Content.Server.Throw;
using Content.Shared.Audio;
using Content.Shared.Physics;
using Robust.Server.GameObjects.EntitySystems;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Components;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Serialization;
using Robust.Shared.ViewVariables;
using Timer = Robust.Shared.Timers.Timer;
namespace Content.Server.GameObjects.Components.Movement
{
[RegisterComponent]
public class SlipperyComponent : Component, ICollideBehavior
{
[Dependency] private IEntityManager _entityManager = default!;
public override string Name => "Slippery";
private List<EntityUid> _slipped = new List<EntityUid>();
/// <summary>
/// How many seconds the mob will be paralyzed for.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float ParalyzeTime { get; set; } = 3f;
/// <summary>
/// Percentage of shape intersection for a slip to occur.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float IntersectPercentage { get; set; } = 0.3f;
/// <summary>
/// Entities will only be slipped if their speed exceeds this limit.
/// </summary>
[ViewVariables(VVAccess.ReadWrite)]
public float RequiredSlipSpeed { get; set; } = 0f;
/// <summary>
/// Path to the sound to be played when a mob slips.
/// </summary>
[ViewVariables]
public string SlipSound { get; set; } = "/Audio/Effects/slip.ogg";
public override void Initialize()
{
base.Initialize();
var collidable = Owner.GetComponent<ICollidableComponent>();
collidable.Hard = false;
var shape = collidable.PhysicsShapes[0];
shape.CollisionLayer |= (int) CollisionGroup.MobImpassable;
shape.CollisionMask = (int)CollisionGroup.None;
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
serializer.DataField(this, x => ParalyzeTime, "paralyzeTime", 3f);
serializer.DataField(this, x => IntersectPercentage, "intersectPercentage", 0.3f);
serializer.DataField(this, x => RequiredSlipSpeed, "requiredSlipSpeed", 0f);
serializer.DataField(this, x => SlipSound, "slipSound", "/Audio/Effects/slip.ogg");
}
public void CollideWith(IEntity collidedWith)
{
if (ContainerHelpers.IsInContainer(Owner)
|| _slipped.Contains(collidedWith.Uid)
|| !collidedWith.TryGetComponent(out StunnableComponent stun)
|| !collidedWith.TryGetComponent(out ICollidableComponent otherBody)
|| !collidedWith.TryGetComponent(out PhysicsComponent otherPhysics)
|| !Owner.TryGetComponent(out ICollidableComponent body))
return;
if (otherPhysics.LinearVelocity.Length < RequiredSlipSpeed || stun.KnockedDown)
return;
var percentage = otherBody.WorldAABB.IntersectPercentage(body.WorldAABB);
if (percentage < IntersectPercentage)
return;
stun.Paralyze(5f);
_slipped.Add(collidedWith.Uid);
if(!string.IsNullOrEmpty(SlipSound))
EntitySystem.Get<AudioSystem>().PlayFromEntity(SlipSound, Owner, AudioHelpers.WithVariation(0.2f));
}
public void Update(float frameTime)
{
foreach (var uid in _slipped.ToArray())
{
if(!uid.IsValid() || !_entityManager.EntityExists(uid)) continue;
var entity = _entityManager.GetEntity(uid);
var collidable = Owner.GetComponent<ICollidableComponent>();
var otherCollidable = entity.GetComponent<ICollidableComponent>();
if (!collidable.WorldAABB.Intersects(otherCollidable.WorldAABB))
_slipped.Remove(uid);
}
}
}
}

View File

@@ -0,0 +1,26 @@
using Content.Server.GameObjects.Components.Movement;
using Robust.Shared.GameObjects;
using Robust.Shared.GameObjects.Systems;
namespace Content.Server.GameObjects.EntitySystems
{
public class SlipperySystem : EntitySystem
{
public override void Initialize()
{
base.Initialize();
EntityQuery = new TypeEntityQuery(typeof(SlipperyComponent));
}
public override void Update(float frameTime)
{
base.Update(frameTime);
foreach (var entity in RelevantEntities)
{
entity.GetComponent<SlipperyComponent>().Update(frameTime);
}
}
}
}

Binary file not shown.

View File

@@ -3027,3 +3027,21 @@
sprite: Objects/Consumable/Food/milkape.rsi sprite: Objects/Consumable/Food/milkape.rsi
- type: Icon - type: Icon
sprite: Objects/Consumable/Food/milkape.rsi sprite: Objects/Consumable/Food/milkape.rsi
- type: entity
name: banana
parent: FoodBase
id: FoodBanana
description: Rich in potassium.
components:
- type: Food
trash: TrashBananaPeel
- type: Solution
contents:
reagents:
- ReagentId: chem.Nutriment
Quantity: 6
- type: Sprite
sprite: Objects/Consumable/Food/banana.rsi
- type: Icon
sprite: Objects/Consumable/Food/banana.rsi

View File

@@ -200,3 +200,16 @@
sprite: Objects/Consumable/Trash/waffles.rsi sprite: Objects/Consumable/Trash/waffles.rsi
- type: Icon - type: Icon
sprite: Objects/Consumable/Trash/waffles.rsi sprite: Objects/Consumable/Trash/waffles.rsi
- type: entity
name: banana peel
parent: TrashBase
id: TrashBananaPeel
components:
- type: Sprite
sprite: Objects/Consumable/Food/banana.rsi
state: peel
- type: Icon
sprite: Objects/Consumable/Food/banana.rsi
state: peel
- type: Slippery

View File

@@ -104,3 +104,92 @@
- type: Item - type: Item
sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi sprite: Objects/Specific/Janitorial/wet_floor_sign.rsi
- type: entity
name: soap
id: Soap
parent: BaseItem
description: A cheap bar of soap. Doesn't smell.
components:
- type: Sprite
sprite: Objects/Specific/Janitorial/soap.rsi
state: soap
- type: Icon
sprite: Objects/Specific/Janitorial/soap.rsi
state: soap
- type: Item
sprite: Objects/Specific/Janitorial/soap.rsi
- type: Slippery
paralyzeTime: 2.5
- type: entity
name: soap
id: SoapNT
parent: Soap
description: A Nanotrasen brand bar of soap. Smells of phoron.
components:
- type: Sprite
state: soapnt
- type: Icon
state: soapnt
- type: entity
name: soap
id: SoapDeluxe
parent: Soap
description: A deluxe Waffle Co. brand bar of soap. Smells of condoms.
components:
- type: Sprite
state: soapdeluxe
- type: Icon
state: soapdeluxe
- type: entity
name: soap
id: SoapSyndie
parent: Soap
description: An untrustworthy bar of soap. Smells of fear.
components:
- type: Sprite
state: soapsyndie
- type: Icon
state: soapsyndie
- type: Slippery
paralyzeTime: 5
- type: entity
name: soap
id: SoapHomemade
parent: Soap
description: A homemade bar of soap. Smells of... well....
components:
- type: Sprite
state: soapgibs
- type: Icon
state: soapgibs
- type: Slippery
paralyzeTime: 2
- type: entity
name: omega soap
id: SoapOmega
parent: Soap
description: The most advanced soap known to mankind. Smells of bluespace.
components:
- type: Sprite
state: soapomega
- type: Icon
state: soapomega
- type: Slippery
paralyzeTime: 7

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

View File

@@ -0,0 +1,28 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA 3.0",
"states": [
{
"name": "icon",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "peel",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 527 B

View File

@@ -0,0 +1,65 @@
{
"version": 1,
"size": {
"x": 32,
"y": 32
},
"license": "CC-BY-SA 3.0",
"copyright": "Taken from https://github.com/vgstation-coders/vgstation13 at a407fc1f5c25cbce8b653c553f53be294d15b071 and https://github.com/tgstation/tgstation at 259acc8c81054d89f7b6bcd9ff702fdf587a19ed. soapomega.png modified by Zumorica",
"states": [
{
"name": "soap",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "soapdeluxe",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "soapgibs",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "soapnt",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "soapomega",
"directions": 1,
"delays": [
[
1.0
]
]
},
{
"name": "soapsyndie",
"directions": 1,
"delays": [
[
1.0
]
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B