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