extends Item class_name Seed const SHOVEL_ICON = preload("res://common/icons/shovel.svg") const SCORE_ICON = preload("res://common/icons/growth.svg") @export var plant_name : String @export var plant_mutations: Array[PlantMutation] @export var random_seed : int var stored_icon : Texture func _init( _plant_name : String = "", _plant_mutations : Array[PlantMutation] = [], ): plant_name = _plant_name plant_mutations = _plant_mutations random_seed = randi() 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() ): return Seed.new( plant_data.plant_name, mutate_mutations(mutations) ) else : return Seed.new( plant_data.plant_name, plant_data.mutations.duplicate_deep() ) static func generate_random(rarity := 0) -> Seed: var new_seed = Seed.new( Random.generate_random_word(), generate_first_mutations(rarity), ) return new_seed func get_item_name() -> String: return tr("%s_SEED") % plant_name func get_item_type() -> ItemType: return Item.ItemType.CONSUMABLE_ITEM func get_description() -> String: return tr("PLANT_%s_MUST_BE_USED_IN_DECONTAMINATED_ZONE") % plant_name func get_icon() -> Texture2D: if stored_icon == null: stored_icon = PlantTextureBuilder.build_seed_texture(plant_name.hash()) return stored_icon func get_pointer() -> Texture2D: return preload("res://gui/pointer/assets/cursors/pointer-seed.svg") func get_energy_used() -> int: return 1 func get_usage_zone_radius() -> int: return 10 func get_usage_objects_affected(areas : Array[Area2D], _zone : Player.ActionZone) -> Array[Area2D]: return areas.filter( func(a): return a is PlantSprite ) func snap_usage_to_grid(): return true func use_text() -> String: return tr("PLANT_%s") % plant_name func is_one_time_use(): return true func can_use(player : Player, zone : Player.ActionZone) -> bool: if ( player.region == null ): return false var is_there_a_plant_here = false for area in zone.get_affected_areas(): if area is PlantSprite or area is TruckRecharge: is_there_a_plant_here = true var plant_tiles = [Math.get_tile_from_pos( zone.get_global_position(), )] as Array[Vector2i] return ( not is_there_a_plant_here and player.region.is_coords_decontaminated(plant_tiles) and not player.region.is_coords_rocky(plant_tiles) ) func use(player : Player, zone : Player.ActionZone) -> bool: if player.region == null: return false AudioManager.play_sfx("Harvest") return player.region.plant(self,zone.get_global_position()) func card_info() -> CardInfo: var info = CardInfo.new( get_item_name() ) info.texture = icon info.type_icon = TYPE_ICON info.stats.append( CardStatInfo.new( str(energy_usage), ENERGY_ICON ) ) var effect_section = CardSectionInfo.new( tr("EFFECT"), get_description() ) effect_section.title_icon = ACTION_ICON if energy_usage > 0: effect_section.title_icon = ENERGY_ICON info.sections.append(effect_section) if len(plant_mutations) != 0: for m in plant_mutations: info.sections.append(m.card_section()) return info func get_particles() -> Array[EffectParticles.Parameters]: var param : Array[EffectParticles.Parameters] = [] for m in plant_mutations: param.append( EffectParticles.Parameters.new( m.get_icon(), PlantMutation.get_rarity_color(m.get_rarity()) ) ) return param func get_rarity_color() -> Color: var higher_rarity : int = -1 var higher_color : Color = Color.WHITE for m in plant_mutations: if m.get_rarity() > higher_rarity: higher_rarity = m.get_rarity() higher_color = PlantMutation.get_rarity_color(higher_rarity) return higher_color static func generate_first_mutations(rarity := 0) -> Array[PlantMutation]: if rarity < 0: return [] var possible_mutation : PlantMutation = GameInfo.game_data.progression_data.available_mutations.filter( func (m : PlantMutation): return m.get_base_rarity() <= rarity ).pick_random().duplicate_deep() var level_to_add = rarity - possible_mutation.get_base_rarity() possible_mutation.level += level_to_add return [possible_mutation] 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(evolvable_mutations) > 0: mutation_possibility.append(UpgradeMutation.new()) var chosen_mutation_possibility = mutation_possibility.pick_random() return chosen_mutation_possibility.mutate(mutations) class MutationPossibility: func mutate(_mutations : Array[PlantMutation])-> Array[PlantMutation]: return [] class AddMutation extends MutationPossibility: func mutate(mutations : Array[PlantMutation])-> Array[PlantMutation]: var new_mutations = mutations.duplicate_deep() var possible_new_mutations = GameInfo.game_data.progression_data.available_mutations.duplicate_deep() possible_new_mutations = possible_new_mutations.filter( func (m : PlantMutation): return 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()) return new_mutations class UpgradeMutation extends MutationPossibility: func mutate( mutations : Array[PlantMutation] ) -> Array[PlantMutation]: var new_mutations = mutations.duplicate_deep() 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 class RemoveMutation extends MutationPossibility: func mutate(mutations : Array[PlantMutation])-> Array[PlantMutation]: var new_mutations = mutations.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)) return new_mutations