physics.py 2.4KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. # coding: utf-8
  2. import typing
  3. from opencombat.simulation.tmx import TileMap
  4. from opencombat.simulation.tmx import TerrainTile
  5. from synergine2_xyz.physics import MoveCostComputer
  6. from synergine2_xyz.physics import TMXPhysics
  7. from synergine2_xyz.subjects import XYZSubject
  8. if typing.TYPE_CHECKING:
  9. from opencombat.simulation.base import BaseSubject
  10. from opencombat.simulation.subject import TileSubject
  11. class TileMoveCostComputer(MoveCostComputer):
  12. def compute_move_cost(
  13. self,
  14. subject: 'BaseSubject',
  15. tile: TerrainTile,
  16. previous_node: str,
  17. next_node: str,
  18. unknown,
  19. ) -> float:
  20. # TODO #MoveCost: Write move cost system
  21. if not tile.property('traversable_by_man'):
  22. return 100
  23. return 1.0
  24. class TilePhysics(TMXPhysics):
  25. tmx_map_class = TileMap
  26. move_cost_computer_class = TileMoveCostComputer
  27. matrixes_configuration = {
  28. 'visibility': [
  29. 'height',
  30. 'opacity',
  31. ]
  32. }
  33. def get_visibility_obstacle(
  34. self,
  35. subject: XYZSubject,
  36. to_position: typing.Tuple[int, int],
  37. matrix_name: str,
  38. opacity_property_name: str='opacity',
  39. ) -> typing.Union[None, typing.Tuple[int, int]]:
  40. """
  41. Return grid position obstacle if any between given subject and given to_position
  42. :param subject: Subject observer
  43. :param to_position: position to observe
  44. :param matrix_name: matrix name to use
  45. :param opacity_property_name: name of property containing opacity property
  46. :return: obstacle grid position or None if not
  47. """
  48. from_x, from_y = subject.position
  49. path_positions = self.matrixes.get_path_positions(from_=(from_x, from_y), to=to_position)
  50. path_opacities = self.matrixes.get_values_for_path(
  51. matrix_name,
  52. path_positions=path_positions,
  53. value_name=opacity_property_name,
  54. )
  55. # TODO #Visibility: Write visibility system
  56. actual_opacity = 0
  57. for i, path_opacity in enumerate(path_opacities):
  58. actual_opacity += path_opacity
  59. if actual_opacity >= 100:
  60. return path_positions[i]
  61. return None
  62. def subject_see_subject(self, observer: 'TileSubject', observed: 'TileSubject') -> bool:
  63. return not bool(self.get_visibility_obstacle(
  64. observer,
  65. observed.position,
  66. matrix_name='visibility',
  67. ))