2021-06-18 01:43:10 +02:00
|
|
|
extends Node3D
|
2021-07-26 20:51:54 +02:00
|
|
|
#Hand Camera Head Player
|
2021-08-29 14:03:19 +02:00
|
|
|
@onready var main = get_tree().root.get_node("Main")
|
2021-09-11 16:32:38 +02:00
|
|
|
@onready var hud = main.get_node("HUD")
|
|
|
|
@onready var score_rank = hud.get_node("ScoreRank")
|
2021-07-26 20:51:54 +02:00
|
|
|
@onready var player = get_parent().get_parent().get_parent().get_parent()
|
2021-08-23 01:57:47 +02:00
|
|
|
@onready var camera = get_parent().get_parent()
|
2021-07-04 21:50:13 +02:00
|
|
|
@onready var ejector = find_node("Ejector")
|
|
|
|
@onready var muzzle = find_node("Muzzle")
|
|
|
|
|
|
|
|
var casing = preload("res://Assets/Weapons/Handgun/Casing.tscn")
|
2021-09-08 22:00:32 +02:00
|
|
|
var flash = preload("res://Assets/Effects/MuzzleFlash.tscn")
|
2021-09-25 18:14:17 +02:00
|
|
|
var tracer = preload("res://Assets/Effects/BulletTracer.tscn")
|
2021-09-08 23:25:52 +02:00
|
|
|
var impact_wall = preload("res://Assets/Effects/ImpactSparks.tscn")
|
|
|
|
var impact_player = preload("res://Assets/Effects/ImpactBlood.tscn")
|
2021-07-04 21:50:13 +02:00
|
|
|
|
2021-09-25 20:51:20 +02:00
|
|
|
# accuracy
|
|
|
|
var spread_min = 1
|
|
|
|
var spread_max = 64
|
|
|
|
var spread_lerp = 0.01
|
|
|
|
var spread_boost = 16
|
|
|
|
var spread = spread_min
|
|
|
|
|
2021-06-18 01:43:10 +02:00
|
|
|
# Declare member variables here. Examples:
|
|
|
|
# var a = 2
|
|
|
|
# var b = "text"
|
|
|
|
|
|
|
|
#enum Trigger {TRIGGER_PRIMARY, TRIGGER_SECONDARY}
|
|
|
|
|
2021-10-06 23:49:16 +02:00
|
|
|
@rpc(any_peer, call_local, reliable) func shoot(spread_offset:=Vector3.ZERO):
|
2021-09-25 20:51:20 +02:00
|
|
|
|
2021-08-23 01:57:47 +02:00
|
|
|
var space_state = get_world_3d().direct_space_state
|
|
|
|
|
|
|
|
var from = camera.get_global_transform().origin
|
|
|
|
var aim = - camera.get_global_transform().basis[2]
|
2021-09-25 20:51:20 +02:00
|
|
|
var to = from + (aim * 1000) + spread_offset
|
2021-08-23 01:57:47 +02:00
|
|
|
|
|
|
|
var ray = space_state.intersect_ray(from, to, [player])
|
|
|
|
|
2021-10-23 22:20:25 +02:00
|
|
|
$"SFX/Shoot A".play()
|
|
|
|
$"SFX/Shoot B".play()
|
|
|
|
$"SFX/Shoot C".play()
|
2021-09-12 03:03:52 +02:00
|
|
|
|
2021-09-25 18:14:17 +02:00
|
|
|
$Handgun/AnimationPlayer.play("Shoot", 0, 2.5)
|
|
|
|
|
|
|
|
var flash_effect = flash.instantiate()
|
|
|
|
var tracer_effect = tracer.instantiate()
|
|
|
|
|
|
|
|
get_parent().add_child(flash_effect)
|
|
|
|
get_tree().root.add_child(tracer_effect)
|
|
|
|
flash_effect.global_transform = muzzle.global_transform
|
2021-09-26 01:12:12 +02:00
|
|
|
tracer_effect.global_transform = muzzle.global_transform.looking_at(to)
|
2021-09-25 18:14:17 +02:00
|
|
|
|
|
|
|
var casing_instance = casing.instantiate()
|
|
|
|
get_tree().root.add_child(casing_instance)
|
|
|
|
|
2021-10-06 23:49:16 +02:00
|
|
|
casing_instance.global_transform = ejector.global_transform.translated(player.motion_velocity / 60) #approximating delta
|
|
|
|
casing_instance.linear_velocity = ejector.global_transform.basis[1] * randf_range(3.2, 4.5) + (player.motion_velocity / 2)
|
2021-09-25 18:14:17 +02:00
|
|
|
casing_instance.angular_velocity.y += randf_range(-10, 10)
|
|
|
|
casing_instance.angular_velocity.x += randf_range(-10, 10)
|
|
|
|
|
2021-10-15 02:15:43 +02:00
|
|
|
|
|
|
|
if ray:
|
|
|
|
if is_multiplayer_authority(): # only do this on the attacker's local instance of the game
|
|
|
|
give_damage(ray['collider'], ray['position'], ray['normal'], 20, self.global_transform.origin, Globals.DamageType.BULLET, 1.0)
|
2021-10-14 23:59:39 +02:00
|
|
|
|
|
|
|
return # skip the rest - it's deprecated code
|
|
|
|
|
2021-08-23 01:57:47 +02:00
|
|
|
var impact_vfx
|
|
|
|
|
2021-08-24 20:56:29 +02:00
|
|
|
if ray: # did we hit anything?
|
2021-10-14 23:59:39 +02:00
|
|
|
if ray['collider'].has_method(&'receive_damage') && is_multiplayer_authority():
|
|
|
|
ray['collider'].rpc(&'damage', 20, get_multiplayer_authority(), global_transform.origin) # apply damage
|
|
|
|
|
|
|
|
return
|
|
|
|
|
2021-08-24 20:56:29 +02:00
|
|
|
if ray['collider'].has_method(&'damage'):
|
2021-09-17 01:32:00 +02:00
|
|
|
if is_multiplayer_authority(): #get_tree().multiplayer.get_multiplayer_unique_id() == 1: # make sure this can only run on the server
|
2021-08-29 20:32:46 +02:00
|
|
|
#print("SHOT HIT ", ray['collider'])
|
2021-10-14 23:59:39 +02:00
|
|
|
ray['collider'].rpc(&'damage', 20) # apply damage
|
2021-09-17 01:32:00 +02:00
|
|
|
if main.player_list.get(ray['collider'].get_multiplayer_authority()).health <= 0: # if he ded
|
2021-09-19 20:51:47 +02:00
|
|
|
ray['collider'].rpc(&'die', self.get_multiplayer_authority())
|
2021-08-29 22:47:40 +02:00
|
|
|
|
2021-09-17 01:32:00 +02:00
|
|
|
main.player_list.players[player.get_multiplayer_authority()].score += 1 # give the killer a point
|
|
|
|
main.rpc(&'player_list_update', main.player_list.get(player.get_multiplayer_authority()).serialize(), player.get_multiplayer_authority())
|
2021-09-12 01:50:12 +02:00
|
|
|
hud.get_node("Crosshair").kill()
|
2021-09-25 00:15:44 +02:00
|
|
|
main.check_game_win_condition()
|
2021-09-25 15:53:12 +02:00
|
|
|
|
|
|
|
# check for firstblood
|
|
|
|
if main.player_list.players[player.get_multiplayer_authority()].score == 1:
|
|
|
|
var firstblood = true
|
|
|
|
for i in main.player_list.players.keys():
|
|
|
|
if i != player.get_multiplayer_authority() and main.player_list.players[i].score > 0:
|
|
|
|
firstblood = false
|
|
|
|
if firstblood:
|
|
|
|
main.get_node("Announcer").speak(main.get_node("Announcer").firstblood)
|
2021-09-25 17:06:01 +02:00
|
|
|
|
|
|
|
# check for revenge (payback) - don't play if this is a duel, it'd be silly
|
2021-09-25 17:36:15 +02:00
|
|
|
if main.player_list.players.size() > 2 and ray['collider'].get_multiplayer_authority() == player.revenge_pid:
|
2021-09-25 17:06:01 +02:00
|
|
|
main.get_node("Announcer").speak(main.get_node("Announcer").payback)
|
|
|
|
player.revenge_pid = -1 # reset revenge
|
2021-09-12 01:50:12 +02:00
|
|
|
else:
|
|
|
|
hud.get_node("Crosshair").hit()
|
2021-09-29 14:08:46 +02:00
|
|
|
ray['collider'].rpc(&'moan')
|
2021-09-11 16:32:38 +02:00
|
|
|
|
2021-08-29 22:47:40 +02:00
|
|
|
# boardcast the new health value to all peers
|
2021-09-17 01:32:00 +02:00
|
|
|
main.rpc(&'player_list_update', main.player_list.get(ray['collider'].get_multiplayer_authority()).serialize(), ray['collider'].get_multiplayer_authority())
|
2021-09-11 16:32:38 +02:00
|
|
|
main.update_hud()
|
2021-08-25 12:03:35 +02:00
|
|
|
|
2021-08-24 20:56:29 +02:00
|
|
|
impact_vfx = impact_player.instantiate()
|
|
|
|
else:
|
|
|
|
impact_vfx = impact_wall.instantiate()
|
|
|
|
|
2021-09-12 03:48:39 +02:00
|
|
|
if impact_vfx != null:
|
2021-08-25 12:03:35 +02:00
|
|
|
impact_vfx.global_transform = impact_vfx.global_transform.looking_at(ray['normal'])
|
|
|
|
impact_vfx.global_transform.origin = ray['position']
|
2021-09-11 14:35:07 +02:00
|
|
|
get_tree().root.add_child(impact_vfx)
|
2021-08-23 01:57:47 +02:00
|
|
|
|
2021-08-25 12:03:35 +02:00
|
|
|
#print(ray)
|
2021-08-23 01:57:47 +02:00
|
|
|
|
2021-10-14 23:59:39 +02:00
|
|
|
func give_damage(target: Node, hit_position: Vector3, hit_normal: Vector3, damage: int, source_position: Vector3, type: Globals.DamageType, push: float):
|
|
|
|
if target.has_method(&'take_damage'): # we've hit a player or something else - the ywill handle everything like effects etc.
|
2021-10-15 02:15:43 +02:00
|
|
|
target.rpc(&'take_damage', get_multiplayer_authority(), hit_position, hit_normal, damage, source_position, type, push)
|
2021-10-14 23:59:39 +02:00
|
|
|
else:
|
|
|
|
pass # TODO take data from the material of the target and spawn an appropriate hit effect
|
|
|
|
|
2021-09-19 20:51:47 +02:00
|
|
|
func trigger(index: int, active: bool) -> void:
|
2021-07-26 20:51:54 +02:00
|
|
|
#print("Weapon " + str(name) + ", Trigger " + str(index) + ", active: " + str(active))
|
2021-08-23 01:57:47 +02:00
|
|
|
if index == 0 and active and $Handgun/AnimationPlayer.is_playing() == false:
|
2021-09-26 02:38:11 +02:00
|
|
|
spread = min(spread + spread_boost, spread_max)
|
|
|
|
|
|
|
|
var spread_offset = Vector3.ZERO
|
|
|
|
|
|
|
|
spread_offset.x = randf_range(-1,1)
|
|
|
|
spread_offset.y = randf_range(-1,1)
|
|
|
|
spread_offset.z = randf_range(-1,1)
|
|
|
|
|
|
|
|
spread_offset = spread_offset.normalized() * randf_range(spread_min, spread)
|
2021-08-23 01:57:47 +02:00
|
|
|
|
2021-09-26 02:38:11 +02:00
|
|
|
rpc(&'shoot', spread_offset)
|
2021-09-25 18:14:17 +02:00
|
|
|
|
2021-06-18 01:43:10 +02:00
|
|
|
# Called when the node enters the scene tree for the first time.
|
|
|
|
func _ready():
|
2021-09-12 03:03:52 +02:00
|
|
|
# align the sound source with the head to produce balanced stereo
|
2021-10-23 22:20:25 +02:00
|
|
|
pass #$SFX/Shoot.global_transform = camera.global_transform
|