119 lines
3.7 KiB
GDScript
119 lines
3.7 KiB
GDScript
extends Node2D
|
|
|
|
@export var ground_radius : float
|
|
@export var cell_height : float
|
|
@export var num_collumns : int
|
|
@export var debug : bool
|
|
|
|
@export var packed_buildings : Array[PackedScene]
|
|
@export var max_build_height = 6
|
|
|
|
var buildings : Array[Building] = []
|
|
|
|
var max_bud_height = 8
|
|
var vines_per_node : Array
|
|
|
|
func _ready() -> void:
|
|
reset()
|
|
|
|
func _draw() -> void:
|
|
if !debug:
|
|
return
|
|
|
|
for i in range(10):
|
|
draw_arc(Vector2.ZERO, ground_radius + i * cell_height, 0, TAU, 250, Color.SKY_BLUE, 1.0, true);
|
|
|
|
for i in range(num_collumns):
|
|
var angle = i * TAU / num_collumns;
|
|
draw_line(Vector2.ZERO, 10000 * Vector2.from_angle(angle), Color.SKY_BLUE);
|
|
|
|
func add_building_to_collumn(building : Building, collumn : int):
|
|
# find the height of the top building in the buildings list:
|
|
building.location = Vector2(collumn, -1)
|
|
var spot_clear : bool = false
|
|
while(!spot_clear):
|
|
building.location.y += 1
|
|
spot_clear = true
|
|
for other in buildings:
|
|
if other.overlaps(building):
|
|
spot_clear = false
|
|
|
|
if building.location.y + building.dimension.y > max_build_height:
|
|
building.free()
|
|
return false
|
|
|
|
add_child(building)
|
|
return true
|
|
|
|
func place_object_list(obj_list : Node2D, building):
|
|
obj_list.reparent(self, false)
|
|
var objects_to_be_placed = obj_list.get_children()
|
|
for object in objects_to_be_placed:
|
|
var offset = object.global_position;
|
|
object.global_position = Grid.get_world_position(building.location, offset)
|
|
|
|
# The building remembers these objects: If it is destroyed, so are they.
|
|
if object is Platform or object is Trap or object is Item:
|
|
building.objects.append(object)
|
|
if "building" in object: object.building = self
|
|
# This scales platforms hoizontally to make sure they still form a floor without gaps.
|
|
if(object.has_method("init_at_horizontal_distortion")):
|
|
object.init_at_horizontal_distortion(object.position.length() / Grid.ground_radius)
|
|
grid_entrance_callback(object)
|
|
|
|
func get_world_position (location: Vector2, offset: Vector2 = Vector2.ZERO) -> Vector2:
|
|
var height = ground_radius + location.y * cell_height - offset.y # currently assumes anchor is bottom left
|
|
var angle = (location.x + offset.x / cell_height) * TAU / num_collumns
|
|
return height * Vector2.from_angle(angle)
|
|
|
|
func get_location_from_world_pos(pos : Vector2):
|
|
var angle = fposmod(pos.angle(), TAU)
|
|
var x = floor(num_collumns * angle / TAU)
|
|
var height = pos.length()
|
|
var y = ceil((height - ground_radius)/cell_height)
|
|
return Vector2(x, y)
|
|
|
|
func get_offset_from_world_pos(pos : Vector2):
|
|
var angle = pos.angle()
|
|
var x = fposmod(num_collumns * angle / TAU, 1) * cell_height
|
|
var height = pos.length()
|
|
var y = fposmod(-(height - ground_radius)/cell_height, 1) * cell_height
|
|
return Vector2(x, y)
|
|
|
|
func reset():
|
|
for obj in get_children():
|
|
obj.free()
|
|
buildings = []
|
|
vines_per_node = []
|
|
for i in range(num_collumns):
|
|
var arr = []
|
|
for j in range(max_bud_height + 2):
|
|
arr.append([])
|
|
vines_per_node.append(arr)
|
|
|
|
func get_vines_at(location) -> Array:
|
|
location = Global.vec_mod(location, num_collumns, true)
|
|
return vines_per_node[location.x][location.y]
|
|
|
|
func add_vine_to(vine, location) -> void:
|
|
if location.y > max_bud_height + 1 or location.y < 0:
|
|
return
|
|
location = Global.vec_mod(location, num_collumns, true)
|
|
vines_per_node[location.x][location.y].append(vine)
|
|
|
|
func grid_entrance_callback(object : Node):
|
|
# Objects receive a callback when placed, starting from the deepest children
|
|
for child in object.get_children():
|
|
grid_entrance_callback(child)
|
|
if object.has_method("_enter_grid"):
|
|
object.call_deferred("_enter_grid")
|
|
|
|
# for testing
|
|
#func _ready() -> void:
|
|
#
|
|
#
|
|
#
|
|
#for i in range(100):
|
|
#var test_building = packed_buildings[0].instantiate()
|
|
#var collumn = randi() % 60
|
|
#add_building_to_collumn(test_building, collumn)
|