This commit is contained in:
ntr 2018-12-20 14:40:36 +11:00
parent c5d7a72fdc
commit e768c267f4
7 changed files with 92 additions and 46 deletions

View File

@ -4,7 +4,7 @@ version = "0.1.0"
authors = ["ntr <ntr@smokestack.io>"] authors = ["ntr <ntr@smokestack.io>"]
[dependencies] [dependencies]
rand = "0.5" rand = "0.6"
uuid = { version = "0.5", features = ["serde", "v4"] } uuid = { version = "0.5", features = ["serde", "v4"] }
serde = "1" serde = "1"
serde_derive = "1" serde_derive = "1"

View File

@ -13,7 +13,6 @@ strangle
## NOW ## NOW
* pve granted stat reroll items * pve granted stat reroll items
## SOON ## SOON
* tutorial * tutorial
* aoe skills * aoe skills
@ -21,13 +20,10 @@ strangle
* modifies skill base speed * modifies skill base speed
* skills * skills
* handle setting account better maybe?
* calculate
* hp increase/decrease
* private fields for opponents * private fields for opponents
* handle unserializable cryps
## LATER ## LATER
* redis for game events
* chat * chat
* notifications * notifications
* rejoin in progress games * rejoin in progress games

View File

@ -8,11 +8,12 @@ use serde_cbor::{from_slice};
use postgres::transaction::Transaction; use postgres::transaction::Transaction;
use rpc::{AccountCreateParams, AccountLoginParams}; use rpc::{AccountCreateParams, AccountLoginParams};
use item::{Item, ItemAction, item_create};
use cryp::{Cryp, CrypRecover, cryp_write}; use cryp::{Cryp, CrypRecover, cryp_write};
use game::Game; use game::Game;
use item::{Item, item_create, ItemAction};
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
@ -102,11 +103,6 @@ pub fn account_create(params: AccountCreateParams, tx: &mut Transaction) -> Resu
println!("{:?} registered", entry.name); println!("{:?} registered", entry.name);
// give them a revive
let revive = Item::new(ItemAction::Revive, &entry);
item_create(revive, tx, &entry)?;
return Ok(entry); return Ok(entry);
} }

View File

