Amélioration QOL et fix divers pour l'alpha-1.1

* Ajout des icônes dans les descriptions des mutations
* QOL sur la fonctionnalité de drop d'item
* Ajout des contrôles dans le tutoriel
* Réécriture des dialogues d'intro et d'échec
* Changements mineurs sur des dialogues et traduction
* Les graines apparaissent avec déjà une mutation
* Limitation du Talion autour de la station de recharge
* Fix de l'ascenseur dans la base Astra
* Ajout d'un effet visuel quand il n'y a plus d'énergie
* Le nombre de graine apparrait désormais dans l'inspécteur de plantes
* Ajout d'un petit icône de progrès de durée de vie de la plante au survol
* Ajout d'une description de la signification des icônes dans le menu pause
* La mutation éphémère réduit désormais la durée de vie de 1
This commit is contained in:
2026-03-13 11:40:31 +01:00
parent 2cd16acd6a
commit 76707171fa
45 changed files with 430 additions and 177 deletions

Binary file not shown.

View File

@@ -7,6 +7,10 @@
[sub_resource type="BoxShape3D" id="BoxShape3D_werxl"]
size = Vector3(0.9637451, 1.8898926, 1)
[sub_resource type="CylinderShape3D" id="CylinderShape3D_werxl"]
height = 0.2268219
radius = 1.0737305
[sub_resource type="Animation" id="Animation_0mfvw"]
length = 0.001
tracks/0/type = "value"
@@ -50,19 +54,28 @@ interactable = false
hover_animation_player = NodePath("HoverAnimationPlayer")
[node name="Sprite3D" type="Sprite3D" parent="." unique_id=1624930927]
transform = Transform3D(-4.2294918e-08, 0.17856176, 0.9839286, 7.805184e-09, 0.9839286, -0.17856176, -1, 1.2748912e-10, -4.3008885e-08, -0.8393693, 1.5452437, 0)
transform = Transform3D(-4.2294918e-08, 0.17856175, 0.9839286, 7.805184e-09, 0.9839286, -0.17856175, -1, 1.2749e-10, -4.3008885e-08, -0.8393693, 1.5452437, 0)
texture = ExtResource("2_cun7v")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=525472594]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.1801186, 1.1958501, 0)
shape = SubResource("BoxShape3D_werxl")
[node name="Model" parent="." unique_id=1309925933 instance=ExtResource("3_x56sx")]
[node name="Model" parent="." unique_id=1852940735 instance=ExtResource("3_x56sx")]
[node name="OmniLight3D" type="OmniLight3D" parent="." unique_id=11561025]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.2593379, 0)
light_color = Color(0.717588, 0.45361686, 0.5535787, 1)
shadow_enabled = true
[node name="RigidBody3D" type="RigidBody3D" parent="." unique_id=618737753]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.26774597, 1.1958501, 0)
gravity_scale = 0.0
freeze = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="RigidBody3D" unique_id=1756356716]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.33335906, -1.2537155, 0)
shape = SubResource("CylinderShape3D_werxl")
[node name="HoverAnimationPlayer" type="AnimationPlayer" parent="." unique_id=487483897]
libraries/ = SubResource("AnimationLibrary_0mfvw")

View File

@@ -125,9 +125,8 @@ shape = SubResource("RectangleShape2D_y51rk")
unique_name_in_owner = true
scale = Vector2(0.33, 0.33)
sprite_frames = SubResource("SpriteFrames_4aafg")
animation = &"close"
frame = 8
frame_progress = 1.0
animation = &"closed"
frame_progress = 0.99532324
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=1875435966]
position = Vector2(0.99999994, -41)

View File

