From 786444e789aa072dd573475a75d2352a65f400f3 Mon Sep 17 00:00:00 2001 From: RealMelwei Date: Sat, 11 Oct 2025 17:36:43 +0200 Subject: [PATCH] Turned Grid into an autoload node. Made Buildings persist after death. --- buildings/building.gd | 19 +++++------ petal.gd | 7 ++-- player/player.gd | 5 +++ project.godot | 4 +++ ui/main_menu/main_menu.gd | 3 +- ui/main_menu/main_menu.tscn | 1 + .../victory_screen_button_main_menu.gd | 2 +- vines_petals/bud.gd | 8 ++--- vines_petals/vine.gd | 29 ++++++++-------- vines_petals/vine_node.gd | 3 +- world/building_generator.gd | 33 ++++++++++--------- world/earth.gd | 7 ++-- world/earth.tscn | 19 +---------- world/grid.gd | 19 +++++++---- world/grid.tscn | 18 ++++++++++ 15 files changed, 95 insertions(+), 82 deletions(-) create mode 100644 world/grid.tscn diff --git a/buildings/building.gd b/buildings/building.gd index 7c8c604..a294a51 100644 --- a/buildings/building.gd +++ b/buildings/building.gd @@ -4,18 +4,15 @@ class_name Building extends Node2D @export var dimension : Vector2i = Vector2(2, 1) # same as above @export var blocks_area = true -@onready var grid : Grid = get_parent() - var objects = [] var destroyed = false # make sure location is set before adding a building to the scene tree # also make sure that the buildings are instantiated as children of the grid func _ready() -> void: - assert(grid != null) - position = grid.get_world_position(location) + position = Grid.get_world_position(location) if blocks_area: - grid.buildings.append(self) + Grid.buildings.append(self) await get_tree().create_timer(0.2).timeout if get_node_or_null("EnemyList") != null: @@ -24,8 +21,8 @@ func _ready() -> void: $EnemyList.reparent(get_tree().get_root().get_node("main"), false) for enemy in enemies: - var oldpos = enemy.position; - enemy.position = grid.get_world_position(location, oldpos) + var oldpos = enemy.global_position; + enemy.global_position = Grid.get_world_position(location, oldpos) if "location" in enemy: enemy.location = location + Vector2i(floor(oldpos.x/300), ceil(-oldpos.y/300)) if "offset" in enemy: enemy.offset = Global.vec_mod(oldpos, 300) @@ -33,7 +30,7 @@ func _ready() -> void: objects.append(enemy) if "building" in enemy: enemy.building = self if(enemy.has_method("init_at_horizontal_distortion")): - enemy.init_at_horizontal_distortion(enemy.position.length() / grid.ground_radius) + enemy.init_at_horizontal_distortion(enemy.position.length() / Grid.ground_radius) func overlaps(other : Building): # heights don't overlap @@ -41,16 +38,16 @@ func overlaps(other : Building): if location.y + dimension.y <= other.location.y: return false # other is above # angles overlap. We can now assume heights overlap - var relative_other_loc = (other.location.x - location.x + grid.num_collumns) % grid.num_collumns + var relative_other_loc = (other.location.x - location.x + Grid.num_collumns) % Grid.num_collumns if dimension.x > relative_other_loc: return true - if relative_other_loc + other.dimension.x > grid.num_collumns: return true + if relative_other_loc + other.dimension.x > Grid.num_collumns: return true # If we get here, angles do not overlap return false func destroy(): if not destroyed: - grid.buildings.remove_at(grid.buildings.find(self)) + Grid.buildings.remove_at(Grid.buildings.find(self)) for object in objects: if object != null and not ("collected" in object and object.collected): object.queue_free() diff --git a/petal.gd b/petal.gd index 910fe05..71e9c8f 100644 --- a/petal.gd +++ b/petal.gd @@ -1,7 +1,6 @@ class_name Petal extends Node2D -@onready var grid : Grid = get_tree().get_root().get_node("main/Earth/Grid") -@onready var location : Vector2 = grid.get_location_from_world_pos(global_position) -@onready var offset : Vector2 = grid.get_offset_from_world_pos(global_position) +@onready var location : Vector2 = Grid.get_location_from_world_pos(global_position) +@onready var offset : Vector2 = Grid.get_offset_from_world_pos(global_position) @export var vine_resource : PackedScene var vine : Vine var activated = false @@ -16,7 +15,7 @@ var item : Item: func _ready() -> void: await get_tree().create_timer(1).timeout vine = vine_resource.instantiate() - vine.petal_location = Global.vec_mod(location, grid.num_collumns) + vine.petal_location = Global.vec_mod(location, Grid.num_collumns) vine.petal_offset = offset get_parent().call_deferred("add_child",vine) await get_tree().create_timer(1).timeout diff --git a/player/player.gd b/player/player.gd index 02d2c31..0d109b0 100644 --- a/player/player.gd +++ b/player/player.gd @@ -210,3 +210,8 @@ func play_double_jump_animation() -> void: node.position = Vector2(0, 5) node.scale = .5 * Vector2.ONE node.reparent(get_parent()) + +func update_vine_statuses(): + var location = Grid.get_location_from_world_pos(global_position) + for vine : Vine in Grid.vines_per_node[location.x][location.y]: + Status.apply(vine.status_name, self, 0.1, vine.status_params) diff --git a/project.godot b/project.godot index 00b120a..f631a9a 100644 --- a/project.godot +++ b/project.godot @@ -15,6 +15,10 @@ run/main_scene="uid://dpkr8yoobtej6" config/features=PackedStringArray("4.5", "Forward Plus") config/icon="res://icon.svg" +[autoload] + +Grid="*res://world/grid.tscn" + [display] window/size/viewport_width=1920 diff --git a/ui/main_menu/main_menu.gd b/ui/main_menu/main_menu.gd index 4b423d0..1a0ecf5 100644 --- a/ui/main_menu/main_menu.gd +++ b/ui/main_menu/main_menu.gd @@ -3,7 +3,8 @@ extends Node func _on_button_start_pressed() -> void: - get_tree().change_scene_to_file("res://main.tscn") + Grid.reset() + get_tree().call_deferred("change_scene_to_file","res://main.tscn") func _on_button_quit_pressed() -> void: diff --git a/ui/main_menu/main_menu.tscn b/ui/main_menu/main_menu.tscn index 3916f82..8bbca66 100644 --- a/ui/main_menu/main_menu.tscn +++ b/ui/main_menu/main_menu.tscn @@ -40,6 +40,7 @@ zoom = Vector2(0.12, 0.12) script = ExtResource("2_d3a7t") initial_buildings = 200 initial_spawn_protection = false +only_on_first_load = true [node name="Timer" type="Timer" parent="Building Generator"] diff --git a/ui/victory_screen/victory_screen_button_main_menu.gd b/ui/victory_screen/victory_screen_button_main_menu.gd index 9c8089a..be81df0 100644 --- a/ui/victory_screen/victory_screen_button_main_menu.gd +++ b/ui/victory_screen/victory_screen_button_main_menu.gd @@ -3,4 +3,4 @@ extends Button func _on_pressed() -> void: - get_tree().change_scene_to_file("res://ui/main_menu/main_menu.tscn") + get_tree().call_deferred("change_scene_to_file","res://ui/main_menu/main_menu.tscn") diff --git a/vines_petals/bud.gd b/vines_petals/bud.gd index c637516..8ca634d 100644 --- a/vines_petals/bud.gd +++ b/vines_petals/bud.gd @@ -12,13 +12,13 @@ func _on_opened(): func spread(): for dir in [Vector2.UP, Vector2.DOWN, Vector2.RIGHT, Vector2.LEFT]: - if not vine.vine_locations.has(Global.vec_mod(location + dir, grid.num_collumns)): + if not vine.vine_locations.has(Global.vec_mod(location + dir, Grid.num_collumns)): grow_to_next_bud(dir) func grow_to_next_bud(dir): var target_offset = vine.random_offset() - var target = Global.vec_mod(location + dir, grid.num_collumns) - var pos1 = grid.get_world_position(location, offset) - var pos2 = grid.get_world_position(target, target_offset) + var target = Global.vec_mod(location + dir, Grid.num_collumns) + var pos1 = Grid.get_world_position(location, offset) + var pos2 = Grid.get_world_position(target, target_offset) var num_seg = floor((pos1-pos2).length() / 96) await vine.grow_vine_sequence(location, offset, target, target_offset, num_seg, depth, true, false) diff --git a/vines_petals/vine.gd b/vines_petals/vine.gd index ebda4ed..88163e4 100644 --- a/vines_petals/vine.gd +++ b/vines_petals/vine.gd @@ -3,10 +3,10 @@ class_name Vine extends Node2D @export var petal_offset : Vector2 @export var vine_locations : Array[Vector2] @export var bud_resource : PackedScene -@onready var grid : Grid var img_path_inactive = "res://vines_petals/vine_inactive.png" @export var img_path_active = "res://vines_petals/vine_active_green.png" -@export var status : Timer +@export var status_name : String +@export var status_params : Dictionary = {} var active_depth = -1 var fully_active = false var vine_data = [] @@ -31,8 +31,8 @@ func draw_vine(pos1 : Vector2, pos2 : Vector2, depth : int): func grow_vine_sequence(location1 : Vector2, offset1 : Vector2, location2: Vector2, offset2 : Vector2, num_segments: int, depth: int, grow_bud = false, quick_spawn = false): depth = min(depth, max_depth) - var pos1 = grid.get_world_position(location1, offset1) - var pos2 = grid.get_world_position(location2, offset2) + var pos1 = Grid.get_world_position(location1, offset1) + var pos2 = Grid.get_world_position(location2, offset2) var positions = [] positions.append(pos1) @@ -49,17 +49,17 @@ func grow_vine_sequence(location1 : Vector2, offset1 : Vector2, location2: Vecto if not quick_spawn: await get_tree().create_timer(0.2).timeout if active_depth >= depth + num_segments: - if grow_bud and location2.y > 0 and location2.y <= grid.max_bud_height: + if grow_bud and location2.y > 0 and location2.y <= Grid.max_bud_height: spawn_bud(location2, offset2, depth + num_segments) else: - if location2.y > 0 and location2.y <= grid.max_bud_height: + if location2.y > 0 and location2.y <= Grid.max_bud_height: for i in range(vine_end_data.size()): if vine_end_data[i].location == location1: vine_end_data.remove_at(i) break vine_end_data.append({"location": location2, "offset": offset2, "depth": depth+num_segments}) - grid.vines_per_node[location2.x][location2.y].append(self) - vine_locations.append(Global.vec_mod(location2, grid.num_collumns)) + Grid.vines_per_node[location2.x][location2.y].append(self) + vine_locations.append(Global.vec_mod(location2, Grid.num_collumns)) func generate_random_offsets(segment_count, max_second_derivative): var differences = [] @@ -105,8 +105,7 @@ func update_active_depth(): update_active_depth() func init_random(): - grid = get_tree().get_root().get_node("main/Earth/Grid") - grid.vines_per_node[petal_location.x][petal_location.y].append(self) + Grid.vines_per_node[petal_location.x][petal_location.y].append(self) vine_locations.append(petal_location) vine_end_data.append({"location": petal_location, "offset": petal_offset, "depth": 0}) for i in range(randi_range(2,2)): @@ -114,13 +113,13 @@ func init_random(): var branches_count = 0 for branch in range(ceil(randf() * 4)): var dir = [Vector2.UP, Vector2.DOWN, Vector2.RIGHT, Vector2.LEFT].pick_random() - var target = Global.vec_mod(end.location + dir, grid.num_collumns) - if target.y <= grid.max_bud_height + 1 and grid.vines_per_node[target.x][target.y].is_empty(): - if not (target.y <= 0 or target.y > grid.max_bud_height): + var target = Global.vec_mod(end.location + dir, Grid.num_collumns) + if target.y <= Grid.max_bud_height + 1 and Grid.vines_per_node[target.x][target.y].is_empty(): + if not (target.y <= 0 or target.y > Grid.max_bud_height): branches_count += 1 var target_offset = random_offset() - var pos1 = grid.get_world_position(end.location, end.offset) - var pos2 = grid.get_world_position(target, target_offset) + var pos1 = Grid.get_world_position(end.location, end.offset) + var pos2 = Grid.get_world_position(target, target_offset) var num_seg = floor((pos1-pos2).length() / 96) grow_vine_sequence(end.location, end.offset, target, target_offset, num_seg, end.depth, true, true) if i==0 and branches_count == 1: diff --git a/vines_petals/vine_node.gd b/vines_petals/vine_node.gd index 8bbcb67..d3c2a52 100644 --- a/vines_petals/vine_node.gd +++ b/vines_petals/vine_node.gd @@ -1,9 +1,8 @@ class_name VineNode extends Node2D @export var vine : Vine -@onready var grid : Grid = get_tree().get_root().get_node("main/Earth/Grid") @export var location : Vector2 @export var offset : Vector2 func _ready() -> void: - position = grid.get_world_position(location, offset) + position = Grid.get_world_position(location, offset) diff --git a/world/building_generator.gd b/world/building_generator.gd index 27d55e3..8bcea99 100644 --- a/world/building_generator.gd +++ b/world/building_generator.gd @@ -1,9 +1,10 @@ class_name BuildingGenerator extends Node -@onready var grid : Grid = %Earth.get_grid() @export var initial_buildings : int; @export var initial_spawn_protection = true @export var spawn_attempts = 5 +@export var only_on_first_load = false +static var first_load = true func random_oppostite_collumn() -> int: var playerpos = %Player.position @@ -11,32 +12,34 @@ func random_oppostite_collumn() -> int: var offset = randf_range(TAU/3, 2*TAU/3) var spawn_angle = player_angle + offset - var collumn = int(spawn_angle / TAU * grid.num_collumns + grid.num_collumns) % grid.num_collumns + var collumn = int(spawn_angle / TAU * Grid.num_collumns + Grid.num_collumns) % Grid.num_collumns return collumn func random_collumn() -> int: - return randi_range(0, grid.num_collumns - 1) + return randi_range(0, Grid.num_collumns - 1) func _ready(): - for i in range(initial_buildings): - for j in range(spawn_attempts): - var collumn = random_collumn() - if initial_spawn_protection and 43 <= collumn and collumn <= 49: - continue - var building = randomize_building() - building.z_index = -2 - if grid.add_building_to_collumn(building, collumn): - break + if not (only_on_first_load and not first_load): + first_load = false + for i in range(initial_buildings): + for j in range(spawn_attempts): + var collumn = random_collumn() + if initial_spawn_protection and 43 <= collumn and collumn <= 49: + continue + var building = randomize_building() + building.z_index = -2 + if Grid.add_building_to_collumn(building, collumn): + break func _on_timer_timeout() -> void: for i in range(spawn_attempts): var collumn = random_oppostite_collumn() var building : Building = randomize_building() building.z_index = -2 - if grid.add_building_to_collumn(building, collumn): + if Grid.add_building_to_collumn(building, collumn): break func randomize_building() -> Building: - var index = randi() % grid.packed_buildings.size() - return grid.packed_buildings[index].instantiate() + var index = randi() % Grid.packed_buildings.size() + return Grid.packed_buildings[index].instantiate() diff --git a/world/earth.gd b/world/earth.gd index 4e6770c..f65695c 100644 --- a/world/earth.gd +++ b/world/earth.gd @@ -4,10 +4,7 @@ extends Node2D func _ready() -> void: ItemSpawn.item_pool = ResourceLoader.load("res://items/generic/item_pool.tres","",ResourceLoader.CACHE_MODE_IGNORE) - for column in range($Grid.num_collumns): + for column in range(Grid.num_collumns): var grass_placed : Building = grass.instantiate() grass_placed.location = Vector2(column, 0) - $Grid.add_child(grass_placed) - -func get_grid() -> Grid: - return $Grid + Grid.add_child(grass_placed) diff --git a/world/earth.tscn b/world/earth.tscn index 50283ee..707a8c3 100644 --- a/world/earth.tscn +++ b/world/earth.tscn @@ -1,16 +1,8 @@ -[gd_scene load_steps=15 format=3 uid="uid://jjoyj1ldafkf"] +[gd_scene load_steps=7 format=3 uid="uid://jjoyj1ldafkf"] [ext_resource type="Script" uid="uid://vgxh2xdevat7" path="res://world/earth.gd" id="1_wxnww"] [ext_resource type="PackedScene" uid="uid://xrbh432lrjge" path="res://world/grass.tscn" id="2_abvrx"] -[ext_resource type="Script" uid="uid://m3vyyfk8gnma" path="res://world/grid.gd" id="3_2bhor"] [ext_resource type="Shader" path="res://world/earth.gdshader" id="3_640fc"] -[ext_resource type="PackedScene" uid="uid://djawvtdwp423v" path="res://buildings/room_temple.tscn" id="3_nihcy"] -[ext_resource type="PackedScene" uid="uid://cmofmd0vf3hx3" path="res://buildings/room_haunted_house.tscn" id="4_ml5no"] -[ext_resource type="PackedScene" uid="uid://dliwqqmrxldjh" path="res://buildings/room_bear_trap.tscn" id="4_r4pw8"] -[ext_resource type="PackedScene" uid="uid://6y637jp2tbma" path="res://buildings/room_pedastal.tscn" id="6_640fc"] -[ext_resource type="PackedScene" uid="uid://dt827qxyycg8n" path="res://buildings/room_pedastal_mean.tscn" id="7_abvrx"] -[ext_resource type="PackedScene" uid="uid://c7ddsyd8kcjji" path="res://buildings/room_wide_item_above.tscn" id="9_ej0af"] -[ext_resource type="PackedScene" uid="uid://oflm2yjjwhf" path="res://buildings/room_giant_leech.tscn" id="10_640fc"] [sub_resource type="CircleShape2D" id="CircleShape2D_5i67w"] radius = 3000.0 @@ -36,12 +28,3 @@ z_index = 3 material = SubResource("ShaderMaterial_abvrx") scale = Vector2(6000, 6000) mesh = SubResource("QuadMesh_ej0af") - -[node name="Grid" type="Node2D" parent="."] -unique_name_in_owner = true -script = ExtResource("3_2bhor") -ground_radius = 3000.0 -cell_height = 300.0 -num_collumns = 60 -packed_buildings = Array[PackedScene]([ExtResource("4_r4pw8"), ExtResource("4_ml5no"), ExtResource("6_640fc"), ExtResource("7_abvrx"), ExtResource("3_nihcy"), ExtResource("9_ej0af"), ExtResource("10_640fc")]) -metadata/_custom_type_script = "uid://m3vyyfk8gnma" diff --git a/world/grid.gd b/world/grid.gd index c4af695..d2cb1eb 100644 --- a/world/grid.gd +++ b/world/grid.gd @@ -1,4 +1,4 @@ -class_name Grid extends Node2D +extends Node2D @export var ground_radius : float @export var cell_height : float @@ -14,11 +14,7 @@ var max_bud_height = 8 var vines_per_node : Array = [] func _ready() -> void: - for i in range(num_collumns): - var arr = [] - for j in range(max_bud_height + 2): - arr.append([]) - vines_per_node.append(arr) + reset() func _draw() -> void: if !debug: @@ -69,6 +65,17 @@ func get_offset_from_world_pos(pos : Vector2): 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) + # for testing #func _ready() -> void: # diff --git a/world/grid.tscn b/world/grid.tscn new file mode 100644 index 0000000..3c7e5e8 --- /dev/null +++ b/world/grid.tscn @@ -0,0 +1,18 @@ +[gd_scene load_steps=9 format=3 uid="uid://dqg5yjkbklfcf"] + +[ext_resource type="Script" uid="uid://m3vyyfk8gnma" path="res://world/grid.gd" id="1_qw8xp"] +[ext_resource type="PackedScene" uid="uid://dliwqqmrxldjh" path="res://buildings/room_bear_trap.tscn" id="2_ryti2"] +[ext_resource type="PackedScene" uid="uid://cmofmd0vf3hx3" path="res://buildings/room_haunted_house.tscn" id="3_5v6ap"] +[ext_resource type="PackedScene" uid="uid://6y637jp2tbma" path="res://buildings/room_pedastal.tscn" id="4_fbocv"] +[ext_resource type="PackedScene" uid="uid://dt827qxyycg8n" path="res://buildings/room_pedastal_mean.tscn" id="5_lkrwq"] +[ext_resource type="PackedScene" uid="uid://djawvtdwp423v" path="res://buildings/room_temple.tscn" id="6_8w44a"] +[ext_resource type="PackedScene" uid="uid://c7ddsyd8kcjji" path="res://buildings/room_wide_item_above.tscn" id="7_ntdb8"] +[ext_resource type="PackedScene" uid="uid://oflm2yjjwhf" path="res://buildings/room_giant_leech.tscn" id="8_um4di"] + +[node name="Grid" type="Node2D"] +script = ExtResource("1_qw8xp") +ground_radius = 3000.0 +cell_height = 300.0 +num_collumns = 60 +packed_buildings = Array[PackedScene]([ExtResource("2_ryti2"), ExtResource("3_5v6ap"), ExtResource("4_fbocv"), ExtResource("5_lkrwq"), ExtResource("6_8w44a"), ExtResource("7_ntdb8"), ExtResource("8_um4di")]) +metadata/_custom_type_script = "uid://m3vyyfk8gnma"