cryp persistence

This commit is contained in:
ntr 2018-10-08 16:25:02 +11:00
parent 6ffc98e472
commit 840d571b89
18 changed files with 216 additions and 205 deletions

View File

@ -4,6 +4,9 @@ export const setAccount = (value) => ({ type: SET_ACCOUNT, value });
export const SET_CRYPS = 'SET_CRYPS'; export const SET_CRYPS = 'SET_CRYPS';
export const setCryps = (value) => ({ type: SET_CRYPS, value }); export const setCryps = (value) => ({ type: SET_CRYPS, value });
export const SET_BATTLE = 'SET_BATTLE';
export const setBattle = (value) => ({ type: SET_BATTLE, value });
export const SET_ACTIVE_CRYP = 'SET_ACTIVE_CRYP'; export const SET_ACTIVE_CRYP = 'SET_ACTIVE_CRYP';
export const setActiveCryp = (value) => ({ type: SET_ACTIVE_CRYP, value }); export const setActiveCryp = (value) => ({ type: SET_ACTIVE_CRYP, value });

View File

@ -0,0 +1,16 @@
const { connect } = require('preact-redux');
const Battle = require('./battle');
const addState = connect(
function receiveState(state) {
const { battle } = state;
// function sendCombatPve(crypId) {
// return ws.sendCombatPve(crypId);
// }
return { battle };
}
);
module.exports = addState(Battle);

View File

@ -0,0 +1,11 @@
const preact = require('preact');
function CrypPanel({ battle }) {
return (
<div className="">
{JSON.stringify(battle)}
</div>
);
}
module.exports = CrypPanel;

View File

@ -0,0 +1,20 @@
// eslint-disable-next-line
const preact = require('preact');
const CrypListContainer = require('./cryp.list.container');
const BattleContainer = require('./battle.container');
function renderBody() {
return (
<section className="columns">
<div className="column is-3">
<CrypListContainer />
</div>
<div className="column">
<BattleContainer />
</div>
</section>
);
}
module.exports = renderBody;

View File

@ -1,100 +0,0 @@
const preact = require('preact');
function CrypPanel() {
return (
<div className="tile is-ancestor has-text-centered">
<div className="tile is-vertical is-parent">
<div className="tile">
<div className="tile is-vertical is-child is-6">
<p className="title"> Future Animation / Fizzy Area</p>
</div>
<div className="tile is-vertical is-child">
<div className="columns">
<div className ="column has-text-right">
<figure className="image">
<svg width="160" height="160" data-jdenticon-value="Drake" />
</figure>
</div>
<div className="column">
<div className="columns">
<div className="column has-text-left">
<p className="title">Drake</p>
<p className="subtitle">Level 1</p>
</div>
<div className="column has-text-centered">
<p> Flying </p>
<p> Fire </p>
<p> Stone </p>
</div>
<div className="column has-text-centered">
<ul> <i className="fas fa-bomb" /> 5 </ul>
<ul> <i className="fas fa-walking" /> 5 </ul>
<ul> <i className="fas fa-shield-alt" /> 5 </ul>
</div>
</div>
<div className="has-text-centered">5 / 5 HP </div>
<progress className="progress is-success" value="5" max="5"></progress>
</div>
</div>
</div>
</div>
<br />
<br />
<div className="tile">
<div className="tile is-vertical is-child is-5">
<div className="columns">
<div className="column">
<div className="columns">
<div className="column has-text-centered">
<ul> <i className="fas fa-bomb" /> 10 </ul>
<ul> <i className="fas fa-walking" /> 1 </ul>
<ul> <i className="fas fa-shield-alt" /> 40 </ul>
</div>
<div className="column has-text-centered">
<p> Walking </p>
<p> Water </p>
<p> Rock </p>
</div>
<div className="column has-text-right">
<p className="title">BB</p>
<p className="subtitle">Level 1</p>
</div>
</div>
<div className="has-text-centered">5 / 5 HP </div>
<progress className="progress is-success" value="5" max="5"></progress>
</div>
<div className ="column has-text-left is-narrow">
<figure className="image">
<svg width="160" height="160" data-jdenticon-value="Turtle" />
</figure>
</div>
</div>
</div>
<div className="tile is-vertical">
<div className="columns">
<div className="column is-one-quarter">
<span className="button is-large is-info is-fullwidth is-rounded" >Ability 1</span>
<br />
<span className="button is-large is-info is-fullwidth is-rounded" >Ability 3</span>
</div>
<div className="column is-one-quarter">
<span className="button is-large is-info is-fullwidth is-rounded" >Ability 2</span>
<br />
<span className="button is-large is-info is-fullwidth is-rounded" >Ability 4</span>
</div>
<div className="column">
<p className="title"> Combat Log </p>
<p> "bamboo basher" deals 0 dmg to "drake" (0 blocked / 1 hp remaining) </p>
<p> "bamboo basher" deals 0 dmg to "drake" (0 blocked / 1 hp remaining) </p>
</div>
</div>
</div>
</div>
<br />
</div>
</div>
);
}
module.exports = CrypPanel;

