système de sauvegarde, scène 3D de test sur la base astra et passage en forward+

This commit is contained in:
2026-02-06 10:28:36 +01:00
parent 83d462f2f4
commit cc421a951f
97 changed files with 2138 additions and 1007 deletions

View File

@@ -3,7 +3,7 @@ class_name ItemObjectData
@export var item : Item
func _init(e : ItemObject):
func _init(e : ItemObject = ItemObject.new()):
position = e.global_position
item = e.item

View File

@@ -121,6 +121,8 @@ func mature():
func die():
for m in data.mutations:
m._start_dead_effect(self)
for i in range(data.get_random_seed_income()):
produce_seed()
disappear()
func disappear():
@@ -132,52 +134,36 @@ func save() -> EntityData:
func card_info() -> CardInfo:
var info = CardInfo.new(
pointer_text()
data.plant_name,
data.archetype.archetype_name
)
var state = data.get_state()
info.important_stat_icon = PLANT_POINT_ICON
info.important_stat_text = "%d" % calculate_plant_score()
info.texture = null #TODO
info.type_icon = PLANT_TYPE_ICON
var state_text = tr("MATURE")
if state != PlantData.State.MATURE:
state_text = tr("GROWING")
info.stats.append(CardStatInfo.new(
tr("DAY_%d") % data.day,
LIFETIME_ICON
))
info.stats.append(CardStatInfo.new(
state_text,
PLANT_TYPE_ICON
))
if state != PlantData.State.MATURE:
info.stats.append(CardStatInfo.new(
tr("MATURE_ON_DAY_%d") % data.get_growing_time(),
GROWING_ICON
))
info.stats.append(CardStatInfo.new(
tr("%d_SCORE_WHEN_MATURE") % data.get_score(PlantData.State.MATURE),
PLANT_POINT_ICON
))
info.stats.append(CardStatInfo.new(
tr("DIE_ON_DAY_%d") % (data.get_lifetime()),
DEATH_ICON
))
info.stats.append_array([
CardStatInfo.new(
str(data.day),
LIFETIME_ICON
),
CardStatInfo.new(
str(data.get_growing_time()),
GROWING_ICON
),
CardStatInfo.new(
str(data.get_lifetime()),
DEATH_ICON
),
])
if len(data.mutations) != 0:
var rarest : int = data.mutations.map(
func(m : PlantMutation) : return m.get_rarity()
).max()
info.bg_color = PlantMutation.get_rarity_color(rarest)
for m in data.mutations:
info.sections.append(m.card_section())

View File

@@ -2,12 +2,12 @@
extends Resource
class_name PlantArchetype
@export var archetype_name = Random.generate_random_name()
@export var archetype_name = Random.generate_random_word()
@export var texture_builder = TextureBuilder.new()
@export var plant_area_radius = 20
@export var plant_influence_radius = 100
@export var growing_time= 2
@export var lifetime = 5
@export var lifetime = 8
@export var base_score = 1
@export var seed_number = 2
@export var seed_random_loose = 1
@@ -16,4 +16,12 @@ class_name PlantArchetype
PrecociousMutation.new(),
QualityMutation.new(),
QuickMutation.new()
]
]
static func get_all() -> Array[PlantArchetype]:
return [
PlantArchetype.new()
]
static func get_random() -> PlantArchetype:
return get_all().pick_random()

View File

@@ -19,9 +19,9 @@ enum State {PLANTED, GROWING, MATURE, DEAD}
@export var roots = 0 # +1 lifetime
func _init(
_position : Vector2,
_archetype : PlantArchetype,
_plant_name : String = Random.generate_random_name(),
_position : Vector2 = Vector2.ZERO,
_archetype : PlantArchetype = PlantArchetype.get_random(),
_plant_name : String = Random.generate_random_word(),
_mutations : Array[PlantMutation] = [],
_day : int = 0,
_random_seed = randi()
@@ -90,7 +90,7 @@ func get_seed_texture():
return archetype.texture_builder.build_seed_texture(random_seed)
func get_seed_number(state = get_state()):
var seed_number = archetype.seed_number if state == State.MATURE else 0
var seed_number = archetype.seed_number if (state == State.MATURE or state == State.DEAD) else 0
for m in mutations:
seed_number = m.mutate_seed_number(self, seed_number)

View File

@@ -3,6 +3,8 @@ class_name PlantMutation
@export var level : int = 1
var name : String : get = get_mutation_name
func _init(_level : int = 1):
level = _level
@@ -65,8 +67,7 @@ func card_section() -> CardSectionInfo:
"[b]%s[/b] %s" % [tr(PlantMutation.get_rarity_text(get_rarity())), get_mutation_description()]
)
section.title_color = PlantMutation.get_rarity_color(get_rarity())
section.title_colored = true
section.color = PlantMutation.get_rarity_color(get_rarity())
section.title_icon = get_icon()
return section

