Initial commit

This commit is contained in:
2026-01-21 23:51:53 +01:00
commit 60b208fee0
1703 changed files with 100223 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
extends Area3D
class_name HitBox
@export var active: bool = false
var attack: Attack
func _ready() -> void:
monitorable = false
func _process(delta: float) -> void:
if !attack: return
var boxesHurt: Array[HurtBox]
for area in get_overlapping_areas():
if area is HurtBox:
boxesHurt.push_back(area)
for box in boxesHurt:
box.hit(attack)

View File

@@ -0,0 +1 @@
uid://c4bkcld6mpuj7

View File

@@ -0,0 +1,10 @@
extends Area3D
class_name HurtBox
signal hitTaken(attack: Attack)
func _ready() -> void:
monitoring = false
func hit(attack: Attack) -> void: ##Emits hitTaken signal to indicate the actor has been hit by an attack
hitTaken.emit(attack)

View File

@@ -0,0 +1 @@
uid://b7kjt28lv4p1h

View File

@@ -0,0 +1,5 @@
extends Object
class_name Attack
var damage: float = 0.0
var trauma: float = 0.0

View File

@@ -0,0 +1 @@
uid://vj6t63oapvo4

View File

@@ -0,0 +1,19 @@
extends Node
class_name EnemyState
signal Transitioned(state: EnemyState, new_state_name: String)
var enemy_ref: BaseEnemy
func Enter() -> void:
pass
func Exit() -> void:
pass
func Update(_delta: float) -> void:
pass
func Physics_Update(_delta: float) -> void:
pass
#Transition State by calling Transitioned.emit(self, "name of other state")

View File

@@ -0,0 +1 @@
uid://dvg03ta13bj84

View File

@@ -0,0 +1,46 @@
extends Node
class_name EnemyStateMachiene
@export var initial_state: EnemyState
@export var enemy_ref: BaseEnemy
var current_state: EnemyState
var states: Dictionary = {}
func _ready() -> void:
for child in get_children():
if child is EnemyState:
states[child.name.to_lower()] = child
child.Transitioned.connect(on_child_transition)
child.enemy_ref = enemy_ref
if initial_state:
initial_state.Enter()
current_state = initial_state
func _process(delta: float) -> void:
if not is_multiplayer_authority(): return
if current_state:
current_state.Update(delta)
func _physics_process(delta: float) -> void:
if not is_multiplayer_authority(): return
if current_state:
current_state.Physics_Update(delta)
func on_child_transition(state: EnemyState, new_state_name: String):
if state != current_state:
return
var new_state = states.get(new_state_name.to_lower())
if !new_state:
return
if current_state:
current_state.Exit()
new_state.Enter()
current_state = new_state

View File

@@ -0,0 +1 @@
uid://biujgdpsjonmi

View File

@@ -0,0 +1,24 @@
extends EnemyState
const maxFollowDistance: float = 12.5
func Enter():
if enemy_ref.spiderLight:
enemy_ref.spiderLight.visible = true
if enemy_ref.hitBoxTeeth:
enemy_ref.hitBoxTeeth.active = true
func Exit():
enemy_ref.can_move = true
if enemy_ref.spiderLight:
enemy_ref.spiderLight.visible = false
if enemy_ref.hitBoxTeeth:
enemy_ref.hitBoxTeeth.active = false
func Update(_delta: float):
if enemy_ref.closestPlayer:
if enemy_ref.distanceClosestPlayer > maxFollowDistance:
Transitioned.emit(self, "Wander")
enemy_ref.can_move = enemy_ref.distanceClosestPlayer > 2
enemy_ref.pathfind(enemy_ref.closestPlayerGridPosition)

View File

@@ -0,0 +1 @@
uid://dc8gd7klgokxu

View File

@@ -0,0 +1,18 @@
extends EnemyState
var rng = RandomNumberGenerator.new()
var arrived: bool = true
var wanderGoal: Vector2
const wanderSpeed := 2.3
const wanderRange: float = 20
const detectionRange: float = 8
func Update(_delta: float) -> void:
if enemy_ref.distanceClosestPlayer < detectionRange:
Transitioned.emit(self,"FollowPlayer")
if arrived:
wanderGoal = Vector2(rng.randf_range(-wanderRange,wanderRange),rng.randf_range(-wanderRange,wanderRange))
arrived = false
enemy_ref.pathfind(wanderGoal,wanderSpeed)
if enemy_ref.pointPath.size() <= 2:
arrived = true

