refonte du système de chunk et correction de bug/traduction

This commit is contained in:
2026-03-01 18:24:46 +01:00
parent d25d614c06
commit 37cd8a54dd
25 changed files with 470 additions and 375 deletions

View File

@@ -37,6 +37,7 @@ func generate_next_run_point(level = 0) -> RunPoint:
region_parameter.level = level region_parameter.level = level
region_parameter.region_flags = get_region_flags(region_parameter) region_parameter.region_flags = get_region_flags(region_parameter)
return RunPoint.new( return RunPoint.new(
level, level,
region_parameter region_parameter
@@ -72,24 +73,3 @@ func get_region_flags(region_parameter : RegionParameter) -> Array[String]:
flags.append("borea") flags.append("borea")
return flags 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

View File

@@ -17,6 +17,7 @@ var settings_data : SettingsData
func load_game_data() -> GameData: func load_game_data() -> GameData:
if ResourceLoader.exists(SAVE_GAME_LOCATION): if ResourceLoader.exists(SAVE_GAME_LOCATION):
game_loaded = true game_loaded = true
game_data = ResourceLoader.load(SAVE_GAME_LOCATION).duplicate_deep() game_data = ResourceLoader.load(SAVE_GAME_LOCATION).duplicate_deep()
else : else :
game_data = GameData.new() game_data = GameData.new()

View File

@@ -0,0 +1,8 @@
shader_type canvas_item;
uniform sampler2D screen_texture: hint_screen_texture;
void fragment() {
COLOR = texture(screen_texture, SCREEN_UV);
}

View File

@@ -0,0 +1 @@
uid://bc65ssv7bgy5d

View File

@@ -59,6 +59,7 @@ shape = SubResource("CapsuleShape3D_mwti2")
[node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="." unique_id=73991663] [node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="." unique_id=73991663]
stream = ExtResource("2_w00q2") stream = ExtResource("2_w00q2")
bus = &"Sfx"
[node name="Model" parent="." unique_id=178278867 instance=ExtResource("3_lp5jo")] [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) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.000101934645, 0)

View File

@@ -89,12 +89,7 @@ func can_use(player : Player, zone : Player.ActionZone) -> bool:
if area is Plant: if area is Plant:
is_there_a_plant_here = true is_there_a_plant_here = true
var is_there_contamination_in_zone = false return not is_there_a_plant_here and player.region.is_coords_decontaminated(zone.get_tiles())
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
func use(player : Player, zone : Player.ActionZone) -> bool: func use(player : Player, zone : Player.ActionZone) -> bool:
if player.region == null: if player.region == null:

View File

@@ -41,12 +41,9 @@ func use(player : Player, zone : Player.ActionZone) -> bool:
await player.get_tree().create_timer(USE_INTERVAL).timeout await player.get_tree().create_timer(USE_INTERVAL).timeout
var bodies = zone.area.get_overlapping_bodies() var bodies = zone.area.get_overlapping_bodies()
var rock_layer_id = bodies.find_custom(func (b) : return b is RockLayer) var rock_layers = bodies.filter(func (b) : return b is RockLayer)
if rock_layer_id != -1: for rock_layer in rock_layers:
var rock_layer : RockLayer = bodies[rock_layer_id] player.region.dig_rocks(zone.get_tiles())
rock_layer.dig_rocks(zone.get_tiles())
var particles := (DIG_PARTICLES.instantiate() as DigParticleEmmitter) var particles := (DIG_PARTICLES.instantiate() as DigParticleEmmitter)
player.region.add_child(particles) player.region.add_child(particles)

View File

@@ -165,7 +165,7 @@ func update_card():
func update_inspector(): 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: if can_interact and current_inspect and current_inspect is Interactable:
%Action.visible = true %Action.visible = true
%ActionText.text = current_inspect.interact_text() %ActionText.text = current_inspect.interact_text()

View File

@@ -2,6 +2,8 @@ extends Node3D
const DIALOG_PATH = "res://dialogs/timelines/story/demeter_ship_presentation.dtl" const DIALOG_PATH = "res://dialogs/timelines/story/demeter_ship_presentation.dtl"
var jingle_played := false
# Cheat Code # Cheat Code
func _input(_e): func _input(_e):
if ( if (
@@ -26,5 +28,6 @@ func _ready():
func _on_jingle_area_body_entered(body: Node3D): 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") AudioManager.play_sfx("Ship_reveal")
jingle_played = true

View File

@@ -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) transform = Transform3D(0.70710677, 0, 0.70710677, 0, 1, 0, -0.70710677, 0, 0.70710677, 31.365097, -1.8906436, 31.188667)
speed = 5.0 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] [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) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.37195766, 0.5465579, -0.44411802)