@@ -8,6 +8,35 @@
atlas = ExtResource("3_j6jm5")
region = Rect2(76, 75, 124, 135)
[sub_resource type="ViewportTexture" id="ViewportTexture_rbgiq"]
viewport_path = NodePath("LifeTimeSprite/SubViewport")
[sub_resource type="Gradient" id="Gradient_rbgiq"]
interpolation_mode = 1
offsets = PackedFloat32Array(0, 0.800905, 1)
colors = PackedColorArray(1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_rbgiq"]
gradient = SubResource("Gradient_rbgiq")
width = 100
height = 100
fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(1, 0.5)
[sub_resource type="Gradient" id="Gradient_j6jm5"]
interpolation_mode = 1
offsets = PackedFloat32Array(0, 0.5248869)
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 0)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_wyuub"]
gradient = SubResource("Gradient_j6jm5")
width = 100
height = 100
fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(1, 0.5)
[sub_resource type="Animation" id="Animation_wyuub"]
length = 0.001
tracks/0/type = "value"
@@ -119,6 +148,30 @@ position = Vector2(4.444448, 31.11118)
scale = Vector2(3.1777775, 3.1777775)
texture = ExtResource("3_rbgiq")
[node name="LifeTimeSprite" type="Sprite2D" parent="." unique_id=799762981]
unique_name_in_owner = true
position = Vector2(-1, -9.999985)
scale = Vector2(0.34, 0.34)
texture = SubResource("ViewportTexture_rbgiq")
[node name="SubViewport" type="SubViewport" parent="LifeTimeSprite" unique_id=1809354262]
disable_3d = true
transparent_bg = true
size = Vector2i(100, 100)
[node name="LifetimeProgressBar" type="TextureProgressBar" parent="LifeTimeSprite/SubViewport" unique_id=967185775]
unique_name_in_owner = true
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 6
size_flags_vertical = 6
fill_mode = 4
texture_over = SubResource("GradientTexture2D_rbgiq")
texture_progress = SubResource("GradientTexture2D_wyuub")
[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=1793068152]
unique_name_in_owner = true
libraries/ = SubResource("AnimationLibrary_8eofq")

View File

@@ -7,11 +7,12 @@ const HARVESTED_SEED_DISPLACEMENT_FACTOR = 100
const RANDOM_MAX_GROW_INTERVAL = Region.MIN_PASS_DAY_ANIMATION_TIME/2. - 0.1
const PLANT_TYPE_ICON = preload("res://common/icons/seedling.svg")
const PLANT_POINT_ICON = preload("res://common/icons/growth.svg")
const LIFETIME_ICON = preload("res://common/icons/calendar-week.svg")
const SCORE_ICON = preload("res://common/icons/growth.svg")
const DURATION_ICON = preload("res://common/icons/calendar-week.svg")
const SHOVEL_ICON = preload("res://common/icons/shovel.svg")
const GROWING_ICON = preload("res://common/icons/chevrons-up.svg")
const DEATH_ICON = preload("res://common/icons/skull.svg")
const LIFETIME_ICON= preload("res://common/icons/skull.svg")
const SEED_ICON = preload("res://common/icons/droplets.svg")
const SPRITE_SCENE : PackedScene = preload("res://entities/plants/plant_sprite.tscn")
@@ -47,11 +48,12 @@ func pointer_text() -> String:
return data.plant_name
func inspect(is_inspected : bool = true):
plant_sprite.modulate = MODULATE_INSPECTED_COLOR if is_inspected else default_modulate
plant_sprite.sprite_modulate = MODULATE_INSPECTED_COLOR if is_inspected else default_modulate
plant_sprite.display_lifetime_sprite = is_inspected
influence_zone.show_influence = is_inspected
func affect_preview(is_affected : bool = true):
plant_sprite.modulate = MODULATE_AFFECTED_COLOR if is_affected else default_modulate
plant_sprite.sprite_modulate = MODULATE_AFFECTED_COLOR if is_affected else default_modulate
func generate_sprite() -> PlantSprite:
var sprite_object : PlantSprite = SPRITE_SCENE.instantiate()
@@ -155,10 +157,10 @@ func save() -> EntityData:
func card_info() -> CardInfo:
var info = CardInfo.new(
data.plant_name,
tr("MATURE") if data.is_mature() else tr("GROWING")# data.archetype.archetype_name
tr("MATURE") if data.is_mature() else tr("JUVENILE")# data.archetype.archetype_name
)
info.important_stat_icon = PLANT_POINT_ICON
info.important_stat_icon = SCORE_ICON
info.important_stat_text = "%d" % calculate_plant_score()
info.type_icon = PLANT_TYPE_ICON
@@ -166,7 +168,7 @@ func card_info() -> CardInfo:
info.stats.append_array([
CardStatInfo.new(
str(data.day),
LIFETIME_ICON
DURATION_ICON
),
CardStatInfo.new(
str(data.get_growing_time()),
@@ -174,7 +176,14 @@ func card_info() -> CardInfo:
),
CardStatInfo.new(
str(data.get_lifetime()),
DEATH_ICON
LIFETIME_ICON
),
CardStatInfo.new(
"%d-%d" % [
data.get_seed_number(PlantData.State.MATURE) - data.get_seed_random_loose(),
data.get_seed_number(PlantData.State.MATURE)
],
SEED_ICON
),
])

