Merge branch 'develop' into msg-pane

This commit is contained in:
ntr 2019-09-21 16:23:03 +10:00
commit 0ec6bdaad5
18 changed files with 103 additions and 69 deletions

View File

@ -1 +1 @@
1.4.6 1.4.8

View File

@ -27,7 +27,6 @@
* fuck magic * fuck magic
* empower on ko * empower on ko
var / skill info rpc -> sell cost / cooldown
* rework vecs into sets * rework vecs into sets
* remove names so games/instances are copy * remove names so games/instances are copy

View File

@ -1,6 +1,6 @@
{ {
"name": "mnml-client", "name": "mnml-client",
"version": "1.4.6", "version": "1.4.8",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
{ {
"name": "mnml-client", "name": "mnml-client",
"version": "1.4.6", "version": "1.4.8",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -34,7 +34,7 @@ class ConstructAvatar extends Component {
<div <div
class="avatar" class="avatar"
id={construct.id} id={construct.id}
onClick={this.onClick.bind(this)} onMouseDown={this.onClick.bind(this)}
style={{ 'background-image': `url(/imgs/${construct.img}.svg)` }}> style={{ 'background-image': `url(/imgs/${construct.img}.svg)` }}>
<ConstructAnimation construct={construct} /> <ConstructAnimation construct={construct} />
</div> </div>

View File

@ -3,7 +3,7 @@ const range = require('lodash/range');
const reactStringReplace = require('react-string-replace'); const reactStringReplace = require('react-string-replace');
const { INFO } = require('./../constants'); const { INFO } = require('./../constants');
const { convertItem, removeTier, itemSpeed } = require('../utils'); const { convertItem, removeTier } = require('../utils');
const shapes = require('./shapes'); const shapes = require('./shapes');
function InfoComponent(args) { function InfoComponent(args) {
@ -46,15 +46,14 @@ function InfoComponent(args) {
: false; : false;
const itemRegEx = /(Red|Blue|Green)/; const itemRegEx = /(Red|Blue|Green)/;
const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]()); const itemSourceDescription = reactStringReplace(itemSourceInfo, itemRegEx, match => shapes[match]());
const calcSpeed = itemSource.length const speed = <div> Speed {shapes.SpeedStat()} multiplier {fullInfo.speed * 4}% </div>;
? (24 + (itemSpeed(itemSource[0].components[0]) + itemSpeed(itemSource[0].components[1])) * itemSpeed(itemSource[0].components[2])) * 4 const cooldown = fullInfo.cooldown ? `${fullInfo.cooldown} Turn delay` : null;
: (24 + itemSpeed(info)) * 4;
const speed = <div> Speed {shapes.SpeedStat()} multiplier {calcSpeed}% </div>;
return ( return (
<div class="info-skill"> <div class="info-skill">
<h2>{fullInfo.item}</h2> <h2>{fullInfo.item} - {fullInfo.cost}b</h2>
<h3>SKILL</h3> <h3> SKILL </h3>
{itemSourceDescription} {itemSourceDescription}
<div> {cooldown} </div>
<div>{infoDescription}</div> <div>{infoDescription}</div>
{speed} {speed}
</div> </div>
@ -133,7 +132,6 @@ function InfoComponent(args) {
} }
return false; return false;
}); });
console.log(info);
const bonusObj = info.includes('Life') const bonusObj = info.includes('Life')
? <div class={`${reqClass} bonus`} > + {bonus.bonus}</div> ? <div class={`${reqClass} bonus`} > + {bonus.bonus}</div>
: <div class={`${reqClass} bonus`} > + {bonus.bonus}%</div>; : <div class={`${reqClass} bonus`} > + {bonus.bonus}%</div>;
@ -157,7 +155,7 @@ function InfoComponent(args) {
return ( return (
<div class="info-spec"> <div class="info-spec">
<h2>{info}</h2> <h2>{info} - {fullInfo.cost}b</h2>
<h3>SPEC</h3> <h3>SPEC</h3>
{itemSourceDescription} {itemSourceDescription}
<div>{infoDescription}</div> <div>{infoDescription}</div>
@ -167,10 +165,10 @@ function InfoComponent(args) {
</div> </div>
); );
} }
const cost = fullInfo.cost ? `- ${fullInfo.cost}b` : false;
return ( return (
<div class="info-item"> <div class="info-item">
<h2>{fullInfo.item}</h2> <h2>{fullInfo.item} {cost}</h2>
<div>{fullInfo.description}</div> <div>{fullInfo.description}</div>
</div> </div>
); );

View File

@ -87,12 +87,12 @@ function registerEvents(store) {
); );
} }
return setTimeout(() => { return setTimeout(() => {
const animSkill = anims.animTarget ? removeTier(anims.animTarget.skill) : false;
store.dispatch(actions.setAnimSource(null)); store.dispatch(actions.setAnimSource(null));
store.dispatch(actions.setAnimTarget(null)); store.dispatch(actions.setAnimTarget(null));
store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimText(null));
store.dispatch(actions.setAnimFocus([])); store.dispatch(actions.setAnimFocus([]));
if (!sequence.includes('END_SKILL') if (!sequence.includes('END_SKILL') || (animSkill && ['Banish', 'Invert'].includes(animSkill))) return cb();
|| ['Banish', 'Invert'].includes(removeTier(anims.animTarget.skill))) return cb();
return true; return true;
}, timeout); }, timeout);
}, err => { }, err => {
@ -206,6 +206,7 @@ function registerEvents(store) {
} }
function setDemo(d) { function setDemo(d) {
const initial = { const initial = {
players: d, players: d,
combiner: [], combiner: [],
@ -215,7 +216,8 @@ function registerEvents(store) {
}; };
const startDemo = () => { const startDemo = () => {
console.log(initial); const { account } = store.getState();
if (account) return false;
store.dispatch(actions.setDemo(initial)); store.dispatch(actions.setDemo(initial));
store.dispatch(actions.setAnimTarget(null)); store.dispatch(actions.setAnimTarget(null));
setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [0] }))), 2000); setTimeout(() => store.dispatch(actions.setDemo(Object.assign({}, initial, { combiner: [0] }))), 2000);

View File

@ -187,20 +187,6 @@ const removeTier = skill => {
return skill; return skill;
}; };
function itemSpeed(item) {
switch (item) {
case 'Attack': return 1;
case 'Stun': return 2;
case 'Block': return 3;
case 'Buff': return 4;
case 'Debuff': return 4;
case 'Red': return 3;
case 'Green': return 2;
case 'Blue': return 1;
default: return 0;
}
}
function postData(url = '/', data = {}) { function postData(url = '/', data = {}) {
// Default options are marked with * // Default options are marked with *
return fetch(`/api${url}`, { return fetch(`/api${url}`, {
@ -264,6 +250,5 @@ module.exports = {
TARGET_COLOURS, TARGET_COLOURS,
randomPoints, randomPoints,
removeTier, removeTier,
itemSpeed,
match, match,
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "mnml-ops", "name": "mnml-ops",
"version": "1.4.6", "version": "1.4.8",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "mnml" name = "mnml"
version = "1.4.6" version = "1.4.8"
authors = ["ntr <ntr@smokestack.io>"] authors = ["ntr <ntr@smokestack.io>"]
[dependencies] [dependencies]

View File

@ -357,6 +357,10 @@ pub fn constructs(tx: &mut Transaction, account: &Account) -> Result<Vec<Constru
}, },
} }
}) })
.map(|mut sk| {
sk.account = account.id;
sk
})
.map(|sk| Construct::from_skeleton(&sk)) .map(|sk| Construct::from_skeleton(&sk))
.collect::<Vec<Construct>>(); .collect::<Vec<Construct>>();
@ -386,6 +390,10 @@ pub fn team(tx: &mut Transaction, account: &Account) -> Result<Vec<Construct>, E
}, },
} }
}) })
.map(|mut sk| {
sk.account = account.id;
sk
})
.map(|sk| Construct::from_skeleton(&sk)) .map(|sk| Construct::from_skeleton(&sk))
.collect::<Vec<Construct>>(); .collect::<Vec<Construct>>();

View File

@ -238,7 +238,7 @@ impl Construct {
pub fn from_skeleton(skeleton: &ConstructSkeleton) -> Construct { pub fn from_skeleton(skeleton: &ConstructSkeleton) -> Construct {
return Construct { return Construct {
id: skeleton.id, id: skeleton.id,
account: skeleton.id, account: skeleton.account,
img: skeleton.img, img: skeleton.img,
name: skeleton.name.clone(), name: skeleton.name.clone(),
@ -249,7 +249,7 @@ impl Construct {
pub fn to_skeleton(&self) -> ConstructSkeleton { pub fn to_skeleton(&self) -> ConstructSkeleton {
ConstructSkeleton { ConstructSkeleton {
id: self.id, id: self.id,
account: self.id, account: self.account,
img: self.img, img: self.img,
name: self.name.clone(), name: self.name.clone(),
} }
@ -271,8 +271,11 @@ impl Construct {
self self
} }
pub fn new_name(self, name: String) -> Construct { pub fn new_name(self, name: String) -> Result<Construct, Error> {
self.named(&name) if name.len() > 20 {
return Err(err_msg("20 character name maximum"));
}
Ok(self.named(&name))
} }
pub fn learn(mut self, s: Skill) -> Construct { pub fn learn(mut self, s: Skill) -> Construct {

View File

@ -322,7 +322,7 @@ impl Game {
return Err(err_msg("game not in skill phase")); return Err(err_msg("game not in skill phase"));
} }
let mut game_state = self.clone(); let mut game_state = self.clone();
self.stack.retain(|s| game_state.construct_by_id(s.source_construct_id).unwrap().account == player_id); self.stack.retain(|s| game_state.construct_by_id(s.source_construct_id).unwrap().account != player_id);
return Ok(self); return Ok(self);
} }

View File

@ -1,7 +1,7 @@
use skill::{Skill}; use skill::{Skill};
use spec::{Spec, SpecValues}; use spec::{Spec, SpecValues};
use construct::{Colours}; use construct::{Colours};
use effect::{Colour}; use effect::{Colour, Cooldown};
#[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)]
pub enum Item { pub enum Item {
@ -320,18 +320,44 @@ impl Item {
let combos = get_combos(); let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self) let combo = combos.iter().find(|c| c.item == *self)
.unwrap_or_else(|| panic!("unable to find components for {:?}", self)); .unwrap_or_else(|| panic!("unable to find components for {:?}", self));
return combo.components.iter().fold(0, |acc, c| acc + c.cost()); return combo.components.iter().fold(0, |acc, c| {
match c {
Item::Attack |
Item::Block |
Item::Buff |
Item::Debuff |
Item::Stun => acc,
Item::Power |
Item::Life |
Item::Speed => acc + 1,
_ => acc + c.cost(),
}
});
}, },
} }
} }
pub fn speed(&self) -> u64 { pub fn base_speed(&self) -> u64 {
match self { match self {
Item::Attack => 1, Item::Attack => 1,
Item::Stun => 2, Item::Stun => 2,
Item::Block => 3, Item::Block => 3,
Item::Buff | Item::Buff |
Item::Debuff => 4, Item::Debuff => 4,
Item::Blue => 1,
Item::Green => 2,
Item::Red => 3,
_ => 0,
}
}
pub fn speed(&self) -> u64 {
match self {
Item::Attack |
Item::Stun |
Item::Block |
Item::Buff |
Item::Debuff => 24 + self.base_speed(),
_ => { _ => {
let combos = get_combos(); let combos = get_combos();
let combo = combos.iter().find(|c| c.item == *self) let combo = combos.iter().find(|c| c.item == *self)
@ -343,17 +369,17 @@ impl Item {
combo.components.iter().for_each(|unit| { combo.components.iter().for_each(|unit| {
colour_speed += match unit { colour_speed += match unit {
Item::Red => 3, Item::Red |
Item::Green => 2, Item::Green |
Item::Blue => 1, Item::Blue => unit.base_speed(),
_ => 0, _ => 0,
}; };
skill_speed += match unit { skill_speed += match unit {
Item::Attack => 1, Item::Attack |
Item::Stun => 2, Item::Stun |
Item::Block => 3, Item::Block |
Item::Buff | Item::Buff |
Item::Debuff => 4, Item::Debuff => unit.base_speed(),
_ => 0, _ => 0,
}; };
if colour_speed == 0 && skill_speed == 0 { if colour_speed == 0 && skill_speed == 0 {
@ -960,7 +986,7 @@ impl Item {
Item::BreakPlus => vec![Item::Break, Item::Break, Item::Break], Item::BreakPlus => vec![Item::Break, Item::Break, Item::Break],
Item::BreakPlusPlus => vec![Item::BreakPlus, Item::BreakPlus, Item::BreakPlus], Item::BreakPlusPlus => vec![Item::BreakPlus, Item::BreakPlus, Item::BreakPlus],
Item::LinkPlus => vec![Item::Link, Item::Link, Item::Link], Item::LinkPlus => vec![Item::Link, Item::Link, Item::Link],
Item::LinkPlusPlus => vec![Item::LinkPlusPlus, Item::LinkPlusPlus, Item::LinkPlusPlus], Item::LinkPlusPlus => vec![Item::LinkPlus, Item::LinkPlus, Item::LinkPlus],
Item::BanishPlus => vec![Item::Banish, Item::Banish, Item::Banish], Item::BanishPlus => vec![Item::Banish, Item::Banish, Item::Banish],
Item::BanishPlusPlus => vec![Item::BanishPlus, Item::BanishPlus, Item::BanishPlus], Item::BanishPlusPlus => vec![Item::BanishPlus, Item::BanishPlus, Item::BanishPlus],
@ -1425,9 +1451,12 @@ pub fn get_combos() -> Vec<Combo> {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct ItemInfo { pub struct ItemInfo {
pub item: Item, pub item: Item,
pub cost: usize,
pub spec: bool, pub spec: bool,
pub skill: bool,
pub values: Option<SpecValues>, pub values: Option<SpecValues>,
pub skill: bool,
pub speed: Option<u64>,
pub cooldown: Cooldown,
pub description: String, pub description: String,
} }
@ -1455,13 +1484,22 @@ pub fn item_info() -> ItemInfoCtr {
.into_iter() .into_iter()
.map(|v| ItemInfo { .map(|v| ItemInfo {
item: v, item: v,
cost: v.cost(),
spec: v.into_spec().is_some(), spec: v.into_spec().is_some(),
skill: v.into_skill().is_some(),
description: v.into_description(),
values: match v.into_spec() { values: match v.into_spec() {
Some(s) => Some(s.values()), Some(s) => Some(s.values()),
None => None None => None
}, },
skill: v.into_skill().is_some(),
description: v.into_description(),
speed: match v.into_skill() {
Some(s) => Some(s.speed()),
None => None
},
cooldown: match v.into_skill() {
Some(s) => s.base_cd(),
None => None
},
}) })
.collect::<Vec<ItemInfo>>(); .collect::<Vec<ItemInfo>>();

View File

@ -152,7 +152,7 @@ pub fn apply(tx: &mut Transaction, account: &Account, variant: MtxVariant, const
account::debit(tx, account.id, cost)?; account::debit(tx, account.id, cost)?;
construct = match mtx.variant { construct = match mtx.variant {
MtxVariant::Rename => construct.new_name(name), MtxVariant::Rename => construct.new_name(name)?,
_ => construct.new_img(), _ => construct.new_img(),
}; };

View File

@ -14,7 +14,7 @@ use cookie::Cookie;
use stripe::{Client as StripeClient, Subscription}; use stripe::{Client as StripeClient, Subscription};
use crossbeam_channel::{unbounded, Sender as CbSender}; use crossbeam_channel::{unbounded, Sender as CbSender};
use ws::{Builder, listen, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender}; use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender};
use account::{Account}; use account::{Account};
use account; use account;

View File

@ -293,7 +293,7 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
let mut target = game.construct_by_id(target.id).unwrap().clone(); let mut target = game.construct_by_id(target.id).unwrap().clone();
match event { match event {
Event::Damage { amount, skill, mitigation: _, colour: _ } => { Event::Damage { amount, skill, mitigation: _, colour: c } => {
if target.affected(Effect::Electric) { if target.affected(Effect::Electric) {
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
.find(|e| e.effect == Effect::Electric).unwrap().clone(); .find(|e| e.effect == Effect::Electric).unwrap().clone();
@ -315,16 +315,17 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
_ => panic!("no absorb skill"), _ => panic!("no absorb skill"),
}; };
} }
if c == Colour::Red {
if target.affected(Effect::Counter) { if target.affected(Effect::Counter) {
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
.find(|e| e.effect == Effect::Counter).unwrap().clone(); .find(|e| e.effect == Effect::Counter).unwrap().clone();
match meta { match meta {
Some(EffectMeta::Skill(s)) => { Some(EffectMeta::Skill(s)) => {
resolutions = counter_attack(&mut target, &mut source, resolutions, s); resolutions = counter_attack(&mut target, &mut source, resolutions, s);
}, },
_ => panic!("no counter skill"), _ => panic!("no counter skill"),
}; };
}
} }
}, },
_ => (), _ => (),

View File

@ -240,7 +240,7 @@ mod tests {
let mut vbox = Vbox::new(); let mut vbox = Vbox::new();
vbox.bound = vec![Item::Strike]; vbox.bound = vec![Item::Strike];
vbox.reclaim(0).unwrap(); vbox.reclaim(0).unwrap();
assert_eq!(vbox.bits, 22); assert_eq!(vbox.bits, 20);
} }
#[test] #[test]