View File

@@ -0,0 +1 @@
uid://dyhvo1kt3kb5e

View File

@@ -0,0 +1,36 @@
extends Marker3D
class_name SpiderIKTarget
@export var step_target: Marker3D
@export var step_distance: float = 1.75
@export var tween_duration: float = 0.45
@export var adjacent_target: SpiderIKTarget
@export var opposite_target: SpiderIKTarget
var spider_body: CharacterBody3D
var is_stepping := false
var can_step : = false
func _ready() -> void:
top_level = true
spider_body = get_parent()
step_distance = step_distance * owner.scale.x
tween_duration = tween_duration * owner.scale.x
func _process(_delta: float) -> void:
if !is_stepping && !adjacent_target.is_stepping && abs(self.global_position.distance_to(step_target.global_position)) >= step_distance:
step()
opposite_target.step()
func step():
var target_pos = step_target.global_position
var half_way = (global_position + step_target.global_position) /2
is_stepping = true
var t = create_tween()
t.tween_property(self,"global_position",half_way + owner.basis.y-Vector3(0,0.45,0)*owner.scale.x,tween_duration / spider_body.velocity.length())
t.tween_property(self,"global_position", target_pos,tween_duration / spider_body.velocity.length())
t.tween_callback(func(): is_stepping = false)

View File

@@ -0,0 +1 @@
uid://b7nx043bbja0u

View File

@@ -0,0 +1,24 @@
extends BaseEnemy
class_name SpiderEnemy
var closestPlayerGridPosition: Vector2
var distanceClosestPlayer: float
var closestPlayer: PlayerCharacter
@onready var spiderLight := $SpiderLight
@onready var hitBoxTeeth := $HitBox
var attackTeeth: Attack = Attack.new()
func _ready() -> void:
attackTeeth.damage = 25.0
attackTeeth.trauma = 0.65
hitBoxTeeth.attack = attackTeeth
func _process(delta: float) -> void:
closestPlayer = getClosestPlayerOnPathGrid()
if !closestPlayer: return
closestPlayerGridPosition = Vector2(closestPlayer.global_position.x,closestPlayer.global_position.z)
distanceClosestPlayer = (closestPlayer.global_position - global_position).length()
baseEnemyIdle(delta)
func _physics_process(delta: float) -> void:
baseEnemyPhysics(delta)

View File

@@ -0,0 +1 @@
uid://drdkwkfj4rnb8

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
extends Skeleton3D
var bones: Array[int] = [6,11,16,21,26,31,36,41]
var boneRotations: Array[Quaternion]
func _ready() -> void:
for bone in bones:
boneRotations.push_back(get_bone_pose_rotation(bone))
func _process(delta: float) -> void:
var x = 0
for bone in bones:
set_bone_pose(bone, boneRotations[x])
x += 1

View File

@@ -0,0 +1 @@
uid://by5f8425fuu8q

View File

@@ -0,0 +1,12 @@
extends RayCast3D
@export var step_target: Marker3D
func _ready() -> void:
step_target.top_level = true
func _physics_process(_delta: float) -> void:
var col_point = get_collision_point()
if col_point:
step_target.global_position = col_point + Vector3(0,0.78,0)*owner.scale.x

View File

@@ -0,0 +1 @@
uid://bb8gorx3134vp

View File

@@ -0,0 +1,14 @@
extends Node3D
@export var offset: float = 10
@onready var parent = get_parent_node_3d()
@onready var previous_position = parent.global_position
func _ready() -> void:
offset = offset*owner.scale.x
func _process(delta: float) -> void:
var velovity : Vector3 = (owner.global_position - previous_position) * delta
global_position = owner.global_position + velovity.normalized() * offset
previous_position = owner.global_position

View File

@@ -0,0 +1 @@
uid://bodwd2ercb5e2

View File

