Dev de la démo

* Modification de l'apparence de l'UI des dialogues
* Changement de l'ordre de déblocage des mutations
* Ajout d'une confirmation pour l'abandon
* Ajout de la scène de fin avec la base Boréa, en tant que fin de démo
* Modification des icône de durée de vie, temps de pousse, et de mort
* Ajout d'un icône au dessus du joueur quand il n'a plus d'énergie
* Amélioration des dialogues du jeu
* Changement du modèle du téléphone
* Ajout de cellule d'énergie et de cellule de talion trouvable sur la carte
* Il est à nouveau possible de se recharger après la fin d'une région
* Buff des mutations ancien sociale et solide
* Modification de la mutation fertile (ne donne de gain de graine qu'à la maturation)
* Ajout d'une récupération automatique des graines
* Ajout de deux cartons de tutoriel ainsi qu'une option pour les revoir dans l'aide de jeu
* Amélioration générale du tutoriel
* Ajout d'un écran titre digne de ce nom
* Lors de l'arrivée à destination, ne téléporte plus le joueur sur une map vide, mais directement dans les lieux de cinématique
* Ajout graphique de plus de pattern de mousse et de roche
* Le talion apparait maintenant sur toute la carte
* La roche peut désormais apparaitre sur la zone de départ
* Ajout dud modificateur de région Canyon
* Equilibrage général
* Fix de bugs en tout genre
This commit is contained in:
2026-05-27 19:13:32 +02:00
parent 7764943714
commit 7b09f2ba7c
289 changed files with 8802 additions and 1520 deletions

View File

@@ -22,7 +22,7 @@ func get_usage_zone_radius() -> int:
return 10
func get_usage_object_affected(i : Area2D) -> bool:
return i is Plant
return i is Plant and Pointer.inspected == i
func use_text() -> String:
return tr("HARVEST")
@@ -30,14 +30,14 @@ func use_text() -> String:
func can_use(_player : Player, zone : Player.ActionZone) -> bool:
var areas = zone.get_affected_areas()
for area in areas :
if area is Plant:
if area is Plant and Pointer.inspected == area:
return true
return false
func use(player : Player, zone : Player.ActionZone) -> bool:
var has_plant = false
for area in zone.get_affected_areas():
if area and area is Plant:
if area and area is Plant and Pointer.inspected == area:
harvest(area, player)
await player.get_tree().create_timer(USE_INTERVAL).timeout
has_plant = true

View File

@@ -2,7 +2,6 @@ extends Item
class_name Seed
const SHOVEL_ICON = preload("res://common/icons/shovel.svg")
const GROWING_ICON = preload("res://common/icons/chevrons-up.svg")
const SCORE_ICON = preload("res://common/icons/growth.svg")
@export var plant_name : String
@@ -21,12 +20,16 @@ func _init(
static func generate_from_parent(plant_data : PlantData) -> Seed:
var mutations : Array[PlantMutation] = plant_data.mutations
var mutation_probability = GameInfo.game_data.current_run.plant_info.get_mutation_probability()
# Mutate for every time mutation probability exceed 1
while mutation_probability > 1:
mutations = mutate_mutations(plant_data.mutations)
mutation_probability -= 1
mutations.sort_custom(
func (a : PlantMutation, b : PlantMutation): return a.get_mutation_name() < b.get_mutation_name()
)
if (
plant_data.get_state() == PlantData.State.MATURE
and randf() < GameInfo.game_data.current_run.plant_info.get_mutation_probability()
@@ -168,13 +171,17 @@ static func generate_first_mutations(rarity := 0) -> Array[PlantMutation]:
static func mutate_mutations(mutations : Array[PlantMutation]) -> Array[PlantMutation]:
var mutation_possibility : Array[MutationPossibility] = []
var evolvable_mutations : Array[PlantMutation] = mutations.filter(
func (m : PlantMutation): return m.get_rarity() < PlantMutation.MAX_RARITY
)
if (
len(mutations) < GameInfo.game_data.current_run.plant_info.get_mutation_max_number()
):
mutation_possibility.append(AddMutation.new())
if len(mutations) > 0:
if len(evolvable_mutations) > 0:
mutation_possibility.append(UpgradeMutation.new())
var chosen_mutation_possibility = mutation_possibility.pick_random()
@@ -206,7 +213,15 @@ class UpgradeMutation extends MutationPossibility:
) -> Array[PlantMutation]:
var new_mutations = mutations.duplicate_deep()
new_mutations.pick_random().level += 1
var evolvable_mutations_id : Array[int] = []
for i in range(len(mutations)):
var m = mutations[i]
if m.get_rarity() < PlantMutation.MAX_RARITY:
evolvable_mutations_id.append(i)
if len(evolvable_mutations_id):
new_mutations[evolvable_mutations_id.pick_random()].level += 1
return new_mutations

View File

@@ -6,6 +6,7 @@
[ext_resource type="Texture2D" uid="uid://c7ff87jniga5m" path="res://entities/player/assets/sprites/robot.png" id="4_bls4j"]
[ext_resource type="Texture2D" uid="uid://drgl0d51d4cf7" path="res://entities/player/assets/sprites/radial-gradient.png" id="5_8fjmc"]
[ext_resource type="Script" uid="uid://b1mmtgmi5oq86" path="res://entities/player/scripts/player_sprite.gd" id="5_fkugw"]
[ext_resource type="Texture2D" uid="uid://51255tpyl6vj" path="res://common/icons/no-bolt.svg" id="7_26q78"]
[ext_resource type="AudioStream" uid="uid://cv5avkd3qekt7" path="res://common/audio_manager/assets/sfx/movement/movement.wav" id="7_qiwj3"]
[sub_resource type="CircleShape2D" id="CircleShape2D_sglur"]
@@ -15,13 +16,13 @@ radius = 13.0
radius = 40.0
[sub_resource type="Gradient" id="Gradient_qiwj3"]
offsets = PackedFloat32Array(0.37339056, 0.49785408)
offsets = PackedFloat32Array(0.25, 0.4)
colors = PackedColorArray(0.043137256, 0.050980393, 0.15686275, 0, 0.043137256, 0.050980393, 0.15686275, 1)
[sub_resource type="GradientTexture2D" id="GradientTexture2D_26q78"]
gradient = SubResource("Gradient_qiwj3")
width = 600
height = 600
width = 1000
height = 1000
fill = 1
fill_from = Vector2(0.5, 0.5)
fill_to = Vector2(0.5, 0)
@@ -136,6 +137,41 @@ point_count = 2
offsets = PackedFloat32Array(0, 0.77729255, 1)
colors = PackedColorArray(0.5803922, 0.7058824, 0.8862745, 1, 0.5785, 0.70829165, 0.89, 1, 0.5785, 0.70829165, 0.89, 0)
[sub_resource type="Animation" id="Animation_bectd"]
length = 0.001
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position:y")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(0),
"points": PackedFloat32Array(0, -0.25, 0, 0.25, 0),
"times": PackedFloat32Array(0)
}
[sub_resource type="Animation" id="Animation_wvtmh"]
resource_name = "bounce"
loop_mode = 1
tracks/0/type = "bezier"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath(".:position:y")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"handle_modes": PackedInt32Array(2, 2),
"points": PackedFloat32Array(-1097.2793, 0, 0, 0, -139.75659, -1097.2793, 0, -112.66321, 0, 0),
"times": PackedFloat32Array(0, 1)
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_7thud"]
_data = {
&"RESET": SubResource("Animation_bectd"),
&"bounce": SubResource("Animation_wvtmh")
}
[sub_resource type="Animation" id="Animation_fkugw"]
length = 0.001
tracks/0/type = "value"
@@ -256,6 +292,7 @@ position = Vector2(0, -17)
shape = SubResource("CircleShape2D_sglur")
[node name="InteractArea2D" type="Area2D" parent="." unique_id=1048722411]
unique_name_in_owner = true
position = Vector2(0, -12)
[node name="CollisionShape2D" type="CollisionShape2D" parent="InteractArea2D" unique_id=1242017003]
@@ -271,7 +308,7 @@ texture = ExtResource("2_fkugw")
[node name="Fog" type="Sprite2D" parent="." unique_id=1590893330]
z_index = 10
position = Vector2(0.99999994, -17)
scale = Vector2(8, 8)
scale = Vector2(5.8320003, 5.8320003)
texture = SubResource("GradientTexture2D_26q78")
[node name="PlayerSprite" type="AnimatedSprite2D" parent="." unique_id=638545037]
@@ -303,6 +340,17 @@ gravity = Vector2(0, 100)
scale_amount_curve = SubResource("Curve_fkugw")
color_ramp = SubResource("Gradient_bls4j")
[node name="NoEnergyLeftIcon" type="Sprite2D" parent="PlayerSprite" unique_id=1059424679]
unique_name_in_owner = true
modulate = Color(1, 0, 0.43137255, 1)
position = Vector2(-15.239998, 0)
scale = Vector2(10.16, 10.16)
texture = ExtResource("7_26q78")
[node name="AnimationPlayer" type="AnimationPlayer" parent="PlayerSprite/NoEnergyLeftIcon" unique_id=390014722]
libraries/ = SubResource("AnimationLibrary_7thud")
autoplay = &"bounce"
[node name="MovementAudioStreamPlayer" type="AudioStreamPlayer" parent="." unique_id=20243230]
unique_name_in_owner = true
stream = ExtResource("7_qiwj3")

View File

@@ -6,6 +6,7 @@ const MAX_REACH = 100
const HOLDING_ITEM_SPRITE_SIZE = 20.
const TURN_ANIMATION_MINIMUM_THRESHOLD = 0.2
const SPEED = 350
const JUST_DROPPED_ITEM_UPDATE_INTERVAL = 1.
signal player_updated(player: Player)
signal upgraded
@@ -30,15 +31,22 @@ var instruction : Instruction = null :
if instruction and is_node_ready():
instruction.spawn_indicator(self)
var just_dropped_item_objects : Array = []
var last_just_dropped_item_objects_updated := 0.
var elapsed_time := 0.
@onready var preview_zone : ActionZone = await setup_action_zone(Vector2.ZERO, null)
@onready var action_zone : ActionZone = await setup_action_zone(Vector2.ZERO, null)
func _ready():
data = GameInfo.game_data.player_data
data.updated.connect(_on_data_changed)
data.inventory.updated.connect(_on_inventory_updated)
player_updated.emit(self)
Pointer.player = self
setup_preview_zone(data.inventory.get_item())
%NoEnergyLeftIcon.visible = data.energy == 0
func appear(with_falling_animation = true):
if with_falling_animation:
@@ -70,6 +78,7 @@ func _end_pass_day():
controlling_player = true
func _process(delta):
elapsed_time += delta
last_action_area_movement_timer += delta
if controlling_player:
@@ -99,12 +108,39 @@ func _process(delta):
elif velocity != Vector2.ZERO and %MovementAudioStreamPlayer.playing == false:
%MovementAudioStreamPlayer.play()
# print("-----")
# print(elapsed_time)
# print(last_just_dropped_item_objects_updated)
if elapsed_time > last_just_dropped_item_objects_updated + JUST_DROPPED_ITEM_UPDATE_INTERVAL:
update_just_dropped_item_objects()
take_surrounding_seeds()
move_and_slide()
func _on_data_changed(pd : PlayerData):
%NoEnergyLeftIcon.visible = pd.energy == 0
func _on_inventory_updated(_inventory: Inventory):
setup_preview_zone(data.inventory.get_item())
emit_signal("player_updated", self)
func update_just_dropped_item_objects():
last_just_dropped_item_objects_updated = elapsed_time
var overlapping_areas = (%InteractArea2D as Area2D).get_overlapping_areas()
just_dropped_item_objects = just_dropped_item_objects.filter(
func (i : ItemObject): return i in overlapping_areas
)
func take_surrounding_seeds():
var overlapping_areas = (%InteractArea2D as Area2D).get_overlapping_areas()
if not data.inventory.is_full():
for area in overlapping_areas:
if area is ItemObject and not area in just_dropped_item_objects:
area.interact(self)
return
func calculate_direction_instruction_direction() -> Vector2:
if (
instruction
@@ -189,7 +225,8 @@ func drop_item():
var item_to_drop : Item = data.inventory.pop_item(ind_to_drop)
if item_to_drop and item_to_drop.type != Item.ItemType.TOOL_ITEM:
terrain.drop_item(item_to_drop, global_position)
var dropped_item_object = terrain.drop_item(item_to_drop, global_position)
just_dropped_item_objects.append(dropped_item_object)
AudioManager.play_sfx("Drop")
region.save()

View File

@@ -10,7 +10,7 @@ const DEFAULT_INVENTORY_SIZE = 3
@export var energy : int = DEFAULT_MAX_ENERGY :
set(v):
energy = v
energy = min(v,max_energy)
updated.emit(self)
@export var inventory := Inventory.new(DEFAULT_INVENTORY_SIZE)