Add some preliminary chat messages
This commit is contained in:
parent
a1f9895207
commit
d1fe3f6bb0
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,
|
||||
},
|
||||
ball::Ball,
|
||||
chat::{Chat, ChatMessage},
|
||||
map::Map,
|
||||
map_resource::MapResource,
|
||||
net::{
|
||||
@ -216,6 +217,11 @@ pub struct Game {
|
||||
|
||||
#[godot_api]
|
||||
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) {
|
||||
self.since_last_sync += delta;
|
||||
if self.since_last_sync > (1. / 60.) {
|
||||
@ -854,6 +860,11 @@ impl Game {
|
||||
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();
|
||||
|
||||
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 Some(source_player) = self.find_player_mut(source_id)
|
||||
{
|
||||
@ -875,8 +886,10 @@ impl Game {
|
||||
&& let PeerKind::Server(peer, _) = peer
|
||||
{
|
||||
if total_prev_kills == 0 {
|
||||
s.on_announcement(Announcement::FirstBlood);
|
||||
peer.broadcast_reliable(Package::Announcement(FirstBlood));
|
||||
if let DamageSource::Player(source_id) = source {
|
||||
s.on_announcement(source_id, Announcement::FirstBlood);
|
||||
peer.broadcast_reliable(Package::Announcement(source_id, FirstBlood));
|
||||
}
|
||||
}
|
||||
let announcement = match killing_spree {
|
||||
2 => Some(Announcement::DoubleKill),
|
||||
@ -885,14 +898,20 @@ impl Game {
|
||||
_ => None,
|
||||
};
|
||||
if let Some(announcement) = announcement {
|
||||
s.on_announcement(announcement);
|
||||
peer.broadcast_reliable(Package::Announcement(announcement));
|
||||
if let DamageSource::Player(source_id) = source {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ use godot::prelude::*;
|
||||
|
||||
pub mod announcer;
|
||||
pub mod ball;
|
||||
pub mod chat;
|
||||
pub mod cli_parser;
|
||||
pub mod game_manager;
|
||||
pub mod game_settings;
|
||||
|
||||
@ -311,7 +311,7 @@ pub enum Package {
|
||||
DespawnBall,
|
||||
SwapWeapon(u16, WeaponType),
|
||||
Goal(Vec<u8>),
|
||||
Announcement(Announcement),
|
||||
Announcement(u16, Announcement),
|
||||
|
||||
// End-of-Game packages
|
||||
FinishGame,
|
||||
|
||||
@ -200,9 +200,9 @@ impl NetworkManager {
|
||||
game.bind_mut().finish_game();
|
||||
}
|
||||
}
|
||||
Package::Announcement(announcement) => {
|
||||
Package::Announcement(source_id, announcement) => {
|
||||
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);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub enum DamageSource {
|
||||
Player(u16),
|
||||
Killbox,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user