Now About Social Code
summaryrefslogtreecommitdiff
path: root/scripts/player.gd
blob: bbcc4f479e2825a6e1cf737f0e085b6c41362d9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
extends Node3D

@export var grapple_distance: float = 10
@export var grapple_speed: float = 10
@export var fire_distance: float = 100

@export var fire_rate: float = 0.1

@export var ui_control: CanvasLayer

enum State {
	NO_GRAPPLE,
	FREE,
	GRAPPLING
}

var current_state: State = State.FREE
var grapple_target: Vector3 = Vector3.ZERO

var bullet_inst = preload("res://prefabs/bullet.tscn")

var ammo: int = 100
var fire_timer: float = fire_rate

var interactable: Node3D = null

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	assert(ui_control != null)
	
func do_grapple() -> void:
	if Input.is_action_just_pressed("attack") and current_state == State.FREE:
		var space_state = get_world_3d().direct_space_state
		
		var starting_pos = global_position
		var ending_pos = starting_pos + grapple_distance * -global_transform.basis.z
		var query = PhysicsRayQueryParameters3D.create(starting_pos, ending_pos)
		query.collision_mask = 0x2
		var result = space_state.intersect_ray(query)
		
		if result:
			grapple_target = result.position + global_transform.basis.z
			current_state = State.GRAPPLING
			
	if Input.is_action_just_released("attack") and current_state == State.GRAPPLING:
		current_state = State.FREE
		grapple_target = Vector3.ZERO
		
	
	#print("State ", current_state, " ", grapple_target)
	if current_state == State.GRAPPLING:
		var dir_to_target = (grapple_target - global_position).normalized()
		
		get_parent().local_velocity = dir_to_target * grapple_speed
	
func fire_weapon(delta: float) -> void:
	if Input.is_action_pressed("attack") and ammo > 0 and fire_timer >= fire_rate:
		var space_state = get_world_3d().direct_space_state
		var starting_pos = global_position
		var ending_pos = starting_pos + fire_distance * -global_transform.basis.z
		var query = PhysicsRayQueryParameters3D.create(starting_pos, ending_pos)
		var result = space_state.intersect_ray(query)
		
		var end = ending_pos
		if result:
			if result.collider.has_method("on_hit"):
				result.collider.on_hit(result.position)
			end = result.position
			
		var bullet: Node3D = bullet_inst.instantiate()
		bullet.position = starting_pos
		bullet.target = end
		get_tree().get_root().add_child(bullet)
		var up = Vector3.UP
		if abs(global_transform.basis.z.y) > 0.99:
			up = Vector3(0, 0, 1)
		bullet.look_at(end, up)
		
		ammo -= 1
		fire_timer = 0
	else:
		fire_timer += delta

func do_interact() -> void:
	if interactable != null and not ui_control.have_toast():
		ui_control.set_toast("Press E to interact", 0)
	elif interactable == null and not ui_control.have_toast():
		ui_control.set_toast("", 0)
		
	if Input.is_action_just_pressed("interact") and interactable != null:
		if interactable.has_method("get_contents"):
			var contents = interactable.get_contents()
			if contents > 0:
				ammo += contents
				ui_control.set_toast("Got " + str(contents) + " ammo!", 1)
			else:
				ui_control.set_toast("Empty container", 1)

func _physics_process(delta: float) -> void:
	do_grapple()
	do_interact()
	fire_weapon(delta)

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(_delta: float) -> void:
	pass

func _on_interactable_enter(body: Node3D) -> void:
	interactable = body

func _on_interactable_exit(body: Node3D) -> void:
	if interactable == body:
		interactable = null