Compare commits
No commits in common. "b75e6be470e37b5ea928929ca064f7dd3835d37d" and "42ea2d3d751d8979cbdd26fc8a0abb2e6dd8e92e" have entirely different histories.
b75e6be470
...
42ea2d3d75
16 changed files with 113 additions and 131 deletions
|
|
@ -2,8 +2,6 @@ extends TextureRect
|
||||||
|
|
||||||
@export var colors : Array[Color] = [Color(0.3, 1, 1) * 0.7, Color(1, 0.6, 0.6) * 0.7, Color(1, 1, 1) * 0.7]
|
@export var colors : Array[Color] = [Color(0.3, 1, 1) * 0.7, Color(1, 0.6, 0.6) * 0.7, Color(1, 1, 1) * 0.7]
|
||||||
|
|
||||||
# Modulate the background with an interpolation of the colors in the list,
|
|
||||||
# depending on the players position on the earth.
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
var index : int = floor((%Player.position.angle() + PI)/ TAU * colors.size())
|
var index : int = floor((%Player.position.angle() + PI)/ TAU * colors.size())
|
||||||
var diff = (%Player.position.angle() + PI)/ TAU * colors.size() - index
|
var diff = (%Player.position.angle() + PI)/ TAU * colors.size() - index
|
||||||
|
|
@ -15,9 +15,31 @@ func _ready() -> void:
|
||||||
if blocks_area:
|
if blocks_area:
|
||||||
Grid.buildings.append(self)
|
Grid.buildings.append(self)
|
||||||
|
|
||||||
|
await get_tree().create_timer(0.2).timeout
|
||||||
if get_node_or_null("ObjectList") != null:
|
if get_node_or_null("ObjectList") != null:
|
||||||
var obj_list = $ObjectList
|
var obj_list = $ObjectList
|
||||||
Grid.call_deferred("place_object_list", obj_list, self)
|
obj_list.reparent(get_tree().get_root().get_node("main"), false)
|
||||||
|
await get_tree().create_timer(0.2).timeout
|
||||||
|
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(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:
|
||||||
|
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 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")
|
||||||
|
|
||||||
func overlaps(other : Building):
|
func overlaps(other : Building):
|
||||||
# heights don't overlap
|
# heights don't overlap
|
||||||
|
|
|
||||||
|
|
@ -102,7 +102,7 @@ func destroy_below():
|
||||||
|
|
||||||
func wave():
|
func wave():
|
||||||
# Raise a wave from the water at the boundary of the screen and move it towards the center.
|
# Raise a wave from the water at the boundary of the screen and move it towards the center.
|
||||||
var angle = player.position.angle()
|
var angle = player.position.angle
|
||||||
var dir = randi_range(0, 1) * 2 - 1
|
var dir = randi_range(0, 1) * 2 - 1
|
||||||
var speed = 3000 / water.radius_base
|
var speed = 3000 / water.radius_base
|
||||||
water.create_tsunami(angle - speed * dir * TAU/30, dir, speed)
|
water.create_tsunami(angle - speed * dir * TAU/30, dir, speed)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
[ext_resource type="Script" uid="uid://cpaskpj67pnaj" path="res://enemies/boss/boss_spawner.gd" id="10_efxa6"]
|
[ext_resource type="Script" uid="uid://cpaskpj67pnaj" path="res://enemies/boss/boss_spawner.gd" id="10_efxa6"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cqn67nwyrtq3k" path="res://ui/journal/journal.tscn" id="10_w48qg"]
|
[ext_resource type="PackedScene" uid="uid://cqn67nwyrtq3k" path="res://ui/journal/journal.tscn" id="10_w48qg"]
|
||||||
[ext_resource type="PackedScene" uid="uid://cpe4s6vsn0ujd" path="res://enemies/boss/boss.tscn" id="11_efxa6"]
|
[ext_resource type="PackedScene" uid="uid://cpe4s6vsn0ujd" path="res://enemies/boss/boss.tscn" id="11_efxa6"]
|
||||||
[ext_resource type="Script" uid="uid://gul4u5tw1vxk" path="res://background/bg_image.gd" id="13_vivmo"]
|
[ext_resource type="Script" uid="uid://gul4u5tw1vxk" path="res://bg_image.gd" id="13_vivmo"]
|
||||||
|
|
||||||
[node name="main" type="Node2D"]
|
[node name="main" type="Node2D"]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,20 @@
|
||||||
extends Control
|
extends Control
|
||||||
|
|
||||||
@onready var item_list : ItemList = $ItemList
|
@onready var item_list : ItemList = $ItemList
|
||||||
var item_list_no_dupes = []
|
|
||||||
|
|
||||||
# Add items from each pool to journal.
|
# Add items from each pool to journal. TODO: Deal with multiplicities.
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
await get_tree().create_timer(0.3).timeout
|
||||||
for item_scene in ItemSpawn.item_pool.common:
|
for item_scene in ItemSpawn.item_pool.common:
|
||||||
add_item_to_journal(item_scene)
|
add_item_to_journal(item_scene.instantiate())
|
||||||
for item_scene in ItemSpawn.item_pool.rare:
|
for item_scene in ItemSpawn.item_pool.rare:
|
||||||
add_item_to_journal(item_scene)
|
add_item_to_journal(item_scene.instantiate())
|
||||||
for item_scene in ItemSpawn.item_pool.unique:
|
for item_scene in ItemSpawn.item_pool.unique:
|
||||||
add_item_to_journal(item_scene)
|
add_item_to_journal(item_scene.instantiate())
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
if Input.is_action_just_pressed("journal"):
|
if Input.is_action_just_pressed("journal"):
|
||||||
visible = not visible
|
visible = not visible
|
||||||
|
|
||||||
# Adds an item to the journal if it was not yet added
|
func add_item_to_journal(item: Item):
|
||||||
func add_item_to_journal(item_scene):
|
item_list.add_item(item.item_name, item.icon)
|
||||||
if not item_list_no_dupes.has(item_scene):
|
|
||||||
item_list_no_dupes.append(item_scene)
|
|
||||||
var item = item_scene.instantiate()
|
|
||||||
item_list.add_item(item.item_name, item.icon)
|
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,14 @@
|
||||||
class_name Bud extends GridNode
|
class_name Bud extends VineNode
|
||||||
signal opened
|
signal opened
|
||||||
var img_path
|
var img_path
|
||||||
@export var vine : Vine
|
|
||||||
|
|
||||||
# Triggers when a bud is hit. Spreads the vine, then removes the bud
|
# Triggers when a bud is hit. Spreads the vine, then removes the bud
|
||||||
func _on_opened():
|
func _on_opened():
|
||||||
$EnemyHurtbox.monitorable = false
|
|
||||||
$EnemyHurtbox.monitoring = false
|
|
||||||
$AnimatedSprite2D.play("open")
|
$AnimatedSprite2D.play("open")
|
||||||
opened.emit()
|
opened.emit()
|
||||||
spread()
|
spread()
|
||||||
await $AnimatedSprite2D.animation_finished
|
await $AnimatedSprite2D.animation_finished
|
||||||
for child in get_children():
|
queue_free()
|
||||||
queue_free()
|
|
||||||
|
|
||||||
# Spread in all directions where the given vine is not yet present
|
# Spread in all directions where the given vine is not yet present
|
||||||
func spread():
|
func spread():
|
||||||
|
|
@ -23,5 +19,5 @@ func spread():
|
||||||
# Grow a vine
|
# Grow a vine
|
||||||
func grow_to_next_bud(dir):
|
func grow_to_next_bud(dir):
|
||||||
var target_location = Global.vec_mod(location + dir, Grid.num_collumns, true)
|
var target_location = Global.vec_mod(location + dir, Grid.num_collumns, true)
|
||||||
var target = GridNode.random_at(target_location)
|
var target = vine.random_vine_node_at(target_location)
|
||||||
await vine.grow_vine_sequence(self, target, true, false)
|
await vine.grow_vine_sequence(self, target, true, false)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
class_name Petal extends GridNode
|
class_name Petal extends VineNode
|
||||||
@export var vine : Vine
|
|
||||||
@export var vine_resource : PackedScene
|
@export var vine_resource : PackedScene
|
||||||
var activated = false
|
var activated = false
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ var vine_end_data = []
|
||||||
func draw_vine(pos1 : Vector2, pos2 : Vector2, depth : int):
|
func draw_vine(pos1 : Vector2, pos2 : Vector2, depth : int):
|
||||||
var sprite = Sprite2D.new()
|
var sprite = Sprite2D.new()
|
||||||
get_tree().get_root().get_node("main").add_child(sprite)
|
get_tree().get_root().get_node("main").add_child(sprite)
|
||||||
if active_depth >= depth or fully_active:
|
if active_depth >= depth:
|
||||||
sprite.texture = ResourceLoader.load(img_path_active)
|
sprite.texture = ResourceLoader.load(img_path_active)
|
||||||
else:
|
else:
|
||||||
sprite.texture = ResourceLoader.load(img_path_inactive)
|
sprite.texture = ResourceLoader.load(img_path_inactive)
|
||||||
|
|
@ -59,7 +59,7 @@ func draw_vine(pos1 : Vector2, pos2 : Vector2, depth : int):
|
||||||
sprite.z_index = -1
|
sprite.z_index = -1
|
||||||
|
|
||||||
# Grows a sequence of vine segments from grid position 1 to grid position 2, starting at given depth.
|
# Grows a sequence of vine segments from grid position 1 to grid position 2, starting at given depth.
|
||||||
func grow_vine_sequence(start : GridNode, target: GridNode, grow_bud = false, quick_spawn = false):
|
func grow_vine_sequence(start : VineNode, target: VineNode, grow_bud = false, quick_spawn = false):
|
||||||
var depth = min(start.depth, max_depth)
|
var depth = min(start.depth, max_depth)
|
||||||
|
|
||||||
# Calculate the number and length of segments from the distance of source and target
|
# Calculate the number and length of segments from the distance of source and target
|
||||||
|
|
@ -86,29 +86,21 @@ func grow_vine_sequence(start : GridNode, target: GridNode, grow_bud = false, qu
|
||||||
if not quick_spawn:
|
if not quick_spawn:
|
||||||
await get_tree().create_timer(0.2).timeout
|
await get_tree().create_timer(0.2).timeout
|
||||||
|
|
||||||
# If growing while active, place buds
|
if active_depth >= depth + num_segments:
|
||||||
if active_depth >= depth + num_segments or fully_active:
|
|
||||||
if grow_bud and target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
if grow_bud and target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
||||||
spawn_bud(target.location, target.offset, depth + num_segments)
|
spawn_bud(target.location, target.offset, depth + num_segments)
|
||||||
else:
|
else:
|
||||||
# Otherwise, remember the spot to spawn a bud later.
|
|
||||||
# Further, note that the previous location is no longer a leaf unless it is the petal.
|
|
||||||
if target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
if target.location.y > 0 and target.location.y <= Grid.max_bud_height:
|
||||||
for i in range(vine_end_data.size()):
|
for i in range(vine_end_data.size()):
|
||||||
if vine_end_data[i].location == start.location and not vine_end_data[i] is Petal:
|
if vine_end_data[i].location == start.location:
|
||||||
vine_end_data.remove_at(i)
|
vine_end_data.remove_at(i)
|
||||||
break
|
break
|
||||||
target.depth = depth + num_segments
|
target.depth = depth + num_segments
|
||||||
vine_end_data.append(target)
|
vine_end_data.append(target)
|
||||||
|
|
||||||
# Register the new vine segment in the grid
|
|
||||||
Grid.add_vine_to(self, target.location)
|
Grid.add_vine_to(self, target.location)
|
||||||
vine_locations.append(Global.vec_mod(target.location, Grid.num_collumns, true))
|
vine_locations.append(Global.vec_mod(target.location, Grid.num_collumns, true))
|
||||||
|
|
||||||
# Generates a random function on (segment_count - 1)
|
|
||||||
# many grid points with bounded second derivative
|
|
||||||
func generate_random_offsets(segment_count, max_second_derivative):
|
func generate_random_offsets(segment_count, max_second_derivative):
|
||||||
# First, randomize the derivative of the desired function
|
|
||||||
var differences = []
|
var differences = []
|
||||||
var last_diff = 0
|
var last_diff = 0
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
|
|
@ -116,15 +108,11 @@ func generate_random_offsets(segment_count, max_second_derivative):
|
||||||
differences.append(new_diff)
|
differences.append(new_diff)
|
||||||
last_diff = new_diff
|
last_diff = new_diff
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
|
|
||||||
# Shift that derivative by a constant to add up to 0
|
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
sum += differences[i]
|
sum += differences[i]
|
||||||
var correction = - sum / segment_count
|
var correction = - sum / segment_count
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
differences[i] += correction
|
differences[i] += correction
|
||||||
|
|
||||||
# Return the partial sums over the derivative constructed above
|
|
||||||
var ret = []
|
var ret = []
|
||||||
var next_val = 0
|
var next_val = 0
|
||||||
for i in range(segment_count):
|
for i in range(segment_count):
|
||||||
|
|
@ -132,7 +120,6 @@ func generate_random_offsets(segment_count, max_second_derivative):
|
||||||
next_val += differences[i]
|
next_val += differences[i]
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# Instantiates a bud
|
|
||||||
func spawn_bud(location, offset, depth):
|
func spawn_bud(location, offset, depth):
|
||||||
var bud = bud_resource.instantiate()
|
var bud = bud_resource.instantiate()
|
||||||
bud.location = location
|
bud.location = location
|
||||||
|
|
@ -141,13 +128,9 @@ func spawn_bud(location, offset, depth):
|
||||||
bud.depth = depth
|
bud.depth = depth
|
||||||
get_tree().get_root().get_node("main").add_child(bud)
|
get_tree().get_root().get_node("main").add_child(bud)
|
||||||
|
|
||||||
# Upon activation start the process of slowly increasing the active depth
|
|
||||||
func activate():
|
func activate():
|
||||||
if active_depth < 0:
|
update_active_depth()
|
||||||
update_active_depth()
|
|
||||||
|
|
||||||
# Progressively activate the vine by retexturing its sprites and spawning buds if neccessary
|
|
||||||
# Once max_depth is reached, fully activate the vine
|
|
||||||
func update_active_depth():
|
func update_active_depth():
|
||||||
if active_depth < max_depth:
|
if active_depth < max_depth:
|
||||||
await get_tree().create_timer(0.15).timeout
|
await get_tree().create_timer(0.15).timeout
|
||||||
|
|
@ -155,13 +138,11 @@ func update_active_depth():
|
||||||
if vine_data.size() > active_depth:
|
if vine_data.size() > active_depth:
|
||||||
for sprite in vine_data[active_depth]:
|
for sprite in vine_data[active_depth]:
|
||||||
sprite.texture = ResourceLoader.load(img_path_active)
|
sprite.texture = ResourceLoader.load(img_path_active)
|
||||||
for node in vine_end_data:
|
for data in vine_end_data:
|
||||||
if node.depth == active_depth and not node is Petal:
|
if data.depth == active_depth:
|
||||||
spawn_bud(node.location, node.offset, node.depth)
|
spawn_bud(data.location, data.offset, data.depth)
|
||||||
update_active_depth()
|
update_active_depth()
|
||||||
else: fully_active = true
|
|
||||||
|
|
||||||
# Upon entering the scene, select the applied status, then spawn the inactive vine
|
|
||||||
func _enter_tree() -> void:
|
func _enter_tree() -> void:
|
||||||
var data : Dictionary = status_data.pick_random()
|
var data : Dictionary = status_data.pick_random()
|
||||||
status_name = data.name
|
status_name = data.name
|
||||||
|
|
@ -169,21 +150,27 @@ func _enter_tree() -> void:
|
||||||
img_path_active = data.img_path
|
img_path_active = data.img_path
|
||||||
init_random()
|
init_random()
|
||||||
|
|
||||||
# Initializes a random vine
|
func random_vine_node_at(location):
|
||||||
|
var offset = random_offset()
|
||||||
|
return VineNode.new(self, location, offset)
|
||||||
|
|
||||||
func init_random():
|
func init_random():
|
||||||
# First, include the petal
|
|
||||||
Grid.add_vine_to(self, petal.location)
|
Grid.add_vine_to(self, petal.location)
|
||||||
vine_locations.append(petal.location)
|
vine_locations.append(petal.location)
|
||||||
vine_end_data.append(petal)
|
vine_end_data.append(petal)
|
||||||
# Attempt to grow a new vine for a total 6 - 12 times
|
for i in range(randi_range(2,2)):
|
||||||
var grow_attempts = randi_range(6,12)
|
|
||||||
while grow_attempts > 0:
|
|
||||||
# Attempt to grow from a random end to 1 - 4 random directions
|
|
||||||
var end = vine_end_data.pick_random()
|
var end = vine_end_data.pick_random()
|
||||||
for branch in range(min(ceil(randf() * 4), grow_attempts)):
|
var branches_count = 0
|
||||||
grow_attempts -= 1
|
for branch in range(ceil(randf() * 4)):
|
||||||
var dir = [Vector2.UP, Vector2.DOWN, Vector2.RIGHT, Vector2.LEFT].pick_random()
|
var dir = [Vector2.UP, Vector2.DOWN, Vector2.RIGHT, Vector2.LEFT].pick_random()
|
||||||
var target_location = Global.vec_mod(end.location + dir, Grid.num_collumns, true)
|
var target_location = Global.vec_mod(end.location + dir, Grid.num_collumns, true)
|
||||||
if target_location.y <= Grid.max_bud_height + 1 and Grid.get_vines_at(target_location).is_empty():
|
if target_location.y <= Grid.max_bud_height + 1 and Grid.get_vines_at(target_location).is_empty():
|
||||||
var target = GridNode.random_at(target_location)
|
if not (target_location.y <= 0 or target_location.y > Grid.max_bud_height):
|
||||||
|
branches_count += 1
|
||||||
|
var target = random_vine_node_at(target_location)
|
||||||
grow_vine_sequence(end, target, true, true)
|
grow_vine_sequence(end, target, true, true)
|
||||||
|
if i==0 and branches_count == 1:
|
||||||
|
vine_end_data.append(petal)
|
||||||
|
|
||||||
|
func random_offset():
|
||||||
|
return Vector2(randf_range(60, 240), randf_range(90, 270))
|
||||||
|
|
|
||||||
|
|
@ -1,37 +1,40 @@
|
||||||
class_name GridNode extends Node2D
|
class_name VineNode extends Node2D
|
||||||
|
|
||||||
# Setting location and offset automatically adjusts position
|
@export var vine : Vine
|
||||||
@export var location : Vector2 :
|
@export var location : Vector2 :
|
||||||
set(new_loc):
|
set(new_loc):
|
||||||
location = Global.vec_mod(new_loc, Grid.num_collumns, true)
|
location = Global.vec_mod(new_loc, Grid.num_collumns, true)
|
||||||
update_position()
|
@export var offset : Vector2
|
||||||
@export var offset : Vector2 :
|
|
||||||
set(new_offset):
|
|
||||||
offset = new_offset
|
|
||||||
update_position()
|
|
||||||
@export var depth : int
|
@export var depth : int
|
||||||
|
|
||||||
# Setting the global position automatically adjusts location and offset
|
func _get(property: StringName) -> Variant:
|
||||||
|
if property == "position":
|
||||||
|
update_position()
|
||||||
|
return position
|
||||||
|
if property == "global_position":
|
||||||
|
update_position()
|
||||||
|
return global_position
|
||||||
|
return null
|
||||||
|
|
||||||
func _set(property: StringName, value: Variant) -> bool:
|
func _set(property: StringName, value: Variant) -> bool:
|
||||||
if property == "global_position":
|
if property == "global_position":
|
||||||
location = Grid.get_location_from_world_pos(value)
|
location = Grid.get_location_from_world_pos(value)
|
||||||
offset = Grid.get_offset_from_world_pos(value)
|
offset = Grid.get_offset_from_world_pos(value)
|
||||||
update_position()
|
update_position()
|
||||||
return true
|
return true
|
||||||
|
if property == "position":
|
||||||
|
update_position()
|
||||||
|
return false
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# Generates position from location and offset
|
|
||||||
func update_position():
|
func update_position():
|
||||||
global_position = Grid.get_world_position(location, offset)
|
global_position = Grid.get_world_position(location, offset)
|
||||||
|
|
||||||
func _enter_grid() -> void:
|
func _enter_grid() -> void:
|
||||||
update_position()
|
update_position()
|
||||||
|
|
||||||
# Constructor for Grid Nodes
|
func _init(_vine = null, _location = Vector2.ZERO, _offset = Vector2.ZERO, _depth = 0):
|
||||||
func _init(_location = Vector2.ZERO, _offset = Vector2.ZERO):
|
vine = _vine
|
||||||
location = _location
|
location = _location
|
||||||
offset = _offset
|
offset = _offset
|
||||||
|
depth = _depth
|
||||||
static func random_at(_location):
|
|
||||||
var rand_offset = Vector2(randf_range(60, 240), randf_range(90, 270))
|
|
||||||
return GridNode.new(_location, rand_offset)
|
|
||||||
|
|
@ -6,43 +6,40 @@ class_name BuildingGenerator extends Node
|
||||||
@export var only_on_first_load = false
|
@export var only_on_first_load = false
|
||||||
static var first_load = true
|
static var first_load = true
|
||||||
|
|
||||||
# Determine the player's column, then choose one in the opposite third of the circle
|
func random_oppostite_collumn() -> int:
|
||||||
func random_opposite_collumn() -> int:
|
var playerpos = %Player.position
|
||||||
var player_location = Grid.get_location_from_world_pos(%Player.position)
|
var player_angle = atan2(playerpos.y, playerpos.x)
|
||||||
var offset = randi_range(int(Grid.num_collumns / 3.0), int(2 * Grid.num_collumns / 3.0))
|
|
||||||
var collumn = player_location.x + offset
|
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
|
||||||
|
|
||||||
return collumn
|
return collumn
|
||||||
|
|
||||||
func random_collumn() -> int:
|
func random_collumn() -> int:
|
||||||
return randi_range(0, Grid.num_collumns - 1)
|
return randi_range(0, Grid.num_collumns - 1)
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# The initial buildings in the main menu are only to be spawned upon first loading
|
|
||||||
if not (only_on_first_load and not first_load):
|
if not (only_on_first_load and not first_load):
|
||||||
first_load = false
|
first_load = false
|
||||||
for i in range(initial_buildings):
|
for i in range(initial_buildings):
|
||||||
# For each building, attempt spawns a few times.
|
|
||||||
# Spawns are not viable if they are within the player spawn protection
|
|
||||||
# or overlap with existing buildings
|
|
||||||
for j in range(spawn_attempts):
|
for j in range(spawn_attempts):
|
||||||
var collumn = random_collumn()
|
var collumn = random_collumn()
|
||||||
if initial_spawn_protection and 43 <= collumn and collumn <= 49:
|
if initial_spawn_protection and 43 <= collumn and collumn <= 49:
|
||||||
continue
|
continue
|
||||||
var building = random_building()
|
var building = randomize_building()
|
||||||
|
building.z_index = -2
|
||||||
if Grid.add_building_to_collumn(building, collumn):
|
if Grid.add_building_to_collumn(building, collumn):
|
||||||
break
|
break
|
||||||
|
|
||||||
# Each time the building generator's timer runs out, generate a new building
|
|
||||||
func _on_timer_timeout() -> void:
|
func _on_timer_timeout() -> void:
|
||||||
for i in range(spawn_attempts):
|
for i in range(spawn_attempts):
|
||||||
var collumn = random_opposite_collumn()
|
var collumn = random_oppostite_collumn()
|
||||||
var building : Building = random_building()
|
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
|
break
|
||||||
|
|
||||||
# Picks a random building from the list. Sets the z_index.
|
func randomize_building() -> Building:
|
||||||
func random_building() -> Building:
|
|
||||||
var index = randi() % Grid.packed_buildings.size()
|
var index = randi() % Grid.packed_buildings.size()
|
||||||
var ret = Grid.packed_buildings[index].instantiate()
|
return Grid.packed_buildings[index].instantiate()
|
||||||
ret.z_index = -2
|
|
||||||
return ret
|
|
||||||
|
|
|
||||||
5
world/draw_circle.gd
Normal file
5
world/draw_circle.gd
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
extends Node2D
|
||||||
|
@export var radius : float;
|
||||||
|
|
||||||
|
func _draw():
|
||||||
|
draw_circle(Vector2.ZERO, radius, Color.BLACK, true, -1.0, true)
|
||||||
1
world/draw_circle.gd.uid
Normal file
1
world/draw_circle.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b5fhsy1xlreco
|
||||||
|
|
@ -3,7 +3,7 @@ extends Node2D
|
||||||
@export var grass : PackedScene
|
@export var grass : PackedScene
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
# Place grass
|
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()
|
var grass_placed : Building = grass.instantiate()
|
||||||
grass_placed.location = Vector2(column, 0)
|
grass_placed.location = Vector2(column, 0)
|
||||||
|
|
|
||||||
|
|
@ -42,33 +42,15 @@ func add_building_to_collumn(building : Building, collumn : int):
|
||||||
building.free()
|
building.free()
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
|
||||||
add_child(building)
|
add_child(building)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
# Adds children of given node to the grid and their building.
|
|
||||||
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)
|
|
||||||
|
|
||||||
# Returns the global position for a given grid location and offset
|
|
||||||
func get_world_position (location: Vector2, offset: Vector2 = Vector2.ZERO) -> Vector2:
|
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 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
|
var angle = (location.x + offset.x / cell_height) * TAU / num_collumns
|
||||||
return height * Vector2.from_angle(angle)
|
return height * Vector2.from_angle(angle)
|
||||||
|
|
||||||
# Returns the grid location for a given global position
|
|
||||||
func get_location_from_world_pos(pos : Vector2):
|
func get_location_from_world_pos(pos : Vector2):
|
||||||
var angle = fposmod(pos.angle(), TAU)
|
var angle = fposmod(pos.angle(), TAU)
|
||||||
var x = floor(num_collumns * angle / TAU)
|
var x = floor(num_collumns * angle / TAU)
|
||||||
|
|
@ -76,7 +58,6 @@ func get_location_from_world_pos(pos : Vector2):
|
||||||
var y = ceil((height - ground_radius)/cell_height)
|
var y = ceil((height - ground_radius)/cell_height)
|
||||||
return Vector2(x, y)
|
return Vector2(x, y)
|
||||||
|
|
||||||
# Returns the offset with respect to the grid location for a given global position
|
|
||||||
func get_offset_from_world_pos(pos : Vector2):
|
func get_offset_from_world_pos(pos : Vector2):
|
||||||
var angle = pos.angle()
|
var angle = pos.angle()
|
||||||
var x = fposmod(num_collumns * angle / TAU, 1) * cell_height
|
var x = fposmod(num_collumns * angle / TAU, 1) * cell_height
|
||||||
|
|
@ -84,10 +65,7 @@ func get_offset_from_world_pos(pos : Vector2):
|
||||||
var y = fposmod(-(height - ground_radius)/cell_height, 1) * cell_height
|
var y = fposmod(-(height - ground_radius)/cell_height, 1) * cell_height
|
||||||
return Vector2(x, y)
|
return Vector2(x, y)
|
||||||
|
|
||||||
# Resets objects in the grids and the item pool.
|
|
||||||
# Also initializes vines_per_node.
|
|
||||||
func reset():
|
func reset():
|
||||||
ItemSpawn.item_pool = ResourceLoader.load("res://items/generic/item_pool.tres","",ResourceLoader.CACHE_MODE_IGNORE)
|
|
||||||
for obj in get_children():
|
for obj in get_children():
|
||||||
obj.free()
|
obj.free()
|
||||||
buildings = []
|
buildings = []
|
||||||
|
|
@ -98,22 +76,22 @@ func reset():
|
||||||
arr.append([])
|
arr.append([])
|
||||||
vines_per_node.append(arr)
|
vines_per_node.append(arr)
|
||||||
|
|
||||||
# Returns all vines present at given grid location.
|
|
||||||
func get_vines_at(location) -> Array:
|
func get_vines_at(location) -> Array:
|
||||||
location = Global.vec_mod(location, num_collumns, true)
|
location = Global.vec_mod(location, num_collumns, true)
|
||||||
return vines_per_node[location.x][location.y]
|
return vines_per_node[location.x][location.y]
|
||||||
|
|
||||||
# Registers a vine at a given grid location.
|
|
||||||
func add_vine_to(vine, location) -> void:
|
func add_vine_to(vine, location) -> void:
|
||||||
if location.y > max_bud_height + 1 or location.y < 0:
|
if location.y > max_bud_height + 1 or location.y < 0:
|
||||||
return
|
return
|
||||||
location = Global.vec_mod(location, num_collumns, true)
|
location = Global.vec_mod(location, num_collumns, true)
|
||||||
vines_per_node[location.x][location.y].append(vine)
|
vines_per_node[location.x][location.y].append(vine)
|
||||||
|
|
||||||
# Calls _enter_grid on all children.
|
# for testing
|
||||||
func grid_entrance_callback(object : Node):
|
#func _ready() -> void:
|
||||||
# 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"):
|
#for i in range(100):
|
||||||
object.call_deferred("_enter_grid")
|
#var test_building = packed_buildings[0].instantiate()
|
||||||
|
#var collumn = randi() % 60
|
||||||
|
#add_building_to_collumn(test_building, collumn)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue