Merge branch 'release/1.4.7'

This commit is contained in:
ntr 2019-09-19 22:33:13 +10:00
commit ce4abaffdd
32 changed files with 325 additions and 167 deletions

View File

@ -7,7 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed ### Fixed
### Changed ### Changed
## [0.1.4 2019-09-17] ## [0.1.4 2019-09-18]
### Changed ### Changed
Removed self targetting, all skills can be used on any target Removed self targetting, all skills can be used on any target
@ -16,6 +16,11 @@ Removed self targetting, all skills can be used on any target
`Purify` No cooldown `Purify` No cooldown
`Recharge` No cooldown `Recharge` No cooldown
`Banish`
Now deals 40 / 75 / 125% target red / blue life before applying banish debuff
Constant 2T duration at all levels
Constant 3T cooldown at all levels
`Link` reworked -> `Link` reworked ->
Stuns caster for 3/2/1T Stuns caster for 3/2/1T
If target has higher green life than caster: If target has higher green life than caster:

View File

@ -1 +1 @@
1.4.6 1.4.7

View File

@ -8,17 +8,13 @@
* can't reset password without knowing password =\ * can't reset password without knowing password =\
* treats * treats
* constructs jiggle when clicked
* client animation bpm * client animation bpm
* background colour changes depending on time of day * background colour changes depending on time of day
* hit animation wobble
* combat text scale + translate
* susbcriber gold name in instance * susbcriber gold name in instance
* bot game grind * bot game grind
* msg pane * msg pane
* game invites
* audio * audio

View File

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

View File

@ -181,3 +181,43 @@ section {
} }
} }
} }
@media (max-width: 800px) {
section {
grid-template-columns: 1fr;
.list {
grid-template-columns: 1fr 1fr;
}
}
.demo {
grid-template-columns: 1fr;
grid-template-areas:
"vinfo"
"vcons"
"game"
"game";
.construct-list .instance-construct:not(:first-child) {
display: none;
}
.game-demo {
grid-template-columns: 1fr;
}
}
.menu .team {
grid-template-columns: 1fr;
.construct {
height: 10em;
}
}
.account {
grid-template-columns: 1fr;
}
}

View File

@ -6,7 +6,7 @@ html, body, #mnml {
background-color: black; background-color: black;
font-family: 'Jura'; font-family: 'Jura';
color: whitesmoke; color: whitesmoke;
font-size: 12pt; font-size: 14pt;
user-select: none; user-select: none;
-moz-user-select: none; -moz-user-select: none;
@ -26,7 +26,7 @@ html, body, #mnml {
@media (min-width: 1921px) { @media (min-width: 1921px) {
html, body, #mnml { html, body, #mnml {
font-size: 14pt; font-size: 16pt;
} }
} }

View File

@ -1,6 +1,6 @@
@media (max-width: 800px) { @media (max-width: 800px) {
#mnml { #mnml {
font-size: 10pt; font-size: 14pt;
padding: 1em 0 0 0; padding: 1em 0 0 0;
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: 1fr min-content; grid-template-rows: 1fr min-content;
@ -44,10 +44,10 @@
display: none; display: none;
} }
header { /* header {
display: none; display: none;
} }
*/
main { main {
overflow-x: hidden; overflow-x: hidden;
padding: 0 0.5em; padding: 0 0.5em;

View File

@ -18,7 +18,7 @@
<body> <body>
<noscript> <noscript>
<p>js is required to run mnml.</p> <p>js is required to run mnml.</p>
<p>this site has no trackers or ads.</p> <p>this site has no ads. free to play forever.</p>
</noscript> </noscript>
</body> </body>
<script src="https://js.stripe.com/v3/"></script> <script src="https://js.stripe.com/v3/"></script>

View File

@ -1,8 +1,8 @@
require('./assets/styles/styles.less'); require('./assets/styles/styles.less');
require('./assets/styles/account.less');
require('./assets/styles/menu.less'); require('./assets/styles/menu.less');
require('./assets/styles/nav.less'); require('./assets/styles/nav.less');
require('./assets/styles/footer.less'); require('./assets/styles/footer.less');
require('./assets/styles/account.less');
require('./assets/styles/controls.less'); require('./assets/styles/controls.less');
require('./assets/styles/instance.less'); require('./assets/styles/instance.less');
require('./assets/styles/vbox.less'); require('./assets/styles/vbox.less');

View File

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

View File

@ -3,8 +3,10 @@ const anime = require('animejs').default;
function wiggle(id, idle) { function wiggle(id, idle) {
const duration = 300; const duration = 300;
const target = document.getElementById(id); const target = document.getElementById(id);
const x = (window.screen.width / anime.random(-100, 100)) * 0.1; const x = window.screen.width * 0.01 * (Math.round(Math.random()) ? Math.random() : -Math.random());
const y = (window.screen.height / anime.random(-20, 100)) * 0.1; const y = window.screen.height * 0.01 * (Math.round(Math.random()) ? Math.random() : -Math.random());
console.log(x, y);
return anime({ return anime({
targets: target, targets: target,
rotate: 0, rotate: 0,

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>
@ -67,7 +67,7 @@ class ConstructAvatar extends Component {
return true; return true;
} }
if (animText && animText.constructId === construct.id) { if (animText && animText !== this.props.animText && animText.constructId === construct.id) {
return wiggle(construct.id, this.idle); return wiggle(construct.id, this.idle);
} }

View File

@ -154,13 +154,17 @@ function Demo(args) {
</div> </div>
<div class="game"> <div class="game">
<div class="game-construct"> <div class="game-construct">
<ConstructAvatar construct={players[1].constructs[0]} /> <div class="left"></div>
<ConstructAnimation construct={players[1].constructs[0]} /> <div class="right">
<ConstructAvatar construct={players[1].constructs[0]} />
</div>
</div> </div>
<div></div> <div></div>
<div class="game-construct"> <div class="game-construct">
<ConstructAvatar construct={players[1].constructs[1]} /> <div class="left"></div>
<ConstructAnimation construct={players[1].constructs[1]} /> <div class="right">
<ConstructAvatar construct={players[1].constructs[1]} />
</div>
</div> </div>
</div> </div>
</div> </div>
@ -168,7 +172,7 @@ function Demo(args) {
}; };
return ( return (
<section class='demo news'> <section class='demo news bottom'>
{vboxDemo()} {vboxDemo()}
{vboxConstructs()} {vboxConstructs()}
{gameDemo()} {gameDemo()}

View File

@ -21,14 +21,14 @@ function InfoComponent(args) {
return ( return (
<div> <div>
<h2>VBOX phase</h2> <h2>VBOX phase</h2>
<p>strengthen and specialise your constructs by equipping items to them.</p> <p>Strengthen and specialise your constructs by equipping items to them.</p>
<p>double click to purchase items in the <b>VBOX</b> and move them to your <b>INVENTORY</b>.</p> <p>Double click to purchase items in the <b>VBOX</b> and move them to your <b>INVENTORY</b>.</p>
<p> <p>
combine a <b>SKILL</b> or <b>SPEC</b> with 2 <b>COLOURS</b> to create an item.<br /> Combine a <b>SKILL</b> or <b>SPEC</b> with 2 <b>COLOURS</b> to create an item.<br />
combine <b>3 of the same item</b> to upgrade it.<br /> Combine <b>3 of the same item</b> to upgrade it.<br />
click an item and then click a construct to <b>equip</b> that item to it.<br /> Click an item and then click a construct to <b>equip</b> that item to it.<br />
</p> </p>
<p>click the <b>READY</b> button for the <b>GAME PHASE</b>.</p> <p>Click the <b>READY</b> button for the <b>GAME PHASE</b>.</p>
</div> </div>
); );
} }
@ -133,14 +133,16 @@ function InfoComponent(args) {
} }
return false; return false;
}); });
console.log(info);
const bonusObj = info.includes('Life')
? <div class={`${reqClass} bonus`} > + {bonus.bonus}</div>
: <div class={`${reqClass} bonus`} > + {bonus.bonus}%</div>;
const overFlowObj = overFlow.length ? <div> {overFlow} </div> : null; const overFlowObj = overFlow.length ? <div> {overFlow} </div> : null;
return ( return (
<div key={i} class="spec-goal"> <div key={i} class="spec-goal">
{goals} {goals}
{overFlowObj} {overFlowObj}
<div class={`${reqClass} bonus`} > {bonusObj}
+ {bonus.bonus}
</div>
</div> </div>
); );
}); });

View File

