1
0
Fork 0
Cleanomancer/Script/Level.gd

153 lines
4.0 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
onready var _wastesound := $Waste/Sound as AudioStreamPlayer
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()
level.waste_sound(waste_line.size())
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()
($Stairs/Sound as AudioStreamPlayer).play()
func update_reservoir() -> void:
_reservoir.frame = _player.reservoir
func waste_sound(var number :int):
for i in range(number):
_wastesound.play()
yield(_wastesound, "finished")