Add shotgun, and a way to swap weapons

This commit is contained in:
Sofia 2026-07-24 17:35:05 +03:00
parent e4e1a94876
commit 5b8dc1acc4
13 changed files with 235 additions and 22 deletions

View File

@ -0,0 +1,46 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://dnh13kxeqbxuu"
path="res://.godot/imported/Shotgun.fbx-c2b7fc9bafc73d2492e9aaff879f9e24.scn"
[deps]
source_file="res://assets/Shotgun.fbx"
dest_files=["res://.godot/imported/Shotgun.fbx-c2b7fc9bafc73d2492e9aaff879f9e24.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/root_script=null
mesh_library/use_node_names_as_mesh_names=false
array_mesh/deduplicate_surfaces=true
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_name_suffixes=true
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=true
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
materials/extract=0
materials/extract_format=0
materials/extract_path=""
_subresources={}
fbx/importer=0
fbx/allow_geometry_helper_nodes=false
fbx/embedded_image_handling=1
fbx/naming_version=2

12
godot/mesh/shotgun.tscn Normal file
View File

@ -0,0 +1,12 @@
[gd_scene format=3 uid="uid://b8nwd3323kwlc"]
[ext_resource type="PackedScene" uid="uid://dnh13kxeqbxuu" path="res://assets/Shotgun.fbx" id="1_wwlim"]
[ext_resource type="Texture2D" uid="uid://bis6yrsc7uo1p" path="res://raw_assets/Soldier/Shotgun.png" id="2_cseg6"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_cseg6"]
albedo_texture = ExtResource("2_cseg6")
[node name="Shotgun" unique_id=1412770732 instance=ExtResource("1_wwlim")]
[node name="Shotgun" parent="." index="0" unique_id=596235308]
surface_material_override/0 = SubResource("StandardMaterial3D_cseg6")

View File

@ -104,6 +104,16 @@ open_chat={
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194309,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
] ]
} }
weapon_1={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":49,"key_label":0,"unicode":49,"location":0,"echo":false,"script":null)
]
}
weapon_2={
"deadzone": 0.2,
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":50,"key_label":0,"unicode":50,"location":0,"echo":false,"script":null)
]
}
[physics] [physics]

View File

@ -0,0 +1,41 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bis6yrsc7uo1p"
path.s3tc="res://.godot/imported/Shotgun.png-6f3d985edecc9116b957d4c0485a368d.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://raw_assets/Soldier/Shotgun.png"
dest_files=["res://.godot/imported/Shotgun.png-6f3d985edecc9116b957d4c0485a368d.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View File

@ -0,0 +1,20 @@
[gd_scene format=3 uid="uid://deyfeiqyi0wmj"]
[ext_resource type="PackedScene" uid="uid://ctslratcr8h6v" path="res://scenes/player/raygun_beam.tscn" id="1_0xpw2"]
[ext_resource type="PackedScene" uid="uid://b8nwd3323kwlc" path="res://mesh/shotgun.tscn" id="3_0xpw2"]
[ext_resource type="AudioStream" uid="uid://bq553wxrelpdr" path="res://raw_assets/sfx/LaserWithRecoveryEditedCompressed.mp3" id="3_8oj30"]
[node name="shotgun" type="Raygun" unique_id=573018429 node_paths=PackedStringArray("sound_emitter", "bullet_source")]
sound_emitter = NodePath("sound_emitter")
bullet_prefab = ExtResource("1_0xpw2")
bullet_source = NodePath("bullet_source")
cooldown = 1.5
[node name="sound_emitter" type="AudioStreamPlayer3D" parent="." unique_id=1572422640]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.8420726, 0)
stream = ExtResource("3_8oj30")
[node name="bullet_source" type="Node3D" parent="." unique_id=211401237]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.36108458, -1.490972)
[node name="Shotgun" parent="." unique_id=1412770732 instance=ExtResource("3_0xpw2")]

View File

