Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
ea4f70f5ef Spawnables 2025-12-03 20:50:47 +05:00
25 changed files with 4784 additions and 4436 deletions

View file

@ -2,11 +2,9 @@
Current plans:
Different damage based on body part
Knife:
Behaviour
Model
Animation
Audio system:
Positional sound
Distance and wall dampening
Gameplay HUD:
Weapon display
Ability display
@ -14,6 +12,7 @@ Current plans:
Molik
Flashbang
Wall smoke
Kamikadze?
Think of something better
Anticheat:
Replace authority over player to server
Make rpc's to sync state
Implement client side state changes and sync calls

BIN
audio/test_damaged.ogg Normal file

Binary file not shown.

View file

@ -0,0 +1,19 @@
[remap]
importer="oggvorbisstr"
type="AudioStreamOggVorbis"
uid="uid://bixhakxpo8epv"
path="res://.godot/imported/test_damaged.ogg-a578462684ffc3782af3d53325026b1e.oggvorbisstr"
[deps]
source_file="res://audio/test_damaged.ogg"
dest_files=["res://.godot/imported/test_damaged.ogg-a578462684ffc3782af3d53325026b1e.oggvorbisstr"]
[params]
loop=false
loop_offset=0
bpm=0
beat_count=0
bar_beats=4

View file

