117 lines
2.7 KiB
GDScript
117 lines
2.7 KiB
GDScript
class_name Player extends CharacterBody3D
|
|
|
|
@export var speed : float = 10
|
|
@onready var body = $Body
|
|
@onready var data : PlayerData = $Data
|
|
|
|
var current_square : Vector3i
|
|
var detecting : bool
|
|
var detect_squares : Dictionary[Vector3i, bool] = {}
|
|
|
|
signal trap_cycled(trap_index)
|
|
signal trap_quantity_changed(trap_index, quantity)
|
|
signal trap_list_changed(traps)
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
var dir = Input.get_vector("west", "east", "north", "south")
|
|
dir = Vector3(dir.x, 0, dir.y)
|
|
if dir.length_squared() > 0:
|
|
body.look_at(body.global_position - dir)
|
|
velocity = speed * dir
|
|
if detecting:
|
|
velocity /= 3
|
|
if !is_on_floor():
|
|
velocity += get_gravity()
|
|
move_and_slide()
|
|
if detecting:
|
|
update_detecting()
|
|
|
|
if Input.is_action_just_pressed("left cycle trap"):
|
|
cycle_active_trap(-1)
|
|
if Input.is_action_just_pressed("right cycle trap"):
|
|
cycle_active_trap(1)
|
|
if Input.is_action_just_pressed("detect"):
|
|
start_detecting()
|
|
elif Input.is_action_just_released("detect"):
|
|
stop_detecting()
|
|
|
|
|
|
func update_detecting() -> void:
|
|
var new_square : Vector3i = (global_position - Vector3.ONE * .5).round()
|
|
if new_square == current_square:
|
|
return
|
|
current_square = new_square
|
|
var new_squares : Dictionary[Vector3i, bool] = {}
|
|
for i in range(-2, 3):
|
|
for j in range(-2, 3):
|
|
for k in range(-2, 2):
|
|
if abs(i) + abs(j) < 3:
|
|
var sq = current_square + Vector3i(i, k, j)
|
|
new_squares[sq] = true
|
|
|
|
|
|
for sq in detect_squares.keys():
|
|
if !new_squares.has(sq):
|
|
Game.level.detect_square(sq, false)
|
|
|
|
|
|
|
|
var remove_list = []
|
|
for sq in new_squares.keys():
|
|
if detect_squares.has(sq):
|
|
continue
|
|
if !Game.level.detect_square(sq, true):
|
|
remove_list.append(sq)
|
|
|
|
detect_squares = new_squares
|
|
for key in remove_list:
|
|
detect_squares.erase(key)
|
|
|
|
|
|
|
|
|
|
|
|
func start_detecting() -> void:
|
|
detecting = true
|
|
current_square = (global_position - Vector3.ONE * .5).round()
|
|
detect_squares = {}
|
|
for i in range(-2, 3):
|
|
for j in range(-2, 3):
|
|
for k in range(-2, 2):
|
|
if abs(i) + abs(j) < 3:
|
|
var sq = current_square + Vector3i(i, k, j)
|
|
detect_squares[sq] = true
|
|
|
|
var remove_list = []
|
|
|
|
for sq in detect_squares.keys():
|
|
if !Game.level.detect_square(sq, true):
|
|
remove_list.append(sq)
|
|
|
|
for key in remove_list:
|
|
detect_squares.erase(key)
|
|
|
|
|
|
func stop_detecting() -> void:
|
|
detecting = false
|
|
for sq in detect_squares.keys():
|
|
Game.level.detect_square(sq, false)
|
|
detect_squares = {}
|
|
|
|
func setup(traps) -> void:
|
|
$Data.traps = traps
|
|
Game.setup_player(self)
|
|
|
|
func cycle_active_trap(dir) -> void:
|
|
var prev = data.active_trap
|
|
data.active_trap += dir
|
|
if data.active_trap < 0:
|
|
data.active_trap = 0
|
|
|
|
if data.active_trap >= len(data.traps):
|
|
data.active_trap = len(data.traps) - 1
|
|
|
|
if prev != data.active_trap:
|
|
trap_cycled.emit(data.active_trap)
|