From ae5f09a5c89e5961139691b7ef7346a55df75624 Mon Sep 17 00:00:00 2001 From: ntr Date: Mon, 14 Jan 2019 20:23:36 +1100 Subject: [PATCH] zone shapes --- server/WORKLOG.md | 6 ++ server/src/zone.rs | 163 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 154 insertions(+), 15 deletions(-) diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 8cc79e27..09ffd399 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -23,6 +23,8 @@ * skills themselves * passive nodes / notables +* tell him about discord + # WORK WORK broken skills @@ -39,6 +41,7 @@ strangle * full svg buttons to not have to fuck around with text * FAQ * aoe skills +* combo skills * keep track of games joined * concede game on leave @@ -49,6 +52,8 @@ strangle * private fields for opponents * flavour text + * chat wheel trash talk + * KO animations and trash talk ## LATER * redis for game events @@ -72,6 +77,7 @@ strangle * prince of peace * bonus healing / no damage * fuck magic +* empower on ko # Mechanic Ideas teams diff --git a/server/src/zone.rs b/server/src/zone.rs index ad08fc86..e80ec927 100644 --- a/server/src/zone.rs +++ b/server/src/zone.rs @@ -9,6 +9,11 @@ use postgres::transaction::Transaction; use failure::Error; use failure::err_msg; +// shapes +use rand::prelude::*; +use rand::{thread_rng}; +use rand::distributions::{WeightedIndex}; + use game::{Game, GameMode, game_pve_new, game_write}; use rpc::{ZoneJoinParams, ZoneCloseParams}; @@ -20,6 +25,16 @@ pub struct Zone { graph: UnGraph, } +#[derive(Debug,Clone,Copy)] +enum Shape { + Diamond, + Line, + Plus, + Diode, + Domino, + Kite, +} + pub type ZoneGraph = UnGraph; #[derive(Debug,Clone,PartialEq,Eq,Hash,PartialOrd,Ord,Serialize,Deserialize)] @@ -27,14 +42,18 @@ pub struct Encounter { tag: String, game_id: Option, success: bool, + x: i8, + y: i8, } impl Encounter { - fn new(tag: &'static str) -> Encounter { + fn new(tag: &'static str, x: i8, y: i8) -> Encounter { return Encounter { tag: tag.to_string(), success: false, game_id: None, + x, + y, }; } fn start() -> Encounter { @@ -42,6 +61,8 @@ impl Encounter { tag: "START".to_string(), success: true, game_id: None, + x: 0, + y: 0, }; } } @@ -179,27 +200,139 @@ pub fn zone_close(params: ZoneCloseParams, tx: &mut Transaction, _account: &Acco return Ok(()); } +// shapes should always add the exit normal node +fn add_shape(shape: Shape, gr: &mut ZoneGraph, start: NodeIndex, x: i8, y: i8) -> (NodeIndex, i8, i8) { + match shape { + Shape::Line => { + let mut next = gr.add_node(Encounter::new("MINIBOSS", x, y)); + gr.add_edge(start, next, ()); + + let exit = gr.add_node(Encounter::new("NORMAL", x + 1, y)); + gr.add_edge(next, exit, ()); + + return (start, x + 1, y); + }, + Shape::Plus => { + let top = gr.add_node(Encounter::new("MINIBOSS", x, y + 1)); + gr.add_edge(start, top, ()); + + let bottom = gr.add_node(Encounter::new("MINIBOSS", x, y - 1)); + gr.add_edge(start, bottom, ()); + + let exit = gr.add_node(Encounter::new("NORMAL", x + 1, y)); + gr.add_edge(start, exit, ()); + + return (exit, x + 1, y); + }, + Shape::Diode => { + let top = gr.add_node(Encounter::new("MINIBOSS", x, y + 1)); + gr.add_edge(start, top, ()); + + let bottom = gr.add_node(Encounter::new("MINIBOSS", x, y - 1)); + gr.add_edge(start, bottom, ()); + + let exit = gr.add_node(Encounter::new("NORMAL", x + 1, y)); + gr.add_edge(start, exit, ()); + + // connect top and exit for an extra chance + gr.add_edge(start, exit, ()); + gr.add_edge(start, exit, ()); + + return (exit, x + 1, y); + }, + Shape::Kite => { + let top = gr.add_node(Encounter::new("MINIBOSS", x + 1, y + 1)); + gr.add_edge(start, top, ()); + + let top_tip = gr.add_node(Encounter::new("BOSS", x + 1, y + 2)); + gr.add_edge(top, top_tip, ()); + + let bottom = gr.add_node(Encounter::new("MINIBOSS", x + 1, y - 1)); + gr.add_edge(start, bottom, ()); + + let bottom_tip = gr.add_node(Encounter::new("BOSS", x + 1, y - 2)); + gr.add_edge(bottom, bottom_tip, ()); + + let side = gr.add_node(Encounter::new("NORMAL", x + 2, y)); + gr.add_edge(top, side, ()); + gr.add_edge(bottom, side, ()); + + let exit = gr.add_node(Encounter::new("NORMAL", x + 3, y)); + gr.add_edge(side, exit, ()); + + return (exit, x + 3, y); + }, + Shape::Domino => { + let top = gr.add_node(Encounter::new("NORMAL", x, y + 1)); + gr.add_edge(start, top, ()); + + let top_tip = gr.add_node(Encounter::new("MINIBOSS", x + 1, y + 1)); + gr.add_edge(top, top_tip, ()); + + let bottom = gr.add_node(Encounter::new("MINIBOSS", x, y - 1)); + gr.add_edge(start, bottom, ()); + + let bottom_tip = gr.add_node(Encounter::new("NORMAL", x + 1, y - 1)); + gr.add_edge(bottom, bottom_tip, ()); + + let side = gr.add_node(Encounter::new("NORMAL", x + 2, y)); + gr.add_edge(top_tip, side, ()); + gr.add_edge(bottom_tip, side, ()); + + let exit = gr.add_node(Encounter::new("NORMAL", x + 3, y)); + gr.add_edge(side, exit, ()); + + return (exit, x + 3, y); + }, + Shape::Diamond => { + let top = gr.add_node(Encounter::new("NORMAL", x + 1, y + 1)); + gr.add_edge(start, top, ()); + + let top_tip = gr.add_node(Encounter::new("MINIBOSS", x + 2, y + 1)); + gr.add_edge(top, top_tip, ()); + + let bottom = gr.add_node(Encounter::new("NORMAL", x + 1, y - 1)); + gr.add_edge(start, bottom, ()); + + let bottom_tip = gr.add_node(Encounter::new("MINIBOSS", x + 2, y - 1)); + gr.add_edge(bottom, bottom_tip, ()); + + let exit = gr.add_node(Encounter::new("NORMAL", x + 3, y)); + gr.add_edge(top_tip, exit, ()); + gr.add_edge(bottom_tip, exit, ()); + + return (exit, x + 3, y); + }, + // _ => panic!("nyi shape"), + } +} + pub fn create_zone_graph() -> ZoneGraph { let mut gr = Graph::new_undirected(); + let mut rng = thread_rng(); let mut last = gr.add_node(Encounter::start()); - let mut next; + let mut x = 1; + let mut y = 0; - next = gr.add_node(Encounter::new("ZONE0")); - gr.add_edge(last, next, ()); - last = next; + for _i in 0..4 { + let shapes = vec![ + (Shape::Line, 1), + (Shape::Diamond, 1), + (Shape::Diode, 1), + (Shape::Kite, 1), + (Shape::Domino, 1), + (Shape::Plus, 1), + ]; - next = gr.add_node(Encounter::new("ZONE1")); - gr.add_edge(last, next, ()); - last = next; + let dist = WeightedIndex::new(shapes.iter().map(|item| item.1)).unwrap(); + let shape = shapes[dist.sample(&mut rng)].0; - next = gr.add_node(Encounter::new("ZONE2")); - gr.add_edge(last, next, ()); - last = next; - - next = gr.add_node(Encounter::new("BOSS")); - gr.add_edge(last, next, ()); - // last = next; + let result = add_shape(shape, &mut gr, last, x, y); + last = result.0; + x = result.1; + y = result.2; + } return gr; }