extends "res://scripts/player.gd"
|
|
|
|
var walls = []
|
|
var placing_wall_node
|
|
var is_placing_wall = false
|
|
|
|
const max_walls = 100
|
|
|
|
# --- Godot overrides ---
|
|
|
|
func _process(delta):
|
|
if is_network_master():
|
|
|
|
# We allow you to just click to place, without needing to press E
|
|
var place_wall = Input.is_action_just_pressed("hero_1_confirm_wall")
|
|
|
|
if Input.is_action_just_pressed("hero_1_place_wall") or (place_wall and not is_placing_wall):
|
|
# Press button twice to cancel
|
|
if is_placing_wall:
|
|
# We changed our mind, delete the placing wall
|
|
placing_wall_node.queue_free()
|
|
is_placing_wall = false
|
|
else:
|
|
# Make a floating placement wall
|
|
placing_wall_node = add_wall()
|
|
is_placing_wall = true
|
|
|
|
if Input.is_action_just_pressed("hero_1_remove_wall"):
|
|
var look_ray = get_node("TPCamera/Camera/Ray")
|
|
var removing = look_ray.get_collider()
|
|
var wall = walls.find(removing)
|
|
if wall != -1:
|
|
rpc("remove_wall", wall)
|
|
|
|
if is_placing_wall or place_wall:
|
|
position_wall(placing_wall_node)
|
|
|
|
if place_wall:
|
|
finalize_wall(placing_wall_node)
|
|
rpc("slave_place_wall", placing_wall_node.get_transform())
|
|
placing_wall_node = null
|
|
is_placing_wall = false
|
|
|
|
func _exit_tree():
|
|
clear_walls()
|
|
|
|
# --- Player overrides ---
|
|
|
|
func spawn():
|
|
.spawn()
|
|
clear_walls()
|
|
|
|
# --- Own ---
|
|
|
|
# Find the point we're looking at, and put the wall there
|
|
func position_wall(wall):
|
|
var aim = get_node("Yaw/Pitch").get_global_transform().basis
|
|
var look_ray = get_node("TPCamera/Camera/Ray")
|
|
var pos = look_ray.get_collision_point()
|
|
wall.set_translation(pos)
|
|
var normal = look_ray.get_collision_normal()
|
|
var towards = normal + pos
|
|
var up = aim[2] # Wall should be horizontal to my view
|
|
# This helps nearly horizontal walls be easier to make flat
|
|
# We have two methods I'm deciding between
|
|
var use_method_two = true
|
|
if not use_method_two:
|
|
# Method one: only allow horizontal or vertical, based on whether the surface faces you
|
|
var wall_wall_margin = 0.75
|
|
if normal.dot(Vector3(0,1,0)) < wall_wall_margin:
|
|
var margin = 0.8
|
|
if up.dot(normal) > margin: # The wall is facing us
|
|
# We want flat
|
|
up = Vector3(0,1,0)
|
|
else:
|
|
# We want straight
|
|
up.y = 0
|
|
else:
|
|
# Method two: Make y more aggressive than other dimensions
|
|
up.y = 3 * tanh(up.y)
|
|
up = up.normalized()
|
|
wall.look_at(towards, up)
|
|
|
|
func clear_walls():
|
|
for wall in walls:
|
|
wall.queue_free()
|
|
walls = []
|
|
|
|
slave func slave_place_wall(tf):
|
|
var wall = add_wall()
|
|
finalize_wall(wall, tf)
|
|
|
|
sync func remove_wall(index):
|
|
walls[index].queue_free()
|
|
walls.remove(index)
|
|
|
|
# Creates wall, adds to world, and returns the node
|
|
func add_wall():
|
|
var wall = preload("res://scenes/wall.tscn").instance()
|
|
var friendly = player_info.is_right_team == master_player.player_info.is_right_team
|
|
var color = friend_color if friendly else enemy_color
|
|
get_node("/root/Level").add_child(wall)
|
|
wall.init(self, color)
|
|
return wall
|
|
|
|
func finalize_wall(wall, tf=null):
|
|
if tf:
|
|
wall.set_transform(tf)
|
|
wall.place()
|
|
# Remember this wall, and return to non-placing state
|
|
# We need to do this even as slave, because we keep track of the count
|
|
walls.append(wall)
|
|
check_wall_count()
|
|
|
|
func check_wall_count():
|
|
# If we've made max_walls, remove the first we made
|
|
if walls.size() > max_walls:
|
|
walls[0].queue_free()
|
|
walls.pop_front()
|
|
# When placing, make the about-to-disappear wall translucent
|
|
if walls.size() >= max_walls:
|
|
walls[0].make_last()
|
|
|