The_Dark_Side_of_Earth/world/grid.gd

120 lines
4.1 KiB
GDScript3
Raw Normal View History

extends Node2D
2025-09-15 19:03:18 +02:00
@export var ground_radius : float
@export var cell_height : float
@export var num_collumns : int
@export var debug : bool
2025-09-16 12:02:37 +02:00
@export var packed_buildings : Array[PackedScene]
2025-09-19 00:18:49 +02:00
@export var max_build_height = 6
2025-09-16 12:02:37 +02:00
2025-09-16 00:19:40 +02:00
var buildings : Array[Building] = []
2025-10-05 15:01:51 +02:00
var max_bud_height = 8
var vines_per_node : Array
2025-10-05 15:01:51 +02:00
func _ready() -> void:
reset()
2025-10-05 15:01:51 +02:00
2025-09-15 19:03:18 +02:00
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);
2025-09-16 00:19:40 +02:00
func add_building_to_collumn(building : Building, collumn : int):
# find the height of the top building in the buildings list:
2025-09-16 11:44:16 +02:00
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
2025-09-19 00:18:49 +02:00
if building.location.y + building.dimension.y > max_build_height:
building.free()
return false
2025-09-16 11:44:16 +02:00
add_child(building)
2025-09-19 00:18:49 +02:00
return true
2025-09-16 00:19:40 +02:00
# Adds children of given node to the grid and their building.
2025-10-22 02:04:12 +02:00
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)
2025-10-22 13:09:12 +02:00
if "building" in object: object.building = building
2025-10-22 02:04:12 +02:00
# 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)
# Returns the global position for a given grid location and offset
2025-10-03 11:30:45 +02:00
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)
2025-10-11 12:47:24 +02:00
# Returns the grid location for a given global position
2025-10-11 12:47:24 +02:00
func get_location_from_world_pos(pos : Vector2):
2025-10-17 14:20:42 +02:00
var angle = fposmod(pos.angle(), TAU)
var x = floor(num_collumns * angle / TAU)
2025-10-11 12:47:24 +02:00
var height = pos.length()
var y = ceil((height - ground_radius)/cell_height)
return Vector2(x, y)
# Returns the offset with respect to the grid location for a given global position
2025-10-11 12:47:24 +02:00
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()
2025-10-17 14:20:42 +02:00
var y = fposmod(-(height - ground_radius)/cell_height, 1) * cell_height
2025-10-11 12:47:24 +02:00
return Vector2(x, y)
# Resets objects in the grids and the item pool.
# Also initializes vines_per_node.
func reset():
ItemSpawn.item_pool = ResourceLoader.load("res://items/generic/item_pool.tres","",ResourceLoader.CACHE_MODE_IGNORE)
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)
# Returns all vines present at given grid location.
func get_vines_at(location) -> Array:
location = Global.vec_mod(location, num_collumns, true)
return vines_per_node[location.x][location.y]
# Registers a vine at a given grid location.
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)
# Calls _enter_grid on all children.
2025-10-22 02:04:12 +02:00
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")