TowerGame/scripts/buildings/conveyor.gd

92 lines
3.0 KiB
GDScript

extends Path3D
@export var speed: float = 1.0
@export var item_offset: Vector3 = Vector3(0,2.0,0)
@export var extra_distance_start: float = 1.0
@export var extra_distance_end: float = 1.0
var transported_items: Dictionary[Item, PackedFloat64Array] = {}
@onready var consumer: Consumer = $Consumer
@onready var producer: Producer = $Producer
@onready var multimesh: MultiMeshInstance3D = $MultiMeshInstance3D
var test_timer: float = 0
@onready var test_item: Item = load("res://items/metal.tres")
func _ready() -> void:
multimesh.multimesh = multimesh.multimesh.duplicate()
func _process(delta: float) -> void:
#test_timer += delta
#if test_timer >= 2.0:
#test_timer -= 2.0
#add_item(test_item)
var belt_moving: bool = check_items_at_end()
if belt_moving:
for transported_item_type in transported_items.keys():
var offsets: PackedFloat64Array = transported_items[transported_item_type]
multimesh.multimesh.instance_count = offsets.size()
for i in range(offsets.size()):
offsets[i] += (delta * speed)
position_item(i, transported_item_type, offsets[i])
func consumer_has_item(item: Item) -> void:
if consumer.take_item_from_storage(item):
add_item(item)
func add_item(item: Item) -> void:
if item.model != multimesh.multimesh.mesh:
multimesh.multimesh.mesh = item.model
var offsets: PackedFloat64Array
if transported_items.has(item):
offsets = transported_items[item]
else:
offsets = []
offsets.append(get_start_offset())
transported_items[item] = offsets
func check_items_at_end() -> bool:
var length: float = get_end_offset()
var belt_moving: bool = true
for transported_item_type in transported_items.keys():
var offsets: PackedFloat64Array = transported_items[transported_item_type]
var to_delete: Array[int] = []
for i in range(offsets.size()):
if offsets[i] >= length:
var sent: bool = producer.send_item(transported_item_type)
if !sent:
belt_moving = false
else:
to_delete.append(i)
for d in to_delete:
offsets.remove_at(d)
return belt_moving
func get_start_offset() -> float:
return -extra_distance_start
func get_end_offset() -> float:
return curve.get_baked_length() + extra_distance_end
func position_item(instance: int, item: Item, offset: float) -> void:
var trans: Transform3D
trans = sample_curve_with_extrapolation(offset).translated_local(item_offset)
multimesh.multimesh.set_instance_transform(instance, trans)
func sample_curve_with_extrapolation(offset: float) -> Transform3D:
var end_offset: float = curve.get_baked_length()
if offset <= 0:
var zero: Transform3D = curve.sample_baked_with_rotation(0)
var almost_zero: Transform3D = curve.sample_baked_with_rotation(0.1)
return almost_zero.interpolate_with(zero, (0.1-offset) * 10)
elif offset > end_offset:
var end: Transform3D = curve.sample_baked_with_rotation(end_offset)
var almost_end: Transform3D = curve.sample_baked_with_rotation(end_offset-0.1)
return almost_end.interpolate_with(end, (offset - (end_offset - 0.1)) * 10)
else:
return curve.sample_baked_with_rotation(offset)