Implement killing almost
This commit is contained in:
parent
0678c56dae
commit
a2cf76701f
@ -1,17 +1,20 @@
|
||||
[gd_scene format=3 uid="uid://ct70bpbca8one"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bod6b3befmyt5" path="res://scenes/player/soldier_m.tscn" id="1_jd651"]
|
||||
[ext_resource type="PackedScene" uid="uid://cl66unms2gim0" path="res://scenes/player/splorch.tscn" id="2_ywmwa"]
|
||||
|
||||
[sub_resource type="Environment" id="Environment_3nx84"]
|
||||
glow_enabled = true
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
|
||||
|
||||
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh")]
|
||||
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch")]
|
||||
look_sensitivity = 1.5
|
||||
camera = NodePath("camera_3d")
|
||||
move_speed = 5.0
|
||||
soldier_mesh = NodePath("soldier_m")
|
||||
collider = NodePath("collision_shape_3d2")
|
||||
splorch = NodePath("splorch")
|
||||
health = 100
|
||||
collision_mask = 4
|
||||
|
||||
@ -27,3 +30,6 @@ transform = Transform3D(-0.5, 0, -4.371139e-08, 0, 0.5, 0, 4.371139e-08, 0, -0.5
|
||||
[node name="collision_shape_3d2" type="CollisionShape3D" parent="." unique_id=442150782]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0310049, 0)
|
||||
shape = SubResource("CapsuleShape3D_oh8vq")
|
||||
|
||||
[node name="splorch" parent="." unique_id=986677517 instance=ExtResource("2_ywmwa")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.16157162, 1.4223524, 0)
|
||||
|
||||
@ -1,12 +1,15 @@
|
||||
[gd_scene format=3 uid="uid://kfxc0migw80o"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bod6b3befmyt5" path="res://scenes/player/soldier_m.tscn" id="1_e2ekk"]
|
||||
[ext_resource type="PackedScene" uid="uid://cl66unms2gim0" path="res://scenes/player/splorch.tscn" id="2_orxjf"]
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_1cgct"]
|
||||
|
||||
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh")]
|
||||
[node name="player" type="RemotePlayer" unique_id=845968872 node_paths=PackedStringArray("soldier_mesh", "collider", "splorch")]
|
||||
move_speed = 5.0
|
||||
soldier_mesh = NodePath("soldier_m")
|
||||
collider = NodePath("collision_shape_3d")
|
||||
splorch = NodePath("gpu_particles_3d")
|
||||
health = 100
|
||||
collision_layer = 2
|
||||
collision_mask = 4
|
||||
@ -17,3 +20,6 @@ transform = Transform3D(-0.5, 0, -4.371139e-08, 0, 0.5, 0, 4.371139e-08, 0, -0.5
|
||||
[node name="collision_shape_3d" type="CollisionShape3D" parent="." unique_id=1110995513]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.0310049, 0)
|
||||
shape = SubResource("CapsuleShape3D_1cgct")
|
||||
|
||||
[node name="gpu_particles_3d" parent="." unique_id=986677517 instance=ExtResource("2_orxjf")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4540546, 0)
|
||||
|
||||
34
godot/scenes/player/splorch.tscn
Normal file
34
godot/scenes/player/splorch.tscn
Normal file
@ -0,0 +1,34 @@
|
||||
[gd_scene format=3 uid="uid://cl66unms2gim0"]
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_1cgct"]
|
||||
particle_flag_align_y = true
|
||||
direction = Vector3(0, 1, 0)
|
||||
spread = 90.0
|
||||
initial_velocity_min = 2.0
|
||||
initial_velocity_max = 5.0
|
||||
|
||||
[sub_resource type="Curve" id="Curve_yli5f"]
|
||||
_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.08643617, 1), -3.6585922, -3.6585922, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
|
||||
point_count = 3
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_dmbod"]
|
||||
albedo_color = Color(0.44894964, 1.3055467e-06, 9.62615e-08, 1)
|
||||
use_particle_trails = true
|
||||
|
||||
[sub_resource type="TubeTrailMesh" id="TubeTrailMesh_wwb7k"]
|
||||
material = SubResource("StandardMaterial3D_dmbod")
|
||||
radius = 0.1
|
||||
radial_steps = 20
|
||||
section_length = 0.1
|
||||
section_rings = 10
|
||||
curve = SubResource("Curve_yli5f")
|
||||
|
||||
[node name="gpu_particles_3d" type="GPUParticles3D" unique_id=986677517]
|
||||
emitting = false
|
||||
amount = 20
|
||||
one_shot = true
|
||||
explosiveness = 0.78
|
||||
trail_enabled = true
|
||||
trail_lifetime = 0.5
|
||||
process_material = SubResource("ParticleProcessMaterial_1cgct")
|
||||
draw_pass_1 = SubResource("TubeTrailMesh_wwb7k")
|
||||
@ -14,7 +14,7 @@ use crate::{
|
||||
},
|
||||
util::NetVector3,
|
||||
},
|
||||
player::{IPlayer, NetPlayerTransform},
|
||||
player::{IPlayer, LocalPlayer, NetPlayerTransform, RemotePlayer},
|
||||
};
|
||||
|
||||
pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
||||
@ -117,6 +117,11 @@ impl INode for Game {
|
||||
PeerKind::Server(peer, _) => {
|
||||
let mut sync_data = HashMap::new();
|
||||
for player in &self.players {
|
||||
if let Some(character) = &player.character {
|
||||
if character.dyn_bind().is_dead() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if let (Some(dir), Some(look_up), Some(transform)) = (
|
||||
player.get_move_dir(),
|
||||
player.get_look_up(),
|
||||
@ -266,16 +271,40 @@ impl Game {
|
||||
peer.send_reliable(to, Package::MapLoaded);
|
||||
} else {
|
||||
self.run_deferred(|s| {
|
||||
for player in &mut s.players {
|
||||
if let Some(map) = &mut s.current_map {
|
||||
let character = map.bind_mut().spawn_player(
|
||||
player,
|
||||
for player in s.players.clone() {
|
||||
let player_id = player.id;
|
||||
if let Some(mut map) = s.current_map.clone() {
|
||||
let mut character = map.bind_mut().spawn_player(
|
||||
&player,
|
||||
player.id == s.self_id.unwrap_or(0),
|
||||
None,
|
||||
);
|
||||
|
||||
if let Some(character) = &mut character {
|
||||
if let Ok(mut local_player) =
|
||||
character.clone().try_cast::<LocalPlayer>()
|
||||
{
|
||||
local_player
|
||||
.bind_mut()
|
||||
.signals()
|
||||
.on_die()
|
||||
.connect_other(s, move |s| s.on_death(player_id));
|
||||
} else if let Ok(mut local_player) =
|
||||
character.clone().try_cast::<RemotePlayer>()
|
||||
{
|
||||
local_player
|
||||
.bind_mut()
|
||||
.signals()
|
||||
.on_die()
|
||||
.connect_other(s, move |s| s.on_death(player_id));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(player) = s.find_player_mut(player_id) {
|
||||
player.character = character;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -351,6 +380,10 @@ impl Game {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn on_death(&mut self, player_id: u16) {
|
||||
godot_print!("Player {} has died!", player_id);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -448,7 +481,7 @@ impl Player {
|
||||
.dyn_bind_mut()
|
||||
.apply_rotation(transform.rotation.into());
|
||||
character.dyn_bind_mut().apply_look_up(look_up);
|
||||
character.dyn_bind_mut().try_shoot(to, true)
|
||||
character.dyn_bind_mut().try_shoot(to, deal_damage)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
@ -2,8 +2,9 @@ use std::{f32::consts::PI, ops::Neg};
|
||||
|
||||
use godot::{
|
||||
classes::{
|
||||
AudioStreamPlayer3D, Camera3D, CharacterBody3D, ICharacterBody3D, Input, InputEvent,
|
||||
InputEventMouseMotion, PhysicsRayQueryParameters3D, input::MouseMode,
|
||||
AudioStreamPlayer3D, Camera3D, CharacterBody3D, CollisionShape3D, GpuParticles3D,
|
||||
ICharacterBody3D, Input, InputEvent, InputEventMouseMotion, PhysicsRayQueryParameters3D,
|
||||
input::MouseMode,
|
||||
},
|
||||
obj::WithBaseField,
|
||||
prelude::*,
|
||||
@ -45,6 +46,8 @@ pub trait IPlayer {
|
||||
fn jump(&mut self);
|
||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool;
|
||||
fn take_damage(&mut self, damage: i32);
|
||||
fn is_dead(&self) -> bool;
|
||||
fn kill(&mut self);
|
||||
}
|
||||
|
||||
pub trait PlayerMovement {
|
||||
@ -83,6 +86,10 @@ pub struct LocalPlayer {
|
||||
#[export]
|
||||
soldier_mesh: Option<Gd<SoldierMesh>>,
|
||||
#[export]
|
||||
collider: Option<Gd<CollisionShape3D>>,
|
||||
#[export]
|
||||
splorch: Option<Gd<GpuParticles3D>>,
|
||||
#[export]
|
||||
health: i32,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
@ -94,6 +101,8 @@ pub struct LocalPlayer {
|
||||
|
||||
shoot_cd: f64,
|
||||
|
||||
is_dead: bool,
|
||||
|
||||
locked: bool,
|
||||
|
||||
base: Base<CharacterBody3D>,
|
||||
@ -158,6 +167,10 @@ impl IPlayer for LocalPlayer {
|
||||
fn apply_look_up(&mut self, _look: f32) {}
|
||||
|
||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool {
|
||||
if self.is_dead {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.shoot_cd <= 0. {
|
||||
let rid = self.base().get_rid();
|
||||
if let Some(weapon) = &mut self.weapon {
|
||||
@ -171,8 +184,31 @@ impl IPlayer for LocalPlayer {
|
||||
}
|
||||
|
||||
fn take_damage(&mut self, damage: i32) {
|
||||
godot_print!("Took damage!");
|
||||
self.health -= damage;
|
||||
if self.health <= 0 {
|
||||
self.kill();
|
||||
}
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
self.is_dead
|
||||
}
|
||||
|
||||
fn kill(&mut self) {
|
||||
self.signals().on_die().emit();
|
||||
if let Some(mut mesh) = self.soldier_mesh.take() {
|
||||
mesh.queue_free();
|
||||
}
|
||||
if let Some(mut weapon) = self.weapon.take() {
|
||||
weapon.queue_free();
|
||||
}
|
||||
if let Some(mut collider) = self.collider.take() {
|
||||
collider.queue_free();
|
||||
}
|
||||
if let Some(splorch) = &mut self.splorch {
|
||||
splorch.set_emitting(true);
|
||||
}
|
||||
self.is_dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -288,7 +324,11 @@ impl ICharacterBody3D for LocalPlayer {
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl LocalPlayer {
|
||||
#[signal]
|
||||
pub fn on_die();
|
||||
|
||||
fn set_lock(&mut self, locked: bool) {
|
||||
self.locked = locked;
|
||||
if self.locked {
|
||||
@ -307,6 +347,10 @@ pub struct RemotePlayer {
|
||||
#[export]
|
||||
soldier_mesh: Option<Gd<SoldierMesh>>,
|
||||
#[export]
|
||||
collider: Option<Gd<CollisionShape3D>>,
|
||||
#[export]
|
||||
splorch: Option<Gd<GpuParticles3D>>,
|
||||
#[export]
|
||||
health: i32,
|
||||
|
||||
pub player_id: Option<u16>,
|
||||
@ -316,6 +360,8 @@ pub struct RemotePlayer {
|
||||
y_speed: f32,
|
||||
look_up: f32,
|
||||
|
||||
is_dead: bool,
|
||||
|
||||
shoot_cd: f64,
|
||||
|
||||
base: Base<CharacterBody3D>,
|
||||
@ -378,6 +424,10 @@ impl IPlayer for RemotePlayer {
|
||||
}
|
||||
|
||||
fn try_shoot(&mut self, to: Vector3, deal_damage: bool) -> bool {
|
||||
if self.is_dead {
|
||||
return false;
|
||||
}
|
||||
|
||||
if self.shoot_cd <= 0. {
|
||||
let rid = self.base().get_rid();
|
||||
if let Some(weapon) = &mut self.weapon {
|
||||
@ -391,8 +441,31 @@ impl IPlayer for RemotePlayer {
|
||||
}
|
||||
|
||||
fn take_damage(&mut self, damage: i32) {
|
||||
godot_print!("Took damage!");
|
||||
self.health -= damage;
|
||||
if self.health <= 0 {
|
||||
self.kill();
|
||||
}
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
self.is_dead
|
||||
}
|
||||
|
||||
fn kill(&mut self) {
|
||||
self.signals().on_die().emit();
|
||||
if let Some(mut mesh) = self.soldier_mesh.take() {
|
||||
mesh.queue_free();
|
||||
}
|
||||
if let Some(mut weapon) = self.weapon.take() {
|
||||
weapon.queue_free();
|
||||
}
|
||||
if let Some(mut collider) = self.collider.take() {
|
||||
collider.queue_free();
|
||||
}
|
||||
if let Some(splorch) = &mut self.splorch {
|
||||
splorch.set_emitting(true);
|
||||
}
|
||||
self.is_dead = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -417,3 +490,9 @@ impl ICharacterBody3D for RemotePlayer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[godot_api]
|
||||
impl RemotePlayer {
|
||||
#[signal]
|
||||
pub fn on_die();
|
||||
}
|
||||
|
||||
@ -55,7 +55,6 @@ impl Weapon for Raygun {
|
||||
}
|
||||
|
||||
if deal_damage && let Some(target) = target {
|
||||
godot_print!("{}", target.collider);
|
||||
if let Ok(mut player) = target.collider.try_dynify::<dyn IPlayer>() {
|
||||
player.dyn_bind_mut().take_damage(100);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user