Add some preliminary chat messages
This commit is contained in:
parent
f053c789a6
commit
c414e6d7c4
93
rust/src/chat.rs
Normal file
93
rust/src/chat.rs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
use godot::{classes::RichTextLabel, prelude::*};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
announcer::Announcement,
|
||||||
|
game_manager::{Game, Player},
|
||||||
|
player::DamageSource,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(GodotClass)]
|
||||||
|
#[class(base=Node, init)]
|
||||||
|
pub struct Chat {
|
||||||
|
messages: Vec<ChatMessage>,
|
||||||
|
base: Base<Node>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[godot_api]
|
||||||
|
impl Chat {
|
||||||
|
#[signal]
|
||||||
|
pub fn on_new_message(idx: Gd<RichTextLabel>);
|
||||||
|
|
||||||
|
pub fn singleton() -> Option<Gd<Chat>> {
|
||||||
|
Game::singleton().and_then(|g| g.get_child(0).map(|c| c.cast()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_messages(&self) -> Vec<Gd<RichTextLabel>> {
|
||||||
|
self.messages.iter().map(|m| m.as_label()).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_message(&mut self, message: ChatMessage) {
|
||||||
|
self.messages.len() as i64;
|
||||||
|
self.messages.push(message.clone());
|
||||||
|
self.signals().on_new_message().emit(&message.as_label());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum ChatMessage {
|
||||||
|
Death(DamageSource, u16),
|
||||||
|
Announcement(u16, Announcement),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChatMessage {
|
||||||
|
pub fn as_label(&self) -> Gd<RichTextLabel> {
|
||||||
|
let mut label = RichTextLabel::new_alloc();
|
||||||
|
match self {
|
||||||
|
ChatMessage::Death(source, player_id) => {
|
||||||
|
if let Some(game) = Game::singleton()
|
||||||
|
&& let Some(player) = game.bind().find_player(*player_id)
|
||||||
|
{
|
||||||
|
match source {
|
||||||
|
DamageSource::Player(source_id) => {
|
||||||
|
if let Some(source) = game.bind().find_player(*source_id) {
|
||||||
|
add_player(&mut label, source);
|
||||||
|
label.append_text(" fragged ");
|
||||||
|
add_player(&mut label, &player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DamageSource::Killbox => {
|
||||||
|
add_player(&mut label, &player);
|
||||||
|
label.append_text(" fell into the void");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ChatMessage::Announcement(player_id, announcement) => {
|
||||||
|
if let Some(game) = Game::singleton()
|
||||||
|
&& let Some(player) = game.bind().find_player(*player_id)
|
||||||
|
{
|
||||||
|
add_player(&mut label, &player);
|
||||||
|
label.append_text(" got ");
|
||||||
|
let what = match announcement {
|
||||||
|
Announcement::FirstBlood => "First Blood",
|
||||||
|
Announcement::DoubleKill => "a Double Kill",
|
||||||
|
Announcement::TripleKill => "a Triple Kill",
|
||||||
|
Announcement::MegaKill => "a Mega Kill",
|
||||||
|
};
|
||||||
|
label.append_text(&format!("[color=red]{}[/color]", what));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_player(label: &mut Gd<RichTextLabel>, player: &Player) {
|
||||||
|
if let Some(game) = Game::singleton()
|
||||||
|
&& let Some(team) = game.bind().get_team(player.data.team)
|
||||||
|
{
|
||||||
|
label.append_text(&format!("[color={}]", team.bind().color));
|
||||||
|
label.add_text(&player.data.name);
|
||||||
|
label.append_text(&format!("[/color]"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,6 +9,7 @@ use crate::{
|
|||||||
Announcer,
|
Announcer,
|
||||||
},
|
},
|
||||||
ball::Ball,
|
ball::Ball,
|
||||||
|
chat::{Chat, ChatMessage},
|
||||||
map::Map,
|
map::Map,
|
||||||
map_resource::MapResource,
|
map_resource::MapResource,
|
||||||
net::{
|
net::{
|
||||||
@ -216,6 +217,11 @@ pub struct Game {
|
|||||||
|
|
||||||
#[godot_api]
|
#[godot_api]
|
||||||
impl INode for Game {
|
impl INode for Game {
|
||||||
|
fn ready(&mut self) {
|
||||||
|
let chat = Chat::new_alloc();
|
||||||
|
self.base_mut().add_child(&chat);
|
||||||
|
}
|
||||||
|
|
||||||
fn physics_process(&mut self, delta: f64) {
|
fn physics_process(&mut self, delta: f64) {
|
||||||
self.since_last_sync += delta;
|
self.since_last_sync += delta;
|
||||||
if self.since_last_sync > (1. / 60.) {
|
if self.since_last_sync > (1. / 60.) {
|
||||||
@ -854,6 +860,11 @@ impl Game {
|
|||||||
pub fn on_kill(&mut self, source: DamageSource, player_id: u16) {
|
pub fn on_kill(&mut self, source: DamageSource, player_id: u16) {
|
||||||
let total_prev_kills: u16 = self.players.iter().map(|p| p.data.kills).sum();
|
let total_prev_kills: u16 = self.players.iter().map(|p| p.data.kills).sum();
|
||||||
|
|
||||||
|
if let Some(chat) = &mut Chat::singleton() {
|
||||||
|
chat.bind_mut()
|
||||||
|
.new_message(ChatMessage::Death(source, player_id));
|
||||||
|
}
|
||||||
|
|
||||||
let killing_spree = if let DamageSource::Player(source_id) = source
|
let killing_spree = if let DamageSource::Player(source_id) = source
|
||||||
&& let Some(source_player) = self.find_player_mut(source_id)
|
&& let Some(source_player) = self.find_player_mut(source_id)
|
||||||
{
|
{
|
||||||
@ -875,8 +886,10 @@ impl Game {
|
|||||||
&& let PeerKind::Server(peer, _) = peer
|
&& let PeerKind::Server(peer, _) = peer
|
||||||
{
|
{
|
||||||
if total_prev_kills == 0 {
|
if total_prev_kills == 0 {
|
||||||
s.on_announcement(Announcement::FirstBlood);
|
if let DamageSource::Player(source_id) = source {
|
||||||
peer.broadcast_reliable(Package::Announcement(FirstBlood));
|
s.on_announcement(source_id, Announcement::FirstBlood);
|
||||||
|
peer.broadcast_reliable(Package::Announcement(source_id, FirstBlood));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let announcement = match killing_spree {
|
let announcement = match killing_spree {
|
||||||
2 => Some(Announcement::DoubleKill),
|
2 => Some(Announcement::DoubleKill),
|
||||||
@ -885,14 +898,20 @@ impl Game {
|
|||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
if let Some(announcement) = announcement {
|
if let Some(announcement) = announcement {
|
||||||
s.on_announcement(announcement);
|
if let DamageSource::Player(source_id) = source {
|
||||||
peer.broadcast_reliable(Package::Announcement(announcement));
|
s.on_announcement(source_id, announcement);
|
||||||
|
peer.broadcast_reliable(Package::Announcement(source_id, announcement));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_announcement(&mut self, announcement: Announcement) {
|
pub fn on_announcement(&mut self, player_id: u16, announcement: Announcement) {
|
||||||
|
if let Some(chat) = &mut Chat::singleton() {
|
||||||
|
chat.bind_mut()
|
||||||
|
.new_message(ChatMessage::Announcement(player_id, announcement));
|
||||||
|
}
|
||||||
Announcer::singleton().bind_mut().announce(announcement);
|
Announcer::singleton().bind_mut().announce(announcement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@ use godot::prelude::*;
|
|||||||
|
|
||||||
pub mod announcer;
|
pub mod announcer;
|
||||||
pub mod ball;
|
pub mod ball;
|
||||||
|
pub mod chat;
|
||||||
pub mod cli_parser;
|
pub mod cli_parser;
|
||||||
pub mod game_manager;
|
pub mod game_manager;
|
||||||
pub mod game_settings;
|
pub mod game_settings;
|
||||||
|
|||||||
@ -311,7 +311,7 @@ pub enum Package {
|
|||||||
DespawnBall,
|
DespawnBall,
|
||||||
SwapWeapon(u16, WeaponType),
|
SwapWeapon(u16, WeaponType),
|
||||||
Goal(Vec<u8>),
|
Goal(Vec<u8>),
|
||||||
Announcement(Announcement),
|
Announcement(u16, Announcement),
|
||||||
|
|
||||||
// End-of-Game packages
|
// End-of-Game packages
|
||||||
FinishGame,
|
FinishGame,
|
||||||
|
|||||||
@ -200,9 +200,9 @@ impl NetworkManager {
|
|||||||
game.bind_mut().finish_game();
|
game.bind_mut().finish_game();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Package::Announcement(announcement) => {
|
Package::Announcement(source_id, announcement) => {
|
||||||
if let Some(game) = &mut Game::singleton() {
|
if let Some(game) = &mut Game::singleton() {
|
||||||
game.bind_mut().on_announcement(announcement);
|
game.bind_mut().on_announcement(source_id, announcement);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
|||||||
@ -897,7 +897,7 @@ impl RemotePlayer {
|
|||||||
pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32);
|
pub fn on_take_damage(source: DamageSourceSignal, source_player: u16, damage: i32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub enum DamageSource {
|
pub enum DamageSource {
|
||||||
Player(u16),
|
Player(u16),
|
||||||
Killbox,
|
Killbox,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user