summaryrefslogtreecommitdiff
path: root/player.gd
blob: b45d0a083a1305b5b54ca396011fc0952ff64be9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
class_name Player
extends CharacterBody3D


var selection_block: MeshInstance3D
var selection_block_data: Block
var previous_looked_at_block_position: Vector3 = Vector3.ZERO

const SPEED = 5.0#10.0#20.0
const JUMP_VELOCITY = 5.0#10.0#20.0

var acc = 0


func _ready() -> void:
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	
	selection_block = MeshInstance3D.new()
	selection_block.visible = false
	selection_block.top_level = true
	selection_block.rotation = Vector3.ZERO
	selection_block.scale = Vector3(1.001, 1.001, 1.001)
	add_child(selection_block)
	selection_block_data = Block.new()
	selection_block_data.type = Block.Type.SELECTION


func _input(event: InputEvent) -> void:
	if event is InputEventMouse and event.is_pressed():
		Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	if event.is_action_pressed("mouse_exit"):
		Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
	
	if event is InputEventMouseMotion:
		$CameraAnchor.rotate_y(deg_to_rad(clamp(-event.relative.x * 0.25, -45, 45)))
		$CameraAnchor.rotate_object_local(Vector3(1,0,0), deg_to_rad(-event.relative.y * 0.25))
	
	if event.is_action_pressed("right_click"):
		if selection_block.visible:
			var point = selection_block.global_position + $CameraAnchor/Camera/RayCast3D.get_collision_normal()
			(get_tree().current_scene as World).add_block(point, $CanvasLayer/MarginContainer.active_type)
	
	if event.is_action_pressed("left_click"):
		if selection_block.visible:
			var point = selection_block.global_position
			var chunk_idx := Chunk.global_to_chunk(point)
			if Chunk.chunk_exists(chunk_idx.x, chunk_idx.y, chunk_idx.z):
				var chunk: Chunk = Chunk.chunks[chunk_idx.x][chunk_idx.y][chunk_idx.z]
				var block_chunk_idx := Chunk.global_to_chunk_block(point)
				chunk.remove_block(block_chunk_idx)


func _process(delta: float) -> void:
	if $CameraAnchor/Camera/RayCast3D.is_colliding():
		var collider = $CameraAnchor/Camera/RayCast3D.get_collider()
		if collider is not StaticBody3D:
			return
		
		var p = $CameraAnchor/Camera/RayCast3D.get_collision_point()
		var n = $CameraAnchor/Camera/RayCast3D.get_collision_normal()
		#var point = $CameraAnchor/Camera/RayCast3D.get_collision_point() - Vector3(1, 1, 1) - $CameraAnchor/Camera/RayCast3D.get_collision_normal()
		#point = $CameraAnchor/Camera/RayCast3D.get_collision_point() - Vector3(0.5, 0.5, 0.5) - $CameraAnchor/Camera/RayCast3D.get_collision_normal()
		var point = $CameraAnchor/Camera/RayCast3D.get_collision_point() - (
			$CameraAnchor/Camera/RayCast3D.get_collision_normal() if $CameraAnchor/Camera/RayCast3D.get_collision_normal() > Vector3.ZERO else Vector3.ZERO
		)
		#point = $CameraAnchor/Camera/RayCast3D.get_collision_point().snapped(Vector3(0.5, 0.5, 0.5))
		
		#var block_idx = floor(point)#floor(point / 2)
		#var chunk_idx = floor(point / 16)#floor(point / (16*2))
		#var block_chunk_idx = Vector3(
			#int(floor(point.x / 2)) % 16,
			#int(floor(point.y / 2)) % 16,
			#int(floor(point.z / 2)) % 16
		#)
		#var block_chunk_idx = block_idx - 16 * chunk_idx
		
		var chunk_idx := Chunk.global_to_chunk(point)
		var block_chunk_idx := Chunk.global_to_chunk_block(point)
		
		#acc += delta
		#if acc / 5 > 1.0:
			#acc = 0
			#print(block_chunk_idx)
			#print(chunk_idx)
		if Chunk.chunk_exists(chunk_idx.x, chunk_idx.y, chunk_idx.z):
			var chunk: Chunk = Chunk.chunks[chunk_idx.x][chunk_idx.y][chunk_idx.z]
			var block: Block = chunk.blocks[block_chunk_idx.x][block_chunk_idx.y][block_chunk_idx.z]
			selection_block.visible = true
			if previous_looked_at_block_position != block.position:
				update_selection_block(block.position)
				previous_looked_at_block_position = block.position
				#print(point, "==", block.position) #??
				#print(Block.Type.keys()[block.type])
	else:
		selection_block.visible = false


func _physics_process(delta: float) -> void:
	# Add the gravity.
	if not is_on_floor():
		velocity += get_gravity() * delta * 1.5

	# Handle jump.
	if Input.is_action_just_pressed("ui_accept") and is_on_floor():
		velocity.y = JUMP_VELOCITY

	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var input_dir := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	var direction := (
		(transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
			.rotated(Vector3(1, 0, 0), $CameraAnchor.rotation.x)
			.rotated(Vector3(0, 1, 0), $CameraAnchor.rotation.y)
			.rotated(Vector3(0, 0, 1), $CameraAnchor.rotation.z)
	)
	if direction:
		velocity.x = direction.x * SPEED
		velocity.z = direction.z * SPEED
	else:
		velocity.x = move_toward(velocity.x, 0, SPEED)
		velocity.z = move_toward(velocity.z, 0, SPEED)

	move_and_slide()


func update_selection_block(new_position: Vector3):
	var material := preload("res://new_shader_material_selection.tres")
	var st = SurfaceTool.new()
	st.begin(Mesh.PRIMITIVE_TRIANGLES)
	st.set_material(material)
	
	for face in Block.Face.values():
		selection_block_data.add_face(st, face)
	
	selection_block.global_position = new_position
	selection_block.mesh = st.commit()