image.py 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # coding: utf-8
  2. import typing
  3. from PIL import Image
  4. from synergine2.config import Config
  5. from synergine2_cocos2d.util import PathManager
  6. from synergine2_xyz.image import ImageCache
  7. from synergine2_xyz.image import ImageCacheManager
  8. from synergine2_xyz.exception import UnknownAnimationIndex
  9. from opencombat.exception import UnknownWeapon
  10. from opencombat.exception import UnknownFiringAnimation
  11. if typing.TYPE_CHECKING:
  12. from opencombat.game.actor import BaseActor
  13. class FiringImageCache(ImageCache):
  14. def add(
  15. self,
  16. mode: str,
  17. weapon: str,
  18. image: Image.Image,
  19. ) -> None:
  20. self.cache.setdefault(mode, {}).setdefault(weapon, []).append(image)
  21. def get(
  22. self,
  23. mode: str,
  24. weapon: str,
  25. position: int,
  26. ) -> Image.Image:
  27. try:
  28. return self.cache[mode][weapon][position]
  29. except KeyError:
  30. raise UnknownFiringAnimation(
  31. 'Unknown firing animation for mode "{}" and weapon "{}"'.format(
  32. mode,
  33. weapon,
  34. )
  35. )
  36. except IndexError:
  37. raise UnknownAnimationIndex(
  38. 'Unknown animation index "{}" for mode "{}" and weapon "{}"'.format(
  39. position,
  40. mode,
  41. weapon,
  42. ),
  43. )
  44. def get_list(
  45. self,
  46. mode: str,
  47. weapon: str,
  48. ) -> typing.List[Image.Image]:
  49. try:
  50. return self.cache[mode][weapon]
  51. except KeyError:
  52. raise UnknownFiringAnimation(
  53. 'Unknown firing animation for mode "{}" and weapon "{}"'.format(
  54. mode,
  55. weapon,
  56. )
  57. )
  58. class TileImageCacheManager(ImageCacheManager):
  59. def __init__(
  60. self,
  61. actor: 'BaseActor',
  62. config: Config,
  63. ) -> None:
  64. super().__init__(actor, config)
  65. self.firing_cache = FiringImageCache()
  66. from opencombat.game.actor import BaseActor
  67. self.actor = typing.cast(BaseActor, self.actor)
  68. self.path_manager = PathManager(
  69. self.config.resolve('global.include_path.graphics'),
  70. )
  71. def build(self) -> None:
  72. super().build()
  73. self.build_firing()
  74. def build_firing(self) -> None:
  75. for mode in self.actor.get_modes():
  76. mode_image_path = self.actor.get_mode_image_path(mode)
  77. mode_image = Image.open(self.path_manager.path(mode_image_path))
  78. for weapon in self.actor.weapons:
  79. try:
  80. images = self.actor.weapon_image_applier.get_firing_image(
  81. mode=mode,
  82. weapon_type=weapon,
  83. )
  84. except UnknownWeapon:
  85. images = [Image.open(self.path_manager.path('empty.png'))]
  86. for position in range(len(images)):
  87. position_image = images[position]
  88. final_image = mode_image.copy()
  89. final_image.paste(
  90. position_image,
  91. (0, 0),
  92. position_image,
  93. )
  94. self.firing_cache.add(mode, weapon, final_image)