Skip to content

Commit

Permalink
Merge pull request #148 from BenjaTK/docs
Browse files Browse the repository at this point in the history
Clarify filtering in modifiers and add "Only Empty Cells" option
  • Loading branch information
BenjaTK authored Aug 3, 2024
2 parents 1ab0074 + 9745c53 commit 6a950d0
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 20 deletions.
37 changes: 27 additions & 10 deletions addons/gaea/modifiers/modifier.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,29 @@ class_name Modifier
extends Resource
##@tutorial(Modifiers): https://benjatk.github.io/Gaea/#/modifiers

enum FilterType { NONE, BLACKLIST, WHITELIST } ## Won't apply any filtering. ## The modifier won't affect the [TileInfo]s in any of the [param check_for_in_layers] whose [param id] can be found in [param filter_ids]. ## The modifier will ONLY affect the [TileInfo]s in any of the [param check_for_in_layers] whose [param id] can be found in [param filter_ids].
enum FilterType {
NONE, ## Won't apply any filtering.
BLACKLIST, ## The modifier won't affect the [TileInfo]s in any of the [param layers] whose [param id] can be found in [param ids].
WHITELIST, ## The modifier will ONLY affect the [TileInfo]s in any of the [param layers] whose [param id] can be found in [param ids].
ONLY_EMPTY_CELLS ## The modifier will ONLY affect empty ([code]null[/code]) cells.
}

@export_group("")
@export var enabled: bool = true
@export var affected_layers: Array[int] = [0]
@export_group("Filters", "filter_")
@export_group("Filtering", "filter_")
## [i]Note: Some modifiers don't support filtering.[/i]
@export var filter_type: FilterType = FilterType.NONE:
set(value):
filter_type = value
notify_property_list_changed()
## All layers the filter should check for to find the ids in [param check_for_ids].[br][br]
## [b]E.g:[/b] If a NoisePainter wants to place a tile in (0, 0), and the filter type is WHITELIST, it checks that
## there's at least one tile in (0, 0) in any of the layers whose id can be found in [param check_for_ids].
@export var filter_check_for_in_layers: Array[int] = []
## An array containing ids that will be used
## to filter the modifier.
@export var filter_check_for_ids: Array[String] = []
@export var filter_ids: Array[String] = []
## All layers the filter should check in for the other filtering options.
## [b]E.g:[/b] If a NoisePainter wants to place a tile in (0, 0), and the filter type is WHITELIST, it checks that
## there's at least one tile in (0, 0) in any of the layers whose id can be found in [param check_for_ids].
@export var filter_layers: Array[int] = []


func apply(grid: GaeaGrid, generator: GaeaGenerator) -> void:
Expand All @@ -33,14 +38,26 @@ func _passes_filter(grid: GaeaGrid, cell) -> bool:
if filter_type == FilterType.NONE:
return true

for layer in filter_check_for_in_layers:
if filter_type == FilterType.ONLY_EMPTY_CELLS:
for layer in grid.get_layer_count():
if grid.get_value(cell, layer) != null:
return false
return true

var layers: Array = filter_layers
if layers.is_empty():
layers = grid.get_grid().keys()

for layer in layers:
var value = grid.get_value(cell, layer)
if value is TileInfo and value.id in filter_check_for_ids:
if value is TileInfo and value.id in filter_ids:
return filter_type == FilterType.WHITELIST

return filter_type == FilterType.BLACKLIST


func _validate_property(property: Dictionary) -> void:
if property.name.begins_with("filter_check") and filter_type == FilterType.NONE:
if (property.name == "filter_ids" or property.name == "filter_layers") and filter_type == FilterType.NONE:
property.usage = PROPERTY_USAGE_NONE
elif property.name == "filter_ids" and filter_type == FilterType.ONLY_EMPTY_CELLS:
property.usage = PROPERTY_USAGE_NONE
14 changes: 13 additions & 1 deletion docs/modifiers.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
# Modifiers

**Modifiers** are similar to those in software like Blender. You add these to your GeneratorSettings, and they get applied after the generation is finished, giving you varied results and possibilities.
**Modifiers** are similar to those in software like Blender. You add these to your GeneratorSettings, and they get applied after the generation is finished, giving you varied results and possibilities. You can think of them this way: each cell in the grid is checked, and if it meets a certain condition, it will get modified (deleted, replaced with another `TileInfo` or a `TileInfo` will be placed in the same spot on a different layer).

> **NOTE**: In Gaea, the modifiers' array order matters. Modifiers get applied in this order, so different sequences can give different results.
## Filtering

Modifiers can be filtered. This means it will only modify certain tiles.

