small racing game im working on
Diffstat (limited to 'ui/editor/track_editor.gd')
| -rw-r--r-- | ui/editor/track_editor.gd | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/ui/editor/track_editor.gd b/ui/editor/track_editor.gd new file mode 100644 index 0000000..9b2a499 --- /dev/null +++ b/ui/editor/track_editor.gd @@ -0,0 +1,122 @@ +extends PanelContainer +class_name TrackEditor + +@export var group: ButtonGroup +@onready var brush := %brush + +enum Mode { Select, Move, Rotate, Scale } +var mode: Mode +var selected: Array[TrackObject]: + set(s): + if s != selected: + for b in selected: # easier than finding the items that are not in selected but are in s + b.live_node.un_highlight() + selected = s + for b in selected: + b.live_node.highlight() + make_gizmo.emit(mode) + selection_changed.emit(selected) +var snapping := true +var objects: Array[TrackObject] = [] +var history := UndoRedo.new() +var track: TrackResource +signal make_gizmo(mode: Mode) +signal selection_changed(objects: Array[TrackObject]) + +const loader := preload("res://scenes/track.tscn") + +func _ready() -> void: + track = Globals.editing if Globals.editing else TrackResource.new([]) + var l: TrackLoader = loader.instantiate() + l.editor = true + l.track = track + add_child(l) + # move over the loaders children + for c in l.get_children(): + l.remove_child(c) + %port.add_child(c) + # the loader has loaded, get rid of it + l.queue_free() + objects = track.blocks.duplicate() # duplicate: if not saved, will be lost + %propertys.name_.text = track.name + %propertys.laps_.value = track.laps + %cam.global_transform = IntroCam.get_origin(track) # put the camera up high, looking straight down + + if not FileAccess.file_exists(Globals.TRACKS % track.name) and not track.builtin: + %save.unsaved = true + + group.pressed.connect(pressed) + tree_exiting.connect( + func(): + for obj in objects: + obj.delete_live() + ) + +func pressed(b: Button) -> void: + mode = Mode[b.name.to_pascal_case()] + make_gizmo.emit(mode) + +func reset_selected() -> void: + var new: Array[TrackObject] = [] + selected = new + +func _on_mousecast_hit(colls: Array[Block]) -> void: + var new_selected: Array[TrackObject] = [] + new_selected.resize(colls.size()) + var painting: bool = brush.button_pressed and not colls.is_empty() + if painting: + history.create_action("paint") + for i in len(colls): + new_selected[i] = tobj_from_node(colls[i]) + if painting and colls[i].materials_allowed() & brush.mat: + history.add_do_method(colls[i].set_mat.bind(brush.mat)) + history.add_undo_method(colls[i].set_mat.bind(colls[i].mat)) + assert(new_selected[i]!=null, "%s was not found" % [colls[i]]) + if not brush.button_pressed: + selected = new_selected + if painting: + history.commit_action() + +func _on_snapping_toggled(button_pressed: bool) -> void: + snapping = button_pressed + +func get_trackdata() -> TrackResource: + objects = objects.filter(func(o: TrackObject): return is_instance_valid(o.live_node)) + track.blocks = objects.duplicate() + track.name = %propertys.name_.text + track.laps = %propertys.laps_.value + return track + +func _on_item_created(object: TrackObject) -> void: + objects.append(object) + if object.live_node is Booster: + for block in objects: + if block.live_node is Booster: + block.live_node.sync() + %thonk.pitch_scale = randf_range(.9, 1.2) + %thonk.play() + +func tobj_from_node(node: Block) -> TrackObject: + for o in objects: + if o.live_node == node: + return o + return null + +func _on_delete_pressed() -> void: + selected = [] + +func _on_remove_tobj(tobj: TrackObject) -> void: + objects.erase(tobj) + +func _on_brush_toggled(on: bool) -> void: + if on: + var painting: bool = brush.button_pressed and not selected.is_empty() + if painting: + history.create_action("paint") + for o in selected: + if painting and o.live_node.materials_allowed() & brush.mat: + history.add_do_method(o.live_node.set_mat.bind(brush.mat)) + history.add_undo_method(o.live_node.set_mat.bind(o.live_node.mat)) + if painting: + history.commit_action() + reset_selected() |