View File

@@ -133,7 +133,7 @@ func get_seed_buff() -> int:
var buff = 0
for m in mutations:
buff += m.mutate_seed_buff(self)
buff = m.mutate_seed_buff(self, buff)
return buff

View File

@@ -51,8 +51,8 @@ func mutate_seed_random_loose(_plant_data: PlantData, seed_random_loose) -> int:
func mutate_lifetime_buff(_plant_data: PlantData) -> int:
return 0
func mutate_seed_buff(_plant_data: PlantData) -> int:
return 0
func mutate_seed_buff(_plant_data: PlantData, seed_buff : int) -> int:
return seed_buff
func _start_planted_effect(_plant: Plant):
pass
@@ -78,7 +78,7 @@ func get_rarity() -> int:
func card_section() -> CardSectionInfo:
var section = CardSectionInfo.new(
get_mutation_name() + (" %d" % level if level > 1 else ""),
"[b]%s[/b] %s" % [tr(PlantMutation.get_rarity_text(get_rarity())), get_mutation_description()]
get_mutation_description()
)
section.color = PlantMutation.get_rarity_color(get_rarity())
@@ -108,4 +108,4 @@ static func get_rarity_color(rarity: int) -> Color:
Color("FFA617"),
]
return rarity_colors[min(rarity, len(rarity_colors) - 1)]
return rarity_colors[min(rarity, len(rarity_colors) - 1)]

View File

