Advertisement
Lakamfo

weapon_script updated

Jun 20th, 2024
1,062
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
GDScript 21.82 KB | Source Code | 0 0
  1. class_name Weapon extends Node3D
  2.  
  3. @export_category("Basic")
  4. @export var weapon_name : String = "fsp45"
  5. ##Rate of fire per minute
  6. @export var fire_rate = 800
  7. ##Rate of burst mode fire per minute
  8. @export var burst_fire_rate = 800
  9. ##Default fire mode
  10. @export_enum("semi", "auto", "burst") var fire_mode : int = 1
  11. @export_flags("semi", "auto", "burst") var available_shooting_modes = 3
  12. ##Maximum engagement distance
  13. @export var fire_distance : float = 50
  14. ##Lenght maps to fire distance
  15. @export var fire_range_damage : Curve = preload("res://player/weapon_logic/damage_curve.tres")
  16. ##Zoom X while aiming
  17. @export var aim_camera_zoom : float = 2
  18.  
  19. @export_group("Bullets")
  20. @export var clip_size : int = 30
  21. @export var magazine_size : int = 300
  22. ##Additional bullet in chamber when tactical reloaded
  23. @export var bullet_in_chamber : bool = true
  24. @export var burst_size : int = 3
  25.  
  26. @export var buckshot_size : int = 0
  27. @export var buckshot_spread_max_angle : int = 5
  28.  
  29. @export_group("Damage")
  30. ##Base damage.
  31. ##Damage depends on the body part and is calculated using the formula:
  32. ##result_damage = (damage * part_mult) * fire_range_distance.sample(distance to enemy / fire_distance)
  33. @export var damage : float = 27
  34.  
  35. @export var head_mult : float = 2
  36. @export var torso_mult : float = 1
  37. @export var limbs_mult : float = 0.7
  38.  
  39. @export_group("Recoil")
  40. @export var max_hip_camera_kick : Vector3
  41. @export var min_hip_camera_kick : Vector3
  42. @export var max_aim_camera_kick : Vector3
  43. @export var min_aim_camera_kick : Vector3
  44.  
  45. #@export var max_camera_kick : Vector3
  46.  
  47. ##Does nothing
  48. @export var random_mult : float = 1
  49.  
  50. ##How fast camera snaps to kick
  51. @export var snappinnes = 6
  52. ##How fast camera returns to normal rotation
  53. @export var return_speed = 2
  54.  
  55. @export_subgroup("NonStop paremetres")
  56. ##If this option is activated, the camera's recoil accumulates
  57. @export var non_stop_mult_enabled : bool = true
  58. @export var max_non_stop_mult : float = 5
  59. @export var min_non_stop_mult : float = 1
  60. ##How much accumulates per shoot
  61. @export var non_stop_increase : float = 0.05
  62. ##Waiting for the last shot to reset the recoil
  63. @export var non_stop_reset_threshold : float = 0.5
  64.  
  65.  
  66. @export_group("Position & Procedural animation")
  67. ##Procedural animations for aiming
  68. @export var procedural_animation_enabled : bool = true
  69.  
  70. @export_subgroup("Hip")
  71. @export var standart_position : Vector3
  72. @export var standart_rotation : Vector3
  73. @export_subgroup("Aim")
  74. @export var aim_position : Vector3
  75. @export var aim_rotation : Vector3
  76. ##How long does the animation last in seconds
  77. @export var aim_speed : float = 1.0
  78.  
  79. @export_group("Shell")
  80. @export var manual_shell_eject : bool = false
  81. @export_enum("9mm:0","7mm:1","5mm:2") var shell_type : int = 0
  82. @export var min_impulse : Vector3
  83. @export var max_impulse : Vector3
  84. @export_subgroup("Custom shell model")
  85. @export var custom_model : PackedScene
  86.  
  87. @export_group("Sounds & Animations")
  88. ## if single loading is true, _animations_reload[0] = reload_start; _animations_reload[1] = reload_cycle; _animations_reload[2] = reload_end.
  89. ##Reload cycle animation should be looped for properly work.
  90. @export var single_loading : bool = false
  91. @export_placeholder("You can write several animations separated by commas") var idle_animation : String = ""
  92. @export_placeholder("You can write several animations separated by commas") var aim_idle_animation : String = ""
  93. @export_placeholder("You can write several animations separated by commas") var take_out_animation : String = ""
  94. @export_subgroup("Fire Animations")
  95. @export_placeholder("You can write several animations separated by commas") var fire_animation : String = ""
  96. @export_placeholder("You can write several animations separated by commas") var aim_fire_animation : String = ""
  97. @export_placeholder("You can write several animations separated by commas") var last_fire_animation : String = ""
  98. @export_placeholder("You can write several animations separated by commas") var last_aim_fire_animation : String = ""
  99. #@export_placeholder("You can write several animations separated by commas") var aim_reload_animation : String = ""
  100. @export_subgroup("Reload Animations")
  101. @export_placeholder("You can write several animations separated by commas") var tactical_reload_animation : String = ""
  102. @export_placeholder("You can write several animations separated by commas") var reload_animation : String = ""
  103.  
  104.  
  105. @export_group("UI")
  106. @export var icon : CompressedTexture2D = preload("res://icon.svg")
  107. @export var hit_marker_standart_color : Color = Color(1, 1, 1)
  108. @export var hit_marker_critical_color : Color = Color(0.72428458929062, 0.14479520916939, 0.22202762961388)
  109.  
  110. @export_group("Nodes")
  111. ## Weapon`s animation node
  112. @export_node_path("AnimationPlayer") var animation_player
  113. ## Weapon`s shot sound
  114. @export_node_path("AudioStreamPlayer3D") var audio_stream_player
  115. ## Weapon`s change mode click
  116. @export_node_path("AudioStreamPlayer3D") var audio_fire_mode_switch_stream_player
  117. ## Weapon`s flash
  118. @export_node_path("OmniLight3D") var omni_light
  119. ## Weapon`s shells spawn position
  120. @export_node_path("Marker3D") var shell_position
  121. ## Weapon`s sparkles and smoke
  122. @export_node_path("GPUParticles3D") var gpu_particles
  123. @export var camera_animation : Node3D
  124.  
  125. @export var bullet_pos : Marker3D
  126. var scene_root
  127.  
  128. #NODES
  129. var _animation_player : AnimationPlayer
  130. var _audio_stream_player : AudioStreamPlayer3D
  131. var _omni_light : OmniLight3D
  132. var _gpu_particles : GPUParticles3D
  133. var _shell_position : Marker3D
  134. var _audio_fire_mode_switch_stream_player : AudioStreamPlayer3D
  135.  
  136. var player
  137. var timer : Timer = Timer.new()
  138. var non_stop_timer : Timer = Timer.new()
  139.  
  140. #Shells
  141. var shell_9mm : PackedScene = preload("res://player/weapons/shells/models/9mm/9_mm_shell.tscn")
  142. var shell_7mm : PackedScene
  143. var shell_5mm : PackedScene
  144.  
  145. var bullet_hole_decal : PackedScene = preload("res://player/weapons/bullet_hole/bullet_hole.tscn")
  146.  
  147. var fire_mode_str : Array = ["SEMI","AUTO","BURST"]
  148.  
  149. #Internal variables
  150. var is_aiming : bool = false
  151. var previous_aim_state : bool = is_aiming
  152.  
  153. var timer_wait : float = 60.0 / fire_rate
  154. var non_stop : float = 1.0
  155. var weapon_ray_cast_3d : RayCast3D
  156. var ui_element
  157.  
  158. var is_tactical_reload : bool = false
  159. var is_reloading : bool = false :
  160.     set(value):
  161.         is_reloading = value
  162.         EventBus.emit_signal("weapon_reload", is_reloading)
  163.  
  164. var is_take_out : bool = false
  165.  
  166. var is_haste : bool = false
  167.  
  168. var clip : int
  169. var magazine : int = magazine_size :
  170.     set(value):
  171.         magazine = value
  172.         self._update_ui()
  173.  
  174. var _animations_fire : AnimationsPack = AnimationsPack.new()
  175. var _animations_aim_fire : AnimationsPack = AnimationsPack.new()
  176. var _animations_last_fire : AnimationsPack = AnimationsPack.new()
  177. var _animations_last_aim_fire : AnimationsPack = AnimationsPack.new()
  178. var _animations_idle : AnimationsPack = AnimationsPack.new()
  179. var _animations_aim_idle : AnimationsPack = AnimationsPack.new()
  180. var _animations_take_out : AnimationsPack = AnimationsPack.new()
  181. var _animations_tactical_reload : AnimationsPack = AnimationsPack.new()
  182. var _animations_reload : AnimationsPack = AnimationsPack.new()
  183.  
  184. class AnimationsPack:
  185.     var _animations_pack : PackedStringArray
  186.     var _pack_size : int = -1
  187.    
  188.     func parse(data : String, splitter : String = ",") -> void:
  189.         _animations_pack = data.split(splitter, false)
  190.        
  191.         _pack_size = _animations_pack.size() - 1
  192.    
  193.     func get_size() -> int:
  194.         return _pack_size
  195.    
  196.     func get_pack() -> PackedStringArray:
  197.         return _animations_pack
  198.    
  199.     func get_rand_animation() -> String:
  200.         if _pack_size > -1:
  201.             return _animations_pack[randi_range(0,_pack_size)]
  202.         else:
  203.             return "null"
  204.  
  205.  
  206. var bullet_tracer = preload("res://player/weapons/in_game/bullet_tracer.tscn")
  207. var tracer_instance
  208. var shell_instance
  209.  
  210. var bullet_shotted : int = 0
  211.  
  212. #Signals
  213. #Weapon_recoil in Event Bus
  214. #Weapon_aim in Event Bus
  215.  
  216. func _ready() -> void:
  217.     add_child(timer)
  218.     add_child(non_stop_timer)
  219.    
  220.     timer.one_shot = true; non_stop_timer.one_shot = true
  221.     timer.autostart = false; non_stop_timer.autostart = false
  222.    
  223.     non_stop = min_non_stop_mult
  224.    
  225.     if animation_player != null: _animation_player = get_node_or_null(animation_player)
  226.     if audio_stream_player != null: _audio_stream_player = get_node_or_null(audio_stream_player)
  227.     if audio_fire_mode_switch_stream_player != null: _audio_fire_mode_switch_stream_player = get_node_or_null(audio_fire_mode_switch_stream_player)
  228.     if omni_light != null: _omni_light = get_node_or_null(omni_light)
  229.     if gpu_particles != null: _gpu_particles = get_node_or_null(gpu_particles)
  230.     if shell_position != null: _shell_position = get_node_or_null(shell_position)
  231.    
  232.     if camera_animation:
  233.         camera_animation.rotation_degrees = Vector3.ZERO
  234.    
  235.     _animations_last_fire.parse(last_fire_animation)
  236.     _animations_last_aim_fire.parse(last_aim_fire_animation)
  237.     _animations_fire.parse(fire_animation)
  238.     _animations_aim_fire.parse(aim_fire_animation)
  239.     _animations_idle.parse(idle_animation)
  240.     _animations_aim_idle.parse(aim_idle_animation)
  241.     _animations_reload.parse(reload_animation)
  242.     _animations_tactical_reload.parse(tactical_reload_animation)
  243.     _animations_take_out.parse(take_out_animation)
  244.    
  245.     scene_root = get_tree().root
  246.    
  247.     magazine = magazine_size
  248.     clip = clip_size
  249.    
  250.     if _animation_player:
  251.         _animation_player.animation_finished.connect(_animation_handler)
  252.    
  253.     _change_shooting_mode(true)
  254.     _update_ui()
  255.  
  256. func _check(_delta : float):
  257.     if !visible:
  258.         return
  259.    
  260.     is_aiming = Input.is_action_pressed("mouse_2")
  261.    
  262.     if Global.player.camera_weapon_animation and camera_animation:
  263.         #Global.player.camera_weapon_animation.position = camera_animation.position
  264.         Global.player.camera_weapon_animation.rotation = camera_animation.rotation
  265.    
  266.     if non_stop_timer.is_stopped():
  267.         non_stop = min_non_stop_mult
  268.    
  269.     if not single_loading:
  270.         if !timer.is_stopped() or is_reloading or is_take_out:
  271.             return
  272.     elif !timer.is_stopped() or is_take_out:
  273.         return
  274.    
  275.     if Input.is_action_just_pressed("mouse_1") and clip == 0:
  276.         _reload()
  277.    
  278.     match fire_mode:
  279.         0: # Semi
  280.             if Input.is_action_just_pressed("mouse_1"):
  281.                 timer_wait = 60.0 / fire_rate
  282.                 _fire()
  283.         1: #Auto
  284.             if Input.is_action_pressed("mouse_1"):
  285.                 timer_wait = 60.0 / fire_rate
  286.                 _fire()
  287.         2: #Burst
  288.             if Input.is_action_just_pressed("mouse_1"):
  289.                 timer_wait = 60.0 / burst_fire_rate
  290.                 for bullet in burst_size:
  291.                     _fire()
  292.                     timer.start(timer_wait)
  293.                     await timer.timeout
  294.  
  295. func _physics_process(delta):
  296.     _check(delta)
  297.    
  298.     if !visible:
  299.         return
  300.    
  301.     if Input.is_action_just_pressed("chande_fire_mode"):
  302.         _change_shooting_mode(false)
  303.    
  304.     if Input.is_action_just_pressed("r"):
  305.         _reload()
  306.  
  307. func _process(delta: float) -> void:
  308.     _check(delta)
  309.    
  310.     _procedural_animation(delta)
  311.  
  312. func _fire():
  313.     if !clip > 0:
  314.         return
  315.    
  316.     is_reloading = false
  317.    
  318.     if not manual_shell_eject:
  319.         _eject_shell()
  320.    
  321.     clip -= 1
  322.    
  323.     if buckshot_size > 0:
  324.         var rot_to = manual_spread()
  325.        
  326.         for bullet in buckshot_size:
  327.             weapon_ray_cast_3d.rotation_degrees = rot_to
  328.             weapon_ray_cast_3d.force_raycast_update()
  329.            
  330.             rot_to = manual_spread()
  331.            
  332.             _hit_reg()
  333.             _play_vfx()
  334.     else:
  335.         _hit_reg()
  336.         _play_vfx()
  337.    
  338.     _update_ui()
  339.    
  340.     random_recoil()
  341.     timer.start(timer_wait)
  342.     non_stop_timer.start(non_stop_reset_threshold)
  343.    
  344.     if _animation_player != null and fire_animation != "":
  345.         _animation_player.stop()
  346.        
  347.         if(aim_fire_animation != "") and is_aiming:
  348.             _play_animation(_animations_aim_fire.get_rand_animation())
  349.         else:
  350.             _play_animation(_animations_fire.get_rand_animation())
  351.    
  352.     if _audio_stream_player != null:
  353.         _audio_stream_player.pitch_scale = randf_range(0.9,1.1)
  354.         _audio_stream_player.play()
  355.    
  356.     non_stop += non_stop_increase
  357.     non_stop = clamp(non_stop, min_non_stop_mult, max_non_stop_mult)
  358.  
  359. func _hit_reg():
  360.     if weapon_ray_cast_3d:
  361.         bullet_shotted += 1
  362.         var collider = weapon_ray_cast_3d.get_collider()
  363.         var hit_position : Vector3
  364.         var normal : Vector3
  365.        
  366.         if collider:
  367.             hit_position = weapon_ray_cast_3d.get_collision_point()
  368.             normal = weapon_ray_cast_3d.get_collision_normal()
  369.        
  370.         if collider and collider.has_method("get_hit"):
  371.             var final_damage = damage
  372.             if collider is Hitbox:
  373.                 match collider.type:
  374.                     0:
  375.                         final_damage *= head_mult
  376.                         EventBus.emit_signal("weapon_hitted", hit_marker_critical_color)
  377.                     1:
  378.                         final_damage *= torso_mult
  379.                         EventBus.emit_signal("weapon_hitted", hit_marker_standart_color)
  380.                     2:
  381.                         final_damage *= limbs_mult
  382.                         EventBus.emit_signal("weapon_hitted", hit_marker_standart_color)
  383.            
  384.             final_damage *= fire_range_damage.sample(Global.player.global_position.distance_to(hit_position) / fire_distance)
  385.            
  386.             EventBus.emit_signal("ui_message","%d Bullet Calculated Damage : %1.1f" %[bullet_shotted,final_damage])
  387.            
  388.             collider.call("get_hit", final_damage, hit_position)
  389.        
  390.         if collider is RigidBody3D:
  391.             collider.apply_impulse(normal * -2, hit_position - collider.global_position)
  392.  
  393.  
  394. func _reload():
  395.     #While shooting, the player cannot start reloading
  396.     if (_animation_player.current_animation in _animations_fire.get_pack() or _animation_player.current_animation in _animations_reload.get_pack()):
  397.         return
  398.    
  399.     if (is_reloading || is_take_out):
  400.         return
  401.    
  402.     if single_loading:
  403.         if magazine > 0 and clip != clip_size:
  404.             _play_animation(_animations_reload.get_pack()[0])
  405.             is_tactical_reload = clip < 1
  406.            
  407.             is_reloading = true
  408.         return
  409.    
  410.     var wasted_ammo_size = clip_size - (clip - int(bullet_in_chamber and clip > 0))
  411.    
  412.     if wasted_ammo_size <= 0 || magazine <= 0:
  413.         return
  414.    
  415.     if clip > 0 and _animations_tactical_reload.get_size() > -1:
  416.         _play_animation(_animations_tactical_reload.get_rand_animation())
  417.         is_tactical_reload = true
  418.         is_reloading = true
  419.     elif _animations_reload.get_size() > -1:
  420.         _play_animation(_animations_reload.get_rand_animation())
  421.         is_tactical_reload = false
  422.         is_reloading = true
  423.    
  424.     await EventBus.weapon_reload
  425.    
  426.     if visible:
  427.         if (wasted_ammo_size <= magazine):
  428.             magazine -= wasted_ammo_size
  429.            
  430.             clip += wasted_ammo_size
  431.         else:
  432.             clip += magazine
  433.             magazine = 0
  434.    
  435.     _update_ui()
  436.  
  437. func _change_shooting_mode(ready_update : bool = false):
  438.     # fire_mode = semi : 0, auto : 1, burst : 2
  439.     # Single modes are not described, because they don't need logic
  440.     if(ready_update):
  441.         match available_shooting_modes:
  442.             1: #Semi
  443.                 fire_mode = 0
  444.             2: # Auto
  445.                 fire_mode = 1
  446.             4: # Burst
  447.                 fire_mode = 2
  448.     else:
  449.         match available_shooting_modes:
  450.             1: #Semi
  451.                 fire_mode = 0
  452.             2: # Auto
  453.                 fire_mode = 1
  454.             4: # Burst
  455.                 fire_mode = 2
  456.             3: #Semi : 1 + Auto : 2
  457.                 if(fire_mode == 0): fire_mode = 1
  458.                 else : fire_mode = 0
  459.             5: #Burst : 4 + Semi : 1
  460.                 if(fire_mode == 0): fire_mode = 2
  461.                 else : fire_mode = 0
  462.             6: #Auto : 2 + burst : 4
  463.                 if(fire_mode == 1): fire_mode = 2
  464.                 else : fire_mode = 1
  465.             7: #Semi : 1 + Auto : 2 + Burst : 4
  466.                 if(fire_mode == 0): fire_mode = 1
  467.                 elif(fire_mode == 1) : fire_mode = 2
  468.                 else : fire_mode =  0
  469.        
  470.         if _audio_fire_mode_switch_stream_player:
  471.             _audio_fire_mode_switch_stream_player.pitch_scale = randf_range(0.9,1.1)
  472.             _audio_fire_mode_switch_stream_player.play()
  473.    
  474.     if(available_shooting_modes == 0):
  475.         DebugOutput.print_warning("Please select at least one shooting mode! : " + str(self))
  476.    
  477.     _update_ui()
  478.  
  479. func random_recoil():
  480.     var camera_kick : Vector3
  481.    
  482.     if is_aiming:
  483.         camera_kick = Vector3(
  484.             randf_range(min_aim_camera_kick.x,max_aim_camera_kick.x),
  485.             randf_range(-min_aim_camera_kick.y,max_aim_camera_kick.y),
  486.             randf_range(-min_aim_camera_kick.z,max_aim_camera_kick.z)
  487.         ) * non_stop
  488.     else:
  489.         camera_kick = Vector3(
  490.             randf_range(min_hip_camera_kick.x,max_hip_camera_kick.x),
  491.             randf_range(-min_hip_camera_kick.y,max_hip_camera_kick.y),
  492.             randf_range(-min_hip_camera_kick.z,max_hip_camera_kick.z)
  493.         ) * non_stop
  494.    
  495.     EventBus.emit_signal("weapon_recoil", camera_kick, snappinnes, return_speed)
  496.  
  497. func _update_ui():
  498.     if ui_element != null:
  499.         ui_element.ammos.text = str(clip) + "/" + str(magazine)
  500.         ui_element.fire_mode.text = fire_mode_str[fire_mode]
  501.  
  502. func _get_random_impulse():
  503.     return Vector3(
  504.                     randf_range(min_impulse.x,max_impulse.x),
  505.                     randf_range(min_impulse.y,max_impulse.y),
  506.                     randf_range(min_impulse.z,max_impulse.z)
  507.                     )
  508.  
  509. func _procedural_animation(_delta : float):
  510.     if !procedural_animation_enabled:
  511.         return
  512.     if is_aiming == previous_aim_state:
  513.         return
  514.    
  515.     previous_aim_state = is_aiming
  516.     var new_tween = get_tree().create_tween()
  517.    
  518.     if (is_aiming):
  519.         EventBus.emit_signal("weapon_aim", aim_camera_zoom, aim_speed, is_aiming)
  520.     else:
  521.         EventBus.emit_signal("weapon_aim", 1, aim_speed, is_aiming)
  522.    
  523.     if is_aiming:
  524.         new_tween.tween_property(self, "position",aim_position, aim_speed).set_trans(Tween.TRANS_SINE)
  525.         new_tween.parallel()
  526.         new_tween.tween_property(self, "rotation_degrees",aim_rotation, aim_speed).set_trans(Tween.TRANS_SINE)
  527.        
  528.         new_tween.play()
  529.         #position = lerp(position, aim_position, aim_speed * delta)
  530.         #rotation_degrees = lerp(rotation_degrees, aim_rotation, aim_speed * delta)
  531.     else:
  532.         new_tween.tween_property(self, "position",standart_position, aim_speed).set_trans(Tween.TRANS_SINE)
  533.         new_tween.parallel()
  534.         new_tween.tween_property(self, "rotation_degrees",standart_rotation, aim_speed).set_trans(Tween.TRANS_SINE)
  535.        
  536.         new_tween.play()
  537.        
  538.         #position = lerp(position, standart_position, aim_speed * delta)
  539.         #rotation_degrees = lerp(rotation_degrees, standart_rotation, aim_speed * delta)
  540.  
  541. func _animation_handler(animation_name : String):
  542.     if (animation_name in _animations_take_out.get_pack() + _animations_fire.get_pack() + _animations_reload.get_pack() + _animations_tactical_reload.get_pack() + _animations_aim_idle.get_pack() + _animations_idle.get_pack()):
  543.         var func_get_idle = func():
  544.             if not is_aiming or _animations_aim_idle.get_size() < 0:
  545.                 return _animations_idle.get_rand_animation()
  546.             else:
  547.                 return _animations_aim_idle.get_rand_animation()
  548.        
  549.         var rand_animation : String = func_get_idle.call()
  550.        
  551.         if(animation_name in _animations_reload.get_pack() + _animations_tactical_reload.get_pack()):
  552.             is_reloading = false
  553.        
  554.         if(animation_name in _animations_take_out.get_pack()):
  555.             is_take_out = false
  556.        
  557.         if (animation_name in _animations_idle.get_pack()):
  558.             rand_animation = func_get_idle.call()
  559.        
  560.         if (animation_name in _animations_fire.get_pack() + _animations_aim_fire.get_pack()):
  561.             rand_animation = func_get_idle.call()
  562.        
  563.         _play_animation(rand_animation)
  564.  
  565. func _play_vfx():
  566.     if !Global.decals_enabled:
  567.         return
  568.    
  569.     if bullet_pos:
  570.         tracer_instance = bullet_tracer.instantiate()
  571.         bullet_pos.add_child(tracer_instance)
  572.        
  573.         tracer_instance.top_level = true
  574.        
  575.         if weapon_ray_cast_3d.is_colliding():
  576.             tracer_instance.look_at(weapon_ray_cast_3d.get_collision_point(), Vector3.UP, true)
  577.    
  578.     if weapon_ray_cast_3d.is_colliding():
  579.         var collider = weapon_ray_cast_3d.get_collider()
  580.        
  581.         if collider:
  582.             if not collider.is_in_group("dynamic_object"):
  583.                 var decal = bullet_hole_decal.instantiate()
  584.                 decal.collider = collider
  585.                 collider.add_child(decal)
  586.                 decal.global_transform.origin = weapon_ray_cast_3d.get_collision_point()
  587.                 decal.look_at(Global.player.neck.global_rotation, weapon_ray_cast_3d.get_collision_normal())
  588.    
  589.     if _gpu_particles:_gpu_particles.emitting = true
  590.     if _omni_light:_omni_light.visible = true
  591.     await get_tree().create_timer(0.1).timeout
  592.     if _gpu_particles:_gpu_particles.emitting = false
  593.     if _omni_light:_omni_light.visible = false
  594.  
  595.  
  596. func _play_animation(anim_name : String):
  597.     if is_haste and anim_name in (_animations_reload.get_pack() + _animations_tactical_reload.get_pack()):
  598.         _animation_player.speed_scale = 2
  599.     else:
  600.         _animation_player.speed_scale = 1
  601.    
  602.     if _animation_player:
  603.         _animation_player.play(anim_name)
  604.  
  605. func change_visible(visible_weapon : bool = false):
  606.     if (visible_weapon == visible):
  607.         return
  608.     else:
  609.         visible = visible_weapon
  610.         is_reloading = false
  611.    
  612.         if(visible_weapon and _animations_take_out.get_size() > -1):
  613.             _animation_player.stop()
  614.             _play_animation(_animations_take_out.get_rand_animation())
  615.             is_take_out = true
  616.  
  617. #Function for track in AnimationPlayer
  618. func end_reloading():
  619.     is_reloading = false
  620.  
  621. func end_take_out():
  622.     is_take_out = false
  623.  
  624. func break_reloading():
  625.     #is_reloading = false
  626.     #if _animation_player:
  627.         #_animation_player.stop()
  628.     #dummy
  629.     pass
  630.  
  631. func manual_spread():
  632.     var raycast_rot : Vector3 = Vector3.ZERO
  633.    
  634.     if is_aiming:
  635.         raycast_rot = Vector3(
  636.             randf_range(-buckshot_spread_max_angle,buckshot_spread_max_angle),
  637.             randf_range(-buckshot_spread_max_angle,buckshot_spread_max_angle),
  638.             0
  639.         ) * non_stop
  640.     else:
  641.         raycast_rot = Vector3(
  642.             randf_range(-buckshot_spread_max_angle,buckshot_spread_max_angle),
  643.             randf_range(-buckshot_spread_max_angle,buckshot_spread_max_angle),
  644.             0
  645.         ) * non_stop
  646.    
  647.     return raycast_rot
  648.  
  649. func reload_by_one():
  650.     if not visible:
  651.         return
  652.    
  653.     if magazine > 0:
  654.         if clip + 1 < clip_size:
  655.             EventBus.emit_signal("ui_message", "Reload Cycle")
  656.             clip += 1; magazine -= 1
  657.             _play_animation(_animations_reload.get_pack()[1])
  658.         else:
  659.             EventBus.emit_signal("ui_message", "Reload End")
  660.             clip += 1; magazine -= 1
  661.            
  662.             if not is_tactical_reload:
  663.                 _play_animation(_animations_reload.get_pack()[2])
  664.             else:
  665.                 _play_animation(_animations_tactical_reload.get_pack()[2])
  666.            
  667.             is_reloading = false
  668.  
  669. func _eject_shell():
  670.     if Global.decals_enabled and shell_position:
  671.         var instance
  672.        
  673.         if not custom_model:
  674.             match shell_type:
  675.                 0:
  676.                     instance = shell_9mm.instantiate()
  677.                 1:
  678.                     instance = shell_9mm.instantiate()
  679.                 2:
  680.                     instance = shell_9mm.instantiate()
  681.         else:
  682.             instance = custom_model.instantiate()
  683.        
  684.         scene_root.add_child(instance)
  685.         instance.global_transform = _shell_position.global_transform
  686.        
  687.         instance.top_level = true
  688.         instance.apply_central_impulse(global_transform.basis * _get_random_impulse())
  689.         instance.apply_torque_impulse(_get_random_impulse())
  690.        
  691.         instance = null
  692.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement