Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make grid a resource #67

Merged
merged 11 commits into from
Oct 28, 2023
38 changes: 20 additions & 18 deletions addons/gaea/generators/2D/cellular_generator/cellular_generator.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extends GaeaGenerator2D
@export var settings: CellularGeneratorSettings


func generate(starting_grid: Dictionary = {}) -> void:
func generate(starting_grid: GaeaGrid = null) -> void:
if Engine.is_editor_hint() and not preview:
return

Expand All @@ -21,7 +21,7 @@ func generate(starting_grid: Dictionary = {}) -> void:

var time_now :int = Time.get_ticks_msec()

if starting_grid.is_empty():
if starting_grid == null:
erase()
else:
grid = starting_grid
Expand All @@ -33,9 +33,11 @@ func generate(starting_grid: Dictionary = {}) -> void:
if is_instance_valid(next_pass):
next_pass.generate(grid)
return

var time_elapsed :int = Time.get_ticks_msec() - time_now
if OS.is_debug_build():
print("%s: Generating took %s seconds" % [name, (float(time_elapsed) / 100)])

grid_updated.emit()


Expand All @@ -44,27 +46,27 @@ func _set_noise() -> void:
for x in range(settings.world_size.x):
for y in range(settings.world_size.y):
if randf() > settings.noise_density:
grid[Vector2(x, y)] = settings.tile
grid.set_value(Vector2i(x, y), settings.tile)
else:
grid[Vector2(x, y)] = null
grid.set_value(Vector2i(x, y), null)


func _smooth() -> void:
for i in settings.smooth_iterations:
var tempGrid: Dictionary = grid.duplicate()
for tile in grid.keys():
var deadNeighborsCount := get_neighbor_count_of_type(
grid, tile, null
)
if grid[tile] == settings.tile and deadNeighborsCount > settings.max_floor_empty_neighbors:
tempGrid[tile] = null
elif grid[tile] == null and deadNeighborsCount <= settings.min_empty_neighbors:
tempGrid[tile] = settings.tile
grid = tempGrid

for tile in grid.keys():
if grid[tile] == null:
grid.erase(tile)
var _temp_grid: GaeaGrid = grid.clone()

for cell in grid.get_cells():
var dead_neighbors_count: int = grid.get_amount_of_empty_neighbors(cell)
if grid.get_value(cell) == settings.tile and dead_neighbors_count > settings.max_floor_empty_neighbors:
_temp_grid.set_value(cell, null)
elif grid.get_value(cell) == null and dead_neighbors_count <= settings.min_empty_neighbors:
_temp_grid.set_value(cell, settings.tile)

grid = _temp_grid

for cell in grid.get_cells():
if grid.get_value(cell) == null:
grid.erase(cell)


### Editor ###
Expand Down
8 changes: 4 additions & 4 deletions addons/gaea/generators/2D/chunk_aware_generator_2d.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,26 @@ func _ready() -> void:
super._ready()


func generate_chunk(chunk_position: Vector2i, starting_grid: Dictionary = {}) -> void:
func generate_chunk(chunk_position: Vector2i, starting_grid: GaeaGrid = null) -> void:
push_warning("generate_chunk method not overriden at %s" % name)


func erase_chunk(chunk_position: Vector2i) -> void:
for x in get_chunk_range(chunk_position.x):
for y in get_chunk_range(chunk_position.y):
grid.erase(Vector2(x, y))
grid.erase(Vector2i(x, y))

chunk_updated.emit(chunk_position)



func _apply_modifiers_chunk(modifiers, chunk_position: Vector2i) -> void:
func _apply_modifiers_chunk(modifiers: Array[Modifier2D], chunk_position: Vector2i) -> void:
for modifier in modifiers:
if not (modifier is ChunkAwareModifier2D):
push_error("%s is not a Chunk compatible modifier!" % modifier.resource_name)
continue

grid = modifier.apply_chunk(grid, self, chunk_position)
modifier.apply_chunk(grid, self, chunk_position)


func unload_chunk(chunk_position: Vector2i) -> void:
Expand Down
56 changes: 3 additions & 53 deletions addons/gaea/generators/2D/generator_2d.gd
Original file line number Diff line number Diff line change
Expand Up @@ -15,56 +15,6 @@ extends GaeaGenerator
@export var next_pass: GaeaGenerator2D