View File

@ -1,6 +1,6 @@
const { connect } = require('preact-redux'); const { connect } = require('preact-redux');
const CrypsPanel = require('./cryps.panel'); const CrypList = require('./cryp.list');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
@ -13,4 +13,4 @@ const addState = connect(
} }
); );
module.exports = addState(CrypsPanel); module.exports = addState(CrypList);

View File

@ -0,0 +1,23 @@
const preact = require('preact');
function CrypPanel({ cryps, sendCombatPve }) {
if (!cryps) return <div>not ready</div>;
const crypPanels = cryps.map(cryp => (
<div key={cryp.id} className="tile is-parent is-vertical box">
<div className="title">{cryp.name}</div>
<button
className="button is-success"
type="submit"
onClick={() => sendCombatPve(cryp.id)}>
Start PVE
</button>
</div>
));
return (
<div>
{crypPanels}
</div>
);
}
module.exports = CrypPanel;

View File

@ -0,0 +1,37 @@
const preact = require('preact');
function renderCrypPanel(cryp) {
return (
<div className="tile">
<div className="tile is-vertical is-child">
<div className="columns">
<div className ="column has-text-right">
<figure className="image">
<svg width="160" height="160" data-jdenticon-value="Drake" />
</figure>
</div>
<div className="column">
<div className="columns">
<div className="column has-text-left">
<p className="title">Drake</p>
<p className="subtitle">Level 1</p>
</div>
<div className="column has-text-centered">
<p>Flying</p>
<p>Fire</p>
<p>Stone</p>
</div>
<div className="column has-text-centered">
<ul> <i className="fas fa-bomb" /> 5 </ul>
<ul> <i className="fas fa-walking" /> 5 </ul>
<ul> <i className="fas fa-shield-alt" /> 5 </ul>
</div>
</div>
<div className="has-text-centered">5 / 5 HP </div>
<progress className="progress is-success" value="5" max="5"></progress>
</div>
</div>
</div>
</div>
)
}

View File