@ -0,0 +1,13 @@
[gd_resource type="Environment" load_steps=3 format=3 uid="uid://ybeuqwdb504c"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_xjw7r"]
sky_top_color = Color(0.6256585, 0.8292434, 0.9808864, 1)
sky_horizon_color = Color(0.53361595, 0.7450959, 0.83056223, 1)
ground_horizon_color = Color(0.53361595, 0.7450959, 0.83056223, 1)
[sub_resource type="Sky" id="Sky_nv7aj"]
sky_material = SubResource("ProceduralSkyMaterial_xjw7r")
[resource]
background_mode = 2
sky = SubResource("Sky_nv7aj")

View file

@ -98,6 +98,12 @@ operation = 2
size = Vector3(3.9233856, 4.9065094, 8.765167)
material = ExtResource("5_bno23")
[node name="CSGBox3D7" type="CSGBox3D" parent="CSGCombiner3D/CSGBox3D5"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.4006386, 1.7042251, 3.8919868)
operation = 2
size = Vector3(3.9233856, 6.302376, 16.471077)
material = ExtResource("5_bno23")
[node name="CSGBox3D6" type="CSGBox3D" parent="CSGCombiner3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14.816613, 1.4951501, 14.911085)
size = Vector3(7.2811394, 2.1549835, 16.348633)

218
levels/split.tscn Normal file
View file

@ -0,0 +1,218 @@
[gd_scene load_steps=8 format=3 uid="uid://cc2v2f2ppu68w"]
[ext_resource type="Environment" uid="uid://ybeuqwdb504c" path="res://environments/split_environment.tres" id="1_muj2s"]
[ext_resource type="Material" uid="uid://bx3f5vx71ynh5" path="res://materials/Graymat.tres" id="4_mj4b4"]
[ext_resource type="Script" uid="uid://3i00rp8urth7" path="res://scripts/object_container.gd" id="9_klida"]
[ext_resource type="Script" uid="uid://ypgm3aplt78m" path="res://scripts/multiplayer/team_spawner.gd" id="10_n3y50"]
[ext_resource type="Script" uid="uid://bqjv6l7hh0lix" path="res://scripts/multiplayer/spawn_system/dyn_objects_spawner.gd" id="11_ydk8w"]
[ext_resource type="Script" uid="uid://dncldab5y4yod" path="res://scripts/item_spawner.gd" id="12_kry5j"]
[ext_resource type="PackedScene" uid="uid://cxdgk74ln5xpn" path="res://scenes/weapons/droppable_bomb.tscn" id="13_hy0sx"]
[node name="PrototypeScene" type="Node3D"]
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
transform = Transform3D(0.36256826, -0.8070987, 0.46597853, 2.7805946e-08, 0.49999994, 0.86602545, -0.93195724, -0.31399333, 0.18128408, 0, 0, 0)
shadow_enabled = true
shadow_opacity = 0.72
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = ExtResource("1_muj2s")
[node name="PlayersContainer" type="Node3D" parent="." node_paths=PackedStringArray("exlusion_list")]
script = ExtResource("9_klida")
exlusion_list = [NodePath("DefenceSpawn"), NodePath("AttackSpawn"), NodePath("SpectatorSpawn"), NodePath("MultiplayerSpawner")]
[node name="DefenceSpawn" type="Marker3D" parent="PlayersContainer"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 37.170197, 0.5180037, -11.271502)
script = ExtResource("10_n3y50")
spawn_radius = 10.0
[node name="AttackSpawn" type="Marker3D" parent="PlayersContainer"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.38304234, -4.809286, -89.24379)
script = ExtResource("10_n3y50")
team = 1
spawn_radius = 5.0
[node name="SpectatorSpawn" type="Marker3D" parent="PlayersContainer"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.1422176, 39.792877, -1.3889732)
script = ExtResource("10_n3y50")
team = 2
spawn_radius = 10.0
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="PlayersContainer"]
_spawnable_scenes = PackedStringArray("uid://dpsr6ug3pkb40", "uid://ckjabjcvgki6n")
spawn_path = NodePath("..")
[node name="DynamicObjectsContainer" type="Node3D" parent="." node_paths=PackedStringArray("exlusion_list")]
script = ExtResource("9_klida")
exlusion_list = [NodePath("MultiplayerSpawner"), NodePath("Bomb")]
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="DynamicObjectsContainer"]
_spawnable_scenes = PackedStringArray("uid://dtbpyfdawb02b", "uid://cxdgk74ln5xpn", "uid://dgfqppi21c2u0")
spawn_path = NodePath("..")
script = ExtResource("11_ydk8w")
[node name="Bomb" type="Node3D" parent="DynamicObjectsContainer"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.75895405, 1.4657042, -82.2781)
script = ExtResource("12_kry5j")
item = ExtResource("13_hy0sx")
[node name="CSGBox3D" type="CSGBox3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.10182953, 0, 0.008199692)
use_collision = true
size = Vector3(200, 30, 200)
material = ExtResource("4_mj4b4")
metadata/_edit_lock_ = true
[node name="CSGBox3D" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.76431274, 5.190714, -85.495895)
operation = 2
size = Vector3(19.616089, 20, 18.007202)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D2" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -11.439907, 5.190714, -79.43837)
operation = 2
size = Vector3(40.967278, 20, 5.892151)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D4" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -28.936323, 5.190714, -73.65309)
operation = 2
size = Vector3(17.32446, 20, 5.892151)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D5" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(-1, 0, -8.742278e-08, 0, 1, 0, 8.742278e-08, 0, -1, -36.057262, 5.190712, -68.04524)
operation = 2
size = Vector3(20.04846, 20, 5.892151)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D6" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1.3113416e-07, 0, -1, 0, 1, 0, 1, 0, 1.3113416e-07, -43.110355, 5.190712, -50.205387)
operation = 2
size = Vector3(41.6351, 20, 5.892151)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D8" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1.3113416e-07, 0, -1, 0, 1, 0, 1, 0, 1.3113416e-07, -49.17052, 5.190712, -54.688)
operation = 2
size = Vector3(14.743811, 20, 18.012482)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D9" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -32.214684, 5.190712, -37.012585)
operation = 2
size = Vector3(23.657562, 20, 5.892151)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D13" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(0.9438586, -0.33034965, 1.6502948e-07, 0.33034965, 0.9438586, 5.7760168e-08, -1.7484555e-07, 0, 1, -14.318398, 8.97945, -37.012585)
operation = 2
size = Vector3(21.155441, 21.89746, 5.892151)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D10" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -27.3817, 5.190712, -36.001347)
operation = 2
size = Vector3(13.4241905, 20, 13.434586)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D14" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -2.32983, 11.473099, -34.799385)
operation = 2
size = Vector3(13.4241905, 20, 15.838509)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D17" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -2.3298304, 12.957962, -22.154272)
operation = 2
size = Vector3(13.4241905, 17.030273, 10.398869)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D25" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -1.975194, 6.971512, -15.152288)
operation = 2
size = Vector3(4.9866176, 5.057373, 4.5284653)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D27" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -15.839454, 6.971512, -4.5533996)
operation = 2
size = Vector3(4.9866176, 5.057373, 4.5284653)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D26" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -6.483385, 8.4767, -5.505255)
operation = 2
size = Vector3(14.003002, 8.067749, 18.016186)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D16" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, -5.9264146e-08, 0.9408039, 0.3389514, -1.6449538e-07, -0.3389514, 0.9408039, -2.0993683, 12.163487, -25.798256)
operation = 2
size = Vector3(5.523605, 18.881592, 9.313798)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D11" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -27.768564, 5.190712, -25.174095)
operation = 2
size = Vector3(5.836166, 20, 10.473482)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D12" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -25.51088, 5.190712, -3.9385576)
operation = 2
size = Vector3(14.805191, 20, 34.73304)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D19" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -43.27089, 5.190712, 11.546464)
operation = 2
size = Vector3(25.511751, 20, 3.7630043)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D20" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -46.06128, 5.190712, 11.546465)
operation = 2
size = Vector3(19.930973, 20, 3.7630043)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D15" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -43.858833, 5.190712, -2.757196)
operation = 2
size = Vector3(26.825138, 20, 19.381424)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D22" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -44.94732, -0.57845306, -2.144785)
size = Vector3(2.5832448, 8.46167, 7.311594)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D24" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -20.040934, -0.57845306, -4.000236)
size = Vector3(3.9078333, 8.46167, 11.022496)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D23" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -34.202385, -2.0242548, 5.7241755)
size = Vector3(2.5832448, 5.5700684, 3.402379)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D21" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 1.7484555e-07, 0, 1, 0, -1.7484555e-07, 0, 1, -51.895195, 5.190712, 8.622506)
operation = 2
size = Vector3(10.752413, 20, 9.287149)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D18" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(0.9759396, 0, 0.21804121, 0, 1, 0, -0.21804121, 0, 0.9759396, -42.8084, 5.190712, -11.5842705)
operation = 2
size = Vector3(27.158907, 20, 8.102915)
material = ExtResource("4_mj4b4")
[node name="CSGBox3D3" type="CSGBox3D" parent="CSGBox3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.069462, 5.190714, -73.87635)
operation = 2
size = Vector3(5.8275757, 20, 5.892151)
material = ExtResource("4_mj4b4")

View file

@ -21,6 +21,7 @@ PlayerGlobal="*res://scripts/player/player_global.gd"
Lobby="*res://scripts/multiplayer/lobby.gd"
Session="*res://scripts/multiplayer/session.gd"
ClientSettings="*res://scripts/client_settings.gd"
Registry="*res://scripts/registry.gd"
[display]

View file

@ -46,7 +46,7 @@ layout_mode = 2
[node name="Label" type="Label" parent="VBoxContainer/GameplayMainAudio"]
layout_mode = 2
text = "Геймплей"
text = "Геймплейные звуки"
[node name="GameplayMainSlider" type="HSlider" parent="VBoxContainer/GameplayMainAudio"]
layout_mode = 2

File diff suppressed because one or more lines are too long

View file

@ -9,7 +9,7 @@
[node name="Bomb" type="Node" node_paths=PackedStringArray("enter_state")]
script = ExtResource("1_krsgt")
animation_prefix = &"baked_bomb_"
droppable = &"uid://cxdgk74ln5xpn"
index = &"bomb"
visibility_target = &"bomb"
max_ammo = 1
ammo_mags = 0

View file

@ -21,7 +21,7 @@ point_count = 5
[node name="StartingPistol" type="Node" node_paths=PackedStringArray("enter_state")]
script = ExtResource("1_g7s1i")
animation_prefix = &"baked_sp_"
droppable = &"uid://dgfqppi21c2u0"
index = &"sp"
visibility_target = &"sp"
max_ammo = 20
speed_modifier = 0.9

View file

@ -5,20 +5,40 @@ func _ready() -> void:
Session.dynamic_objects_spawner = self
func request_spawn(data: Variant) -> Node:
if data.has("scene") == false:
if is_multiplayer_authority() == false: return
if data.has("type") == false or data.has("spawn_name") == false:
return Node.new()
var node = load(data.scene).instantiate()
if data.has("impulse"):
if data.has_all(["ammo","remaining_ammo","slot"]):
node.weapon.ammo = data.ammo
node.weapon.remaining_ammo = data.remaining_ammo
node.slot = data.slot
node.apply_impulse(data.impulse)
for key in data.keys():
if key in ["scene","ammo","remaining_ammo","slot","position","rotation"]:
continue
node.set(key,data[key])
return node
match data.type:
"weapon":
var weapon: DroppableWeapon = Registry.weapons[data.spawn_name].dropped_scene.instantiate()
weapon.apply_central_impulse(data.impulse)
weapon.weapon.ammo = data.ammo
weapon.weapon.remaining_ammo = data.remaining_ammo
weapon.slot = Registry.weapons[data.spawn_name].slot
for key in data.keys():
if key == "impulse" or key == "ammo" or key == "remaining_ammo":
continue
weapon.set(key,data[key])
return weapon
"projectile":
var projectile: RigidBody3D = Registry.spawnable_objects[data.spawn_name].instantiate()
projectile.apply_central_impulse(data.impulse)
for key in data.keys():
if key == "impulse":
continue
projectile.set(key,data[key])
return projectile
"object":
var object: Node3D = Registry.spawnable_objects[data.spawn_name].instantiate()
for key in data.keys():
object.set(key,data[key])
return object
_:
return Node.new()

View file

@ -0,0 +1,11 @@
extends Node
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta: float) -> void:
pass

View file

@ -0,0 +1 @@
uid://cg0v1nmwuuoej

View file

@ -66,6 +66,7 @@ func set_after_spawn(start_position: Vector3,new_team: int):
@rpc("any_peer","call_local","reliable")
func take_damage(damage: int):
hp -= damage
$DamageAudio.multiplayer_play()
func _input(event: InputEvent) -> void:
if not is_multiplayer_authority():

11
scripts/registry.gd Normal file
View file

@ -0,0 +1,11 @@
extends Node
var spawnable_objects: Dictionary[StringName,PackedScene]
var weapons: Dictionary[StringName,WeaponResource]
func _ready() -> void:
for file in ResourceLoader.list_directory("res://weapons/"):
weapons[file.trim_suffix(".tres")] = load("res://weapons/"+ file)
for file in ResourceLoader.list_directory("res://spawnables/"):
spawnable_objects[file.trim_suffix(".tscn")] = load("res://spawnables/" + file)

1
scripts/registry.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://c7p8avavia4fp

View file

@ -0,0 +1,9 @@
extends Resource
class_name WeaponResource
@export var cost: int
@export var preview: Texture2D
@export var dropped_scene: PackedScene
@export var weapon_system_scene: PackedScene
@export var slot: StringName

View file

@ -0,0 +1 @@
uid://bvnn2eiwqbu7t

View file

@ -1,7 +1,5 @@
extends WeaponState
const active_bomb: StringName = "uid://dtbpyfdawb02b"
func enter():
machine.animation_player.play(machine.animation_prefix+"plant")
machine.animation_player.animation_finished.connect(on_animation_finished)
@ -17,7 +15,7 @@ func on_animation_finished(animation: StringName):
return
if animation == machine.animation_prefix + "plant":
Session.spawn({"scene": active_bomb, "position": machine.player_camera.get_parent().global_position,"plant": Session.get_site().name})
Session.spawn({"type": "object","spawn_name": "active_bomb", "position": machine.player_camera.get_parent().global_position,"plant": Session.get_site().name})
machine.ammo -= 1
return_to_previous.emit()

View file

@ -3,7 +3,7 @@ extends SubStateMachine
class_name WeaponSubStateMachine
@export var animation_prefix: StringName
@export var droppable: StringName
@export var index: StringName
@export var visibility_target: StringName
@export var max_ammo: int

View file

@ -103,7 +103,8 @@ func drop(weapon: WeaponSubStateMachine) -> void:
if slots.find_key(weapon) == "knife":
return
var drop_data: Dictionary = {}
drop_data.scene = weapon.droppable
drop_data.type = "weapon"
drop_data.spawn_name = weapon.index
drop_data.ammo = weapon.ammo
drop_data.remaining_ammo = weapon.remaining_ammo
drop_data.slot = weapon.slot

14
weapons/bomb.tres Normal file
View file

@ -0,0 +1,14 @@
[gd_resource type="Resource" script_class="WeaponResource" load_steps=5 format=3 uid="uid://b1obqb8w0o3ma"]
[ext_resource type="PackedScene" uid="uid://cxdgk74ln5xpn" path="res://scenes/weapons/droppable_bomb.tscn" id="1_sbnmj"]
[ext_resource type="Script" uid="uid://bvnn2eiwqbu7t" path="res://scripts/resources/weapon_resource.gd" id="1_w2ux2"]
[ext_resource type="Texture2D" uid="uid://dnxw4x3cmu7io" path="res://icon.svg" id="2_vkfbs"]
[ext_resource type="PackedScene" uid="uid://bxdatd1ilfgmc" path="res://scenes/weapons/bomb.tscn" id="4_shxvo"]
[resource]
script = ExtResource("1_w2ux2")
preview = ExtResource("2_vkfbs")
dropped_scene = ExtResource("1_sbnmj")
weapon_system_scene = ExtResource("4_shxvo")
slot = &"bomb"
metadata/_custom_type_script = "uid://bvnn2eiwqbu7t"

15
weapons/sp.tres Normal file
View file

@ -0,0 +1,15 @@
[gd_resource type="Resource" script_class="WeaponResource" load_steps=5 format=3 uid="uid://2jxguk5jxlim"]
[ext_resource type="PackedScene" uid="uid://dgfqppi21c2u0" path="res://scenes/weapons/droppable_sp.tscn" id="1_vpohq"]
[ext_resource type="Texture2D" uid="uid://dnxw4x3cmu7io" path="res://icon.svg" id="2_c0lu7"]
[ext_resource type="Script" uid="uid://bvnn2eiwqbu7t" path="res://scripts/resources/weapon_resource.gd" id="3_eyl1o"]
[ext_resource type="PackedScene" uid="uid://djwjl8xll53vn" path="res://scenes/weapons/starting_pistol.tscn" id="4_vpohq"]
[resource]
script = ExtResource("3_eyl1o")
cost = 200
preview = ExtResource("2_c0lu7")
dropped_scene = ExtResource("1_vpohq")
weapon_system_scene = ExtResource("4_vpohq")
slot = &"secondary"
metadata/_custom_type_script = "uid://bvnn2eiwqbu7t"