refonte du système de chunk et correction de bug/traduction
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
8
common/vfx/materials/shaders/chunk_mask.gdshader
Normal file
8
common/vfx/materials/shaders/chunk_mask.gdshader
Normal file
@@ -0,0 +1,8 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
uniform sampler2D screen_texture: hint_screen_texture;
|
||||
|
||||
void fragment() {
|
||||
|
||||
COLOR = texture(screen_texture, SCREEN_UV);
|
||||
}
|
||||
1
common/vfx/materials/shaders/chunk_mask.gdshader.uid
Normal file
1
common/vfx/materials/shaders/chunk_mask.gdshader.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bc65ssv7bgy5d
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
@@ -1 +0,0 @@
|
||||
uid://clqa88okc325t
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
)
|
||||
@@ -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()
|
||||
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
|
||||
)
|
||||
@@ -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)
|
||||
|
||||
46
stages/terrain/region/scripts/tiles_diff_data.gd
Normal file
46
stages/terrain/region/scripts/tiles_diff_data.gd
Normal 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))
|
||||
1
stages/terrain/region/scripts/tiles_diff_data.gd.uid
Normal file
1
stages/terrain/region/scripts/tiles_diff_data.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dy6d4rmdu6gh0
|
||||
26
stages/terrain/region/test_chunk.tscn
Normal file
26
stages/terrain/region/test_chunk.tscn
Normal 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"
|
||||
@@ -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
|
||||
|
||||
|
Reference in New Issue
Block a user