@ -3,6 +3,7 @@
[ext_resource type="PackedScene" uid="uid://cw7duhhjebypt" path="res://scenes/player/raygun.tscn" id="1_a50o4"] [ext_resource type="PackedScene" uid="uid://cw7duhhjebypt" path="res://scenes/player/raygun.tscn" id="1_a50o4"]
[ext_resource type="PackedScene" uid="uid://ncxcmgdit2j1" path="res://mesh/soldier_m.tscn" id="1_sxefq"] [ext_resource type="PackedScene" uid="uid://ncxcmgdit2j1" path="res://mesh/soldier_m.tscn" id="1_sxefq"]
[ext_resource type="PackedScene" uid="uid://ci8r4lgijtalh" path="res://scenes/player/ball_weapon.tscn" id="2_jbny0"] [ext_resource type="PackedScene" uid="uid://ci8r4lgijtalh" path="res://scenes/player/ball_weapon.tscn" id="2_jbny0"]
[ext_resource type="PackedScene" uid="uid://deyfeiqyi0wmj" path="res://scenes/player/shotgun.tscn" id="2_kknoo"]
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_a50o4"] [sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_a50o4"]
animation = &"Soldier|StrafeLeft" animation = &"Soldier|StrafeLeft"
@ -49,19 +50,20 @@ hand_attachment = NodePath("bone_attachment_3d/hand")
animation_tree = NodePath("animation_tree") animation_tree = NodePath("animation_tree")
skeleton = NodePath("SoldierM/Soldier/Skeleton3D") skeleton = NodePath("SoldierM/Soldier/Skeleton3D")
raygun = ExtResource("1_a50o4") raygun = ExtResource("1_a50o4")
shotgun = ExtResource("2_kknoo")
ball = ExtResource("2_jbny0") ball = ExtResource("2_jbny0")
look_at = NodePath("look_at_root") look_at = NodePath("look_at_root")
hand_remover = NodePath("SoldierM/Soldier/Skeleton3D/player_hand_remover") hand_remover = NodePath("SoldierM/Soldier/Skeleton3D/player_hand_remover")
[node name="SoldierM" parent="." unique_id=1868587353 instance=ExtResource("1_sxefq")] [node name="SoldierM" parent="." unique_id=1868587353 instance=ExtResource("1_sxefq")]
[node name="Skeleton3D" parent="SoldierM/Soldier" parent_id_path=PackedInt32Array(1868587353, 803584260) index="0" unique_id=1574145981] [node name="Skeleton3D" parent="SoldierM/Soldier" parent_id_path=PackedInt32Array(1868587353, 1101404322) index="0" unique_id=1074852808]
bones/0/position = Vector3(0, 0, 0.00071418716) bones/0/position = Vector3(0, 0, 0.00071418716)
bones/1/position = Vector3(0, 0, -0.007) bones/1/position = Vector3(0, 0, -0.007)
bones/1/rotation = Quaternion(0.6942035, 0, 0, 0.7197788) bones/1/rotation = Quaternion(0.69334954, 0, 0, 0.7206015)
bones/1/scale = Vector3(1, 1, 1) bones/1/scale = Vector3(1, 1, 1)
bones/2/position = Vector3(0.002, 3.469447e-18, -1.4901118e-10) bones/2/position = Vector3(0.002, 3.469447e-18, -1.4901118e-10)
bones/2/rotation = Quaternion(0.9459847, 2.1362002e-08, 2.3277545e-08, -0.3242114) bones/2/rotation = Quaternion(0.9452424, 2.1415062e-08, 2.3228734e-08, -0.32636914)
bones/2/scale = Vector3(1, 1, 1) bones/2/scale = Vector3(1, 1, 1)
bones/3/position = Vector3(0, 0.0069999984, 5.169879e-25) bones/3/position = Vector3(0, 0.0069999984, 5.169879e-25)
bones/3/scale = Vector3(1, 0.99999994, 1) bones/3/scale = Vector3(1, 0.99999994, 1)
@ -69,7 +71,7 @@ bones/4/position = Vector3(-2.39752e-11, 0.010049875, -1.4156722e-10)
bones/4/rotation = Quaternion(0.73982674, -2.6881349e-08, 7.0005948e-09, 0.67279744) bones/4/rotation = Quaternion(0.73982674, -2.6881349e-08, 7.0005948e-09, 0.67279744)
bones/4/scale = Vector3(1, 0.99999994, 0.99999994) bones/4/scale = Vector3(1, 0.99999994, 0.99999994)
bones/6/position = Vector3(-0.002, 3.469447e-18, -1.4901205e-10) bones/6/position = Vector3(-0.002, 3.469447e-18, -1.4901205e-10)
bones/6/rotation = Quaternion(0.9995959, 1.81219e-08, 1.8705832e-08, 0.02842787) bones/6/rotation = Quaternion(0.99965096, 1.8159414e-08, 1.8669416e-08, 0.026421284)
bones/6/scale = Vector3(1, 1, 1) bones/6/scale = Vector3(1, 1, 1)
bones/7/position = Vector3(0, 0.0069999984, -5.169879e-25) bones/7/position = Vector3(0, 0.0069999984, -5.169879e-25)
bones/7/rotation = Quaternion(-0.21973656, 4.264305e-08, 9.604991e-09, 0.9755593) bones/7/rotation = Quaternion(-0.21973656, 4.264305e-08, 9.604991e-09, 0.9755593)
@ -78,33 +80,33 @@ bones/8/position = Vector3(-2.3975525e-11, 0.010049875, -4.6138777e-11)
bones/8/rotation = Quaternion(0.86758894, -7.867721e-09, 3.036851e-08, 0.4972821) bones/8/rotation = Quaternion(0.86758894, -7.867721e-09, 3.036851e-08, 0.4972821)
bones/8/scale = Vector3(1, 0.99999994, 0.99999994) bones/8/scale = Vector3(1, 0.99999994, 0.99999994)
bones/10/position = Vector3(0, 0.009, 0) bones/10/position = Vector3(0, 0.009, 0)
bones/10/rotation = Quaternion(-0.1543622, -0.13157132, 0.01979417, 0.97901464) bones/10/rotation = Quaternion(-0.15285766, -0.13164644, 0.019584488, 0.97924477)
bones/10/scale = Vector3(1, 1, 1) bones/10/scale = Vector3(1, 1, 1)
bones/11/position = Vector3(6.8186457e-17, 0.008, 0.001) bones/11/position = Vector3(6.8186457e-17, 0.008, 0.001)
bones/11/rotation = Quaternion(0.058568474, 0.00011758354, -0.016027864, 0.9981548) bones/11/rotation = Quaternion(0.06447923, 0.00012945535, -0.017645404, 0.99776304)
bones/11/scale = Vector3(1, 1, 1) bones/11/scale = Vector3(1, 1, 1)
bones/12/position = Vector3(-2.2285185e-16, 0.0035, 0.0015000002) bones/12/position = Vector3(-2.2285185e-16, 0.0035, 0.0015000002)
bones/12/rotation = Quaternion(-0.70710677, 0, 0, 0.70710677) bones/12/rotation = Quaternion(-0.70710677, 0, 0, 0.70710677)
bones/12/scale = Vector3(1, 1, 1) bones/12/scale = Vector3(1, 1, 1)
bones/14/position = Vector3(0.005, 0.005, -1.7336413e-21) bones/14/position = Vector3(0.005, 0.005, -1.7336413e-21)
bones/14/rotation = Quaternion(0.8948624, 0.033474486, 0.43199828, -0.10713685) bones/14/rotation = Quaternion(0.8961431, 0.033815596, 0.4309325, -0.10040586)
bones/14/scale = Vector3(1, 0.99999994, 1) bones/14/scale = Vector3(1, 0.99999994, 1)
bones/15/position = Vector3(-1.3005262e-15, 0.0050000004, -6.938894e-18) bones/15/position = Vector3(-1.3005262e-15, 0.0050000004, -6.938894e-18)
bones/15/rotation = Quaternion(1.0353366e-08, -6.775671e-09, 0.9306435, 0.3659275) bones/15/rotation = Quaternion(1.0371065e-08, -6.748545e-09, 0.93159807, 0.36349007)
bones/15/scale = Vector3(1, 1, 1) bones/15/scale = Vector3(1, 1, 1)
bones/16/position = Vector3(7.632945e-11, 0.007071071, 6.938894e-18) bones/16/position = Vector3(7.632945e-11, 0.007071071, 6.938894e-18)
bones/16/rotation = Quaternion(0.0061545833, -0.0946999, -0.18472542, 0.9781977) bones/16/rotation = Quaternion(0.0037297043, -0.10077756, -0.18467139, 0.9776127)
bones/16/scale = Vector3(0.99999994, 0.9999999, 1) bones/16/scale = Vector3(0.99999994, 0.9999999, 1)
bones/18/position = Vector3(-0.005, 0.005, -1.7303326e-21) bones/18/position = Vector3(-0.005, 0.005, -1.7303326e-21)
bones/18/rotation = Quaternion(0.6569365, 0.16839267, -0.13031884, -0.72325325) bones/18/rotation = Quaternion(0.6575139, 0.16474941, -0.13285781, -0.7231058)
bones/18/scale = Vector3(1, 0.99999994, 1) bones/18/scale = Vector3(1, 0.99999994, 1)
bones/19/position = Vector3(-1.3005262e-15, 0.0050000004, -6.938894e-18) bones/19/position = Vector3(-1.3005262e-15, 0.0050000004, -6.938894e-18)
bones/19/rotation = Quaternion(-2.1264423e-08, -3.5540214e-08, -0.2685776, 0.9632581) bones/19/rotation = Quaternion(-2.1580865e-08, -3.5348958e-08, -0.27716652, 0.960822)
bones/19/scale = Vector3(1, 1, 1) bones/19/scale = Vector3(1, 1, 1)
bones/20/position = Vector3(-2.2286711e-10, 0.007071072, 0) bones/20/position = Vector3(-2.2286711e-10, 0.007071072, 0)
bones/20/rotation = Quaternion(-0.11203431, -0.4710411, -0.13362855, 0.8647035) bones/20/rotation = Quaternion(-0.10948259, -0.47254592, -0.13016704, 0.8647373)
bones/20/scale = Vector3(1, 0.9999999, 1) bones/20/scale = Vector3(1, 0.9999999, 1)
bones/22/position = Vector3(0.01127276, -0.0085772155, 0.0025254297) bones/22/position = Vector3(0.010810219, -0.0085772155, 0.0026520095)
bones/22/rotation = Quaternion(3.090862e-08, 0.70710677, 0.70710677, 3.090862e-08) bones/22/rotation = Quaternion(3.090862e-08, 0.70710677, 0.70710677, 3.090862e-08)
bones/22/scale = Vector3(1, 1, 1) bones/22/scale = Vector3(1, 1, 1)
bones/24/position = Vector3(-0.011000002, 0.0050000013, 0.0070000007) bones/24/position = Vector3(-0.011000002, 0.0050000013, 0.0070000007)
@ -156,7 +158,7 @@ origin_external_node = NodePath("../../../../look_at_root")
transform = Transform3D(1, -2.2737368e-13, 0, 2.2737368e-13, 1, 0, -1.3552527e-20, 0, 1, 0, 0, 0) transform = Transform3D(1, -2.2737368e-13, 0, 2.2737368e-13, 1, 0, -1.3552527e-20, 0, 1, 0, 0, 0)
[node name="bone_attachment_3d" type="BoneAttachment3D" parent="." unique_id=1964353847] [node name="bone_attachment_3d" type="BoneAttachment3D" parent="." unique_id=1964353847]
transform = Transform3D(-35.09831, 3.8198574, -93.56024, -83.58222, 43.767776, 33.14208, 42.21521, 89.832, -12.169015, -0.47216344, 3.3898914, 0.7404115) transform = Transform3D(-35.57116, 3.7920692, -93.38263, -83.207954, 44.21317, 33.490837, 42.55741, 89.61482, -12.571805, -0.4719007, 3.3932352, 0.7389869)
bone_name = "HAND.R_end" bone_name = "HAND.R_end"
bone_idx = 17 bone_idx = 17
use_external_skeleton = true use_external_skeleton = true

