138 lines
5.9 KiB
GDScript
138 lines
5.9 KiB
GDScript
extends Node
|
|
|
|
const IMAGE_WIDTH := 1024
|
|
const IMAGE_HEIGHT := 1048
|
|
|
|
const PLACEHOLDER_SEED_TEXTURE: Texture = preload("res://entities/plants/assets/sprites/default/seed.png")
|
|
const PLACEHOLDER_MATURE_TEXTURE: Texture = preload("res://entities/plants/assets/sprites/default/mature.png")
|
|
const PLACEHOLDER_GROWING_TEXTURE: Texture = preload("res://entities/plants/assets/sprites/default/growing.png")
|
|
|
|
# @export var parts_archetype_associations: Dictionary[PlantArchetype, PartArchetypeAssociation] TODO:: have the archetypes
|
|
@export var bases: Array[PlantPart]
|
|
@export var baby_bases: Array[PlantPart]
|
|
@export var branches: Array[PlantPart]
|
|
@export var n_branches: int = 2
|
|
@export var base_leaves: Array[PlantPart]
|
|
@export var parts_mutation_associations: Dictionary[String, PartMutationAssociation]
|
|
|
|
var rng := RandomNumberGenerator.new()
|
|
var image: Image = Image.create_empty(IMAGE_WIDTH, IMAGE_HEIGHT, false, Image.FORMAT_RGBA8)
|
|
var image_center: Vector2i = Vector2(0.5, 1) * Vector2(image.get_size())
|
|
|
|
func random_ind(array: Array) -> int:
|
|
return rng.randi_range(0, array.size() - 1)
|
|
|
|
func pick_random(array: Array) -> Variant:
|
|
return array[random_ind(array)]
|
|
|
|
func shuffle(array: Array):
|
|
var available_ind := 0
|
|
for i in range(array.size()):
|
|
var temp = array[available_ind]
|
|
var picked_ind := rng.randi_range(available_ind, array.size() - 1)
|
|
array[available_ind] = array[picked_ind]
|
|
array[picked_ind] = temp
|
|
|
|
func build_seed_texture(_random_seed: int) -> Texture:
|
|
return PLACEHOLDER_SEED_TEXTURE
|
|
|
|
func build_plant_texture(plant_data: PlantData) -> Texture:
|
|
rng.seed = plant_data.random_seed
|
|
|
|
|
|
var mature_texture: Texture = PLACEHOLDER_MATURE_TEXTURE
|
|
var base_part: PlantPart
|
|
var base_image_coord: Vector2i
|
|
var available_attaches: Array[PlantAttach]
|
|
var parent_image_coords: Array[Vector2]
|
|
var parts_to_place: Array[PlantPart]
|
|
|
|
match plant_data.get_state():
|
|
PlantData.State.MATURE:
|
|
# print("Build mature texture")
|
|
# var plant_archetype := plant_data.archetype
|
|
if bases.size() == 0:
|
|
printerr("No base in archetype")
|
|
return mature_texture
|
|
# var base_part: PlantPart = pick_random(parts_archetype_associations[plant_archetype].bases)
|
|
base_part = pick_random(bases)
|
|
|
|
var base_image := base_part.image
|
|
var base_image_center: Vector2i = 0.5 * base_image.get_size()
|
|
base_image_coord = image_center - Vector2i(base_part.root.position)
|
|
image.blend_rect(base_image, Rect2i(Vector2i.ZERO, base_image.get_size()), base_image_coord - base_image_center)
|
|
|
|
if branches.size() == 0:
|
|
printerr("No branches in archetype")
|
|
# var branch_parts: Array[PlantPart] = parts_archetype_associations[plant_archetype].branches
|
|
for i in n_branches:
|
|
parts_to_place.append(pick_random(branches))
|
|
|
|
for m in plant_data.mutations:
|
|
# print("mutations: ", m.id)
|
|
var association: PartMutationAssociation = parts_mutation_associations[m.id]
|
|
var mutation_possible_parts := association.parts
|
|
for p in association.part_amount:
|
|
parts_to_place.append(pick_random(mutation_possible_parts))
|
|
|
|
PlantData.State.GROWING:
|
|
# print("Build growing texture")
|
|
# var plant_archetype := plant_data.archetype
|
|
if baby_bases.size() == 0:
|
|
printerr("No baby base in archetype")
|
|
return mature_texture
|
|
# var base_part: PlantPart = pick_random(parts_archetype_associations[plant_archetype].baby_bases)
|
|
base_part = pick_random(baby_bases)
|
|
|
|
var base_image := base_part.image
|
|
var base_image_center: Vector2i = 0.5 * base_image.get_size()
|
|
base_image_coord = image_center - Vector2i(base_part.root.position)
|
|
image.blend_rect(base_image, Rect2i(Vector2i.ZERO, base_image.get_size()), base_image_coord - base_image_center)
|
|
|
|
for m in plant_data.mutations:
|
|
# print("mutations: ", m.id)
|
|
var association: PartMutationAssociation = parts_mutation_associations[m.id]
|
|
var mutation_possible_parts := association.parts
|
|
for p in ceil(0.5 * association.part_amount):
|
|
parts_to_place.append(pick_random(mutation_possible_parts))
|
|
_:
|
|
print("Not handled state")
|
|
return null
|
|
|
|
available_attaches = base_part.attaches.duplicate()
|
|
parent_image_coords.resize(available_attaches.size())
|
|
parent_image_coords.fill(base_image_coord)
|
|
|
|
for part: PlantPart in parts_to_place:
|
|
# print("Add part : ", part.resource_name)
|
|
var ind := find_random_matching_attach_ind(part.root, available_attaches)
|
|
if ind == -1:
|
|
printerr("No attach found")
|
|
continue
|
|
|
|
var attach: PlantAttach = available_attaches.pop_at(ind)
|
|
|
|
var parent_image_coord: Vector2i = parent_image_coords.pop_at(ind)
|
|
|
|
var part_image: Image = part.image
|
|
var part_image_center: Vector2i = 0.5 * part_image.get_size()
|
|
var part_image_coord: Vector2i = parent_image_coord + Vector2i(attach.position - part.root.position)
|
|
image.blend_rect(part_image, Rect2i(Vector2i.ZERO, part.image.get_size()), part_image_coord - part_image_center)
|
|
|
|
for sub_attach in part.attaches:
|
|
available_attaches.append(sub_attach)
|
|
parent_image_coords.append(part_image_coord)
|
|
|
|
mature_texture = ImageTexture.create_from_image(image)
|
|
image.fill(Color.TRANSPARENT)
|
|
return mature_texture
|
|
|
|
## returns -1 if not found
|
|
func find_random_matching_attach_ind(attach_to_match: PlantAttach, array: Array[PlantAttach]) -> int:
|
|
var indices: Array = range(array.size())
|
|
shuffle(indices)
|
|
for i in indices:
|
|
if array[i].attach_types.any(func(type): return attach_to_match.attach_types.has(type)):
|
|
return i
|
|
return -1
|