97 lines
No EOL
3.2 KiB
Rust
97 lines
No EOL
3.2 KiB
Rust
use std::fmt::Debug;
|
|
|
|
use super::{entry::{ActionDefinition, ActionResult, GameEntry}, chat_message::ChatMessage};
|
|
|
|
pub trait Character<E: GameEntry> : CharacterSheet {
|
|
/// types of actions that can be done on the specified entry (e.g. cast for spells and wear for armor)
|
|
fn actions(&self, entry: &E) -> Vec<ActionDefinition>;
|
|
/// uses an action for a specific character, some actions should be split into multiple
|
|
///
|
|
/// for example, an attack sequence will be of:
|
|
///
|
|
/// - `Attack` invoked on a weapon entry, which will have the `roll damage` option in the chat
|
|
/// - `roll damage` will be done on the attacking character, which show the `damage` and `double` actions
|
|
/// - `damage` will be used on the target character (which could apply reductions as well)
|
|
fn use_action(&mut self, entry: &E, action: &ActionResult) -> ChatMessage;
|
|
}
|
|
|
|
pub trait CharacterSheet : Default {
|
|
/// Character sheet inputs (stuff that are not calculated from different items), such as Name, Age, Strength
|
|
fn inputs(&self, access: AccessLevel) -> Vec<(String, EntryType)>;
|
|
/// All fields in the character sheet, maybe change it to only a vec of strings?
|
|
fn fields(&self) -> Vec<(String, EntryType)>;
|
|
/// Character sheet to display, ordered. `None`s can be used to convey a seperator (of any sort)
|
|
fn display(&self, access: AccessLevel) -> Vec<Option<(String, EntryType)>>;
|
|
/// Gets a character sheet entry value
|
|
fn get(&self, entry: &str, access: AccessLevel) -> Option<EntryType>;
|
|
/// Sets a cahrater sheet entry value
|
|
fn set(&mut self, entry: &str, value: EntryType, access: AccessLevel);
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub enum AccessLevel {
|
|
Admin = 0, Owner = 1, PartyMember = 2, World = 3,
|
|
}
|
|
impl AccessLevel {
|
|
pub fn has_access(self, other: Self) -> bool {
|
|
(self as u8) <= (other as u8)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum EntryType {
|
|
Number(i32),
|
|
Text(String),
|
|
Bool(bool),
|
|
Array(Vec<EntryType>),
|
|
}
|
|
impl Default for EntryType {
|
|
fn default() -> Self {
|
|
EntryType::Number(0)
|
|
}
|
|
}
|
|
impl EntryType {
|
|
pub fn as_num(&self) -> i32 {
|
|
if let EntryType::Number(n) = *self {
|
|
n
|
|
}
|
|
else {
|
|
0
|
|
}
|
|
}
|
|
pub fn as_text(&self) -> String {
|
|
if let EntryType::Text(t) = self {
|
|
t.clone()
|
|
}
|
|
else {
|
|
String::new()
|
|
}
|
|
}
|
|
pub fn as_bool(&self) -> bool {
|
|
if let EntryType::Bool(b) = *self {
|
|
b
|
|
}
|
|
else {
|
|
false
|
|
}
|
|
}
|
|
}
|
|
impl std::fmt::Display for EntryType {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
EntryType::Number(n) => write!(f, "{}", n),
|
|
EntryType::Text(t) => write!(f, "{}", t),
|
|
EntryType::Bool(b) => write!(f, "{}", b),
|
|
EntryType::Array(v) => {
|
|
write!(f, "[ ")?;
|
|
if v.len() > 0 {
|
|
for i in v.iter().take(v.len() - 1) {
|
|
write!(f, "{}, ", i)?;
|
|
};
|
|
write!(f, "{} ", v.iter().last().unwrap())?;
|
|
};
|
|
write!(f, "]")
|
|
},
|
|
}
|
|
}
|
|
} |