const NEIGHBORS := [Vector2.RIGHT, Vector2.LEFT, Vector2.UP, Vector2.DOWN,
Vector2(1, 1), Vector2(1, -1), Vector2(-1, -1), Vector2(-1, 1)]


### Utils ###


func get_tile(pos: Vector2) -> TileInfo:
return grid[pos]


static func are_all_neighbors_of_type(grid: Dictionary, pos: Vector2, type: TileInfo) -> bool:
for neighbor in NEIGHBORS:
if not grid.has(pos + neighbor):
continue

if grid[pos + neighbor] != type:
return false

return true


static func get_neighbor_count_of_type(grid: Dictionary, pos: Vector2, type: TileInfo) -> int:
var count = 0

for neighbor in NEIGHBORS:
if not grid.has(pos + neighbor):
if type == null:
count += 1
continue

if grid[pos + neighbor] == type:
count += 1

return count


static func get_tiles_of_type(type: TileInfo, grid: Dictionary) -> Array[Vector2i]:
var tiles: Array[Vector2i] = []
for tile in grid:
if grid[tile] == type:
tiles.append(tile)

return tiles


static func get_area_from_grid(grid: Dictionary) -> Rect2i:
var keys = grid.keys()
if keys.is_empty():
return Rect2i()
var rect: Rect2i = Rect2i(keys.front(), Vector2.ZERO)
for k in keys: rect = rect.expand(k)
return rect
func _ready() -> void:
grid = GaeaGrid2D.new()
super()
45 changes: 45 additions & 0 deletions addons/gaea/generators/2D/grid_2d.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
class_name GaeaGrid2D
extends GaeaGrid


const SURROUNDING := [Vector2i.RIGHT, Vector2i.LEFT, Vector2i.UP, Vector2i.DOWN,
Vector2i(1, 1), Vector2i(1, -1), Vector2i(-1, -1), Vector2i(-1, 1)]


## Returns a [Rect2i] of the full extent of the grid.
func get_area() -> Rect2i:
var cells = self.get_cells()
if cells.is_empty():
return Rect2i()

var rect: Rect2i = Rect2i(cells.front(), Vector2i.ZERO)
for cell in cells:
rect = rect.expand(cell)
return rect


### Helper Functions ###


## Returns the amount of non-existing and null cells (including corners) around [param pos].
func get_amount_of_empty_neighbors(pos: Vector2i) -> int:
var count: int = 0

for n in SURROUNDING:
if get_value(pos + n) == null:
count += 1

return count


## Returns an array with the positions of all cells surrounding [param pos], including corners.[br]
## If [param ignore_empty] is [code]true[/code], all non-existing cells will not be counted. Cells of value [code]null[/code] will still be counted.
func get_surrounding_cells(pos: Vector2i, ignore_empty: bool = false) -> Array[Vector2i]:
var surrounding: Array[Vector2i]

for n in SURROUNDING:
if ignore_empty and not has_cell(pos + n):
continue
surrounding.append(pos + n)

return surrounding
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func _ready() -> void:
super()


func generate(starting_grid: Dictionary = {}) -> void:
func generate(starting_grid: GaeaGrid = null) -> void:
if Engine.is_editor_hint() and not preview:
return
var time_now :int = Time.get_ticks_msec()
Expand All @@ -28,31 +28,33 @@ func generate(starting_grid: Dictionary = {}) -> void:
if settings.random_noise_seed:
settings.noise.seed = randi()

if starting_grid.is_empty():
if starting_grid == null:
erase()
else:
grid = starting_grid
_set_grid()
_apply_modifiers(settings.modifiers)

if is_instance_valid(next_pass):
next_pass.generate()
next_pass.generate(grid)
return

var time_elapsed :int = Time.get_ticks_msec() - time_now
if OS.is_debug_build():
print("%s: Generating took %s seconds" % [name, float(time_elapsed) / 100 ])

grid_updated.emit()


func generate_chunk(chunk_position: Vector2i, starting_grid: Dictionary = {}) -> void:
func generate_chunk(chunk_position: Vector2i, starting_grid: GaeaGrid = null) -> void:
if Engine.is_editor_hint() and not preview:
return

if not settings:
push_error("%s doesn't have a settings resource" % name)
return