@ -179,10 +179,9 @@ function Construct(props) {
const stats = Object.keys(STATS).map(s => { const stats = Object.keys(STATS).map(s => {
const stat = STATS[s]; const stat = STATS[s];
const info = (s === 'SpeedStat' && 'Speed') const info = (s === 'SpeedStat' && 'speedStat')
|| (s.includes('Power') && 'Power') || (s.includes('Power') && 'powerStat')
|| (s.includes('Life') && 'Life'); || (s.includes('Life') && 'lifeStat');
return <div key={stat.stat} return <div key={stat.stat}
alt={stat.stat} alt={stat.stat}
class={stat.stat} class={stat.stat}

View File

@ -60,12 +60,15 @@ function Play(args) {
if (!shop) return false; if (!shop) return false;
const useMtx = (item, i) => ( const useMtx = (item, i) => {
<figure key={i} onClick={() => setMtxActive(item)} > const price = item === 'Rename' ? 5 : 1;
<figcaption>{item}</figcaption> return (
<button disabled={account.balance === 0}>¤1</button> <figure key={i} onClick={() => setMtxActive(item)} >
</figure> <figcaption>{item}</figcaption>
); <button disabled={account.balance === 0}>¤{price}</button>
</figure>
);
};
const availableMtx = (item, i) => ( const availableMtx = (item, i) => (
<figure key={i} onClick={() => mtxBuy(item)} > <figure key={i} onClick={() => mtxBuy(item)} >
@ -87,7 +90,6 @@ function Play(args) {
Subscribe Subscribe
</button>; </button>;
return ( return (
<section class="top"> <section class="top">
<div class="news"> <div class="news">

View File

@ -9,6 +9,14 @@ function Scoreboard(args) {
leave, leave,
} = args; } = args;
const scoreText = () => {
if (player.score === 'Zero') return '▫▫▫';
if (player.score === 'One') return '■▫▫';
if (player.score === 'Two') return '■■▫';
if (player.score === 'Win') return '■■■';
return '';
};
/*
let scoreText = () => { let scoreText = () => {
if (player.score === 'Zero') return '▫▫▫▫'; if (player.score === 'Zero') return '▫▫▫▫';
if (player.score === 'One') return '■▫▫▫'; if (player.score === 'One') return '■▫▫▫';
@ -18,6 +26,7 @@ function Scoreboard(args) {
if (player.score === 'Win') return '■■■■'; if (player.score === 'Win') return '■■■■';
return ''; return '';
}; };
*/
if (!isPlayer) { if (!isPlayer) {
return ( return (

View File

@ -27,21 +27,21 @@ function Shop(args) {
return ( return (
<section class="top"> <section class="top">
<div class="news"> <div class="news">
<h1>support the game</h1> <h1>Support the game</h1>
<p> <p>
<b>credits</b> are in game currency that can be used to purchase: <b>Credits</b> are in game currency used to change your team appearance:
<ul> <ul>
<li>img sets</li> <li>Image sets</li>
<li>construct renames</li> <li>Reroll construct image from owned sets </li>
<li>new constructs</li> <li>Construct renames</li>
<li>New constructs</li>
</ul> </ul>
</p> </p>
<p> <p>
<b>subscriptions</b> grant extra benefits: <b>Subscriptions</b> grant extra benefits:
<ul> <ul>
<li>¤150 per month</li> <li>¤150 per month</li>
<li>chat wheel (soon )</li> <li>More community features in the future including account icons and chat wheel</li>
<li>account icons (soon )</li>
</ul> </ul>
</p> </p>
</div> </div>

View File

@ -62,10 +62,10 @@ function Register(args) {
return ( return (
<div class="login"> <div class="login">
<p> <p>
send a recovery email to your account's confirmed email address. Send a recovery email to your account's confirmed email address.
</p> </p>
<p> <p>
if you have not set and confirmed an email address for your account If you have not set and confirmed an email address for your account
please contact support. please contact support.
</p> </p>
<label for="username">Account Email</label> <label for="username">Account Email</label>

View File

@ -51,17 +51,16 @@ function Welcome() {
<section> <section>
<div class="news"> <div class="news">
<p> <p>
mnml is a turn-based 1v1 strategy game in an abstract setting.<br /> Welcome to mnml.
outplay your opponents by building your team of 3 constructs from a shifting meta of skills, effects and specialisations.<br /> </p>
<p> Turn-based 1v1 strategy game in an abstract setting. </p>
<p>
Build a unique team of 3 constructs from a range of skills and specialisations.<br />
Outplay your opponent in multiple rounds by adapting to an always shifting meta. <br />
Simple rules, complex interactions and unique mechanics.<br />
</p> </p>
<p> <p>
simple rules, complex interactions, simultaneous turns to increase the pace, and a unique speed mechanic;<br /> Free to play, no pay to win. Register to start playing.<br />
mnml is a tactical game unlike any other.
</p>
<p>
free to play<br />
no email required<br />
glhf
</p> </p>
</div> </div>
{pageEl()} {pageEl()}

View File

@ -26,11 +26,11 @@ module.exports = {
INFO: { INFO: {
vbox: { vbox: {
item: 'VBOX', item: 'VBOX',
description: <p><b>ITEMS</b> that are available to buy.<br />the <b>VBOX</b> is refilled every round.<br />click <b>REFILL</b> at the bottom to purchase a refill. </p>, description: <p><b>ITEMS</b> that are available to buy.<br />The <b>VBOX</b> is refilled every round.<br />Click <b>REFILL</b> at the bottom to purchase a refill. </p>,
}, },
inventory: { inventory: {
item: 'INVENTORY', item: 'INVENTORY',
description: <p>holds <b>ITEMS</b><br /><b>ITEMS</b> carry over each round.</p>, description: <p>Holds <b>ITEMS</b><br /><b>ITEMS</b> carry over each round.</p>,
}, },
bits: { bits: {
item: 'BITS', item: 'BITS',
@ -72,6 +72,17 @@ module.exports = {
item: 'SPECS', item: 'SPECS',
description: 'SPECS increase the STATS of a CONSTRUCT.\nSPECS have increased effect once they reach a THRESHOLD across your whole team.\nClick a SPEC above and select a CONSTRUCT to equip.\nDouble-click to unequip.', description: 'SPECS increase the STATS of a CONSTRUCT.\nSPECS have increased effect once they reach a THRESHOLD across your whole team.\nClick a SPEC above and select a CONSTRUCT to equip.\nDouble-click to unequip.',
}, },
powerStat: {
item: 'POWER',
description: 'Power determines the base damage and healing of your construct skills. Combine POWER specs to increase construct power.',
},
lifeStat: {
item: 'LIFE',
description: 'The life of your construct.\n When your construct reaches 0 green life it is knocked out and cannot cast skills.\nRed life mitigates red damage and blue life mitigates blue damage. Combine LIFE specs to increase life totals.',
},
speedStat: {
item: 'SPEED',
description: 'Speed determines the order in which skills resolve. Combine SPEED specs to increase speed.',
},
}, },
}; };

View File

@ -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

@ -63,6 +63,23 @@ server {
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
} }
server {
server_name minimalstudios.com.au;
location / {
root /var/lib/mnml/public/press/;
index index.html;
try_files $uri $uri/ index.html;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/minimalstudios.com.au/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/minimalstudios.com.au/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
# http -> https # http -> https
server { server {
@ -74,3 +91,8 @@ server {
server_name minimal.gg; server_name minimal.gg;
return 301 https://mnml.gg$request_uri; return 301 https://mnml.gg$request_uri;
} }
server {
server_name minimalstudios.com.au;
return 301 https://minimalstudios.com.au$request_uri;
}

View File

@ -1,6 +1,6 @@
{ {
"name": "mnml-ops", "name": "mnml-ops",
"version": "1.4.6", "version": "1.4.7",
"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.7"
authors = ["ntr <ntr@smokestack.io>"] authors = ["ntr <ntr@smokestack.io>"]
[dependencies] [dependencies]

View File

@ -76,7 +76,7 @@ pub fn invader_write(id: Uuid) -> Result<Uuid, Error> {
write!(&mut svg, "</g></svg>")?; write!(&mut svg, "</g></svg>")?;
let dest = format!("/var/lib/mnml/public/imgs/{}.svg", id); let dest = format!("/var/lib/mnml/public/imgs/{}.svg", id);
println!("molecule dest={:?}", dest); // info!("molecule dest={:?}", dest);
let mut file = File::create(dest)?; let mut file = File::create(dest)?;
file.write_all(&svg)?; file.write_all(&svg)?;
@ -232,7 +232,7 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
write!(&mut svg, "</g></svg>")?; write!(&mut svg, "</g></svg>")?;
let dest = format!("/var/lib/mnml/public/imgs/{}.svg", id); let dest = format!("/var/lib/mnml/public/imgs/{}.svg", id);
println!("/var/lib/mnml/public/imgs/{}.svg", id); // println!("/var/lib/mnml/public/imgs/{}.svg", id);
let mut file = File::create(dest)?; let mut file = File::create(dest)?;
file.write_all(&svg)?; file.write_all(&svg)?;

View File

@ -15,9 +15,9 @@ use chrono::Duration;
use account::Account; use account::Account;
use account; use account;
use events::{EventsTx, Event};
use player::{Player, Score, player_create}; use player::{Player, Score, player_create};
use construct::{Construct, construct_get};
use mob::{bot_player, instance_mobs}; use mob::{bot_player, instance_mobs};
use game::{Game, Phase, game_get, game_write, game_update}; use game::{Game, Phase, game_get, game_write, game_update};
use item::{Item}; use item::{Item};

View File

@ -563,76 +563,106 @@ impl Item {
Item::Red => format!("Combine with skills and specs to create upgraded items. \n Speed and chaos."), Item::Red => format!("Combine with skills and specs to create upgraded items. \n Speed and chaos."),
// base skills // base skills
Item::Attack => format!("Deal {:?}% RedPower as red damage", Item::Attack => format!("Deal {:?}% RedPower as red damage.",
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
Item::Block => format!("Reduce red damage taken by {:?}%", Item::Block => format!("Reduce red damage taken by {:?}%.",
100 - self.into_skill().unwrap().effect()[0].get_multiplier()), 100 - self.into_skill().unwrap().effect()[0].get_multiplier()),
Item::Stun => format!("Stun target construct for {:?}T", Item::Stun => format!("Stun target construct for {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Buff => format!("Increase target construct RedPower and SpeedStat by {:?}%", Item::Buff => format!("Increase target construct RedPower and SpeedStat by {:?}%.",
self.into_skill().unwrap().effect()[0].get_multiplier() - 100), self.into_skill().unwrap().effect()[0].get_multiplier() - 100),
Item::Debuff => format!("Slows the target reducing SpeedStat by {:?}%", Item::Debuff => format!("Slows the target reducing SpeedStat by {:?}%.",
100 - self.into_skill().unwrap().effect()[0].get_multiplier()), 100 - self.into_skill().unwrap().effect()[0].get_multiplier()),
// specs // specs
// Base // Base
Item::Power => format!("Base item for increased power. Power determines the base damage and healing of your construct skills."), Item::Power => format!("Increases all power stats by {:?}%. Power determines the base damage and healing of your construct skills.",
Item::Life => format!("Base item for increased life. self.into_spec().unwrap().values().base()),
When your construct reaches 0 GreenLife it is knocked out and cannot cast skills."), Item::Life => format!("Increases construct GreenLife by {:?}.
Item::Speed => format!("Base item for increased speed. When your construct reaches 0 GreenLife it is knocked out and cannot cast skills.",
Speed SpeedStat determines the order in which skills resolve."), self.into_spec().unwrap().values().base()),
Item::Speed => format!("Increases construct speed by {:?}%.
Speed SpeedStat determines the order in which skills resolve.",
self.into_spec().unwrap().values().base()),
// Lifes Upgrades // Lifes Upgrades
Item::LifeGG=> format!("Increases construct GreenLife green life. Item::LifeGG |
When your construct reaches 0 GreenLife it is knocked out and cannot cast skills."), Item::LifeGGPlus |
Item::LifeRR=> format!("Increases construct RedLife red life. Item::LifeGGPlusPlus => format!("Increases construct GreenLife by {:?}.
Mitigates red damage that would otherwise reduce your GreenLife green life."), If your team meets total colour thresholds the spec provides additional bonuses.",
Item::LifeBB=> format!("Increases construct BlueLife blue life. self.into_spec().unwrap().values().base()),
Mitigates blue damage that would otherwise reduce your GreenLife green life."),
Item::LifeRG=> format!("Increases construct GreenLife and RedLife"), Item::LifeRR |
Item::LifeGB=> format!("Increases construct GreenLife and BlueLife"), Item::LifeRRPlus |
Item::LifeRB=> format!("Increases construct RedLife and BlueLife"), Item::LifeRRPlusPlus => format!("Increases construct RedLife by {:?}.
Item::LifeGGPlus => format!("Increases construct GreenLife."), If your team meets total colour thresholds the spec provides additional bonuses.",
Item::LifeRRPlus => format!("Increases construct RedLife."), self.into_spec().unwrap().values().base()),
Item::LifeBBPlus => format!("Increases construct BlueLife."),
Item::LifeRGPlus => format!("Increases construct GreenLife and RedLife"), Item::LifeBB |
Item::LifeGBPlus => format!("Increases construct GreenLife and BlueLife"), Item::LifeBBPlus |
Item::LifeRBPlus => format!("Increases construct RedLife and BlueLife"), Item::LifeBBPlusPlus => format!("Increases construct BlueLife by {:?}.
Item::LifeGGPlusPlus => format!("Increases construct GreenLife."), If your team meets total colour thresholds the spec provides additional bonuses.",
Item::LifeRRPlusPlus => format!("Increases construct RedLife."), self.into_spec().unwrap().values().base()),
Item::LifeBBPlusPlus => format!("Increases construct BlueLife."),
Item::LifeRGPlusPlus => format!("Increases construct GreenLife and RedLife"), Item::LifeRG |
Item::LifeGBPlusPlus => format!("Increases construct GreenLife and BlueLife"), Item::LifeRGPlus |
Item::LifeRBPlusPlus => format!("Increases construct RedLife and BlueLife"), Item::LifeRGPlusPlus => format!("Increases construct RedLife and GreenLife by {:?}.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
Item::LifeGB |
Item::LifeGBPlus |
Item::LifeGBPlusPlus => format!("Increases construct GreenLife and BlueLife by {:?}.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
Item::LifeRB |
Item::LifeRBPlus |
Item::LifeRBPlusPlus => format!("Increases construct RedLife and BlueLife by {:?}.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
// Power Upgrades // Power Upgrades
Item::PowerRR=> format!("Increases construct RedPower."), Item::PowerRR |
Item::PowerBB=> format!("Increases construct BluePower."), Item::PowerRRPlus |
Item::PowerGG=> format!("Increases construct GreenPower."), Item::PowerRRPlusPlus => format!("Increases construct RedPower by {:?}%.
Item::PowerRG=> format!("Increases construct GreenPower and RedPower."), If your team meets total colour thresholds the spec provides additional bonuses.",
Item::PowerGB=> format!("Increases construct GreenPower and BluePower."), self.into_spec().unwrap().values().base()),
Item::PowerRB=> format!("Increases construct RedPower and BluePower."), Item::PowerBB |
Item::PowerRRPlus => format!("Increases construct RedPower."), Item::PowerBBPlus |
Item::PowerBBPlus => format!("Increases construct BluePower."), Item::PowerBBPlusPlus => format!("Increases construct BluePower by {:?}%.
Item::PowerGGPlus => format!("Increases construct GreenPower."), If your team meets total colour thresholds the spec provides additional bonuses.",
Item::PowerRGPlus => format!("Increases construct GreenPower and RedPower."), self.into_spec().unwrap().values().base()),
Item::PowerGBPlus => format!("Increases construct GreenPower and BluePower."),
Item::PowerRBPlus => format!("Increases construct RedPower and BluePower."), Item::PowerGG |
Item::PowerRRPlusPlus => format!("Increases construct RedPower."), Item::PowerGGPlus |
Item::PowerBBPlusPlus => format!("Increases construct BluePower."), Item::PowerGGPlusPlus => format!("Increases construct GreenPower by {:?}%.
Item::PowerGGPlusPlus => format!("Increases construct GreenPower."), If your team meets total colour thresholds the spec provides additional bonuses.",
Item::PowerRGPlusPlus => format!("Increases construct GreenPower and RedPower."), self.into_spec().unwrap().values().base()),
Item::PowerGBPlusPlus => format!("Increases construct GreenPower and BluePower."), Item::PowerRG |
Item::PowerRBPlusPlus => format!("Increases construct RedPower and BluePower."), Item::PowerRGPlus |
Item::PowerRGPlusPlus => format!("Increases construct GreenPower and RedPower by {:?}%.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
Item::PowerGB |
Item::PowerGBPlus |
Item::PowerGBPlusPlus => format!("Increases construct GreenPower and BluePower by {:?}%.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
Item::PowerRB |
Item::PowerRBPlus |
Item::PowerRBPlusPlus => format!("Increases construct RedPower and BluePower by {:?}%.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
// Speed Upgrades // Speed Upgrades
Item::SpeedRR| Item::SpeedRR |
Item::SpeedBB| Item::SpeedBB |
Item::SpeedGG| Item::SpeedGG |
Item::SpeedRG| Item::SpeedRG |
Item::SpeedGB| Item::SpeedGB |
Item::SpeedRB| Item::SpeedRB |
Item::SpeedRRPlus | Item::SpeedRRPlus |
Item::SpeedBBPlus | Item::SpeedBBPlus |
Item::SpeedGGPlus | Item::SpeedGGPlus |
@ -644,20 +674,23 @@ impl Item {
Item::SpeedGGPlusPlus | Item::SpeedGGPlusPlus |
Item::SpeedRGPlusPlus | Item::SpeedRGPlusPlus |
Item::SpeedGBPlusPlus | Item::SpeedGBPlusPlus |
Item::SpeedRBPlusPlus => format!("Increases construct SpeedStat and provides COLOUR BONUSES"), Item::SpeedRBPlusPlus => format!("Increases construct SpeedStat by {:?}%.
If your team meets total colour thresholds the spec provides additional bonuses.",
self.into_spec().unwrap().values().base()),
// Skills <- need to move effect mulltipliers into skills // Skills <- need to move effect mulltipliers into skills
Item::Amplify| Item::Amplify|
Item::AmplifyPlus | Item::AmplifyPlus |
Item::AmplifyPlusPlus => format!("Increase RedPower and BluePower by {:?}%. Lasts {:?}T", Item::AmplifyPlusPlus => format!("Increase RedPower and BluePower by {:?}%. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_multiplier() - 100, self.into_skill().unwrap().effect()[0].get_multiplier() - 100,
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Banish| Item::Banish|
Item::BanishPlus | Item::BanishPlus |
Item::BanishPlusPlus => format!("Banish target for {:?}T. Item::BanishPlusPlus => format!("Banish target for {:?}T. Deal blue damage and red damage equal to {:?}% target red and blue life.
Banished constructs are immune to all skills and effects.", Banished constructs are immune to all skills and effects.",
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().multiplier()),
Item::Blast| Item::Blast|
Item::BlastPlus | Item::BlastPlus |
@ -666,7 +699,7 @@ impl Item {
Item::Chaos| Item::Chaos|
Item::ChaosPlus | Item::ChaosPlus |
Item::ChaosPlusPlus => format!( Item::ChaosPlusPlus => format!(
"Hits twice for red and blue damage. Damage {:?}% RedPower and BluePower. Randomly deals 0 to 30% more damage", "Hits twice for red and blue damage. Damage {:?}% RedPower and BluePower. Randomly deals 0 to 30% more damage.",
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
Item::Sustain| Item::Sustain|
@ -687,14 +720,14 @@ impl Item {
Item::Curse| Item::Curse|
Item::CursePlus | Item::CursePlus |
Item::CursePlusPlus => format!( Item::CursePlusPlus => format!(
"Increases red and blue damage taken by {:?}%. Lasts {:?}T", "Increases red and blue damage taken by {:?}%. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_multiplier() - 100, self.into_skill().unwrap().effect()[0].get_multiplier() - 100,
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Decay| Item::Decay|
Item::DecayPlus | Item::DecayPlus |
Item::DecayPlusPlus => format!( Item::DecayPlusPlus => format!(
"Reduces healing taken by {:?}% for {:?}T. Deals blue damage {:?}% BluePower each turn for {:?}T", "Reduces healing taken by {:?}% for {:?}T. Deals blue damage {:?}% BluePower each turn for {:?}T.",
100 - self.into_skill().unwrap().effect()[0].get_multiplier(), 100 - self.into_skill().unwrap().effect()[0].get_multiplier(),
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().effect()[1].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[1].get_skill().unwrap().multiplier(),
@ -703,7 +736,7 @@ impl Item {
Item::Absorb| Item::Absorb|
Item::AbsorbPlus | Item::AbsorbPlus |
Item::AbsorbPlusPlus => format!( Item::AbsorbPlusPlus => format!(
"Gain Absorb for {:?}T. {} Absorption lasts {:?}T", "Gain Absorb for {:?}T. {} Absorption lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
"When attacked with Absorb you gain Absorption which increases RedPower and BluePower based on Damage taken.", "When attacked with Absorb you gain Absorption which increases RedPower and BluePower based on Damage taken.",
self.into_skill().unwrap().effect()[0].get_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_skill().unwrap().effect()[0].get_duration()),
@ -723,7 +756,7 @@ impl Item {
Item::Hybrid| Item::Hybrid|
Item::HybridPlus | Item::HybridPlus |
Item::HybridPlusPlus => format!( Item::HybridPlusPlus => format!(
"Hybrid increases GreenPower by {:?}%, Blue based Attack skills will blast again dealing {:?}% GreenPower as blue damage. Lasts {:?}T", "Hybrid increases GreenPower by {:?}%, Blue based Attack skills will blast again dealing {:?}% GreenPower as blue damage. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_multiplier() - 100, self.into_skill().unwrap().effect()[0].get_multiplier() - 100,
Skill::HybridBlast.multiplier(), Skill::HybridBlast.multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
@ -744,7 +777,8 @@ impl Item {
Item::Purge| Item::Purge|
Item::PurgePlus | Item::PurgePlus |
Item::PurgePlusPlus => format!("Remove buffs from target construct"), Item::PurgePlusPlus => format!("Remove buffs from target construct. Applies purge which disables target green skills for {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration()),
Item::Purify| Item::Purify|
Item::PurifyPlus | Item::PurifyPlus |
@ -755,13 +789,13 @@ impl Item {
Item::Reflect| Item::Reflect|
Item::ReflectPlus | Item::ReflectPlus |
Item::ReflectPlusPlus => format!( Item::ReflectPlusPlus => format!(
"Reflect incoming blue skills to source. Lasts {:?}T", "Reflect incoming blue skills to source. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Recharge| Item::Recharge|
Item::RechargePlus | Item::RechargePlus |
Item::RechargePlusPlus => format!( Item::RechargePlusPlus => format!(
"Recharge RedLife and BlueLife based on {:?}% RedPower and BluePower", "Recharge RedLife and BlueLife based on {:?}% RedPower and BluePower.",
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
Item::Ruin| Item::Ruin|
@ -783,7 +817,7 @@ impl Item {
Item::SilencePlus | Item::SilencePlus |
Item::SilencePlusPlus => format!( Item::SilencePlusPlus => format!(
"Block the target from using blue skills for {:?}T and deals {:?}% BluePower as blue damage. "Block the target from using blue skills for {:?}T and deals {:?}% BluePower as blue damage.
Deals 45% more Damage per blue skill on target", Deals 45% more Damage per blue skill on target.",
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
@ -803,28 +837,28 @@ impl Item {
Item::Restrict| Item::Restrict|
Item::RestrictPlus | Item::RestrictPlus |
Item::RestrictPlusPlus => format!( Item::RestrictPlusPlus => format!(
"Block the target from using red skills for {:?}T and deals {:?}% RedPower as red damage. Deals 35% more damage per red skill on target", "Block the target from using red skills for {:?}T and deals {:?}% RedPower as red damage. Deals 35% more damage per red skill on target.",
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
Item::Bash| Item::Bash|
Item::BashPlus | Item::BashPlus |
Item::BashPlusPlus => format!( Item::BashPlusPlus => format!(
"Bash the target increasing the cooldowns of their skills. "Bash the target increasing the cooldowns of target skills by 1T.
Deals {:?}% RedPower per cooldown increased. Lasts {:?}T.", Deals {:?}% RedPower as red damage and 45% more damage per cooldown increased. Stuns for {:?}T.",
self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Strike| Item::Strike|
Item::StrikePlus | Item::StrikePlus |
Item::StrikePlusPlus => format!( Item::StrikePlusPlus => format!(
"Strike the target with speed dealing {:?}% RedPower as red damage", "Strike the target with speed dealing {:?}% RedPower as red damage.",
self.into_skill().unwrap().multiplier()), self.into_skill().unwrap().multiplier()),
Item::Siphon| Item::Siphon|
Item::SiphonPlus | Item::SiphonPlus |
Item::SiphonPlusPlus => format!( Item::SiphonPlusPlus => format!(
"Deals {:?}% BluePower as blue damage each turn and heals caster based on damage dealt. Lasts {:?}T", "Deals {:?}% BluePower as blue damage each turn and heals caster based on damage dealt. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
@ -838,7 +872,7 @@ impl Item {
Item::Break| Item::Break|
Item::BreakPlus | Item::BreakPlus |
Item::BreakPlusPlus => format!( Item::BreakPlusPlus => format!(
"Stun the target for {:?}T and applies Vulnerable increasing red damage taken by {:?}% for {:?}T", "Stun the target for {:?}T and applies Vulnerable increasing red damage taken by {:?}% for {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().effect()[1].get_multiplier() - 100, self.into_skill().unwrap().effect()[1].get_multiplier() - 100,
self.into_skill().unwrap().effect()[1].get_duration()), self.into_skill().unwrap().effect()[1].get_duration()),
@ -846,7 +880,7 @@ impl Item {
Item::Triage| Item::Triage|
Item::TriagePlus | Item::TriagePlus |
Item::TriagePlusPlus => format!( Item::TriagePlusPlus => format!(
"Heals target for {:?}% GreenPower each turn. Lasts {:?}T", "Heals target for {:?}% GreenPower each turn. Lasts {:?}T.",
self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
} }

View File

@ -27,24 +27,26 @@ pub enum Score {
} }
impl Score { impl Score {
pub fn add_win(self, opp: &Score) -> Score { pub fn add_win(self, _opp: &Score) -> Score {
match self { match self {
Score::Zero => Score::One, Score::Zero => Score::One,
Score::One => Score::Two, Score::One => Score::Two,
Score::Two => Score::Three, Score::Two => Score::Win,
Score::Three => match opp { // Tennis scoring
Score::Adv => Score::Three, // Score::Three => match opp {
Score::Three => Score::Adv, // Score::Adv => Score::Three,
_ => Score::Win, // Score::Three => Score::Adv,
} // _ => Score::Win,
Score::Adv => Score::Win, // }
// Score::Adv => Score::Win,
_ => panic!("faulty score increment {:?}", self), _ => panic!("faulty score increment {:?}", self),
} }
} }
pub fn add_loss(self) -> Score { pub fn add_loss(self) -> Score {
match self { match self {
Score::Adv => Score::Three, // Score::Adv => Score::Three,
_ => self, _ => self,
} }
} }
@ -376,7 +378,10 @@ mod tests {
player.score = player.score.add_win(&Score::Zero); player.score = player.score.add_win(&Score::Zero);
player.score = player.score.add_win(&Score::Zero); player.score = player.score.add_win(&Score::Zero);
player.score = player.score.add_win(&Score::Zero); player.score = player.score.add_win(&Score::Zero);
assert_eq!(player.score, Score::Three); // 40 / 0 assert_eq!(player.score, Score::Win); // 40 / 0
// Bo7 tennis scoring
/*assert_eq!(player.score, Score::Three); // 40 / 0
player.score = player.score.add_loss(); // adv -> deuce player.score = player.score.add_loss(); // adv -> deuce
assert_eq!(player.score, Score::Three); assert_eq!(player.score, Score::Three);
@ -391,7 +396,7 @@ mod tests {
assert_eq!(player.score, Score::Adv); assert_eq!(player.score, Score::Adv);
player.score = player.score.add_win(&Score::Three); player.score = player.score.add_win(&Score::Three);
assert_eq!(player.score, Score::Win); assert_eq!(player.score, Score::Win);*/
} }
} }

View File

@ -768,6 +768,10 @@ impl Skill {
Skill::SleepPlus => 300, Skill::SleepPlus => 300,
Skill::SleepPlusPlus => 400, Skill::SleepPlusPlus => 400,
Skill::Banish=> 40, //Green dmg (heal)
Skill::BanishPlus => 75,
Skill::BanishPlusPlus => 125,
Skill::Bash=> 65, Skill::Bash=> 65,
Skill::BashPlus => 95, Skill::BashPlus => 95,
Skill::BashPlusPlus => 140, Skill::BashPlusPlus => 140,
@ -810,9 +814,9 @@ impl Skill {
Skill::AmplifyPlusPlus => vec![ConstructEffect {effect: Effect::Amplify, duration: 4, Skill::AmplifyPlusPlus => vec![ConstructEffect {effect: Effect::Amplify, duration: 4,
meta: Some(EffectMeta::Multiplier(200)), tick: None}], meta: Some(EffectMeta::Multiplier(200)), tick: None}],
Skill::Banish => vec![ConstructEffect {effect: Effect::Banish, duration: 1,meta: None, tick: None}], Skill::Banish => vec![ConstructEffect {effect: Effect::Banish, duration: 2, meta: None, tick: None}],
Skill::BanishPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 2,meta: None, tick: None}], Skill::BanishPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 2, meta: None, tick: None}],
Skill::BanishPlusPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 3,meta: None, tick: None}], Skill::BanishPlusPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 2, meta: None, tick: None}],
Skill::Block => vec![ConstructEffect {effect: Effect::Block, duration: 1, Skill::Block => vec![ConstructEffect {effect: Effect::Block, duration: 1,
meta: Some(EffectMeta::Multiplier(50)), tick: None}], meta: Some(EffectMeta::Multiplier(50)), tick: None}],
Skill::Buff => vec![ConstructEffect {effect: Effect::Buff, duration: 2, Skill::Buff => vec![ConstructEffect {effect: Effect::Buff, duration: 2,
@ -1049,9 +1053,9 @@ impl Skill {
Skill::PurgePlus => None, Skill::PurgePlus => None,
Skill::PurgePlusPlus => None, Skill::PurgePlusPlus => None,
Skill::Banish=> Some(1), Skill::Banish |
Skill::BanishPlus => Some(1), Skill::BanishPlus |
Skill::BanishPlusPlus => Some(1), Skill::BanishPlusPlus => Some(3),
Skill::Haste=> Some(2), Skill::Haste=> Some(2),
Skill::HastePlus => Some(2), Skill::HastePlus => Some(2),
@ -1749,7 +1753,24 @@ fn purify(source: &mut Construct, target: &mut Construct, mut results: Resolutio
} }
fn banish(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { fn banish(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); results.push(Resolution::new(source, target).event(Event::Skill { skill }));
let red_damage = target.red_life().pct(skill.multiplier());
let blue_damage = target.blue_life().pct(skill.multiplier());
if red_damage > 0 {
target.deal_red_damage(skill, red_damage)
.into_iter()
.for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
}
if blue_damage > 0 {
target.deal_blue_damage(skill, blue_damage)
.into_iter()
.for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly)));
}
results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0])).stages(EventStages::PostOnly));
return results; return results;
} }

View File

@ -28,6 +28,10 @@ impl SpecValues {
self.bonuses.iter().fold(self.base, |acc, s| acc + s.get_bonus(c)) self.bonuses.iter().fold(self.base, |acc, s| acc + s.get_bonus(c))
} }
pub fn base (self) -> u64 {
self.base
}
/* /*
pub fn calc_multi (&self, c: &Colours) -> u64 { pub fn calc_multi (&self, c: &Colours) -> u64 {
self.multi * (c.red + c.green + c.blue) as u64 self.multi * (c.red + c.green + c.blue) as u64

View File

@ -148,7 +148,8 @@ fn fetch_instances(mut tx: Transaction) -> Result<Transaction, Error> {
} }
for mut instance in instances_idle(&mut tx)? { for mut instance in instances_idle(&mut tx)? {
instance_delete(&mut tx, instance.id)?; instance.finish();
instance_update(&mut tx, instance)?;
} }
Ok(tx) Ok(tx)