170 lines
5.4 KiB
GDScript
170 lines
5.4 KiB
GDScript
extends Building
|
|
|
|
@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
|
|
@export var spacing: float = 1.0
|
|
|
|
var transported_items: Dictionary[Item, PackedFloat64Array] = {}
|
|
var belt_moving: bool = true
|
|
var closest_item: float = 0.0
|
|
|
|
@onready var path: Path3D = $Path3D
|
|
@onready var multimesh: MultiMeshInstance3D = $MultiMeshInstance3D
|
|
|
|
var test_timer: float = 0
|
|
@onready var test_item: Item = load("res://items/metal.tres")
|
|
|
|
var input_building: Building = null:
|
|
set(value):
|
|
if value.producer != null:
|
|
input_building = value
|
|
input_building.producer.consumers.append(consumer)
|
|
var output_building: Building = null:
|
|
set(value):
|
|
if value.consumer != null:
|
|
output_building = value
|
|
producer.consumers.append(output_building.consumer)
|
|
|
|
var waypoints: Array[Vector3] = []
|
|
var editing_waypoint: int = 0
|
|
|
|
func _placement_select_building(building: Building, confirmed: bool) -> int:
|
|
var ret: int = 0
|
|
if input_building == null:
|
|
if building.producer != null:
|
|
ret |= PLACEMENT_POSITION_OK
|
|
if confirmed:
|
|
input_building = building
|
|
ret |= PLACEMENT_PART_ADDED
|
|
set_path_waypoint(building.global_position + Vector3(0,1,0), confirmed)
|
|
elif output_building == null and building != input_building:
|
|
if building.consumer != null:
|
|
ret |= PLACEMENT_POSITION_OK
|
|
if confirmed:
|
|
output_building = building
|
|
ret |= PLACEMENT_COMPLETED
|
|
set_path_waypoint(building.global_position + Vector3(0,1,0), confirmed)
|
|
return ret
|
|
#return super(building, confirmed)
|
|
|
|
func _placement_select_position(pos: Vector3, confirmed: bool) -> int:
|
|
var ret: int = PLACEMENT_POSITION_OK
|
|
set_path_waypoint(pos.round() + Vector3(0,1,0), confirmed)
|
|
if confirmed:
|
|
ret |= PLACEMENT_PART_ADDED
|
|
return confirmed
|
|
|
|
func set_path_waypoint(global_pos: Vector3, add: bool) -> void:
|
|
var local_pos: Vector3
|
|
if editing_waypoint == 0:
|
|
global_position = global_pos
|
|
local_pos = Vector3()
|
|
else:
|
|
local_pos = to_local(global_pos)
|
|
while waypoints.size() <= editing_waypoint:
|
|
waypoints.append(Vector3())
|
|
waypoints[editing_waypoint] = local_pos
|
|
if add:
|
|
editing_waypoint += 1
|
|
update_path_from_waypoints()
|
|
|
|
func update_path_from_waypoints() -> void:
|
|
path.curve.clear_points()
|
|
|
|
for waypoint in waypoints:
|
|
path.curve.add_point(waypoint)
|
|
# find paths between the defined points
|
|
#for i in range(1, waypoints.size()):
|
|
#var a: Vector3 = to_global(waypoints[i-1])
|
|
#var b: Vector3 = to_global(waypoints[i])
|
|
#var route: PackedVector3Array = NavigationServer3D.map_get_path(NavigationServer3D.get_maps()[0], a, b, false, 1)
|
|
#
|
|
#for point in route:
|
|
#path.curve.add_point(to_local(point + Vector3(0,1,0)))
|
|
|
|
|
|
|
|
# set the path3d's points to the path points
|
|
# adjust the control points to some uniform amount
|
|
pass
|
|
|
|
func _ready() -> void:
|
|
multimesh.multimesh = multimesh.multimesh.duplicate()
|
|
path.curve = path.curve.duplicate()
|
|
|
|
func _process(delta: float) -> void:
|
|
belt_moving = check_items_at_end()
|
|
consumer.enabled = belt_moving and (closest_item >= spacing)
|
|
|
|
var movement: float = (delta * speed)
|
|
closest_item += movement
|
|
if belt_moving:
|
|
for transported_item_type: Item 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] += movement
|
|
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
|
|
|
|
closest_item = 0.0
|
|
|
|
func check_items_at_end() -> bool:
|
|
var length: float = get_end_offset()
|
|
var ret: bool = true
|
|
for transported_item_type: Item 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:
|
|
ret = false
|
|
else:
|
|
to_delete.append(i)
|
|
for d in to_delete:
|
|
offsets.remove_at(d)
|
|
return ret
|
|
|
|
func get_start_offset() -> float:
|
|
return -extra_distance_start
|
|
|
|
func get_end_offset() -> float:
|
|
return path.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 = path.curve.get_baked_length()
|
|
if offset <= 0:
|
|
var zero: Transform3D = path.curve.sample_baked_with_rotation(0)
|
|
var almost_zero: Transform3D = path.curve.sample_baked_with_rotation(0.1)
|
|
return almost_zero.interpolate_with(zero, (0.1-offset) * 10)
|
|
elif offset > end_offset:
|
|
var end: Transform3D = path.curve.sample_baked_with_rotation(end_offset)
|
|
var almost_end: Transform3D = path.curve.sample_baked_with_rotation(end_offset-0.1)
|
|
return almost_end.interpolate_with(end, (offset - (end_offset - 0.1)) * 10)
|
|
else:
|
|
return path.curve.sample_baked_with_rotation(offset)
|
|
|