extends InspectableEntity class_name Plant signal harvested(p: Plant) signal state_changed(p: Plant) const PLANT_AREA_RADIUS = 20 const PLANT_INFLUENCE_RADIUS = 100 const HARVESTED_SEED_DISPLACEMENT_FACTOR = 100 const RANDOM_MAX_GROW_INTERVAL = Planet.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 SHOVEL_ICON = preload("res://common/icons/shovel.svg") const GROWING_ICON = preload("res://common/icons/chevrons-up.svg") const HARVEST_EFFECT_ICON = preload("res://common/icons/shovel.svg") const MATURE_EFFECT_ICON = preload("res://common/icons/chevrons-up.svg") const CYCLIC_EFFECT_ICON = preload("res://common/icons/rotate-rectangle.svg") const SPRITE_SCENE : PackedScene = preload("res://entities/plants/plant_sprite.tscn") enum State {PLANTED, GROWING, MATURE} @export var plant_type: PlantType var state: State = State.PLANTED @export var day: int @onready var plant_sprite: PlantSprite @onready var collision_shape: CollisionShape2D @onready var influence_zone : PlantInfluenceZone var harvest_effects = [] var mature_effects = [] var cyclic_effects = [] var plant_score = 0 var plant_mutations : Array[PlantMutation] = [] func _init( _plant_type : PlantType, _plant_mutations : Array[PlantMutation] = [], _day = 0, ): plant_type = _plant_type harvest_effects = plant_type.default_harvest_effects.duplicate_deep() mature_effects = plant_type.default_mature_effects.duplicate_deep() cyclic_effects = plant_type.default_cyclic_effects.duplicate_deep() day = _day plant_mutations = _plant_mutations func _ready(): plant_sprite = generate_sprite() collision_shape = generate_collision_shape() influence_zone = generate_influence_zone() update_plant(false) plant_sprite.update_plant_sprite(self, false) func pointer_text() -> String: return plant_type.name func inspect(is_inspected : bool = true): modulate = MODULATE_INSPECTED_COLOR if is_inspected else default_modulate influence_zone.show_influence = is_inspected func generate_sprite() -> PlantSprite: var sprite_object : PlantSprite = SPRITE_SCENE.instantiate() add_child(sprite_object) sprite_object.generate_mutation_effects(self) return sprite_object func generate_collision_shape() -> CollisionShape2D: var collision = CollisionShape2D.new() var shape = CircleShape2D.new() shape.radius = PLANT_AREA_RADIUS collision.shape = shape add_child(collision) return collision func generate_influence_zone() -> PlantInfluenceZone: var zone = PlantInfluenceZone.new(PLANT_INFLUENCE_RADIUS) add_child(zone) return zone # Méthode déclenchée par la classe planet func _pass_day(): await get_tree().create_timer(randf_range(0., RANDOM_MAX_GROW_INTERVAL)).timeout if state == State.MATURE and len(cyclic_effects): for effect in cyclic_effects: effect.effect(self) var old_state = state day += 1 update_plant() if old_state != state and state == State.MATURE: for effect in mature_effects: if effect : effect.effect(self) for effect in cyclic_effects: if effect : effect.effect(self) func update_plant(with_animation : bool = true): if day + 1 > calculate_grow_time(): if state != State.MATURE: change_state(State.MATURE, with_animation) elif day == 0: change_state(State.PLANTED, with_animation) else: if state != State.GROWING: change_state(State.GROWING, with_animation) func calculate_plant_score( overwite_state : State = state ) -> int: var mutated_plant_score = plant_type.default_plant_score if overwite_state == State.MATURE else 0 for m in plant_mutations: mutated_plant_score = m.mutate_score(overwite_state, self, mutated_plant_score) return mutated_plant_score func calculate_grow_time() -> int: var mutated_grow_time = plant_type.default_growing_time for m in plant_mutations: mutated_grow_time = m.mutate_grow_time(self, mutated_grow_time) return mutated_grow_time func change_state(_state: State, with_animation : bool = true): if state != _state: state = _state plant_sprite.update_plant_sprite(self, with_animation) state_changed.emit(self) func harvest(): if state == State.MATURE: for effect in harvest_effects: if effect : effect.effect(self) plant_sprite.start_harvest_animation() await plant_sprite.harvest_animation_finished harvested.emit(self) queue_free() func save() -> EntityData: return PlantData.new(self) func card_info() -> CardInfo: var info = CardInfo.new( pointer_text() ) info.important_stat_icon = PLANT_POINT_ICON info.important_stat_text = "%d" % calculate_plant_score() info.texture = plant_type.mature_texture info.type_icon = PLANT_TYPE_ICON var state_text = "Mature" if state != State.MATURE: state_text = "Growing" info.stats.append(CardStatInfo.new( "Day [b]%d[/b]" % day, LIFETIME_ICON )) info.stats.append(CardStatInfo.new( state_text, PLANT_TYPE_ICON )) if state != State.MATURE: info.stats.append(CardStatInfo.new( "Mature on day [b]%d[/b]" % calculate_grow_time(), GROWING_ICON )) info.stats.append(CardStatInfo.new( "[b]%d[/b] score when mature" % calculate_plant_score(State.MATURE), PLANT_POINT_ICON )) 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()) info.sections.append_array(card_effect_sections()) return info func card_effect_sections() -> Array[CardSectionInfo]: var sections : Array[CardSectionInfo] = [] var effects_category = [ mature_effects, harvest_effects, cyclic_effects ] var effects_category_labels : Array[String] = [ "On mature", "When harvested", "Each day when mature", ] var effects_category_icon : Array[Texture] = [ MATURE_EFFECT_ICON, HARVEST_EFFECT_ICON, CYCLIC_EFFECT_ICON, ] for i in range(len(effects_category)): var effects = effects_category[i] if len(effects): var section = CardSectionInfo.new( effects_category_labels[i] ) section.title_icon = effects_category_icon[i] var effects_text : Array = effects.map( func (e : PlantEffect): return "[b]%s[/b] %s" % [e.get_styled_effect_name() , e.get_effect_description()] ) section.text = "\n".join(effects_text) sections.append(section) return sections