67 lines
2.4 KiB
GDScript
67 lines
2.4 KiB
GDScript
extends Node
|
|
## The generator works with pure numbers, you'll need something else to convert it to actual tiles
|
|
|
|
## Makes a new chunk, derived from the given WFC samples
|
|
func generate_chunk_at(_x: int, _y: int, _chunk_array: Array[Chunk], _samples: Array[PackedInt32Array]) -> Chunk:
|
|
#TODO: fix the chunk-edges
|
|
var chunk: Chunk = Chunk.new(_x, _y)
|
|
|
|
while _set_lowest_entropy_tile(chunk, _samples) > 0: pass
|
|
|
|
_chunk_array.append(chunk)
|
|
return chunk
|
|
|
|
## Returns the entropy of the selected tile
|
|
func _set_lowest_entropy_tile(chunk: Chunk, _samples: Array[PackedInt32Array]) -> int:
|
|
var entropy: Array[Array] = []
|
|
entropy.resize(Chunk.CHUNK_WIDTH * Chunk.CHUNK_HEIGHT)
|
|
|
|
#iterate over unset tiles with valid neighbours
|
|
for x in range(Chunk.CHUNK_WIDTH):
|
|
for y in range((Chunk.CHUNK_HEIGHT)):
|
|
if chunk.data[y * Chunk.CHUNK_HEIGHT + x] == 0: #direct access, to skip extra checks
|
|
entropy[y * Chunk.CHUNK_HEIGHT + x] = _find_valid_samples(chunk, x, y, _samples)
|
|
|
|
#find the lowest-entropy tile
|
|
var lowest: int = -1
|
|
for i in range(Chunk.CHUNK_WIDTH * Chunk.CHUNK_HEIGHT):
|
|
if entropy[i].size() == 0: continue #no options
|
|
|
|
if lowest < 0:
|
|
lowest = i
|
|
continue
|
|
if entropy[i].size() < entropy[lowest].size():
|
|
lowest = i
|
|
|
|
#finished
|
|
if lowest < 0: return lowest
|
|
|
|
#finally, set the tile from the sample
|
|
var s: PackedInt32Array = entropy[lowest].pick_random()
|
|
chunk.data[lowest] = s[4]
|
|
return entropy.size()
|
|
|
|
## Returns the valid samples
|
|
func _find_valid_samples(chunk: Chunk, tile_x: int, tile_y: int, _samples: Array[PackedInt32Array]) -> Array[PackedInt32Array]:
|
|
var valid: Array[PackedInt32Array] = []
|
|
|
|
#use a lambda for easy reading below
|
|
var compare := func (tile_value: int, sample: int) -> bool:
|
|
return tile_value <= 0 or tile_value == sample
|
|
|
|
#filter the samples
|
|
for sample in _samples:
|
|
if !compare.call(chunk.get_tile(tile_x -1, tile_y -1), sample[0]): continue
|
|
if !compare.call(chunk.get_tile(tile_x , tile_y -1), sample[1]): continue
|
|
if !compare.call(chunk.get_tile(tile_x +1, tile_y -1), sample[2]): continue
|
|
if !compare.call(chunk.get_tile(tile_x -1, tile_y ), sample[3]): continue
|
|
# //
|
|
if !compare.call(chunk.get_tile(tile_x +1, tile_y ), sample[5]): continue
|
|
if !compare.call(chunk.get_tile(tile_x -1, tile_y +1), sample[6]): continue
|
|
if !compare.call(chunk.get_tile(tile_x , tile_y +1), sample[7]): continue
|
|
if !compare.call(chunk.get_tile(tile_x +1, tile_y +1), sample[8]): continue
|
|
|
|
valid.append(sample)
|
|
|
|
return valid
|