création du squelette des region modifier, amélioration du tutoriel et mise en place de la run complète avec cinématique d'outro

This commit is contained in:
2026-02-21 20:44:41 +01:00
parent eb48a095de
commit e767e776f2
80 changed files with 415 additions and 201 deletions

View File

@@ -35,7 +35,7 @@ func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
set_room_part_number()
chosen_incubator_id = randi_range(0, len(%Incubators.get_children()))
chosen_incubator_id = randi_range(0, len(%Incubators.get_children()) - 1)
var new_player_incubator := %Incubators.get_children()[chosen_incubator_id] as Incubator
new_player_incubator.used = true
%Player3D.position = new_player_incubator.global_position + Vector3.UP
@@ -52,6 +52,7 @@ func _ready():
func story():
AudioManager.play_sfx("Respawn")
if not INTRO_DIALOG in GameInfo.game_data.dialogs_done:
await get_tree().create_timer(TIME_WITHOUT_PHONE).timeout
%Phone.play_audio()

View File

@@ -184,6 +184,9 @@ volumetric_fog_sky_affect = 0.0
adjustment_enabled = true
adjustment_saturation = 1.3
[sub_resource type="BoxShape3D" id="BoxShape3D_c8vcx"]
size = Vector3(0.001, 7.6933594, 7.697876)
[node name="BoreaBase" type="Node3D" unique_id=442220603]
script = ExtResource("1_fevne")
@@ -910,6 +913,13 @@ autoplay = &"blink"
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=1121246225]
environment = SubResource("Environment_fevne")
[node name="AmbianceChangeDetector" type="Area3D" parent="." unique_id=1401161313]
transform = Transform3D(0.25881904, 0, 0.96592593, 0, 1, 0, -0.96592593, 0, 0.25881904, 2.7012572, -5.600957, -42.815655)
[node name="CollisionShape3D" type="CollisionShape3D" parent="AmbianceChangeDetector" unique_id=1969356725]
transform = Transform3D(0.9999994, 0, 0, 0, 1, 0, 0, 0, 0.9999994, -9.359516, 0.82910156, 2.9935746)
shape = SubResource("BoxShape3D_c8vcx")
[node name="Player3D" parent="." unique_id=549819967 instance=ExtResource("3_c8vcx")]
unique_name_in_owner = true
transform = Transform3D(0.25881904, 0, 0.96592593, 0, 1, 0, -0.96592593, 0, 0.25881904, 29.244379, 41.40791, 8.823577)
@@ -924,3 +934,5 @@ transform = Transform3D(-0.93482566, 0, 0.35510686, 0, 1, 0, -0.35510686, 0, -0.
[node name="Credits" parent="." unique_id=180964898 instance=ExtResource("6_c8vcx")]
unique_name_in_owner = true
visible = false
[connection signal="body_entered" from="AmbianceChangeDetector" to="." method="_on_ambiance_change_detector_body_entered"]

View File

@@ -12,4 +12,11 @@ func _ready():
await Dialogic.timeline_ended
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
%Credits.show()
AudioManager.play_music("Title")
AudioManager.stop_ambiance()
func _on_ambiance_change_detector_body_entered(body: Node3D):
if body is Player3D:
AudioManager.stop_ambiance()
AudioManager.play_music("Title")

View File

@@ -109,7 +109,7 @@ func update_dashboard():
if choosen_run_point:
dashboard.destination_title_label = tr("DESTINATION")
dashboard.destination_longitude = float(choosen_run_point.level) / RunData.RUN_POINT_MAX_LEVEL
dashboard.destination_label = choosen_run_point.region_parameter.name
dashboard.destination_label = choosen_run_point.region_parameter.region_name
dashboard.status_text = ""
else:
dashboard.status_text = tr("CHOOSE_DESTINATION")

View File

@@ -95,13 +95,13 @@ func set_left_destination(v := left_destination):
%LeftScreenStats.visible = left_destination != null
if left_destination:
%LeftScreenActionIcon.texture = LAND_ICON
%LeftScreenActionLabel.text = left_destination.region_parameter.name
%LeftScreenActionLabel.text = left_destination.region_parameter.get_region_name()
%LeftScreenStat1Icon.texture = GROWTH_ICON
%LeftScreenStat1Label.text = str(left_destination.region_parameter.objective)
%LeftScreenStat1Label.text = str(left_destination.region_parameter.get_objective())
%LeftScreenStat2Icon.texture = CHARGE_ICON
%LeftScreenStat2Label.text = str(left_destination.region_parameter.charges)
%LeftScreenStat2Label.text = str(left_destination.region_parameter.get_charge())
func set_right_destination(v := right_destination):
right_destination = v
@@ -111,10 +111,10 @@ func set_right_destination(v := right_destination):
%RightScreenStats.visible = right_destination != null
if right_destination:
%RightScreenActionIcon.texture = LAND_ICON
%RightScreenActionLabel.text = right_destination.region_parameter.name
%RightScreenActionLabel.text = right_destination.region_parameter.get_region_name()
%RightScreenStat1Icon.texture = GROWTH_ICON
%RightScreenStat1Label.text = str(right_destination.region_parameter.objective)
%RightScreenStat1Label.text = str(right_destination.region_parameter.get_objective())
%RightScreenStat2Icon.texture = CHARGE_ICON
%RightScreenStat2Label.text = str(right_destination.region_parameter.charges)
%RightScreenStat2Label.text = str(right_destination.region_parameter.get_charge())

View File

@@ -17,8 +17,6 @@ func _input(_e):
func _ready():
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
GameInfo.game_data.tutorial_done = true
%Phone.play_audio()
await %Phone.clicked
%Phone.stop_audio()

View File

@@ -107,7 +107,7 @@ func update_region_points():
func _on_camera_3d_region_point_clicked(rp : RunPoint):
selected_run_point = rp
%TravelValidationLabel.text = tr("TRAVEL_TO_REGION_%s") % rp.region_parameter.name
%TravelValidationLabel.text = tr("TRAVEL_TO_REGION_%s") % rp.region_parameter.region_name
%TravelValidation.show()
func _on_travel_validation_go_button_button_down():

View File

@@ -20,6 +20,7 @@ unique_name_in_owner = true
layer = 2
[node name="Tutorial" parent="RegionGui" unique_id=762436685 node_paths=PackedStringArray("player", "region") instance=ExtResource("2_2f6js")]
unique_name_in_owner = true
player = NodePath("../../Entities/Player")
region = NodePath("../..")
@@ -31,8 +32,9 @@ y_sort_enabled = true
[node name="Player" parent="Entities" unique_id=75851644 instance=ExtResource("5_ovqi1")]
z_index = 1
[node name="TruckRecharge" parent="Entities" unique_id=2068738444 instance=ExtResource("7_6d8m3")]
position = Vector2(-1, -169)
[node name="RechargeStation" parent="Entities" unique_id=2068738444 instance=ExtResource("7_6d8m3")]
unique_name_in_owner = true
position = Vector2(-405, -151)
[node name="AstraDoor" parent="Entities" unique_id=2053096538 instance=ExtResource("8_2f6js")]
unique_name_in_owner = true
@@ -45,15 +47,17 @@ default_info_desc = "ASTRA_FACTORY_TEXT"
[node name="BoreaDoor" parent="Entities" unique_id=135926916 instance=ExtResource("8_2f6js")]
unique_name_in_owner = true
visible = false
position = Vector2(91, -177)
to_scene_id = "BOREA"
default_interact_text = "ENTER"
default_info_title = "BOREA_BASE"
default_info_desc = "ASTRA_FACTORY_TEXT"
default_info_desc = "BOREA_BASE_DESC_TEXT"
[node name="ShipGarageDoor" parent="Entities" unique_id=1073871193 instance=ExtResource("8_2f6js")]
unique_name_in_owner = true
visible = false
modulate = Color(1, 0, 0, 1)
position = Vector2(91, -177)
to_scene_id = "GARAGE"
default_interact_text = "ENTER"
available = false

View File

@@ -6,9 +6,6 @@ signal generated
var region : Region
var region_seed : int
var wall_threshold = 0.3
var decontamination_threshold = 0.
var cristal_threshold = 0.08
var rock_noise_image : Noise = null
var decontamination_noise_image : Noise = null
@@ -23,6 +20,8 @@ const GENERATION_NUMBER = 4
const NOISE_IMAGE_SIZE := 150
const MAX_DECONTAMINATION_DISTANCE=2
const ROCK_NOISE_FREQUENCY := 0.01
const DECONTAMINATION_NOISE_FREQUENCY := 0.01
@@ -34,9 +33,9 @@ var data : ChunkData
func _init(
_data : ChunkData,
_planet : Region = null,
_region : Region = null,
):
region = _planet
region = _region
if region:
region_seed = region.data.region_seed
data = _data
@@ -129,10 +128,10 @@ func get_generated_rock_type(coord : Vector2i) -> RockLayer.TileType:
var saved_diff := data.get_rock_tile_diff(coord)
if (
(saved_diff == ChunkData.TileDiff.PRESENT or tile_value < wall_threshold)
(saved_diff == ChunkData.TileDiff.PRESENT or tile_value < region.data.rock_threshold)
and saved_diff != ChunkData.TileDiff.ABSENT
):
return RockLayer.TileType.CRISTAL if tile_value < cristal_threshold else RockLayer.TileType.ROCK
return RockLayer.TileType.CRISTAL if tile_value < region.data.cristal_threshold else RockLayer.TileType.ROCK
return RockLayer.TileType.EMPTY
func generate_ground():
@@ -148,10 +147,16 @@ func generate_decontamination():
for x in range(Region.CHUNK_TILE_SIZE):
for y in range(Region.CHUNK_TILE_SIZE):
var coord = Vector2i(x,y)
var tile_value : float = get_tile_value_from_noise(coord, decontamination_noise_image)
var tile_value : float = (
1. if data.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)
if (
(saved_diff == ChunkData.TileDiff.PRESENT or tile_value < decontamination_threshold)
(
saved_diff == ChunkData.TileDiff.PRESENT
or (tile_value < region.data.decontamination_threshold)
)
and saved_diff != ChunkData.TileDiff.ABSENT
):
decontamination_tiles.append(Vector2i(x,y) + Region.CHUNK_TILE_SIZE * data.chunk_coord)

View File

@@ -0,0 +1,14 @@
extends RegionModifier
class_name AridModifier
func get_modifier_name() -> String:
return tr("ARID")
func get_description() -> String:
return tr("ARID_MODIFIER_DESC_TEXT")
func modify_decontamination_threshold(decontamination_threshold : float) -> float:
return decontamination_threshold
func modify_start_decontamination_zone_radius(start_decontamination_zone_radius : int) -> int:
return start_decontamination_zone_radius

View File

@@ -0,0 +1 @@
uid://3o33x8mesgrn

View File

@@ -0,0 +1,35 @@
@abstract
extends Resource
class_name RegionModifier
var level : int = 1
var modifier_name : String : get = get_modifier_name
var description : String : get = get_description
func _init(_level : int = 1):
level = _level
@abstract func get_modifier_name() -> String
@abstract func get_description() -> String
func get_difficulty_score() -> float:
return float(level)
func modify_charge(charge : int) -> int:
return charge
func modify_objective(objective : int) -> int:
return objective
func modify_rock_threshold(rock_threshold : float) -> float:
return rock_threshold
func modify_decontamination_threshold(decontamination_threshold : float) -> float:
return decontamination_threshold
func modify_cristal_threshold(cristal_threshold : float) -> float:
return cristal_threshold
func modify_start_decontamination_zone_radius(start_decontamination_zone_radius : int) -> int:
return start_decontamination_zone_radius

View File

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

View File

@@ -10,7 +10,8 @@ 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 START_DECONTAMINATION_HOLE_RADIUS = 3
const SPAWN_OBJECT_RANDOM_MOVEMENT = 200
const CHUNK_TILE_SIZE : int = 20
const CHUNK_SIZE = CHUNK_TILE_SIZE * TILE_SIZE
const CHUNK_LOAD_DISTANCE : int = 1
@@ -46,6 +47,7 @@ func _input(_e):
and Input.is_action_pressed("move_left")
and Input.is_action_just_pressed("action")
):
%Tutorial.finish_tutorial()
data.succeded.emit()
data.state = RegionData.State.SUCCEEDED
data.update()
@@ -89,6 +91,10 @@ func _ready():
edit_map_origin()
spawn_object_random_move(%RechargeStation)
spawn_object_random_move(%BoreaDoor)
spawn_object_random_move(%ShipGarageDoor)
func _process(_d):
if player:
generate_near_chunks(player)
@@ -144,17 +150,17 @@ func edit_map_origin():
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:
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 position
# Dig a hole in player spawn
var player_hole_tiles : Array[Vector2i] = []
var player_tile_position := Vector2i(
roundi(data.player_position.x/float(TILE_SIZE)),
roundi(data.player_position.y/float(TILE_SIZE))
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):
@@ -192,6 +198,15 @@ func save():
data.player_position = player.global_position
GameInfo.save_game_data()
func spawn_object_random_move(object : Node2D):
var rng := RandomNumberGenerator.new()
rng.seed = data.region_seed + object.name.hash()
object.position = Vector2(
rng.randf_range(-SPAWN_OBJECT_RANDOM_MOVEMENT,+SPAWN_OBJECT_RANDOM_MOVEMENT),
rng.randf_range(-SPAWN_OBJECT_RANDOM_MOVEMENT,SPAWN_OBJECT_RANDOM_MOVEMENT)
)
func setup_flagged_properties():
%AstraDoor.visible = false
@@ -205,12 +220,13 @@ func setup_flagged_properties():
%ShipGarageDoor.visible = true
%AstraDoor.available = false
%ShipGarageDoor.available = data.state == RegionData.State.SUCCEEDED
data.succeded.connect(
%Tutorial.succeded.connect(
func ():
%ShipGarageDoor.available = true
)
"borea":
%BoreaDoor.visible = true
%RechargeStation.visible = false
#endregion

View File

@@ -18,10 +18,15 @@ const MAX_RANDOM_SPAWN_DISTANCE = 3000
@export var region_seed : int
@export var region_name : String
@export var region_level : int = 0
@export var rock_threshold : float
@export var decontamination_threshold : float
@export var cristal_threshold : float
@export var start_decontamination_hole_radius = 3
@export var day : int = 1
@export var entities_saved_data : Array[EntityData] = []
@export var generated_chunk_entities : Array[Vector2i]
@export var tutorial_step : int = 0
@export var flags : Array[String] = []
@export var plants : Array[PlantData]
@@ -50,13 +55,17 @@ var in_passing_day_animation := false
func _init(
parameter : RegionParameter = RegionParameter.new()
):
charges = parameter.charges
objective = parameter.objective
region_name = parameter.name
region_level = parameter.level
region_seed = parameter.region_seed
charges = parameter.get_charge()
objective = parameter.get_objective()
region_name = parameter.get_region_name()
region_level = parameter.get_region_level()
region_seed = parameter.get_region_seed()
rock_threshold = parameter.get_rock_threshold()
decontamination_threshold = parameter.get_decontamination_threshold()
cristal_threshold = parameter.get_cristal_threshold()
start_decontamination_hole_radius = parameter.get_start_decontamination_zone_radius()
flags = parameter.get_region_flags()
flags = parameter.flags
player_spawn = get_random_spawn_position()
player_position = player_spawn
@@ -137,7 +146,6 @@ func add_plant_data(plant_data : PlantData, with_update = true):
update()
func _on_plant_disappeared(plant_data : PlantData):
print("disappeared")
plants = plants.filter(func (p) : return p.random_seed != plant_data.random_seed)
update()
@@ -151,3 +159,5 @@ func get_random_spawn_position():
) + Region.CHUNK_SIZE/2. * Vector2.ONE
return rand_pos
#endregion

