| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- using Content.Shared.Bed.Sleep;
- using Content.Shared.Buckle.Components;
- using Content.Shared.CombatMode.Pacification;
- using Content.Shared.Damage.ForceSay;
- using Content.Shared.Emoting;
- using Content.Shared.Hands;
- using Content.Shared.Interaction;
- using Content.Shared.Interaction.Events;
- using Content.Shared.Inventory.Events;
- using Content.Shared.Item;
- using Content.Shared.Mobs.Components;
- using Content.Shared.Movement.Events;
- using Content.Shared.Pointing;
- using Content.Shared.Pulling.Events;
- using Content.Shared.Speech;
- using Content.Shared.Standing;
- using Content.Shared.Strip.Components;
- using Content.Shared.Throwing;
- using Robust.Shared.Physics.Components;
- namespace Content.Shared.Mobs.Systems;
- public partial class MobStateSystem
- {
- //General purpose event subscriptions. If you can avoid it register these events inside their own systems
- private void SubscribeEvents()
- {
- SubscribeLocalEvent<MobStateComponent, BeforeGettingStrippedEvent>(OnGettingStripped);
- SubscribeLocalEvent<MobStateComponent, ChangeDirectionAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, UseAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, AttackAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, ConsciousAttemptEvent>(CheckConcious);
- SubscribeLocalEvent<MobStateComponent, ThrowAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, SpeakAttemptEvent>(OnSpeakAttempt);
- SubscribeLocalEvent<MobStateComponent, IsEquippingAttemptEvent>(OnEquipAttempt);
- SubscribeLocalEvent<MobStateComponent, EmoteAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, IsUnequippingAttemptEvent>(OnUnequipAttempt);
- SubscribeLocalEvent<MobStateComponent, DropAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, PickupAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, StartPullAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, UpdateCanMoveEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, StandAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, PointAttemptEvent>(CheckAct);
- SubscribeLocalEvent<MobStateComponent, TryingToSleepEvent>(OnSleepAttempt);
- SubscribeLocalEvent<MobStateComponent, CombatModeShouldHandInteractEvent>(OnCombatModeShouldHandInteract);
- SubscribeLocalEvent<MobStateComponent, AttemptPacifiedAttackEvent>(OnAttemptPacifiedAttack);
- SubscribeLocalEvent<MobStateComponent, UnbuckleAttemptEvent>(OnUnbuckleAttempt);
- }
- private void OnUnbuckleAttempt(Entity<MobStateComponent> ent, ref UnbuckleAttemptEvent args)
- {
- // TODO is this necessary?
- // Shouldn't the interaction have already been blocked by a general interaction check?
- if (args.User == ent.Owner && IsIncapacitated(ent))
- args.Cancelled = true;
- }
- private void CheckConcious(Entity<MobStateComponent> ent, ref ConsciousAttemptEvent args)
- {
- switch (ent.Comp.CurrentState)
- {
- case MobState.Dead:
- case MobState.Critical:
- args.Cancelled = true;
- break;
- }
- }
- private void OnStateExitSubscribers(EntityUid target, MobStateComponent component, MobState state)
- {
- switch (state)
- {
- case MobState.Alive:
- //unused
- break;
- case MobState.Critical:
- _standing.Stand(target);
- break;
- case MobState.Dead:
- RemComp<CollisionWakeComponent>(target);
- _standing.Stand(target);
- break;
- case MobState.Invalid:
- //unused
- break;
- default:
- throw new NotImplementedException();
- }
- }
- private void OnStateEnteredSubscribers(EntityUid target, MobStateComponent component, MobState state)
- {
- // All of the state changes here should already be networked, so we do nothing if we are currently applying a
- // server state.
- if (_timing.ApplyingState)
- return;
- _blocker.UpdateCanMove(target); //update movement anytime a state changes
- switch (state)
- {
- case MobState.Alive:
- _standing.Stand(target);
- _appearance.SetData(target, MobStateVisuals.State, MobState.Alive);
- break;
- case MobState.Critical:
- _standing.Down(target);
- _appearance.SetData(target, MobStateVisuals.State, MobState.Critical);
- break;
- case MobState.Dead:
- EnsureComp<CollisionWakeComponent>(target);
- _standing.Down(target);
- _appearance.SetData(target, MobStateVisuals.State, MobState.Dead);
- break;
- case MobState.Invalid:
- //unused;
- break;
- default:
- throw new NotImplementedException();
- }
- }
- #region Event Subscribers
- private void OnSleepAttempt(EntityUid target, MobStateComponent component, ref TryingToSleepEvent args)
- {
- if (IsDead(target, component))
- args.Cancelled = true;
- }
- private void OnGettingStripped(EntityUid target, MobStateComponent component, BeforeGettingStrippedEvent args)
- {
- // Incapacitated or dead targets get stripped two or three times as fast. Makes stripping corpses less tedious.
- if (IsDead(target, component))
- args.Multiplier /= 3;
- else if (IsCritical(target, component))
- args.Multiplier /= 2;
- }
- private void OnSpeakAttempt(EntityUid uid, MobStateComponent component, SpeakAttemptEvent args)
- {
- if (HasComp<AllowNextCritSpeechComponent>(uid))
- {
- RemCompDeferred<AllowNextCritSpeechComponent>(uid);
- return;
- }
- CheckAct(uid, component, args);
- }
- private void CheckAct(EntityUid target, MobStateComponent component, CancellableEntityEventArgs args)
- {
- switch (component.CurrentState)
- {
- case MobState.Dead:
- case MobState.Critical:
- args.Cancel();
- break;
- }
- }
- private void OnEquipAttempt(EntityUid target, MobStateComponent component, IsEquippingAttemptEvent args)
- {
- // is this a self-equip, or are they being stripped?
- if (args.Equipee == target)
- CheckAct(target, component, args);
- }
- private void OnUnequipAttempt(EntityUid target, MobStateComponent component, IsUnequippingAttemptEvent args)
- {
- // is this a self-equip, or are they being stripped?
- if (args.Unequipee == target)
- CheckAct(target, component, args);
- }
- private void OnCombatModeShouldHandInteract(EntityUid uid, MobStateComponent component, ref CombatModeShouldHandInteractEvent args)
- {
- // Disallow empty-hand-interacting in combat mode
- // for non-dead mobs
- if (!IsDead(uid, component))
- args.Cancelled = true;
- }
- private void OnAttemptPacifiedAttack(Entity<MobStateComponent> ent, ref AttemptPacifiedAttackEvent args)
- {
- args.Cancelled = true;
- }
- #endregion
- }
|