using Content.Shared.Anomaly.Components;
using Content.Shared.Anomaly.Effects;
-using Content.Shared.Body.Components;
+using Content.Shared.Humanoid;
using Robust.Client.GameObjects;
namespace Content.Client.Anomaly.Effects;
var index = _sprite.LayerMapReserve((ent.Owner, sprite), ent.Comp.LayerMap);
- if (TryComp<BodyComponent>(ent, out var body) &&
- body.Prototype is not null &&
- ent.Comp.SpeciesSprites.TryGetValue(body.Prototype.Value, out var speciesSprite))
+ if (TryComp<HumanoidAppearanceComponent>(ent, out var humanoidAppearance) &&
+ ent.Comp.SpeciesSprites.TryGetValue(humanoidAppearance.Species, out var speciesSprite))
{
_sprite.LayerSetSprite((ent.Owner, sprite), index, speciesSprite);
}
using System.Numerics;
-using Content.Shared.Body.Components;
using Content.Shared.CardboardBox;
using Content.Shared.CardboardBox.Components;
using Content.Shared.Examine;
+using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Components;
using Robust.Client.GameObjects;
[Dependency] private readonly ExamineSystemShared _examine = default!;
[Dependency] private readonly SpriteSystem _sprite = default!;
- private EntityQuery<BodyComponent> _bodyQuery;
+ private EntityQuery<MobStateComponent> _mobStateQuery;
public override void Initialize()
{
base.Initialize();
- _bodyQuery = GetEntityQuery<BodyComponent>();
+ _mobStateQuery = GetEntityQuery<MobStateComponent>();
SubscribeNetworkEvent<PlayBoxEffectMessage>(OnBoxEffect);
}
if (!_examine.InRangeUnOccluded(sourcePos, mapPos, box.Distance, null))
continue;
- // no effect for anything too exotic
- if (!_bodyQuery.HasComp(mob))
+ // no effect for non-mobs that have MobMover, such as mechs and vehicles.
+ if (!_mobStateQuery.HasComp(mob))
continue;
var ent = Spawn(box.Effect, mapPos);
#nullable enable
using Content.Server.Cuffs;
-using Content.Shared.Body.Components;
using Content.Shared.Cuffs.Components;
using Content.Shared.Hands.Components;
using Robust.Server.Console;
using Robust.Shared.GameObjects;
-using Robust.Shared.Map;
namespace Content.IntegrationTests.Tests.GameObjects.Components.ActionBlocking
{
components:
- type: Cuffable
- type: Hands
+ hands:
+ hand_right:
+ location: Right
+ hand_left:
+ location: Left
+ sortedHands:
+ - hand_right
+ - hand_left
- type: ComplexInteraction
- - type: Body
- prototype: Human
- type: entity
name: HandcuffsDummy
HandsComponent hands = default!;
var entityManager = server.ResolveDependency<IEntityManager>();
- var mapManager = server.ResolveDependency<IMapManager>();
var host = server.ResolveDependency<IServerConsoleHost>();
var map = await pair.CreateTestMap();
{
Assert.That(entityManager.TryGetComponent(human, out cuffed!), $"Human has no {nameof(CuffableComponent)}");
Assert.That(entityManager.TryGetComponent(human, out hands!), $"Human has no {nameof(HandsComponent)}");
- Assert.That(entityManager.TryGetComponent(human, out BodyComponent? _), $"Human has no {nameof(BodyComponent)}");
Assert.That(entityManager.TryGetComponent(cuffs, out HandcuffComponent? _), $"Handcuff has no {nameof(HandcuffComponent)}");
Assert.That(entityManager.TryGetComponent(secondCuffs, out HandcuffComponent? _), $"Second handcuffs has no {nameof(HandcuffComponent)}");
});
using Content.Server.Body.Components;
using Content.Server.Ghost.Components;
-using Content.Shared.Body.Components;
using Content.Shared.Body.Events;
using Content.Shared.Mind;
using Content.Shared.Mind.Components;
+using Content.Shared.Mobs.Components;
using Content.Shared.Pointing;
-namespace Content.Server.Body.Systems
+namespace Content.Server.Body.Systems;
+
+public sealed class BrainSystem : EntitySystem
{
- public sealed class BrainSystem : EntitySystem
- {
- [Dependency] private readonly SharedMindSystem _mindSystem = default!;
+ [Dependency] private readonly SharedMindSystem _mindSystem = default!;
- public override void Initialize()
- {
- base.Initialize();
+ public override void Initialize()
+ {
+ base.Initialize();
- SubscribeLocalEvent<BrainComponent, OrganAddedToBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
- SubscribeLocalEvent<BrainComponent, OrganRemovedFromBodyEvent>((uid, _, args) => HandleMind(uid, args.OldBody));
- SubscribeLocalEvent<BrainComponent, PointAttemptEvent>(OnPointAttempt);
- }
+ SubscribeLocalEvent<BrainComponent, OrganAddedToBodyEvent>((uid, _, args) => HandleMind(args.Body, uid));
+ SubscribeLocalEvent<BrainComponent, OrganRemovedFromBodyEvent>((uid, _, args) => HandleMind(uid, args.OldBody));
+ SubscribeLocalEvent<BrainComponent, PointAttemptEvent>(OnPointAttempt);
+ }
- private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
- {
- if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
- return;
+ private void HandleMind(EntityUid newEntity, EntityUid oldEntity)
+ {
+ if (TerminatingOrDeleted(newEntity) || TerminatingOrDeleted(oldEntity))
+ return;
- EnsureComp<MindContainerComponent>(newEntity);
- EnsureComp<MindContainerComponent>(oldEntity);
+ EnsureComp<MindContainerComponent>(newEntity);
+ EnsureComp<MindContainerComponent>(oldEntity);
- var ghostOnMove = EnsureComp<GhostOnMoveComponent>(newEntity);
- if (HasComp<BodyComponent>(newEntity))
- ghostOnMove.MustBeDead = true;
+ var ghostOnMove = EnsureComp<GhostOnMoveComponent>(newEntity);
+ ghostOnMove.MustBeDead = HasComp<MobStateComponent>(newEntity); // Don't ghost living players out of their bodies.
- if (!_mindSystem.TryGetMind(oldEntity, out var mindId, out var mind))
- return;
+ if (!_mindSystem.TryGetMind(oldEntity, out var mindId, out var mind))
+ return;
- _mindSystem.TransferTo(mindId, newEntity, mind: mind);
- }
+ _mindSystem.TransferTo(mindId, newEntity, mind: mind);
+ }
- private void OnPointAttempt(Entity<BrainComponent> ent, ref PointAttemptEvent args)
- {
- args.Cancel();
- }
+ private void OnPointAttempt(Entity<BrainComponent> ent, ref PointAttemptEvent args)
+ {
+ args.Cancel();
}
}
+
if (args.Handled)
return;
- if (!TryComp<BodyComponent>(uid, out var body) || !TryComp<MobStateComponent>(uid, out var state))
+ if (!TryComp<MobStateComponent>(uid, out var state))
{
- Log.Error($"Tried to get the mob price of {ToPrettyString(uid)}, which has no {nameof(BodyComponent)} and no {nameof(MobStateComponent)}.");
+ Log.Error($"Tried to get the mob price of {ToPrettyString(uid)}, which has no {nameof(MobStateComponent)}.");
return;
}
- // TODO: Better handling of missing.
- var partList = _bodySystem.GetBodyChildren(uid, body).ToList();
- var totalPartsPresent = partList.Sum(_ => 1);
- var totalParts = partList.Count;
+ var partPenalty = 0.0;
+ if (TryComp<BodyComponent>(uid, out var body))
+ {
+ var partList = _bodySystem.GetBodyChildren(uid, body).ToList();
+ var totalPartsPresent = partList.Sum(_ => 1);
+ var totalParts = partList.Count;
- var partRatio = totalPartsPresent / (double) totalParts;
- var partPenalty = component.Price * (1 - partRatio) * component.MissingBodyPartPenalty;
+ var partRatio = totalPartsPresent / (double) totalParts;
+ partPenalty = component.Price * (1 - partRatio) * component.MissingBodyPartPenalty;
+ }
args.Price += (component.Price - partPenalty) * (_mobStateSystem.IsAlive(uid, state) ? 1.0 : component.DeathPenalty);
}
popupEnt = Spawn(proto, coords.Offset(_robustRandom.NextVector2(0.25f)));
}
- var hasBody = TryComp<BodyComponent>(args.Args.Target.Value, out var body);
-
// only show a big popup when butchering living things.
- var popupType = PopupType.Small;
- if (hasBody)
- popupType = PopupType.LargeCaution;
+ // Meant to differentiate cutting up clothes and cutting up your boss.
+ var popupType = HasComp<MobStateComponent>(args.Args.Target.Value)
+ ? PopupType.LargeCaution
+ : PopupType.Small;
_popupSystem.PopupEntity(Loc.GetString("butcherable-knife-butchered-success", ("target", args.Args.Target.Value), ("knife", Identity.Entity(uid, EntityManager))),
- popupEnt, args.Args.User, popupType);
-
- if (hasBody)
- _bodySystem.GibBody(args.Args.Target.Value, body: body);
+ popupEnt,
+ args.Args.User,
+ popupType);
+ _bodySystem.GibBody(args.Args.Target.Value); // does nothing if ent can't be gibbed
_destructibleSystem.DestroyEntity(args.Args.Target.Value);
args.Handled = true;
using Content.Server.Storage.Components;
-using Content.Shared.Body.Components;
using Content.Shared.Examine;
+using Content.Shared.Mobs.Components;
using Content.Shared.Morgue;
using Content.Shared.Morgue.Components;
using Robust.Shared.Audio.Systems;
foreach (var ent in storage.Contents.ContainedEntities)
{
- if (!hasMob && HasComp<BodyComponent>(ent))
+ if (!hasMob && HasComp<MobStateComponent>(ent))
hasMob = true;
if (HasComp<ActorComponent>(ent))
using Content.Shared.Anomaly.Effects;
using Content.Shared.Body.Prototypes;
+using Content.Shared.Humanoid.Prototypes;
using Robust.Shared.Audio;
using Robust.Shared.GameStates;
using Robust.Shared.Prototypes;
/// Ability to use unique sprites for different body types
/// </summary>
[DataField, AutoNetworkedField]
- public Dictionary<ProtoId<BodyPrototype>, SpriteSpecifier> SpeciesSprites = new();
+ public Dictionary<ProtoId<SpeciesPrototype>, SpriteSpecifier> SpeciesSprites = new();
/// <summary>
/// The key of the entity layer into which the sprite will be inserted
using System.Linq;
using Content.Shared.ActionBlocker;
using Content.Shared.Administration.Logs;
-using Content.Shared.Body.Components;
using Content.Shared.Climbing.Systems;
using Content.Shared.Containers;
using Content.Shared.Database;
using Content.Shared.IdentityManagement;
using Content.Shared.Interaction;
using Content.Shared.Item;
+using Content.Shared.Mobs.Components;
using Content.Shared.Movement.Events;
using Content.Shared.Popups;
using Content.Shared.Power;
return false;
var storable = HasComp<ItemComponent>(entity);
- if (!storable && !HasComp<BodyComponent>(entity))
+ if (!storable && !HasComp<MobStateComponent>(entity))
return false;
if (_whitelistSystem.IsBlacklistPass(component.Blacklist, entity) ||
-using Content.Shared.Body.Components;
using Content.Shared.Morgue.Components;
using Content.Shared.Standing;
using Content.Shared.Storage.Components;
{
foreach (var ent in args.Contents)
{
- if (HasComp<BodyComponent>(ent) && !_standing.IsDown(ent))
+ // Explicitly check for standing state component, as entities without it will return false for IsDown()
+ // which prevents inserting any kind of non-mobs into this container (which is unintended)
+ if (TryComp<StandingStateComponent>(ent, out var standingState) && !_standing.IsDown(ent, standingState))
args.Contents.Remove(ent);
}
}
using Content.Shared.Wall;
using Content.Shared.Whitelist;
using Content.Shared.ActionBlocker;
+using Content.Shared.Mobs.Components;
using Robust.Shared.Audio.Systems;
using Robust.Shared.Containers;
using Robust.Shared.GameStates;
return _whitelistSystem.IsValid(component.Whitelist, toInsert);
// The inserted entity must be a mob or an item.
- return HasComp<BodyComponent>(toInsert) || HasComp<ItemComponent>(toInsert);
+ return HasComp<MobStateComponent>(toInsert) || HasComp<ItemComponent>(toInsert);
}
public bool TryOpenStorage(EntityUid user, EntityUid target, bool silent = false)
- type: Implanter
whitelist:
components:
- - Body # no chair microbomb
+ - MobState # no chair microbomb
blacklist:
components:
- Guardian # no holoparasite macrobomb wombo combo
components:
- Anchorable
- Item
- - Body
+ - MobState
- type: Explosive # Powerful explosion in a large radius. Will break underplating.
explosionType: DemolitionCharge
totalIntensity: 360
disableWhenFirstOpened: true
whitelist:
components:
- - Body
+ - MobState
- type: LockVisuals
stateLocked: cursed_door
stateUnlocked: decursed_door
- type: WhitelistTriggerCondition
userWhitelist:
components:
- - Body
+ - MobState
- type: entity
id: ProjectilePolyboltMonkey
- type: WhitelistTriggerCondition
userWhitelist:
components:
- - Body
+ - MobState
- type: entity
id: ProjectilePolyboltDoor
- type: WhitelistTriggerCondition
userWhitelist:
components:
- - Body
+ - MobState
- type: entity
id: ProjectileIcicle
- type: WhitelistTriggerCondition
userWhitelist:
components:
- - Body
+ - MobState
- type: EntityTargetAction
whitelist:
components:
- - Body # this also allows borgs because that supercode uses Body for no reason
+ - MobState
- PAI # intended to mindswap pAIs and AIs
- StationAiCore
event: !type:MindSwapSpellEvent
- type: EntityTargetAction
whitelist:
components:
- - Body
+ - MobState
canTargetSelf: false
- type: entity