behaviour.py 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. # coding: utf-8
  2. from synergine2.simulation import SubjectBehaviour, SimulationMechanism, SimulationBehaviour
  3. from synergine2.simulation import Event
  4. from synergine2.utils import ChunkManager
  5. from synergine2.xyz_utils import get_around_positions_of_positions
  6. class GrassGrownUp(Event):
  7. def __init__(self, subject_id, density, *args, **kwargs):
  8. super().__init__(*args, **kwargs)
  9. self.subject_id = subject_id
  10. self.density = density
  11. def repr_debug(self) -> str:
  12. return '{}: subject_id:{}, density:{}'.format(
  13. self.__class__.__name__,
  14. self.subject_id,
  15. self.density,
  16. )
  17. class GrassSpawn(Event):
  18. def __init__(self, subject_id, position, density, *args, **kwargs):
  19. super().__init__(*args, **kwargs)
  20. self.subject_id = subject_id
  21. self.position = position
  22. self.density = density
  23. def repr_debug(self) -> str:
  24. return '{}: subject_id:{}, position:{}, density:{}'.format(
  25. self.__class__.__name__,
  26. self.subject_id,
  27. self.position,
  28. self.density,
  29. )
  30. class GrassSpotablePositionsMechanism(SimulationMechanism):
  31. parallelizable = True
  32. def run(self, process_number: int=None, process_count: int=None):
  33. chunk_manager = ChunkManager(process_count)
  34. positions = list(self.simulation.subjects.grass_xyz.keys())
  35. positions_chunks = chunk_manager.make_chunks(positions)
  36. spotables = []
  37. for position in positions_chunks[process_number]:
  38. arounds = get_around_positions_of_positions(position)
  39. from_subject = self.simulation.subjects.grass_xyz[position]
  40. around_data = {
  41. 'from_subject': from_subject,
  42. 'around': [],
  43. }
  44. for around in arounds:
  45. if around not in self.simulation.subjects.grass_xyz:
  46. around_data['around'].append(around)
  47. if around_data['around']:
  48. spotables.append(around_data)
  49. return spotables
  50. class GrowUp(SubjectBehaviour):
  51. frequency = 20
  52. def run(self, data):
  53. return True
  54. def action(self, data) -> [Event]:
  55. self.subject.density += 1
  56. return [GrassGrownUp(
  57. self.subject.id,
  58. self.subject.density,
  59. )]
  60. class GrassSpawnBehaviour(SimulationBehaviour):
  61. frequency = 100
  62. use = [GrassSpotablePositionsMechanism]
  63. def run(self, data):
  64. spawns = []
  65. for around_data in data[GrassSpotablePositionsMechanism]:
  66. from_subject = around_data['from_subject']
  67. arounds = around_data['around']
  68. if from_subject.density >= 40:
  69. spawns.extend(arounds)
  70. return spawns
  71. @classmethod
  72. def merge_data(cls, new_data, start_data=None):
  73. start_data = start_data or []
  74. start_data.extend(new_data)
  75. return start_data
  76. def action(self, data) -> [Event]:
  77. from sandbox.engulf.subject import Grass # cyclic
  78. events = []
  79. for position in data:
  80. if position not in list(self.simulation.subjects.grass_xyz.keys()):
  81. new_grass = Grass(
  82. self.simulation,
  83. position=position,
  84. density=20,
  85. )
  86. self.simulation.subjects.append(new_grass)
  87. events.append(GrassSpawn(
  88. new_grass.id,
  89. new_grass.position,
  90. new_grass.density,
  91. ))
  92. return events