zone shapes

This commit is contained in:
ntr 2019-01-14 20:23:36 +11:00
parent 15bcd2b13f
commit ae5f09a5c8
2 changed files with 154 additions and 15 deletions

View File

@ -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

View File

@ -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<Encounter, ()>,
}
#[derive(Debug,Clone,Copy)]
enum Shape {
Diamond,
Line,
Plus,
Diode,
Domino,
Kite,
}
pub type ZoneGraph = UnGraph<Encounter, ()>;
#[derive(Debug,Clone,PartialEq,Eq,Hash,PartialOrd,Ord,Serialize,Deserialize)]
@ -27,14 +42,18 @@ pub struct Encounter {
tag: String,
game_id: Option<Uuid>,
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;
}