EscapeOperator.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. using System.Threading;
  2. using System.Threading.Tasks;
  3. using Content.Server.NPC.Components;
  4. using Content.Server.Storage.EntitySystems;
  5. using Content.Shared.CombatMode;
  6. using Robust.Server.Containers;
  7. namespace Content.Server.NPC.HTN.PrimitiveTasks.Operators.Combat.Melee;
  8. public sealed partial class EscapeOperator : HTNOperator, IHtnConditionalShutdown
  9. {
  10. [Dependency] private readonly IEntityManager _entManager = default!;
  11. private ContainerSystem _container = default!;
  12. private EntityStorageSystem _entityStorage = default!;
  13. [DataField("shutdownState")]
  14. public HTNPlanState ShutdownState { get; private set; } = HTNPlanState.TaskFinished;
  15. [DataField("targetKey", required: true)]
  16. public string TargetKey = default!;
  17. public override void Initialize(IEntitySystemManager sysManager)
  18. {
  19. base.Initialize(sysManager);
  20. _container = sysManager.GetEntitySystem<ContainerSystem>();
  21. _entityStorage = sysManager.GetEntitySystem<EntityStorageSystem>();
  22. }
  23. public override void Startup(NPCBlackboard blackboard)
  24. {
  25. base.Startup(blackboard);
  26. var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
  27. var target = blackboard.GetValue<EntityUid>(TargetKey);
  28. if (_entityStorage.TryOpenStorage(owner, target))
  29. {
  30. TaskShutdown(blackboard, HTNOperatorStatus.Finished);
  31. return;
  32. }
  33. var melee = _entManager.EnsureComponent<NPCMeleeCombatComponent>(owner);
  34. melee.MissChance = blackboard.GetValueOrDefault<float>(NPCBlackboard.MeleeMissChance, _entManager);
  35. melee.Target = target;
  36. }
  37. public override async Task<(bool Valid, Dictionary<string, object>? Effects)> Plan(NPCBlackboard blackboard,
  38. CancellationToken cancelToken)
  39. {
  40. var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
  41. if (!blackboard.TryGetValue<EntityUid>(TargetKey, out var target, _entManager))
  42. {
  43. return (false, null);
  44. }
  45. if (!_container.IsEntityInContainer(owner))
  46. {
  47. return (false, null);
  48. }
  49. if (_entityStorage.TryOpenStorage(owner, target))
  50. {
  51. return (false, null);
  52. }
  53. return (true, null);
  54. }
  55. public void ConditionalShutdown(NPCBlackboard blackboard)
  56. {
  57. var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
  58. _entManager.System<SharedCombatModeSystem>().SetInCombatMode(owner, false);
  59. _entManager.RemoveComponent<NPCMeleeCombatComponent>(owner);
  60. blackboard.Remove<EntityUid>(TargetKey);
  61. }
  62. public override void TaskShutdown(NPCBlackboard blackboard, HTNOperatorStatus status)
  63. {
  64. base.TaskShutdown(blackboard, status);
  65. ConditionalShutdown(blackboard);
  66. }
  67. public override void PlanShutdown(NPCBlackboard blackboard)
  68. {
  69. base.PlanShutdown(blackboard);
  70. ConditionalShutdown(blackboard);
  71. }
  72. public override HTNOperatorStatus Update(NPCBlackboard blackboard, float frameTime)
  73. {
  74. base.Update(blackboard, frameTime);
  75. var owner = blackboard.GetValue<EntityUid>(NPCBlackboard.Owner);
  76. HTNOperatorStatus status;
  77. if (_entManager.TryGetComponent<NPCMeleeCombatComponent>(owner, out var combat) &&
  78. blackboard.TryGetValue<EntityUid>(TargetKey, out var target, _entManager))
  79. {
  80. combat.Target = target;
  81. // Success
  82. if (!_container.IsEntityInContainer(owner))
  83. {
  84. status = HTNOperatorStatus.Finished;
  85. }
  86. else
  87. {
  88. if (_entityStorage.TryOpenStorage(owner, target))
  89. {
  90. status = HTNOperatorStatus.Finished;
  91. }
  92. else
  93. {
  94. switch (combat.Status)
  95. {
  96. case CombatStatus.TargetOutOfRange:
  97. case CombatStatus.Normal:
  98. status = HTNOperatorStatus.Continuing;
  99. break;
  100. default:
  101. status = HTNOperatorStatus.Failed;
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. else
  108. {
  109. status = HTNOperatorStatus.Failed;
  110. }
  111. // Mark it as finished to continue the plan.
  112. if (status == HTNOperatorStatus.Continuing && ShutdownState == HTNPlanState.PlanFinished)
  113. {
  114. status = HTNOperatorStatus.Finished;
  115. }
  116. return status;
  117. }
  118. }