From 28bda483f1a9120e2692ac289346603e2522e35a Mon Sep 17 00:00:00 2001 From: ntr Date: Sat, 29 Dec 2018 23:38:42 +1100 Subject: [PATCH] more zone stuff --- client/src/scenes/menu.game.list.js | 2 +- client/src/scenes/missions.js | 8 +- client/src/socket.js | 5 ++ server/WORKLOG.md | 5 ++ server/src/rpc.rs | 28 ++++++- server/src/zone.rs | 121 +++++++++++++++++++++------- 6 files changed, 136 insertions(+), 33 deletions(-) diff --git a/client/src/scenes/menu.game.list.js b/client/src/scenes/menu.game.list.js index e04c1640..1ef465c2 100644 --- a/client/src/scenes/menu.game.list.js +++ b/client/src/scenes/menu.game.list.js @@ -124,7 +124,7 @@ class MenuGameList extends Phaser.Scene { zones.on('pointerdown', () => { this.scene.add('Missions', Missions, true); - return ws.sendZoneCreate(); + return ws.sendAccountZone(); }); diff --git a/client/src/scenes/missions.js b/client/src/scenes/missions.js index b5db1c2d..4aff968a 100644 --- a/client/src/scenes/missions.js +++ b/client/src/scenes/missions.js @@ -16,16 +16,20 @@ class Missions extends Phaser.Scene { } create() { + const zone = this.registry.get('zone'); + if (!zone) return false; + this.scene.manager.add('MissionControls', MissionControls, true); this.graphics = this.add.graphics(); - const nodeData = this.registry.get('zone').nodes; - this.edgeData = this.registry.get('zone').edges.map(x => x.map(y => nodeData[y])); + const nodeData = zone.graph.nodes; + this.edgeData = zone.graph.edges.map(x => x.map(y => nodeData[y])); this.cameras.main.setViewport(COMBAT.width() * 0.2, COMBAT.y(), COMBAT.width() * 0.8, COMBAT.height()); this.addNodes(nodeData); this.drawEdges(nodeData); this.addCameraControl(); this.addEvents(); + return this; } addNodes(nodeData) { diff --git a/client/src/socket.js b/client/src/socket.js index 52079b9c..fa2a562b 100644 --- a/client/src/socket.js +++ b/client/src/socket.js @@ -48,6 +48,10 @@ function createSocket(events) { send({ method: 'account_items', params: {} }); } + function sendAccountZone() { + send({ method: 'account_zone', params: {} }); + } + function sendCrypSpawn(name) { send({ method: 'cryp_spawn', params: { name } }); } @@ -233,6 +237,7 @@ function createSocket(events) { sendAccountDemo, sendAccountCryps, sendAccountItems, + sendAccountZone, sendGameState, sendGamePve, sendGamePvp, diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 6e8428a1..2f0df686 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -11,6 +11,11 @@ strangle ## NOW +* zones + * open w/ item? + * close + * check node joinable + * update on game finish ## SOON * aoe skills diff --git a/server/src/rpc.rs b/server/src/rpc.rs index c680005f..8c04896b 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -20,7 +20,7 @@ use game::{Game, PveMode, game_state, game_pve, game_pvp, game_join, game_joinab use account::{Account, account_create, account_login, account_from_token, account_cryps, account_zone}; use item::{Item, items_list, item_use}; use skill::{Skill}; -use zone::{Zone, zone_create, zone_join}; +use zone::{Zone, zone_create, zone_join, zone_close}; pub struct Rpc; @@ -72,6 +72,7 @@ impl Rpc { "game_target" => Rpc::game_target(data, &mut tx, account.unwrap(), client), "zone_create" => Rpc::zone_create(data, &mut tx, account.unwrap(), client), "zone_join" => Rpc::zone_join(data, &mut tx, account.unwrap(), client), + "zone_close" => Rpc::zone_close(data, &mut tx, account.unwrap(), client), "account_cryps" => Rpc::account_cryps(data, &mut tx, account.unwrap(), client), "account_items" => Rpc::account_items(data, &mut tx, account.unwrap(), client), "account_zone" => Rpc::account_zone(data, &mut tx, account.unwrap(), client), @@ -346,6 +347,18 @@ impl Rpc { return Ok(response); } + + fn zone_close(data: Vec, tx: &mut Transaction, account: Account, _client: &mut WebSocket) -> Result { + let msg = from_slice::(&data).or(Err(err_msg("invalid params")))?; + + let response = RpcResponse { + method: "zone_close".to_string(), + params: RpcResult::ZoneClose(zone_close(msg.params, tx, &account)?) + }; + + return Ok(response); + } + } #[derive(Debug,Clone,Serialize,Deserialize)] @@ -366,6 +379,7 @@ pub enum RpcResult { ItemList(Vec), ItemUse(()), ZoneState(Zone), + ZoneClose(()), } #[derive(Debug,Clone,Serialize,Deserialize)] @@ -555,6 +569,18 @@ pub struct ZoneJoinParams { pub cryp_ids: Vec, } +#[derive(Debug,Clone,Serialize,Deserialize)] +struct ZoneCloseMsg { + method: String, + params: ZoneCloseParams, +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct ZoneCloseParams { + pub zone_id: Uuid, +} + + // #[cfg(test)] // mod tests { // use super::*; diff --git a/server/src/zone.rs b/server/src/zone.rs index ac37d622..3d432cac 100644 --- a/server/src/zone.rs +++ b/server/src/zone.rs @@ -10,11 +10,12 @@ use failure::Error; use failure::err_msg; use game::{Game, PveMode, game_pve_new, game_write}; -use rpc::{ZoneJoinParams}; +use rpc::{ZoneJoinParams, ZoneCloseParams}; #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Zone { id: Uuid, + active: bool, graph: UnGraph, } @@ -35,31 +36,13 @@ impl Encounter { game_id: None, }; } -} - -pub fn create_zone_graph() -> UnGraph { - let mut gr = Graph::new_undirected(); - - let mut last = gr.add_node(Encounter::new("ZONE0")); - let mut next; - - next = gr.add_node(Encounter::new("ZONE1")); - gr.add_edge(last, next, ()); - last = next; - - next = gr.add_node(Encounter::new("ZONE2")); - gr.add_edge(last, next, ()); - last = next; - - next = gr.add_node(Encounter::new("ZONE3")); - gr.add_edge(last, next, ()); - last = next; - - next = gr.add_node(Encounter::new("BOSS")); - gr.add_edge(last, next, ()); - // last = next; - - return gr; + fn start() -> Encounter { + return Encounter { + tag: "START".to_string(), + success: true, + game_id: None, + }; + } } pub fn zone_delete(tx: &mut Transaction, id: Uuid) -> Result<(), Error> { @@ -116,6 +99,7 @@ pub fn zone_create(tx: &mut Transaction, account: &Account) -> Result Result<(), Error> { let query = " UPDATE zones - SET data = $1 - WHERE id = $2 + SET data = $1, active = $2 + WHERE id = $3 RETURNING id, data; "; let result = tx - .query(query, &[&bytes, &zone.id])?; + .query(query, &[&bytes, &zone.active, &zone.id])?; result.iter().next().ok_or(format_err!("zone {:?} could not be written", zone))?; @@ -175,6 +159,78 @@ pub fn zone_join(params: ZoneJoinParams, tx: &mut Transaction, account: &Account return Ok(game); } +pub fn zone_close(params: ZoneCloseParams, tx: &mut Transaction, account: &Account) -> Result<(), Error> { + let mut zone = zone_get(tx, params.zone_id)?; + zone.active = false; + zone_update(&zone, tx)?; + return Ok(()); +} + +pub fn create_zone_graph() -> ZoneGraph { + let mut gr = Graph::new_undirected(); + + let mut last = gr.add_node(Encounter::start()); + let mut next; + + next = gr.add_node(Encounter::new("ZONE0")); + gr.add_edge(last, next, ()); + last = next; + + next = gr.add_node(Encounter::new("ZONE1")); + gr.add_edge(last, next, ()); + last = next; + + 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; + + return gr; +} + +pub fn node_joinable(graph: &mut ZoneGraph, target_index: NodeIndex) -> bool { + // early return for already attempted + { + let target_encounter = match graph.node_weight(target_index) { + Some(encounter) => encounter, + None => panic!("{:?} has no weight for {:?}", graph, target_index), + }; + + println!("{:?}", target_encounter); + + if target_encounter.game_id.is_some() { + return false; + } + } + + // now check the graph for connectedness + // get all the nodes that have been successfully completed + let mut filtered = graph.clone(); + filtered.retain_nodes(|g, i| { + match g.node_weight(i) { + Some(encounter) => encounter.success, + None => panic!("no weight for {:?}", i), + } + }); + + println!("{:?}", filtered); + + // if a node is a neighbour of that graph + // and hasn't been attempted + // it is joinable + for i in filtered.node_indices() { + match graph.neighbors(i).find(|n| *n == target_index) { + Some(_n) => return true, + None => continue, + }; + } + + return false; +} + #[cfg(test)] mod tests { use zone::*; @@ -189,4 +245,11 @@ mod tests { // println!("{:?}", Dot::with_config(&graph, &[Config::EdgeNoLabel])); } + + #[test] + fn zone_joinable_test() { + let mut graph = create_zone_graph(); + assert!(node_joinable(&mut graph, NodeIndex::from(1))); + assert!(!node_joinable(&mut graph, NodeIndex::from(2))); + } }