Compare commits
2 Commits
b2dbd2deee
...
c8d11f8a54
| Author | SHA1 | Date | |
|---|---|---|---|
| c8d11f8a54 | |||
| 41c50a764e |
@ -3,4 +3,5 @@
|
|||||||
[ext_resource type="MapResource" uid="uid://c7n1tacc7a73t" path="res://maps/default_map.tres" id="1_glms7"]
|
[ext_resource type="MapResource" uid="uid://c7n1tacc7a73t" path="res://maps/default_map.tres" id="1_glms7"]
|
||||||
|
|
||||||
[node name="game_manager" type="GameManager" unique_id=1442044769]
|
[node name="game_manager" type="GameManager" unique_id=1442044769]
|
||||||
|
respawn_timer = 5.0
|
||||||
maps = Array[MapResource]([ExtResource("1_glms7")])
|
maps = Array[MapResource]([ExtResource("1_glms7")])
|
||||||
|
|||||||
@ -8,13 +8,14 @@ glow_enabled = true
|
|||||||
|
|
||||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
|
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_oh8vq"]
|
||||||
|
|
||||||
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch")]
|
[node name="player" type="LocalPlayer" unique_id=863055906 node_paths=PackedStringArray("camera", "soldier_mesh", "collider", "splorch", "dead_cam_target")]
|
||||||
look_sensitivity = 1.5
|
look_sensitivity = 1.5
|
||||||
camera = NodePath("camera_3d")
|
camera = NodePath("camera_3d")
|
||||||
move_speed = 5.0
|
move_speed = 5.0
|
||||||
soldier_mesh = NodePath("soldier_m")
|
soldier_mesh = NodePath("soldier_m")
|
||||||
collider = NodePath("collision_shape_3d2")
|
collider = NodePath("collision_shape_3d2")
|
||||||
splorch = NodePath("splorch")
|
splorch = NodePath("splorch")
|
||||||
|
dead_cam_target = NodePath("dead_camera_target")
|
||||||
health = 100
|
health = 100
|
||||||
collision_mask = 4
|
collision_mask = 4
|
||||||
|
|
||||||
@ -33,3 +34,6 @@ shape = SubResource("CapsuleShape3D_oh8vq")
|
|||||||
|
|
||||||
[node name="splorch" parent="." unique_id=986677517 instance=ExtResource("2_ywmwa")]
|
[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)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.16157162, 1.4223524, 0)
|
||||||
|
|
||||||
|
[node name="dead_camera_target" type="Node3D" parent="." unique_id=559969559]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.9069022, 0.4213412, 0, -0.4213412, 0.9069022, 0, 2.3258846, 1.5254744)
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use crate::{
|
|||||||
net::{
|
net::{
|
||||||
network_manager::{
|
network_manager::{
|
||||||
NetworkManager,
|
NetworkManager,
|
||||||
Package::{self, Kill, SelfSync, TakeDamage},
|
Package::{self, Kill, SelfSync, SpawnPlayer, TakeDamage},
|
||||||
PeerKind, SyncPackage,
|
PeerKind, SyncPackage,
|
||||||
},
|
},
|
||||||
util::NetVector3,
|
util::NetVector3,
|
||||||
@ -22,6 +22,9 @@ pub const GAME_MANAGER_GLOBAL: &str = "GameManagerGlobal";
|
|||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
#[class(base=Node, init)]
|
#[class(base=Node, init)]
|
||||||
pub struct GameManager {
|
pub struct GameManager {
|
||||||
|
#[export]
|
||||||
|
pub respawn_timer: f64,
|
||||||
|
|
||||||
pub game: Option<Gd<Game>>,
|
pub game: Option<Gd<Game>>,
|
||||||
base: Base<Node>,
|
base: Base<Node>,
|
||||||
|
|
||||||
@ -51,6 +54,7 @@ impl GameManager {
|
|||||||
let mut game = Game::new_alloc();
|
let mut game = Game::new_alloc();
|
||||||
game.bind_mut().is_host = is_host;
|
game.bind_mut().is_host = is_host;
|
||||||
game.bind_mut().maps = self.maps.clone();
|
game.bind_mut().maps = self.maps.clone();
|
||||||
|
game.bind_mut().respawn_timer = self.respawn_timer;
|
||||||
|
|
||||||
self.run_deferred(|s| {
|
self.run_deferred(|s| {
|
||||||
if let Some(game) = &s.game {
|
if let Some(game) = &s.game {
|
||||||
@ -78,6 +82,9 @@ impl GameManager {
|
|||||||
#[derive(GodotClass)]
|
#[derive(GodotClass)]
|
||||||
#[class(base=Node, init)]
|
#[class(base=Node, init)]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
|
#[export]
|
||||||
|
pub respawn_timer: f64,
|
||||||
|
|
||||||
pub selected_map_idx: u8,
|
pub selected_map_idx: u8,
|
||||||
pub selected_map: Option<Gd<MapResource>>,
|
pub selected_map: Option<Gd<MapResource>>,
|
||||||
pub maps: Array<Gd<MapResource>>,
|
pub maps: Array<Gd<MapResource>>,
|
||||||
@ -143,6 +150,25 @@ impl INode for Game {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(peer) = &mut NetworkManager::singleton().bind_mut().peer {
|
||||||
|
if let PeerKind::Server(peer, _) = peer {
|
||||||
|
for player in self.players.clone() {
|
||||||
|
if let Some(character) = player.character {
|
||||||
|
if character.dyn_bind().dead_for() > self.respawn_timer {
|
||||||
|
let character = self.spawn_player_server(player.id);
|
||||||
|
|
||||||
|
if let Some(character) = character {
|
||||||
|
peer.broadcast_reliable(SpawnPlayer(
|
||||||
|
player.id,
|
||||||
|
character.dyn_bind().get_transform(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,55 +298,58 @@ impl Game {
|
|||||||
} else {
|
} else {
|
||||||
self.run_deferred(|s| {
|
self.run_deferred(|s| {
|
||||||
for player in s.players.clone() {
|
for player in s.players.clone() {
|
||||||
let player_id = player.id;
|
s.spawn_player_server(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,
|
}
|
||||||
);
|
|
||||||
|
pub fn spawn_player_server(&mut self, id: u16) -> Option<DynGd<CharacterBody3D, dyn IPlayer>> {
|
||||||
|
if let Some(player) = self.find_player_mut(id)
|
||||||
|
&& let Some(character) = &mut player.character
|
||||||
|
{
|
||||||
|
// This is a respawn, remove old character
|
||||||
|
character.queue_free();
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(mut map) = self.current_map.clone() {
|
||||||
|
let mut character =
|
||||||
|
map.bind_mut()
|
||||||
|
.spawn_player(id, id == self.self_id.unwrap_or(0), None);
|
||||||
|
|
||||||
if let Some(character) = &mut character {
|
if let Some(character) = &mut character {
|
||||||
if let Ok(mut local_player) =
|
if let Ok(mut local_player) = character.clone().try_cast::<LocalPlayer>() {
|
||||||
character.clone().try_cast::<LocalPlayer>()
|
|
||||||
{
|
|
||||||
local_player
|
local_player
|
||||||
.bind_mut()
|
.bind_mut()
|
||||||
.signals()
|
.signals()
|
||||||
.on_die()
|
.on_die()
|
||||||
.connect_other(s, move |s| s.on_death(player_id));
|
.connect_other(self, move |s| s.on_death(id));
|
||||||
local_player
|
local_player
|
||||||
.bind_mut()
|
.bind_mut()
|
||||||
.signals()
|
.signals()
|
||||||
.on_take_damage()
|
.on_take_damage()
|
||||||
.connect_other(s, move |s, damage| {
|
.connect_other(self, move |s, damage| s.on_take_damage(id, damage));
|
||||||
s.on_take_damage(player_id, damage)
|
} else if let Ok(mut remote_player) = character.clone().try_cast::<RemotePlayer>() {
|
||||||
});
|
|
||||||
} else if let Ok(mut remote_player) =
|
|
||||||
character.clone().try_cast::<RemotePlayer>()
|
|
||||||
{
|
|
||||||
remote_player
|
remote_player
|
||||||
.bind_mut()
|
.bind_mut()
|
||||||
.signals()
|
.signals()
|
||||||
.on_die()
|
.on_die()
|
||||||
.connect_other(s, move |s| s.on_death(player_id));
|
.connect_other(self, move |s| s.on_death(id));
|
||||||
remote_player
|
remote_player
|
||||||
.bind_mut()
|
.bind_mut()
|
||||||
.signals()
|
.signals()
|
||||||
.on_take_damage()
|
.on_take_damage()
|
||||||
.connect_other(s, move |s, damage| {
|
.connect_other(self, move |s, damage| s.on_take_damage(id, damage));
|
||||||
s.on_take_damage(player_id, damage)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(player) = s.find_player_mut(player_id) {
|
if let Some(player) = self.find_player_mut(id) {
|
||||||
player.character = character;
|
player.character = character.clone();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
character
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,8 +357,13 @@ impl Game {
|
|||||||
pub fn spawn_player_client(&mut self, id: u16, transform: NetPlayerTransform) {
|
pub fn spawn_player_client(&mut self, id: u16, transform: NetPlayerTransform) {
|
||||||
if let Some(map) = &mut self.current_map {
|
if let Some(map) = &mut self.current_map {
|
||||||
if let Some(player) = self.players.iter_mut().find(|p| p.id == id) {
|
if let Some(player) = self.players.iter_mut().find(|p| p.id == id) {
|
||||||
|
if let Some(character) = &mut player.character {
|
||||||
|
// This is a respawn, delete old character
|
||||||
|
character.queue_free();
|
||||||
|
}
|
||||||
|
|
||||||
let character = map.bind_mut().spawn_player(
|
let character = map.bind_mut().spawn_player(
|
||||||
player,
|
player.id,
|
||||||
player.id == self.self_id.unwrap_or(0),
|
player.id == self.self_id.unwrap_or(0),
|
||||||
Some(transform),
|
Some(transform),
|
||||||
);
|
);
|
||||||
@ -410,7 +444,6 @@ impl Game {
|
|||||||
|
|
||||||
// Handle dying, from server to client
|
// Handle dying, from server to client
|
||||||
pub fn handle_kill(&mut self, player_id: u16) {
|
pub fn handle_kill(&mut self, player_id: u16) {
|
||||||
godot_print!("Got kill!");
|
|
||||||
if let Some(player) = self.find_player_mut(player_id) {
|
if let Some(player) = self.find_player_mut(player_id) {
|
||||||
if let Some(character) = &mut player.character {
|
if let Some(character) = &mut player.character {
|
||||||
character.dyn_bind_mut().kill();
|
character.dyn_bind_mut().kill();
|
||||||
|
|||||||
@ -34,14 +34,14 @@ impl Map {
|
|||||||
|
|
||||||
pub fn spawn_player(
|
pub fn spawn_player(
|
||||||
&mut self,
|
&mut self,
|
||||||
player: &Player,
|
player_id: u16,
|
||||||
is_local: bool,
|
is_local: bool,
|
||||||
transform: Option<NetPlayerTransform>,
|
transform: Option<NetPlayerTransform>,
|
||||||
) -> Option<DynGd<CharacterBody3D, dyn IPlayer + 'static>> {
|
) -> Option<DynGd<CharacterBody3D, dyn IPlayer + 'static>> {
|
||||||
if is_local {
|
if is_local {
|
||||||
if let Some(local_player) = &self.local_player {
|
if let Some(local_player) = &self.local_player {
|
||||||
let mut node = local_player.instantiate_as::<LocalPlayer>();
|
let mut node = local_player.instantiate_as::<LocalPlayer>();
|
||||||
node.bind_mut().player_id = Some(player.id);
|
node.bind_mut().player_id = Some(player_id);
|
||||||
self.base_mut().add_child(&node);
|
self.base_mut().add_child(&node);
|
||||||
if let Some(transform) = transform {
|
if let Some(transform) = transform {
|
||||||
node.bind_mut()
|
node.bind_mut()
|
||||||
@ -63,7 +63,7 @@ impl Map {
|
|||||||
}
|
}
|
||||||
} else if let Some(remote_player) = &self.remote_player {
|
} else if let Some(remote_player) = &self.remote_player {
|
||||||
let mut node = remote_player.instantiate_as::<RemotePlayer>();
|
let mut node = remote_player.instantiate_as::<RemotePlayer>();
|
||||||
node.bind_mut().player_id = Some(player.id);
|
node.bind_mut().player_id = Some(player_id);
|
||||||
self.base_mut().add_child(&node);
|
self.base_mut().add_child(&node);
|
||||||
if let Some(transform) = transform {
|
if let Some(transform) = transform {
|
||||||
node.bind_mut()
|
node.bind_mut()
|
||||||
|
|||||||
@ -48,6 +48,7 @@ pub trait IPlayer {
|
|||||||
fn take_damage(&mut self, damage: i32, kill: bool);
|
fn take_damage(&mut self, damage: i32, kill: bool);
|
||||||
fn is_dead(&self) -> bool;
|
fn is_dead(&self) -> bool;
|
||||||
fn kill(&mut self);
|
fn kill(&mut self);
|
||||||
|
fn dead_for(&self) -> f64;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait PlayerMovement {
|
pub trait PlayerMovement {
|
||||||
@ -94,6 +95,8 @@ pub struct LocalPlayer {
|
|||||||
#[export]
|
#[export]
|
||||||
splorch: Option<Gd<GpuParticles3D>>,
|
splorch: Option<Gd<GpuParticles3D>>,
|
||||||
#[export]
|
#[export]
|
||||||
|
dead_cam_target: Option<Gd<Node3D>>,
|
||||||
|
#[export]
|
||||||
health: i32,
|
health: i32,
|
||||||
|
|
||||||
pub player_id: Option<u16>,
|
pub player_id: Option<u16>,
|
||||||
@ -106,6 +109,7 @@ pub struct LocalPlayer {
|
|||||||
shoot_cd: f64,
|
shoot_cd: f64,
|
||||||
|
|
||||||
is_dead: bool,
|
is_dead: bool,
|
||||||
|
dead_for: f64,
|
||||||
|
|
||||||
locked: bool,
|
locked: bool,
|
||||||
|
|
||||||
@ -199,6 +203,10 @@ impl IPlayer for LocalPlayer {
|
|||||||
self.is_dead
|
self.is_dead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dead_for(&self) -> f64 {
|
||||||
|
self.dead_for
|
||||||
|
}
|
||||||
|
|
||||||
fn kill(&mut self) {
|
fn kill(&mut self) {
|
||||||
self.run_deferred(move |s| s.signals().on_die().emit());
|
self.run_deferred(move |s| s.signals().on_die().emit());
|
||||||
if let Some(mut mesh) = self.soldier_mesh.take() {
|
if let Some(mut mesh) = self.soldier_mesh.take() {
|
||||||
@ -241,6 +249,10 @@ impl ICharacterBody3D for LocalPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, delta: f64) {
|
fn process(&mut self, delta: f64) {
|
||||||
|
if self.is_dead {
|
||||||
|
self.dead_for += delta;
|
||||||
|
}
|
||||||
|
|
||||||
self.shoot_cd -= delta;
|
self.shoot_cd -= delta;
|
||||||
|
|
||||||
let input_direction = if self.locked {
|
let input_direction = if self.locked {
|
||||||
@ -264,6 +276,15 @@ impl ICharacterBody3D for LocalPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.player_update(delta);
|
self.player_update(delta);
|
||||||
|
|
||||||
|
if self.is_dead
|
||||||
|
&& let Some(target) = &self.dead_cam_target
|
||||||
|
&& let Some(camera) = &mut self.camera
|
||||||
|
{
|
||||||
|
let camera_prev_pos = camera.get_global_position();
|
||||||
|
let new_pos = camera_prev_pos.lerp(target.get_global_position(), 0.1);
|
||||||
|
camera.set_global_position(new_pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn input(&mut self, event: Gd<InputEvent>) {
|
fn input(&mut self, event: Gd<InputEvent>) {
|
||||||
@ -370,6 +391,7 @@ pub struct RemotePlayer {
|
|||||||
look_up: f32,
|
look_up: f32,
|
||||||
|
|
||||||
is_dead: bool,
|
is_dead: bool,
|
||||||
|
dead_for: f64,
|
||||||
|
|
||||||
shoot_cd: f64,
|
shoot_cd: f64,
|
||||||
|
|
||||||
@ -461,6 +483,10 @@ impl IPlayer for RemotePlayer {
|
|||||||
self.is_dead
|
self.is_dead
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dead_for(&self) -> f64 {
|
||||||
|
self.dead_for
|
||||||
|
}
|
||||||
|
|
||||||
fn kill(&mut self) {
|
fn kill(&mut self) {
|
||||||
self.run_deferred(move |s| s.signals().on_die().emit());
|
self.run_deferred(move |s| s.signals().on_die().emit());
|
||||||
if let Some(mut mesh) = self.soldier_mesh.take() {
|
if let Some(mut mesh) = self.soldier_mesh.take() {
|
||||||
@ -488,6 +514,10 @@ impl ICharacterBody3D for RemotePlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn process(&mut self, delta: f64) {
|
fn process(&mut self, delta: f64) {
|
||||||
|
if self.is_dead {
|
||||||
|
self.dead_for += delta;
|
||||||
|
}
|
||||||
|
|
||||||
self.player_update(delta);
|
self.player_update(delta);
|
||||||
|
|
||||||
self.shoot_cd -= delta;
|
self.shoot_cd -= delta;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user