View File

@@ -2,20 +2,6 @@
extends Node2D extends Node2D
class_name Chunk 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 GENERATION_NUMBER = 4
const NOISE_IMAGE_SIZE := 150 const NOISE_IMAGE_SIZE := 150
@@ -25,41 +11,83 @@ const MAX_DECONTAMINATION_DISTANCE=2
const ROCK_NOISE_FREQUENCY := 0.01 const ROCK_NOISE_FREQUENCY := 0.01
const DECONTAMINATION_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(): @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() generate()
var data : ChunkData
func _init( func _init(
_data : ChunkData, _chunk_coord : Vector2i = Vector2i.ZERO,
_region : Region = null, _region_data : RegionData = RegionData.new(),
_generation_semaphore = Semaphore.new()
): ):
region = _region chunk_coord = _chunk_coord
if region: region_data = _region_data
region_seed = region.data.region_seed generation_semaphore = _generation_semaphore
data = _data
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(): func generate():
rock_noise_image = generate_noise(region_seed + 1, ROCK_NOISE_FREQUENCY) rock_noise_image = generate_noise(region_data.region_seed + 1, ROCK_NOISE_FREQUENCY)
decontamination_noise_image = generate_noise(region_seed + 2, DECONTAMINATION_NOISE_FREQUENCY) decontamination_noise_image = generate_noise(region_data.region_seed + 2, DECONTAMINATION_NOISE_FREQUENCY)
global_position = data.chunk_coord * (Region.CHUNK_TILE_SIZE * Region.TILE_SIZE) cristal_noise_image = generate_noise(region_data.region_seed + 3, ROCK_NOISE_FREQUENCY)
generate_rocks()
generate_ground() rock_layer = RockLayer.new(region_data)
generate_decontamination() ground_layer = GroundLayer.new(region_data)
decontamination_layer = DecontaminationLayer.new(region_data)
generation_semaphore.wait()
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)
func finish_one_generation(generation_name : String):
generation_finished.append(generation_name)
if len(generation_finished) >= GENERATION_NUMBER:
is_generated = true is_generated = true
func unload(): # func unload():
for x in range(Region.CHUNK_TILE_SIZE): # for x in range(Region.CHUNK_TILE_SIZE):
for y 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 # var global_coord = Vector2i(x, y) + Region.CHUNK_TILE_SIZE * chunk_coord
region.rock_layer.erase_cell(global_coord) # region.rock_layer.erase_cell(global_coord)
region.ground_layer.erase_cell(global_coord) # region.ground_layer.erase_cell(global_coord)
region.decontamination_layer.erase_cell(global_coord) # region.decontamination_layer.erase_cell(global_coord)
# Debug # Debug
# func _draw(): # func _draw():
@@ -94,8 +122,8 @@ func generate_noise(
noise.fractal_type = FastNoiseLite.FRACTAL_NONE noise.fractal_type = FastNoiseLite.FRACTAL_NONE
noise.fractal_weighted_strength = 1.0 noise.fractal_weighted_strength = 1.0
noise.offset = Vector3( noise.offset = Vector3(
noise_image_size.x * data.chunk_coord.x, noise_image_size.x * chunk_coord.x,
noise_image_size.y * data.chunk_coord.y, noise_image_size.y * chunk_coord.y,
1 1
) )
@@ -108,62 +136,80 @@ func get_tile_value_from_noise(tile_position : Vector2i, noise : Noise) -> float
) )
return (val + 1)/2 return (val + 1)/2
func generate_rocks(): func generate_rocks(layer : RockLayer):
var cristals : Array[Vector2i] = [] var cristals : Array[Vector2i] = []
var rocks : Array[Vector2i] = [] var rocks : Array[Vector2i] = []
for x in range(Region.CHUNK_TILE_SIZE): for x in range(0, Region.CHUNK_TILE_SIZE):
for y in range(Region.CHUNK_TILE_SIZE): for y in range(0, Region.CHUNK_TILE_SIZE):
var tile_type := get_generated_rock_type(Vector2i(x, y)) 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: if tile_type == RockLayer.TileType.CRISTAL:
cristals.append(global_coord) cristals.append(coord)
elif tile_type == RockLayer.TileType.ROCK: 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")) layer.place_rocks(cristals, RockLayer.TileType.CRISTAL)
region.rock_layer.place_rocks(rocks, RockLayer.TileType.ROCK, func(): finish_one_generation("cristal")) layer.place_rocks(rocks, RockLayer.TileType.ROCK)
func get_generated_rock_type(coord : Vector2i) -> RockLayer.TileType: func get_generated_rock_type(coord : Vector2i) -> RockLayer.TileType:
var tile_value : float = get_tile_value_from_noise(coord, rock_noise_image) var rock_tile_value : float = get_tile_value_from_noise(coord, rock_noise_image)
var saved_diff := data.get_rock_tile_diff(coord) 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 ( if saved_diff == TilesDiffData.TileDiff.ABSENT:
(saved_diff == ChunkData.TileDiff.PRESENT or tile_value < region.data.rock_threshold) return RockLayer.TileType.EMPTY
and saved_diff != ChunkData.TileDiff.ABSENT 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.CRISTAL if cristal_tile_value < region_data.cristal_threshold else RockLayer.TileType.ROCK
else :
return RockLayer.TileType.EMPTY return RockLayer.TileType.EMPTY
func generate_ground(): func generate_ground(layer : GroundLayer):
var coords : Array[Vector2i] = [] var coords : Array[Vector2i] = []
for x in range(Region.CHUNK_TILE_SIZE): for x in range(0, Region.CHUNK_TILE_SIZE):
for y in range(Region.CHUNK_TILE_SIZE): for y in range(0,Region.CHUNK_TILE_SIZE):
coords.append(Vector2i(x,y) + Region.CHUNK_TILE_SIZE * data.chunk_coord) 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] = [] var decontamination_tiles : Array[Vector2i] = []
for x in range(Region.CHUNK_TILE_SIZE): for x in range(0, Region.CHUNK_TILE_SIZE):
for y in range(Region.CHUNK_TILE_SIZE): for y in range(0, Region.CHUNK_TILE_SIZE):
var coord = Vector2i(x,y) var coord = Vector2i(x,y)
var tile_value : float = ( 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) 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 ( if (
( (
saved_diff == ChunkData.TileDiff.PRESENT (tile_value < region_data.decontamination_threshold)
or (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, decontamination_tiles,
false, 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()

View File

@@ -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)

View File

@@ -1 +0,0 @@
uid://clqa88okc325t

View File

@@ -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_SET : TileSet = preload("res://stages/terrain/region/resources/moss_biome.tres")
const TILE_SCALE = 1 const TILE_SCALE = 1
const TILE_SIZE : int = roundi(TILE_SET.tile_size.x * TILE_SCALE) 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 SPAWN_OBJECT_RANDOM_MOVEMENT = 200
const CHUNK_TILE_SIZE : int = 20 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_LOAD_DISTANCE : int = 1
const CHUNK_UNLOAD_DISTANCE : int = 2 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 first_loot_number : int = 3
@export var loot_item_number : Array[int] = [1,2] @export var loot_item_number : Array[int] = [1,2]
@@ -28,15 +28,12 @@ var data : RegionData
var in_passing_day_animation = false var in_passing_day_animation = false
var contamination_texture : ImageTexture var contamination_texture : ImageTexture
var rock_layer : RockLayer
var ground_layer : GroundLayer var creating_new_layer_pack = false
var decontamination_layer : DecontaminationLayer
var score_by_plant : Dictionary[PlantData, int] = {} var score_by_plant : Dictionary[PlantData, int] = {}
var tile_set = Region.TILE_SET var generated_chunks : Array[Chunk] = []
var generated_chunks : Dictionary[String,Chunk] = {}
var generation_semaphore : Semaphore var generation_semaphore : Semaphore
# Cheat Code # Cheat Code
@@ -66,7 +63,7 @@ func _init():
func _ready(): func _ready():
generation_semaphore = Semaphore.new() generation_semaphore = Semaphore.new()
generation_semaphore.post() generation_semaphore.post(MAX_GENERATION_THREAD)
entity_container.position = TILE_SIZE * CHUNK_TILE_SIZE * Vector2.ONE / 2 entity_container.position = TILE_SIZE * CHUNK_TILE_SIZE * Vector2.ONE / 2
load_entities(data.entities_saved_data) load_entities(data.entities_saved_data)
@@ -75,16 +72,6 @@ func _ready():
if e is Plant: if e is Plant:
data.add_plant_data(e.data, false) 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 %AstraDoor.global_position = data.player_spawn
player.global_position = data.player_position player.global_position = data.player_position
@@ -92,8 +79,6 @@ func _ready():
generate_near_chunks(player) generate_near_chunks(player)
edit_map_origin()
spawn_object_random_move(%RechargeStation) spawn_object_random_move(%RechargeStation)
%RechargeStation.update() %RechargeStation.update()
spawn_object_random_move(%BoreaDoor) spawn_object_random_move(%BoreaDoor)
@@ -109,93 +94,59 @@ func _process(_d):
func get_chunk_key(coord) -> String: func get_chunk_key(coord) -> String:
return "%d:%d" % [coord.x, coord.y] 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) var player_chunk_coord = Math.get_chunk_from_pos(p.global_position)
for x in range(-CHUNK_LOAD_DISTANCE, CHUNK_LOAD_DISTANCE+1): for x in range(-CHUNK_LOAD_DISTANCE, CHUNK_LOAD_DISTANCE+1):
for y 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 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) generate_chunk(coord)
new_chunk_created = true
func remove_far_chunks(p : Player): return new_chunk_created
func remove_far_chunks(p : Player) -> bool:
var chunk_deleted = false
var player_chunk_coord = Vector2i( var player_chunk_coord = Vector2i(
floor(p.global_position.x / (CHUNK_TILE_SIZE * TILE_SIZE)), floor(p.global_position.x / (CHUNK_TILE_SIZE * TILE_SIZE)),
floor(p.global_position.y / (CHUNK_TILE_SIZE * TILE_SIZE)) floor(p.global_position.y / (CHUNK_TILE_SIZE * TILE_SIZE))
) )
for chunk in generated_chunks.values(): for chunk in generated_chunks:
var chunk_coord = chunk.data.chunk_coord var chunk_coord = chunk.chunk_coord
if player_chunk_coord.distance_to(chunk_coord) > CHUNK_UNLOAD_DISTANCE: if player_chunk_coord.distance_to(chunk_coord) > CHUNK_UNLOAD_DISTANCE:
remove_chunk(chunk) remove_chunk(chunk)
chunk_deleted = true
return chunk_deleted
func generate_chunk(coord : Vector2i): func generate_chunk(coord : Vector2i):
var chunk_data := data.get_or_create_chunk_data(coord) if not is_chunk_generated(coord):
var chunk_key = get_chunk_key(coord)
if not generated_chunks.has(chunk_key):
var new_chunk = Chunk.new( var new_chunk = Chunk.new(
chunk_data, coord,
self data,
generation_semaphore
) )
generated_chunks[chunk_key] = new_chunk
add_child(new_chunk) add_child(new_chunk)
data.generated_chunk_entities.append(coord) generated_chunks.append(new_chunk)
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)
func remove_chunk(chunk : Chunk): func remove_chunk(chunk : Chunk):
generated_chunks.erase(get_chunk_key(chunk.data.chunk_coord)) generated_chunks.erase(chunk)
chunk.unload()
chunk.queue_free() chunk.queue_free()
func check_is_generated() -> bool: func check_is_generated() -> bool:
if len(generated_chunks.keys()) == 0: var ret = true
return false for c in generated_chunks:
return get_chunk_generation_count() == float(get_full_chunk_generation_count()) if not c.is_generated:
ret = false
return ret
func get_generated_value(): func get_generated_value() -> float:
return get_chunk_generation_count() / float(get_full_chunk_generation_count()) # if layer_pack:
# return layer_pack.generated_value
func get_full_chunk_generation_count() -> int: return 1.
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 save(): func save():
data.entities_saved_data = save_entities() data.entities_saved_data = save_entities()
@@ -232,6 +183,10 @@ func setup_flagged_properties():
%BoreaDoor.visible = true %BoreaDoor.visible = true
%RechargeStation.visible = false %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 #endregion
#region ------------------ Usage ------------------ #region ------------------ Usage ------------------
@@ -269,4 +224,51 @@ func pass_day():
data.end_pass_day() data.end_pass_day()
save() 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 #endregion

View File

@@ -14,6 +14,8 @@ signal pass_day_ended(region_data : RegionData)
const DEFAULT_START_CHARGE := 10 const DEFAULT_START_CHARGE := 10
const DEFAULT_OBJECTIVE := 10 const DEFAULT_OBJECTIVE := 10
const MAX_RANDOM_SPAWN_DISTANCE = 3000 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_seed : int
@export var region_name : String @export var region_name : String
@@ -26,14 +28,11 @@ const MAX_RANDOM_SPAWN_DISTANCE = 3000
@export var day : int = 1 @export var day : int = 1
@export var entities_saved_data : Array[EntityData] = [] @export var entities_saved_data : Array[EntityData] = []
@export var generated_chunk_entities : Array[Vector2i]
@export var flags : Array[String] = [] @export var flags : Array[String] = []
@export var plants : Array[PlantData] @export var plants : Array[PlantData]
@export var state : State = State.IN_PROGRESS @export var state : State = State.IN_PROGRESS
@export var chunks_data : Dictionary[String, ChunkData]
@export var player_position : Vector2 @export var player_position : Vector2
@export var player_spawn : Vector2 @export var player_spawn : Vector2
@@ -47,6 +46,8 @@ const MAX_RANDOM_SPAWN_DISTANCE = 3000
objective = v objective = v
update() update()
@export var rock_tiles_data : TilesDiffData
@export var decontamination_tiles_data : TilesDiffData
var in_passing_day_animation := false var in_passing_day_animation := false
@@ -67,6 +68,11 @@ func _init(
player_spawn = get_random_spawn_position() player_spawn = get_random_spawn_position()
player_position = player_spawn player_position = player_spawn
rock_tiles_data = TilesDiffData.new()
decontamination_tiles_data = TilesDiffData.new()
edit_map_origin()
func update(): func update():
if objective > 0 and get_score() >= objective and not "tutorial" in flags: if objective > 0 and get_score() >= objective and not "tutorial" in flags:
if state != State.SUCCEEDED: if state != State.SUCCEEDED:
@@ -78,30 +84,6 @@ func update():
state = State.FAILED state = State.FAILED
updated.emit(self) 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 #endregion
#region ------------------ Score ------------------ #region ------------------ Score ------------------
@@ -159,3 +141,36 @@ func get_random_spawn_position():
return rand_pos return rand_pos
#endregion #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

View File

@@ -11,22 +11,12 @@ func setup():
func place_decontamination(coord : Vector2i, save = false): func place_decontamination(coord : Vector2i, save = false):
place_decontaminations([coord], save) place_decontaminations([coord], save)
func place_decontaminations(coords : Array[Vector2i], save := false, on_finished : Callable = (func(): pass)): func place_decontaminations(coords : Array[Vector2i], save := false):
async_place_terrain_cells( place_terrain_cells(
coords, coords,
DECONTAMINATION_TILE_TERRAIN_SET, DECONTAMINATION_TILE_TERRAIN_SET,
DECONTAMINATION_TILE_TERRAIN, 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: func is_decontamined(coord : Vector2i) -> bool:
return has_cell(coord) return has_cell(coord)

View File

@@ -10,10 +10,9 @@ func setup():
material = MATERIAL material = MATERIAL
z_index = -100 z_index = -100
func place_ground(coords : Array[Vector2i], on_finished : Callable = (func(): pass)): func place_ground(coords : Array[Vector2i]):
async_place_terrain_cells( place_terrain_cells(
coords, coords,
GROUND_TILE_TERRAIN_SET, GROUND_TILE_TERRAIN_SET,
GROUND_TILE_TERRAIN, GROUND_TILE_TERRAIN,
on_finished
) )

View File

@@ -1,20 +1,22 @@
@tool
@abstract @abstract
extends TileMapLayer extends TileMapLayer
class_name RegionLayer class_name RegionLayer
var threads : Array[Thread] = [] @export var region_data : RegionData
var is_generated = false
var region : Region
func _init( func _init(
_planet : Region = null _region_data : RegionData
): ):
region = _planet set_physics_quadrant_size(Region.CHUNK_TILE_SIZE)
set_rendering_quadrant_size(Region.CHUNK_TILE_SIZE)
func _ready(): tile_set = Region.TILE_SET
tile_set = region.tile_set
scale = Vector2.ONE * Region.TILE_SCALE scale = Vector2.ONE * Region.TILE_SCALE
navigation_enabled = false navigation_enabled = false
region_data = _region_data
# collision_visibility_mode = DebugVisibilityMode.DEBUG_VISIBILITY_MODE_FORCE_SHOW
func _ready():
setup() setup()
func setup(): func setup():
@@ -35,37 +37,22 @@ func get_all_neighbors_cell(coord : Vector2i) -> Array[Vector2i]:
func has_cell(tile_position : Vector2i) -> bool: func has_cell(tile_position : Vector2i) -> bool:
return get_cell_source_id(tile_position) != -1 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( func place_terrain_cells(
coords : Array[Vector2i], coords : Array[Vector2i],
tile_terrain_set : int = 0, tile_terrain_set : int = 0,
tile_terrain : int = 0 tile_terrain : int = 0
): ):
region.generation_semaphore.wait() var valid_coords : Array[Vector2i] = coords.filter(is_coord_valid)
set_cells_terrain_connect( set_cells_terrain_connect(
coords, valid_coords,
tile_terrain_set, tile_terrain_set,
tile_terrain tile_terrain
) )
region.generation_semaphore.post()
func _exit_tree(): func is_coord_valid(coord : Vector2i) -> bool:
for t in threads: return (
t.wait_to_finish() coord.x >= 0
and coord.y >= 0
and coord.x < Region.CHUNK_TILE_SIZE
and coord.y < Region.CHUNK_TILE_SIZE
)

View File

@@ -6,61 +6,26 @@ const ROCK_TILE_TERRAIN_SET : int = 0
const ROCK_TILE_TERRAIN : int = 1 const ROCK_TILE_TERRAIN : int = 1
const CRISTAL_TILE_TERRAIN : int = 2 const CRISTAL_TILE_TERRAIN : int = 2
const CRISTAL_LOOT_CHANCE : float = 1
enum TileType { EMPTY,ROCK,CRISTAL } enum TileType { EMPTY,ROCK,CRISTAL }
func setup(): func setup():
z_index = -1 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: if type != TileType.EMPTY:
async_place_terrain_cells( place_terrain_cells(
coords, coords,
ROCK_TILE_TERRAIN_SET, ROCK_TILE_TERRAIN_SET,
ROCK_TILE_TERRAIN if type == TileType.ROCK else CRISTAL_TILE_TERRAIN, 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)): func remove_rocks(coords : Array[Vector2i], save = false):
async_place_terrain_cells( place_terrain_cells(
coords, coords,
ROCK_TILE_TERRAIN_SET, ROCK_TILE_TERRAIN_SET,
-1, -1
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)),
)
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: func has_tile(coord : Vector2i) -> bool:
return has_cell(coord) return has_cell(coord)

View File

@@ -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))

View File

@@ -0,0 +1 @@
uid://dy6d4rmdu6gh0

View File

@@ -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"

View File

@@ -10,7 +10,7 @@ PLANT_INFO_TEXT,"[b]1[/b] Name
[b]2[/b] Archétype [b]2[/b] Archétype
[b]3[/b] Score [b]3[/b] Score
[b]4[/b] Age [b]4[/b] Age
[b]5[/b] Durée de pousse [b]5[/b] Temps de croissance
[b]6[/b] Durée de vie" [b]6[/b] Durée de vie"
TERRAINS,Terrains,Terrains 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 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)" NO_ENERGY_LEFT," (no energy left)", " (pas d'énergie restante)"
%d_GARDEN_SCORE_LEFT,"%d garden score left","%d score de jardin restant" %d_GARDEN_SCORE_LEFT,"%d garden score left","%d score de jardin restant"
SETTINGS,Settings,Paramètres SETTINGS,Settings,Paramètres
LANGUAGE,Language,Language LANGUAGE,Language,Langage
SOUND,Sound,Son SOUND,Sound,Son
MUSIC_VOLUME,Music volume,Volume de la musique MUSIC_VOLUME,Music volume,Volume de la musique
ENVIRONMENT_VOLUME,Environment Volume,Volume de l'environnement ENVIRONMENT_VOLUME,Environment Volume,Volume de l'environnement
1 keys en fr
10 GARDEN Garden Jardin
11 COMMA , ,
12 OR or ou
13 PAUSE Pause Pause
14 CONTROLS Controls Contrôles
15 RESUME_GAME Resume Reprendre
16 RESTART Restart Recommencer
143 CONTROLS Controls Contrôles
144 MOVE_RIGHT Move right Déplacement à droite
145 MOVE_LEFT Move left Déplacement à gauche
146 MOVE_UP Move up Déplacement en haut
147 MOVE_DOWN Move down Déplacement en bas
148 ACTION Action Action
149 DROP Drop Lacher