Merge branch 'release/1.5.1'

This commit is contained in:
ntr 2019-09-24 15:10:49 +10:00
commit 771a2aad53
33 changed files with 472 additions and 434 deletions

View File

@ -1 +1 @@
1.5.0 1.5.1

View File

@ -1,31 +1,27 @@
# WORK WORK # WORK WORK
## NOW ## NOW (Before PAX)
*PRODUCTION* *PRODUCTION*
* mobile styles
* mobile info page
* Add TOS and accept to register page
* can't reset password without knowing password =\
## SOON (Before or After PAX)
* bot game grind
* ACP * ACP
* essential * essential
* serde serialize privatise * serde serialize privatise
* mobile styles * msg pane / chatwheel
* can't reset password without knowing password =\ * audio
* treats * treats
* susbcriber gold name in instance
* client animation bpm * client animation bpm
* background colour changes depending on time of day * background colour changes depending on time of day
* susbcriber gold name in instance
* bot game grind
* msg pane
* audio
## SOON
*SERVER*
* modules
* troll life -> dmg
* prince of peace
* bonus healing / no damage
* fuck magic
* empower on ko
* rework vecs into sets * rework vecs into sets
* remove names so games/instances are copy * remove names so games/instances are copy
@ -44,22 +40,17 @@
* Industrial * Industrial
*CLIENT* *CLIENT*
fix info highlighting
theme toasts theme toasts
mobile info page
reconnect based on time delta reconnect based on time delta
consolidate game and instance consolidate game and instance
*SERVER* * elo + leaderboards
* vbox drops chances
* 50% spec, 25% colour etc
* mnml tv * mnml tv
## LATER ## LATER
* elo + leaderboards
* constants * constants
* change to ownership pattern
$$$ $$$
* Items * Items
@ -69,6 +60,13 @@ $$$
* Highlight (dota) colour * Highlight (dota) colour
* fx colours + styles * fx colours + styles
* modules
* troll life -> dmg
* prince of peace
* bonus healing / no damage
* fuck magic
* empower on ko
# Mechanics # Mechanics
* 10d chaos maths, not rock paper scissors * 10d chaos maths, not rock paper scissors
* phys is faster and chaotic * phys is faster and chaotic

View File

@ -12,7 +12,7 @@ require('./../client/assets/styles/instance.less');
require('./../client/assets/styles/vbox.less'); require('./../client/assets/styles/vbox.less');
require('./../client/assets/styles/game.less'); require('./../client/assets/styles/game.less');
require('./../client/assets/styles/styles.mobile.css'); require('./../client/assets/styles/styles.mobile.css');
require('./../client/assets/styles/instance.mobile.css'); require('./../client/assets/styles/instance.mobile.less');
// kick it off // kick it off
require('./src/acp'); require('./src/acp');

View File

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

View File

@ -13,9 +13,9 @@ rm -rf dist
npm i npm i
npm run build npm run build
echo "Building acp version $VERSION" # echo "Building acp version $VERSION"
cd $MNML_PATH/acp # cd $MNML_PATH/acp
rm -rf dist # rm -rf dist
npm i # npm i
npm run build # npm run build
mv dist/* $MNML_PATH/client/dist/ # mv dist/* $MNML_PATH/client/dist/

View File

@ -6,6 +6,7 @@ footer {
button { button {
margin: 0; margin: 0;
border-radius: 0;
border: none; border: none;
background: #222; background: #222;
font-size: 1.5em; font-size: 1.5em;

View File

@ -317,37 +317,58 @@
grid-template-rows: 1fr 0.2fr 1.5fr; grid-template-rows: 1fr 0.2fr 1.5fr;
grid-template-columns: 1fr; grid-template-columns: 1fr;
.game-construct {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content 1fr;
.left {
grid-template-rows: min-content min-content;
} }
.game .stats div { .skills {
button {
padding: 0 0.5em ;
margin: 0;
}
}
.stats div {
padding: 0; padding: 0;
} }
.game .stats .max { .stats .max {
display: none; display: none;
} }
.game .stats .value { .stats .value {
display: flex; display: flex;
} }
.game .stats svg { .stats svg {
height: 1em; height: 1em;
} }
.game .stats div { .stats div {
margin: 0 0.2em; margin: 0 0.2em;
} }
.game .effects { .effects {
font-size: 100%; font-size: 100%;
} }
#mnml .game .skills button, #mnml .game .stats { .skills button, .stats, .name {
font-size: 75%; font-size: 75%;
} }
}
.game-construct .name { .opponent {
display: none; .game-construct {
display: grid;
grid-template-columns: 1fr;
grid-template-rows: min-content 1fr;
}
}
} }
} }

View File

@ -1,3 +1,5 @@
@import 'colours.less';
@media (max-width: 800px) { @media (max-width: 800px) {
.instance { .instance {
font-size: 8pt; font-size: 8pt;
@ -7,25 +9,29 @@
grid-template-areas: grid-template-areas:
"vbox" "vbox"
"constructs"; "constructs";
.info {
display: none;
}
} }
.instance .nav-btn { display: initial; } .instance .nav-btn { display: initial; }
/* Default view */
.instance .equip { display: none; }
.instance .info { display: none; }
.instance .construct-list { display: none; }
.vbox { .vbox {
grid-area: vbox; grid-area: vbox;
margin-bottom: 0;
display: grid; display: grid;
grid-template-rows: min-content min-content min-content min-content min-content; grid-template-rows: min-content min-content min-content min-content;
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-areas: grid-template-areas:
"vbox" "vbox"
"varrow" "varrow"
"inventory" "inventory"
"carrow"
"combiner"; "combiner";
&:not(.visible) {
display: none;
}
} }
.vbox-arrow { .vbox-arrow {
@ -44,27 +50,13 @@
margin: 0; margin: 0;
} }
/* constructs toggled on */ .construct-list {
.instance.constructs-visible .vbox { display: grid;
grid-auto-rows: 1fr;
.instance-construct:not(.visible) {
display: none; display: none;
} };
.instance.constructs-visible .equip {
display: initial;
grid-area: vbox;
margin: 0;
}
.instance.constructs-visible .highlight {
display: initial;
}
.instance.constructs-visible .construct-list {
display: flex;
flex-flow: row;
align-content: flex-end;
height: 100%;
margin: 0;
} }
.vbox-inventory { .vbox-inventory {
@ -87,7 +79,6 @@
} }
.instance-construct { .instance-construct {
flex: 1;
display: grid; display: grid;
grid-template-rows: min-content min-content min-content 1fr min-content; grid-template-rows: min-content min-content min-content 1fr min-content;
grid-template-areas: grid-template-areas:
@ -106,10 +97,6 @@
transition-timing-function: ease; transition-timing-function: ease;
} }
.instance-construct .avatar {
min-height: 150px;
}
.instance-construct:first-child { .instance-construct:first-child {
border-left-width: 0; border-left-width: 0;
} }

