physics.py 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  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: Objets/IT qui compute les couts de déplacement
  21. if not tile.property('traversable_by_man'):
  22. # TODO: revoir la lib disjkstar because les mecs traverses quand meme ...
  23. return 100
  24. return 1.0
  25. class TilePhysics(TMXPhysics):
  26. tmx_map_class = TileMap
  27. move_cost_computer_class = TileMoveCostComputer
  28. matrixes_configuration = {
  29. 'visibility': [
  30. 'height',
  31. 'opacity',
  32. ]
  33. }
  34. def get_visibility_obstacle(
  35. self,
  36. subject: XYZSubject,
  37. to_position: typing.Tuple[int, int],
  38. matrix_name: str,
  39. opacity_property_name: str='opacity',
  40. ) -> typing.Union[None, typing.Tuple[int, int]]:
  41. """
  42. Return grid position obstacle if any between given subject and given to_position
  43. :param subject: Subject observer
  44. :param to_position: position to observe
  45. :param matrix_name: matrix name to use
  46. :param opacity_property_name: name of property containing opacity property
  47. :return: obstacle grid position or None if not
  48. """
  49. from_x, from_y = subject.position
  50. path_positions = self.matrixes.get_path_positions(from_=(from_x, from_y), to=to_position)
  51. path_opacities = self.matrixes.get_values_for_path(
  52. matrix_name,
  53. path_positions=path_positions,
  54. value_name=opacity_property_name,
  55. )
  56. # FIXME: This algo is not ok, it is for test
  57. actual_opacity = 0
  58. for i, path_opacity in enumerate(path_opacities):
  59. actual_opacity += path_opacity
  60. if actual_opacity >= 100:
  61. return path_positions[i]
  62. return None
  63. def subject_see_subject(self, observer: 'TileSubject', observed: 'TileSubject') -> bool:
  64. return not bool(self.get_visibility_obstacle(
  65. observer,
  66. observed.position,
  67. matrix_name='visibility',
  68. ))