`filter_type`: can be NONE, BLACKLIST, WHITELIST, or ONLY_EMPTY_CELLS.

`filter_ids`: in BLACKLIST, it will NOT attempt to modify tiles with an `id` that can be found in this list (`id`s are strings that make identifying `TileInfo`s easier, see [Gaea's Resources](resources.md)). WHITELIST will invert this logic. _For example, using a `NoisePainter` to only place gold ore in tiles with the `id` "stone"._

`filter_layers`: it will only check in these layers for the `id`s mentioned above or, if `filter_type` is ONLY_EMPTY_CELLS, for an empty cell. Leaving this array empty, the filtering will check for all layers.

## List

There are a few modifiers in Gaea at the moment:

### <img src="assets/icons/generate_borders.svg" width="24" height="24" style="float:left;margin:0px 8px 0px 0px"> Generate Borders
Expand Down
8 changes: 6 additions & 2 deletions docs/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ Gaea takes advantage of Godot's **resources**. In this addon, they're used for t

Probably the most important resource in Gaea, it holds a dictionary of cells and their values, filled by the various generators found in the add-on. It can be easily saved using various methods, which means you can keep the world you generated without problem.

## TileInfo
This resource is stored in a certain position in the generator's grid. The base class is empty, but the subclasses such as `TilemapTileInfo` contain data that the renderer takes and uses to draw the grid.

`id`: A string value that represents your `TileInfo`. (e.g "grass"). This is used for filtering modifiers and more.\
`layer`: The `GaeaGrid` layer the TileInfo will be placed on. If it doesn't exist yet, it will automatically be created.

## GeneratorSettings
Each generator has a unique `GeneratorSettings` resource, which includes variables like world size, rules, and the modifiers that will be applied to your generation.

Expand All @@ -14,5 +20,3 @@ You can use these resources to create different world types, floors for a roguel
## Modifiers
Modifiers take the generation and change it algorithmically, similar to how Blender's modifiers work. They're non-destructive, meaning you can remove them, change their order, etc. without worrying about breaking your generator.

## TileInfo
This resource is stored in a certain position in the generator's grid. The base class is empty, but the subclasses such as `TilemapTileInfo` contain data that the renderer takes and uses to draw the grid.
19 changes: 12 additions & 7 deletions scenes/demos/heightmap/terraria-like_generation_settings.tres
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
[ext_resource type="Script" path="res://addons/gaea/generators/2D/heightmap_generator/heightmap_generator_2d_settings.gd" id="5_haojk"]

[sub_resource type="Resource" id="Resource_6kmi4"]
resource_name = "Stone"
script = ExtResource("2_6f082")
type = 0
tilemap_layer = 0
source_id = 1
atlas_coord = Vector2i(0, 0)
alternative_tile = 0
id = ""
id = "stone"
layer = 0

[sub_resource type="Resource" id="Resource_pu43q"]
Expand Down Expand Up @@ -52,7 +53,7 @@ filter_type = 0

[sub_resource type="FastNoiseLite" id="FastNoiseLite_1mckf"]
noise_type = 3
seed = -319710493
seed = 1045566220
frequency = 0.012
fractal_type = 2
fractal_octaves = 3
Expand All @@ -73,7 +74,7 @@ affected_layers = Array[int]([0])
filter_type = 0

[sub_resource type="FastNoiseLite" id="FastNoiseLite_kyspj"]
seed = -879214990
seed = 486061723
frequency = 0.0617
fractal_octaves = 2
fractal_lacunarity = 2.95
Expand Down Expand Up @@ -101,10 +102,12 @@ bounds_max = Vector2(0, 0)
bounds_min = Vector2(0, 0)
salt = 1908549200
enabled = true
filter_type = 0
filter_type = 2
filter_ids = Array[String](["stone"])
filter_layers = Array[int]([])

[sub_resource type="FastNoiseLite" id="FastNoiseLite_vkmxs"]
seed = -885391533
seed = 479885180
frequency = 0.0511
fractal_lacunarity = 0.565
domain_warp_type = 2
Expand Down Expand Up @@ -133,11 +136,13 @@ bounds_max = Vector2(0, 0)
bounds_min = Vector2(0, 0)
salt = 1902372657
enabled = true
filter_type = 0
filter_type = 2
filter_ids = Array[String](["stone"])
filter_layers = Array[int]([])

[sub_resource type="FastNoiseLite" id="FastNoiseLite_mwtbk"]
noise_type = 3
seed = 1507203106
seed = -1422487477

[sub_resource type="Resource" id="Resource_hitrj"]
script = ExtResource("2_6f082")
Expand Down

0 comments on commit 6a950d0

Please sign in to comment.