@@ -0,0 +1,104 @@
extends CharacterBody3D
class_name BaseEnemy
@export var turn_speed: float = PI/2 ##how fast the enemy turns into the direction it is moving
@export var turn_to_move := true ##Aktivates/ Deaktivates turn to move direction logic
@export var can_move := true ##Controls weather move and slide gets executed on process
@export var base_speed := 3.5 ##Base movespeed of the enemy
@export var decelleration := 0.5 ## How much the enemy decellerates each frame
@export var max_speed := 10.0
@export var min_speed := 0.05
@export var pathfindLeniency := 0.25 ## How close this enemy needs to be to a pathfinding node to pathfind to the next node
var health: float = 100.0 ##If health reaches 0, the enemy dies
var momentum := Vector3(0,0,0) ##Controlls the speed of the player
var lastMoveDirection:= Vector3(0,0,0) ##Which direction the enemy moved last, used for rotation
var directionMovePathfind: Vector2 ##
@export var mapLogicRef: MapLogic
var pointPath: PackedVector2Array ##Path used for Pathfinding
var pathfindingGoalLocation: Vector2 = Vector2(0,0)
func _ready() -> void:
mapLogicRef = get_parent_node_3d() # Might need to change
func baseEnemyIdle(delta: float) -> void:
if health <= 0.0:
die()
if turn_to_move:
rotation.y = rotate_toward(rotation.y,atan2(lastMoveDirection.x,lastMoveDirection.z), turn_speed*delta)
if momentum.length() <= min_speed:
momentum = Vector3(0,0,0)
momentum -= momentum.normalized()*delta*decelleration*momentum.length() #decelerate
func baseEnemyPhysics(delta:float) -> void:
if can_move:
velocity = momentum
move_and_slide()
func createPath(pos1: Vector2,pos2: Vector2) -> PackedVector2Array:
if !mapLogicRef:
return PackedVector2Array([])
if !mapLogicRef.astar:
return PackedVector2Array([])
var closestPointPos1: int = mapLogicRef.astar.get_closest_point(pos1)
var closestPointPos2: int = mapLogicRef.astar.get_closest_point(pos2)
return mapLogicRef.astar.get_point_path(closestPointPos1,closestPointPos2)
func updatePointPath() -> void:
pointPath = createPath(Vector2(global_position.x,global_position.z),pathfindingGoalLocation)
func pathfind(goal_pos: Vector2,speed: float = 0.0) -> void:
pathfindingGoalLocation = goal_pos
if (goal_pos - Vector2(global_position.x,global_position.z)).length() <= pathfindLeniency:
return
if pointPath.is_empty():
updatePointPath()
if pointPath:
directionMovePathfind = pointPath[0] - Vector2(global_position.x,global_position.z)
move(Vector3(directionMovePathfind.x,0,directionMovePathfind.y),speed)
if directionMovePathfind.length() <= pathfindLeniency:
updatePointPath()
if !pointPath.is_empty():
pointPath.remove_at(0)
func clampVectorLength(Vector: Vector3, minLength: float, maxLength: float) -> Vector3:
#scales Vector up/ down to the max/ min length givin. If the Vector has a length of 0 it will be returned without being scaled.
if Vector.length() == 0: return Vector
if Vector.length() < minLength:
return Vector * minLength / Vector.length()
elif Vector.length() > maxLength:
return Vector * maxLength / Vector.length()
return Vector
func getClosestPlayerOnPathGrid() -> PlayerCharacter:
if !Multiplayer.alivePlayerDict:
return
var shortestPath: PackedVector2Array
var closestPlayer: PlayerCharacter
for player in Multiplayer.alivePlayerDict.values():
var path := createPath(Vector2(self.global_position.x,self.global_position.z),Vector2(player.global_position.x,player.global_position.z))
if !shortestPath.size():
shortestPath = path
closestPlayer = player
else:
if shortestPath.size() > path.size():
shortestPath = path
closestPlayer = player
return closestPlayer
func move(direction: Vector3, speed: float = 0.0) -> void: ##add momentum in direction, depending on speed, if speed parameter is left empty (or == 0) the function will use the base speed of the enemy
if speed:
momentum = clampVectorLength(direction.normalized()*speed,min_speed,max_speed)
else:
momentum = clampVectorLength(direction.normalized()*base_speed,min_speed,max_speed)
lastMoveDirection = momentum
func die() -> void:
queue_free()

View File

@@ -0,0 +1 @@
uid://clrqxvcw8k08m

59
actors/Player/Hud.tscn Normal file
View File

