make legs affect movement speed with body (#12928)

Co-authored-by: DrSmugleaf <DrSmugleaf@users.noreply.github.com>
This commit is contained in:
Nemanja
2022-12-09 20:08:47 -05:00
committed by GitHub
parent 45b72d4852
commit 9db34a4e8a
20 changed files with 114 additions and 3 deletions

View File

@@ -21,6 +21,13 @@ public sealed class BodyComponent : Component, IDraggable
[DataField("gibSound")]
public SoundSpecifier GibSound = new SoundCollectionSpecifier("gib");
/// <summary>
/// The amount of legs required to move at full speed.
/// If 0, then legs do not impact speed.
/// </summary>
[DataField("requiredLegs")]
public int RequiredLegs;
bool IDraggable.CanStartDrag(StartDragDropEvent args)
{
return true;

View File

@@ -164,6 +164,32 @@ public partial class SharedBodySystem
}
}
/// <summary>
/// Returns all body part slots in the graph, including ones connected by
/// body parts which are null.
/// </summary>
/// <param name="partId"></param>
/// <param name="part"></param>
/// <returns></returns>
public IEnumerable<BodyPartSlot> GetAllBodyPartSlots(EntityUid partId, BodyPartComponent? part = null)
{
if (!Resolve(partId, ref part, false))
yield break;
foreach (var slot in part.Children.Values)
{
if (!TryComp<BodyPartComponent>(slot.Child, out var childPart))
continue;
yield return slot;
foreach (var child in GetAllBodyPartSlots(slot.Child.Value, childPart))
{
yield return child;
}
}
}
public virtual HashSet<EntityUid> GibBody(EntityUid? partId, bool gibOrgans = false,
BodyComponent? body = null, bool deleteItems = false)
{

View File

@@ -6,6 +6,7 @@ using Content.Shared.Body.Organ;
using Content.Shared.Body.Part;
using Content.Shared.Damage;
using Content.Shared.Damage.Prototypes;
using Content.Shared.Movement.Components;
using Content.Shared.Random.Helpers;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
@@ -211,6 +212,9 @@ public partial class SharedBodySystem
if (part.Body is { } newBody)
{
if (part.PartType == BodyPartType.Leg)
UpdateMovementSpeed(newBody);
var partAddedEvent = new BodyPartAddedEvent(slot.Id, part);
RaiseLocalEvent(newBody, ref partAddedEvent);
@@ -254,10 +258,11 @@ public partial class SharedBodySystem
var args = new BodyPartRemovedEvent(slot.Id, part);
RaiseLocalEvent(oldBody, ref args);
if (part.PartType == BodyPartType.Leg &&
!GetBodyChildrenOfType(oldBody, BodyPartType.Leg).Any())
if (part.PartType == BodyPartType.Leg)
{
Standing.Down(oldBody);
UpdateMovementSpeed(oldBody);
if(!GetBodyChildrenOfType(oldBody, BodyPartType.Leg).Any())
Standing.Down(oldBody);
}
if (part.IsVital && !GetBodyChildrenOfType(oldBody, part.PartType).Any())
@@ -282,6 +287,44 @@ public partial class SharedBodySystem
return true;
}
public void UpdateMovementSpeed(EntityUid body, BodyComponent? component = null, MovementSpeedModifierComponent? movement = null)
{
if (!Resolve(body, ref component, ref movement, false))
return;
if (component.RequiredLegs <= 0)
return;
if (component.Root?.Child is not { } root)
return;
var allSlots = GetAllBodyPartSlots(root).ToHashSet();
var allLegs = new HashSet<EntityUid>();
foreach (var slot in allSlots)
{
if (slot.Type == BodyPartType.Leg && slot.Child is { } child)
allLegs.Add(child);
}
var walkSpeed = 0f;
var sprintSpeed = 0f;
var acceleration = 0f;
foreach (var leg in allLegs)
{
if (!TryComp<MovementSpeedModifierComponent>(leg, out var legModifier))
continue;
walkSpeed += legModifier.BaseWalkSpeed;
sprintSpeed += legModifier.BaseSprintSpeed;
acceleration += legModifier.Acceleration;
}
walkSpeed /= component.RequiredLegs;
sprintSpeed /= component.RequiredLegs;
acceleration /= component.RequiredLegs;
Movement.ChangeBaseSpeed(body, walkSpeed, sprintSpeed, acceleration, movement);
}
public bool DropPartAt(EntityUid? partId, EntityCoordinates dropAt, BodyPartComponent? part = null)
{
if (partId == null || !DropPart(partId, part))

View File

@@ -1,4 +1,5 @@
using Content.Shared.Damage;
using Content.Shared.Movement.Systems;
using Content.Shared.Standing;
using Robust.Shared.Containers;
using Robust.Shared.Prototypes;
@@ -14,6 +15,7 @@ public abstract partial class SharedBodySystem : EntitySystem
[Dependency] protected readonly SharedContainerSystem Containers = default!;
[Dependency] protected readonly DamageableSystem Damageable = default!;
[Dependency] protected readonly StandingStateSystem Standing = default!;
[Dependency] protected readonly MovementSpeedModifierSystem Movement = default!;
public override void Initialize()
{

View File

@@ -37,6 +37,7 @@
components:
- type: BodyPart
partType: Leg
- type: MovementSpeedModifier
- type: entity
id: FeetAnimal

View File

@@ -118,6 +118,9 @@
- type: BodyPart
partType: Leg
symmetry: Left
- type: MovementSpeedModifier
baseWalkSpeed : 1.5
baseSprintSpeed : 3.5
- type: entity
id: RightLegDiona
@@ -131,6 +134,9 @@
- type: BodyPart
partType: Leg
symmetry: Right
- type: MovementSpeedModifier
baseWalkSpeed : 1.5
baseSprintSpeed : 3.5
- type: entity
id: LeftFootDiona

View File

@@ -136,6 +136,7 @@
- type: BodyPart
partType: Leg
symmetry: Left
- type: MovementSpeedModifier
- type: entity
id: RightLegHuman
@@ -152,6 +153,7 @@
- type: BodyPart
partType: Leg
symmetry: Right
- type: MovementSpeedModifier
- type: entity
id: LeftFootHuman

View File

@@ -134,6 +134,9 @@
- type: BodyPart
partType: Leg
symmetry: Left
- type: MovementSpeedModifier
baseWalkSpeed : 2.7
baseSprintSpeed : 4.5
- type: entity
id: RightLegReptilian
@@ -150,6 +153,9 @@
- type: BodyPart
partType: Leg
symmetry: Right
- type: MovementSpeedModifier
baseWalkSpeed : 2.7
baseSprintSpeed : 4.5
- type: entity
id: LeftFootReptilian

View File

@@ -149,6 +149,7 @@
- type: BodyPart
partType: Leg
symmetry: Left
- type: MovementSpeedModifier
- type: entity
id: RightLegSkeleton
@@ -165,6 +166,7 @@
- type: BodyPart
partType: Leg
symmetry: Right
- type: MovementSpeedModifier
- type: entity
id: LeftFootSkeleton

View File

@@ -135,6 +135,7 @@
- type: BodyPart
partType: Leg
symmetry: Left
- type: MovementSpeedModifier
- type: entity
id: RightLegSlime
@@ -151,6 +152,7 @@
- type: BodyPart
partType: Leg
symmetry: Right
- type: MovementSpeedModifier
- type: entity
id: LeftFootSlime

View File

@@ -136,6 +136,7 @@
- type: BodyPart
partType: Leg
symmetry: Left
- type: MovementSpeedModifier
- type: entity
id: RightLegVox
@@ -152,6 +153,7 @@
- type: BodyPart
partType: Leg
symmetry: Right
- type: MovementSpeedModifier
- type: entity
id: LeftFootVox

View File

@@ -711,6 +711,7 @@
speechSounds: Monkey
- type: Body
prototype: Primate
requiredLegs: 1 # TODO: More than 1 leg
- type: DamageStateVisuals
states:
Alive:

View File

@@ -50,6 +50,7 @@
Piercing: 8
- type: Body
prototype: Rat
requiredLegs: 1 # TODO: More than 1 leg
- type: Hunger # probably should be prototyped
thresholds:
Overfed: 200
@@ -225,6 +226,7 @@
Piercing: 3
- type: Body
prototype: Rat
requiredLegs: 1 # TODO: More than 1 leg
- type: Hunger # probably should be prototyped
thresholds:
Overfed: 200

View File

@@ -177,6 +177,7 @@
species: Human
- type: Body
prototype: Human
requiredLegs: 2
- type: Damageable
damageContainer: Biological
- type: RadiationReceiver
@@ -366,6 +367,7 @@
species: Human
- type: Body
prototype: Human
requiredLegs: 2
- type: Damageable
damageContainer: Biological
- type: MobState

View File

@@ -15,6 +15,7 @@
state: full
- type: Body
prototype: Diona
requiredLegs: 2
- type: Damageable
damageContainer: Biological
damageModifierSet: Diona

View File

@@ -24,6 +24,7 @@
scale: 1, 0.8
- type: Body
prototype: Human
requiredLegs: 2
- type: entity
save: false

View File

@@ -14,6 +14,7 @@
state: full
- type: Body
prototype: Reptilian
requiredLegs: 2
- type: LizardAccent
- type: Speech
speechSounds: Lizard

View File

@@ -12,6 +12,7 @@
state: full
- type: Body
prototype: Skeleton
requiredLegs: 2
gibSound: /Audio/Effects/bone_rattle.ogg
- type: Damageable
damageContainer: Biological

View File

@@ -11,6 +11,7 @@
state: full
- type: Body
prototype: Slime
requiredLegs: 2
- type: Humanoid
species: SlimePerson
- type: Speech

View File

@@ -81,6 +81,7 @@
- map: [ "pocket2" ]
- type: Body
prototype: Vox
requiredLegs: 2
# Vox nitrogen stuff is handled in their metabolism
- type: Respirator
damage:
@@ -110,4 +111,5 @@
species: Vox
- type: Body
prototype: Vox
requiredLegs: 2