184 lines
5.4 KiB
GDScript
184 lines
5.4 KiB
GDScript
extends Node3D
|
|
|
|
const WEAPON_SCENE = preload("res://entities/Weapon.scn")
|
|
|
|
@onready var player_root = get_node("../../..")
|
|
@onready var raycast = get_node("../Camera3D/AimCast") as RayCast3D
|
|
#@onready var crosshair = $Crosshair
|
|
|
|
var ALL_WEAPONS = []
|
|
var weapons = []
|
|
|
|
var current_weapon_index = 0
|
|
var current_weapon = null
|
|
|
|
var mouse_mov : Vector3
|
|
var sway_lerp = 5
|
|
@onready var game = get_node("/root/Game") as Game
|
|
|
|
func _ready():
|
|
Init_Config(game.weapon_config)
|
|
if not player_root.is_local_authority():
|
|
for w_name in game.init_config.get_value("PLAYER", "starting_weapons"):
|
|
GiveWeapon(w_name)
|
|
|
|
func set_weapons():
|
|
for w_name in game.init_config.get_value("PLAYER", "starting_weapons"):
|
|
rpc("GiveWeapon",w_name)
|
|
|
|
@rpc(call_local, any_peer)
|
|
func GiveWeapon(weapon_name):
|
|
for i in ALL_WEAPONS.size():
|
|
if(ALL_WEAPONS[i].name != weapon_name):
|
|
continue
|
|
if(weapons.has(i)):
|
|
return
|
|
|
|
weapons.append(i)
|
|
if(current_weapon == null):
|
|
rpc("ChangeWeapon", ((posmod(current_weapon_index, weapons.size()))))
|
|
return
|
|
|
|
@rpc(call_local, any_peer)
|
|
func TakeWeapon(weapon_name):
|
|
for i in ALL_WEAPONS.size():
|
|
if(ALL_WEAPONS[i].name != weapon_name):
|
|
continue
|
|
weapons.erase(i)
|
|
if(current_weapon == ALL_WEAPONS[i]):
|
|
rpc("ChangeWeapon", ((posmod(current_weapon_index, weapons.size()))))
|
|
|
|
func _input(event):
|
|
if not player_root.is_local_authority():
|
|
return
|
|
if event is InputEventMouseMotion:
|
|
mouse_mov.y = clampf(-event.relative.x, -0.1, 0.1)
|
|
mouse_mov.x = clampf(event.relative.y, -0.1, 0.1)
|
|
if event is InputEventKey and event.is_pressed():
|
|
if event.keycode == KEY_T:
|
|
rpc("GiveWeapon","CHAINSAW")
|
|
|
|
func _unhandled_input(_event):
|
|
if not player_root.is_local_authority():
|
|
return
|
|
|
|
if(weapons.size() == 0):
|
|
return
|
|
|
|
if weapons.size() > 1 && Input.is_action_just_released("wheel_up"):
|
|
rpc("ChangeWeapon", (posmod((current_weapon_index + 1),weapons.size())))
|
|
if weapons.size() > 1 && Input.is_action_just_released("wheel_down"):
|
|
rpc("ChangeWeapon", (posmod((current_weapon_index - 1),weapons.size())))
|
|
|
|
if Input.is_action_just_pressed("reload"):
|
|
current_weapon.Reload()
|
|
@rpc(call_local, any_peer)
|
|
func ChangeWeapon(i):
|
|
if(current_weapon):
|
|
current_weapon.hide()
|
|
|
|
if(weapons.size() == 0):
|
|
current_weapon = null
|
|
return
|
|
|
|
current_weapon_index = i
|
|
var w_index = weapons[current_weapon_index]
|
|
current_weapon = ALL_WEAPONS[w_index]
|
|
current_weapon.show()
|
|
current_weapon.init()
|
|
raycast.target_position.z = -current_weapon.RAY_LEN
|
|
|
|
var time = 0
|
|
|
|
func _process(delta):
|
|
if not player_root.is_local_authority():
|
|
return
|
|
if(current_weapon == null):
|
|
return
|
|
|
|
if Input.is_action_pressed("shoot") && current_weapon.Shoot():
|
|
if(current_weapon.HITSCAN):
|
|
HitScan()
|
|
else:
|
|
Projectile()
|
|
|
|
if Input.is_action_just_released("shoot"):
|
|
current_weapon.Release()
|
|
|
|
|
|
#SWAY
|
|
if mouse_mov != null && mouse_mov.length() > 0:
|
|
current_weapon.MODEL.rotation = current_weapon.MODEL.rotation.lerp(mouse_mov, sway_lerp * delta)
|
|
mouse_mov = Vector3.ZERO
|
|
else:
|
|
current_weapon.MODEL.rotation = current_weapon.MODEL.rotation.lerp(Vector3.ZERO, sway_lerp * delta)
|
|
|
|
#BOB
|
|
if player_root.velocity.length() > 0:
|
|
time += delta
|
|
var bobOscillate = sin(time * 4 * (2 * PI)) * 0.01
|
|
position.y = bobOscillate
|
|
bobOscillate = sin(time * 4 * (PI) + PI/4) * 0.015
|
|
position.x = bobOscillate
|
|
|
|
@rpc(call_local, any_peer)
|
|
func HitScan():
|
|
if(raycast.is_colliding()):
|
|
var target = raycast.get_collider()
|
|
print_debug("Hit target ", target.name, " with ", current_weapon.name, " ",current_weapon_index, ". Dealt damage ", current_weapon.DAMAGE)
|
|
if(raycast.get_collision_mask_value(10)):
|
|
if(target is Hitable):
|
|
target.Hit(current_weapon.DAMAGE)
|
|
|
|
|
|
func Projectile():
|
|
pass
|
|
|
|
|
|
func Init_Config(config):
|
|
for weapon in config.get_sections():
|
|
var root = WEAPON_SCENE.instantiate()
|
|
root.name = weapon
|
|
|
|
var model_path = config.get_value(weapon, "MODEL") as String
|
|
var weapon_model
|
|
if(model_path.ends_with(".glb") or model_path.ends_with(".gltf")):
|
|
weapon_model = Runtimeloader.load_gltf(model_path, root) as Node3D
|
|
elif(model_path.ends_with(".tscn") or model_path.ends_with(".scn")):
|
|
weapon_model = Runtimeloader.loadScene(model_path, root)
|
|
else:
|
|
printerr("Invalid file extension for "+ model_path)
|
|
continue
|
|
|
|
|
|
root.position = config.get_value(weapon, "HAND_POS")
|
|
root.rotation = config.get_value(weapon, "HAND_ROT")
|
|
root.hide()
|
|
add_child(root)
|
|
|
|
#Set Weapon Data
|
|
root.MELEE = config.get_value(weapon, "MELEE")
|
|
root.MAX_CLIP = config.get_value(weapon, "MAX_CLIP")
|
|
root.clip = root.MAX_CLIP
|
|
root.DAMAGE = config.get_value(weapon, "DAMAGE")
|
|
root.RPM = config.get_value(weapon, "RPM")
|
|
root.FIREMODE = config.get_value(weapon, "FIREMODE")
|
|
root.HITSCAN = config.get_value(weapon, "HITSCAN")
|
|
if(not root.HITSCAN):
|
|
print("Projectile stats")
|
|
else:
|
|
root.RAY_LEN = config.get_value(weapon, "RAY_LEN")
|
|
|
|
#Set Anim Data
|
|
root.MODEL = weapon_model
|
|
root.DRAW_POS = config.get_value(weapon, "DRAW_POS")
|
|
root.DRAW_ROT = config.get_value(weapon, "DRAW_ROT")
|
|
root.MOMENTUM = config.get_value(weapon, "MOMENTUM")
|
|
root.ANGULAR_MOMENTUM = config.get_value(weapon, "ANGULAR_MOMENTUM")
|
|
root.RECOIL_COOLDOWN = config.get_value(weapon, "RECOIL_COOLDOWN")
|
|
root.RELOAD_MOMENTUM = config.get_value(weapon, "RELOAD_MOMENTUM")
|
|
root.RELOAD_ANGULAR_MOMENTUM = config.get_value(weapon, "RELOAD_ANGULAR_MOMENTUM")
|
|
root.RELOAD_TIME = config.get_value(weapon, "RELOAD_TIME")
|
|
|
|
ALL_WEAPONS.append(root)
|