View File

@@ -1,24 +1,92 @@
extends Resource
class_name RegionParameter
@export var charges : int
@export var objective : int
@export var name : String
@export var flags : Array[String]
const DEFAULT_ROCK_THRESHOLD = 0.3
const DEFAULT_DECONTAMINATION_THRESHOLD = 0.15
const DEFAULT_CRISTAL_THRESHOLD = 0.06
const DEFAULT_CHARGE = 10
const DEFAULT_START_DECONTAMINATION_ZONE_RADIUS = 3
@export var region_name : String
@export var region_flags : Array[String]
@export var level : int
@export var region_seed : int
@export var modifiers : Array[RegionModifier]
static func get_objective_by_level(l : int) -> int:
return 10 + 5 * l
func _init(
_charges : int = 10,
_objective : int = 10,
_level = 0,
_name = Random.generate_random_word(),
_flags : Array[String] = [],
_level = 0,
_modifiers : Array[RegionModifier] = [],
_region_seed = randi(),
):
charges = _charges
objective = _objective
name = _name
flags = _flags
region_name = _name
region_flags = _flags
level = _level
modifiers = _modifiers
region_seed = _region_seed
func get_region_name() -> String:
return region_name
func get_region_flags() -> Array[String]:
return region_flags
func get_region_level() -> int:
return level
func get_region_seed() -> int:
return region_seed
func get_objective() -> int:
if "tutorial" in region_flags:
return 1
var o = get_objective_by_level(get_region_level())
for m in modifiers:
o = m.modify_objective(o)
return o
func get_charge() -> int:
var c = DEFAULT_CHARGE
for m in modifiers:
c = m.modify_charge(c)
return c
func get_rock_threshold() -> float:
var threshold = DEFAULT_ROCK_THRESHOLD
for m in modifiers:
threshold = m.modify_rock_threshold(threshold)
return threshold
func get_decontamination_threshold() -> float:
var threshold = DEFAULT_DECONTAMINATION_THRESHOLD
for m in modifiers:
threshold = m.modify_decontamination_threshold(threshold)
return threshold
func get_cristal_threshold() -> float:
var threshold = DEFAULT_CRISTAL_THRESHOLD
for m in modifiers:
threshold = m.modify_cristal_threshold(threshold)
return threshold
func get_start_decontamination_zone_radius() -> int:
var zone_radius := DEFAULT_START_DECONTAMINATION_ZONE_RADIUS
for m in modifiers:
zone_radius = m.modify_start_decontamination_zone_radius(zone_radius)
return zone_radius