write battles

This commit is contained in:
ntr 2018-10-20 00:36:47 +11:00
parent bfd0208785
commit b0c80472e6
6 changed files with 156 additions and 99 deletions

View File

@ -3,14 +3,17 @@ const preact = require('preact');
function CrypPanel({ battle }) { function CrypPanel({ battle }) {
if (!battle) return <div>...</div>; if (!battle) return <div>...</div>;
return ( return (
<div className=""> <div>{JSON.stringify(battle)}</div>
<div>{JSON.stringify(battle.a)}</div> )
<div>{JSON.stringify(battle.b)}</div> // return (
<div> // <div className="">
{battle.log.map((l, i) => (<p key={i} >{l}</p>))} // <div>{JSON.stringify(battle.a)}</div>
</div> // <div>{JSON.stringify(battle.b)}</div>
</div> // <div>
); // {battle.log.map((l, i) => (<p key={i} >{l}</p>))}
// </div>
// </div>
// );
} }
module.exports = CrypPanel; module.exports = CrypPanel;

View File

@ -1,6 +1,14 @@
use uuid::Uuid; use uuid::Uuid;
use rand::prelude::*; use rand::prelude::*;
// Db Commons
use serde_cbor::{from_slice, to_vec};
use postgres::transaction::Transaction;
use failure::Error;
use failure::err_msg;
use account::Account;
use rpc::BattleAbilityParams;
use cryp::{Cryp, CrypStat, Stat}; use cryp::{Cryp, CrypStat, Stat};
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
@ -54,12 +62,12 @@ impl Ability {
// roll = c.skills.iter().fold(roll, |roll, s| s.apply(roll)); // roll = c.skills.iter().fold(roll, |roll, s| s.apply(roll));
// finally combine with stat // finally combine with stat
// log.push(format!("{:064b} <- finalised", roll.result)); println!("{:064b} <- finalised", roll.result);
roll.result = roll.result & stat.value; roll.result = roll.result & stat.value;
// log.push(format!("{:064b} & <- attribute roll", self.value)); println!("{:064b} & <- attribute roll", stat.value);
println!("{:064b} = {:?}", roll.result, roll.result); println!("{:064b} = {:?}", roll.result, roll.result);
// log.push(format!("")); println!("");
return roll; return roll;
} }
@ -96,9 +104,9 @@ pub struct Team {
} }
impl Team { impl Team {
pub fn new() -> Team { pub fn new(account: Uuid) -> Team {
return Team { return Team {
id: Uuid::new_v4(), id: account,
cryps: vec![], cryps: vec![],
abilities: vec![], abilities: vec![],
incoming: vec![], incoming: vec![],
@ -124,6 +132,7 @@ impl Team {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Battle { pub struct Battle {
pub id: Uuid,
pub team_size: usize, pub team_size: usize,
pub team_num: usize, pub team_num: usize,
pub teams: Vec<Team>, pub teams: Vec<Team>,
@ -135,6 +144,7 @@ pub struct Battle {
impl Battle { impl Battle {
pub fn new() -> Battle { pub fn new() -> Battle {
return Battle { return Battle {
id: Uuid::new_v4(),
team_size: 0, team_size: 0,
team_num: 0, team_num: 0,
teams: vec![], teams: vec![],
@ -287,7 +297,7 @@ impl Battle {
if self.is_finished() { if self.is_finished() {
self.phase = Phase::Finish; self.phase = Phase::Finish;
return self return self;
} }
self.ability_phase_start(); self.ability_phase_start();
@ -300,11 +310,6 @@ impl Battle {
panic!("battle not in damage phase"); panic!("battle not in damage phase");
} }
// go through every team
// roll the incoming ability
// resolve
// check if battle is over
// sometimes... you just gotta // sometimes... you just gotta
for team in self.teams.clone().iter_mut() { for team in self.teams.clone().iter_mut() {
for incoming in team.incoming.clone().iter_mut() { for incoming in team.incoming.clone().iter_mut() {
@ -321,42 +326,56 @@ impl Battle {
pub fn is_finished(&self) -> bool { pub fn is_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()))
} }
}
// pub fn next(&mut self) -> &mut Battle {
// if self.finished() {
// panic!("{:?} is finished", self);
// }
// let mut a_turn = self.a.turn();
// let mut b_turn = self.b.turn();
// self.a.assign_dmg(&self.b, &mut a_turn, &b_turn);
// self.b.assign_dmg(&self.a, &mut b_turn, &a_turn);
// self.log.append(&mut a_turn.log);
// self.log.append(&mut b_turn.log);
// self
// }
// pub fn cryp_by_id(&self, id: Uuid) -> &Cryp { // add the ability
// match self.cryps().iter().find(|c| c.id == id) { // add client function call
// Some(c) => c, // check for cryp ability ownership
// None => panic!("cryp not in battle {:?}", self), // check for battle participation
// }
// }
// pub fn winner(&self) -> Option<&Cryp> { pub fn battle_ability(params: BattleAbilityParams, tx: &mut Transaction, account: &Account) -> Result<Battle, Error> {
// if self.cryps().iter().all(|c| c.is_ko()) { let query = "
// return None SELECT *
// } FROM battles
WHERE id = $1
";
// match self.cryps().iter().find(|c| !c.is_ko()) { let result = tx
// Some(w) => Some(w), .query(query, &[&params.battle_id])?;
// None => panic!("no winner found {:?}", self),
// } let returned = match result.iter().next() {
// } Some(row) => row,
None => return Err(err_msg("battle not found")),
};
// tells from_slice to cast into a cryp
let battle_bytes: Vec<u8> = returned.get("data");
let mut battle = from_slice::<Battle>(&battle_bytes)?;
battle.add_ability(account.id, params.cryp_id, params.target_team_id, params.kind);
return battle_write(battle, tx);
}
pub fn battle_write(battle: Battle, tx: &mut Transaction) -> Result<Battle, Error> {
let battle_bytes = to_vec(&battle)?;
let query = "
UPDATE battles
SET data = $1
WHERE id = $2
RETURNING id, data;
";
let result = tx
.query(query, &[&battle_bytes, &battle.id])?;
let _returned = result.iter().next().expect("no row returned");
println!("{:?} wrote battle", battle.id);
return Ok(battle);
} }
@ -387,13 +406,13 @@ mod tests {
.set_team_num(2) .set_team_num(2)
.set_team_size(1); .set_team_size(1);
let mut x_team = Team::new(); let x_team_id = Uuid::new_v4();
let x_team_id = x_team.id; let mut x_team = Team::new(x_team_id);
x_team x_team
.set_cryps(vec![x]); .set_cryps(vec![x]);
let mut y_team = Team::new(); let y_team_id = Uuid::new_v4();
let y_team_id = y_team.id; let mut y_team = Team::new(y_team_id);
y_team y_team
.set_cryps(vec![y]); .set_cryps(vec![y]);
@ -423,6 +442,8 @@ mod tests {
assert!([Phase::Ability, Phase::Finish].contains(&battle.phase)); assert!([Phase::Ability, Phase::Finish].contains(&battle.phase));
println!("{:?}", battle);
return; return;
} }
} }

View File

@ -1,3 +1,4 @@
use uuid::Uuid;
use rand::prelude::*; use rand::prelude::*;
use serde_cbor::{from_slice}; use serde_cbor::{from_slice};
@ -10,7 +11,7 @@ use account::Account;
use rpc::{CombatPveParams}; use rpc::{CombatPveParams};
use cryp::{Cryp, cryp_write}; use cryp::{Cryp, cryp_write};
use battle::Battle; use battle::{Battle, Team};
// use skill::Skill; // use skill::Skill;
fn generate_mob(plr: &Cryp) -> Cryp { fn generate_mob(plr: &Cryp) -> Cryp {
@ -30,54 +31,52 @@ fn generate_mob(plr: &Cryp) -> Cryp {
} }
pub fn pve(params: CombatPveParams, tx: &mut Transaction, account: &Account) -> Result<Battle, Error> { pub fn pve(params: CombatPveParams, tx: &mut Transaction, account: &Account) -> Result<Battle, Error> {
let query = "
SELECT *
FROM cryps
WHERE id = $1
AND account = $2;
";
let result = tx
.query(query, &[&params.id, &account.id])?;
let returned = match result.iter().next() {
Some(row) => row,
None => return Err(err_msg("cryp not found")),
};
// tells from_slice to cast into a cryp
let cryp_bytes: Vec<u8> = returned.get("data");
let plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?;
// TEMP
if plr.hp.value == 0 {
return Err(err_msg("cryp is ko")); return Err(err_msg("cryp is ko"));
// plr.rez();
}
// let query = " let mob = generate_mob(&plr);
// SELECT *
// FROM cryps
// WHERE id = $1
// AND account = $2;
// ";
// let result = tx let mut battle = Battle::new();
// .query(query, &[&params.id, &account.id])?;
// let returned = match result.iter().next() { battle
// Some(row) => row, .set_team_num(2)
// None => return Err(err_msg("cryp not found")), .set_team_size(1);
// };
// // tells from_slice to cast into a cryp let mut plr_team = Team::new(account.id);
// let cryp_bytes: Vec<u8> = returned.get("data"); plr_team
// let plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?; .set_cryps(vec![plr]);
// // TEMP let mut mob_team = Team::new(Uuid::nil());
// if plr.hp.value == 0 { mob_team
// return Err(err_msg("cryp is ko")); .set_cryps(vec![mob]);
// // plr.rez();
// }
// let mob = generate_mob(&plr); battle
// let mut battle = Battle::new(&plr, &mob); .add_team(plr_team)
.add_team(mob_team);
// loop { battle.start();
// battle.next();
// if battle.finished() { Ok(battle)
// let success = match battle.winner() {
// Some(c) => c.id == plr.id,
// None => false,
// };
// let mut post_battle_plr = battle.cryp_by_id(plr.id).clone();
// if success {
// post_battle_plr = post_battle_plr.add_xp();
// }
// cryp_write(post_battle_plr, tx)?;
// break Ok(battle)
// }
// }
} }

View File

@ -36,7 +36,6 @@ impl Item {
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::Revive => revive(self, tx, target),
_ => panic!("missing item action"),
} }
} }
} }

View File

@ -4,7 +4,6 @@ extern crate tungstenite;
extern crate env_logger; extern crate env_logger;
extern crate bcrypt; extern crate bcrypt;
#[macro_use]
extern crate dotenv; extern crate dotenv;
extern crate postgres; extern crate postgres;
extern crate r2d2; extern crate r2d2;

View File

@ -11,7 +11,7 @@ use failure::err_msg;
use net::Db; use net::Db;
use cryp::{Cryp, cryp_spawn}; use cryp::{Cryp, cryp_spawn};
use battle::{Battle}; use battle::{Battle, AbilityKind, battle_ability};
use combat::{pve}; use combat::{pve};
use account::{Account, account_create, account_login, account_from_token, account_cryps}; use account::{Account, account_create, account_login, account_from_token, account_cryps};
use item::{Item, items_list, item_use}; use item::{Item, items_list, item_use};
@ -40,6 +40,7 @@ impl Rpc {
let response = match v.method.as_ref() { let response = match v.method.as_ref() {
"cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account, client), "cryp_spawn" => Rpc::cryp_spawn(data, &mut tx, account, client),
"combat_pve" => Rpc::combat_pve(data, &mut tx, account, client), "combat_pve" => Rpc::combat_pve(data, &mut tx, account, client),
"battle_ability" => Rpc::battle_ability(data, &mut tx, account, client),
"account_create" => Rpc::account_create(data, &mut tx, account, client), "account_create" => Rpc::account_create(data, &mut tx, account, client),
"account_login" => Rpc::account_login(data, &mut tx, account, client), "account_login" => Rpc::account_login(data, &mut tx, account, client),
"account_cryps" => Rpc::account_cryps(data, &mut tx, account, client), "account_cryps" => Rpc::account_cryps(data, &mut tx, account, client),
@ -86,7 +87,28 @@ impl Rpc {
return Ok(battle_response); return Ok(battle_response);
} }
fn cryp_spawn(data: Vec<u8>, tx: &mut Transaction, account: Option<Account>, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn battle_ability(data: Vec<u8>, tx: &mut Transaction, account: Option<Account>, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
let a = match account {
Some(a) => a,
None => return Err(err_msg("auth required")),
};
let msg = from_slice::<BattleAbilityMsg>(&data).or(Err(err_msg("invalid params")))?;
let battle_response = RpcResponse {
method: "battle_state".to_string(),
params: RpcResult::Pve(battle_ability(msg.params, tx, &a)?)
};
// Rpc::send_msg(client, RpcResponse {
// method: "account_cryps".to_string(),
// params: RpcResult::CrypList(account_cryps(tx, &a)?)
// })?;
return Ok(battle_response);
}
fn cryp_spawn(data: Vec<u8>, tx: &mut Transaction, account: Option<Account>, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
match from_slice::<CrypSpawnMsg>(&data) { match from_slice::<CrypSpawnMsg>(&data) {
Ok(v) => { Ok(v) => {
match account { match account {
@ -101,7 +123,7 @@ impl Rpc {
} }
} }
fn account_create(data: Vec<u8>, tx: &mut Transaction, account: Option<Account>, client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> { fn account_create(data: Vec<u8>, tx: &mut Transaction, _account: Option<Account>, _client: &mut WebSocket<TcpStream>) -> Result<RpcResponse, Error> {
match from_slice::<AccountCreateMsg>(&data) { match from_slice::<AccountCreateMsg>(&data) {
Ok(v) => Ok(RpcResponse { Ok(v) => Ok(RpcResponse {
method: v.method, method: v.method,
@ -206,6 +228,20 @@ pub struct CombatPveParams {
pub id: Uuid, pub id: Uuid,
} }
#[derive(Debug,Clone,Serialize,Deserialize)]
struct BattleAbilityMsg {
method: String,
params: BattleAbilityParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct BattleAbilityParams {
pub battle_id: Uuid,
pub cryp_id: Uuid,
pub target_team_id: Uuid,
pub kind: AbilityKind,
}
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
struct AccountCreateMsg { struct AccountCreateMsg {
method: String, method: String,