From 657f40dd21145b5a6c6fb0709196eb8d5764fae1 Mon Sep 17 00:00:00 2001 From: Altaezio Date: Sat, 25 Jul 2026 12:31:19 +0200 Subject: [PATCH] Plant blinking when about to dye --- entities/plants/scripts/plant.gd | 43 +++++++++-------- entities/plants/scripts/plant_sprite.gd | 61 ++++++++++++++++++------- gui/pause/scripts/pause.gd | 10 ++-- 3 files changed, 73 insertions(+), 41 deletions(-) diff --git a/entities/plants/scripts/plant.gd b/entities/plants/scripts/plant.gd index 39caf2f..c0acacd 100644 --- a/entities/plants/scripts/plant.gd +++ b/entities/plants/scripts/plant.gd @@ -6,28 +6,28 @@ const PLANT_GROWING_AREA_HEIGHT = 70 const PLANT_MATURE_AREA_HEIGHT = 150 const HARVESTED_SEED_DISPLACEMENT_FACTOR = 100 -const RANDOM_MAX_GROW_INTERVAL = Region.MIN_PASS_DAY_ANIMATION_TIME/2. - 0.1 +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 SCORE_ICON = preload("res://common/icons/growth.svg") -const DURATION_ICON = preload("res://common/icons/clock.svg") +const DURATION_ICON = preload("res://common/icons/clock.svg") const SHOVEL_ICON = preload("res://common/icons/shovel.svg") -const GROWING_ICON = preload("res://common/icons/clock-up.svg") -const LIFETIME_ICON= preload("res://common/icons/clock-death.svg") +const GROWING_ICON = preload("res://common/icons/clock-up.svg") +const LIFETIME_ICON = preload("res://common/icons/clock-death.svg") const SEED_ICON = preload("res://common/icons/seeds.svg") -const SPRITE_SCENE : PackedScene = preload("res://entities/plants/plant_sprite.tscn") +const SPRITE_SCENE: PackedScene = preload("res://entities/plants/plant_sprite.tscn") -@export var data : PlantData +@export var data: PlantData @onready var plant_sprite: PlantSprite @onready var collision_shape: CollisionShape2D -@onready var influence_zone : PlantInfluenceZone +@onready var influence_zone: PlantInfluenceZone var harvested = false -var last_state : PlantData.State +var last_state: PlantData.State func _init( - _data : PlantData + _data: PlantData ): data = _data @@ -39,7 +39,7 @@ func _ready(): plant_sprite.setup_plant_sprite(data) if region: region.data.updated.connect( - func (_d : RegionData): + func(_d: RegionData): await get_tree().create_timer(0.05).timeout update_nearby_plant() update_decontamination_area_factor() @@ -47,17 +47,19 @@ func _ready(): await get_tree().create_timer(0.05).timeout update_nearby_plant() update_decontamination_area_factor() + if data.day == data.get_lifetime() - 1: + plant_sprite.apply_about_to_dye_effect() func pointer_text() -> String: return data.plant_name -func inspect(is_inspected : bool = true): - plant_sprite.sprite_modulate = MODULATE_INSPECTED_COLOR if is_inspected else default_modulate +func inspect(is_inspected: bool = true): + plant_sprite.set_modulate_color(MODULATE_INSPECTED_COLOR if is_inspected else default_modulate, false) plant_sprite.display_lifetime_sprite = is_inspected influence_zone.show_influence = is_inspected func generate_sprite() -> PlantSprite: - var sprite_object : PlantSprite = SPRITE_SCENE.instantiate() + var sprite_object: PlantSprite = SPRITE_SCENE.instantiate() add_child(sprite_object) # sprite_object.generate_mutation_effects(self) @@ -105,6 +107,9 @@ func _pass_day(): for m in data.mutations: m._start_day_effect(self) + if data.day == data.get_lifetime() - 1: + plant_sprite.apply_about_to_dye_effect() + func _end_pass_day(): match data.get_state(): PlantData.State.MATURE: @@ -117,9 +122,7 @@ func _end_pass_day(): plant_sprite.update_plant_sprite(data, last_state != data.get_state()) -func calculate_plant_score( - with_state : PlantData.State = data.get_state() -) -> int: +func calculate_plant_score(with_state: PlantData.State = data.get_state()) -> int: return data.get_score(with_state) func harvest(): @@ -187,11 +190,11 @@ func update_decontamination_area_factor(): var factor = 0. var full_decontaminated = true - var tiles = Math.get_tiles_in_circle(global_position, influence_zone.radius + Region.TILE_SIZE/2.) - for tile : Vector2i in tiles: + var tiles = Math.get_tiles_in_circle(global_position, influence_zone.radius + Region.TILE_SIZE / 2.) + for tile: Vector2i in tiles: if region.is_coords_decontaminated([tile]): - factor += 1./len(tiles) - else : + factor += 1. / len(tiles) + else: full_decontaminated = false if full_decontaminated: diff --git a/entities/plants/scripts/plant_sprite.gd b/entities/plants/scripts/plant_sprite.gd index 3bb63fe..b5a28b7 100644 --- a/entities/plants/scripts/plant_sprite.gd +++ b/entities/plants/scripts/plant_sprite.gd @@ -4,32 +4,38 @@ class_name PlantSprite const PLANTED_SEED_CROP_WIDTH = 50 const PLANTED_SEED_POS_Y = 0 -const PARTICLES_SCENE : PackedScene = preload("res://common/vfx/particles/effect_particles.tscn") +const PARTICLES_SCENE: PackedScene = preload("res://common/vfx/particles/effect_particles.tscn") + +const ABOUT_TO_DYE_COLOR := Color("#fca67e") +const ABOUT_TO_DYE_PERIOD := 1.0 signal harvest_animation_finished -var last_updated_on_state : PlantData.State = PlantData.State.MATURE -var stored_seed_image : Texture = null +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 +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): +var about_to_dye_tween: Tween +var target_modulate_color := Color.WHITE + +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) + update_plant_sprite(plant_data, true) -func update_plant_sprite(plant_data : PlantData, with_animation = false): +func update_plant_sprite(plant_data: PlantData, with_animation = false): if with_animation: %AnimationPlayer.play("bump") await %AnimationPlayer.animation_finished - %Sprite.flip_h = true if plant_data.random_seed%2 == 0 else false + %Sprite.flip_h = true if plant_data.random_seed % 2 == 0 else false %Sprite.texture = PlantTextureBuilder.build_plant_texture(plant_data) %PlantedSeed.visible = plant_data.get_state() == PlantData.State.PLANTED - %LifetimeProgressBar.value = 100 * (float(plant_data.day)/plant_data.get_lifetime()) + %LifetimeProgressBar.value = 100 * (float(plant_data.day) / plant_data.get_lifetime()) # %PlantedSeed.region_rect = Rect2( # 0, @@ -38,9 +44,9 @@ func update_plant_sprite(plant_data : PlantData, with_animation = false): # %PlantedSeed.texture.texture.get_height() - PLANTED_SEED_CROP_WIDTH + -1 * PLANTED_SEED_POS_Y, # ) -func generate_mutation_effects(plant : Plant): +func generate_mutation_effects(plant: Plant): for m in plant.data.mutations: - var particles_emitter : EffectParticles = PARTICLES_SCENE.instantiate() as EffectParticles + var particles_emitter: EffectParticles = PARTICLES_SCENE.instantiate() as EffectParticles particles_emitter.setup_particles( EffectParticles.Parameters.new( m.get_icon(), @@ -52,7 +58,7 @@ func generate_mutation_effects(plant : Plant): func start_harvest_animation(): $AnimationPlayer.play("harvest") await $AnimationPlayer.animation_finished - harvest_animation_finished.emit() + harvest_animation_finished.emit() func set_display_lifetime_sprite(d := display_lifetime_sprite): display_lifetime_sprite = d @@ -64,8 +70,8 @@ func set_sprite_modulate(c := sprite_modulate): if is_node_ready(): %Sprite.modulate = c -func affect_preview(is_affected : bool = true): - sprite_modulate = InspectableEntity.MODULATE_AFFECTED_COLOR if is_affected else Color.WHITE +func affect_preview(is_affected: bool = true): + set_modulate_color(InspectableEntity.MODULATE_AFFECTED_COLOR if is_affected else Color.WHITE, true) func _on_body_entered(body: Node2D) -> void: if body is Player && $AnimationPlayer.current_animation != "player_move": @@ -73,4 +79,27 @@ func _on_body_entered(body: Node2D) -> void: func play_bump_animation(): %AnimationPlayer.play("bump") - await %AnimationPlayer.animation_finished \ No newline at end of file + await %AnimationPlayer.animation_finished + +func set_modulate_color(color: Color, pause_about_to_dye: bool): + target_modulate_color = color + if about_to_dye_tween: + if pause_about_to_dye and about_to_dye_tween.is_running(): + about_to_dye_tween.pause() + modulate = target_modulate_color + elif not pause_about_to_dye and not about_to_dye_tween.is_running(): + about_to_dye_tween.play() + elif is_node_ready(): + %Sprite.modulate = target_modulate_color + +func apply_about_to_dye_effect(): + if not about_to_dye_tween: + about_to_dye_tween = create_tween() + about_to_dye_tween.tween_property(%Sprite, "modulate:r", ABOUT_TO_DYE_COLOR.r, ABOUT_TO_DYE_PERIOD).from(target_modulate_color.r) + about_to_dye_tween.parallel().tween_property(%Sprite, "modulate:g", ABOUT_TO_DYE_COLOR.g, ABOUT_TO_DYE_PERIOD).from(target_modulate_color.g) + about_to_dye_tween.parallel().tween_property(%Sprite, "modulate:b", ABOUT_TO_DYE_COLOR.b, ABOUT_TO_DYE_PERIOD).from(target_modulate_color.b) + + about_to_dye_tween.tween_property(%Sprite, "modulate:r", target_modulate_color.r, ABOUT_TO_DYE_PERIOD).from(ABOUT_TO_DYE_COLOR.r) + about_to_dye_tween.parallel().tween_property(%Sprite, "modulate:g", target_modulate_color.g, ABOUT_TO_DYE_PERIOD).from(ABOUT_TO_DYE_COLOR.g) + about_to_dye_tween.parallel().tween_property(%Sprite, "modulate:b", target_modulate_color.b, ABOUT_TO_DYE_PERIOD).from(ABOUT_TO_DYE_COLOR.b) + about_to_dye_tween.set_loops() diff --git a/gui/pause/scripts/pause.gd b/gui/pause/scripts/pause.gd index f8a7810..5029782 100644 --- a/gui/pause/scripts/pause.gd +++ b/gui/pause/scripts/pause.gd @@ -1,7 +1,7 @@ extends CanvasLayer -var pause = false : set = set_pause -var mouse_mode_before_pause : Input.MouseMode +var pause = false: set = set_pause +var mouse_mode_before_pause: Input.MouseMode func _ready(): hide() @@ -17,7 +17,7 @@ func set_pause(p): get_tree().paused = pause %Settings.close_settings() %Controls.close_controls() - if p : + if p: mouse_mode_before_pause = Input.mouse_mode Input.mouse_mode = Input.MOUSE_MODE_VISIBLE else: @@ -32,8 +32,8 @@ func set_pause(p): GameInfo.save_settings() func _input(_event): - if (SceneManager.actual_scene - and SceneManager.actual_scene.get_scene_id() != "TITLE" + if ((not SceneManager.actual_scene + or SceneManager.actual_scene.get_scene_id() != "TITLE") and Input.is_action_just_pressed("pause") and not %Settings.is_visible_in_tree() and not %Controls.is_visible_in_tree()