diff --git a/gdrl/Debug/test_render_map.gd b/gdrl/Debug/test_render_map.gd index be1fd1d..c432d4b 100644 --- a/gdrl/Debug/test_render_map.gd +++ b/gdrl/Debug/test_render_map.gd @@ -15,7 +15,7 @@ func _draw() -> void: var cell = RL.game.world.map.cells[y][x] draw_rect( Rect2(x*cell_size,y*cell_size,cell_size,cell_size), - Color.RED if cell.blocking else Color.GREEN) + Color.RED if cell.properties.has(Cell.BlockingProp) else Color.GREEN) for y in RL.game.world.entities.all_entities: draw_rect( diff --git a/gdrl/Debug/test_scene.gd b/gdrl/Debug/test_scene.gd index ef99c04..94e73e6 100644 --- a/gdrl/Debug/test_scene.gd +++ b/gdrl/Debug/test_scene.gd @@ -13,19 +13,20 @@ func _ready() -> void: RL.game.world.rng = RandomNumberGenerator.new() RL.game.world.rng.seed = 37 generate_cells(RL.game.world.rng, RL.game.world.map) - for i in 3: + for i in 1: var entity = Entity.new() var pos = RL.game.world.map.get_random_coord() - while RL.game.world.map.get_cell(pos).blocking: + while RL.game.world.map.get_cell(pos).properties.has(Cell.BlockingProp): pos = RL.game.world.map.get_random_coord() entity.position = pos RL.game.world.entities.add_entity(entity) - func generate_cells(rng:RandomNumberGenerator, map:Map): var blocking_cell = Cell.new() - blocking_cell.blocking = true + blocking_cell.properties.append(Cell.BlockingProp) + blocking_cell.resource_name = "blocking" var clear_cell = Cell.new() + clear_cell.resource_name = "clear" var err = map.cells.resize(map_size.y) assert(err == OK) @@ -33,8 +34,8 @@ func generate_cells(rng:RandomNumberGenerator, map:Map): var row:Array = [] row.resize(map_size.x) for p in map_size.x: - # can duplicate() here if we need unique resource-per-cell - row[p] = clear_cell.duplicate() if rng.randf() >= 0.5 else blocking_cell.duplicate() + # we use cell references + row[p] = clear_cell if rng.randf() >= 0.5 else blocking_cell map.cells[i] = row pass diff --git a/gdrl/Debug/test_ui.gd b/gdrl/Debug/test_ui.gd index 3eac466..4789ba6 100644 --- a/gdrl/Debug/test_ui.gd +++ b/gdrl/Debug/test_ui.gd @@ -81,13 +81,14 @@ func press_simulate(): is_simulating = true # generator will not modify world state, just reads it var generators:Array[BaseActionGenerator] = [] - var start_pos = Vector2i( - RL.game.rng.randi_range(0, RL.game.world.map.get_size().x-1), - RL.game.rng.randi_range(0, RL.game.world.map.get_size().y-1)) - generators.append(GenerateTransformCell.new(Vector2i.UP, start_pos, true)) - generators.append(GenerateTransformCell.new(Vector2i.RIGHT, start_pos, true)) - generators.append(GenerateTransformCell.new(Vector2i.LEFT, start_pos, true)) - generators.append(GenerateTransformCell.new(Vector2i.DOWN, start_pos, true)) + var start_pos = RL.game.world.entities.get_entity_by_id(0).position + #Vector2i( + #RL.game.world.rng.randi_range(0, RL.game.world.map.get_size().x-1), + #RL.game.world.rng.randi_range(0, RL.game.world.map.get_size().y-1)) + generators.append(GenerateTransformCell.new(Vector2i.DOWN, start_pos, false)) + #generators.append(GenerateTransformCell.new(Vector2i.RIGHT, start_pos, false)) + #generators.append(GenerateTransformCell.new(Vector2i.LEFT, start_pos, false)) + #generators.append(GenerateTransformCell.new(Vector2i.DOWN, start_pos, false)) await simulate(generators) diff --git a/gdrl/Game/Logic/Action Generators/generate_move_entity.gd b/gdrl/Game/Logic/Action Generators/generate_move_entity.gd index 57293b2..d0fc1dd 100644 --- a/gdrl/Game/Logic/Action Generators/generate_move_entity.gd +++ b/gdrl/Game/Logic/Action Generators/generate_move_entity.gd @@ -31,7 +31,7 @@ func tick(world:WorldState, _new_generators:Array[BaseActionGenerator])->Array: if cell == null: return result - if cell.blocking: + if cell.properties.has(Cell.BlockingProp): # TODO bump action will be needed for vis # multiple count, bump ends set has_moved = true diff --git a/gdrl/Game/Logic/Action Generators/generate_transform_cell.gd b/gdrl/Game/Logic/Action Generators/generate_transform_cell.gd index b934ebe..2e33996 100644 --- a/gdrl/Game/Logic/Action Generators/generate_transform_cell.gd +++ b/gdrl/Game/Logic/Action Generators/generate_transform_cell.gd @@ -46,7 +46,13 @@ func tick(world:WorldState, new_generators:Array[BaseActionGenerator])->Array: return result var cell = world.map.get_cell(current_index) - var action = TransformCell.new(current_index,!cell.blocking, cell.occluding) + var props_to_add:Array[StringName] + var props_to_remove:Array[StringName] + if cell.properties.has(cell.BlockingProp): + props_to_remove.append(cell.BlockingProp) + else: + props_to_add.append(Cell.BlockingProp) + var action = TransformCell.new(current_index,props_to_add, props_to_remove) result.push_back(action) current_index += direction return result diff --git a/gdrl/Game/Logic/Actions/transform_cell.gd b/gdrl/Game/Logic/Actions/transform_cell.gd index c8604d1..90ef4e9 100644 --- a/gdrl/Game/Logic/Actions/transform_cell.gd +++ b/gdrl/Game/Logic/Actions/transform_cell.gd @@ -6,18 +6,44 @@ class_name TransformCell var cell_coord_to_change:Vector2i ### should the target cell become blocking -var target_blocking:bool +var properties_to_add:Array[StringName] ### should the target cells become occluding -var target_occluding:bool +var properties_to_remove:Array[StringName] -func _init(_target_cell:Vector2i, _target_blocking:bool, _target_occluding:bool) -> void: +func _init(_target_cell:Vector2i, _properties_to_add:Array[StringName], _properties_to_remove:Array[StringName]) -> void: cell_coord_to_change = _target_cell - target_occluding = _target_occluding - target_blocking = _target_blocking + properties_to_add = _properties_to_add + properties_to_remove = _properties_to_remove func perform_action(context:WorldState): var cell = context.map.get_cell(cell_coord_to_change) - cell.blocking = target_blocking - cell.occluding = target_occluding + var needs_transform = false + for i in properties_to_add: + if !cell.properties.has(i): + needs_transform = true + + # only check removes if we need to + if not needs_transform: + for i in properties_to_remove: + if cell.properties.has(i): + needs_transform = true + + if needs_transform: + var newCell = cell + if not cell.unique: + #cell duplicate for resource independence + newCell = cell.duplicate(true) + newCell.unique = true + newCell.resource_name = newCell.resource_name + "_instance" + context.map.set_cell(cell_coord_to_change, newCell) + + for i in properties_to_add: + if !newCell.properties.has(i): + newCell.properties.append(i) + + for i in properties_to_remove: + var index = newCell.properties.find(i) + if index != -1: + newCell.properties.remove_at(index) diff --git a/gdrl/Game/Logic/Maps/cell.gd b/gdrl/Game/Logic/Maps/cell.gd index 203c9c6..631cc27 100644 --- a/gdrl/Game/Logic/Maps/cell.gd +++ b/gdrl/Game/Logic/Maps/cell.gd @@ -2,9 +2,22 @@ extends Resource ### A square on the map class_name Cell -### does this cell block movement -@export var blocking:bool +### cell properties (array of strings for now) +@export var properties:Array[String] -### does this cell occlude vision -@export var occluding:bool -# discovered +### static name of blocking property +static var BlockingProp = "blocking" + +### convenience access for "Blocking" property +var blocking:bool: + get: + return properties.has(BlockingProp) + +### is this cell unique in the map? +# we can either +# A) have each point on the map be an entirely unique cell +# - this is a lot of duplicate data per map +# B) have each point on the map be a reference to a cell +# - changing cells would involve making copies. +# so we went with B, and are using `unique` to flag if a cell is unique or not. +@export var unique:bool = false diff --git a/gdrl/Game/Logic/Maps/map.gd b/gdrl/Game/Logic/Maps/map.gd index db16e08..8cb388d 100644 --- a/gdrl/Game/Logic/Maps/map.gd +++ b/gdrl/Game/Logic/Maps/map.gd @@ -24,6 +24,9 @@ func get_cell(pos:Vector2i)->Cell: return null return cells[pos.y][pos.x] + +func set_cell(pos:Vector2i, cell:Cell): + cells[pos.y][pos.x] = cell ### get a random coordinate bounds by map size. Uses `Game.world_context.rng` by default func get_random_coord(rng:RandomNumberGenerator = RL.game.world.rng)->Vector2i: diff --git a/gdrl/Game/Runner/Actors/enemy_actor.gd b/gdrl/Game/Runner/Actors/enemy_actor.gd index db9f2ff..8c65a32 100644 --- a/gdrl/Game/Runner/Actors/enemy_actor.gd +++ b/gdrl/Game/Runner/Actors/enemy_actor.gd @@ -26,7 +26,7 @@ func begin_turn(_runner:Runner): while target_direction == null: for i in copy_directions: var cell = RL.game.world.map.get_cell(entity.position + i) - if cell != null && !cell.blocking: + if cell != null && !cell.properties.has(Cell.BlockingProp): target_direction = i break if target_direction == null: diff --git a/gdrl/Game/Runner/runner.gd b/gdrl/Game/Runner/runner.gd index d314f8e..354ba81 100644 --- a/gdrl/Game/Runner/runner.gd +++ b/gdrl/Game/Runner/runner.gd @@ -30,7 +30,7 @@ func _ready() -> void: # player # TODO pull starter position out of map structure var starter_pos = RL.game.world.map.get_random_coord() - while RL.game.world.map.get_cell(starter_pos).blocking: + while RL.game.world.map.get_cell(starter_pos).properties.has(Cell.BlockingProp): starter_pos = RL.game.world.map.get_random_coord() generate_player(starter_pos) generate_enemies() @@ -80,7 +80,7 @@ func generate_player(position:Vector2i): func generate_enemies(): for i in 5: var starter_pos = RL.game.world.map.get_random_coord() - while RL.game.world.map.get_cell(starter_pos).blocking || RL.game.world.entities.get_entity_at_position(starter_pos)!= null: + while RL.game.world.map.get_cell(starter_pos).properties.has(Cell.BlockingProp) || RL.game.world.entities.get_entity_at_position(starter_pos)!= null: starter_pos = RL.game.world.map.get_random_coord() var entity = Entity.new() entity.position = starter_pos @@ -95,7 +95,7 @@ func generate_enemies(): ### Temporary. Move to a Map Generator func generate_cells(rng:RandomNumberGenerator, map:Map): var blocking_cell = Cell.new() - blocking_cell.blocking = true + blocking_cell.properties.append(Cell.BlockingProp) var clear_cell = Cell.new() var map_size = 8 var err = map.cells.resize(map_size) @@ -106,7 +106,7 @@ func generate_cells(rng:RandomNumberGenerator, map:Map): row.resize(map_size) for p in map_size: # can duplicate() here if we need unique resource-per-cell - row[p] = clear_cell.duplicate() if rng.randf() >= 0.5 else blocking_cell.duplicate() + row[p] = clear_cell if rng.randf() >= 0.5 else blocking_cell map.cells[i] = row pass