source: Studio/Player.gd@ 5a9a237

sandbox
Last change on this file since 5a9a237 was 5a9a237, checked in by Kevin Chapman <victory2b@…>, 3 years ago

(WIP) Making it so a player can walk up stairs. Made Raycast for checking if feet connect, but body does not.

  • Property mode set to 100644
File size: 10.1 KB
Line 
1extends KinematicBody
2
3# Load Config File
4var player_data = {}
5var player_config = ConfigFile.new()
6var player_filepath = "res://config/player.ini"
7
8# Popup menus
9var Pause_Popup_tscn = preload("res://Pause_Popup.tscn")
10var Dead_Popup_tscn = preload("res://Dead_Popup.tscn")
11
12###################-VARIABLES-####################
13
14# Camera
15export(NodePath) var head_path = "Head"
16export(NodePath) var cam_path = "Head/Camera"
17export(float) var FOV = 80.0
18var mouse_axis := Vector2()
19onready var head: Spatial = get_node(head_path)
20onready var cam: Camera = get_node(cam_path)
21
22# Move
23var velocity := Vector3()
24var direction := Vector3()
25var move_axis := Vector2()
26var snap := Vector3() # Connecting to ground
27var falling := Vector3()
28
29# Walk and Sprint
30const FLOOR_MAX_ANGLE: float = deg2rad(46.0)
31export(float) var gravity = 20.0
32export(int) var walk_speed = 10
33export(int) var sprint_speed = 16
34export(int) var acceleration = 8
35export(int) var deacceleration = 10
36export(float, 0.0, 1.0, 0.05) var air_control = 0.3
37export(int) var jump_height = 12
38var _speed: int
39var _is_sprinting_input := false
40var _is_jumping_input := false
41var sprint_enabled := true
42var hold_walk := false
43var stamina_delay = 0
44
45# Climb stairs
46var foot_collide = false
47var wall_collide = false
48
49# Grounded
50enum GROUNDED_STATE {
51 GROUNDED,
52 MIDAIR,
53 TOUCHDOWN
54}
55var player_state = GROUNDED_STATE.GROUNDED
56
57# Player defaults if not found in INI file
58var player = "player"
59var exhausted_delay = 30
60var sprint_energy_consumption = 0.5
61var stamina_regen_speed = 0.5
62var mana_needed_to_heal = 30
63var mana_heal_ammount = 10
64var mana_regen_speed = 0.01
65var health = 100
66var stamina = 100
67var mana = 100
68var lifeforce = 100
69var xp = 0
70var dead = false
71
72
73# Damage
74var max_fall := Vector3() # Total disatance falled down
75var fall_threshold_damage = 17 # distance down a player has to fall before taking damage
76
77
78##################################################
79
80# Called when the node enters the scene tree
81func _ready() -> void:
82 if player_config.load(player_filepath) == OK:
83 mana_needed_to_heal = player_config.get_value(player, "mana_needed_to_heal")
84 mana_heal_ammount = player_config.get_value(player, "mana_heal_ammount")
85 mana_regen_speed = player_config.get_value(player, "mana_regen_speed")
86 fall_threshold_damage = player_config.get_value(player, "fall_threshold_damage")
87 gravity = player_config.get_value(player, "gravity")
88 walk_speed = player_config.get_value(player, "walk_speed")
89 exhausted_delay = player_config.get_value(player, "exhausted_delay")
90 stamina_regen_speed = player_config.get_value(player, "stamina_regen_speed")
91 sprint_speed = player_config.get_value(player, "sprint_speed")
92 sprint_energy_consumption = player_config.get_value(player, "sprint_energy_consumption")
93 jump_height = player_config.get_value(player, "jump_height")
94
95 else:
96 print("Player Config File Not Found - Using defaults")
97
98
99 # Remove this later, this is just a temp line until future code is avalable for each player to have its own stats
100 Globals.dead = false
101
102 Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
103 cam.fov = FOV
104
105# Called every frame. 'delta' is the elapsed time since the previous frame
106func _process(_delta: float) -> void:
107 move_axis.x = Input.get_action_strength("move_forward") - Input.get_action_strength("move_backward")
108 move_axis.y = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
109 check_foot()
110
111 if Globals.dead:
112 Globals.player_dead()
113
114 if Globals.food_task:
115 get_node("HUD/Control/LifeforceBar").value = Globals.lifeforce
116
117 if Input.is_action_just_pressed("move_jump"):
118 _is_jumping_input = true
119
120 if Input.is_action_pressed("move_sprint"):
121 _is_sprinting_input = true
122
123 if Input.is_action_just_pressed("hold_move_forward"):
124 if hold_walk == true:
125 hold_walk = false
126 else:
127 hold_walk = true
128
129 if Input.is_action_just_pressed("move_forward") || Input.is_action_just_pressed("move_backward"):
130 hold_walk = false
131
132 if hold_walk == true:
133 move_axis.x = hold_walk
134
135# Recapture mouse when resuming
136 if Input.get_mouse_mode() == Input.MOUSE_MODE_VISIBLE && !Globals.dead:
137 Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
138
139# Called every physics tick. 'delta' is constant
140func _physics_process(delta: float) -> void:
141 walk(delta)
142
143# Fall damage calculation
144 match player_state:
145 GROUNDED_STATE.GROUNDED:
146 falling = Vector3.ZERO
147 if not is_on_floor():
148 player_state = GROUNDED_STATE.MIDAIR
149 GROUNDED_STATE.MIDAIR:
150 falling += Vector3.DOWN * gravity * delta
151 if velocity.y <= -fall_threshold_damage:
152 max_fall = velocity
153 if is_on_floor():
154 player_state = GROUNDED_STATE.TOUCHDOWN
155 GROUNDED_STATE.TOUCHDOWN:
156 if falling.length() >= fall_threshold_damage and max_fall.y <= -fall_threshold_damage:
157 Globals.health -= round(-(max_fall.y + fall_threshold_damage))
158 Globals.stamina -= round(-(max_fall.y + fall_threshold_damage))
159 if round(-(max_fall.y + fall_threshold_damage)) > 5:
160 Globals.health -= round(-(max_fall.y + fall_threshold_damage)*9)
161 else:
162 if round(-(max_fall.y + fall_threshold_damage)) > 10:
163 Globals.health -= round(-(max_fall.y + fall_threshold_damage)*15)
164 if Globals.health <= 0:
165 Globals.lifeforce += Globals.health * 2
166 if Globals.lifeforce <= 0:
167 Globals.health = 0
168 Globals.lifeforce = 0
169 Globals.dead = true
170 else:
171 Globals.health = 1
172 Globals.mana = 0
173 Globals.stamina = 0
174 stamina_delay = exhausted_delay
175 sprint_enabled = false
176 get_node("HUD/Control/LifeforceBar").value = Globals.lifeforce
177 get_node("HUD/Control/ManaBar").value = Globals.mana
178 get_node("Head/AnimationPlayer").play("FallDamage")
179 get_node("HUD/Control/HealthBar").value = Globals.health
180 max_fall = Vector3.ZERO
181 player_state = GROUNDED_STATE.GROUNDED
182
183
184# Called when there is an input event
185func _input(event: InputEvent) -> void:
186 if event is InputEventMouseMotion:
187 mouse_axis = event.relative
188 camera_rotation()
189
190# Heal button
191 if Input.is_action_just_pressed("heal") && Globals.mana >= mana_needed_to_heal:
192 if Globals.health != 100:
193 Globals.mana -= mana_needed_to_heal
194 if 100 < Globals.health + mana_heal_ammount:
195 Globals.health = 100
196 elif Globals.health == 0:
197 Globals.health = mana_heal_ammount
198 else:
199 Globals.health += mana_heal_ammount
200 get_node("HUD/Control/HealthBar").value = Globals.health
201 get_node("HUD/Control/ManaBar").value = Globals.mana
202
203func walk(delta: float) -> void:
204 direction_input()
205
206 if is_on_floor():
207 snap = -get_floor_normal() - get_floor_velocity() * delta
208
209 # Workaround for sliding down after jump on slope
210 if velocity.y < 0:
211 velocity.y = 0
212 jump()
213 else:
214 # Workaround for 'vertical bump' when going off platform
215 if snap != Vector3.ZERO && velocity.y != 0:
216 velocity.y = 0
217
218 snap = Vector3.ZERO
219
220 velocity.y -= gravity * delta
221
222 sprint(delta)
223
224 accelerate(delta)
225
226 velocity = move_and_slide_with_snap(velocity, snap, Vector3.UP, true, 4, FLOOR_MAX_ANGLE)
227 _is_jumping_input = false
228 _is_sprinting_input = false
229
230func camera_rotation() -> void:
231 if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
232 return
233 if mouse_axis.length() > 0:
234 var horizontal: float = -mouse_axis.x * (Globals.mouse_sensitivity / 100)
235 var vertical: float = -mouse_axis.y * (Globals.mouse_sensitivity / 100)
236
237 mouse_axis = Vector2()
238
239 rotate_y(deg2rad(horizontal))
240 head.rotate_x(deg2rad(vertical))
241
242 # Clamp mouse rotation
243 var temp_rot: Vector3 = head.rotation_degrees
244 temp_rot.x = clamp(temp_rot.x, -90, 90)
245 head.rotation_degrees = temp_rot
246
247
248func direction_input() -> void:
249 direction = Vector3()
250 var aim: Basis = get_global_transform().basis
251 if move_axis.x >= 0.5:
252 direction -= aim.z
253 if move_axis.x <= -0.5:
254 direction += aim.z
255 if move_axis.y <= -0.5:
256 direction -= aim.x
257 if move_axis.y >= 0.5:
258 direction += aim.x
259 direction.y = 0
260 direction = direction.normalized()
261
262
263func accelerate(delta: float) -> void:
264 # Where would the player go
265 var _temp_vel: Vector3 = velocity
266 var _temp_accel: float
267 var _target: Vector3 = direction * _speed
268
269 _temp_vel.y = 0
270 if direction.dot(_temp_vel) > 0:
271 _temp_accel = acceleration
272
273 else:
274 _temp_accel = deacceleration
275
276 if not is_on_floor():
277 _temp_accel *= air_control
278
279 # Interpolation
280 _temp_vel = _temp_vel.linear_interpolate(_target, _temp_accel * delta)
281
282 velocity.x = _temp_vel.x
283 velocity.z = _temp_vel.z
284
285 # Make too low values zero
286 if direction.dot(velocity) == 0:
287 var _vel_clamp := 0.01
288 if abs(velocity.x) < _vel_clamp:
289 velocity.x = 0
290 if abs(velocity.z) < _vel_clamp:
291 velocity.z = 0
292
293
294func jump() -> void:
295 if _is_jumping_input:
296 velocity.y = jump_height
297 snap = Vector3.ZERO
298
299func sprint(delta: float) -> void:
300 if can_sprint():
301 if Globals.stamina >= 0 && stamina_delay <= 1:
302 _speed = sprint_speed
303 cam.set_fov(lerp(cam.fov, FOV * 1.25, delta * 8))
304 Globals.stamina -= sprint_energy_consumption
305 if Globals.stamina <= 0:
306 stamina_delay = exhausted_delay
307 sprint_enabled = false
308 cam.fov = FOV
309 _speed = walk_speed
310 return
311 get_node("HUD/Control/StaminaBar").value = Globals.stamina
312 else:
313 _speed = walk_speed
314 cam.set_fov(lerp(cam.fov, FOV, delta * 8))
315 if stamina_delay >= 0:
316 stamina_delay -= 0.1
317 sprint_enabled = true
318 elif Globals.stamina <= 100:
319 if velocity.x == 0:
320 Globals.stamina += stamina_regen_speed * 2
321 else:
322 Globals.stamina += stamina_regen_speed
323 elif Globals.stamina >= 100 && Globals.mana < 100:
324 if velocity.x == 0:
325 Globals.mana += mana_regen_speed * 2
326 else:
327 Globals.mana += mana_regen_speed
328 get_node("HUD/Control/ManaBar").value = Globals.mana
329 get_node("HUD/Control/StaminaBar").value = Globals.stamina
330
331func can_sprint() -> bool:
332 return (sprint_enabled and is_on_floor() and _is_sprinting_input and move_axis.x >= 0.5)
333
334func check_wall() -> void:
335 for wallray in $WallCheck.get_children():
336 var wall : RayCast = wallray
337 if wall.is_colliding():
338 wall_collide = true
339 else:
340 wall_collide = false
341
342func check_foot() -> void:
343 for footray in $FootCheck.get_children():
344 var foot : RayCast = footray
345 if foot.is_colliding():
346 foot_collide = true
347 if wall_collide == false:
348 print ("stepup")
349 velocity.y = jump_height
350 snap = Vector3.ZERO
351 else:
352 foot_collide = false
353
Note: See TracBrowser for help on using the repository browser.