working with new sprites
This commit is contained in:
@@ -13,6 +13,8 @@ func generate_plants():
|
||||
var plant_data: PlantData = PlantData.new(plant_position)
|
||||
plant_data.day = plant_data.get_growing_time()
|
||||
plant_data.mutations.append(plant_data.archetype.available_mutations.pick_random())
|
||||
plant_data.mutations.append(plant_data.archetype.available_mutations.pick_random())
|
||||
plant_data.mutations.append(plant_data.archetype.available_mutations.pick_random())
|
||||
var plant: Plant = Plant.new(plant_data)
|
||||
add_child(plant)
|
||||
plant.global_position = plant_position
|
||||
|
||||
7
entities/plants/scripts/texture_builder/plant_attach.gd
Normal file
7
entities/plants/scripts/texture_builder/plant_attach.gd
Normal file
@@ -0,0 +1,7 @@
|
||||
extends Resource
|
||||
class_name PlantAttach
|
||||
|
||||
enum AttachType {ORANGE_ATTACH, BLUE_ATTACH, PINK_ATTACH}
|
||||
|
||||
@export var position: Vector2
|
||||
@export var attach_types: Array[AttachType]
|
||||
@@ -0,0 +1 @@
|
||||
uid://co46ywm8bgnfh
|
||||
@@ -0,0 +1,10 @@
|
||||
extends Node2D
|
||||
class_name PlantAttachBuilder
|
||||
|
||||
@export var attach_types: Array[PlantAttach.AttachType]
|
||||
|
||||
static func to_plant_attach(builder: PlantAttachBuilder) -> PlantAttach:
|
||||
var plant_attach := PlantAttach.new()
|
||||
plant_attach.position = builder.position
|
||||
plant_attach.attach_types = builder.attach_types
|
||||
return plant_attach
|
||||
@@ -0,0 +1 @@
|
||||
uid://d01kj3twwcrmu
|
||||
@@ -4,23 +4,12 @@ class_name PlantPart
|
||||
enum PartType {BASE_PART, BRANCH_PART, LEAF_PART, FLOWER_PART}
|
||||
|
||||
@export var texture: Texture
|
||||
@export var root: Vector2
|
||||
@export var attaches: Array[Vector2]
|
||||
@export var bottom_attaches: Array[Vector2]
|
||||
@export var type: PartType
|
||||
@export var root: PlantAttach
|
||||
@export var attaches: Array[PlantAttach] # array of vec2
|
||||
|
||||
@export var is_back: bool
|
||||
@export var base_attachable: bool
|
||||
@export var bottom_attachable: bool
|
||||
@export var branch_attachable: bool
|
||||
|
||||
func init(textute_arg: Texture, root_arg: Vector2, attaches_arg: Array[Vector2], bottom_attaches_arg: Array[Vector2], type_arg: PartType, is_back_arg: bool, base_attachable_arg: bool, bottom_attachable_arg: bool, branch_attachable_arg: bool) -> void:
|
||||
func init(textute_arg: Texture, type_arg: PartType, root_arg: PlantAttach, attaches_arg: Array[PlantAttach]) -> void:
|
||||
texture = textute_arg
|
||||
type = type_arg
|
||||
root = root_arg
|
||||
attaches = attaches_arg
|
||||
bottom_attaches = bottom_attaches_arg
|
||||
type = type_arg
|
||||
is_back = is_back_arg
|
||||
base_attachable = base_attachable_arg
|
||||
bottom_attachable = bottom_attachable_arg
|
||||
branch_attachable = branch_attachable_arg
|
||||
|
||||
@@ -1,82 +1,55 @@
|
||||
@tool
|
||||
extends Sprite2D
|
||||
class_name PlantPartScene
|
||||
class_name PlantPartBuilder
|
||||
|
||||
@export var part_name: String
|
||||
|
||||
@export_tool_button("Load resource") var load_resource_button = load_resource
|
||||
|
||||
@export var root: Node2D
|
||||
@export var attaches: Node
|
||||
@export var bottom_attaches: Node
|
||||
@export var type: PlantPart.PartType
|
||||
|
||||
@export var is_back: bool
|
||||
@export var base_attachable: bool
|
||||
@export var bottom_attachable: bool
|
||||
@export var branch_attachable: bool
|
||||
@export var root: PlantAttachBuilder
|
||||
@export var attaches: Node
|
||||
|
||||
@export_tool_button("Save as resource") var save_as_resource_button = save_as_resource
|
||||
|
||||
|
||||
func load_resource():
|
||||
var destination := "res://entities/plants/resources/plant_parts/" + part_name + ".tres"
|
||||
print("Loading: ", part_name, " at: ", destination)
|
||||
var plant_part = ResourceLoader.load(destination)
|
||||
if plant_part is PlantPart:
|
||||
root.position = plant_part.root
|
||||
var plant_part: PlantPart = ResourceLoader.load(destination) as PlantPart
|
||||
if plant_part:
|
||||
texture = plant_part.texture
|
||||
type = plant_part.type
|
||||
root.position = plant_part.root.position
|
||||
root.attach_types = plant_part.root.attach_types
|
||||
|
||||
var attaches_children := attaches.get_children()
|
||||
for i in maxi(attaches_children.size(), plant_part.attaches.size()):
|
||||
if i < attaches_children.size() && i < plant_part.attaches.size():
|
||||
attaches_children[i].position = plant_part.attaches[i]
|
||||
attaches_children[i].position = plant_part.attaches[i].position
|
||||
elif i >= attaches_children.size():
|
||||
var new_child = Node2D.new()
|
||||
var new_child = PlantAttachBuilder.new()
|
||||
new_child.name = "attach" + str(i)
|
||||
new_child.position = plant_part.attaches[i]
|
||||
new_child.position = plant_part.attaches[i].position
|
||||
new_child.attach_types = plant_part.attaches[i].attach_types
|
||||
attaches.add_child(new_child)
|
||||
new_child.set_owner(self )
|
||||
elif i >= plant_part.attaches.size():
|
||||
attaches_children[i].free()
|
||||
else:
|
||||
printerr("Invalid code path")
|
||||
|
||||
var bottom_attaches_children := bottom_attaches.get_children()
|
||||
for i in maxi(bottom_attaches_children.size(), plant_part.bottom_attaches.size()):
|
||||
if i < bottom_attaches_children.size() && i < plant_part.bottom_attaches.size():
|
||||
bottom_attaches_children[i].position = plant_part.bottom_attaches[i]
|
||||
elif i >= bottom_attaches_children.size():
|
||||
var new_child = Node2D.new()
|
||||
new_child.name = "bottom_attach" + str(i)
|
||||
new_child.position = plant_part.bottom_attaches[i]
|
||||
bottom_attaches.add_child(new_child)
|
||||
new_child.set_owner(self )
|
||||
elif i >= plant_part.bottom_attaches.size():
|
||||
bottom_attaches_children[i].free()
|
||||
else:
|
||||
printerr("Invalid code path")
|
||||
|
||||
type = plant_part.type
|
||||
is_back = plant_part.is_back
|
||||
base_attachable = plant_part.base_attachable
|
||||
bottom_attachable = plant_part.bottom_attachable
|
||||
branch_attachable = plant_part.branch_attachable
|
||||
else:
|
||||
printerr("Error loading ", part_name)
|
||||
|
||||
func save_as_resource():
|
||||
var destination := "res://entities/plants/resources/plant_parts/" + part_name + ".tres"
|
||||
print("Saving: ", part_name, " at: ", destination)
|
||||
var attaches_vec2: Array[Vector2]
|
||||
var attaches_vec2: Array[PlantAttach]
|
||||
for attach in attaches.get_children():
|
||||
attaches_vec2.append(attach.position)
|
||||
var bottom_attaches_vec2: Array[Vector2]
|
||||
for bottom_attach in bottom_attaches.get_children():
|
||||
bottom_attaches_vec2.append(bottom_attach.position)
|
||||
attaches_vec2.append(PlantAttachBuilder.to_plant_attach(attach))
|
||||
|
||||
var plant_part = PlantPart.new()
|
||||
plant_part.init(texture, root.position, attaches_vec2, bottom_attaches_vec2, type, is_back, base_attachable, bottom_attachable, branch_attachable)
|
||||
var err := ResourceSaver.save(plant_part, destination)
|
||||
plant_part.init(texture, type, PlantAttachBuilder.to_plant_attach(root), attaches_vec2)
|
||||
plant_part.resource_name = part_name
|
||||
var err := ResourceSaver.save(plant_part, destination, ResourceSaver.FLAG_REPLACE_SUBRESOURCE_PATHS)
|
||||
if err != OK:
|
||||
printerr("Error saving resource: ", error_string(err))
|
||||
else:
|
||||
|
||||
@@ -16,6 +16,20 @@ const PLACEHOLDER_GROWING_TEXTURE: Texture = preload("res://entities/plants/asse
|
||||
|
||||
var rng := RandomNumberGenerator.new()
|
||||
|
||||
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
|
||||
|
||||
@@ -25,13 +39,10 @@ func build_plant_texture(plant_data: PlantData) -> Texture:
|
||||
var mature_texture: Texture = PLACEHOLDER_MATURE_TEXTURE
|
||||
var mature_image: Image = Image.create_empty(IMAGE_WIDTH, IMAGE_HEIGHT, false, Image.FORMAT_RGBA8)
|
||||
var mature_image_center: Vector2i = 0.5 * mature_image.get_size()
|
||||
var branch_parts: Array[PlantPart]
|
||||
var base_part: PlantPart
|
||||
var available_base_attaches: Array[Vector2]
|
||||
var available_base_bottom_attach: Array[Vector2]
|
||||
var branch_attaches: Array[Vector2]
|
||||
var branch_root: Array[Vector2]
|
||||
var branch_parent_attach: Array[Vector2]
|
||||
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():
|
||||
@@ -46,13 +57,14 @@ func build_plant_texture(plant_data: PlantData) -> Texture:
|
||||
|
||||
var base_image = base_part.texture.get_image()
|
||||
var base_image_center: Vector2i = 0.5 * base_image.get_size()
|
||||
mature_image.blend_rect(base_image, Rect2i(Vector2i.ZERO, base_image.get_size()), mature_image_center - base_image_center - Vector2i(base_part.root))
|
||||
base_image_coord = mature_image_center - Vector2i(base_part.root.position)
|
||||
mature_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:
|
||||
branch_parts.append(pick_random(branches))
|
||||
parts_to_place.append(pick_random(branches))
|
||||
|
||||
for m in plant_data.mutations:
|
||||
print("mutations: ", m.id)
|
||||
@@ -73,7 +85,8 @@ func build_plant_texture(plant_data: PlantData) -> Texture:
|
||||
|
||||
var base_image = base_part.texture.get_image()
|
||||
var base_image_center: Vector2i = 0.5 * base_image.get_size()
|
||||
mature_image.blend_rect(base_image, Rect2i(Vector2i.ZERO, base_image.get_size()), mature_image_center - base_image_center - Vector2i(base_part.root))
|
||||
base_image_coord = mature_image_center - Vector2i(base_part.root.position)
|
||||
mature_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)
|
||||
@@ -85,74 +98,34 @@ func build_plant_texture(plant_data: PlantData) -> Texture:
|
||||
print("Not handled state")
|
||||
return null
|
||||
|
||||
available_base_attaches = base_part.attaches.duplicate()
|
||||
available_base_bottom_attach = base_part.bottom_attaches.duplicate()
|
||||
|
||||
assert(branch_parts.size() <= base_part.attaches.size(),
|
||||
str("More branches (", branch_parts.size(), ") than base attaches (", base_part.attaches.size(), ")"))
|
||||
|
||||
for branch in branch_parts:
|
||||
if available_base_attaches.size() == 0:
|
||||
break
|
||||
|
||||
var ind: int = rng.randi_range(0, available_base_attaches.size() - 1)
|
||||
var attach: Vector2 = available_base_attaches.pop_at(ind)
|
||||
|
||||
var branch_image: Image = branch.texture.get_image()
|
||||
var branch_image_center: Vector2i = 0.5 * branch_image.get_size()
|
||||
mature_image.blend_rect(branch_image, Rect2i(Vector2i.ZERO, branch.texture.get_size()), mature_image_center - branch_image_center + Vector2i(attach - branch.root - base_part.root))
|
||||
|
||||
for branch_attach in branch.attaches:
|
||||
branch_attaches.append(branch_attach)
|
||||
branch_root.append(branch.root)
|
||||
branch_parent_attach.append(attach)
|
||||
|
||||
if parts_to_place.size() > branch_attaches.size() + base_part.attaches.size() - branch_parts.size():
|
||||
printerr("ERROR generating : Parts to place : ", parts_to_place.size(),
|
||||
"; Branch Attaches : ", branch_attaches.size(),
|
||||
"; Base attaches : ", base_part.attaches.size(),
|
||||
"; Branch parts : ", branch_parts.size())
|
||||
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("create part")
|
||||
var attach: Vector2
|
||||
var parent_root: Vector2
|
||||
var chosen_attach_type: int = 0
|
||||
var attachables: Array[int]
|
||||
if part.base_attachable && available_base_attaches.size() > 0:
|
||||
attachables.append(1)
|
||||
if part.bottom_attachable && available_base_bottom_attach.size() > 0:
|
||||
attachables.append(2)
|
||||
if part.branch_attachable && branch_attaches.size() > 0:
|
||||
attachables.append(3)
|
||||
# assert(attachables.size() > 0)
|
||||
if attachables.size() == 0:
|
||||
print("No attach available")
|
||||
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
|
||||
chosen_attach_type = pick_random(attachables)
|
||||
|
||||
if chosen_attach_type == 1: # base attach
|
||||
var ind := rng.randi_range(0, available_base_attaches.size() - 1)
|
||||
attach = available_base_attaches.pop_at(ind)
|
||||
parent_root = base_part.root
|
||||
elif chosen_attach_type == 2: # bottom
|
||||
var ind := rng.randi_range(0, available_base_bottom_attach.size() - 1)
|
||||
attach = available_base_bottom_attach.pop_at(ind)
|
||||
parent_root = base_part.root
|
||||
elif chosen_attach_type == 3: # branch
|
||||
var ind := rng.randi_range(0, branch_attaches.size() - 1)
|
||||
attach = branch_attaches.pop_at(ind) - branch_root.pop_at(ind) + branch_parent_attach.pop_at(ind)
|
||||
parent_root = base_part.root
|
||||
var attach: PlantAttach = available_attaches.pop_at(ind)
|
||||
var parent_image_coord: Vector2i = parent_image_coords.pop_at(ind)
|
||||
|
||||
var part_image: Image = part.texture.get_image()
|
||||
var part_image_center: Vector2i = 0.5 * part_image.get_size()
|
||||
var relative_root_centered_pos: Vector2 = Vector2(mature_image_center - part_image_center) - part.root
|
||||
mature_image.blend_rect(part_image, Rect2i(Vector2i.ZERO, part.texture.get_size()), relative_root_centered_pos + attach - parent_root)
|
||||
var part_image_coord: Vector2i = parent_image_coord + Vector2i(attach.position - part.root.position)
|
||||
mature_image.blend_rect(part_image, Rect2i(Vector2i.ZERO, part.texture.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)
|
||||
|
||||
if rng.randi() % 2 == 0:
|
||||
mature_image.flip_x()
|
||||
mature_texture = ImageTexture.create_from_image(mature_image)
|
||||
return mature_texture
|
||||
|
||||
func pick_random(array: Array):
|
||||
return array[rng.randi_range(0, array.size() - 1)]
|
||||
## 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)
|
||||
return indices.find_custom(func(i): return array[i].attach_types.any(func(type): return attach_to_match.attach_types.has(type)))
|
||||
|
||||
Reference in New Issue
Block a user