MobStateSystem.StateMachine.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. using Content.Shared.Database;
  2. using Content.Shared.Mobs.Components;
  3. namespace Content.Shared.Mobs.Systems;
  4. public partial class MobStateSystem
  5. {
  6. #region Public API
  7. /// <summary>
  8. /// Check if an Entity can be set to a particular MobState
  9. /// </summary>
  10. /// <param name="entity">Target Entity</param>
  11. /// <param name="mobState">MobState to check</param>
  12. /// <param name="component">MobState Component owned by the target</param>
  13. /// <returns>If the entity can be set to that MobState</returns>
  14. public bool HasState(EntityUid entity, MobState mobState, MobStateComponent? component = null)
  15. {
  16. return _mobStateQuery.Resolve(entity, ref component, false) &&
  17. component.AllowedStates.Contains(mobState);
  18. }
  19. /// <summary>
  20. /// Run a MobState update check. This will trigger update events if the state has been changed.
  21. /// </summary>
  22. /// <param name="entity">Target Entity we want to change the MobState of</param>
  23. /// <param name="component">MobState Component attached to the entity</param>
  24. /// <param name="origin">Entity that caused the state update (if applicable)</param>
  25. public void UpdateMobState(EntityUid entity, MobStateComponent? component = null, EntityUid? origin = null)
  26. {
  27. if (!_mobStateQuery.Resolve(entity, ref component))
  28. return;
  29. var ev = new UpdateMobStateEvent {Target = entity, Component = component, Origin = origin};
  30. RaiseLocalEvent(entity, ref ev);
  31. ChangeState(entity, component, ev.State, origin: origin);
  32. }
  33. /// <summary>
  34. /// Change the MobState without triggering UpdateMobState events.
  35. /// WARNING: use this sparingly when you need to override other systems (MobThresholds)
  36. /// </summary>
  37. /// <param name="entity">Target Entity we want to change the MobState of</param>
  38. /// <param name="mobState">The new MobState we want to set</param>
  39. /// <param name="component">MobState Component attached to the entity</param>
  40. /// <param name="origin">Entity that caused the state update (if applicable)</param>
  41. public void ChangeMobState(EntityUid entity, MobState mobState, MobStateComponent? component = null,
  42. EntityUid? origin = null)
  43. {
  44. if (!_mobStateQuery.Resolve(entity, ref component))
  45. return;
  46. ChangeState(entity, component, mobState, origin: origin);
  47. }
  48. #endregion
  49. #region Virtual API
  50. /// <summary>
  51. /// Called when a new MobState is entered.
  52. /// </summary>
  53. /// <param name="entity">The owner of the MobState Component</param>
  54. /// <param name="component">MobState Component owned by the target</param>
  55. /// <param name="state">The new MobState</param>
  56. protected virtual void OnEnterState(EntityUid entity, MobStateComponent component, MobState state)
  57. {
  58. OnStateEnteredSubscribers(entity, component, state);
  59. }
  60. /// <summary>
  61. /// Called when this entity changes MobState
  62. /// </summary>
  63. /// <param name="entity">The owner of the MobState Component</param>
  64. /// <param name="component">MobState Component owned by the target</param>
  65. /// <param name="oldState">The previous MobState</param>
  66. /// <param name="newState">The new MobState</param>
  67. protected virtual void OnStateChanged(EntityUid entity, MobStateComponent component, MobState oldState,
  68. MobState newState)
  69. {
  70. }
  71. /// <summary>
  72. /// Called when a new MobState is exited.
  73. /// </summary>
  74. /// <param name="entity">The owner of the MobState Component</param>
  75. /// <param name="component">MobState Component owned by the target</param>
  76. /// <param name="state">The old MobState</param>
  77. protected virtual void OnExitState(EntityUid entity, MobStateComponent component, MobState state)
  78. {
  79. OnStateExitSubscribers(entity, component, state);
  80. }
  81. #endregion
  82. #region Private Implementation
  83. //Actually change the MobState
  84. private void ChangeState(EntityUid target, MobStateComponent component, MobState newState, EntityUid? origin = null)
  85. {
  86. var oldState = component.CurrentState;
  87. //make sure we are allowed to enter the new state
  88. if (oldState == newState || !component.AllowedStates.Contains(newState))
  89. return;
  90. OnExitState(target, component, oldState);
  91. component.CurrentState = newState;
  92. OnEnterState(target, component, newState);
  93. var ev = new MobStateChangedEvent(target, component, oldState, newState, origin);
  94. OnStateChanged(target, component, oldState, newState);
  95. RaiseLocalEvent(target, ev, true);
  96. _adminLogger.Add(LogType.Damaged, oldState == MobState.Alive ? LogImpact.Low : LogImpact.Medium,
  97. $"{ToPrettyString(target):user} state changed from {oldState} to {newState}");
  98. Dirty(target, component);
  99. }
  100. #endregion
  101. }
  102. /// <summary>
  103. /// Event that gets triggered when we want to update the mobstate. This allows for systems to override MobState changes
  104. /// </summary>
  105. /// <param name="Target">The Entity whose MobState is changing</param>
  106. /// <param name="Component">The MobState Component owned by the Target</param>
  107. /// <param name="State">The new MobState we want to set</param>
  108. /// <param name="Origin">Entity that caused the state update (if applicable)</param>
  109. [ByRefEvent]
  110. public record struct UpdateMobStateEvent(EntityUid Target, MobStateComponent Component, MobState State,
  111. EntityUid? Origin = null);