@ -14,6 +14,7 @@ use account::Account;
use rpc::{GameStateParams, GameSkillParams, GamePveParams, GamePvpParams, GameTargetParams, GameJoinParams}; use rpc::{GameStateParams, GameSkillParams, GamePveParams, GamePvpParams, GameTargetParams, GameJoinParams};
use cryp::{Cryp, cryp_get}; use cryp::{Cryp, cryp_get};
use skill::{Skill, Cast, ResolutionResult}; use skill::{Skill, Cast, ResolutionResult};
use item::{item_drop};
pub type Log = Vec<String>; pub type Log = Vec<String>;
@ -514,7 +515,7 @@ impl Game {
// handle cooldowns and statuses // handle cooldowns and statuses
self.progress_durations(); self.progress_durations();
if self.is_finished() { if self.finished() {
return self.finish() return self.finish()
} }
@ -551,13 +552,18 @@ impl Game {
self self
} }
fn is_finished(&self) -> bool { fn finished(&self) -> bool {
self.teams.iter().any(|t| t.cryps.iter().all(|c| c.is_ko())) 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 { fn finish(&mut self) -> &mut Game {
self.phase = Phase::Finish; self.phase = Phase::Finish;
self.log.push(format!("Game finished.")); self.log.push(format!("Game finished."));
self.stack.clear();
{ {
let winner = self.teams.iter().find(|t| t.cryps.iter().any(|c| !c.is_ko())); 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 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))?; 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(()); return Ok(());
} }

View File

@ -5,6 +5,11 @@ use postgres::transaction::Transaction;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
// drops
use rand::prelude::*;
use rand::{thread_rng, Rng};
use rand::distributions::{WeightedIndex};
use account::Account; use account::Account;
use rpc::{ItemUseParams}; use rpc::{ItemUseParams};
use cryp::{cryp_get, cryp_write}; use cryp::{cryp_get, cryp_write};
@ -12,7 +17,9 @@ use cryp::{cryp_get, cryp_write};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub enum ItemAction { pub enum ItemAction {
Revive, RerollPhysDamage,
RerollSpellDamage,
RerollStamina,
} }
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -24,18 +31,20 @@ pub struct Item {
} }
impl 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(); let id = Uuid::new_v4();
return Item { return Item {
id, id,
account: account.id, account: account_id,
action, action,
}; };
} }
fn apply(&mut self, tx: &mut Transaction, target: Uuid) -> Result<(), Error> { fn apply(&mut self, tx: &mut Transaction, target: Uuid) -> Result<(), Error> {
match self.action { 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(()); return Ok(());
} }
pub fn item_create(item: Item, tx: &mut Transaction, account: &Account) -> Result<Item, Error> { pub fn item_drop(tx: &mut Transaction, account_id: Uuid) -> Result<Item, Error> {
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<Item, Error> {
let item_bytes = to_vec(&item)?; let item_bytes = to_vec(&item)?;
let query = " let query = "
@ -57,11 +85,11 @@ pub fn item_create(item: Item, tx: &mut Transaction, account: &Account) -> Resul
"; ";
let result = tx 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); return Ok(item);
} }
@ -84,13 +112,33 @@ pub fn item_use(params: ItemUseParams, tx: &mut Transaction, account: &Account)
let mut item = from_slice::<Item>(&item_bytes)?; let mut item = from_slice::<Item>(&item_bytes)?;
item.apply(tx, params.target)?; 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(()); return Ok(());
} }
pub fn items_list(tx: &mut Transaction, account: &Account) -> Result<Vec<Item>, Error> { pub fn items_list(tx: &mut Transaction, account: &Account) -> Result<Vec<Item>, Error> {
let query = " let query = "
SELECT data SELECT data, id
FROM items FROM items
WHERE account = $1; WHERE account = $1;
"; ";
@ -98,18 +146,21 @@ pub fn items_list(tx: &mut Transaction, account: &Account) -> Result<Vec<Item>,
let result = tx let result = tx
.query(query, &[&account.id])?; .query(query, &[&account.id])?;
let items: Result<Vec<Item>, _> = result.iter().map(|row| { let mut items = vec![];
let item_bytes: Vec<u8> = row.get(0);
from_slice::<Item>(&item_bytes)
}).collect();
// catch any errors for row in result.into_iter() {
if items.is_err() { let item_bytes: Vec<u8> = row.get(0);
return Err(err_msg("could not deserialize an item")); let id = row.get(1);
match from_slice::<Item>(&item_bytes) {
Ok(i) => items.push(i),
Err(_e) => {
item_delete(tx, id)?;
}
};
} }
// now unwrap is safe return Ok(items);
return Ok(items.unwrap());
} }
// # max damage potion // # max damage potion

View File

@ -7,7 +7,7 @@ use std::net::{TcpStream};
// demo // demo
use std::iter; use std::iter;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use rand::distributions::Alphanumeric; use rand::distributions::{Alphanumeric};
use serde_cbor::{from_slice, to_vec}; use serde_cbor::{from_slice, to_vec};
use uuid::Uuid; use uuid::Uuid;
@ -164,11 +164,6 @@ impl Rpc {
params: RpcResult::GameState(game_skill(msg.params, tx, &account)?) 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); return Ok(game_response);
} }
@ -180,11 +175,6 @@ impl Rpc {
params: RpcResult::GameState(game_target(msg.params, tx, &account)?) 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); return Ok(game_response);
} }

View File

@ -355,6 +355,9 @@ pub enum Skill {
Calm, Calm,
Rez, Rez,
// Sleep,
// Nightmare,
// ------------------- // -------------------
// Destruction // Destruction
// ------------------- // -------------------