@@ -0,0 +1,59 @@
[gd_scene load_steps=5 format=3 uid="uid://mv0dgwdlha3m"]
[ext_resource type="Texture2D" uid="uid://d0idf4f20sbiy" path="res://assets/2D/Back.png" id="1_05nb1"]
[ext_resource type="Texture2D" uid="uid://dlnfrfnyh16sb" path="res://assets/2D/Progress.png" id="2_4v4de"]
[ext_resource type="Texture2D" uid="uid://c1401tikex5vt" path="res://assets/2D/Viser.png" id="3_gwlmi"]
[ext_resource type="Texture2D" uid="uid://csbtt12ohhvec" path="res://assets/2D/GreenCross.png" id="4_je5l8"]
[node name="Hud" type="Control"]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="TextureProgressBar" type="TextureProgressBar" parent="."]
z_index = 2
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -101.25
offset_top = -129.0
offset_right = 101.25
grow_horizontal = 2
grow_vertical = 0
value = 100.0
nine_patch_stretch = true
texture_under = ExtResource("1_05nb1")
texture_progress = ExtResource("2_4v4de")
[node name="Viser" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
offset_top = -9.0
offset_bottom = 15.0
grow_horizontal = 2
grow_vertical = 2
texture = ExtResource("3_gwlmi")
expand_mode = 2
[node name="InteractCross" type="TextureRect" parent="."]
layout_mode = 1
anchors_preset = 7
anchor_left = 0.5
anchor_top = 1.0
anchor_right = 0.5
anchor_bottom = 1.0
offset_left = -160.0
offset_top = -120.0
offset_right = -120.0
offset_bottom = -80.0
grow_horizontal = 2
grow_vertical = 0
texture = ExtResource("4_je5l8")

View File

@@ -0,0 +1,12 @@
[gd_scene load_steps=2 format=3 uid="uid://cas4ts0b08qd6"]
[ext_resource type="Script" uid="uid://rywjg37p7ush" path="res://actors/Player/spectator.gd" id="1_ibavb"]
[node name="Spectator" type="Node3D"]
script = ExtResource("1_ibavb")
[node name="SpringArm3D" type="SpringArm3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 0.888617, 0.45865, 0, -0.45865, 0.888617, 0, 0.543102, 0)
spring_length = 1.8
[node name="Camera3D" type="Camera3D" parent="SpringArm3D"]

View File

@@ -0,0 +1,351 @@
extends CharacterBody3D
class_name PlayerCharacter
var aceleration: float = 4.32 #Current aceleration
var maxSpeed: float = 6.2 #Maximum Speed
var sprintSpeed: float = 3.34 #Additional Speed gained while Sprinting
var slowdownSpeedLimit: float = 0.8 #How fast the player can go when slowed
var gear: String = "neutral" #Weather the player is going forward, backward or standing still
var isMoving: bool = false
var slowed: bool = false
var momentum: float = 0
var newMoveDirection: Vector3 = Vector3(0,0,0)
var moveDirection: Vector3 = Vector3(0,0,0)
var deceleration: float = 5.56
var turnSpeed: float = PI/2 #Speed at wich body turn sideways
var handling: float = 0.67
var facingDirection = Vector2(0,1) #Where the legs are facing
var sprinting = false #While Player is sprinting
var sprintEnergy: float = 100 #Energy used for Sprinting
var sprintEnergyInitialUse: float = 4.5 #How much % sprint energy is used immediatly when initiating a sprint
var sprintEnergyUse: float = 17.5 #How much % energy is used per 1 sec of sprint
var sprintEnergyGain: float = 30 #How much % energy is gained per 1 sec of recovery
var maxDriftAngle = 0.12 #Quaternion(0,0,0.06,0.998).normalized() #How much the playesr turns to the side while drifting (radians)
var rightLeftLean: float = 0.0 #How much the player leans right or left from -1 to 1 with negative numbers being left and 0 being no lean
var currentControlState: int = 0
enum controls {DEFAULT,STANDARD_MINIGAME}
var health: float = 100.0
var invulnerable: bool = false
var alive: bool = true
@onready var camera: Camera3D = $CameraPivot/Camera3D
@onready var cameraPivot: Marker3D = $CameraPivot
@onready var flashlight: SpotLight3D = $CameraPivot/Camera3D/flashlight
@onready var backlightR := $pivot/BodyPivot/body/BacklightR
@onready var backlightL := $pivot/BodyPivot/body/BacklightL
@onready var pivot: = $pivot
@onready var headPivot: = $pivot/HeadBinoculars/HeadPivot
@onready var headBinoculars: = $pivot/HeadBinoculars
@onready var legs := $pivot/BodyPivot/CaterpillarLegs
@onready var body: = $pivot/BodyPivot/body
@onready var hud = $/root/Main/Hud
@onready var interactCross := $/root/Main/Hud/InteractCross
@onready var sprintBar := $/root/Main/Hud/TextureProgressBar
@onready var grabRaycast: = $CameraPivot/Camera3D/GrabDetector
@onready var grabPivot: = $pivot/BodyPivot/body/GrabPivot
@onready var grabBox: = $pivot/BodyPivot/body/GrabBox
var grabbedObject: GrabableObject
@onready var interactRaycast = $CameraPivot/Camera3D/InteractDetector
@onready var VoiceChat = $VoiceChat
@onready var bodyPivot: Node3D = $pivot/BodyPivot
var mouseSensetivity := 0.1 #How much mouse movement affects ingame camera movement
var spectatorScene: PackedScene = preload("res://actors/Player/Spectator.tscn")
var spectatorParent: Node3D
var mapLogic: MapLogic
#Camera Shake Stuff
var traumaReductionRate:float = 0.34
var trauma: float = 0
@export var maxX = 12
@export var maxY = 12
@export var maxZ = 7
@export var shakeIntensety : float = 7.0
var time: float = 0
@export var noise: Noise
var noiseSpeed: float = 50
var initialRotation = rotation_degrees as Vector3
# Camera Shake Stuff end
func _enter_tree() -> void:
set_multiplayer_authority(name.to_int())
if is_multiplayer_authority():
$CameraPivot/Camera3D.make_current()
$pivot/HeadBinoculars.hide()
$/root/Main/Hud/TextureProgressBar.show()
func _ready() -> void:
Multiplayer.player_ready.emit(int(name))
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
mapLogic = Multiplayer.currentMapLogic
spectatorParent = get_node("/root/Main/Spectators")
if mapLogic:
mapLogic.onCollision.connect(onCollision)
if is_multiplayer_authority():
position.y += 2
return
func _process(delta: float) -> void:
if not is_multiplayer_authority(): return
if not alive: return
if invulnerable and trauma == 0.0:
invulnerable = false
if Input.is_action_just_pressed("debug"): ##Debug
die()
match currentControlState:
controls.DEFAULT:
regularControlsIdle(delta)
controls.STANDARD_MINIGAME:
standardMinigameControlsIdle(delta)
func _physics_process(delta: float) -> void:
if not is_multiplayer_authority(): return
if not alive: return
match currentControlState:
controls.DEFAULT:
regularControlsPhysics(delta)
controls.STANDARD_MINIGAME:
endOfPhysicsCleanup(delta)
func standardMinigameControlsIdle(_delta:float):
if Input.is_action_just_pressed("moveDown") or Input.is_action_just_pressed("interact"):
currentControlState = controls.DEFAULT
func regularControlsIdle(_delta:float):
#Interacting Logic
var InteractCollider: InteractBox = interactRaycast.get_collider()
if InteractCollider and Input.is_action_just_pressed("interact"):
InteractCollider.playerRef = self
InteractCollider.interact()
if InteractCollider.type == "minigame":
currentControlState = controls.STANDARD_MINIGAME
momentum = 0
#Grabbing Logic
var GrabCollider: GrabBox = grabRaycast.get_collider()
var grabBoxCollider: Array[Area3D] = grabBox.get_overlapping_areas()
if(grabBoxCollider and Input.is_action_just_pressed("interact") and !grabbedObject):
if grabBoxCollider.has(GrabCollider): #If the player is looking at an object and it is in the grab box
grabbedObject = GrabCollider.grab()
else:
#If the player is not looking at an object, grab the closet one in the grab box
var closestObj: GrabBox
var distanceToClosestObj: float = 100
for grabObj in grabBoxCollider:
if (getDistance(self,grabObj) < distanceToClosestObj):
closestObj = grabObj
distanceToClosestObj = getDistance(self, grabObj)
grabbedObject = closestObj.grab()
if InteractCollider or grabBoxCollider:
interactCross.show()
else:
interactCross.hide()
if Input.is_action_just_pressed("flashlight"):
flashlight.visible = !flashlight.visible
if grabbedObject:
grabbedObject.global_position = grabPivot.global_position# + grabbedObject.grabPositionPositionOffset
grabbedObject.rotation = grabPivot.global_rotation + grabbedObject.grabPositionRotationOffset
if grabbedObject.grabBox.heavy: slowed = true
if Input.is_action_just_pressed("drop"):
grabbedObject.release.rpc()
grabbedObject = null
slowed = false
momentum = 0
if Input.is_action_just_pressed("throw"):
grabbedObject.release.rpc()
grabbedObject.throw.rpc_id(1,facingDirection.x,facingDirection.y,camera.rotation.x)
grabbedObject = null
slowed = false
momentum = 0
func regularControlsPhysics(delta: float):
isMoving = false
#Drain energy on sprint start to prevent the player from pressing sprint every other frame to get infinity energy
if Input.is_action_just_pressed("Sprint"):
sprintEnergy = clamp(sprintEnergy - sprintEnergyInitialUse, -(sprintEnergyInitialUse*2) , 100)
# Rest of sprint energy logic
if Input.is_action_pressed("Sprint"):
sprintEnergy = clamp(sprintEnergy - sprintEnergyUse * delta, 0 , 100) # Drain sprint when holding the button
if sprintEnergy > 0:
sprinting = true
else:
sprinting = false
else:
sprinting = false
sprintEnergy = clamp(sprintEnergy + sprintEnergyGain * delta, -(sprintEnergyInitialUse*2) , 100) # Gain sprint when not holding the button
if not is_on_floor(): velocity += get_gravity()
newMoveDirection = Vector3(0,0,0)
# Set moveDirection based on input
if Input.is_action_pressed("moveUp") and !Input.is_action_pressed("moveDown"):
isMoving = true
newMoveDirection += Vector3(facingDirection.x,0,facingDirection.y)
if Input.is_action_pressed("moveRight") and !Input.is_action_pressed("moveLeft"):
newMoveDirection -= Vector3(facingDirection.x,0,facingDirection.y).rotated(up_direction,PI/2)
if Input.is_action_pressed("moveLeft") and !Input.is_action_pressed("moveRight"):
newMoveDirection += Vector3(facingDirection.x,0,facingDirection.y).rotated(up_direction,PI/2)
if Input.is_action_pressed("moveDown") and !Input.is_action_pressed("moveUp"):
isMoving = true
newMoveDirection += Vector3(facingDirection.x,0,facingDirection.y)
showBacklights()
else:
hideBacklights()
if newMoveDirection != Vector3(0,0,0):
moveDirection = clampVectorLength(moveDirection + newMoveDirection*delta,0,handling)
endOfPhysicsCleanup(delta)
#Momentum stuff
if isMoving:
if Input.is_action_pressed("moveDown"):
momentum = clamp(momentum + -aceleration*2 * delta,-maxSpeed/2,maxSpeed)
else:
momentum = clamp(momentum + aceleration * delta,-maxSpeed/2,maxSpeed)
else:
if momentum >= 0:
momentum = clamp(momentum - deceleration * delta,-maxSpeed/2,maxSpeed)
if momentum < 0:
momentum = clamp(momentum + deceleration * delta,-maxSpeed/2,maxSpeed)
if sprinting and isMoving and !Input.is_action_pressed("moveDown"):
velocity = clampVectorLength(moveDirection.normalized() * (momentum + sprintSpeed),0,maxSpeed+sprintSpeed)
else:
velocity = clampVectorLength(moveDirection.normalized() * momentum,0,maxSpeed)
bodyPivot.rotation.y = rotate_toward(bodyPivot.rotation.y, -atan2(moveDirection.z,moveDirection.x) + PI/2,delta*turnSpeed)
#print(facingDirection.length())
move_and_slide() #applies movement
func endOfPhysicsCleanup(delta: float):
trauma = max(trauma-delta*traumaReductionRate,0)
time += delta
rotation_degrees.x = initialRotation.x + maxX * getShakeIntensity() * getNoiseFromSeed(343)
rotation_degrees.y = initialRotation.y + maxY * getShakeIntensity() * getNoiseFromSeed(123)
rotation_degrees.z = initialRotation.z + maxZ * getShakeIntensity() * getNoiseFromSeed(234)
#Rotate head based on camera movement
headPivot.rotation.y = cameraPivot.rotation.y
headPivot.rotation.x = -camera.rotation.x
if trauma == 0.0:
headPivot.rotation.z = 0.0
headBinoculars.rotation.z = 0.0
sprintBar.value = sprintEnergy
func showBacklights() -> void:
backlightL.show()
backlightR.show()
func hideBacklights() -> void:
backlightL.hide()
backlightR.hide()
func useSprintEnergy(delta: float):
sprintEnergy = clamp(sprintEnergy - sprintEnergyUse * delta, 0, 100)
func setRightLeftLean(direction: int, strength: float, delta: float) -> void:
if direction > 0 and rightLeftLean < 0:
rightLeftLean = 0
elif direction < 0 and rightLeftLean > 0:
rightLeftLean = 0
rightLeftLean = clamp(rightLeftLean + strength * delta * direction,-1,1)
func getAngleBetweenVectors(a: Vector3, b: Vector3) -> float:
if a.length() == 0 or b. length() == 0:
return 0
return acos((a.dot(b)/(a.length()*b.length())))
func getDistance(a: Node3D, b: Node3D) -> float:
var distanceVector: Vector3
distanceVector = b.global_position - a.global_position
return distanceVector.length()
func clampVectorLength(Vector: Vector3, minLength: float, maxLength: float) -> Vector3:
#scales Vector up/ down to the max/ min length givin. If the Vector has a length of 0 it will be returned without being scaled.
if Vector.length() == 0: return Vector
if Vector.length() < minLength:
return Vector * minLength / Vector.length()
elif Vector.length() > maxLength:
return Vector * maxLength / Vector.length()
return Vector
func onCollision() -> void:
trauma = 1
func addTrauma(traumaAmount: float):
trauma = clamp(trauma+traumaAmount,0,1)
func getShakeIntensity() -> float:
return shakeIntensety * trauma * trauma
func getNoiseFromSeed(seed_: int) -> float:
noise.seed = seed_
return noise.get_noise_1d(time*noiseSpeed)
func _input(event: InputEvent) -> void: #Camera movement with mouse
if event is InputEventMouseMotion && Input.mouse_mode == 2:
camera.rotation.x -= clamp(deg_to_rad(event.relative.y * mouseSensetivity),-180,180)
cameraPivot.rotation.y -= deg_to_rad(event.relative.x * mouseSensetivity)
facingDirection = facingDirection.rotated(deg_to_rad(event.relative.x * mouseSensetivity))
camera.rotation_degrees.x = clamp(camera.rotation_degrees.x, -70, 70)
cameraPivot.rotation.z = 0
func _on_hurt_box_hit_taken(attack: Attack) -> void:
if invulnerable: return
trauma = attack.trauma
health -= attack.damage
if health <= 0.0:
die()
invulnerable = true
func die() -> void:
Multiplayer.alivePlayerDict.erase(int(name))
headBinoculars.show()
headPivot.position = Vector3(0,0.382,0.063)
headPivot.rotation = Vector3(0,0,0)
$"pivot/pivotRightLeg/pivotLeftLeg/body/Grabby Arms_L".rotation.x = deg_to_rad(90)
$"pivot/pivotRightLeg/pivotLeftLeg/body/Grabby Arms_R".rotation.x = deg_to_rad(90)
var spectator = spectatorScene.instantiate()
spectatorParent.add_child(spectator)
camera.current = false
alive = false

View File

@@ -0,0 +1 @@
uid://bbs5fa4ewvrwn

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
extends Node3D
var followTarget: Node3D
var followedPlayerIndex: int = 0
var mouseSensetivity: float = 0.1
func _ready() -> void:
activateCamera()
func _process(_delta: float) -> void:
updateFollowTarget()
if followTarget:
global_position = followTarget.global_position
func _input(event: InputEvent) -> void: #Camera movement with mouse
if event is InputEventMouseMotion && Input.mouse_mode == 2:
rotation.x = clampf(rotation.x - deg_to_rad(event.relative.y * mouseSensetivity),-PI/8,PI/4)
rotation.y -= deg_to_rad(event.relative.x * mouseSensetivity)
func updateFollowTarget() -> void:
if Input.is_action_just_pressed("throw"):
followedPlayerIndex += 1
if followedPlayerIndex >= Multiplayer.playerDict.size():
followedPlayerIndex = 0
followTarget = Multiplayer.playerDict.values()[followedPlayerIndex]
func activateCamera() -> void:
$SpringArm3D/Camera3D.current = true

View File

@@ -0,0 +1 @@
uid://rywjg37p7ush