diff --git a/common/game_data/scripts/run/run_data.gd b/common/game_data/scripts/run/run_data.gd index 55ccc54..289afac 100644 --- a/common/game_data/scripts/run/run_data.gd +++ b/common/game_data/scripts/run/run_data.gd @@ -37,6 +37,7 @@ func generate_next_run_point(level = 0) -> RunPoint: region_parameter.level = level region_parameter.region_flags = get_region_flags(region_parameter) + return RunPoint.new( level, region_parameter @@ -72,24 +73,3 @@ func get_region_flags(region_parameter : RegionParameter) -> Array[String]: flags.append("borea") return flags - -class DifficultyModifier: - func modify(_region_parameter : RegionParameter): - pass - - func can_modifiy(_region_parameter : RegionParameter) -> bool: - return true - - func get_difficulty_cost() -> int: - return 1 - -class DifficultyIncreaseObjective extends DifficultyModifier: - func modify(region_parameter : RegionParameter): - region_parameter.objective += 1 - -class DifficultyDecreaseCharge extends DifficultyModifier: - func modify(region_parameter : RegionParameter): - region_parameter.charges -= 1 - - func can_modifiy(region_parameter : RegionParameter) -> bool: - return region_parameter.charges >= 3 diff --git a/common/game_info/game_info.gd b/common/game_info/game_info.gd index ec1cf3c..321bcb4 100644 --- a/common/game_info/game_info.gd +++ b/common/game_info/game_info.gd @@ -17,6 +17,7 @@ var settings_data : SettingsData func load_game_data() -> GameData: if ResourceLoader.exists(SAVE_GAME_LOCATION): game_loaded = true + game_data = ResourceLoader.load(SAVE_GAME_LOCATION).duplicate_deep() else : game_data = GameData.new() diff --git a/common/vfx/materials/shaders/chunk_mask.gdshader b/common/vfx/materials/shaders/chunk_mask.gdshader new file mode 100644 index 0000000..254b014 --- /dev/null +++ b/common/vfx/materials/shaders/chunk_mask.gdshader @@ -0,0 +1,8 @@ +shader_type canvas_item; + +uniform sampler2D screen_texture: hint_screen_texture; + +void fragment() { + + COLOR = texture(screen_texture, SCREEN_UV); +} \ No newline at end of file diff --git a/common/vfx/materials/shaders/chunk_mask.gdshader.uid b/common/vfx/materials/shaders/chunk_mask.gdshader.uid new file mode 100644 index 0000000..ea79994 --- /dev/null +++ b/common/vfx/materials/shaders/chunk_mask.gdshader.uid @@ -0,0 +1 @@ +uid://bc65ssv7bgy5d diff --git a/entities/interactable_3d/phone/phone.tscn b/entities/interactable_3d/phone/phone.tscn index b743206..0f9bcb4 100644 --- a/entities/interactable_3d/phone/phone.tscn +++ b/entities/interactable_3d/phone/phone.tscn @@ -59,6 +59,7 @@ shape = SubResource("CapsuleShape3D_mwti2") [node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="." unique_id=73991663] stream = ExtResource("2_w00q2") +bus = &"Sfx" [node name="Model" parent="." unique_id=178278867 instance=ExtResource("3_lp5jo")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.000101934645, 0) diff --git a/entities/player/inventory/scripts/items/seed.gd b/entities/player/inventory/scripts/items/seed.gd index f9afa55..8d190aa 100644 --- a/entities/player/inventory/scripts/items/seed.gd +++ b/entities/player/inventory/scripts/items/seed.gd @@ -88,13 +88,8 @@ func can_use(player : Player, zone : Player.ActionZone) -> bool: for area in zone.get_affected_areas(): if area is Plant: is_there_a_plant_here = true - - var is_there_contamination_in_zone = false - for tile in zone.get_tiles(): - if not player.region.decontamination_layer.is_decontamined(tile): - is_there_contamination_in_zone = true - return not is_there_a_plant_here and not is_there_contamination_in_zone + return not is_there_a_plant_here and player.region.is_coords_decontaminated(zone.get_tiles()) func use(player : Player, zone : Player.ActionZone) -> bool: if player.region == null: diff --git a/entities/player/inventory/scripts/items/shovel.gd b/entities/player/inventory/scripts/items/shovel.gd index 37d693b..30c8d97 100644 --- a/entities/player/inventory/scripts/items/shovel.gd +++ b/entities/player/inventory/scripts/items/shovel.gd @@ -41,12 +41,9 @@ func use(player : Player, zone : Player.ActionZone) -> bool: await player.get_tree().create_timer(USE_INTERVAL).timeout var bodies = zone.area.get_overlapping_bodies() - var rock_layer_id = bodies.find_custom(func (b) : return b is RockLayer) - if rock_layer_id != -1: - var rock_layer : RockLayer = bodies[rock_layer_id] - - rock_layer.dig_rocks(zone.get_tiles()) - + var rock_layers = bodies.filter(func (b) : return b is RockLayer) + for rock_layer in rock_layers: + player.region.dig_rocks(zone.get_tiles()) var particles := (DIG_PARTICLES.instantiate() as DigParticleEmmitter) player.region.add_child(particles) diff --git a/gui/pointer/scripts/pointer.gd b/gui/pointer/scripts/pointer.gd index 91b55a0..402d9e0 100644 --- a/gui/pointer/scripts/pointer.gd +++ b/gui/pointer/scripts/pointer.gd @@ -165,7 +165,7 @@ func update_card(): func update_inspector(): - if player and not get_tree().paused: + if player and (get_tree() and not get_tree().paused): if can_interact and current_inspect and current_inspect is Interactable: %Action.visible = true %ActionText.text = current_inspect.interact_text() diff --git a/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend b/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend index fe21204..b1138c4 100644 Binary files a/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend and b/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend differ diff --git a/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend1 b/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend1 index 120fd48..fe21204 100644 Binary files a/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend1 and b/stages/3d_scenes/ship_garage/assets/3d/ship_garage.blend1 differ diff --git a/stages/3d_scenes/ship_garage/scripts/ship_garage.gd b/stages/3d_scenes/ship_garage/scripts/ship_garage.gd index abdce17..6bf6ff2 100644 --- a/stages/3d_scenes/ship_garage/scripts/ship_garage.gd +++ b/stages/3d_scenes/ship_garage/scripts/ship_garage.gd @@ -2,6 +2,8 @@ extends Node3D const DIALOG_PATH = "res://dialogs/timelines/story/demeter_ship_presentation.dtl" +var jingle_played := false + # Cheat Code func _input(_e): if ( @@ -26,5 +28,6 @@ func _ready(): func _on_jingle_area_body_entered(body: Node3D): - if body is Player3D: + if body is Player3D and not jingle_played: AudioManager.play_sfx("Ship_reveal") + jingle_played = true diff --git a/stages/3d_scenes/ship_garage/ship_garage.tscn b/stages/3d_scenes/ship_garage/ship_garage.tscn index 414b7ee..1a9c45b 100644 --- a/stages/3d_scenes/ship_garage/ship_garage.tscn +++ b/stages/3d_scenes/ship_garage/ship_garage.tscn @@ -82,7 +82,102 @@ unique_name_in_owner = true transform = Transform3D(0.70710677, 0, 0.70710677, 0, 1, 0, -0.70710677, 0, 0.70710677, 31.365097, -1.8906436, 31.188667) speed = 5.0 -[node name="ship_garage" parent="." unique_id=1509517206 instance=ExtResource("4_g14ji")] +[node name="ship_garage" parent="." unique_id=1531736402 instance=ExtResource("4_g14ji")] + +[node name="ContourLight" type="Node3D" parent="ship_garage" unique_id=550025035] + +[node name="OmniLight3D10" type="OmniLight3D" parent="ship_garage/ContourLight" unique_id=829875236] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.591785, 0.35355997, 8.740698) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D11" type="OmniLight3D" parent="ship_garage/ContourLight" unique_id=2048991137] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.7106285, 0.35355997, 16.913948) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D12" type="OmniLight3D" parent="ship_garage/ContourLight" unique_id=65773175] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.056013, 0.35355997, 13.631781) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="ContourLight2" type="Node3D" parent="ship_garage" unique_id=1796913469] +transform = Transform3D(0.02940453, 0, 0.99956757, 0, 1, 0, -0.99956757, 0, 0.02940453, 0, 0, 0) + +[node name="OmniLight3D10" type="OmniLight3D" parent="ship_garage/ContourLight2" unique_id=752809093] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.591785, 0.35355997, 8.740698) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D11" type="OmniLight3D" parent="ship_garage/ContourLight2" unique_id=670102541] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.7106285, 0.35355997, 16.913948) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D12" type="OmniLight3D" parent="ship_garage/ContourLight2" unique_id=1890812582] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.056013, 0.35355997, 13.631781) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="ContourLight3" type="Node3D" parent="ship_garage" unique_id=1350477936] +transform = Transform3D(-0.9973743, 0, -0.07242006, 0, 1, 0, 0.07242006, 0, -0.9973743, 0, 0, 0) + +[node name="OmniLight3D10" type="OmniLight3D" parent="ship_garage/ContourLight3" unique_id=455622633] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.591785, 0.35355997, 8.740698) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D11" type="OmniLight3D" parent="ship_garage/ContourLight3" unique_id=1267181375] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.7106285, 0.35355997, 16.913948) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D12" type="OmniLight3D" parent="ship_garage/ContourLight3" unique_id=1105689331] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.056013, 0.35355997, 13.631781) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="ContourLight4" type="Node3D" parent="ship_garage" unique_id=1659332102] +transform = Transform3D(-0.09118883, 0, -0.99583364, 0, 1, 0, 0.99583364, 0, -0.09118883, 0, 0, 0) + +[node name="OmniLight3D10" type="OmniLight3D" parent="ship_garage/ContourLight4" unique_id=1763252326] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.591785, 0.35355997, 8.740698) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D11" type="OmniLight3D" parent="ship_garage/ContourLight4" unique_id=683595114] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.7106285, 0.35355997, 16.913948) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 + +[node name="OmniLight3D12" type="OmniLight3D" parent="ship_garage/ContourLight4" unique_id=919630929] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -13.056013, 0.35355997, 13.631781) +light_color = Color(0.8780363, 0.49553913, 0.4937222, 1) +light_energy = 7.245 +shadow_enabled = true +omni_range = 21.258795 [node name="OmniLight3D" type="OmniLight3D" parent="ship_garage" unique_id=1914600869] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.37195766, 0.5465579, -0.44411802) diff --git a/stages/terrain/region/scripts/chunk.gd b/stages/terrain/region/scripts/chunk.gd index 5a46e94..e35d183 100644 --- a/stages/terrain/region/scripts/chunk.gd +++ b/stages/terrain/region/scripts/chunk.gd @@ -2,20 +2,6 @@ extends Node2D class_name Chunk -signal generated - -var region : Region -var region_seed : int -var rock_noise_image : Noise = null -var decontamination_noise_image : Noise = null - -var is_generated : bool = false : - set(v): - is_generated = true - if is_generated: - generated.emit() -var generation_finished : Array[String] = [] - const GENERATION_NUMBER = 4 const NOISE_IMAGE_SIZE := 150 @@ -25,41 +11,83 @@ const MAX_DECONTAMINATION_DISTANCE=2 const ROCK_NOISE_FREQUENCY := 0.01 const DECONTAMINATION_NOISE_FREQUENCY := 0.01 +@export var region_data : RegionData +@export var chunk_coord : Vector2i + +var is_generated : bool = false + +var rock_noise_image : Noise = null +var cristal_noise_image : Noise = null +var decontamination_noise_image : Noise = null + +var rock_layer : RockLayer +var ground_layer : GroundLayer +var decontamination_layer : DecontaminationLayer + +var generation_thread : Thread + +var generation_semaphore : Semaphore + @export_tool_button("Update", "Callable") var update_action = func(): - region_seed = randi() + generation_semaphore.post() + for c in get_children(): + c.queue_free() + + setup_position() generate() -var data : ChunkData - func _init( - _data : ChunkData, - _region : Region = null, + _chunk_coord : Vector2i = Vector2i.ZERO, + _region_data : RegionData = RegionData.new(), + _generation_semaphore = Semaphore.new() ): - region = _region - if region: - region_seed = region.data.region_seed - data = _data + chunk_coord = _chunk_coord + region_data = _region_data + generation_semaphore = _generation_semaphore + +func _ready(): + setup_position() + async_generate() + +func async_generate(): + generation_thread = Thread.new() + generation_thread.start(generate) + +func setup_position(): + global_position = chunk_coord * (Region.CHUNK_TILE_SIZE * Region.TILE_SIZE) func generate(): - rock_noise_image = generate_noise(region_seed + 1, ROCK_NOISE_FREQUENCY) - decontamination_noise_image = generate_noise(region_seed + 2, DECONTAMINATION_NOISE_FREQUENCY) - global_position = data.chunk_coord * (Region.CHUNK_TILE_SIZE * Region.TILE_SIZE) - generate_rocks() - generate_ground() - generate_decontamination() + rock_noise_image = generate_noise(region_data.region_seed + 1, ROCK_NOISE_FREQUENCY) + decontamination_noise_image = generate_noise(region_data.region_seed + 2, DECONTAMINATION_NOISE_FREQUENCY) + cristal_noise_image = generate_noise(region_data.region_seed + 3, ROCK_NOISE_FREQUENCY) + + rock_layer = RockLayer.new(region_data) + ground_layer = GroundLayer.new(region_data) + decontamination_layer = DecontaminationLayer.new(region_data) -func finish_one_generation(generation_name : String): - generation_finished.append(generation_name) - if len(generation_finished) >= GENERATION_NUMBER: - is_generated = true + generation_semaphore.wait() -func unload(): - for x in range(Region.CHUNK_TILE_SIZE): - for y in range(Region.CHUNK_TILE_SIZE): - var global_coord = Vector2i(x, y) + Region.CHUNK_TILE_SIZE * data.chunk_coord - region.rock_layer.erase_cell(global_coord) - region.ground_layer.erase_cell(global_coord) - region.decontamination_layer.erase_cell(global_coord) + generate_rocks(rock_layer) + generate_ground(ground_layer) + generate_decontamination(decontamination_layer) + + generation_semaphore.post() + + # clear_padding_cells(rock_layer) + + add_child.call_deferred(rock_layer) + add_child.call_deferred(ground_layer) + add_child.call_deferred(decontamination_layer) + + is_generated = true + +# func unload(): +# for x in range(Region.CHUNK_TILE_SIZE): +# for y in range(Region.CHUNK_TILE_SIZE): +# var global_coord = Vector2i(x, y) + Region.CHUNK_TILE_SIZE * chunk_coord +# region.rock_layer.erase_cell(global_coord) +# region.ground_layer.erase_cell(global_coord) +# region.decontamination_layer.erase_cell(global_coord) # Debug # func _draw(): @@ -94,8 +122,8 @@ func generate_noise( noise.fractal_type = FastNoiseLite.FRACTAL_NONE noise.fractal_weighted_strength = 1.0 noise.offset = Vector3( - noise_image_size.x * data.chunk_coord.x, - noise_image_size.y * data.chunk_coord.y, + noise_image_size.x * chunk_coord.x, + noise_image_size.y * chunk_coord.y, 1 ) @@ -108,62 +136,80 @@ func get_tile_value_from_noise(tile_position : Vector2i, noise : Noise) -> float ) return (val + 1)/2 -func generate_rocks(): +func generate_rocks(layer : RockLayer): var cristals : Array[Vector2i] = [] var rocks : Array[Vector2i] = [] - for x in range(Region.CHUNK_TILE_SIZE): - for y in range(Region.CHUNK_TILE_SIZE): + for x in range(0, Region.CHUNK_TILE_SIZE): + for y in range(0, Region.CHUNK_TILE_SIZE): var tile_type := get_generated_rock_type(Vector2i(x, y)) - var global_coord = Vector2i(x, y) + Region.CHUNK_TILE_SIZE * data.chunk_coord + var coord = Vector2i(x, y) if tile_type == RockLayer.TileType.CRISTAL: - cristals.append(global_coord) + cristals.append(coord) elif tile_type == RockLayer.TileType.ROCK: - rocks.append(global_coord) + rocks.append(coord) - region.rock_layer.place_rocks(cristals, RockLayer.TileType.CRISTAL, func(): finish_one_generation("rock")) - region.rock_layer.place_rocks(rocks, RockLayer.TileType.ROCK, func(): finish_one_generation("cristal")) + layer.place_rocks(cristals, RockLayer.TileType.CRISTAL) + layer.place_rocks(rocks, RockLayer.TileType.ROCK) func get_generated_rock_type(coord : Vector2i) -> RockLayer.TileType: - var tile_value : float = get_tile_value_from_noise(coord, rock_noise_image) - var saved_diff := data.get_rock_tile_diff(coord) + var rock_tile_value : float = get_tile_value_from_noise(coord, rock_noise_image) + var cristal_tile_value : float = get_tile_value_from_noise(coord, cristal_noise_image) + var saved_diff := region_data.rock_tiles_data.get_tile_diff_for_local_coord(coord, chunk_coord) - if ( - (saved_diff == ChunkData.TileDiff.PRESENT or tile_value < region.data.rock_threshold) - and saved_diff != ChunkData.TileDiff.ABSENT + if saved_diff == TilesDiffData.TileDiff.ABSENT: + return RockLayer.TileType.EMPTY + elif saved_diff == TilesDiffData.TileDiff.PRESENT: + return RockLayer.TileType.ROCK + elif ( + rock_tile_value < region_data.rock_threshold ): - return RockLayer.TileType.CRISTAL if tile_value < region.data.cristal_threshold else RockLayer.TileType.ROCK - return RockLayer.TileType.EMPTY + return RockLayer.TileType.CRISTAL if cristal_tile_value < region_data.cristal_threshold else RockLayer.TileType.ROCK + else : + return RockLayer.TileType.EMPTY -func generate_ground(): +func generate_ground(layer : GroundLayer): var coords : Array[Vector2i] = [] - for x in range(Region.CHUNK_TILE_SIZE): - for y in range(Region.CHUNK_TILE_SIZE): - coords.append(Vector2i(x,y) + Region.CHUNK_TILE_SIZE * data.chunk_coord) + for x in range(0, Region.CHUNK_TILE_SIZE): + for y in range(0,Region.CHUNK_TILE_SIZE): + coords.append(Vector2i(x,y)) - region.ground_layer.place_ground(coords, func(): finish_one_generation("ground")) + layer.place_ground(coords) -func generate_decontamination(): +func generate_decontamination(layer : DecontaminationLayer): var decontamination_tiles : Array[Vector2i] = [] - for x in range(Region.CHUNK_TILE_SIZE): - for y in range(Region.CHUNK_TILE_SIZE): + for x in range(0, Region.CHUNK_TILE_SIZE): + for y in range(0, Region.CHUNK_TILE_SIZE): var coord = Vector2i(x,y) var tile_value : float = ( - 1. if data.chunk_coord.distance_to(Vector2i.ZERO) > MAX_DECONTAMINATION_DISTANCE + 1. if chunk_coord.distance_to(Vector2i.ZERO) > MAX_DECONTAMINATION_DISTANCE else get_tile_value_from_noise(coord, decontamination_noise_image) ) - var saved_diff := data.get_decontamination_tile_diff(coord) + var saved_diff : TilesDiffData.TileDiff = region_data.decontamination_tiles_data.get_tile_diff_for_local_coord(coord, chunk_coord) if ( ( - saved_diff == ChunkData.TileDiff.PRESENT - or (tile_value < region.data.decontamination_threshold) + (tile_value < region_data.decontamination_threshold) + or saved_diff == TilesDiffData.TileDiff.PRESENT ) - and saved_diff != ChunkData.TileDiff.ABSENT + and saved_diff != TilesDiffData.TileDiff.ABSENT ): - decontamination_tiles.append(Vector2i(x,y) + Region.CHUNK_TILE_SIZE * data.chunk_coord) + decontamination_tiles.append(Vector2i(x,y)) - region.decontamination_layer.place_decontaminations( + layer.place_decontaminations( decontamination_tiles, false, - func(): - finish_one_generation("decontamination") ) + + +func clear_padding_cells(layer : RegionLayer): + var coords : Array[Vector2i] = [] + for x in [-1, Region.CHUNK_TILE_SIZE + 1]: + for y in range(-1, Region.CHUNK_TILE_SIZE + 1): + coords.append(Vector2i(x,y)) + + for y in [-1, Region.CHUNK_TILE_SIZE + 1]: + for x in range(0, Region.CHUNK_TILE_SIZE + 1): + coords.append(Vector2i(x,y)) + layer.set_cells_terrain_connect(coords, 0, -1) + +func _exit_tree(): + generation_thread.wait_to_finish() diff --git a/stages/terrain/region/scripts/chunk_data.gd b/stages/terrain/region/scripts/chunk_data.gd deleted file mode 100644 index 4041bc0..0000000 --- a/stages/terrain/region/scripts/chunk_data.gd +++ /dev/null @@ -1,62 +0,0 @@ -extends Resource -class_name ChunkData - -enum TileDiff { NO_DIFF,PRESENT,ABSENT } - -@export var chunk_coord : Vector2i -@export var rock_tiles_diff : Dictionary[String, TileDiff] -@export var decontamination_tiles_diff : Dictionary[String, TileDiff] - -func _init( - _chunk_coord : Vector2i = Vector2i.ZERO -): - chunk_coord = _chunk_coord - -#region ------------------ Generic Tile ------------------ - -func get_coord_key(coord : Vector2i) -> String: - return "%d:%d" % [coord.x, coord.y] - -func get_tile_diff( - coord : Vector2i, - tiles_diff : Dictionary[String, TileDiff] -) -> TileDiff: - if not has_diff(coord, tiles_diff): - return TileDiff.NO_DIFF - return tiles_diff[get_coord_key(coord)] - -func update_tile_diff( - coord : Vector2i, - diff : TileDiff, - tiles_diff : Dictionary[String, TileDiff] -): - tiles_diff[get_coord_key(coord)] = diff - -func has_diff( - coord : Vector2i, - tiles_diff : Dictionary[String, TileDiff] -): - return tiles_diff.has(get_coord_key(coord)) - -#region ------------------ Rock ------------------ - -func get_rock_tile_diff(coord : Vector2i) -> TileDiff: - return get_tile_diff(coord, rock_tiles_diff) - -func update_rock_tile_diff(coord : Vector2i, diff : TileDiff): - update_tile_diff(coord, diff, rock_tiles_diff) - -func has_rock_tile_diff(coord : Vector2i): - return has_diff(coord, rock_tiles_diff) - - -#region ------------------ Decontamination ------------------ - -func get_decontamination_tile_diff(coord : Vector2i) -> TileDiff: - return get_tile_diff(coord, decontamination_tiles_diff) - -func update_decontamination_tile_diff(coord : Vector2i, diff : TileDiff): - update_tile_diff(coord, diff, decontamination_tiles_diff) - -func has_decontamination_tile_diff(coord : Vector2i): - return has_diff(coord, decontamination_tiles_diff) \ No newline at end of file diff --git a/stages/terrain/region/scripts/chunk_data.gd.uid b/stages/terrain/region/scripts/chunk_data.gd.uid deleted file mode 100644 index 1367907..0000000 --- a/stages/terrain/region/scripts/chunk_data.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://clqa88okc325t diff --git a/stages/terrain/region/scripts/region.gd b/stages/terrain/region/scripts/region.gd index 4f744fc..27b12d4 100644 --- a/stages/terrain/region/scripts/region.gd +++ b/stages/terrain/region/scripts/region.gd @@ -8,8 +8,6 @@ const TUTORIAL_SCENE : PackedScene = preload("res://gui/game/tutorial/tutorial.t const TILE_SET : TileSet = preload("res://stages/terrain/region/resources/moss_biome.tres") const TILE_SCALE = 1 const TILE_SIZE : int = roundi(TILE_SET.tile_size.x * TILE_SCALE) -const START_ROCK_HOLE_RADIUS = 5 -const PLAYER_ROCK_HOLE_RADIUS = 5 const SPAWN_OBJECT_RANDOM_MOVEMENT = 200 const CHUNK_TILE_SIZE : int = 20 @@ -17,6 +15,8 @@ const CHUNK_SIZE = CHUNK_TILE_SIZE * TILE_SIZE const CHUNK_LOAD_DISTANCE : int = 1 const CHUNK_UNLOAD_DISTANCE : int = 2 +const MAX_GENERATION_THREAD = 1 # Crash when superior to 1 + @export var first_loot_number : int = 3 @export var loot_item_number : Array[int] = [1,2] @@ -28,23 +28,20 @@ var data : RegionData var in_passing_day_animation = false var contamination_texture : ImageTexture -var rock_layer : RockLayer -var ground_layer : GroundLayer -var decontamination_layer : DecontaminationLayer + +var creating_new_layer_pack = false var score_by_plant : Dictionary[PlantData, int] = {} -var tile_set = Region.TILE_SET - -var generated_chunks : Dictionary[String,Chunk] = {} -var generation_semaphore: Semaphore +var generated_chunks : Array[Chunk] = [] +var generation_semaphore : Semaphore # Cheat Code func _input(_e): if ( Input.is_action_pressed("drop") and Input.is_action_pressed("move_right") - and Input.is_action_pressed("move_left") + and Input.is_action_pressed("move_left") and Input.is_action_just_pressed("action") ): %Tutorial.finish_tutorial() @@ -55,7 +52,7 @@ func _input(_e): if ( Input.is_action_pressed("drop") and Input.is_action_pressed("move_right") - and Input.is_action_pressed("move_left") + and Input.is_action_pressed("move_left") and Input.is_action_just_pressed("move_pointer") ): data.charges = 0 @@ -66,7 +63,7 @@ func _init(): func _ready(): generation_semaphore = Semaphore.new() - generation_semaphore.post() + generation_semaphore.post(MAX_GENERATION_THREAD) entity_container.position = TILE_SIZE * CHUNK_TILE_SIZE * Vector2.ONE / 2 load_entities(data.entities_saved_data) @@ -75,16 +72,6 @@ func _ready(): if e is Plant: data.add_plant_data(e.data, false) - ground_layer = GroundLayer.new(self) - ground_layer.name = "GroundLayer" - add_child(ground_layer) - rock_layer = RockLayer.new(self) - rock_layer.name = "RockLayer" - add_child(rock_layer) - decontamination_layer = DecontaminationLayer.new(self) - decontamination_layer.name = "DecontaminationLayer" - add_child(decontamination_layer) - %AstraDoor.global_position = data.player_spawn player.global_position = data.player_position @@ -92,8 +79,6 @@ func _ready(): generate_near_chunks(player) - edit_map_origin() - spawn_object_random_move(%RechargeStation) %RechargeStation.update() spawn_object_random_move(%BoreaDoor) @@ -108,94 +93,60 @@ func _process(_d): func get_chunk_key(coord) -> String: return "%d:%d" % [coord.x, coord.y] - -func generate_near_chunks(p : Player): + +func generate_near_chunks(p : Player) -> bool: + var new_chunk_created = false var player_chunk_coord = Math.get_chunk_from_pos(p.global_position) for x in range(-CHUNK_LOAD_DISTANCE, CHUNK_LOAD_DISTANCE+1): for y in range(-CHUNK_LOAD_DISTANCE, CHUNK_LOAD_DISTANCE+1): var coord : Vector2i = Vector2i(x,y) + player_chunk_coord - if not generated_chunks.has(get_chunk_key(coord)): + if (not is_chunk_generated(coord)): generate_chunk(coord) + new_chunk_created = true + + return new_chunk_created -func remove_far_chunks(p : Player): +func remove_far_chunks(p : Player) -> bool: + var chunk_deleted = false var player_chunk_coord = Vector2i( floor(p.global_position.x / (CHUNK_TILE_SIZE * TILE_SIZE)), floor(p.global_position.y / (CHUNK_TILE_SIZE * TILE_SIZE)) ) - for chunk in generated_chunks.values(): - var chunk_coord = chunk.data.chunk_coord + for chunk in generated_chunks: + var chunk_coord = chunk.chunk_coord if player_chunk_coord.distance_to(chunk_coord) > CHUNK_UNLOAD_DISTANCE: remove_chunk(chunk) + chunk_deleted = true + return chunk_deleted func generate_chunk(coord : Vector2i): - var chunk_data := data.get_or_create_chunk_data(coord) - - var chunk_key = get_chunk_key(coord) - if not generated_chunks.has(chunk_key): + if not is_chunk_generated(coord): var new_chunk = Chunk.new( - chunk_data, - self + coord, + data, + generation_semaphore ) - generated_chunks[chunk_key] = new_chunk add_child(new_chunk) - data.generated_chunk_entities.append(coord) - new_chunk.generate() - -func edit_map_origin(): - # Dig a hole in map origin - var chunk_center = Vector2i.ONE * floori(CHUNK_TILE_SIZE/2.) - var hole_tiles : Array[Vector2i] = [] - var decontamination_tiles : Array[Vector2i] = [] - for x in range(CHUNK_TILE_SIZE): - for y in range(CHUNK_TILE_SIZE): - var coord = Vector2i(x,y) - if coord.distance_to(chunk_center) < START_ROCK_HOLE_RADIUS: - hole_tiles.append(coord) - if coord.distance_to(chunk_center) < data.start_decontamination_hole_radius: - decontamination_tiles.append(coord) - - rock_layer.remove_rocks(hole_tiles, true) - decontamination_layer.place_decontaminations(decontamination_tiles, true) - - # Dig a hole in player spawn - var player_hole_tiles : Array[Vector2i] = [] - var player_tile_position := Vector2i( - roundi(data.player_spawn.x/float(TILE_SIZE)), - roundi(data.player_spawn.y/float(TILE_SIZE)) - ) - for x in range(-PLAYER_ROCK_HOLE_RADIUS, PLAYER_ROCK_HOLE_RADIUS): - for y in range(-PLAYER_ROCK_HOLE_RADIUS, PLAYER_ROCK_HOLE_RADIUS): - var coord = Vector2i(x,y) - if coord.distance_to(Vector2.ZERO) < PLAYER_ROCK_HOLE_RADIUS: - player_hole_tiles.append(coord + player_tile_position) - rock_layer.remove_rocks(player_hole_tiles, true) + generated_chunks.append(new_chunk) func remove_chunk(chunk : Chunk): - generated_chunks.erase(get_chunk_key(chunk.data.chunk_coord)) - chunk.unload() + generated_chunks.erase(chunk) chunk.queue_free() func check_is_generated() -> bool: - if len(generated_chunks.keys()) == 0: - return false - return get_chunk_generation_count() == float(get_full_chunk_generation_count()) + var ret = true + for c in generated_chunks: + if not c.is_generated: + ret = false + return ret -func get_generated_value(): - return get_chunk_generation_count() / float(get_full_chunk_generation_count()) - -func get_full_chunk_generation_count() -> int: - return len(generated_chunks.keys()) * Chunk.GENERATION_NUMBER - -func get_chunk_generation_count() -> int: - var generation_count = 0 - - for key in generated_chunks.keys(): - generation_count += len(generated_chunks[key].generation_finished) - - return generation_count +func get_generated_value() -> float: + # if layer_pack: + # return layer_pack.generated_value + return 1. func save(): data.entities_saved_data = save_entities() @@ -232,6 +183,10 @@ func setup_flagged_properties(): %BoreaDoor.visible = true %RechargeStation.visible = false +func is_chunk_generated(coord : Vector2i): + return generated_chunks.find_custom( + func (c: Chunk) : return get_chunk_key(c.chunk_coord) == get_chunk_key(coord) + ) != -1 #endregion #region ------------------ Usage ------------------ @@ -269,4 +224,51 @@ func pass_day(): data.end_pass_day() save() + +func get_chunk_for_coord(tiles_coord : Vector2i) -> Chunk: + var chunk_coord = Vector2i( + floori(float(tiles_coord.x)/Region.CHUNK_TILE_SIZE), + floori(float(tiles_coord.y)/Region.CHUNK_TILE_SIZE), + ) + + var id = generated_chunks.find_custom( + func (c: Chunk): return c.chunk_coord.x == chunk_coord.x and c.chunk_coord.y == chunk_coord.y + ) + + if id == -1 or not generated_chunks[id].is_generated: + return null + return generated_chunks[id] + +func is_coords_decontaminated(tiles_coords : Array[Vector2i]): + for coord in tiles_coords: + var chunk : Chunk = get_chunk_for_coord(coord) + if chunk: + var local_coord := TilesDiffData.get_local_coord(coord, chunk.chunk_coord) + if not chunk.decontamination_layer.is_decontamined(local_coord): + return false + return true + + +func dig_rocks(tiles_coords : Array[Vector2i], save_tiles_diff := true, loot := true): + if save_tiles_diff : + data.rock_tiles_data.update_tiles_diff(tiles_coords, TilesDiffData.TileDiff.ABSENT) + + for coord in tiles_coords: + var chunk : Chunk = get_chunk_for_coord(coord) + if chunk: + var local_coord := TilesDiffData.get_local_coord(coord, chunk.chunk_coord) + + if loot and chunk.rock_layer.get_tile_type(local_coord) == RockLayer.TileType.CRISTAL: + loot_talion(coord) + + chunk.rock_layer.remove_rocks([local_coord]) + +func loot_talion(coord : Vector2i): + var new_seed = Seed.generate_random() + drop_item( + new_seed, + coord * TILE_SIZE, + 10 + ) + #endregion diff --git a/stages/terrain/region/scripts/region_data.gd b/stages/terrain/region/scripts/region_data.gd index 00a7bdc..1a62f5d 100644 --- a/stages/terrain/region/scripts/region_data.gd +++ b/stages/terrain/region/scripts/region_data.gd @@ -14,6 +14,8 @@ signal pass_day_ended(region_data : RegionData) const DEFAULT_START_CHARGE := 10 const DEFAULT_OBJECTIVE := 10 const MAX_RANDOM_SPAWN_DISTANCE = 3000 +const START_ROCK_HOLE_RADIUS = 5 +const PLAYER_ROCK_HOLE_RADIUS = 5 @export var region_seed : int @export var region_name : String @@ -26,14 +28,11 @@ const MAX_RANDOM_SPAWN_DISTANCE = 3000 @export var day : int = 1 @export var entities_saved_data : Array[EntityData] = [] -@export var generated_chunk_entities : Array[Vector2i] @export var flags : Array[String] = [] @export var plants : Array[PlantData] @export var state : State = State.IN_PROGRESS -@export var chunks_data : Dictionary[String, ChunkData] - @export var player_position : Vector2 @export var player_spawn : Vector2 @@ -47,6 +46,8 @@ const MAX_RANDOM_SPAWN_DISTANCE = 3000 objective = v update() +@export var rock_tiles_data : TilesDiffData +@export var decontamination_tiles_data : TilesDiffData var in_passing_day_animation := false @@ -67,6 +68,11 @@ func _init( player_spawn = get_random_spawn_position() player_position = player_spawn + rock_tiles_data = TilesDiffData.new() + decontamination_tiles_data = TilesDiffData.new() + + edit_map_origin() + func update(): if objective > 0 and get_score() >= objective and not "tutorial" in flags: if state != State.SUCCEEDED: @@ -78,30 +84,6 @@ func update(): state = State.FAILED updated.emit(self) -#region ------------------ Chunks ------------------ - -func get_coord_id(coord): - return "%d:%d" % [coord.x, coord.y] - -func has_chunk_data(coord : Vector2i) -> bool: - return chunks_data.has(get_coord_id(coord)) - -func add_chunk_data(coord : Vector2i, data : ChunkData): - chunks_data[get_coord_id(coord)] = data - -func get_chunk_data(coord : Vector2i) -> ChunkData: - if get_coord_id(coord) in chunks_data: - return chunks_data[get_coord_id(coord)] - return null - -func get_or_create_chunk_data(coord : Vector2i) -> ChunkData: - if has_chunk_data(coord): - return get_chunk_data(coord) - else: - var new_chunk_data = ChunkData.new(coord) - add_chunk_data(coord, new_chunk_data) - return new_chunk_data - #endregion #region ------------------ Score ------------------ @@ -159,3 +141,36 @@ func get_random_spawn_position(): return rand_pos #endregion + +#region ------------------ Tiles ------------------ + +func edit_map_origin(): + # Dig a hole in map origin + var chunk_center = Vector2i.ONE * floori(Region.CHUNK_TILE_SIZE/2.) + var hole_tiles : Array[Vector2i] = [] + var decontamination_tiles : Array[Vector2i] = [] + for x in range(Region.CHUNK_TILE_SIZE): + for y in range(Region.CHUNK_TILE_SIZE): + var coord = Vector2i(x,y) + if coord.distance_to(chunk_center) < START_ROCK_HOLE_RADIUS: + hole_tiles.append(coord) + if coord.distance_to(chunk_center) < start_decontamination_hole_radius: + decontamination_tiles.append(coord) + + rock_tiles_data.update_tiles_diff(hole_tiles, TilesDiffData.TileDiff.ABSENT) + + # Dig a hole in player spawn + var player_hole_tiles : Array[Vector2i] = [] + var player_tile_position := Vector2i( + roundi(player_spawn.x/float(Region.TILE_SIZE)), + roundi(player_spawn.y/float(Region.TILE_SIZE)) + ) + for x in range(-PLAYER_ROCK_HOLE_RADIUS, PLAYER_ROCK_HOLE_RADIUS): + for y in range(-PLAYER_ROCK_HOLE_RADIUS, PLAYER_ROCK_HOLE_RADIUS): + var coord = Vector2i(x,y) + if coord.distance_to(Vector2.ZERO) < PLAYER_ROCK_HOLE_RADIUS: + player_hole_tiles.append(coord + player_tile_position) + + rock_tiles_data.update_tiles_diff(player_hole_tiles, TilesDiffData.TileDiff.ABSENT) + +#endregion \ No newline at end of file diff --git a/stages/terrain/region/scripts/tile_map_layers/decontamination_layer.gd b/stages/terrain/region/scripts/tile_map_layers/decontamination_layer.gd index 2bff6bd..26b91a2 100644 --- a/stages/terrain/region/scripts/tile_map_layers/decontamination_layer.gd +++ b/stages/terrain/region/scripts/tile_map_layers/decontamination_layer.gd @@ -11,22 +11,12 @@ func setup(): func place_decontamination(coord : Vector2i, save = false): place_decontaminations([coord], save) -func place_decontaminations(coords : Array[Vector2i], save := false, on_finished : Callable = (func(): pass)): - async_place_terrain_cells( +func place_decontaminations(coords : Array[Vector2i], save := false): + place_terrain_cells( coords, DECONTAMINATION_TILE_TERRAIN_SET, DECONTAMINATION_TILE_TERRAIN, - on_finished ) - if save: - for coord in coords: - var chunk_coord = Vector2i( - floori(coord.x / float(Region.CHUNK_TILE_SIZE)), - floori(coord.y / float(Region.CHUNK_TILE_SIZE)), - ) - (region.data - .get_or_create_chunk_data(chunk_coord) - .update_decontamination_tile_diff(coord, ChunkData.TileDiff.PRESENT)) func is_decontamined(coord : Vector2i) -> bool: return has_cell(coord) diff --git a/stages/terrain/region/scripts/tile_map_layers/ground_layer.gd b/stages/terrain/region/scripts/tile_map_layers/ground_layer.gd index ff65103..6257a1d 100644 --- a/stages/terrain/region/scripts/tile_map_layers/ground_layer.gd +++ b/stages/terrain/region/scripts/tile_map_layers/ground_layer.gd @@ -10,10 +10,9 @@ func setup(): material = MATERIAL z_index = -100 -func place_ground(coords : Array[Vector2i], on_finished : Callable = (func(): pass)): - async_place_terrain_cells( +func place_ground(coords : Array[Vector2i]): + place_terrain_cells( coords, GROUND_TILE_TERRAIN_SET, GROUND_TILE_TERRAIN, - on_finished ) \ No newline at end of file diff --git a/stages/terrain/region/scripts/tile_map_layers/region_layer.gd b/stages/terrain/region/scripts/tile_map_layers/region_layer.gd index 163710b..f5b12d3 100644 --- a/stages/terrain/region/scripts/tile_map_layers/region_layer.gd +++ b/stages/terrain/region/scripts/tile_map_layers/region_layer.gd @@ -1,20 +1,22 @@ +@tool @abstract extends TileMapLayer class_name RegionLayer -var threads : Array[Thread] = [] -var is_generated = false -var region : Region +@export var region_data : RegionData func _init( - _planet : Region = null + _region_data : RegionData ): - region = _planet - -func _ready(): - tile_set = region.tile_set + set_physics_quadrant_size(Region.CHUNK_TILE_SIZE) + set_rendering_quadrant_size(Region.CHUNK_TILE_SIZE) + tile_set = Region.TILE_SET scale = Vector2.ONE * Region.TILE_SCALE navigation_enabled = false + region_data = _region_data + # collision_visibility_mode = DebugVisibilityMode.DEBUG_VISIBILITY_MODE_FORCE_SHOW + +func _ready(): setup() func setup(): @@ -35,37 +37,22 @@ func get_all_neighbors_cell(coord : Vector2i) -> Array[Vector2i]: func has_cell(tile_position : Vector2i) -> bool: return get_cell_source_id(tile_position) != -1 -func async_place_terrain_cells( - coords : Array[Vector2i], - tile_terrain_set : int = 0, - tile_terrain : int = 0, - on_finished : Callable = (func(): pass) -): - var thread = Thread.new() - threads.append(thread) - thread.start( - func (): - place_terrain_cells( - coords, - tile_terrain_set, - tile_terrain - ) - on_finished.call_deferred() - ) - func place_terrain_cells( coords : Array[Vector2i], tile_terrain_set : int = 0, tile_terrain : int = 0 ): - region.generation_semaphore.wait() + var valid_coords : Array[Vector2i] = coords.filter(is_coord_valid) set_cells_terrain_connect( - coords, + valid_coords, tile_terrain_set, tile_terrain ) - region.generation_semaphore.post() -func _exit_tree(): - for t in threads: - t.wait_to_finish() \ No newline at end of file +func is_coord_valid(coord : Vector2i) -> bool: + return ( + coord.x >= 0 + and coord.y >= 0 + and coord.x < Region.CHUNK_TILE_SIZE + and coord.y < Region.CHUNK_TILE_SIZE + ) \ No newline at end of file diff --git a/stages/terrain/region/scripts/tile_map_layers/rock_layer.gd b/stages/terrain/region/scripts/tile_map_layers/rock_layer.gd index 2d4ba4f..d507ea2 100644 --- a/stages/terrain/region/scripts/tile_map_layers/rock_layer.gd +++ b/stages/terrain/region/scripts/tile_map_layers/rock_layer.gd @@ -6,61 +6,26 @@ const ROCK_TILE_TERRAIN_SET : int = 0 const ROCK_TILE_TERRAIN : int = 1 const CRISTAL_TILE_TERRAIN : int = 2 -const CRISTAL_LOOT_CHANCE : float = 1 - enum TileType { EMPTY,ROCK,CRISTAL } func setup(): z_index = -1 -func place_rocks(coords : Array[Vector2i], type := TileType.ROCK,on_finished : Callable = (func(): pass)): +func place_rocks(coords : Array[Vector2i], type := TileType.ROCK): if type != TileType.EMPTY: - async_place_terrain_cells( + place_terrain_cells( coords, ROCK_TILE_TERRAIN_SET, ROCK_TILE_TERRAIN if type == TileType.ROCK else CRISTAL_TILE_TERRAIN, - on_finished ) -func remove_rocks(coords : Array[Vector2i], save = false,on_finished : Callable = (func(): pass)): - async_place_terrain_cells( +func remove_rocks(coords : Array[Vector2i], save = false): + place_terrain_cells( coords, ROCK_TILE_TERRAIN_SET, - -1, - on_finished + -1 ) - if save: - for coord in coords: - var chunk_coord = Vector2i( - floori(coord.x / float(Region.CHUNK_TILE_SIZE)), - floori(coord.y / float(Region.CHUNK_TILE_SIZE)), - ) - var chunk_tile_coord : Vector2i = coord - chunk_coord * Region.CHUNK_TILE_SIZE - (region.data - .get_or_create_chunk_data(chunk_coord) - .update_rock_tile_diff(chunk_tile_coord, ChunkData.TileDiff.ABSENT)) -func dig_rocks(coords : Array[Vector2i]) -> bool: - var has_rock = false - - for coord in coords: - if has_tile(coord): - has_rock = true - loot_rock(coord) - - if has_rock: - remove_rocks(coords, true) - - return has_rock - -func loot_rock(coord : Vector2i): - if get_tile_type(coord) == TileType.CRISTAL and randf() < CRISTAL_LOOT_CHANCE: - var loot = Seed.generate_random() - region.drop_item( - loot, - coord * Region.TILE_SIZE + Vector2i.ONE * floori(Region.TILE_SIZE/2.), - floor(Region.TILE_SIZE/2.) - ) func has_tile(coord : Vector2i) -> bool: return has_cell(coord) diff --git a/stages/terrain/region/scripts/tiles_diff_data.gd b/stages/terrain/region/scripts/tiles_diff_data.gd new file mode 100644 index 0000000..30b7497 --- /dev/null +++ b/stages/terrain/region/scripts/tiles_diff_data.gd @@ -0,0 +1,46 @@ +extends Resource +class_name TilesDiffData + +enum TileDiff { NO_DIFF,PRESENT,ABSENT } + +@export var tiles_diff : Dictionary[String, TileDiff] + +static func get_coord_key(coord : Vector2i) -> String: + return "%d:%d" % [coord.x, coord.y] + +static func get_global_coord(local_coord : Vector2i, chunk_coord : Vector2i, ) -> Vector2i: + return local_coord + (Vector2i.ONE * Region.CHUNK_TILE_SIZE * chunk_coord) + +static func get_local_coord(coord : Vector2i, chunk_coord : Vector2i, ) -> Vector2i: + return coord - (Vector2i.ONE * Region.CHUNK_TILE_SIZE * chunk_coord) + +func get_tile_diff( + coord : Vector2i, +) -> TileDiff: + if not has_diff(coord): + return TileDiff.NO_DIFF + return tiles_diff[get_coord_key(coord)] + +func get_tile_diff_for_local_coord( + local_coord : Vector2i, + chunk_coord : Vector2i +) -> TileDiff: + return get_tile_diff(get_global_coord(local_coord, chunk_coord)) + +func update_tile_diff( + coord : Vector2i, + diff : TileDiff, +): + tiles_diff[get_coord_key(coord)] = diff + +func update_tiles_diff( + coords : Array[Vector2i], + diff : TileDiff, +): + for coord in coords: + tiles_diff[get_coord_key(coord)] = diff + +func has_diff( + coord : Vector2i, +): + return tiles_diff.has(get_coord_key(coord)) \ No newline at end of file diff --git a/stages/terrain/region/scripts/tiles_diff_data.gd.uid b/stages/terrain/region/scripts/tiles_diff_data.gd.uid new file mode 100644 index 0000000..0879cc8 --- /dev/null +++ b/stages/terrain/region/scripts/tiles_diff_data.gd.uid @@ -0,0 +1 @@ +uid://dy6d4rmdu6gh0 diff --git a/stages/terrain/region/test_chunk.tscn b/stages/terrain/region/test_chunk.tscn new file mode 100644 index 0000000..0ce0b33 --- /dev/null +++ b/stages/terrain/region/test_chunk.tscn @@ -0,0 +1,26 @@ +[gd_scene format=3 uid="uid://dtfuxosn6s0cr"] + +[ext_resource type="Script" uid="uid://d2ixbaa2uqlv4" path="res://stages/terrain/region/scripts/chunk.gd" id="1_mhr83"] +[ext_resource type="Script" uid="uid://bgbbce45hjv3d" path="res://entities/scripts/entity_data.gd" id="2_tiw8g"] +[ext_resource type="Script" uid="uid://da6j333qs7wse" path="res://entities/plants/scripts/plant_data.gd" id="3_ct7cr"] +[ext_resource type="Script" uid="uid://cx30nvq8b34lj" path="res://stages/terrain/region/scripts/region_data.gd" id="4_0rtv3"] + +[sub_resource type="Resource" id="Resource_tiw8g"] +script = ExtResource("4_0rtv3") +rock_threshold = 0.5 +decontamination_threshold = 0.5 +metadata/_custom_type_script = "uid://cx30nvq8b34lj" + +[node name="TestChunk" type="Node2D" unique_id=990498648] + +[node name="Chunk" type="Node2D" parent="." unique_id=709095052] +script = ExtResource("1_mhr83") +region_data = SubResource("Resource_tiw8g") +metadata/_custom_type_script = "uid://d2ixbaa2uqlv4" + +[node name="Chunk2" type="Node2D" parent="." unique_id=509661921] +position = Vector2(1280, 0) +script = ExtResource("1_mhr83") +region_data = SubResource("Resource_tiw8g") +chunk_coord = Vector2i(1, 0) +metadata/_custom_type_script = "uid://d2ixbaa2uqlv4" diff --git a/translation/game/gui.csv b/translation/game/gui.csv index f9bd8bd..e83f910 100644 --- a/translation/game/gui.csv +++ b/translation/game/gui.csv @@ -10,7 +10,7 @@ PLANT_INFO_TEXT,"[b]1[/b] Name [b]2[/b] Archétype [b]3[/b] Score [b]4[/b] Age -[b]5[/b] Durée de pousse +[b]5[/b] Temps de croissance [b]6[/b] Durée de vie" TERRAINS,Terrains,Terrains FERTILE_LAND_TEXT,[b]Fertile Land[/b] Seeds can only be planted on this zone,[b]Terre fertile[/b] Des graines peuvent être plantées dans cette zone @@ -143,7 +143,7 @@ CHOOSE_A_LANGUAGE,Choose a language,Choisissez une langue NO_ENERGY_LEFT," (no energy left)", " (pas d'énergie restante)" %d_GARDEN_SCORE_LEFT,"%d garden score left","%d score de jardin restant" SETTINGS,Settings,Paramètres -LANGUAGE,Language,Language +LANGUAGE,Language,Langage SOUND,Sound,Son MUSIC_VOLUME,Music volume,Volume de la musique ENVIRONMENT_VOLUME,Environment Volume,Volume de l'environnement