@@ -13,10 +13,12 @@ func get_mutation_name() -> String:
return tr("ANCIENT")
func get_mutation_description() -> String:
return tr("ANCIENT_EFFECT_TEXT_LEVEL").format(
return tr("ANCIENT_EFFECT_TEXT").format(
{
"score_increase": get_score_increase(),
"day_factor": get_day_factor()
"score_icon": Text.bbcode_icon(Plant.SCORE_ICON),
"day_factor": get_day_factor(),
"duration_icon": Text.bbcode_icon(Plant.DURATION_ICON),
}
)

View File

@@ -11,16 +11,21 @@ func get_mutation_name() -> String:
return tr("EPHEMERAL")
func get_mutation_description() -> String:
return tr("EPHEMERAL_EFFECT_TEXT_LEVEL").format({"seed_number": level, "lifetime_change": get_lifetime_change()})
return tr("EPHEMERAL_EFFECT_TEXT").format({
"seed_number": level,
"seed_icon": Text.bbcode_icon(Plant.SEED_ICON),
"lifetime_change": get_lifetime_change(),
"lifetime_icon": Text.bbcode_icon(Plant.LIFETIME_ICON),
})
func mutate_lifetime(_plant_data: PlantData, lifetime: int) -> int:
return lifetime + get_lifetime_change()
func mutate_seed_number(_plant_data: PlantData, seed_number: int):
return seed_number + level
return seed_number + level + 1
func get_seed_increase() -> int:
return floori((level + 1.0) / 2)
func get_lifetime_change() -> int:
return -2
return -1

View File

@@ -11,7 +11,13 @@ func get_mutation_name() -> String:
return tr("FERTILE")
func get_mutation_description() -> String:
return tr("FERTILE_EFFECT_TEXT_LEVEL_%d") % level
return tr("FERTILE_EFFECT_TEXT").format({
"seed_buff": get_seed_buff(),
"seed_icon": Text.bbcode_icon(Plant.SEED_ICON)
})
func mutate_seed_buff(_plant_data: PlantData) -> int:
return level
func mutate_seed_buff(_plant_data: PlantData, seed_buff) -> int:
return seed_buff + get_seed_buff()
func get_seed_buff():
return level

View File

@@ -11,7 +11,13 @@ func get_mutation_name() -> String:
return tr("PRECOCIOUS")
func get_mutation_description() -> String:
return tr("PRECOCIOUS_EFFECT_TEXT_LEVEL_%d") % level
return tr("PRECOCIOUS_EFFECT_TEXT").format({
"score": get_score(),
"score_icon": Text.bbcode_icon(Plant.SCORE_ICON)
})
func mutate_score(data : PlantData, score : int) -> int:
return score + (0 if data.get_state() == PlantData.State.MATURE else level)
return score + (0 if data.get_state() == PlantData.State.MATURE else get_score())
func get_score():
return level

View File

@@ -11,7 +11,9 @@ func get_mutation_name() -> String:
return tr("PURIFICATION")
func get_mutation_description() -> String:
return tr("PURIFICATION_EFFECT_TEXT_LEVEL_%d") % get_purification_radius()
return tr("PURIFICATION_EFFECT_TEXT").format({
"purification_radius": get_purification_radius()
})
func _start_maturation_effect(plant : Plant):
plant.region.decontaminate(Math.get_tiles_in_circle(

View File

@@ -14,7 +14,13 @@ func get_mutation_name() -> String:
return tr("QUALITY")
func get_mutation_description() -> String:
return tr("QUALITY_EFFECT_TEXT_LEVEL_%d") % level
return tr("QUALITY_EFFECT_TEXT").format({
"score": get_score(),
"score_icon": Text.bbcode_icon(Plant.SCORE_ICON)
})
func mutate_score(data : PlantData, score : int) -> int:
return score + (level if data.get_state() == PlantData.State.MATURE else 0)
return score + (get_score() if data.get_state() == PlantData.State.MATURE else 0)
func get_score():
return level

View File

@@ -11,7 +11,14 @@ func get_mutation_name() -> String:
return tr("QUICK")
func get_mutation_description() -> String:
return tr("QUICK_EFFECT_TEXT_LEVEL").format({"score_increase": get_score_increase(), "lifetime_decrease": get_lifetime_decrease()})
return tr("QUICK_EFFECT_TEXT").format(
{
"score_increase": get_score_increase(),
"lifetime_decrease": get_lifetime_change(),
"score_icon": Text.bbcode_icon(Plant.SCORE_ICON),
"lifetime_icon": Text.bbcode_icon(Plant.LIFETIME_ICON)
}
)
func mutate_score(plant_data: PlantData, score: int) -> int:
if not plant_data.is_mature():
@@ -20,10 +27,10 @@ func mutate_score(plant_data: PlantData, score: int) -> int:
return score + level
func mutate_lifetime(_plant_data: PlantData, lifetime: int) -> int:
return max(1, lifetime-get_lifetime_decrease())
return max(1, lifetime+get_lifetime_change())
func get_score_increase() -> int:
return level * 2
func get_lifetime_decrease() -> int:
return 3
func get_lifetime_change() -> int:
return -3

View File

@@ -13,10 +13,11 @@ func get_mutation_name() -> String:
return tr("SOCIABLE")
func get_mutation_description() -> String:
return tr("SOCIABLE_EFFECT_TEXT_LEVEL").format(
return tr("SOCIABLE_EFFECT_TEXT").format(
{
"near_amount": get_near_plants_around(),
"score_increase": get_score_increase()
"score_increase": get_score_increase(),
"score_icon": Text.bbcode_icon(Plant.SCORE_ICON),
}
)

View File

@@ -11,13 +11,21 @@ func get_mutation_name() -> String:
return tr("TOUGH")
func get_mutation_description() -> String:
return tr("TOUGH_EFFECT_TEXT_LEVEL_%d") % get_growing_time_increase()
return tr("TOUGH_EFFECT_TEXT").format({
"score_icon": Text.bbcode_icon(Plant.SCORE_ICON),
"score_multiplier": get_score_multiplier(),
"growing_time": get_growing_time_increase(),
"growing_icon": Text.bbcode_icon(Plant.GROWING_ICON)
})
func mutate_score_multiplier(_plant_data: PlantData, multiplier: int) -> int:
return multiplier * 2
return multiplier * get_score_multiplier()
func mutate_growing_time(_plant_data: PlantData, growing_time: int) -> int:
return maxi(0, growing_time + get_growing_time_increase())
func get_growing_time_increase()->int:
return 4 - level
func get_score_multiplier()->int:
return 2

View File

@@ -11,7 +11,11 @@ signal harvest_animation_finished
var last_updated_on_state : PlantData.State = PlantData.State.MATURE
var stored_seed_image : Texture = null
var display_lifetime_sprite : bool = false : set = set_display_lifetime_sprite
var sprite_modulate : Color = Color.WHITE : set = set_sprite_modulate
func setup_plant_sprite(plant_data : PlantData):
set_display_lifetime_sprite()
%PlantedSeed.texture = PlantTextureBuilder.build_seed_texture(plant_data.plant_name.hash())
update_plant_sprite(plant_data,true)
@@ -25,6 +29,8 @@ func update_plant_sprite(plant_data : PlantData, with_animation = false):
%PlantedSeed.visible = plant_data.get_state() == PlantData.State.PLANTED
%LifetimeProgressBar.value = 100 * (float(plant_data.day)/plant_data.get_lifetime())
# %PlantedSeed.region_rect = Rect2(
# 0,
# PLANTED_SEED_POS_Y,
@@ -47,3 +53,13 @@ func start_harvest_animation():
$AnimationPlayer.play("harvest")
await $AnimationPlayer.animation_finished
harvest_animation_finished.emit()
func set_display_lifetime_sprite(d := display_lifetime_sprite):
display_lifetime_sprite = d
if is_node_ready():
%LifeTimeSprite.visible = d
func set_sprite_modulate(c := sprite_modulate):
sprite_modulate = c
if is_node_ready():
%Sprite.modulate = c

View File

@@ -40,8 +40,7 @@ static func generate_from_parent(plant_data : PlantData) -> Seed:
static func generate_random() -> Seed:
var archetype = PlantArchetype.get_random()
var random_mutations : Array[PlantMutation] = []
if randf() < MUTATION_PROBABILITY:
random_mutations = ([archetype.available_mutations.pick_random().duplicate_deep()] as Array[PlantMutation])
random_mutations.append(archetype.available_mutations.pick_random().duplicate_deep())
var new_seed = Seed.new(
Random.generate_random_word(),
PlantArchetype.get_random(),

View File

@@ -156,8 +156,11 @@ func pick_item(item : Item):
func drop_item():
var ind_to_drop := data.inventory.current_item_ind
if data.inventory.current_is_tool():
ind_to_drop = data.inventory.n_tools
while (
(data.inventory.get_item(ind_to_drop) == null or ind_to_drop < data.inventory.n_tools)
and ind_to_drop < len(data.inventory.items) - 1
):
ind_to_drop += 1
var item_to_drop = data.inventory.pop_item(ind_to_drop)
if item_to_drop:
terrain.drop_item(item_to_drop, global_position)

View File

@@ -47,10 +47,6 @@ func _physics_process(delta):
)
query_mouse = false
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var input_dir = Input.get_vector("move_left", "move_right", "move_up", "move_down")
@@ -64,7 +60,11 @@ func _physics_process(delta):
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
move_and_slide()
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta
move_and_slide()
func update_mouse_hovered_cockpit_actions() -> void: