Implement friendly fire gamerule
This commit is contained in:
parent
f732472f7c
commit
4f9e24f5ab
@ -11,7 +11,7 @@ use godot::{
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
game_manager::Game,
|
||||
game_manager::{Game, GameOption},
|
||||
net::{
|
||||
network_manager::{
|
||||
NetworkManager,
|
||||
@ -56,14 +56,15 @@ pub trait IPlayer {
|
||||
fn get_ball_origin(&self) -> Option<Gd<Node3D>>;
|
||||
}
|
||||
|
||||
pub trait PlayerMovement {
|
||||
pub trait PlayerCommon {
|
||||
fn player_update(&mut self, delta: f64);
|
||||
fn try_jump(&mut self) -> bool;
|
||||
fn drop_ball_common(&mut self, with_velocity: bool) -> bool;
|
||||
fn get_look_dir(&self) -> Vector3;
|
||||
fn can_take_damage(&self, source: &DamageSource) -> bool;
|
||||
}
|
||||
|
||||
impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerMovement for T {
|
||||
impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerCommon for T {
|
||||
fn player_update(&mut self, delta: f64) {
|
||||
self.set_y_speed(self.get_y_speed() - 9.8 * delta as f32);
|
||||
if self.base().is_on_floor() && self.get_y_speed() < 0. {
|
||||
@ -141,6 +142,30 @@ impl<T: IPlayer + ICharacterBody3D + WithBaseField> PlayerMovement for T {
|
||||
Vector3::ZERO
|
||||
}
|
||||
}
|
||||
|
||||
fn can_take_damage(&self, source: &DamageSource) -> bool {
|
||||
match source {
|
||||
DamageSource::Player(source_player_id) => {
|
||||
if let Some(game) = Game::singleton() {
|
||||
let (self_team, source_team) = if let Some(self_player) =
|
||||
game.bind().find_player(self.get_player_id().unwrap_or(0))
|
||||
&& let Some(source_player) = game.bind().find_player(*source_player_id)
|
||||
{
|
||||
(self_player.data.team, source_player.data.team)
|
||||
} else {
|
||||
(0, 0)
|
||||
};
|
||||
if self_team == source_team
|
||||
&& !game.bind().opts.is_true(GameOption::FriendlyFire)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(GodotClass)]
|
||||
@ -271,12 +296,16 @@ impl IPlayer for LocalPlayer {
|
||||
}
|
||||
|
||||
fn take_damage(&mut self, source: DamageSource, damage: i32, kill: bool) {
|
||||
let (signal, player) = source.into_signal();
|
||||
self.run_deferred(move |s| s.signals().on_take_damage().emit(signal, player, damage));
|
||||
self.health -= damage;
|
||||
if kill && self.health <= 0 {
|
||||
self.kill(source);
|
||||
}
|
||||
self.run_deferred(move |s| {
|
||||
if s.can_take_damage(&source) {
|
||||
let (signal, player) = source.into_signal();
|
||||
s.run_deferred(move |s| s.signals().on_take_damage().emit(signal, player, damage));
|
||||
s.health -= damage;
|
||||
if kill && s.health <= 0 {
|
||||
s.kill(source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
@ -645,12 +674,16 @@ impl IPlayer for RemotePlayer {
|
||||
}
|
||||
|
||||
fn take_damage(&mut self, source: DamageSource, damage: i32, kill: bool) {
|
||||
let (signal, player) = source.into_signal();
|
||||
self.run_deferred(move |s| s.signals().on_take_damage().emit(signal, player, damage));
|
||||
self.health -= damage;
|
||||
if kill && self.health <= 0 {
|
||||
self.kill(source);
|
||||
}
|
||||
self.run_deferred(move |s| {
|
||||
if s.can_take_damage(&source) {
|
||||
let (signal, player) = source.into_signal();
|
||||
s.run_deferred(move |s| s.signals().on_take_damage().emit(signal, player, damage));
|
||||
s.health -= damage;
|
||||
if kill && s.health <= 0 {
|
||||
s.kill(source);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fn is_dead(&self) -> bool {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user