This commit is contained in:
2026-01-21 23:40:20 +01:00
commit d1f8068081
478 changed files with 24902 additions and 0 deletions

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