View File

@ -698,7 +698,7 @@ impl Game {
if let Some(player) = self.find_player_mut(player_id) if let Some(player) = self.find_player_mut(player_id)
&& let Some(character) = &mut player.character && let Some(character) = &mut player.character
{ {
character.dyn_bind_mut().swap_weapon(weapon_type); character.dyn_bind_mut().spawn_weapon_common(weapon_type);
let player_id = player.id(); let player_id = player.id();
self.run_deferred(move |_| { self.run_deferred(move |_| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer

View File

@ -386,6 +386,15 @@ impl NetworkManager {
} }
} }
} }
Package::SwapWeapon(_, weapon_type) => {
if let Some(game) = &mut Game::singleton()
&& let Some(player) =
game.bind_mut().find_player_by_addr_mut(&conn.address)
&& let Some(character) = &mut player.character
{
character.dyn_bind_mut().swap_weapon_proxy(weapon_type);
}
}
_ => {} _ => {}
}, },
}, },

View File

@ -58,8 +58,10 @@ pub trait IPlayer {
fn is_dead(&self) -> bool; fn is_dead(&self) -> bool;
fn kill(&mut self, source_player: DamageSource); fn kill(&mut self, source_player: DamageSource);
fn dead_for(&self) -> f64; fn dead_for(&self) -> f64;
fn swap_weapon(&mut self, weapon: WeaponType); fn spawn_weapon_common(&mut self, weapon: WeaponType);
fn swap_weapon_proxy(&mut self, weapon: WeaponType);
fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>>; fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>>;
fn take_weapon(&mut self) -> Option<DynGd<Node3D, dyn Weapon>>;
fn drop_ball(&mut self, with_velocity: bool) -> bool; fn drop_ball(&mut self, with_velocity: bool) -> bool;
fn get_camera_origin(&self) -> Option<Gd<Node3D>>; fn get_camera_origin(&self) -> Option<Gd<Node3D>>;
} }
@ -68,6 +70,7 @@ pub trait PlayerCommon {
fn player_update(&mut self, delta: f64); fn player_update(&mut self, delta: f64);
fn try_jump(&mut self) -> bool; fn try_jump(&mut self) -> bool;
fn drop_ball_common(&mut self, with_velocity: bool) -> bool; fn drop_ball_common(&mut self, with_velocity: bool) -> bool;
fn swap_weapon(&mut self, ty: WeaponType);
fn get_look_dir(&self) -> Vector3; fn get_look_dir(&self) -> Vector3;
fn can_take_damage(&self, source: &DamageSource) -> bool; fn can_take_damage(&self, source: &DamageSource) -> bool;
} }
@ -105,14 +108,14 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
} }
fn drop_ball_common(&mut self, with_velocity: bool) -> bool { fn drop_ball_common(&mut self, with_velocity: bool) -> bool {
if let Some(weapon) = self.get_weapon() if let Some(weapon) = self.take_weapon()
&& let Ok(_) = weapon.try_cast::<BallWeapon>() && let Ok(_) = weapon.try_cast::<BallWeapon>()
{ {
self.run_deferred(move |s| { self.run_deferred(move |s| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
&& let PeerKind::Server(peer, _) = peer && let PeerKind::Server(peer, _) = peer
{ {
s.swap_weapon(WeaponType::Raygun); s.spawn_weapon_common(WeaponType::Raygun);
peer.broadcast_reliable(Package::SwapWeapon( peer.broadcast_reliable(Package::SwapWeapon(
s.get_player_id().unwrap_or(0), s.get_player_id().unwrap_or(0),
WeaponType::Raygun, WeaponType::Raygun,
@ -143,6 +146,28 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
} }
} }
fn swap_weapon(&mut self, ty: WeaponType) {
if ty == WeaponType::Ball {
return;
}
self.spawn_weapon_common(ty);
self.run_deferred(move |s| {
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
match peer {
PeerKind::Client(peer, socket_addr) => {
peer.send_reliable(socket_addr, Package::SwapWeapon(0, ty));
}
PeerKind::Server(peer, _) => {
peer.broadcast_reliable(Package::SwapWeapon(
s.get_player_id().unwrap_or(0),
ty,
));
}
}
}
});
}
fn get_look_dir(&self) -> Vector3 { fn get_look_dir(&self) -> Vector3 {
if let Some(camera_origin) = self.get_camera_origin() { if let Some(camera_origin) = self.get_camera_origin() {
camera_origin.get_global_basis().col_c().neg() camera_origin.get_global_basis().col_c().neg()
@ -359,7 +384,9 @@ impl IPlayer for LocalPlayer {
} }
} }
fn swap_weapon(&mut self, weapon: WeaponType) { fn spawn_weapon_common(&mut self, weapon: WeaponType) {
self.drop_ball(true);
if let Some(mesh) = self.soldier_mesh.clone() { if let Some(mesh) = self.soldier_mesh.clone() {
match weapon { match weapon {
WeaponType::Raygun => { WeaponType::Raygun => {
@ -367,6 +394,11 @@ impl IPlayer for LocalPlayer {
self.spawn_weapon(raygun.instantiate_as::<Raygun>().into_dyn().upcast()); self.spawn_weapon(raygun.instantiate_as::<Raygun>().into_dyn().upcast());
} }
} }
WeaponType::Shotgun => {
if let Some(raygun) = &mesh.bind().shotgun {
self.spawn_weapon(raygun.instantiate_as::<Raygun>().into_dyn().upcast());
}
}
WeaponType::Ball => { WeaponType::Ball => {
if let Some(ball) = &mesh.bind().ball { if let Some(ball) = &mesh.bind().ball {
self.spawn_weapon(ball.instantiate_as::<BallWeapon>().into_dyn().upcast()); self.spawn_weapon(ball.instantiate_as::<BallWeapon>().into_dyn().upcast());
@ -376,10 +408,18 @@ impl IPlayer for LocalPlayer {
} }
} }
fn swap_weapon_proxy(&mut self, weapon: WeaponType) {
self.swap_weapon(weapon);
}
fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>> { fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>> {
self.weapon.clone() self.weapon.clone()
} }
fn take_weapon(&mut self) -> Option<DynGd<Node3D, dyn Weapon>> {
self.weapon.as_ref().take().cloned()
}
fn drop_ball(&mut self, with_velocity: bool) -> bool { fn drop_ball(&mut self, with_velocity: bool) -> bool {
self.drop_ball_common(with_velocity) self.drop_ball_common(with_velocity)
} }
@ -427,7 +467,7 @@ impl ICharacterBody3D for LocalPlayer {
.connect_other(self, |s| s.update_lock()); .connect_other(self, |s| s.update_lock());
} }
self.swap_weapon(WeaponType::Raygun); self.spawn_weapon_common(WeaponType::Raygun);
if let Some(camera) = &mut self.camera { if let Some(camera) = &mut self.camera {
camera.set_current(true); camera.set_current(true);
@ -602,6 +642,10 @@ impl ICharacterBody3D for LocalPlayer {
} }
} }
} }
} else if event.is_action_pressed("weapon_1") {
self.swap_weapon(WeaponType::Raygun);
} else if event.is_action_pressed("weapon_2") {
self.swap_weapon(WeaponType::Shotgun);
} }
if let Ok(event) = event.try_cast::<InputEventMouseMotion>() { if let Ok(event) = event.try_cast::<InputEventMouseMotion>() {
@ -850,21 +894,34 @@ impl IPlayer for RemotePlayer {
self.is_dead = true; self.is_dead = true;
} }
fn swap_weapon(&mut self, weapon: WeaponType) { fn spawn_weapon_common(&mut self, weapon: WeaponType) {
self.drop_ball(true);
if let Some(mesh) = &mut self.soldier_mesh { if let Some(mesh) = &mut self.soldier_mesh {
match weapon { match weapon {
WeaponType::Raygun => mesh.bind_mut().spawn_raygun(), WeaponType::Raygun => mesh.bind_mut().spawn_raygun(),
WeaponType::Shotgun => mesh.bind_mut().spawn_shotgun(),
WeaponType::Ball => mesh.bind_mut().spawn_ball(), WeaponType::Ball => mesh.bind_mut().spawn_ball(),
}; };
} }
} }
fn swap_weapon_proxy(&mut self, weapon: WeaponType) {
self.swap_weapon(weapon);
}
fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>> { fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>> {
self.soldier_mesh self.soldier_mesh
.as_ref() .as_ref()
.and_then(|m| m.bind().get_weapon()) .and_then(|m| m.bind().get_weapon())
} }
fn take_weapon(&mut self) -> Option<DynGd<Node3D, dyn Weapon>> {
self.soldier_mesh
.as_mut()
.and_then(|m| m.bind_mut().take_weapon().cloned())
}
fn drop_ball(&mut self, with_velocity: bool) -> bool { fn drop_ball(&mut self, with_velocity: bool) -> bool {
self.drop_ball_common(with_velocity) self.drop_ball_common(with_velocity)
} }
@ -889,7 +946,7 @@ impl ICharacterBody3D for RemotePlayer {
} }
}); });
self.swap_weapon(WeaponType::Raygun); self.spawn_weapon_common(WeaponType::Raygun);
} }
fn process(&mut self, delta: f64) { fn process(&mut self, delta: f64) {

View File

@ -20,6 +20,8 @@ pub struct SoldierMesh {
#[export] #[export]
pub raygun: Option<Gd<PackedScene>>, pub raygun: Option<Gd<PackedScene>>,
#[export] #[export]
pub shotgun: Option<Gd<PackedScene>>,
#[export]
pub ball: Option<Gd<PackedScene>>, pub ball: Option<Gd<PackedScene>>,
#[export] #[export]
look_at: Option<Gd<Node3D>>, look_at: Option<Gd<Node3D>>,
@ -58,6 +60,15 @@ impl SoldierMesh {
} }
} }
pub fn spawn_shotgun(&mut self) -> Option<DynGd<Node3D, dyn Weapon>> {
if let Some(shotgun) = &self.shotgun {
let node = shotgun.instantiate_as::<Raygun>();
self.spawn_weapon(node.into_dyn().upcast())
} else {
None
}
}
pub fn spawn_ball(&mut self) -> Option<DynGd<Node3D, dyn Weapon>> { pub fn spawn_ball(&mut self) -> Option<DynGd<Node3D, dyn Weapon>> {
if let Some(ball) = &self.ball { if let Some(ball) = &self.ball {
let node = ball.instantiate_as::<BallWeapon>(); let node = ball.instantiate_as::<BallWeapon>();
@ -86,4 +97,8 @@ impl SoldierMesh {
pub fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>> { pub fn get_weapon(&self) -> Option<DynGd<Node3D, dyn Weapon>> {
self.current_weapon.clone() self.current_weapon.clone()
} }
pub fn take_weapon(&self) -> Option<&DynGd<Node3D, dyn Weapon>> {
self.current_weapon.as_ref().take()
}
} }

View File

@ -23,6 +23,7 @@ pub trait Weapon {
#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, PartialOrd)] #[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, PartialOrd)]
pub enum WeaponType { pub enum WeaponType {
Raygun, Raygun,
Shotgun,
Ball, Ball,
} }