144 lines
3.8 KiB
GDScript
144 lines
3.8 KiB
GDScript
tool
|
|
extends TileMap
|
|
|
|
class_name Level
|
|
|
|
onready var _floor := self as TileMap
|
|
onready var _props := $Props as TileMap
|
|
onready var _waste := $Waste as TileMap
|
|
onready var _player := $Player as Player
|
|
onready var _stairs := $Stairs as AnimatedSprite
|
|
onready var _reservoir := $Reservoir as AnimatedSprite
|
|
|
|
export var start_x := 0
|
|
export var start_y := 0
|
|
|
|
export var stairs_x := 0
|
|
export var stairs_y := 0
|
|
|
|
func _ready():
|
|
_player.level = self
|
|
_player.tile_position = Vector2(start_x, start_y)
|
|
_stairs.visible = false
|
|
_stairs.modulate = Color.white
|
|
|
|
func _process(delta):
|
|
|
|
if Engine.editor_hint:
|
|
|
|
if not _player is Player:
|
|
_player = $Player as Player
|
|
|
|
_player.level = self
|
|
_player.tile_position = Vector2(start_x, start_y)
|
|
_player.update_position()
|
|
|
|
|
|
if not _stairs is AnimatedSprite:
|
|
_stairs = $Stairs as AnimatedSprite
|
|
|
|
_stairs.position = map_to_world(Vector2(stairs_x, stairs_y))
|
|
|
|
if not _reservoir is AnimatedSprite:
|
|
_reservoir = $Reservoir as AnimatedSprite
|
|
|
|
update_reservoir()
|
|
|
|
|
|
class Tile:
|
|
var x :int
|
|
var y :int
|
|
var level :Level
|
|
|
|
func get_tile(var tile_map :TileMap) -> int:
|
|
return tile_map.get_cell(x, y)
|
|
|
|
func has_tile(var tile_map :TileMap) -> bool:
|
|
return get_tile(tile_map) >= 0
|
|
|
|
func set_tile(var tile_map :TileMap, var tile :int) -> void:
|
|
tile_map.set_cell(x, y, tile)
|
|
|
|
func swap_tile(var tile_map:TileMap, var other :Tile) -> void:
|
|
var tile := other.get_tile(tile_map)
|
|
other.set_tile(tile_map, self.get_tile(tile_map))
|
|
self.set_tile(tile_map, tile)
|
|
|
|
func has_floor() -> bool:
|
|
return has_tile(level._floor)
|
|
|
|
func has_prop() -> bool:
|
|
return has_tile(level._props)
|
|
|
|
func has_waste() -> bool:
|
|
return has_tile(level._waste)
|
|
|
|
func can_walk() -> bool:
|
|
return has_floor() and not has_prop() and not has_waste()
|
|
|
|
func get_next_tile(var direction :Vector2) -> Tile:
|
|
return level.get_tile(x + direction.x, y + direction.y)
|
|
|
|
func can_push(var direction :Vector2) -> bool:
|
|
if has_waste():
|
|
return get_next_tile(direction).can_push(direction)
|
|
elif has_prop():
|
|
return false
|
|
elif has_floor():
|
|
return true
|
|
else:
|
|
return false
|
|
|
|
func get_waste_line(var direction :Vector2, var continuous := false, var max_tiles := -1) -> Array:
|
|
var waste_line := []
|
|
if max_tiles != 0 and (has_waste() and has_floor() or continuous and can_walk()):
|
|
waste_line = get_next_tile(direction).get_waste_line(direction, continuous, max_tiles - 1)
|
|
if has_waste():
|
|
waste_line.push_front(self)
|
|
return waste_line
|
|
|
|
func push(var direction :Vector2) -> void:
|
|
if can_push(direction):
|
|
var waste_line := get_waste_line(direction)
|
|
if not waste_line.empty():
|
|
var last = waste_line.pop_back()
|
|
last.push_r(direction, waste_line)
|
|
|
|
func push_r(var direction: Vector2, var waste_line := []) -> void:
|
|
var empty_tile = get_next_tile(direction)
|
|
swap_tile(level._waste, empty_tile)
|
|
if not waste_line.empty():
|
|
waste_line.pop_back().push_r(direction, waste_line)
|
|
return
|
|
|
|
func dash(var direction: Vector2, var tile_limit = INF, var waste_limit = INF) -> Tile:
|
|
var waste_line = get_waste_line(direction, true, tile_limit)
|
|
waste_line.resize(min(waste_limit, waste_line.size()))
|
|
for tile in waste_line:
|
|
tile.set_tile(level._waste, -1)
|
|
level.check_completed()
|
|
return waste_line.back() if not waste_line.empty() else self
|
|
|
|
func get_tile_v(var position :Vector2) -> Tile:
|
|
return get_tile(position.x, position.y)
|
|
|
|
func get_tile(var x :int, var y :int) -> Tile:
|
|
var tile = Tile.new()
|
|
tile.x = x
|
|
tile.y = y
|
|
tile.level = self
|
|
return tile
|
|
|
|
func check_completed() -> void:
|
|
var left = _waste.get_used_cells()
|
|
if left.empty():
|
|
show_stairs()
|
|
|
|
func show_stairs() -> void:
|
|
print ("show stairs")
|
|
_stairs.frame = 0
|
|
_stairs.visible = true
|
|
_stairs.play()
|
|
|
|
func update_reservoir() -> void:
|
|
_reservoir.frame = _player.reservoir
|