From 050e4b60219832bc3596a60dde16301c0fbeb81e Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 4 Aug 2026 22:02:11 +0300 Subject: [PATCH] Add decals to shotgun as well --- godot/scenes/weapons/shotgun.tscn | 2 ++ rust/src/player/weapon.rs | 58 ++++++++++++++++++++++--------- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/godot/scenes/weapons/shotgun.tscn b/godot/scenes/weapons/shotgun.tscn index d2c6212..aac8e37 100644 --- a/godot/scenes/weapons/shotgun.tscn +++ b/godot/scenes/weapons/shotgun.tscn @@ -1,5 +1,6 @@ [gd_scene format=3 uid="uid://deyfeiqyi0wmj"] +[ext_resource type="PackedScene" uid="uid://b32uxedvawp73" path="res://scenes/weapons/bullet_hole_decal.tscn" id="1_278ir"] [ext_resource type="AudioStream" uid="uid://bcclq2sv7k0x3" path="res://raw_assets/sfx/gun_sounds/shotgun_compressed.mp3" id="1_pyt38"] [ext_resource type="PackedScene" uid="uid://b8nwd3323kwlc" path="res://mesh/shotgun.tscn" id="3_0xpw2"] @@ -53,6 +54,7 @@ curve = SubResource("Curve_yli5f") sound_emitter = NodePath("sound_emitter") vfx = NodePath("gpu_particles_3d") cooldown = 1.0 +decal = ExtResource("1_278ir") [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) diff --git a/rust/src/player/weapon.rs b/rust/src/player/weapon.rs index 12b23ab..50570a9 100644 --- a/rust/src/player/weapon.rs +++ b/rust/src/player/weapon.rs @@ -1,14 +1,14 @@ use std::{collections::HashSet, f32::consts::PI}; use godot::{ - classes::{AudioStreamPlayer3D, GpuParticles3D}, + classes::{AudioStreamPlayer3D, GpuParticles3D, RandomNumberGenerator}, prelude::*, }; use serde::{Deserialize, Serialize}; use crate::{ game::Game, - net::util::{cast_ray, shotgun_ray}, + net::util::{RaycastResult, cast_ray, shotgun_ray}, player::{DamageSource, shootable::Shootable}, replay::StandaloneReplayManager, }; @@ -92,16 +92,8 @@ impl Weapon for Raygun { let target_clone = target.clone(); self.run_deferred(|s| { - if let Some(mut game) = Game::singleton() - && let Some(map) = &mut game.bind_mut().current_map - && let Some(target) = target_clone - && let Some(prefab) = &s.decal - { - let mut decal = prefab.instantiate_as::(); - map.add_child(&decal); - decal.set_global_position(target.position); - let quat = Quaternion::from_rotation_arc(Vector3::UP, target.normal); - decal.set_global_rotation(quat.get_euler()); + if let Some(target) = target_clone { + add_decal(&target, s.decal.clone()); } }); @@ -177,8 +169,13 @@ pub struct Shotgun { #[export] cooldown: f64, + #[export] + decal: Option>, + cooldown_remaining: f64, + rng: Gd, + base: Base, } @@ -212,8 +209,7 @@ impl Weapon for Shotgun { } let mut colliders = HashSet::new(); - - for result in shotgun_ray( + let results = shotgun_ray( from, to, up, @@ -222,8 +218,25 @@ impl Weapon for Shotgun { 10, PI / 2., 10., - ) { - colliders.insert(result.collider); + ); + let mut bullet_decal_results = Vec::new(); + for _ in 0..10 { + if let Some(result) = results + .get(self.rng.randi_range(0, results.len() as i32 - 1) as usize) + .cloned() + { + bullet_decal_results.push(result); + } + } + + for result in bullet_decal_results { + self.run_deferred(move |s| { + add_decal(&result, s.decal.clone()); + }); + } + + for result in &results { + colliders.insert(result.collider.clone()); } if deal_damage { @@ -339,3 +352,16 @@ impl Weapon for BallWeapon { fn set_remaining_cd(&mut self, _: f64) {} } + +fn add_decal(result: &RaycastResult, prefab: Option>) { + if let Some(mut game) = Game::singleton() + && let Some(map) = &mut game.bind_mut().current_map + && let Some(prefab) = prefab + { + let mut decal = prefab.instantiate_as::(); + map.add_child(&decal); + decal.set_global_position(result.position); + let quat = Quaternion::from_rotation_arc(Vector3::UP, result.normal); + decal.set_global_rotation(quat.get_euler()); + } +}