From e768c267f4fa915ed19fc9de5116ad391b6f8977 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 20 Dec 2018 14:40:36 +1100 Subject: [PATCH] drops --- server/Cargo.toml | 2 +- server/WORKLOG.md | 6 +-- server/src/account.rs | 8 +--- server/src/game.rs | 20 +++++++--- server/src/item.rs | 87 ++++++++++++++++++++++++++++++++++--------- server/src/rpc.rs | 12 +----- server/src/skill.rs | 3 ++ 7 files changed, 92 insertions(+), 46 deletions(-) diff --git a/server/Cargo.toml b/server/Cargo.toml index 725929a2..e3edacc1 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["ntr "] [dependencies] -rand = "0.5" +rand = "0.6" uuid = { version = "0.5", features = ["serde", "v4"] } serde = "1" serde_derive = "1" diff --git a/server/WORKLOG.md b/server/WORKLOG.md index 5f5e5e6c..071d97c3 100644 --- a/server/WORKLOG.md +++ b/server/WORKLOG.md @@ -13,7 +13,6 @@ strangle ## NOW * pve granted stat reroll items - ## SOON * tutorial * aoe skills @@ -21,13 +20,10 @@ strangle * modifies skill base speed * skills - * handle setting account better maybe? - * calculate - * hp increase/decrease * private fields for opponents -* handle unserializable cryps ## LATER +* redis for game events * chat * notifications * rejoin in progress games diff --git a/server/src/account.rs b/server/src/account.rs index f0541c97..23563129 100644 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -8,11 +8,12 @@ use serde_cbor::{from_slice}; use postgres::transaction::Transaction; use rpc::{AccountCreateParams, AccountLoginParams}; -use item::{Item, ItemAction, item_create}; use cryp::{Cryp, CrypRecover, cryp_write}; use game::Game; +use item::{Item, item_create, ItemAction}; + use failure::Error; use failure::err_msg; @@ -102,11 +103,6 @@ pub fn account_create(params: AccountCreateParams, tx: &mut Transaction) -> Resu println!("{:?} registered", entry.name); - // give them a revive - let revive = Item::new(ItemAction::Revive, &entry); - item_create(revive, tx, &entry)?; - - return Ok(entry); } diff --git a/server/src/game.rs b/server/src/game.rs index 9499aac1..ca026b28 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -14,6 +14,7 @@ use account::Account; use rpc::{GameStateParams, GameSkillParams, GamePveParams, GamePvpParams, GameTargetParams, GameJoinParams}; use cryp::{Cryp, cryp_get}; use skill::{Skill, Cast, ResolutionResult}; +use item::{item_drop}; pub type Log = Vec; @@ -514,7 +515,7 @@ impl Game { // handle cooldowns and statuses self.progress_durations(); - if self.is_finished() { + if self.finished() { return self.finish() } @@ -551,13 +552,18 @@ impl Game { self } - fn is_finished(&self) -> bool { + fn finished(&self) -> bool { self.teams.iter().any(|t| t.cryps.iter().all(|c| c.is_ko())) } + fn winner(&self) -> Option<&Team> { + self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko())) + } + fn finish(&mut self) -> &mut Game { self.phase = Phase::Finish; self.log.push(format!("Game finished.")); + self.stack.clear(); { let winner = self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko())); @@ -567,8 +573,6 @@ impl Game { }; } - self.stack.clear(); - self } } @@ -717,7 +721,13 @@ pub fn game_update(game: &Game, tx: &mut Transaction) -> Result<(), Error> { result.iter().next().ok_or(format_err!("game {:?} could not be written", game))?; - // println!("{:} wrote game", game.id); + if game.finished() { + if let Some(t) = game.winner() { + if !t.id.is_nil() { + item_drop(tx, t.id)?; + } + } + } return Ok(()); } diff --git a/server/src/item.rs b/server/src/item.rs index a86ac114..e9729c43 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -5,6 +5,11 @@ use postgres::transaction::Transaction; use failure::Error; use failure::err_msg; +// drops +use rand::prelude::*; +use rand::{thread_rng, Rng}; +use rand::distributions::{WeightedIndex}; + use account::Account; use rpc::{ItemUseParams}; use cryp::{cryp_get, cryp_write}; @@ -12,7 +17,9 @@ use cryp::{cryp_get, cryp_write}; #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum ItemAction { - Revive, + RerollPhysDamage, + RerollSpellDamage, + RerollStamina, } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -24,18 +31,20 @@ pub struct Item { } impl Item { - pub fn new(action: ItemAction, account: &Account) -> Item { + pub fn new(action: ItemAction, account_id: Uuid) -> Item { let id = Uuid::new_v4(); return Item { id, - account: account.id, + account: account_id, action, }; } fn apply(&mut self, tx: &mut Transaction, target: Uuid) -> Result<(), Error> { match self.action { - ItemAction::Revive => revive(self, tx, target), + ItemAction::RerollStamina => revive(self, tx, target), + ItemAction::RerollPhysDamage => revive(self, tx, target), + ItemAction::RerollSpellDamage => revive(self, tx, target), } } } @@ -47,7 +56,26 @@ fn revive(item: &mut Item, tx: &mut Transaction, target: Uuid) -> Result<(), Err return Ok(()); } -pub fn item_create(item: Item, tx: &mut Transaction, account: &Account) -> Result { +pub fn item_drop(tx: &mut Transaction, account_id: Uuid) -> Result { + let mut rng = thread_rng(); + + let actions = [ + (ItemAction::RerollStamina, 1), + (ItemAction::RerollPhysDamage, 1), + (ItemAction::RerollSpellDamage, 1) + ]; + + let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap(); + let kind = actions[dist.sample(&mut rng)].0; + let item = Item::new(kind, account_id); + + println!("{:?} dropped {:?}", account_id, item); + + return item_create(item, tx, account_id); +} + + +pub fn item_create(item: Item, tx: &mut Transaction, account_id: Uuid) -> Result { let item_bytes = to_vec(&item)?; let query = " @@ -57,11 +85,11 @@ pub fn item_create(item: Item, tx: &mut Transaction, account: &Account) -> Resul "; let result = tx - .query(query, &[&item.id, &account.id, &item_bytes])?; + .query(query, &[&item.id, &account_id, &item_bytes])?; - let _returned = result.iter().next().expect("no row returned"); + result.iter().next().expect("no row returned"); - println!("{:?} wrote item {:}", account.id, item.id); + println!("{:?} wrote item {:}", account_id, item.id); return Ok(item); } @@ -84,13 +112,33 @@ pub fn item_use(params: ItemUseParams, tx: &mut Transaction, account: &Account) let mut item = from_slice::(&item_bytes)?; item.apply(tx, params.target)?; + item_delete(tx, params.item)?; + + return Ok(()); +} + +pub fn item_delete(tx: &mut Transaction, id: Uuid) -> Result<(), Error> { + let query = " + DELETE + FROM items + WHERE id = $1; + "; + + let result = tx + .execute(query, &[&id])?; + + if result != 1 { + return Err(format_err!("unable to delete item {:?}", id)); + } + + println!("invalid item deleted {:?}", id); return Ok(()); } pub fn items_list(tx: &mut Transaction, account: &Account) -> Result, Error> { let query = " - SELECT data + SELECT data, id FROM items WHERE account = $1; "; @@ -98,18 +146,21 @@ pub fn items_list(tx: &mut Transaction, account: &Account) -> Result, let result = tx .query(query, &[&account.id])?; - let items: Result, _> = result.iter().map(|row| { - let item_bytes: Vec = row.get(0); - from_slice::(&item_bytes) - }).collect(); + let mut items = vec![]; - // catch any errors - if items.is_err() { - return Err(err_msg("could not deserialize an item")); + for row in result.into_iter() { + let item_bytes: Vec = row.get(0); + let id = row.get(1); + + match from_slice::(&item_bytes) { + Ok(i) => items.push(i), + Err(_e) => { + item_delete(tx, id)?; + } + }; } - // now unwrap is safe - return Ok(items.unwrap()); + return Ok(items); } // # max damage potion diff --git a/server/src/rpc.rs b/server/src/rpc.rs index b636ec6f..b989b444 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -7,7 +7,7 @@ use std::net::{TcpStream}; // demo use std::iter; use rand::{thread_rng, Rng}; -use rand::distributions::Alphanumeric; +use rand::distributions::{Alphanumeric}; use serde_cbor::{from_slice, to_vec}; use uuid::Uuid; @@ -164,11 +164,6 @@ impl Rpc { params: RpcResult::GameState(game_skill(msg.params, tx, &account)?) }; - // Rpc::send_msg(client, RpcResponse { - // method: "account_cryps".to_string(), - // params: RpcResult::CrypList(account_cryps(tx, &account)?) - // })?; - return Ok(game_response); } @@ -180,11 +175,6 @@ impl Rpc { params: RpcResult::GameState(game_target(msg.params, tx, &account)?) }; - // Rpc::send_msg(client, RpcResponse { - // method: "account_cryps".to_string(), - // params: RpcResult::CrypList(account_cryps(tx, &account)?) - // })?; - return Ok(game_response); } diff --git a/server/src/skill.rs b/server/src/skill.rs index b6993749..2e9eed89 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -355,6 +355,9 @@ pub enum Skill { Calm, Rez, + // Sleep, + // Nightmare, + // ------------------- // Destruction // -------------------