View File

@ -1,6 +1,6 @@
@import 'colours.less'; @import 'colours.less';
html, body, #mnml { html body {
margin: 0; margin: 0;
background-color: black; background-color: black;
@ -12,7 +12,9 @@ html, body, #mnml {
-moz-user-select: none; -moz-user-select: none;
-webkit-user-select: none; -webkit-user-select: none;
-ms-user-select: none; -ms-user-select: none;
}
#mnml {
/* this is the sweet nectar to keep it full page*/ /* this is the sweet nectar to keep it full page*/
height: 100vh; height: 100vh;
max-height: 100vh; max-height: 100vh;
@ -21,7 +23,7 @@ html, body, #mnml {
/* stops inspector going skitz*/ /* stops inspector going skitz*/
overflow-x: hidden; overflow-x: hidden;
overflow-y: hidden; // overflow-y: hidden;
} }
@media (min-width: 1921px) { @media (min-width: 1921px) {

View File

@ -1,12 +1,16 @@
@media (max-width: 800px) { @media (max-width: 800px) {
#mnml { #mnml {
font-size: 14pt; font-size: 12pt;
padding: 1em 0 0 0; padding: 0;
grid-template-columns: 1fr; grid-template-columns: 1fr;
grid-template-rows: 1fr min-content; grid-template-rows: 1fr min-content;
grid-template-areas: grid-template-areas:
"main" "main"
"footer"; "footer";
height: 100vh;
max-height: initial;
min-height: initial;
} }
#mnml button { #mnml button {
@ -50,6 +54,8 @@
*/ */
main { main {
overflow-x: hidden; overflow-x: hidden;
overflow-y: initial;
max-height: 100vh;
padding: 0 0.5em; padding: 0 0.5em;
} }

View File

@ -9,7 +9,7 @@ require('./assets/styles/vbox.less');
require('./assets/styles/game.less'); require('./assets/styles/game.less');
require('./assets/styles/player.less'); require('./assets/styles/player.less');
require('./assets/styles/styles.mobile.css'); require('./assets/styles/styles.mobile.css');
require('./assets/styles/instance.mobile.css'); require('./assets/styles/instance.mobile.less');
// kick it off // kick it off
require('./src/app'); require('./src/app');

View File

@ -1,6 +1,6 @@
{ {
"name": "mnml-client", "name": "mnml-client",
"version": "1.5.0", "version": "1.5.1",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
@ -19,6 +19,7 @@
"async": "^2.6.2", "async": "^2.6.2",
"borc": "^2.0.3", "borc": "^2.0.3",
"docco": "^0.7.0", "docco": "^0.7.0",
"hammerjs": "^2.0.8",
"izitoast": "^1.4.0", "izitoast": "^1.4.0",
"keymaster": "^1.6.2", "keymaster": "^1.6.2",
"linkstate": "^1.1.1", "linkstate": "^1.1.1",

View File

@ -27,6 +27,7 @@ export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value }); export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value });
export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value }); export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value });
export const setNav = value => ({ type: 'SET_NAV', value }); export const setNav = value => ({ type: 'SET_NAV', value });
export const setNavInstance = value => ({ type: 'SET_NAV_INSTANCE', value });
export const setPing = value => ({ type: 'SET_PING', value }); export const setPing = value => ({ type: 'SET_PING', value });
export const setPlayer = value => ({ type: 'SET_PLAYER', value }); export const setPlayer = value => ({ type: 'SET_PLAYER', value });
export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value }); export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value });

View File

@ -5,7 +5,7 @@ const { connect } = require('preact-redux');
const actions = require('./../actions'); const actions = require('./../actions');
const TeamFooter = require('./team.footer'); const TeamFooter = require('./team.footer');
const ListFooter = require('./list.footer'); const PlayFooter = require('./play.footer');
const InstanceFooter = require('./instance.footer'); const InstanceFooter = require('./instance.footer');
const GameFooter = require('./game.footer'); const GameFooter = require('./game.footer');
@ -30,8 +30,8 @@ function renderHeader(args) {
if (game) return <GameFooter />; if (game) return <GameFooter />;
if (instance) return <InstanceFooter />; if (instance) return <InstanceFooter />;
if (nav === 'team') return <TeamFooter />; if (nav === 'team' || nav === 'account') return <TeamFooter />;
if (nav === 'list') return <ListFooter />; if (nav === 'play' || nav === 'shop' || !nav) return <PlayFooter />;
} }

View File