if starting_grid.is_empty():
if starting_grid == null:
erase_chunk(chunk_position)
else:
grid = starting_grid
Expand Down Expand Up @@ -103,4 +105,4 @@ func _set_grid_area(area: Rect2i) -> void:
var height = floor(settings.noise.get_noise_1d(x) * settings.height_intensity + settings.height_offset)
for y in range(area.position.y, area.end.y):
if y > -height and y <= -settings.min_height:
grid[Vector2(x, y)] = settings.tile
grid.set_value(Vector2i(x, y), settings.tile)
14 changes: 8 additions & 6 deletions addons/gaea/generators/2D/noise_generator/noise_generator.gd
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ func _ready() -> void:
super._ready()


func generate(starting_grid: Dictionary = {}) -> void:
func generate(starting_grid: GaeaGrid = null) -> void:
if Engine.is_editor_hint() and not preview:
return
var time_now :int = Time.get_ticks_msec()
Expand All @@ -30,7 +30,7 @@ func generate(starting_grid: Dictionary = {}) -> void:
settings.noise.seed = randi()


if starting_grid.is_empty():
if starting_grid == null:
erase()
else:
grid = starting_grid
Expand All @@ -41,21 +41,23 @@ func generate(starting_grid: Dictionary = {}) -> void:
if is_instance_valid(next_pass):
next_pass.generate(grid)
return

var time_elapsed :int = Time.get_ticks_msec() - time_now
if OS.is_debug_build():
print("%s: Generating took %s seconds" % [name, float(time_elapsed) / 100 ])

grid_updated.emit()


func generate_chunk(chunk_position: Vector2i, starting_grid: Dictionary = {}) -> void:
func generate_chunk(chunk_position: Vector2i, starting_grid: GaeaGrid = null) -> void:
if Engine.is_editor_hint() and not preview:
return

if not settings:
push_error("%s doesn't have a settings resource" % name)
return

if starting_grid.is_empty():
if starting_grid == null:
erase_chunk(chunk_position)
else:
grid = starting_grid
Expand Down Expand Up @@ -99,9 +101,9 @@ func _set_grid_area(rect: Rect2i) -> void:

var noise = settings.noise.get_noise_2d(x, y)
if settings.falloff_enabled and settings.falloff_map and not settings.infinite:
noise = ((noise + 1) * settings.falloff_map.get_value(Vector2(x, y))) - 1.0
noise = ((noise + 1) * settings.falloff_map.get_value(Vector2i(x, y))) - 1.0

for threshold in settings.tiles:
if noise > threshold:
grid[Vector2(x, y)] = settings.tiles[threshold]
grid.set_value(Vector2i(x, y), settings.tiles[threshold])
break
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var _walkers : Array[Walker]
var _walked_tiles : Array[Vector2]


func generate(starting_grid: Dictionary = {}) -> void:
func generate(starting_grid: GaeaGrid = null) -> void:
if Engine.is_editor_hint() and not preview:
return
var time_now :int = Time.get_ticks_msec()
Expand All @@ -28,7 +28,7 @@ func generate(starting_grid: Dictionary = {}) -> void:
push_error("%s doesn't have a settings resource" % name)
return

if starting_grid.is_empty():
if starting_grid == null:
erase()
else:
grid = starting_grid
Expand All @@ -41,9 +41,11 @@ func generate(starting_grid: Dictionary = {}) -> void:
if is_instance_valid(next_pass):
next_pass.generate(grid)
return

var time_elapsed :int = Time.get_ticks_msec() - time_now
if OS.is_debug_build():
print("%s: Generating took %s seconds" % [name, float(time_elapsed) / 100 ])

grid_updated.emit()


Expand Down Expand Up @@ -81,7 +83,7 @@ func _generate_floor() -> void:
iterations += 1

for tile in _walked_tiles:
grid[tile] = settings.tile
grid.set_value(Vector2i(tile), settings.tile)

_walkers.clear()
_walked_tiles.clear()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ enum FullnessCheck {
## build large open areas.[br]
## [b]Note:[/b] Chances are between [code]0-1[/code]
@export var room_chances = {
Vector2(2, 2): 0.5,
Vector2(3, 3): 0.1
Vector2i(2, 2): 0.5,
Vector2i(3, 3): 0.1
}
@export_group("")

Expand All @@ -55,7 +55,7 @@ var constrain_world_size : bool = false :
return
constrain_world_size = value
notify_property_list_changed()
var world_size := Vector2(30, 30)
var world_size := Vector2i(30, 30)


func _get_property_list() -> Array[Dictionary]:
Expand Down
Loading