Now About Social Code
summaryrefslogtreecommitdiff
path: root/scripts/player.gd
blob: 2d4db998e21a8f9eadf72e9074c92af8cbf5a132 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
extends CharacterBody3D

const SPEED = 5.0
const RUN_SPEED = 1.5 * SPEED
const JUMP_VELOCITY = 4.5
const THROW_FORCE = 10.0
const RUN_CONSUMPTION = 20.0
const STAM_REGEN = 10.0

#@export_node_path("ProgressBar") var stam_bar_path = null
@export var stam_bar: ProgressBar = null;
@export var seed_text: RichTextLabel = null;

var stamina: float = 100
var num_seeds: int = 0

# Get the gravity from the project settings to be synced with RigidBody nodes.
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")

var current_node: Node3D = null
var holding: Node3D = null

var climbing: bool = false
var last_wall_direction: Vector3 = Vector3()

func got_body(body: Node3D):
	if current_node == null:
		current_node = body

func leave_body(body: Node3D):
	if current_node == body:
		current_node = null
		
func pickup():
	if holding == null:
		holding = current_node
		current_node.get_parent().remove_child(current_node)
		holding.position = Vector3.ZERO
		holding.freeze = true
		$Holder.add_child(holding)
		
func throw():
	var g_pos = holding.global_position
	holding.get_parent().remove_child(holding)
	get_parent().add_child(holding)
	holding.global_position = g_pos
	
	var fwd = $ThirdPersonCamera.get_front_direction()
	var right = Vector3.UP
	var dir = (fwd + right).normalized()
	holding.freeze = false
	holding.apply_impulse(THROW_FORCE*dir)
	holding = null

func _ready():
	assert(stam_bar != null, "Stamina bar is null")
	assert(seed_text != null, "Seed text is null")
		
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	$ThirdPersonCamera.mouse_follow = true
	
	$Picker.connect("body_entered", got_body)
	$Picker.connect("body_exited", leave_body)
	
func _process(_delta):
	stam_bar.value = stamina
	seed_text.text = str(num_seeds)

func _physics_process(delta):
	var speed = SPEED
	var stam_consumption = 0
	
	if Input.is_action_pressed("run") and stamina > 0:
		speed = RUN_SPEED
		stam_consumption += RUN_CONSUMPTION
		
	if Input.is_action_just_pressed("pickup"):
		if holding == null and current_node != null:
			pickup()
		elif holding != null:
			throw()
	
	# Add the gravity.
	if not is_on_floor() and not climbing:
		velocity.y -= gravity * delta
		
	var fwd = $ThirdPersonCamera.get_front_direction()
	var right = $ThirdPersonCamera.get_right_direction()
	
	var climb_direction_fwd = Vector3()
	var climb_direction_right = Vector3()
	
	var valid_climb = false
	if is_on_wall():
		for col in get_slide_collision_count():
			var col_obj = get_slide_collision(col)
			print(col_obj.get_collider().collision_layer)
			if col_obj.get_collider().collision_layer & 0b100:
				valid_climb = true
		
	if valid_climb and stamina > 0:	
		last_wall_direction = get_wall_normal()
		climbing = true
		stam_consumption += RUN_CONSUMPTION
		print("Climbing now")
	elif climbing:
		climbing = false
		print("Not climbing")
		
	if climbing:
		climb_direction_fwd = (Vector3.UP - Vector3.UP.project(last_wall_direction)).normalized()
		climb_direction_right = (right - right.project(last_wall_direction)).normalized()

	# Handle Jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY
	
	look_at(position + fwd, Vector3.UP)

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir = Input.get_vector("left", "right", "backward", "forward")
	var direction = (input_dir.y * fwd + input_dir.x * right).normalized()
	var climb_direction = (input_dir.y * climb_direction_fwd + input_dir.x * climb_direction_right).normalized()
	if climbing:
		print("Climb direction is ", climb_direction_fwd, " ", climb_direction_right, " ", get_wall_normal())
		velocity = climb_direction * speed
		velocity += -speed * last_wall_direction
		print("Velocity is ", velocity)
	elif direction:
		velocity.x = direction.x * speed
		velocity.z = direction.z * speed
	else:
		velocity.x = move_toward(velocity.x, 0, speed)
		velocity.z = move_toward(velocity.z, 0, speed)

	move_and_slide()
	
	if stam_consumption == 0 and not Input.is_action_pressed("run") and is_on_floor():
		stam_consumption = -STAM_REGEN
	
	stamina = clamp(stamina - stam_consumption * delta, 0, 100)