View File

@@ -1,7 +1,7 @@
extends PlantMutation
class_name AncientMutation
const DEFAULT_DAY_FACTOR = 5
const DEFAULT_DAY_FACTOR = 3
func get_icon() -> Texture:
return preload("res://common/icons/wood.svg")

View File

@@ -13,5 +13,5 @@ func get_mutation_name() -> String:
func get_mutation_description() -> String:
return tr("QUICK_EFFECT_TEXT_LEVEL_%d") % level
func mutate_grow_time(_data : PlantData, grow_time : int) -> int:
func mutate_growing_time(_data : PlantData, grow_time : int) -> int:
return max(grow_time - level, 0)

View File

@@ -97,6 +97,7 @@ func is_full():
return true
func clear():
print("clearing inventory")
for i in range(len(items)):
items[i] = null
updated.emit(self)

View File

@@ -6,11 +6,11 @@ const ACTION_ICON = preload("res://common/icons/swipe-down.svg")
const ENERGY_ICON = preload("res://common/icons/bolt.svg")
const ONE_TIME_ICON = preload("res://common/icons/circle-number-1.svg")
var name: String : get = get_item_name
var description: String : get = get_description
var icon: Texture2D : get = get_icon
var usage_zone_radius: int = 5 : get = get_usage_zone_radius
var energy_usage : int = 1 : get = get_energy_used
@export var name: String : get = get_item_name
@export var description: String : get = get_description
@export var icon: Texture2D : get = get_icon
@export var usage_zone_radius: int = 5 : get = get_usage_zone_radius
@export var energy_usage : int = 1 : get = get_energy_used
func get_item_name() -> String:
return name
@@ -51,19 +51,11 @@ func card_info() -> CardInfo:
info.stats.append(
CardStatInfo.new(
tr("COST_%d_ENERGY") % energy_usage,
str(energy_usage),
ENERGY_ICON
)
)
if is_one_time_use():
info.stats.append(
CardStatInfo.new(
tr("ONE_TIME_USE"),
ONE_TIME_ICON
)
)
var effect_section = CardSectionInfo.new(
tr("EFFECT"),
get_description()

View File

@@ -13,8 +13,8 @@ const SCORE_ICON = preload("res://common/icons/growth.svg")
@export var random_seed : int
func _init(
_plant_name : String,
_plant_archetype : PlantArchetype,
_plant_name : String = "",
_plant_archetype : PlantArchetype = PlantArchetype.get_random(),
_plant_mutations : Array[PlantMutation] = [],
):
plant_name = _plant_name
@@ -27,23 +27,27 @@ static func generate_from_parent(plant_data : PlantData) -> Seed:
return Seed.new(
plant_data.plant_name,
plant_data.archetype,
mutate(plant_data.mutations)
mutate_mutations(plant_data)
)
else :
# TODO
return Seed.new(
plant_data.plant_name,
plant_data.archetype,
mutate(plant_data.mutations)
plant_data.mutations.duplicate_deep()
)
static func generate_random() -> Seed:
return Seed.new(
Random.generate_random_name(),
PlantArchetype.new(),
var new_seed = Seed.new(
Random.generate_random_word(),
PlantArchetype.get_random(),
[]
)
if randf() > MUTATION_PROBABILITY:
new_seed.plant_mutations.append(
new_seed.plant_archetype.available_mutations.pick_random().duplicate_deep()
)
return new_seed
func get_item_name() -> String:
return tr("%s_SEED") % plant_name
@@ -102,19 +106,11 @@ func card_info() -> CardInfo:
info.stats.append(
CardStatInfo.new(
tr("COST_%d_ENERGY") % energy_usage,
str(energy_usage),
ENERGY_ICON
)
)
if is_one_time_use():
info.stats.append(
CardStatInfo.new(
tr("ONE_TIME_USE"),
ONE_TIME_ICON
)
)
var effect_section = CardSectionInfo.new(
tr("EFFECT"),
get_description()
@@ -127,10 +123,6 @@ func card_info() -> CardInfo:
info.sections.append(effect_section)
if len(plant_mutations) != 0:
var rarest : int = plant_mutations.map(
func(m : PlantMutation) : return m.get_rarity()
).max()
info.bg_color = PlantMutation.get_rarity_color(rarest)
for m in plant_mutations:
info.sections.append(m.card_section())
@@ -149,69 +141,67 @@ func get_particles() -> Array[Particles.Parameters]:
return param
static func mutate(parent_mutation : Array[PlantMutation] = []) -> Array[PlantMutation]:
static func mutate_mutations(parent : PlantData) -> Array[PlantMutation]:
# TODO
# var possible_mutations_change : Array[MutationPossibility] = [
# AddMutation.new()
# ]
var mutation_possibility : Array[MutationPossibility] = [
AddMutation.new()
]
# if (
# len(parent_mutation) >= 2
# ):
# possible_mutations_change = [
# UpgradeMutation.new(),
# RemoveMutation.new(),
# ]
# elif len(parent_mutation) > 0:
# possible_mutations_change = [
# AddMutation.new(),
# UpgradeMutation.new(),
# RemoveMutation.new(),
# ]
if (
len(parent.mutations) >= GameInfo.game_data.max_mutations_by_plant
):
mutation_possibility = [
UpgradeMutation.new(),
RemoveMutation.new(),
]
elif len(parent.mutations) > 0:
mutation_possibility = [
AddMutation.new(),
UpgradeMutation.new(),
RemoveMutation.new(),
]
# var chosen_mutation = possible_mutations_change.pick_random()
var chosen_mutation_possibility = mutation_possibility.pick_random()
return parent_mutation
return chosen_mutation_possibility.mutate(parent)
class MutationPossibility:
func mutate(_parent : PlantData)-> Array[PlantMutation]:
return []
# class MutationPossibility:
# func mutate(_parent_mutation : Array[PlantMutation] = [])-> Array[PlantMutation]:
# return []
class AddMutation extends MutationPossibility:
func mutate(parent : PlantData)-> Array[PlantMutation]:
var new_mutations = parent.mutations.duplicate_deep()
var possible_new_mutations = parent.archetype.available_mutations.duplicate_deep()
# class AddMutation extends MutationPossibility:
# func mutate(parent_mutation : Array[PlantMutation] = [])-> Array[PlantMutation]:
# var new_mutations = parent_mutation.duplicate_deep()
# var mut = PlantMutation.random_mutation(parent_mutation)
possible_new_mutations = possible_new_mutations.filter(
func (m : PlantMutation):
return parent.mutations.find_custom(func(m2: PlantMutation): return m2.name == m.name) == -1
)
if len(possible_new_mutations):
new_mutations.append(possible_new_mutations.pick_random())
# if mut:
# var existing_mut_id = new_mutations.find_custom(func(m:PlantMutation): return m.get_mutation_name() == mut.get_mutation_name())
# if existing_mut_id >= 0:
# new_mutations[existing_mut_id].level += 1
# else :
# new_mutations.append(mut)
return new_mutations
# return new_mutations
class UpgradeMutation extends MutationPossibility:
func mutate(
parent : PlantData
) -> Array[PlantMutation]:
var new_mutations = parent.mutations.duplicate_deep()
# class UpgradeMutation extends MutationPossibility:
# func mutate(
# parent_mutation : Array[PlantMutation] = []
# ) -> Array[PlantMutation]:
# var new_mutations = parent_mutation.duplicate_deep()
new_mutations.pick_random().level += 1
# new_mutations.pick_random().level += 1
return new_mutations
# return new_mutations
class RemoveMutation extends MutationPossibility:
func mutate(parent : PlantData)-> Array[PlantMutation]:
var new_mutations = parent.mutations.duplicate_deep()
# class RemoveMutation extends MutationPossibility:
# func mutate(parent_mutation : Array[PlantMutation] = [])-> Array[PlantMutation]:
# var new_mutations :Array[PlantMutation] = parent_mutation.duplicate_deep()
var mut_to_remove = new_mutations.pick_random()
if mut_to_remove.level > 1:
mut_to_remove.level -= 1
else:
new_mutations.remove_at(new_mutations.find(mut_to_remove))
# var mut_to_remove = new_mutations.pick_random()
# if mut_to_remove.level > 1:
# mut_to_remove.level -= 1
# else:
# new_mutations.remove_at(new_mutations.find(mut_to_remove))
# return new_mutations
return new_mutations

View File

@@ -182,6 +182,7 @@ func use_item(item : Item):
data.energy -= item.energy_usage
if item.is_one_time_use():
data.inventory.remove_item(item)
region.save()
func upgrade_max_energy(amount = 1):
data.max_energy += amount

View File

@@ -0,0 +1,67 @@
[gd_scene format=3 uid="uid://da7a74dg30q1l"]
[ext_resource type="Script" uid="uid://3rrym6yv7xyp" path="res://entities/player_3d/scripts/player_3d.gd" id="1_pvvbh"]
[ext_resource type="Material" uid="uid://cr7bp4fhh1ipr" path="res://entities/player_3d/resources/materials/post_process_quad.tres" id="2_fcmrk"]
[ext_resource type="Theme" uid="uid://bgcmd213j6gk1" path="res://gui/ressources/hud.tres" id="2_qi48i"]
[ext_resource type="PackedScene" uid="uid://clicjf8ts51h8" path="res://gui/game/inventory_gui/inventory_gui.tscn" id="3_ea0v7"]
[ext_resource type="Texture2D" uid="uid://ba8vh5h3r6pr2" path="res://common/icons/focus.svg" id="4_sbfo8"]
[sub_resource type="QuadMesh" id="QuadMesh_o44vi"]
size = Vector2(2, 2)
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_eodxe"]
radius = 0.46868896
height = 1.7342377
[node name="Player3D" type="CharacterBody3D" unique_id=549819967 node_paths=PackedStringArray("pointer_texture_rect")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 0, 0, 0)
script = ExtResource("1_pvvbh")
pointer_texture_rect = NodePath("CanvasLayer/PointerTexture")
[node name="Camera3D" type="Camera3D" parent="." unique_id=2091917091]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.19785136, 0)
near = 0.003
[node name="MeshInstance3D" type="MeshInstance3D" parent="Camera3D" unique_id=818458454]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.2)
mesh = SubResource("QuadMesh_o44vi")
surface_material_override/0 = ExtResource("2_fcmrk")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=456230433]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.253273, 0)
shape = SubResource("CapsuleShape3D_eodxe")
[node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=1210282091]
[node name="MarginContainer" type="MarginContainer" parent="CanvasLayer" unique_id=355504485]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme = ExtResource("2_qi48i")
[node name="Inventory" parent="CanvasLayer/MarginContainer" unique_id=820746652 instance=ExtResource("3_ea0v7")]
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
[node name="PointerTexture" type="TextureRect" parent="CanvasLayer" unique_id=99628184]
unique_name_in_owner = true
custom_minimum_size = Vector2(30, 30)
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -2.5
offset_top = -2.5
offset_right = 2.5
offset_bottom = 2.5
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("4_sbfo8")
expand_mode = 1