@ -9,7 +9,7 @@ const addState = connect(
ws, ws,
game, game,
account, account,
showNav, animating,
} = state; } = state;
function sendGameReady() { function sendGameReady() {
@ -24,9 +24,9 @@ const addState = connect(
return { return {
game, game,
account, account,
animating,
sendInstanceState, sendInstanceState,
sendGameReady, sendGameReady,
showNav,
}; };
}, },
@ -36,15 +36,7 @@ const addState = connect(
dispatch(actions.setInstance(null)); dispatch(actions.setInstance(null));
} }
function skip() { return { quit };
dispatch(actions.setSkip(true));
}
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
return { setShowNav, quit, skip };
} }
); );
@ -53,22 +45,13 @@ function GameFooter(props) {
const { const {
game, game,
account, account,
showNav, animating,
quit, quit,
setShowNav,
sendGameReady, sendGameReady,
sendInstanceState, sendInstanceState,
} = props; } = props;
if (!game) {
return (
<footer id="footer">
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
</footer>
);
}
const playerTeam = game.players.find(t => t.id === account.id); const playerTeam = game.players.find(t => t.id === account.id);
function quitClick() { function quitClick() {
@ -86,6 +69,7 @@ function GameFooter(props) {
const readyBtn = ( const readyBtn = (
<button <button
disabled={animating}
class={`${playerTeam.ready ? 'ready' : ''} ready-btn`} class={`${playerTeam.ready ? 'ready' : ''} ready-btn`}
onClick={sendGameReady}> onClick={sendGameReady}>
Ready Ready
@ -122,7 +106,6 @@ function GameFooter(props) {
return ( return (
<footer> <footer>
{timer} {timer}
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
{game.phase === 'Finish' && quitBtn } {game.phase === 'Finish' && quitBtn }
{game.phase === 'Skill' && readyBtn } {game.phase === 'Skill' && readyBtn }
</footer> </footer>

View File

@ -1,6 +1,9 @@
const { Component } = require('preact');
const preact = require('preact'); const preact = require('preact');
const { connect } = require('preact-redux'); const { connect } = require('preact-redux');
const Hammer = require('hammerjs');
const Vbox = require('./vbox.component'); const Vbox = require('./vbox.component');
const InfoContainer = require('./info.container'); const InfoContainer = require('./info.container');
const InstanceConstructsContainer = require('./instance.constructs'); const InstanceConstructsContainer = require('./instance.constructs');
@ -11,8 +14,14 @@ const actions = require('../actions');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { instance, nav } = state; const { instance,
return { instance, nav }; nav,
navInstance,
} = state;
return { instance,
nav,
navInstance,
};
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
@ -20,6 +29,11 @@ const addState = connect(
return dispatch(actions.setInfo(c)); return dispatch(actions.setInfo(c));
} }
function setNavInstance(c) {
return dispatch(actions.setNavInstance(c));
}
function clearItems() { function clearItems() {
dispatch(actions.setCombiner([])); dispatch(actions.setCombiner([]));
dispatch(actions.setReclaiming(false)); dispatch(actions.setReclaiming(false));
@ -33,17 +47,17 @@ const addState = connect(
return { return {
setInfo, setInfo,
clearItems, clearItems,
setNavInstance,
}; };
} }
); );
function Instance(args) { class Instance extends Component {
render(args) {
const { const {
instance, instance,
setInfo, setInfo,
clearItems, clearItems,
nav,
} = args; } = args;
if (!instance) return false; if (!instance) return false;
@ -57,9 +71,12 @@ function Instance(args) {
clearItems(); clearItems();
} }
const instanceClasses = `instance ${nav === 'constructs' ? 'constructs-visible' : ''}`; function onTouchMove(e) {
e.preventDefault();
}
return ( return (
<main class={instanceClasses} onClick={instanceClick} onMouseOver={() => setInfo(null)} > <main id="instance" class='instance' onClick={instanceClick} onMouseOver={() => setInfo(null)} onTouchMove={onTouchMove}>
<Vbox /> <Vbox />
<InfoContainer /> <InfoContainer />
<InstanceConstructsContainer /> <InstanceConstructsContainer />
@ -67,4 +84,35 @@ function Instance(args) {
); );
} }
componentDidMount() {
this.bindSwipes();
}
bindSwipes() {
const instance = document.getElementById('instance');
if (!instance) return setTimeout(this.bindSwipes, 50);
if (this.h) this.h.destroy();
this.h = new Hammer(instance);
const display = ['vbox', 'c0', 'c1', 'c2'];
this.h.on('swiperight', () => {
const {
navInstance,
setNavInstance,
} = this.props;
setNavInstance(navInstance === 0 ? 3 : navInstance - 1);
});
this.h.on('swipeleft', () => {
const {
navInstance,
setNavInstance,
} = this.props;
setNavInstance((navInstance + 1) % 4);
});
return true;
}
}
module.exports = addState(Instance); module.exports = addState(Instance);

View File

@ -9,7 +9,16 @@ const actions = require('../actions');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { ws, instance, player, account, itemInfo, itemEquip, activeConstruct } = state; const {
ws,
instance,
player,
account,
itemInfo,
itemEquip,
activeConstruct,
navInstance,
} = state;
function sendVboxApply(constructId, i) { function sendVboxApply(constructId, i) {
return ws.sendVboxApply(instance.id, constructId, i); return ws.sendVboxApply(instance.id, constructId, i);
@ -26,6 +35,7 @@ const addState = connect(
sendVboxApply, sendVboxApply,
itemInfo, itemInfo,
itemEquip, itemEquip,
navInstance,
activeConstruct, activeConstruct,
sendUnequip, sendUnequip,
}; };
@ -63,7 +73,6 @@ const addState = connect(
function Construct(props) { function Construct(props) {
const { const {
activeConstruct,
itemEquip, itemEquip,
construct, construct,
player, player,
@ -74,6 +83,7 @@ function Construct(props) {
itemInfo, itemInfo,
setInfo, setInfo,
sendUnequip, sendUnequip,
mobileVisible,
} = props; } = props;
function onClick(e) { function onClick(e) {
@ -191,8 +201,10 @@ function Construct(props) {
</div>; </div>;
}); });
const classes = `instance-construct ${mobileVisible ? 'visible' : ''}`;
return ( return (
<div key={construct.id} class="instance-construct" onClick={onClick} > <div key={construct.id} class={classes} onClick={onClick} >
<ConstructAvatar construct={construct} /> <ConstructAvatar construct={construct} />
<h2 class="name" >{construct.name}</h2> <h2 class="name" >{construct.name}</h2>
<div class="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} > <div class="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} >
@ -224,6 +236,7 @@ function InstanceConstructs(props) {
setItemUnequip, setItemUnequip,
setItemEquip, setItemEquip,
sendUnequip, sendUnequip,
navInstance,
} = props; } = props;
if (!player) return false; if (!player) return false;
@ -242,6 +255,7 @@ function InstanceConstructs(props) {
itemInfo, itemInfo,
setVboxHighlight, setVboxHighlight,
sendUnequip, sendUnequip,
mobileVisible: navInstance === i + 1,
})); }));
const classes = `construct-list`; const classes = `construct-list`;

View File

@ -5,32 +5,22 @@ const actions = require('../actions');
const addState = connect( const addState = connect(
function receiveState(state) { function receiveState(state) {
const { ws, instance, player, nav, showNav } = state; const { ws, instance, player, nav } = state;
function sendInstanceReady() { function sendInstanceReady() {
return ws.sendInstanceReady(instance.id); return ws.sendInstanceReady(instance.id);
} }
return { player, instance, sendInstanceReady, nav, showNav }; return { player, instance, sendInstanceReady, nav };
}, },
function receiveDispatch(dispatch) { function receiveDispatch(dispatch) {
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
function setInfo(c) {
return dispatch(actions.setInfo(c));
}
function setNav(v) { function setNav(v) {
return dispatch(actions.setNav(v)); return dispatch(actions.setNav(v));
} }
return { return {
setInfo,
setNav, setNav,
setShowNav,
}; };
} }
); );
@ -39,30 +29,11 @@ function Instance(args) {
const { const {
instance, instance,
player, player,
nav,
showNav,
setInfo,
setNav,
setShowNav,
sendInstanceReady, sendInstanceReady,
} = args; } = args;
if (!instance || !player) { const rdyClasses = `ready-btn ready`;
return (
<footer id="footer">
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
</footer>
);
}
function hoverInfo(e, info) {
e.stopPropagation();
return setInfo(info);
}
const rdyClasses = `${player.ready ? 'ready ready-btn' : 'ready-btn'}`;
const readyInfo = instance.phase === 'Lobby' const readyInfo = instance.phase === 'Lobby'
? 'lobbyReady' ? 'lobbyReady'
: 'ready'; : 'ready';
@ -70,27 +41,11 @@ function Instance(args) {
const readyBtn = ( const readyBtn = (
<button <button
class={rdyClasses} class={rdyClasses}
onMouseOver={e => hoverInfo(e, readyInfo)}
onClick={() => sendInstanceReady()}> onClick={() => sendInstanceReady()}>
Ready Ready
</button> </button>
); );
function navClick() {
if (nav === 'vbox') return setNav('constructs');
return setNav('vbox');
}
const navBtn = instance.phase === 'InProgress'
? (
<button
id="instance-nav"
onClick={navClick}>
{nav === 'vbox' ? 'Constructs' : 'Vbox'}
</button>
)
: null;
const zero = Date.parse(instance.phase_start); const zero = Date.parse(instance.phase_start);
const now = Date.now(); const now = Date.now();
const end = Date.parse(instance.phase_end); const end = Date.parse(instance.phase_end);
@ -118,8 +73,6 @@ function Instance(args) {
return ( return (
<footer id="footer"> <footer id="footer">
{timer} {timer}
<button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
{navBtn}
{readyBtn} {readyBtn}
</footer> </footer>
); );

View File

@ -1,48 +0,0 @@
const { connect } = require('preact-redux');
const preact = require('preact');
const actions = require('./../actions');
const addState = connect(
function receiveState(state) {
const { showNav } = state;
return { showNav };
},
function receiveDispatch(dispatch) {
function navToTeam() {
return dispatch(actions.setNav('team'));
}
function setShowNav(v) {
return dispatch(actions.setShowNav(v));
}
return {
navToTeam,
setShowNav,
};
}
);
function ListFooter(args) {
return false;
// const {
// showNav,
// navToTeam,
// setShowNav,
// } = args;
// return (
// <footer>
// <button id="nav-btn" onClick={() => setShowNav(!showNav)} ></button>
// <button
// onClick={() => navToTeam()}>
// Back
// </button>
// </footer>
// );
}
module.exports = addState(ListFooter);

View File

@ -0,0 +1,139 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const { errorToast, infoToast } = require('../utils');
const AccountBox = require('./account.box');
const addState = connect(
function receiveState(state) {
const {
ws,
instances,
invite,
} = state;
function sendInstanceState(id) {
ws.sendInstanceState(id);
}
function sendInstancePractice() {
ws.sendInstancePractice();
}
function sendInstanceQueue() {
ws.sendInstanceQueue();
}
function sendInstanceInvite() {
ws.sendInstanceInvite();
}
return {
instances,
invite,
sendInstanceState,
sendInstanceQueue,
sendInstancePractice,
sendInstanceInvite,
};
}
);
function JoinButtons(args) {
const {
instances,
invite,
sendInstanceState,
sendInstanceQueue,
sendInstancePractice,
sendInstanceInvite,
} = args;
const discordBtn = (
<button
class='discord-btn'
onClick={() => window.open('https://discord.gg/YJJgurM') }>
&nbsp;
</button>
);
if (instances.length) {
return (
<footer id="footer">
<div class="timer-container"></div>
<button
class='pvp ready full'
onClick={() => sendInstanceState(instances[0].id)}
type="submit">
Rejoin
</button>
</footer>
);
}
const inviteBtn = () => {
if (!invite) {
return (
<button
class='pvp ready'
onClick={() => sendInstanceInvite()}
type="submit">
Invite
</button>
);
}
function copyClick(e) {
const link = `${document.location.origin}#join=${invite}`;
const textArea = document.createElement('textarea', { id: '#clipboard' });
textArea.value = link;
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
try {
document.execCommand('copy');
infoToast('Invite link copied.');
} catch (err) {
console.error('link copy error', err);
errorToast('Invite link copy error.');
}
document.body.removeChild(textArea);
return true;
}
return (
<button
class='pvp ready enabled'
onClick={copyClick}
type="submit">
Copy Link
</button>
);
};
return (
<footer id="footer">
<div class="timer-container"></div>
<button
class='practice'
onClick={() => sendInstancePractice()}
type="submit">
Learn
</button>
{inviteBtn()}
<button
class='pvp ready'
onClick={() => sendInstanceQueue()}
type="submit">
PVP
</button>
</footer>
);
}
module.exports = addState(JoinButtons);

View File

@ -17,6 +17,7 @@ const addState = connect(
vboxSelected, vboxSelected,
itemInfo, itemInfo,
itemUnequip, itemUnequip,
navInstance,
} = state; } = state;
function sendVboxDiscard() { function sendVboxDiscard() {
@ -51,7 +52,8 @@ const addState = connect(
vboxSelected, vboxSelected,
itemInfo, itemInfo,
itemUnequip, itemUnequip,
sendItemUnequip sendItemUnequip,
navInstance,
}; };
}, },
@ -90,6 +92,7 @@ const addState = connect(
function Vbox(args) { function Vbox(args) {
const { const {
combiner, combiner,
navInstance,
// instance, // instance,
itemInfo, itemInfo,
player, player,
@ -348,7 +351,7 @@ function Vbox(args) {
return setInfo(info); return setInfo(info);
} }
const classes = 'vbox'; const classes = `vbox ${navInstance === 0 ? 'visible' : ''}`;
return ( return (
<div class={classes}> <div class={classes}>
{vboxElement()} {vboxElement()}

View File

@ -1,69 +0,0 @@
// eslint-disable-next-line
const preact = require('preact');
const { Component } = require('preact')
const { connect } = require('preact-redux');
const linkState = require('linkstate').default;
const { postData, errorToast, infoToast } = require('../utils');
const addState = connect(
(state) => {
const {
ws
} = state;
function submitRegister(name, password, code) {
postData('/account/register', { name, password, code })
.then(res => res.json())
.then(data => {
if (data.error) return errorToast(data.error);
infoToast(data.message);
ws.connect();
})
.catch(error => errorToast(error));
}
return {
submitRegister,
}
},
);
function Register(args) {
const {
submitRegister,
navRegister,
} = args;
return (
<div class="login">
<p>
mnml is made deep in the southern hemisphere by ntr & mashy.
</p>
<p>
if you like this game please support the development by buying credits or subscribing.
</p>
<p>
this site has no trackers or ads.
</p>
<p>
you can reach us for feedback and support with the discord and email buttons below.
</p>
<p>
the access code grep842 is currently active.
</p>
<button
class="login-btn"
onClick={() => document.location.assign('https://discord.gg/YJJgurM')}>
Discord
</button>
<button
class="login-btn"
onClick={() => navRegister()}>
Register
</button>
</div>
);
}
module.exports = addState(Register);

View File

@ -19,7 +19,7 @@ function Welcome() {
}; };
return ( return (
<main class="menu"> <main class="menu welcome">
<header> <header>
<div class="options"> <div class="options">
<button <button

View File

@ -40,6 +40,7 @@ module.exports = {
itemUnequip: createReducer([], 'SET_ITEM_UNEQUIP'), itemUnequip: createReducer([], 'SET_ITEM_UNEQUIP'),
mtxActive: createReducer(null, 'SET_MTX_ACTIVE'), mtxActive: createReducer(null, 'SET_MTX_ACTIVE'),
nav: createReducer(null, 'SET_NAV'), nav: createReducer(null, 'SET_NAV'),
navInstance: createReducer(0, 'SET_NAV_INSTANCE'),
showNav: createReducer(null, 'SET_SHOW_NAV'), showNav: createReducer(null, 'SET_SHOW_NAV'),
ping: createReducer(null, 'SET_PING'), ping: createReducer(null, 'SET_PING'),
player: createReducer(null, 'SET_PLAYER'), player: createReducer(null, 'SET_PLAYER'),

View File

@ -2,6 +2,10 @@ const uuidv4 = require('uuid/v4');
// give everybody the shapes mtx // give everybody the shapes mtx
exports.up = async knex => { exports.up = async knex => {
await knex.raw(`
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
`);
await knex.raw(` await knex.raw(`
INSERT INTO mtx (id, account, variant) INSERT INTO mtx (id, account, variant)
SELECT uuid_generate_v4() as id, id as account, 'Shapes' SELECT uuid_generate_v4() as id, id as account, 'Shapes'

View File

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

View File

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

View File

@ -348,7 +348,7 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
.insert(tx)?; .insert(tx)?;
} }
img::shapes_write(img)?; // img::shapes_write(img)?;
info!("registration account={:?}", name); info!("registration account={:?}", name);

View File

@ -145,7 +145,7 @@ impl ConstructStat {
// self.recalculate(specs) // self.recalculate(specs)
// } // }
pub fn recalculate(&mut self, specs: &Vec<Spec>, construct_colours: &Colours, player_colours: &Colours) -> &mut ConstructStat { pub fn recalculate(&mut self, specs: &Vec<Spec>, player_colours: &Colours) -> &mut ConstructStat {
let specs = specs let specs = specs
.iter() .iter()
.filter(|s| s.affects().contains(&self.stat)) .filter(|s| s.affects().contains(&self.stat))
@ -154,7 +154,7 @@ impl ConstructStat {
// applied with fold because it can be zeroed or multiplied // applied with fold because it can be zeroed or multiplied
// but still needs access to the base amount // but still needs access to the base amount
let value = specs.iter().fold(self.base, |acc, s| s.apply(acc, self.base, construct_colours, player_colours)); let value = specs.iter().fold(self.base, |acc, s| s.apply(acc, self.base, player_colours));
self.value = value; self.value = value;
self.max = value; self.max = value;
@ -223,7 +223,7 @@ impl Construct {
red_life: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::RedLife }, red_life: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::RedLife },
blue_power: ConstructStat { base: 320, value: 320, max: 320, stat: Stat::BluePower }, blue_power: ConstructStat { base: 320, value: 320, max: 320, stat: Stat::BluePower },
blue_life: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::BlueLife }, blue_life: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::BlueLife },
green_power: ConstructStat { base: 320, value: 300, max: 300, stat: Stat::GreenPower }, green_power: ConstructStat { base: 300, value: 300, max: 300, stat: Stat::GreenPower },
green_life: ConstructStat { base: 950, value: 950, max: 950, stat: Stat::GreenLife }, green_life: ConstructStat { base: 950, value: 950, max: 950, stat: Stat::GreenLife },
speed: ConstructStat { base: 100, value: 100, max: 100, stat: Stat::Speed }, speed: ConstructStat { base: 100, value: 100, max: 100, stat: Stat::Speed },
// evasion: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::Evasion }, // evasion: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::Evasion },
@ -325,14 +325,14 @@ impl Construct {
pub fn apply_modifiers(&mut self, player_colours: &Colours) -> &mut Construct { pub fn apply_modifiers(&mut self, player_colours: &Colours) -> &mut Construct {
self.specs.sort_unstable(); self.specs.sort_unstable();
self.red_power.recalculate(&self.specs, &self.colours, player_colours); self.red_power.recalculate(&self.specs, player_colours);
self.red_life.recalculate(&self.specs, &self.colours, player_colours); self.red_life.recalculate(&self.specs, player_colours);
self.blue_power.recalculate(&self.specs, &self.colours, player_colours); self.blue_power.recalculate(&self.specs, player_colours);
self.blue_life.recalculate(&self.specs, &self.colours, player_colours); self.blue_life.recalculate(&self.specs, player_colours);
// self.evasion.recalculate(&self.specs, &self.colours, player_colours); // self.evasion.recalculate(&self.specs, &self.colours, player_colours);
self.speed.recalculate(&self.specs, &self.colours, player_colours); self.speed.recalculate(&self.specs, player_colours);
self.green_power.recalculate(&self.specs, &self.colours, player_colours); self.green_power.recalculate(&self.specs, player_colours);
self.green_life.recalculate(&self.specs, &self.colours, player_colours); self.green_life.recalculate(&self.specs, player_colours);
self self
} }

View File

@ -263,7 +263,7 @@ impl Events {
None => false, None => false,
}) })
.map(|(_id, c)| PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() }) .map(|(_id, c)| PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() })
.ok_or(format_err!("invite not found code={:?}", code))?; .ok_or(format_err!("invite expired code={:?}", code))?;
let join = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() }; let join = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() };

View File

@ -737,8 +737,8 @@ impl Item {
Item::Electrify| Item::Electrify|
Item::ElectrifyPlus | Item::ElectrifyPlus |
Item::ElectrifyPlusPlus => format!( Item::ElectrifyPlusPlus => format!(
"Self targetting defensive for {:?}T. Applies Electric to attackers dealing BlueDamage {:?}% \ "Applies electrify for {:?}T. If a construct with electrify takes damage they will apply an electrocute debuff to the caster dealing {:?}% \
BluePower per turn for {:?}T.", BluePower as BlueDamage per turn for {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
self.into_skill().unwrap().effect()[0].get_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(),
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()),
@ -790,20 +790,20 @@ impl Item {
Item::Invert| Item::Invert|
Item::InvertPlus | Item::InvertPlus |
Item::InvertPlusPlus => format!( Item::InvertPlusPlus => format!(
"Reverse healing into damage and damage into healing. "Reverse healing into damage and damage into healing. Any excess red or blue damage is converted into shield recharge. Lasts {:?}T.",
Any excess red or blue damage is converted into shield recharge."), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Counter| Item::Counter|
Item::CounterPlus | Item::CounterPlus |
Item::CounterPlusPlus => format!("Self targetting skill. Recharges RedLife for {:?}% RedPower and blocks red skills for {:?}T. Item::CounterPlusPlus => format!("Applies counter and block {:?}T. Block reduces incoming red damage by {:?}%.
If a red skill is parried the construct will riposte the source dealing {:?}% RedPower as red damage.", Red damage taken during counter will trigger a counter attack dealing {:?}% RedPower as red damage.",
self.into_skill().unwrap().multiplier(),
self.into_skill().unwrap().effect()[0].get_duration(), self.into_skill().unwrap().effect()[0].get_duration(),
100 - self.into_skill().unwrap().effect()[1].get_multiplier(),
self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier()), self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier()),
Item::Purge| Item::Purge|
Item::PurgePlus | Item::PurgePlus |
Item::PurgePlusPlus => format!("Remove buffs from target construct. Applies purge which disables target green skills for {:?}T.", Item::PurgePlusPlus => format!("Remove buffs from target construct. Applies purge disabling target green skills for {:?}T.",
self.into_skill().unwrap().effect()[0].get_duration()), self.into_skill().unwrap().effect()[0].get_duration()),
Item::Purify| Item::Purify|

View File

@ -1,7 +1,7 @@
use rand::prelude::*; use rand::prelude::*;
use rand::{thread_rng}; use rand::{thread_rng};
const FIRSTS: [&'static str; 50] = [ const FIRSTS: [&'static str; 51] = [
"artificial", "artificial",
"ambient", "ambient",
"borean", "borean",
@ -17,6 +17,7 @@ const FIRSTS: [&'static str; 50] = [
"emotive", "emotive",
"emotionless", "emotionless",
"elliptical", "elliptical",
"extrasolar",
"fierce", "fierce",
"fossilised", "fossilised",
"frozen", "frozen",
@ -54,9 +55,10 @@ const FIRSTS: [&'static str; 50] = [
"weary", "weary",
]; ];
const LASTS: [&'static str; 55] = [ const LASTS: [&'static str; 56] = [
"artifact", "artifact",
"assembly", "assembly",
"alloy",
"carbon", "carbon",
"console", "console",
"construct", "construct",
@ -68,7 +70,7 @@ const LASTS: [&'static str; 55] = [
"detector", "detector",
"energy", "energy",
"entropy", "entropy",
"exomorph", "exoplanet",
"foilage", "foilage",
"forest", "forest",
"form", "form",

View File

@ -19,7 +19,6 @@ impl SpecBonus {
#[derive(Debug,Clone,Serialize,Deserialize)] #[derive(Debug,Clone,Serialize,Deserialize)]
pub struct SpecValues { pub struct SpecValues {
pub base: u64, pub base: u64,
pub multi: u64,
pub bonuses: Vec<SpecBonus>, pub bonuses: Vec<SpecBonus>,
} }
@ -31,12 +30,6 @@ impl SpecValues {
pub fn base (self) -> u64 { pub fn base (self) -> u64 {
self.base self.base
} }
/*
pub fn calc_multi (&self, c: &Colours) -> u64 {
self.multi * (c.red + c.green + c.blue) as u64
}
*/
} }
@ -149,8 +142,6 @@ impl Spec {
Spec::SpeedGBPlusPlus => vec![Stat::Speed], Spec::SpeedGBPlusPlus => vec![Stat::Speed],
Spec::SpeedRBPlusPlus => vec![Stat::Speed], Spec::SpeedRBPlusPlus => vec![Stat::Speed],
Spec::Life => vec![Stat::GreenLife], Spec::Life => vec![Stat::GreenLife],
Spec::LifeRR => vec![Stat::RedLife], Spec::LifeRR => vec![Stat::RedLife],
Spec::LifeBB => vec![Stat::BlueLife], Spec::LifeBB => vec![Stat::BlueLife],
@ -176,12 +167,12 @@ impl Spec {
pub fn values(&self) -> SpecValues { pub fn values(&self) -> SpecValues {
match *self { match *self {
Spec::Power => SpecValues { Spec::Power => SpecValues {
multi: 0, base: 10, base: 10,
bonuses: vec![] bonuses: vec![]
}, },
Spec::PowerRR=> SpecValues { Spec::PowerRR=> SpecValues {
multi: 10, base: 25, base: 25,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 25 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 25 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 25 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 25 },
@ -190,7 +181,7 @@ impl Spec {
}, },
Spec::PowerGG=> SpecValues { Spec::PowerGG=> SpecValues {
multi: 10, base: 25, base: 25,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 25 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 25 },
@ -199,7 +190,7 @@ impl Spec {
}, },
Spec::PowerBB=> SpecValues { Spec::PowerBB=> SpecValues {
multi: 10, base: 25, base: 25,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 25 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 25 },
@ -208,7 +199,7 @@ impl Spec {
}, },
Spec::PowerRG=> SpecValues { Spec::PowerRG=> SpecValues {
multi: 5, base: 15, base: 15,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 15 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 15 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 15 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 15 },
@ -217,7 +208,7 @@ impl Spec {
}, },
Spec::PowerGB=> SpecValues { Spec::PowerGB=> SpecValues {
multi: 5, base: 15, base: 15,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 15 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 15 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 15 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 15 },
@ -226,7 +217,7 @@ impl Spec {
}, },
Spec::PowerRB=> SpecValues { Spec::PowerRB=> SpecValues {
multi: 5, base: 15, base: 15,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 15 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 15 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 15 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 15 },
@ -235,7 +226,7 @@ impl Spec {
}, },
Spec::PowerRRPlus => SpecValues { Spec::PowerRRPlus => SpecValues {
multi: 10, base: 40, base: 40,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 40 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 40 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 40 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 40 },
@ -244,7 +235,7 @@ impl Spec {
}, },
Spec::PowerGGPlus => SpecValues { Spec::PowerGGPlus => SpecValues {
multi: 10, base: 40, base: 40,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 40 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 40 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 40 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 40 },
@ -253,7 +244,7 @@ impl Spec {
}, },
Spec::PowerBBPlus => SpecValues { Spec::PowerBBPlus => SpecValues {
multi: 10, base: 40, base: 40,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 40 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 40 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 40 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 40 },
@ -262,7 +253,7 @@ impl Spec {
}, },
Spec::PowerRGPlus => SpecValues { Spec::PowerRGPlus => SpecValues {
multi: 7, base: 25, base: 25,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 25 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 25 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 25 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 25 },
@ -271,7 +262,7 @@ impl Spec {
}, },
Spec::PowerGBPlus => SpecValues { Spec::PowerGBPlus => SpecValues {
multi: 7, base: 25, base: 25,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 25 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 25 },
@ -280,7 +271,7 @@ impl Spec {
}, },
Spec::PowerRBPlus => SpecValues { Spec::PowerRBPlus => SpecValues {
multi: 7, base: 25, base: 25,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 25 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 25 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 25 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 25 },
@ -288,7 +279,7 @@ impl Spec {
], ],
}, },
Spec::PowerRRPlusPlus => SpecValues { Spec::PowerRRPlusPlus => SpecValues {
multi: 20, base: 60, base: 60,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 60 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 60 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 60 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 60 },
@ -297,7 +288,7 @@ impl Spec {
}, },
Spec::PowerGGPlusPlus => SpecValues { Spec::PowerGGPlusPlus => SpecValues {
multi: 20, base: 60, base: 60,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 60 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 60 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 60 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 60 },
@ -306,7 +297,7 @@ impl Spec {
}, },
Spec::PowerBBPlusPlus => SpecValues { Spec::PowerBBPlusPlus => SpecValues {
multi: 20, base: 60, base: 60,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 60 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 60 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 60 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 60 },
@ -315,7 +306,7 @@ impl Spec {
}, },
Spec::PowerRGPlusPlus => SpecValues { Spec::PowerRGPlusPlus => SpecValues {
multi: 20, base: 40, base: 40,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 40 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 40 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 40 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 40 },
@ -324,30 +315,30 @@ impl Spec {
}, },
Spec::PowerGBPlusPlus => SpecValues { Spec::PowerGBPlusPlus => SpecValues {
multi: 20, base: 40, base: 40,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 40 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 25 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 40 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 10 }, bonus: 25 } SpecBonus { req: Colours { red: 0, green: 10, blue: 10 }, bonus: 40 }
], ],
}, },
Spec::PowerRBPlusPlus => SpecValues { Spec::PowerRBPlusPlus => SpecValues {
multi: 20, base: 40, base: 40,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 25 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 40 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 25 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 40 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 10 }, bonus: 25 } SpecBonus { req: Colours { red: 10, green: 0, blue: 10 }, bonus: 40 }
], ],
}, },
Spec::Speed => SpecValues { Spec::Speed => SpecValues {
multi: 0, base: 40, base: 40,
bonuses: vec![] bonuses: vec![]
}, },
Spec::SpeedRR=> SpecValues { Spec::SpeedRR=> SpecValues {
multi: 20, base: 80, base: 80,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 80 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 80 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 80 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 80 },
@ -356,7 +347,7 @@ impl Spec {
}, },
Spec::SpeedGG=> SpecValues { Spec::SpeedGG=> SpecValues {
multi: 20, base: 80, base: 80,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 80 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 80 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 80 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 80 },
@ -365,7 +356,7 @@ impl Spec {
}, },
Spec::SpeedBB=> SpecValues { Spec::SpeedBB=> SpecValues {
multi: 20, base: 80, base: 80,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 80 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 80 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 80 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 80 },
@ -374,7 +365,7 @@ impl Spec {
}, },
Spec::SpeedRG=> SpecValues { Spec::SpeedRG=> SpecValues {
multi: 15, base: 60, base: 60,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 60 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 60 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 60 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 60 },
@ -383,7 +374,7 @@ impl Spec {
}, },
Spec::SpeedGB=> SpecValues { Spec::SpeedGB=> SpecValues {
multi: 15, base: 60, base: 60,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 60 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 60 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 60 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 60 },
@ -392,7 +383,7 @@ impl Spec {
}, },
Spec::SpeedRB=> SpecValues { Spec::SpeedRB=> SpecValues {
multi: 15, base: 60, base: 60,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 60 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 60 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 60 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 60 },
@ -401,7 +392,7 @@ impl Spec {
}, },
Spec::SpeedRRPlus => SpecValues { Spec::SpeedRRPlus => SpecValues {
multi: 20, base: 120, base: 120,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 120 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 120 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 120 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 120 },
@ -410,7 +401,7 @@ impl Spec {
}, },
Spec::SpeedGGPlus => SpecValues { Spec::SpeedGGPlus => SpecValues {
multi: 20, base: 120, base: 120,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 120 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 120 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 120 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 120 },
@ -419,7 +410,7 @@ impl Spec {
}, },
Spec::SpeedBBPlus => SpecValues { Spec::SpeedBBPlus => SpecValues {
multi: 20, base: 120, base: 120,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 120 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 120 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 120 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 120 },
@ -428,7 +419,7 @@ impl Spec {
}, },
Spec::SpeedRGPlus => SpecValues { Spec::SpeedRGPlus => SpecValues {
multi: 15, base: 80, base: 80,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 80 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 80 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 80 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 80 },
@ -437,7 +428,7 @@ impl Spec {
}, },
Spec::SpeedGBPlus => SpecValues { Spec::SpeedGBPlus => SpecValues {
multi: 15, base: 80, base: 80,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 80 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 80 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 80 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 80 },
@ -446,7 +437,7 @@ impl Spec {
}, },
Spec::SpeedRBPlus => SpecValues { Spec::SpeedRBPlus => SpecValues {
multi: 15, base: 80, base: 80,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 80 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 80 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 80 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 80 },
@ -455,7 +446,7 @@ impl Spec {
}, },
Spec::SpeedRRPlusPlus => SpecValues { Spec::SpeedRRPlusPlus => SpecValues {
multi: 20, base: 160, base: 160,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 160 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 160 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 160 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 160 },
@ -464,7 +455,7 @@ impl Spec {
}, },
Spec::SpeedGGPlusPlus => SpecValues { Spec::SpeedGGPlusPlus => SpecValues {
multi: 20, base: 160, base: 160,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 160 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 160 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 160 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 160 },
@ -473,7 +464,7 @@ impl Spec {
}, },
Spec::SpeedBBPlusPlus => SpecValues { Spec::SpeedBBPlusPlus => SpecValues {
multi: 20, base: 160, base: 160,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 160 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 160 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 160 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 160 },
@ -482,7 +473,7 @@ impl Spec {
}, },
Spec::SpeedRGPlusPlus => SpecValues { Spec::SpeedRGPlusPlus => SpecValues {
multi: 15, base: 120, base: 120,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 120 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 120 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 120 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 120 },
@ -491,7 +482,7 @@ impl Spec {
}, },
Spec::SpeedGBPlusPlus => SpecValues { Spec::SpeedGBPlusPlus => SpecValues {
multi: 15, base: 120, base: 120,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 120 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 120 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 120 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 120 },
@ -500,7 +491,7 @@ impl Spec {
}, },
Spec::SpeedRBPlusPlus => SpecValues { Spec::SpeedRBPlusPlus => SpecValues {
multi: 15, base: 120, base: 120,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 120 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 120 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 120 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 120 },
@ -509,11 +500,11 @@ impl Spec {
}, },
Spec::Life => SpecValues { Spec::Life => SpecValues {
multi: 0, base: 100, base: 100,
bonuses: vec![]}, bonuses: vec![]},
Spec::LifeRR=> SpecValues { Spec::LifeRR=> SpecValues {
multi: 50, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 100 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 100 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 100 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 100 },
@ -522,7 +513,7 @@ impl Spec {
}, },
Spec::LifeGG=> SpecValues { Spec::LifeGG=> SpecValues {
multi: 50, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 100 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 100 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 100 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 100 },
@ -531,7 +522,7 @@ impl Spec {
}, },
Spec::LifeBB=> SpecValues { Spec::LifeBB=> SpecValues {
multi: 50, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 100 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 100 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 100 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 100 },
@ -540,7 +531,7 @@ impl Spec {
}, },
Spec::LifeRG=> SpecValues { Spec::LifeRG=> SpecValues {
multi: 40, base: 150, base: 150,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 75 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 75 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 75 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 75 },
@ -549,7 +540,7 @@ impl Spec {
}, },
Spec::LifeGB=> SpecValues { Spec::LifeGB=> SpecValues {
multi: 40, base: 150, base: 150,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 75 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 75 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 75 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 75 },
@ -558,7 +549,7 @@ impl Spec {
}, },
Spec::LifeRB=> SpecValues { Spec::LifeRB=> SpecValues {
multi: 40, base: 150, base: 150,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 75 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 75 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 75 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 75 },
@ -567,7 +558,7 @@ impl Spec {
}, },
Spec::LifeRRPlus => SpecValues { Spec::LifeRRPlus => SpecValues {
multi: 50, base: 300, base: 300,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 150 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 150 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 150 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 150 },
@ -576,7 +567,7 @@ impl Spec {
}, },
Spec::LifeGGPlus => SpecValues { Spec::LifeGGPlus => SpecValues {
multi: 50, base: 300, base: 300,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 150 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 150 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 150 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 150 },
@ -585,7 +576,7 @@ impl Spec {
}, },
Spec::LifeBBPlus => SpecValues { Spec::LifeBBPlus => SpecValues {
multi: 50, base: 300, base: 300,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 150 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 150 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 150 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 150 },
@ -594,7 +585,7 @@ impl Spec {
}, },
Spec::LifeRGPlus => SpecValues { Spec::LifeRGPlus => SpecValues {
multi: 40, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 100 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 100 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 100 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 100 },
@ -603,7 +594,7 @@ impl Spec {
}, },
Spec::LifeGBPlus => SpecValues { Spec::LifeGBPlus => SpecValues {
multi: 40, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 100 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 100 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 100 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 100 },
@ -612,7 +603,7 @@ impl Spec {
}, },
Spec::LifeRBPlus => SpecValues { Spec::LifeRBPlus => SpecValues {
multi: 40, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 100 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 100 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 100 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 100 },
@ -620,7 +611,7 @@ impl Spec {
], ],
}, },
Spec::LifeRRPlusPlus => SpecValues { Spec::LifeRRPlusPlus => SpecValues {
multi: 40, base: 300, base: 300,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 300 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 300 },
SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 300 }, SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 300 },
@ -629,7 +620,7 @@ impl Spec {
}, },
Spec::LifeGGPlusPlus => SpecValues { Spec::LifeGGPlusPlus => SpecValues {
multi: 40, base: 300, base: 300,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 300 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 300 },
SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 300 }, SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 300 },
@ -638,7 +629,7 @@ impl Spec {
}, },
Spec::LifeBBPlusPlus => SpecValues { Spec::LifeBBPlusPlus => SpecValues {
multi: 40, base: 300, base: 300,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 300 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 300 },
SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 300 }, SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 300 },
@ -647,7 +638,7 @@ impl Spec {
}, },
Spec::LifeRGPlusPlus => SpecValues { Spec::LifeRGPlusPlus => SpecValues {
multi: 40, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 200 }, SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 200 },
SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 200 }, SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 200 },
@ -656,7 +647,7 @@ impl Spec {
}, },
Spec::LifeGBPlusPlus => SpecValues { Spec::LifeGBPlusPlus => SpecValues {
multi: 40, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 200 }, SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 200 },
SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 200 }, SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 200 },
@ -665,7 +656,7 @@ impl Spec {
}, },
Spec::LifeRBPlusPlus => SpecValues { Spec::LifeRBPlusPlus => SpecValues {
multi: 40, base: 200, base: 200,
bonuses: vec![ bonuses: vec![
SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 200 }, SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 200 },
SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 200 }, SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 200 },
@ -675,7 +666,7 @@ impl Spec {
} }
} }
pub fn apply(&self, modified: u64, base: u64, construct_colours: &Colours, player_colours: &Colours) -> u64 { pub fn apply(&self, modified: u64, base: u64, player_colours: &Colours) -> u64 {
match *self { match *self {
// Percentage multipliers based on base value // Percentage multipliers based on base value
Spec::Power | Spec::Power |