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)