TerrainUndo.gd 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. @tool
  2. extends Node
  3. var action_index := 0
  4. var action_count := 0
  5. var _current_action_index := 0
  6. var _current_action_count := 0
  7. func create_tile_restore_point(undo_manager: EditorUndoRedoManager, tm: TileMapLayer, cells: Array, and_surrounding_cells: bool = true) -> void:
  8. if and_surrounding_cells:
  9. cells = BetterTerrain._widen(tm, cells)
  10. var restore := []
  11. for c in cells:
  12. restore.append([
  13. c,
  14. tm.get_cell_source_id(c),
  15. tm.get_cell_atlas_coords(c),
  16. tm.get_cell_alternative_tile(c)
  17. ])
  18. undo_manager.add_undo_method(self, &"restore_tiles", tm, restore)
  19. func create_tile_restore_point_area(undo_manager: EditorUndoRedoManager, tm: TileMapLayer, area: Rect2i, and_surrounding_cells: bool = true) -> void:
  20. area.end += Vector2i.ONE
  21. var restore := []
  22. for y in range(area.position.y, area.end.y):
  23. for x in range(area.position.x, area.end.x):
  24. var c := Vector2i(x, y)
  25. restore.append([
  26. c,
  27. tm.get_cell_source_id(c),
  28. tm.get_cell_atlas_coords(c),
  29. tm.get_cell_alternative_tile(c)
  30. ])
  31. undo_manager.add_undo_method(self, &"restore_tiles", tm, restore)
  32. if !and_surrounding_cells:
  33. return
  34. var edges := []
  35. for x in range(area.position.x, area.end.x):
  36. edges.append(Vector2i(x, area.position.y))
  37. edges.append(Vector2i(x, area.end.y))
  38. for y in range(area.position.y + 1, area.end.y - 1):
  39. edges.append(Vector2i(area.position.x, y))
  40. edges.append(Vector2i(area.end.x, y))
  41. edges = BetterTerrain._widen_with_exclusion(tm, edges, area)
  42. create_tile_restore_point(undo_manager, tm, edges, false)
  43. func restore_tiles(tm: TileMapLayer, restore: Array) -> void:
  44. for r in restore:
  45. tm.set_cell(r[0], r[1], r[2], r[3])
  46. func create_peering_restore_point(undo_manager: EditorUndoRedoManager, ts: TileSet) -> void:
  47. var restore := []
  48. for s in ts.get_source_count():
  49. var source_id := ts.get_source_id(s)
  50. var source := ts.get_source(source_id) as TileSetAtlasSource
  51. if !source:
  52. continue
  53. for t in source.get_tiles_count():
  54. var coord := source.get_tile_id(t)
  55. for a in source.get_alternative_tiles_count(coord):
  56. var alternate := source.get_alternative_tile_id(coord, a)
  57. var td := source.get_tile_data(coord, alternate)
  58. var tile_type := BetterTerrain.get_tile_terrain_type(td)
  59. if tile_type == BetterTerrain.TileCategory.NON_TERRAIN:
  60. continue
  61. var peering_dict := {}
  62. for c in BetterTerrain.tile_peering_keys(td):
  63. peering_dict[c] = BetterTerrain.tile_peering_types(td, c)
  64. var symmetry = BetterTerrain.get_tile_symmetry_type(td)
  65. restore.append([source_id, coord, alternate, tile_type, peering_dict, symmetry])
  66. undo_manager.add_undo_method(self, &"restore_peering", ts, restore)
  67. func create_peering_restore_point_specific(undo_manager: EditorUndoRedoManager, ts: TileSet, protect: int) -> void:
  68. var restore := []
  69. for s in ts.get_source_count():
  70. var source_id := ts.get_source_id(s)
  71. var source := ts.get_source(source_id) as TileSetAtlasSource
  72. if !source:
  73. continue
  74. for t in source.get_tiles_count():
  75. var coord := source.get_tile_id(t)
  76. for a in source.get_alternative_tiles_count(coord):
  77. var alternate := source.get_alternative_tile_id(coord, a)
  78. var td := source.get_tile_data(coord, alternate)
  79. var tile_type := BetterTerrain.get_tile_terrain_type(td)
  80. if tile_type == BetterTerrain.TileCategory.NON_TERRAIN:
  81. continue
  82. var to_restore : bool = tile_type == protect
  83. var terrain := BetterTerrain.get_terrain(ts, tile_type)
  84. var cells = BetterTerrain.data.get_terrain_peering_cells(ts, terrain.type)
  85. for c in cells:
  86. if protect in BetterTerrain.tile_peering_types(td, c):
  87. to_restore = true
  88. break
  89. if !to_restore:
  90. continue
  91. var peering_dict := {}
  92. for c in cells:
  93. peering_dict[c] = BetterTerrain.tile_peering_types(td, c)
  94. var symmetry = BetterTerrain.get_tile_symmetry_type(td)
  95. restore.append([source_id, coord, alternate, tile_type, peering_dict, symmetry])
  96. undo_manager.add_undo_method(self, &"restore_peering", ts, restore)
  97. func create_peering_restore_point_tile(undo_manager: EditorUndoRedoManager, ts: TileSet, source_id: int, coord: Vector2i, alternate: int) -> void:
  98. var source := ts.get_source(source_id) as TileSetAtlasSource
  99. var td := source.get_tile_data(coord, alternate)
  100. var tile_type := BetterTerrain.get_tile_terrain_type(td)
  101. var restore := []
  102. var peering_dict := {}
  103. for c in BetterTerrain.tile_peering_keys(td):
  104. peering_dict[c] = BetterTerrain.tile_peering_types(td, c)
  105. var symmetry = BetterTerrain.get_tile_symmetry_type(td)
  106. restore.append([source_id, coord, alternate, tile_type, peering_dict, symmetry])
  107. undo_manager.add_undo_method(self, &"restore_peering", ts, restore)
  108. func restore_peering(ts: TileSet, restore: Array) -> void:
  109. for r in restore:
  110. var source := ts.get_source(r[0]) as TileSetAtlasSource
  111. var td := source.get_tile_data(r[1], r[2])
  112. BetterTerrain.set_tile_terrain_type(ts, td, r[3])
  113. var peering_types = r[4]
  114. for peering in peering_types:
  115. var types := BetterTerrain.tile_peering_types(td, peering)
  116. for t in types:
  117. BetterTerrain.remove_tile_peering_type(ts, td, peering, t)
  118. for t in peering_types[peering]:
  119. BetterTerrain.add_tile_peering_type(ts, td, peering, t)
  120. var symmetry = r[5]
  121. BetterTerrain.set_tile_symmetry_type(ts, td, symmetry)
  122. func create_terrain_type_restore_point(undo_manager: EditorUndoRedoManager, ts: TileSet) -> void:
  123. var count = BetterTerrain.terrain_count(ts)
  124. var restore = []
  125. for i in count:
  126. restore.push_back(BetterTerrain.get_terrain(ts, i))
  127. undo_manager.add_undo_method(self, &"restore_terrain", ts, restore)
  128. func restore_terrain(ts: TileSet, restore: Array) -> void:
  129. for i in restore.size():
  130. var r = restore[i]
  131. BetterTerrain.set_terrain(ts, i, r.name, r.color, r.type, r.categories, r.icon)
  132. func add_do_method(undo_manager: EditorUndoRedoManager, object:Object, method:StringName, args:Array):
  133. if action_index > _current_action_index:
  134. _current_action_index = action_index
  135. _current_action_count = action_count
  136. if action_count > _current_action_count:
  137. _current_action_count = action_count
  138. undo_manager.add_do_method(self, "_do_method", object, method, args, action_count)
  139. func _do_method(object:Object, method:StringName, args:Array, this_action_count:int):
  140. if this_action_count >= _current_action_count:
  141. object.callv(method, args)
  142. func finish_action():
  143. _current_action_count = 0