open_tavern/src/game/chat_message.rs

122 lines
3.9 KiB
Rust

use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct ChatMessage {
/// message text, `{item}` can be used to refer to items and such, where item is of the path such as `items/sword` or `spells/fireball`
pub text: String,
/// Source user initiated the action/sent the message
#[serde(default = "default_source")]
pub source: String,
/// Character "sending" the message
pub character: Option<String>,
/// whisper item
pub whisper: Option<String>,
/// Rolls of the action, if not empty a roll should happen before
pub roll: Option<Vec<RollDialogOption>>,
/// Optional roll target
pub roll_target: Option<i32>,
/// Optional action buttons, for a chat message this will be empty
pub actions: Option<Vec<String>>,
/// Targets of the action, for a chat message this will be empty
pub targets: Option<Vec<String>>,
/// message id, should be left emitted or 0 for new messages
#[serde(default = "default_id")]
pub id: usize,
}
fn default_source() -> String {
String::new()
}
impl ChatMessage {
/// Creates a new chat message with a given text and source
pub fn new(text: String) -> Self {
Self {
text, ..Default::default()
}
}
pub fn source(mut self, source: String) -> Self {
self.source = source;
self
}
/// sets the whisper value of the message
pub fn whisper(mut self, whisper: Option<String>) -> Self {
self.whisper = whisper;
self
}
/// sets the roll value for the message (chaining multiple will override each other)
pub fn roll(mut self, roll: Option<Vec<RollDialogOption>>) -> Self {
self.roll = roll;
self
}
/// adds a single roll to the message (chaining multiple will add multiple rolls)
pub fn with_roll(mut self, roll: RollDialogOption) -> Self {
if let Some(rs) = &mut self.roll {
rs.push(roll);
}
else {
self.roll = Some(vec![roll]);
}
self
}
pub fn roll_target(mut self, target: Option<i32>) -> Self {
self.roll_target = target;
self
}
/// sets the actions value (chaining multiple will override)
pub fn actions(mut self, actions: Option<Vec<String>>) -> Self {
self.actions = actions;
self
}
/// adds a single action to the message (chaining multiple will add multiple actions)
pub fn with_action(mut self, action: String) -> Self {
if let Some(acts) = &mut self.actions {
acts.push(action);
}
else {
self.actions = Some(vec![action]);
}
self
}
/// sets the targets value (chaining multiple will override)
pub fn targets(mut self, targets: Option<Vec<String>>) -> Self {
self.targets = targets;
self
}
/// adds a single target to the message (chaining multiple will add multiple targets)
pub fn with_target(mut self, target: String) -> Self {
if let Some(targets) = &mut self.targets {
targets.push(target);
}
else {
self.targets = Some(vec![target]);
}
self
}
/// Sets the message id
///
/// WARNING: duplicate message id will cause an overwrite of the original message (and an edit at the client)
pub fn id(mut self, id: usize) -> Self {
self.id = id;
self
}
}
fn default_id() -> usize { 0 }
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct RollDialogOption {
/// Field name
pub name: String,
/// dice size (aka d6, d12, d20)
pub dice_type: u16,
/// amount of dice (aka 1d6, 2d12, 10d20)
pub dice_amount: u16,
/// Constant amout to add (+7, +3, -1)
pub constant: i16,
/// Extra data, like damage type
pub extra: String,
/// should be enabled by default
pub enabled: bool
}