Now compares the angle of the old connection to the new one and based off of the attachment being from clockwise movement or counterclockwise movement, it disconnects Signed-off-by: Ethan Wellenreiter <ewellenreiter@gmail.com>
129 lines
4.1 KiB
GDScript
129 lines
4.1 KiB
GDScript
extends Node2D
|
|
class_name Rope
|
|
|
|
@onready var rope_seg_scene : PackedScene = preload("res://assets/rope_segment.tscn")
|
|
|
|
@onready var player : Player = %Player
|
|
|
|
@export var DIST_MARGIN : float = 0.01
|
|
|
|
var rope_segments : Array[RopeSegment] = []
|
|
|
|
func add_rope_seg(conn_point : Vector2) -> void:
|
|
var rope_seg : RopeSegment = rope_seg_scene.instantiate()
|
|
add_child(rope_seg)
|
|
rope_seg.set_conn_point(conn_point)
|
|
rope_seg.update_sprite_heading(player.global_position)
|
|
rope_seg.update_ray_heading(player.global_position)
|
|
rope_segments.append(rope_seg)
|
|
|
|
func shift_add_rope_seg(conn_point : Vector2) -> void:
|
|
add_rope_seg(rope_segments[-1].conn_point)
|
|
rope_segments[-2].conn_point = conn_point
|
|
|
|
var t1 = rope_segments[-2]
|
|
rope_segments[-2] = rope_segments[-1]
|
|
rope_segments[-1] = t1
|
|
|
|
rope_segments[-2].update_sprite_heading(conn_point)
|
|
rope_segments[-2].update_ray_heading(player.global_position)
|
|
|
|
rope_segments[-1].update_sprite_heading(player.global_position)
|
|
rope_segments[-1].update_ray_heading(player.global_position)
|
|
|
|
func pop_rope_seg() -> void:
|
|
if (rope_segments.size() == 0):
|
|
print("ERROR: popping from empty rope")
|
|
else:
|
|
var rope_seg : RopeSegment = rope_segments[-1]
|
|
remove_child(rope_seg)
|
|
rope_segments.remove_at(rope_segments.size()-1)
|
|
rope_seg.safe_destroy()
|
|
|
|
func shift_pop_rope_seg() -> void:
|
|
#print("shift_pop_entered")
|
|
if (rope_segments.size() == 0):
|
|
print("ERROR: popping from empty rope")
|
|
else:
|
|
var t1 = rope_segments[-2]
|
|
rope_segments[-2] = rope_segments[-1]
|
|
rope_segments[-1] = t1
|
|
rope_segments[-2].conn_point = rope_segments[-1].conn_point
|
|
rope_segments[-2].update_sprite_heading(player.global_position)
|
|
rope_segments[-2].update_ray_heading(player.global_position)
|
|
pop_rope_seg()
|
|
|
|
|
|
|
|
func clear_rope() -> void:
|
|
while not rope_segments.is_empty():
|
|
pop_rope_seg()
|
|
|
|
|
|
func angle_valid_release_rope(a1:float, cw:bool) -> bool:
|
|
var result : bool
|
|
if cw:
|
|
result = a1 < 0
|
|
else:
|
|
result = a1 > 0
|
|
|
|
return result
|
|
|
|
|
|
|
|
func check_new_coll():
|
|
#print("enter")
|
|
var cur_rope = rope_segments[-1]
|
|
if cur_rope.rope_ray.is_colliding():
|
|
var col_point : Vector2 = cur_rope.rope_ray.get_collision_point()
|
|
var dist : float = player.global_position.distance_to(col_point)
|
|
#print(player.rope_length, " ", dist)
|
|
|
|
if player.rope_length - dist > DIST_MARGIN:
|
|
|
|
shift_add_rope_seg(col_point)
|
|
#rope_segments[-2].connection_angle = rope_segments[-2].conn_point.angle_to_point(player.global_position)
|
|
var tangent : Vector2 = col_point - player.global_position
|
|
tangent = Vector2(tangent.y, -tangent.x)
|
|
rope_segments[-2].clockwise = player.velocity.dot(tangent) > 0
|
|
#print(tangent, " ", player.velocity, " ", rope_segments[-2].clockwise)
|
|
#cur_rope.update_sprite_heading(col_point)
|
|
player.rope_length = dist
|
|
player.connection_point = col_point
|
|
else:
|
|
|
|
var counter : int = rope_segments.size() - 2
|
|
#var pop : bool = false
|
|
while counter >= 0:
|
|
#print("looping")
|
|
if rope_segments[counter].rope_ray.is_colliding(): # safety check
|
|
if rope_segments[counter].conn_point.distance_to(rope_segments[counter].rope_ray.get_collision_point()) < DIST_MARGIN and \
|
|
angle_valid_release_rope((rope_segments[counter].conn_point - player.global_position).angle_to(rope_segments[counter+1].conn_point - player.global_position), rope_segments[counter].clockwise): # if the collision of the other ray is longer (so it can see the earlier connection point)
|
|
player.connection_point = rope_segments[counter].conn_point
|
|
player.rope_length = player.global_position.distance_to(player.connection_point)
|
|
shift_pop_rope_seg()
|
|
counter -= 1
|
|
else:
|
|
break
|
|
else:
|
|
break
|
|
#print("exit")
|
|
|
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
|
func _process(delta: float) -> void:
|
|
#print(global_position)
|
|
|
|
if player.on_rope and rope_segments.size() >= 1:
|
|
#print("hi")
|
|
rope_segments[-1].update_sprite_heading(player.global_position)
|
|
for i in range(rope_segments.size()):
|
|
rope_segments[i].update_ray_heading(player.global_position)
|
|
#print("aim_dir ", aim_dir)
|
|
#look_at(aim_dir)
|
|
|
|
check_new_coll()
|
|
|
|
|
|
pass
|
|
|