image.py 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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.gui.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. class TileImageCacheManager(ImageCacheManager):
  45. def __init__(
  46. self,
  47. actor: 'BaseActor',
  48. config: Config,
  49. ) -> None:
  50. super().__init__(actor, config)
  51. self.firing_cache = FiringImageCache()
  52. from opencombat.gui.actor import BaseActor
  53. self.actor = typing.cast(BaseActor, self.actor)
  54. self.path_manager = PathManager(
  55. self.config.resolve('global.include_path.graphics'),
  56. )
  57. def build(self) -> None:
  58. super().build()
  59. self.build_firing()
  60. def build_firing(self) -> None:
  61. for mode in self.actor.get_modes():
  62. mode_image_path = self.actor.default_image_path # FIXME !
  63. mode_image = Image.open(self.path_manager.path(mode_image_path))
  64. for weapon in self.actor.weapons:
  65. try:
  66. images = self.actor.weapon_image_applier.get_firing_image(
  67. mode=mode,
  68. weapon_type=weapon,
  69. )
  70. except UnknownWeapon:
  71. images = [Image.open(self.path_manager.path('empty.png'))]
  72. for position in range(len(images)):
  73. position_image = images[position]
  74. final_image = mode_image.copy()
  75. final_image.paste(
  76. position_image,
  77. (0, 0),
  78. position_image,
  79. )
  80. self.firing_cache.add(mode, weapon, final_image)