Files
Scoom/scripts/player/Weapons.gd
2023-01-17 22:30:12 +01:00

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)