sector.py 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. # Flexlay - A Generic 2D Game Editor
  2. # Copyright (C) 2014 Ingo Ruhnke <grumbel@gmail.com>
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. from typing import Any, Optional, TYPE_CHECKING
  17. import logging
  18. from flexlay.object_layer import ObjectLayer
  19. from flexlay.objmap_tilemap_object import ObjMapTilemapObject
  20. from flexlay.editor_map import EditorMap
  21. from flexlay.math import Point, Pointf, Size, Rectf
  22. from flexlay.util.sexpr_writer import SExprWriter
  23. from supertux.gameobjs import Camera, SpawnPoint
  24. from supertux.tilemap import SuperTuxTileMap
  25. from supertux.gameobj_factor import supertux_gameobj_factory
  26. if TYPE_CHECKING:
  27. from supertux.level import Level
  28. class Sector:
  29. def __init__(self, parent: 'Level') -> None:
  30. self.parent: Level = parent
  31. self.name: str = ""
  32. self.music: str = ""
  33. self.gravity: float = 10.0
  34. self.init_script: str = ""
  35. self.ambient_light: list[float] = [1, 1, 1]
  36. self.width: int = 0
  37. self.height: int = 0
  38. self.tilemaps: list[SuperTuxTileMap] = []
  39. self.camera: Optional[Camera] = None
  40. self.object_layer: Optional[ObjectLayer] = None
  41. # self.sketch = None
  42. self.editormap: Optional[EditorMap] = None
  43. def get_some_solid_tilemap(self) -> SuperTuxTileMap:
  44. for tilemap in self.tilemaps:
  45. if tilemap.solid:
  46. return tilemap
  47. return self.tilemaps[0]
  48. def get_level(self) -> 'Level':
  49. return self.parent
  50. def resize(self, size: Size, pos: Point) -> None:
  51. self.width = size.width
  52. self.height = size.height
  53. for tilemap in self.tilemaps:
  54. tilemap.resize(size, pos)
  55. assert self.object_layer is not None
  56. for obj in self.object_layer.objects:
  57. p = obj.get_pos() + 32 * pos.to_f()
  58. obj.set_pos(p)
  59. def new_from_size(self, name: str, width: int, height: int) -> 'Sector':
  60. self.name = name
  61. self.music = ""
  62. self.gravity = 10.0
  63. self.width = width
  64. self.height = height
  65. self.tilemaps.append(SuperTuxTileMap.from_size(self.width, self.height, "background", -100, False))
  66. self.tilemaps.append(SuperTuxTileMap.from_size(self.width, self.height, "interactive", 0, True))
  67. self.tilemaps.append(SuperTuxTileMap.from_size(self.width, self.height, "foreground", 100, False))
  68. self.object_layer = ObjectLayer()
  69. self.editormap = EditorMap()
  70. # self.editormap.set_background_color(Color(255, 255, 255))
  71. for tilemap in self.tilemaps:
  72. # self.editormap.add_layer(tilemap.tilemap_layer)
  73. assert self.object_layer is not None
  74. assert tilemap.tilemap_layer is not None
  75. self.object_layer.add_object(ObjMapTilemapObject(tilemap.tilemap_layer, tilemap))
  76. spawn = SpawnPoint()
  77. spawn.properties[0].value = "main"
  78. spawn_x = 5 if self.width > 5 else 0
  79. spawn_y = self.height * 3 / 4
  80. assert spawn.objmap_object is not None
  81. spawn.objmap_object.pos = Pointf(spawn_x * 32, spawn_y * 32)
  82. assert self.object_layer is not None
  83. assert spawn.objmap_object is not None
  84. self.object_layer.add_object(spawn.objmap_object)
  85. self.camera = Camera()
  86. assert self.camera.objmap_object is not None
  87. self.object_layer.add_object(self.camera.objmap_object)
  88. self.editormap.add_layer(self.object_layer)
  89. # self.editormap.add_layer(self.sketch)
  90. self.editormap.metadata = self
  91. return self
  92. def load_v2(self, data: list[Any]) -> None:
  93. self.name = "<No Name>"
  94. self.music = ""
  95. self.init_script = ""
  96. self.gravity = 10.0
  97. self.width = 0
  98. self.height = 0
  99. self.objects = []
  100. self.tilemaps = []
  101. self.object_layer = ObjectLayer()
  102. self.editormap = EditorMap()
  103. self.editormap.add_layer(self.object_layer)
  104. for i in data:
  105. (name, data) = i[0], i[1:]
  106. if name == "name":
  107. self.name = data[0]
  108. elif name == "ambient-light":
  109. self.ambient_light = data
  110. elif name == "gravity":
  111. self.gravity = data[0]
  112. elif name == "music":
  113. self.music = data[0]
  114. elif name == "init-script":
  115. self.init_script = data[0]
  116. elif name == "tilemap":
  117. tilemap = SuperTuxTileMap.from_sexpr(data)
  118. self.tilemaps.append(tilemap)
  119. # self.editormap.add_layer(tilemap.tilemap_layer)
  120. # GRUMBEL: incorrect
  121. if tilemap.solid:
  122. assert tilemap.tilemap_layer is not None
  123. self.width = max(self.width, tilemap.tilemap_layer.width)
  124. self.height = max(self.height, tilemap.tilemap_layer.height)
  125. self.editormap.set_bounding_rect(Rectf(0, 0, self.width * 32, self.height * 32))
  126. assert tilemap.tilemap_layer is not None
  127. self.object_layer.add_object(ObjMapTilemapObject(tilemap.tilemap_layer, tilemap))
  128. else:
  129. obj = supertux_gameobj_factory.create_gameobj(name, data)
  130. if obj is None:
  131. logging.error("Couldn't resolve object type: " + name)
  132. logging.warning("Sector: Unhandled tag: " + name)
  133. else:
  134. if isinstance(obj, Camera):
  135. self.camera = obj
  136. self.objects.append(obj)
  137. assert obj.objmap_object is not None
  138. self.object_layer.add_object(obj.objmap_object)
  139. self.editormap.metadata = self
  140. def write(self, writer: SExprWriter) -> None:
  141. writer.write_string("name", self.name)
  142. if self.music:
  143. writer.write_string("music", self.music)
  144. if self.gravity != 10.0:
  145. writer.write_float("gravity", self.gravity)
  146. if self.init_script:
  147. writer.write_string("init-script", self.init_script)
  148. writer.write_rgb("ambient-light", self.ambient_light)
  149. assert self.object_layer is not None
  150. for obj in self.object_layer.get_objects():
  151. obj.metadata.write(writer, obj)
  152. # for tilemap in self.tilemaps:
  153. # tilemap.write(writer)
  154. # EOF #