Base data structures
This commit is contained in:
commit
f2b9e6ccb3
|
@ -0,0 +1 @@
|
||||||
|
**/target
|
|
@ -0,0 +1,11 @@
|
||||||
|
[package]
|
||||||
|
name = "common"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
serde = { version = "1" }
|
||||||
|
serde_derive = { version = "1" }
|
||||||
|
thiserror = { version = "1" }
|
|
@ -0,0 +1,12 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
|
||||||
|
pub mod types;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
assert_eq!(2 + 2, 4);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,201 @@
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Error)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Tier out of range {0}")]
|
||||||
|
TierOutOfRange(u8),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum Type {
|
||||||
|
Arkus,
|
||||||
|
Delve,
|
||||||
|
Glaive,
|
||||||
|
Jack,
|
||||||
|
Nano,
|
||||||
|
Wright,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum StatType {
|
||||||
|
Might,
|
||||||
|
Speed,
|
||||||
|
Intellect,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum Cost {
|
||||||
|
Nothing,
|
||||||
|
Constant { stat: StatType, cost: u8 },
|
||||||
|
Variable(StatType),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Tier(u8);
|
||||||
|
|
||||||
|
impl Tier {
|
||||||
|
pub fn new(val: u8) -> Result<Tier, Error> {
|
||||||
|
if val < 1 || val > 6 {
|
||||||
|
Err(Error::TierOutOfRange(val))
|
||||||
|
} else {
|
||||||
|
Ok(Tier(val))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Stat {
|
||||||
|
current: u8,
|
||||||
|
max: u8,
|
||||||
|
edge: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Stats {
|
||||||
|
might: Stat,
|
||||||
|
speed: Stat,
|
||||||
|
intellect: Stat,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct SpecialAbility {
|
||||||
|
name: String,
|
||||||
|
cost: Cost,
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum SkillRank {
|
||||||
|
Inability,
|
||||||
|
Trained,
|
||||||
|
Specialized,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Skill {
|
||||||
|
skill: String,
|
||||||
|
rank: SkillRank,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum Range {
|
||||||
|
Immediate,
|
||||||
|
Short,
|
||||||
|
Long,
|
||||||
|
VeryLong,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Attack {
|
||||||
|
weapon: String,
|
||||||
|
damage: u8,
|
||||||
|
range: Range,
|
||||||
|
ammo: Option<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Defense {
|
||||||
|
armor: String,
|
||||||
|
defense: u8,
|
||||||
|
speed_cost: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct CharacterSheet {
|
||||||
|
name: String,
|
||||||
|
descriptor: String,
|
||||||
|
type_: Type,
|
||||||
|
focus: String,
|
||||||
|
tier: Tier,
|
||||||
|
pools: Stats,
|
||||||
|
effort: u8,
|
||||||
|
cypher_limit: u8,
|
||||||
|
special_abilities: Vec<SpecialAbility>,
|
||||||
|
skills: Vec<Skill>,
|
||||||
|
attacks: Vec<Attack>,
|
||||||
|
defenses: Vec<Defense>,
|
||||||
|
equipment: Vec<String>,
|
||||||
|
cyphers: Vec<Cypher>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct Cypher {
|
||||||
|
name: String,
|
||||||
|
level: u8,
|
||||||
|
form: String,
|
||||||
|
description: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(any(test, feature = "test_data"))]
|
||||||
|
mod test_data {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn opal() -> CharacterSheet {
|
||||||
|
CharacterSheet {
|
||||||
|
name: "Opal".to_owned(),
|
||||||
|
descriptor: "Adaptable".to_owned(),
|
||||||
|
type_: Type::Jack,
|
||||||
|
focus: "Speaks with a Silver Tongue".to_owned(),
|
||||||
|
tier: Tier::new(1).unwrap(),
|
||||||
|
pools: Stats {
|
||||||
|
might: Stat {
|
||||||
|
current: 11,
|
||||||
|
max: 11,
|
||||||
|
edge: 0,
|
||||||
|
},
|
||||||
|
speed: Stat {
|
||||||
|
current: 12,
|
||||||
|
max: 12,
|
||||||
|
edge: 0,
|
||||||
|
},
|
||||||
|
intellect: Stat {
|
||||||
|
current: 13,
|
||||||
|
max: 13,
|
||||||
|
edge: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
effort: 1,
|
||||||
|
cypher_limit: 3,
|
||||||
|
special_abilities: vec![
|
||||||
|
SpecialAbility { name: "Versatile".to_owned(),
|
||||||
|
cost: Cost::Nothing,
|
||||||
|
description: "+2 to any pool. It can be reassigned after each ten-hour recovery roll.".to_owned() },
|
||||||
|
SpecialAbility { name: "Flex Skill".to_owned(),
|
||||||
|
cost: Cost::Nothing,
|
||||||
|
description: "at the beginning of each day, choose one skill (other than attack or defense). For the rest of the day, you are trained in that skill.".to_owned() },
|
||||||
|
SpecialAbility{ name: "Face Morph".to_owned(),
|
||||||
|
cost: Cost::Constant { stat: StatType::Intellect, cost: 2 },
|
||||||
|
description: "You alter your features and coloration for one hour.".to_owned() },
|
||||||
|
],
|
||||||
|
skills: vec![
|
||||||
|
Skill{ skill: "Perception".to_owned(), rank: SkillRank::Trained },
|
||||||
|
Skill{ skill: "Resilient".to_owned(), rank: SkillRank::Trained },
|
||||||
|
Skill{ skill: "Social interactions".to_owned(), rank: SkillRank::Trained },
|
||||||
|
Skill{ skill: "Pleasant social interactiosn".to_owned(), rank: SkillRank::Specialized },
|
||||||
|
],
|
||||||
|
attacks: vec![
|
||||||
|
Attack { weapon: "Crank Crossbow".to_owned(), damage: 4, range: Range::Long, ammo: Some(25), },
|
||||||
|
Attack { weapon: "Rapier".to_owned(), damage: 2, range: Range::Immediate, ammo: None, },
|
||||||
|
],
|
||||||
|
defenses: vec![
|
||||||
|
Defense {
|
||||||
|
armor: "Brigandine".to_owned(),
|
||||||
|
defense: 2,
|
||||||
|
speed_cost: 2,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
equipment: vec![
|
||||||
|
"A book for recording favorite words, inspiration stories, and speech anecdotes.".to_owned(),
|
||||||
|
"Explorer's pack".to_owned(),
|
||||||
|
],
|
||||||
|
cyphers: vec![
|
||||||
|
Cypher {
|
||||||
|
name: "Flying Cap".to_owned(),
|
||||||
|
level: 3,
|
||||||
|
form: "Hat".to_owned(),
|
||||||
|
description: "Whatever".to_owned(),
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Tasks
|
||||||
|
|
||||||
|
- Players
|
||||||
|
- need to be able to see their character sheets
|
||||||
|
- need to be able to edit their character sheets
|
||||||
|
- need to record damage
|
||||||
|
- need to mark abilities as used
|
||||||
|
- need to see active status effects ("flex skill")
|
||||||
|
- need to trigger recovery (regain pool points, reset skills that reset on recovery)
|
||||||
|
- need to mark artifacts as depleted
|
||||||
|
- need to expend cyphers
|
||||||
|
- GM
|
||||||
|
- needs to see all character sheet
|
||||||
|
- needs to send items to players
|
||||||
|
- needs a pool of potential cyphers
|
||||||
|
- Other
|
||||||
|
- all actions must be undoable
|
||||||
|
|
||||||
|
Cypher:
|
||||||
|
- name
|
||||||
|
- level
|
||||||
|
- form
|
||||||
|
- description
|
||||||
|
|
||||||
|
Character Sheet
|
|
@ -0,0 +1,10 @@
|
||||||
|
[package]
|
||||||
|
name = "datasphere-server"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
warp = { version = "0.3.1" }
|
|
@ -0,0 +1,46 @@
|
||||||
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
|
use warp::Filter;
|
||||||
|
|
||||||
|
fn gm_paths() -> impl Filter {
|
||||||
|
let base = warp::path("gm").and(warp::header("authentication"));
|
||||||
|
|
||||||
|
let character_sheet = base
|
||||||
|
.clone()
|
||||||
|
.and(warp::path!("character" / String))
|
||||||
|
.map(|auth: String, name| format!("name: {}", name));
|
||||||
|
let send_item = base
|
||||||
|
.clone()
|
||||||
|
.and(warp::path("send_item"))
|
||||||
|
.map(|auth| format!("send_item"));
|
||||||
|
let send_resource = base
|
||||||
|
.clone()
|
||||||
|
.and(warp::path("send_resource"))
|
||||||
|
.map(|auth| format!("send_resource"));
|
||||||
|
|
||||||
|
character_sheet.or(send_item).or(send_resource)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn player_paths() -> impl Filter {
|
||||||
|
let base = warp::path("player").and(warp::header("authentication"));
|
||||||
|
let character_sheet = base
|
||||||
|
.and(warp::path!("character" / String))
|
||||||
|
.map(|authentication: String, name: String| format!("name: {}", name));
|
||||||
|
|
||||||
|
character_sheet
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
pub async fn main() {
|
||||||
|
let hi = warp::path!("hello" / String)
|
||||||
|
.and(warp::header("user-agent"))
|
||||||
|
.map(|param: String, agent: String| format!("Saluton! {}, {}", param, agent));
|
||||||
|
let bye = warp::path!("goodbye").map(|| "Goodbye!");
|
||||||
|
|
||||||
|
let server = warp::serve(hi.or(bye));
|
||||||
|
server
|
||||||
|
.run(SocketAddr::new(
|
||||||
|
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
|
||||||
|
8000,
|
||||||
|
))
|
||||||
|
.await;
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
let
|
||||||
|
rust_overlay = import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz");
|
||||||
|
pkgs = import <pkgs-21.05> { overlays = [ rust_overlay ]; };
|
||||||
|
unstable = import <unstable> {};
|
||||||
|
rust = pkgs.rust-bin.stable."1.54.0".default.override {
|
||||||
|
extensions = [ "rust-src" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
in pkgs.mkShell {
|
||||||
|
name = "datasphere";
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
rust
|
||||||
|
unstable.rust-analyzer
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
if [ -e ~/.nixpkgs/shellhook.sh ]; then . ~/.nixpkgs/shellhook.sh; fi
|
||||||
|
'';
|
||||||
|
}
|
Loading…
Reference in New Issue