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)