@ -1,88 +0,0 @@
const preact = require('preact');
function CrypPanel({ cryps, sendCombatPve }) {
if (!cryps) return <div>not ready</div>;
const crypPanels = cryps.map(cryp => (
<div key={cryp.id} className="tile is-ancestor has-text-centered has-background-grey is-dark is-10">
<div className="tile is-6">
<div className="tile is-parent is-vertical is-3">
<section className="tile is-child notification is-success">
<p>Helm Slot</p>
</section>
<section className="tile is-child notification is-success">
<p>Body Armor</p>
</section>
<section className="tile is-child notification is-success">
<p>Gloves</p>
</section>
<section className="tile is-child notification is-success">
<p>Boots</p>
</section>
</div>
<div className="tile is-parent is-6">
<section className="tile is-child notification is-info">
<figure className="image">
<svg width="160" height="160" data-jdenticon-value={cryp.name} />
</figure>
<p className="title">{cryp.name}</p>
<p className="subtitle">The big boy</p>
</section>
</div>
<div className="tile is-parent is-vertical is-3">
<section className="tile is-child notification is-dark">
<p>Weapon</p>
</section>
<section className="tile is-child notification is-dark">
<p>Jewellery</p>
</section>
<section className="tile is-child notification is-dark">
<p>Artifact</p>
</section>
</div>
</div>
<div className="tile is-parent is-6">
<section className="tile is-child notification has-background-grey is-dark">
<p className="title">Cryp Stats</p>
<p className="subtitle">Level - {cryp.lvl}</p>
<div className="columns">
<div className="column">
<ul> Hit Points <i className="fas fa-plus" /> {cryp.hp.value} </ul>
<ul> Attack Damage <i className="fas fa-bomb" /> {cryp.dmg.value} </ul>
</div>
<div className="column">
<ul> Stamina <i className="fas fa-walking" /> {cryp.stam.value} </ul>
<ul> Defense <i className="fas fa-shield-alt" /> {cryp.def.value} </ul>
</div>
</div>
<br />
Progress to next level
<div className="columns">
<div className="column is-10">
<progress className="progress is-success" value={cryp.xp} max="4"></progress>
</div>
<div className="column has-text-left has-text-weight-bold">
{cryp.xp} / 4 XP
</div>
</div>
<button
className="button is-success"
type="submit"
onClick={() => sendCombatPve(cryp.id)}>
Start PVE
</button>
</section>
</div>
</div>
));
// map is a function that is called on every element of an array
// so in this ^^ case it calls Icon('Mashy') which returns some jsx
// that gets put into the dom
return (
<section>
{crypPanels}
</section>
);
}
module.exports = CrypPanel;

View File

@ -0,0 +1,19 @@
// eslint-disable-next-line
const preact = require('preact');
const LoginContainer = require('./login.container');
function renderHeader() {
return (
<section className="hero is-dark">
<div className="hero-body">
<div className="container">
<h1 className="title">cryps.gg</h1>
<LoginContainer />
</div>
</div>
</section>
)
}
module.exports = renderHeader;

View File

@ -0,0 +1,19 @@
// eslint-disable-next-line
const preact = require('preact');
const LoginContainer = require('./login.container');
function renderHeader() {
return (
<section className="hero is-dark">
<div className="hero-body">
<div className="container">
<h1 className="title">cryps.gg</h1>
<LoginContainer />
</div>
</div>
</section>
);
}
module.exports = renderHeader;

View File

