behaviour.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. # coding: utf-8
  2. import random
  3. import time
  4. import typing
  5. from synergine2.simulation import Event
  6. from synergine2.simulation import disable_when
  7. from synergine2.simulation import config_value
  8. from opencombat.const import COLLECTION_ALIVE
  9. from opencombat.simulation.base import AliveSubjectBehaviour
  10. from opencombat.simulation.event import NoLongerVisibleOpponent
  11. from opencombat.simulation.event import FireEvent
  12. from opencombat.simulation.event import DieEvent
  13. from opencombat.simulation.event import NewVisibleOpponent
  14. from opencombat.simulation.mechanism import OpponentVisibleMechanism
  15. class LookAroundBehaviour(AliveSubjectBehaviour):
  16. """
  17. Behaviour who permit to reference visible things like enemies
  18. """
  19. visible_mechanism = OpponentVisibleMechanism
  20. use = [visible_mechanism]
  21. def __init__(self, *args, **kwargs) -> None:
  22. super().__init__(*args, **kwargs)
  23. self._seconds_frequency = float(self.config.resolve('game.look_around.frequency'))
  24. @property
  25. def seconds_frequency(self) -> typing.Optional[float]:
  26. return self._seconds_frequency
  27. def action(self, data) -> [Event]:
  28. new_visible_subject_events = []
  29. no_longer_visible_subject_events = []
  30. for no_longer_visible_subject_id in data['no_longer_visible_subject_ids']:
  31. no_longer_visible_subject_events.append(NoLongerVisibleOpponent(
  32. observer_subject_id=self.subject.id,
  33. observed_subject_id=no_longer_visible_subject_id,
  34. ))
  35. self.subject.visible_opponent_ids.remove(no_longer_visible_subject_id)
  36. for new_visible_subject_id in data['new_visible_subject_ids']:
  37. new_visible_subject_events.append(NewVisibleOpponent(
  38. observer_subject_id=self.subject.id,
  39. observed_subject_id=new_visible_subject_id,
  40. ))
  41. self.subject.visible_opponent_ids.append(new_visible_subject_id)
  42. return new_visible_subject_events + no_longer_visible_subject_events
  43. @disable_when(config_value('_runtime.placement_mode'))
  44. def run(self, data):
  45. visible_subjects = data[self.visible_mechanism]['visible_subjects']
  46. visible_subject_ids = [s.id for s in visible_subjects]
  47. new_visible_subject_ids = []
  48. no_longer_visible_subject_ids = []
  49. for subject_id in self.subject.visible_opponent_ids:
  50. if subject_id not in visible_subject_ids:
  51. no_longer_visible_subject_ids.append(subject_id)
  52. for subject in visible_subjects:
  53. if subject.id not in self.subject.visible_opponent_ids:
  54. new_visible_subject_ids.append(subject.id)
  55. return {
  56. 'new_visible_subject_ids': new_visible_subject_ids,
  57. 'no_longer_visible_subject_ids': no_longer_visible_subject_ids,
  58. }
  59. class EngageOpponent(AliveSubjectBehaviour):
  60. visible_mechanism = OpponentVisibleMechanism
  61. use = [visible_mechanism]
  62. def __init__(self, *args, **kwargs) -> None:
  63. super().__init__(*args, **kwargs)
  64. self._seconds_frequency = float(self.config.resolve('game.engage.frequency'))
  65. @property
  66. def seconds_frequency(self) -> typing.Optional[float]:
  67. return self._seconds_frequency
  68. def action(self, data) -> [Event]:
  69. kill = data['kill']
  70. target_subject_id = data['target_subject_id']
  71. target_subject = self.simulation.subjects.index[target_subject_id]
  72. target_position = data['target_position']
  73. events = list()
  74. events.append(FireEvent(
  75. shooter_subject_id=self.subject.id,
  76. target_position=target_position,
  77. ))
  78. # Must be check if target is not already dead (killed same cycle)
  79. if kill and COLLECTION_ALIVE in target_subject.collections:
  80. DieEvent.apply_subject_death(target_subject)
  81. events.append(DieEvent(
  82. shooter_subject_id=self.subject.id,
  83. shoot_subject_id=target_subject_id,
  84. ))
  85. return events
  86. @disable_when(config_value('_runtime.placement_mode'))
  87. def run(self, data):
  88. visible_subjects = data[self.visible_mechanism]['visible_subjects']
  89. if not visible_subjects:
  90. return
  91. # Manage selected target (can change, better visibility, etc ...)
  92. # Manage weapon munition to be able to fire
  93. # Manage fear/under fire ...
  94. # Manage weapon reload time
  95. # For dev fun, don't fire at random
  96. if random.randint(1, 3) == -1:
  97. # Executed but decided to fail
  98. self.last_execution_time = time.time()
  99. return False
  100. target_subject = random.choice(visible_subjects)
  101. kill = random.randint(0, 100) >= 75
  102. # Manage fire miss or touch (visibility, fear, opponent hiding, etc ...)
  103. return {
  104. 'kill': kill,
  105. 'target_subject_id': target_subject.id,
  106. 'target_position': target_subject.position,
  107. }