View File

@@ -0,0 +1,12 @@
[gd_resource type="ShaderMaterial" format=3 uid="uid://cr7bp4fhh1ipr"]
[ext_resource type="Shader" uid="uid://n6r7u234l2iy" path="res://common/vfx/materials/shaders/3d_outline_2.gdshader" id="1_tvsbc"]
[resource]
render_priority = 0
shader = ExtResource("1_tvsbc")
shader_parameter/step_count = 3
shader_parameter/thickness = 2.0000000149012003
shader_parameter/edge_color = Color(0.0627451, 0.05882353, 0.16862746, 1)
shader_parameter/fade_start = 100.0
shader_parameter/fade_length = 200.0

View File

@@ -0,0 +1,70 @@
extends CharacterBody3D
const POINTER_TEXTURE = preload("res://common/icons/focus.svg")
const POINTER_ACTION_TEXTURE = preload("res://common/icons/hand-stop.svg")
@export var pointer_texture_rect : TextureRect
const SPEED = 4.0
const MOUSE_SENSIVITY = 0.002
const RAY_LENGTH = 10.
var cockpit_action_hovered : CockpitAction = null
var query_mouse := false
func _input(event):
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
rotate_y(-event.relative.x * MOUSE_SENSIVITY)
%Camera3D.rotate_x(-event.relative.y * MOUSE_SENSIVITY)
%Camera3D.rotation.x = clampf($Camera3D.rotation.x, -deg_to_rad(70), deg_to_rad(70))
query_mouse = true
if event.is_action_pressed("action") and cockpit_action_hovered and cockpit_action_hovered:
cockpit_action_hovered.click()
func _physics_process(delta):
if query_mouse:
update_mouse_hovered_cockpit_actions()
%PointerTexture.texture = (
POINTER_ACTION_TEXTURE if cockpit_action_hovered != null
else POINTER_TEXTURE
)
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")
var direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
move_and_slide()
func update_mouse_hovered_cockpit_actions() -> void:
var space_state = get_world_3d().direct_space_state
var middle_screen = get_viewport().get_visible_rect().size / 2
var from = %Camera3D.project_ray_origin(middle_screen)
var to = from + %Camera3D.project_ray_normal(middle_screen) * RAY_LENGTH
var query = PhysicsRayQueryParameters3D.create(from, to)
query.collide_with_areas = true
var result = space_state.intersect_ray(query)
if result and result.collider and result.collider is CockpitAction and result.collider.pickable:
if cockpit_action_hovered and cockpit_action_hovered != result.collider:
cockpit_action_hovered._on_mouse_exited()
cockpit_action_hovered = result.collider
cockpit_action_hovered._on_mouse_entered()
else :
if cockpit_action_hovered:
cockpit_action_hovered._on_mouse_exited()
cockpit_action_hovered = null

View File

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