@ -6,17 +6,16 @@ const { createStore, combineReducers } = require('redux');
const reducers = require('./reducers'); const reducers = require('./reducers');
const actions = require('./actions'); const actions = require('./actions');
const fizzyText = require('../lib/fizzy-text'); // const fizzyText = require('../lib/fizzy-text');
const createSocket = require('./socket'); const createSocket = require('./socket');
const CrypsContainer = require('./components/cryps.container'); const Header = require('./components/header.component');
const LoginContainer = require('./components/login.container'); const Body = require('./components/body.component');
const CrypBattle = require('./components/cryp.battle');
// const Navbar = require('./components/navbar');
// Redux Store // Redux Store
const store = createStore( const store = createStore(
combineReducers({ combineReducers({
battle: reducers.battleReducer,
account: reducers.accountReducer, account: reducers.accountReducer,
cryps: reducers.crypsReducer, cryps: reducers.crypsReducer,
ws: reducers.wsReducer, ws: reducers.wsReducer,
@ -37,11 +36,8 @@ jdenticon.config = {
const Cryps = () => ( const Cryps = () => (
<section> <section>
<LoginContainer /> <Header />
<div id="fizzytext" /> <Body />
<CrypsContainer />
<br />
<CrypBattle />
</section> </section>
); );
@ -53,4 +49,4 @@ const Main = () => (
preact.render(<Main />, document.body); preact.render(<Main />, document.body);
fizzyText('cryps.gg'); // fizzyText('cryps.gg');

View File

@ -20,6 +20,16 @@ function crypsReducer(state = defaultCryps, action) {
} }
} }
const defaultBattle = null;
function battleReducer(state = defaultBattle, action) {
switch (action.type) {
case actions.SET_BATTLE:
return action.value;
default:
return state;
}
}
const defaultWs = null; const defaultWs = null;
function wsReducer(state = defaultWs, action) { function wsReducer(state = defaultWs, action) {
switch (action.type) { switch (action.type) {
@ -31,6 +41,7 @@ function wsReducer(state = defaultWs, action) {
} }
module.exports = { module.exports = {
battleReducer,
accountReducer, accountReducer,
crypsReducer, crypsReducer,
wsReducer, wsReducer,

View File

@ -41,6 +41,11 @@ function createSocket(store) {
console.log('got my cryps', cryps); console.log('got my cryps', cryps);
} }
function battleState(response) {
const [structName, battle] = response;
store.dispatch(actions.setBattle(battle));
}
function crypSpawn(response) { function crypSpawn(response) {
const [structName, cryp] = response; const [structName, cryp] = response;
console.log('got a new cryp', cryp); console.log('got a new cryp', cryp);
@ -77,6 +82,7 @@ function createSocket(store) {
const handlers = { const handlers = {
cryp_spawn: crypSpawn, cryp_spawn: crypSpawn,
combat_pve: combatPve, combat_pve: combatPve,
battle_state: battleState,
account_login: accountLogin, account_login: accountLogin,
account_create: accountLogin, account_create: accountLogin,
account_cryps: accountCryps, account_cryps: accountCryps,

View File

@ -1,4 +1,7 @@
* Battling * Battling
* QOL
* auto login
* ws reconnect
* Levelling * Levelling
* Global rolls * Global rolls
* Logins ✔️ * Logins ✔️

View File

@ -10,7 +10,7 @@ use net::Db;
use account::Account; use account::Account;
use rpc::{CombatPveParams}; use rpc::{CombatPveParams};
use cryp::Cryp; use cryp::{Cryp, write_cryp};
use battle::Battle; use battle::Battle;
use skill::Skill; use skill::Skill;
@ -113,7 +113,7 @@ where F: Fn(&Battle) -> Result<(), Error>
// tells from_slice to cast into a cryp // tells from_slice to cast into a cryp
let cryp_bytes: Vec<u8> = returned.get("data"); let cryp_bytes: Vec<u8> = returned.get("data");
let plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?; let mut plr: Cryp = from_slice::<Cryp>(&cryp_bytes)?;
let mob = generate_mob(&plr); let mob = generate_mob(&plr);
let mut battle = Battle::new(&plr, &mob); let mut battle = Battle::new(&plr, &mob);
@ -124,6 +124,16 @@ where F: Fn(&Battle) -> Result<(), Error>
send(&battle)?; send(&battle)?;
if battle.finished() { if battle.finished() {
let success = match battle.winner() {
Some(c) => c.id == plr.id,
None => false,
};
if success {
plr = plr.add_xp();
write_cryp(plr, db, account)?;
}
break Ok(battle) break Ok(battle)
} }
} }

View File

@ -217,6 +217,31 @@ pub fn spawn(params: CrypSpawnParams, db: Db, account: Account) -> Result<Cryp,
return Ok(cryp); return Ok(cryp);
} }
pub fn write_cryp(cryp: Cryp, db: Db, account: Account) -> Result<Cryp, Error> {
let cryp_bytes = to_vec(&cryp)?;
let query = "
UPDATE cryps
SET data = $1
WHERE id = $2
AND account = $3
RETURNING id, account, data;
";
let tx = db.transaction()?;
let result = tx
.query(query, &[&cryp_bytes, &cryp.id, &account.id])?;
let _returned = result.iter().next().expect("no row returned");
println!("{:?} wrote cryp {:}", account.id, cryp.id);
tx.commit()?;
return Ok(cryp);
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use cryp::*; use cryp::*;

View File

@ -48,7 +48,7 @@ impl Rpc {
"combat_pve" => { "combat_pve" => {
let send = |b: &Battle| -> Result<(), Error> { let send = |b: &Battle| -> Result<(), Error> {
let reply = RpcResponse { let reply = RpcResponse {
method: "combat_pve".to_string(), method: "battle_state".to_string(),
params: RpcResult::Pve(b.clone()) params: RpcResult::Pve(b.clone())
}; };
let response = to_vec(&reply)?; let response = to_vec(&reply)?;