Compare commits
No commits in common. "64d8c148ce70a1d5f30aa41814f46b672e5b3de2" and "e242f3f58425da1a4c1d51e439421a27145d1a1d" have entirely different histories.
64d8c148ce
...
e242f3f584
@ -158,9 +158,3 @@ name = "Fantozzi"
|
|||||||
[[people.credits]]
|
[[people.credits]]
|
||||||
credit = "Fantozzi's Footsteps (Grass/Sand & Stone)"
|
credit = "Fantozzi's Footsteps (Grass/Sand & Stone)"
|
||||||
link = "https://opengameart.org/content/fantozzis-footsteps-grasssand-stone"
|
link = "https://opengameart.org/content/fantozzis-footsteps-grasssand-stone"
|
||||||
|
|
||||||
[[people]]
|
|
||||||
name = "TobiasM"
|
|
||||||
[[people.credits]]
|
|
||||||
credit = "Blood splat"
|
|
||||||
link = "https://opengameart.org/content/blood-splat"
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 86 KiB |
@ -1,40 +0,0 @@
|
|||||||
[remap]
|
|
||||||
|
|
||||||
importer="texture"
|
|
||||||
type="CompressedTexture2D"
|
|
||||||
uid="uid://cnahou6bg32pu"
|
|
||||||
path="res://.godot/imported/blood_splat.png-2bef76897d4f45e457d6e9899a1358ed.ctex"
|
|
||||||
metadata={
|
|
||||||
"vram_texture": false
|
|
||||||
}
|
|
||||||
|
|
||||||
[deps]
|
|
||||||
|
|
||||||
source_file="res://raw_assets/blood_splat.png"
|
|
||||||
dest_files=["res://.godot/imported/blood_splat.png-2bef76897d4f45e457d6e9899a1358ed.ctex"]
|
|
||||||
|
|
||||||
[params]
|
|
||||||
|
|
||||||
compress/mode=0
|
|
||||||
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=false
|
|
||||||
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=1
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
[gd_scene format=3 uid="uid://c1sc6yl56mi0s"]
|
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cnahou6bg32pu" path="res://raw_assets/blood_splat.png" id="1_1rw23"]
|
|
||||||
|
|
||||||
[node name="bullet_hole_decal" type="Node3D" unique_id=18163478]
|
|
||||||
|
|
||||||
[node name="decal" type="Decal" parent="." unique_id=1515351623]
|
|
||||||
size = Vector3(1, 1, 1)
|
|
||||||
texture_albedo = ExtResource("1_1rw23")
|
|
||||||
@ -11,7 +11,6 @@
|
|||||||
[ext_resource type="AudioStream" uid="uid://dpafq3gxer7qf" path="res://raw_assets/sfx/footsteps_congusbongus/tile/0.ogg" id="8_7a25g"]
|
[ext_resource type="AudioStream" uid="uid://dpafq3gxer7qf" path="res://raw_assets/sfx/footsteps_congusbongus/tile/0.ogg" id="8_7a25g"]
|
||||||
[ext_resource type="AudioStream" uid="uid://fn5olcnrb1jn" path="res://raw_assets/sfx/footsteps_congusbongus/water/2.ogg" id="9_k2vl2"]
|
[ext_resource type="AudioStream" uid="uid://fn5olcnrb1jn" path="res://raw_assets/sfx/footsteps_congusbongus/water/2.ogg" id="9_k2vl2"]
|
||||||
[ext_resource type="AudioStream" uid="uid://br64dea537kkw" path="res://raw_assets/sfx/footsteps_congusbongus/wood/0.ogg" id="10_x30cj"]
|
[ext_resource type="AudioStream" uid="uid://br64dea537kkw" path="res://raw_assets/sfx/footsteps_congusbongus/wood/0.ogg" id="10_x30cj"]
|
||||||
[ext_resource type="PackedScene" uid="uid://c1sc6yl56mi0s" path="res://scenes/player/blood_decal.tscn" id="11_otyku"]
|
|
||||||
|
|
||||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_1cgct"]
|
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_1cgct"]
|
||||||
particle_flag_align_y = true
|
particle_flag_align_y = true
|
||||||
@ -58,7 +57,6 @@ footstep_sounds = Dictionary[String, AudioStream]({
|
|||||||
"Wood": ExtResource("10_x30cj")
|
"Wood": ExtResource("10_x30cj")
|
||||||
})
|
})
|
||||||
walk_sfx_cd = 0.5
|
walk_sfx_cd = 0.5
|
||||||
blood_decal = ExtResource("11_otyku")
|
|
||||||
|
|
||||||
[node name="splorch" type="GPUParticles3D" parent="." unique_id=986677517]
|
[node name="splorch" type="GPUParticles3D" parent="." unique_id=986677517]
|
||||||
emitting = false
|
emitting = false
|
||||||
|
|||||||
@ -31,7 +31,6 @@ use crate::{
|
|||||||
buffs::{Buff, BuffKind},
|
buffs::{Buff, BuffKind},
|
||||||
local_player::LocalPlayer,
|
local_player::LocalPlayer,
|
||||||
remote_player::RemotePlayer,
|
remote_player::RemotePlayer,
|
||||||
shootable::Shootable,
|
|
||||||
telegrenade::Telegrenade,
|
telegrenade::Telegrenade,
|
||||||
weapon::WeaponType,
|
weapon::WeaponType,
|
||||||
},
|
},
|
||||||
@ -1088,25 +1087,6 @@ impl Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handled whenever a player is shot, run on client-side only
|
|
||||||
pub fn handle_on_shot(
|
|
||||||
&mut self,
|
|
||||||
player_id: u16,
|
|
||||||
source: DamageSource,
|
|
||||||
damage: i32,
|
|
||||||
delta: NetVector3,
|
|
||||||
) {
|
|
||||||
if let Some(player) = self.find_player_mut(player_id)
|
|
||||||
&& let Some(character) = &mut player.character
|
|
||||||
{
|
|
||||||
if let Ok(mut shootable) = character.clone().into_gd().try_dynify::<dyn Shootable>() {
|
|
||||||
shootable
|
|
||||||
.dyn_bind_mut()
|
|
||||||
.on_shoot_visual(source, damage, delta.into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle shooting, either from the server of from a client
|
// Handle shooting, either from the server of from a client
|
||||||
pub fn handle_shoot(
|
pub fn handle_shoot(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@ -181,8 +181,6 @@ impl Shootable for ShootableTrigger {
|
|||||||
self.signals().on_shot().emit(id, damage, dir);
|
self.signals().on_shot().emit(id, damage, dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_shoot_visual(&mut self, _: DamageSource, _: i32, _: Vector3) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
|
|||||||
@ -357,7 +357,6 @@ pub enum Package {
|
|||||||
Jump(u16),
|
Jump(u16),
|
||||||
Shoot(u16, NetVector3, NetTransform, f32),
|
Shoot(u16, NetVector3, NetTransform, f32),
|
||||||
Punch(u16, NetVector3, NetTransform, f32),
|
Punch(u16, NetVector3, NetTransform, f32),
|
||||||
OnShot(u16, DamageSource, i32, NetVector3),
|
|
||||||
TakeDamage(DamageSource, u16, i32),
|
TakeDamage(DamageSource, u16, i32),
|
||||||
Kill(DamageSource, u16),
|
Kill(DamageSource, u16),
|
||||||
SpawnBall(NetTransform, NetVector3, Option<u16>),
|
SpawnBall(NetTransform, NetVector3, Option<u16>),
|
||||||
|
|||||||
@ -262,12 +262,6 @@ impl NetworkManager {
|
|||||||
game.bind_mut().on_trigger_deactivate(id);
|
game.bind_mut().on_trigger_deactivate(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Package::OnShot(player_id, source, damage, delta) => {
|
|
||||||
if let Some(game) = &mut Game::singleton() {
|
|
||||||
game.bind_mut()
|
|
||||||
.handle_on_shot(player_id, source, damage, delta);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
use godot::prelude::*;
|
use godot::{
|
||||||
|
classes::{PhysicsRayQueryParameters3D, World3D},
|
||||||
|
prelude::*,
|
||||||
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||||
|
|||||||
@ -94,12 +94,10 @@ impl Ball {
|
|||||||
|
|
||||||
#[godot_dyn]
|
#[godot_dyn]
|
||||||
impl Shootable for Ball {
|
impl Shootable for Ball {
|
||||||
fn on_shoot(&mut self, _: DamageSource, damage: i32, delta: Vector3) {
|
fn on_shoot(&mut self, _: DamageSource, damage: i32, dir: Vector3) {
|
||||||
let prev_velocity = self.base().get_linear_velocity();
|
let prev_velocity = self.base().get_linear_velocity();
|
||||||
let force = damage as f32 / 10.;
|
let force = damage as f32 / 10.;
|
||||||
self.base_mut()
|
self.base_mut()
|
||||||
.set_linear_velocity(prev_velocity + delta.normalized() * force);
|
.set_linear_velocity(prev_velocity + dir * force);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_shoot_visual(&mut self, _: DamageSource, _: i32, _: Vector3) {}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
use std::f32::consts::PI;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use godot::{
|
use godot::{
|
||||||
classes::{AudioStream, AudioStreamPlayer3D, GpuParticles3D, RandomNumberGenerator},
|
classes::{AudioStream, AudioStreamPlayer3D, GpuParticles3D},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{game::Game, util::shotgun_ray};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, GodotConvert, Export, Var, Default, PartialEq, PartialOrd, Eq)]
|
#[derive(Debug, Clone, Copy, GodotConvert, Export, Var, Default, PartialEq, PartialOrd, Eq)]
|
||||||
#[godot(via = GString)]
|
#[godot(via = GString)]
|
||||||
pub enum FootstepKind {
|
pub enum FootstepKind {
|
||||||
@ -38,10 +36,6 @@ pub struct PlayerEffects {
|
|||||||
footstep_sounds: Dictionary<FootstepKind, Option<Gd<AudioStream>>>,
|
footstep_sounds: Dictionary<FootstepKind, Option<Gd<AudioStream>>>,
|
||||||
#[export]
|
#[export]
|
||||||
walk_sfx_cd: f64,
|
walk_sfx_cd: f64,
|
||||||
#[export]
|
|
||||||
blood_decal: Option<Gd<PackedScene>>,
|
|
||||||
|
|
||||||
rng: Gd<RandomNumberGenerator>,
|
|
||||||
|
|
||||||
walk_sfx_cd_remaining: f64,
|
walk_sfx_cd_remaining: f64,
|
||||||
|
|
||||||
@ -99,44 +93,4 @@ impl PlayerEffects {
|
|||||||
sfx.set_stream(&sound);
|
sfx.set_stream(&sound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shoot_blood(&mut self, delta: Vector3, force: f32) {
|
|
||||||
self.run_deferred(move |s| {
|
|
||||||
if let Some(mut game) = Game::singleton()
|
|
||||||
&& let Some(map) = &mut game.bind_mut().current_map
|
|
||||||
&& let Some(prefab) = &s.blood_decal
|
|
||||||
{
|
|
||||||
let results = shotgun_ray(
|
|
||||||
s.base().get_global_position(),
|
|
||||||
s.base().get_global_position() + delta,
|
|
||||||
s.base().get_basis().col_c(),
|
|
||||||
&s.base().get_world_3d(),
|
|
||||||
&Array::new(),
|
|
||||||
10,
|
|
||||||
// Calculate the particular spread of blood
|
|
||||||
(((PI / 4.) * force) / delta.length()).min(PI / 2.),
|
|
||||||
10. + delta.length() / 3.,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut decal_results = Vec::new();
|
|
||||||
for _ in 0..(force * force * 3.) as usize {
|
|
||||||
if let Some(result) = results
|
|
||||||
.get(s.rng.randi_range(0, results.len() as i32 - 1) as usize)
|
|
||||||
.cloned()
|
|
||||||
{
|
|
||||||
decal_results.push(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for result in decal_results {
|
|
||||||
let mut decal = prefab.instantiate_as::<Node3D>();
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -939,28 +939,7 @@ impl LocalPlayer {
|
|||||||
|
|
||||||
#[godot_dyn]
|
#[godot_dyn]
|
||||||
impl Shootable for LocalPlayer {
|
impl Shootable for LocalPlayer {
|
||||||
fn on_shoot(&mut self, source: DamageSource, damage: i32, delta: Vector3) {
|
fn on_shoot(&mut self, source: DamageSource, damage: i32, _: Vector3) {
|
||||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
|
|
||||||
&& let PeerKind::Server(peer, _) = peer
|
|
||||||
{
|
|
||||||
peer.broadcast_reliable(Package::OnShot(
|
|
||||||
self.player_id.unwrap_or(0),
|
|
||||||
source,
|
|
||||||
damage,
|
|
||||||
delta.into(),
|
|
||||||
));
|
|
||||||
self.on_shoot_visual(source, damage, delta);
|
|
||||||
}
|
|
||||||
self.take_damage(source, damage, true);
|
self.take_damage(source, damage, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_shoot_visual(&mut self, source: DamageSource, damage: i32, delta: Vector3) {
|
|
||||||
self.run_deferred(move |s| {
|
|
||||||
if s.can_take_damage(&source)
|
|
||||||
&& let Some(fx) = &mut s.effects
|
|
||||||
{
|
|
||||||
fx.bind_mut().shoot_blood(delta, damage as f32 / 100.);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,7 +10,6 @@ use godot::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
game::{Game, opts::GameOption},
|
game::{Game, opts::GameOption},
|
||||||
map::{killbox::KillboxKind, pickup::PickupKind},
|
map::{killbox::KillboxKind, pickup::PickupKind},
|
||||||
net::network_manager::{NetworkManager, Package, PeerKind},
|
|
||||||
player::{
|
player::{
|
||||||
DamageSource, DamageSourceSignal, IPlayer, NetTransform, PlayerCommon,
|
DamageSource, DamageSourceSignal, IPlayer, NetTransform, PlayerCommon,
|
||||||
buffs::{Buff, Buffs},
|
buffs::{Buff, Buffs},
|
||||||
@ -502,28 +501,7 @@ impl RemotePlayer {
|
|||||||
|
|
||||||
#[godot_dyn]
|
#[godot_dyn]
|
||||||
impl Shootable for RemotePlayer {
|
impl Shootable for RemotePlayer {
|
||||||
fn on_shoot(&mut self, source: DamageSource, damage: i32, delta: Vector3) {
|
fn on_shoot(&mut self, source: DamageSource, damage: i32, _: Vector3) {
|
||||||
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer
|
|
||||||
&& let PeerKind::Server(peer, _) = peer
|
|
||||||
{
|
|
||||||
peer.broadcast_reliable(Package::OnShot(
|
|
||||||
self.player_id.unwrap_or(0),
|
|
||||||
source,
|
|
||||||
damage,
|
|
||||||
delta.into(),
|
|
||||||
));
|
|
||||||
self.on_shoot_visual(source, damage, delta);
|
|
||||||
}
|
|
||||||
self.take_damage(source, damage, true);
|
self.take_damage(source, damage, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_shoot_visual(&mut self, source: DamageSource, damage: i32, delta: Vector3) {
|
|
||||||
self.run_deferred(move |s| {
|
|
||||||
if s.can_take_damage(&source)
|
|
||||||
&& let Some(fx) = &mut s.effects
|
|
||||||
{
|
|
||||||
fx.bind_mut().shoot_blood(delta, damage as f32 / 100.);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,5 @@ use crate::player::DamageSource;
|
|||||||
use godot::prelude::*;
|
use godot::prelude::*;
|
||||||
|
|
||||||
pub trait Shootable {
|
pub trait Shootable {
|
||||||
fn on_shoot(&mut self, source: DamageSource, damage: i32, delta: Vector3);
|
fn on_shoot(&mut self, source: DamageSource, damage: i32, dir: Vector3);
|
||||||
fn on_shoot_visual(&mut self, source: DamageSource, damage: i32, delta: Vector3);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use std::{collections::HashMap, f32::consts::PI};
|
use std::{collections::HashSet, f32::consts::PI};
|
||||||
|
|
||||||
use godot::{
|
use godot::{
|
||||||
classes::{AudioStreamPlayer3D, GpuParticles3D, RandomNumberGenerator},
|
classes::{AudioStreamPlayer3D, GpuParticles3D, RandomNumberGenerator},
|
||||||
@ -104,13 +104,11 @@ impl Weapon for Raygun {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let beam_dir = (to - source.get_global_position()).normalized();
|
let dir = (to - source.get_global_position()).normalized();
|
||||||
let beam_end = target
|
let beam_end = target
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|r| r.position)
|
.map(|r| r.position)
|
||||||
.unwrap_or(source.get_global_position() + beam_dir * 100.);
|
.unwrap_or(source.get_global_position() + dir * 100.);
|
||||||
let delta = beam_end - source.get_global_position();
|
|
||||||
godot_print!("{}", delta);
|
|
||||||
|
|
||||||
if let Some(prefab) = &self.bullet_prefab
|
if let Some(prefab) = &self.bullet_prefab
|
||||||
&& play_fx
|
&& play_fx
|
||||||
@ -140,7 +138,7 @@ impl Weapon for Raygun {
|
|||||||
shootable.dyn_bind_mut().on_shoot(
|
shootable.dyn_bind_mut().on_shoot(
|
||||||
DamageSource::Player(player_id),
|
DamageSource::Player(player_id),
|
||||||
100,
|
100,
|
||||||
delta,
|
dir.normalized(),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -224,7 +222,7 @@ impl Weapon for Shotgun {
|
|||||||
vfx.set_emitting(true);
|
vfx.set_emitting(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut colliders: HashMap<Gd<Object>, Vec<Vector3>> = HashMap::new();
|
let mut colliders = HashSet::new();
|
||||||
let results = shotgun_ray(
|
let results = shotgun_ray(
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
@ -255,17 +253,17 @@ impl Weapon for Shotgun {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for result in &results {
|
for result in &results {
|
||||||
if let Some(positions) = colliders.get_mut(&result.collider) {
|
colliders.insert(result.collider.clone());
|
||||||
positions.push(result.position)
|
|
||||||
} else {
|
|
||||||
colliders.insert(result.collider.clone(), vec![result.position]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if deal_damage {
|
if deal_damage {
|
||||||
for (collider, positions) in colliders {
|
for collider in colliders {
|
||||||
let position = positions.iter().sum::<Vector3>() / positions.len() as f32;
|
let collider_pos = if let Ok(node) = collider.clone().try_cast::<Node3D>() {
|
||||||
let delta = position - from;
|
node.get_global_position()
|
||||||
|
} else {
|
||||||
|
Vector3::ZERO
|
||||||
|
};
|
||||||
|
let delta = collider_pos - from;
|
||||||
|
|
||||||
if let Ok(mut shootable) = collider.clone().try_dynify::<dyn Shootable>() {
|
if let Ok(mut shootable) = collider.clone().try_dynify::<dyn Shootable>() {
|
||||||
self.run_deferred(move |_| {
|
self.run_deferred(move |_| {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user