source: Studio/Player.gd@ a89628a

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

Final version of step climbing. Fixed issue with sliding on slopes. Also setup Camera perspective button P to go from first to third person perspective

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