diff --git a/WORKLOG.md b/WORKLOG.md index b779ffc4..a190ad2b 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -33,6 +33,9 @@ ## NOW *CLIENT* +* fix mobile menu + * make fullscreen + * disappear on touch *SERVER* diff --git a/client/assets/styles/instance.css b/client/assets/styles/instance.css index b746cf16..637d96d3 100644 --- a/client/assets/styles/instance.css +++ b/client/assets/styles/instance.css @@ -289,14 +289,8 @@ margin: 0 1em; } -.equip-icon { - height: 2em; - stroke-width: 5px; - fill: none; -} - -.construct-list .stat-icon { - width: 100%; +.icons figure { + flex: 1; } .construct-list .stats .damage-label { @@ -420,19 +414,29 @@ button.equipping { .thresholds { display: flex; - flex-flow: row-wrap; - /*align-items: center;*/ + flex-flow: column; + text-align: center; +} + +.thresholds svg { + stroke-width: 5px; +} + +.thresholds hr { + margin: 1em 0; +} + +.colour-reqs { + display: flex; + flex-flow: row; justify-content: space-around; } -.spec-goals { -} - -.spec-goals figure svg { +.thresholds figure svg { height: 2em; } -.spec-goals .unmet { +.thresholds .unmet { opacity: 0.5; } diff --git a/client/assets/styles/styles.css b/client/assets/styles/styles.css index 55ca7ec6..0b13c08e 100644 --- a/client/assets/styles/styles.css +++ b/client/assets/styles/styles.css @@ -475,7 +475,7 @@ figure.gray { stroke-color: #333; } -.stat-icon { +.stats svg, .specs svg { height: 2em; stroke-width: 5px; fill: none; diff --git a/client/src/components/game.component.jsx b/client/src/components/game.component.jsx index 5cabdae3..d199661d 100644 --- a/client/src/components/game.component.jsx +++ b/client/src/components/game.component.jsx @@ -1,7 +1,8 @@ const preact = require('preact'); const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils'); -const { animationDivs } = require('../animations'); +// const { animationDivs } = require('../animations'); const GameConstruct = require('./game.construct'); +const shapes = require('./shapes'); function GamePanel(props) { const { @@ -121,11 +122,11 @@ function GamePanel(props) { const ko = construct.green_life.value === 0 ? 'ko' : ''; const classes = eventClasses(resolution, construct); - const stats = [STATS.redLife, STATS.greenLife, STATS.blueLife].map((s, j) => ( -
- {s.svg(`stat-icon ${s.colour}`)} -
{construct[s.stat].value} / {construct[s.stat].max}
-
{construct[s.stat].value}
+ const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => ( +
+ {shapes[s]()} +
{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}
+
{construct[STATS[s].stat].value}
)); diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index b364466c..b749e37b 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -5,6 +5,7 @@ const range = require('lodash/range'); const actions = require('../actions'); const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils'); const { animationDivs } = require('../animations'); +const shapes = require('./shapes'); const SkillBtn = require('./skill.btn'); @@ -57,11 +58,11 @@ function GameConstruct(props) { const skills = range(0, 3) .map(i => ); - const stats = [STATS.redLife, STATS.greenLife, STATS.blueLife].map((s, j) => ( -
- {s.svg(`stat-icon ${s.colour}`)} -
{construct[s.stat].value} / {construct[s.stat].max}
-
{construct[s.stat].value}
+ const stats = ['RedLife', 'GreenLife', 'BlueLife'].map((s, j) => ( +
+ {shapes[s]()} +
{construct[STATS[s].stat].value} / {construct[STATS[s].stat].max}
+
{construct[STATS[s].stat].value}
)); diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 70fb688a..cbbc714a 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -2,10 +2,10 @@ const preact = require('preact'); const range = require('lodash/range'); const { INFO } = require('./../constants'); -const { SPECS } = require('./../utils'); -const { COLOUR_ICONS, convertItem } = require('../utils'); +const { convertItem } = require('../utils'); +const shapes = require('./shapes'); -function Info(args) { +function InfoComponent(args) { const { info, itemInfo, @@ -24,16 +24,6 @@ function Info(args) { const isSkill = fullInfo.skill; const isSpec = fullInfo.spec; - let red = 0; - let blue = 0; - let green = 0; - player.constructs.forEach(construct => { - red += construct.colours.red; - blue += construct.colours.blue; - green += construct.colours.green; - }); - const teamColours = { red, blue, green }; - if (isSkill) { return (
@@ -44,32 +34,64 @@ function Info(args) { } if (isSpec) { - const breaks = SPECS[info].thresholds; - const colourReqs = SPECS[info].colours || []; + let red = 0; + let blue = 0; + let green = 0; + player.constructs.forEach(construct => { + red += construct.colours.red; + blue += construct.colours.blue; + green += construct.colours.green; + }); + const teamColours = { red, blue, green }; - const thresholdEl = colourReqs.map((c, i) => { - const numIcons = Math.max(...breaks); - const dots = range(0, numIcons).map(j => { - const unmet = teamColours[c] < j + 1; - const caption = breaks.includes(j + 1) - ? '+ x' - : ''; + const colourReqs = fullInfo.values.bonuses || []; - const reqClass = unmet - ? 'unmet' - : ''; + const thresholds = colourReqs.map((bonus, i) => { + const colours = ['red', 'green', 'blue']; + const colourGoals = colours.map(c => { + const colourReq = bonus.req[c]; + if (colourReqs === 0) return false; + + const start = i === 0 + ? 0 + : colourReqs[i - 1].req[c]; + + const dots = range(start, colourReq).map(j => { + const unmet = teamColours[c] < j + 1; + + const reqClass = unmet + ? 'unmet' + : ''; + + return ( +
+ {shapes.square([c])} +
+ ); + }); return ( -
- {COLOUR_ICONS[c].svg(`stat-icon ${COLOUR_ICONS[c].colour}`)} -
{caption}
-
+
+ {dots} +
); }); + const reqsMet = colours.every(c => teamColours[c] >= bonus.req[c]); + + const reqClass = reqsMet + ? '' + : 'unmet'; + return ( -
- {dots} +
+
+ {colourGoals} +
+
+ + {bonus.bonus} +
+
); }); @@ -79,7 +101,7 @@ function Info(args) {

{info}

{fullInfo.description}
- {thresholdEl} + {thresholds}
); @@ -142,4 +164,4 @@ function Info(args) { ); } -module.exports = Info; +module.exports = InfoComponent; diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx index 7c72e07c..91af7728 100644 --- a/client/src/components/instance.constructs.jsx +++ b/client/src/components/instance.constructs.jsx @@ -3,7 +3,7 @@ const preact = require('preact'); const range = require('lodash/range'); const shapes = require('./shapes'); -const { SPECS, STATS, instanceConstruct } = require('../utils'); +const { STATS, instanceConstruct } = require('../utils'); const actions = require('../actions'); const addState = connect( @@ -146,12 +146,14 @@ function Construct(props) { const equip = specList.includes(vbox.bound[itemEquip]) ? 'equip-spec' : 'gray'; return (
- {shapes.diamond(`stat-icon ${equip}`)} + {shapes.diamond(equip)}
 
); } + const specInfo = itemInfo.items.find(i => i.item === s); + function specClick(e) { e.stopPropagation(); setItemUnequip(s); @@ -174,35 +176,23 @@ function Construct(props) { onClick={specClick} onDblClick={specDblClick} onMouseOver={e => hoverInfo(e, s)} > - {SPECS[s].svg(`stat-icon ${SPECS[s].colour}`)} -
{SPECS[s].caption}
+ {shapes[s]()} +
{s}
); }); - const stats = Object.values(STATS).map(s => ( -
- {s.svg(`stat-icon ${s.colour} stat`)} -
{construct[s.stat].value}
-
- )); + const stats = Object.keys(STATS).map(s => { + const stat = STATS[s]; + return
+ {shapes[s]()} +
{construct[stat.stat].value}
+
; + }); + const activeId = activeConstruct ? activeConstruct.id : false; const constructClass = activeId === construct.id ? 'instance-construct-active' : 'instance-construct'; - // const cTotal = construct.colours.red + construct.colours.blue + construct.colours.green; - // const colours = mapValues(construct.colours, c => { - // if (cTotal === 0) return 245; - // return Math.floor(c / cTotal * 255); - // }); - // const alpha = cTotal === 0 ? 1 : 0.75; - // const thickness = total => { - // if (total < 3) return 1; - // if (total < 6) return 2; - // if (total < 9) return 3; - // return 4; - // }; - // const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` }; - return (
{instanceConstruct(construct.name, construct.id)} diff --git a/client/src/components/instance.equip.jsx b/client/src/components/instance.equip.jsx index fa5f8813..3a18908a 100644 --- a/client/src/components/instance.equip.jsx +++ b/client/src/components/instance.equip.jsx @@ -4,7 +4,7 @@ const range = require('lodash/range'); const actions = require('../actions'); const shapes = require('./shapes'); -const { convertItem, SPECS } = require('./../utils'); +const { convertItem } = require('./../utils'); const addState = connect( function receiveState(state) { @@ -64,9 +64,11 @@ function Equipment(props) { const isSkill = fullInfo && fullInfo.skill; const isSpec = fullInfo && fullInfo.spec; + console.log('isSkill', isSkill, fullInfo); + function skillClick(e, i) { if (itemUnequip && activeConstruct) return false; - const value = vbox.bound[i]; + // const value = vbox.bound[i]; setItemEquip(i); return false; } @@ -87,37 +89,38 @@ function Equipment(props) { const skillClass = isSkill ? 'skills highlight' : 'skills'; const specClass = isSpec ? 'specs highlight' : 'specs'; - const skillList = itemInfo.items.filter(v => v.skill).map(v => v.item); - const specList = itemInfo.items.filter(v => v.spec).map(v => v.item); - const skills = range(0, 9).map(i => { const item = convertItem(vbox.bound[i]); - if (skillList.includes(item)) { + const skillInfo = itemInfo.items.find(i => i.item === item); + if (skillInfo && skillInfo.skill) { return ( ); - } return false; + } + return false; }); const specs = range(0, 9).map(i => { const item = convertItem(vbox.bound[i]); - if (specList.includes(item)) { + const specInfo = itemInfo.items.find(i => i.item === item); + if (specInfo && specInfo.spec) { return (
skillClick(e, i)} onMouseOver={e => hoverInfo(e, item)} > - {SPECS[item].svg(`stat-icon ${SPECS[item].colour}`)} -
{SPECS[item].caption}
+ {shapes[item]()} +
{item}
); - } return false; + } + return false; }); if (skills.every(s => !s)) skills.push(); if (specs.every(s => !s)) { specs.push(
- {shapes.diamond('stat-icon gray')} + {shapes.diamond('gray')}
 
); diff --git a/client/src/components/shapes.jsx b/client/src/components/shapes.jsx index 4366f759..1693937a 100644 --- a/client/src/components/shapes.jsx +++ b/client/src/components/shapes.jsx @@ -18,4 +18,43 @@ module.exports = { triangle, saw, vboxColour, + + // stats + RedLife: () => square(['red']), + GreenLife: () => square(['green']), + BlueLife: () => square(['blue']), + RedPower: () => circle(['red']), + GreenPower: () => circle(['green']), + BluePower: () => circle(['blue']), + Speed: () => triangle(['white']), + + // specs + // Base + Power: () => circle(['white']), + Life: () => square(['white']), + // Speed, + + // Lifes Upgrades + LifeGGI: () => square(['green']), + LifeRRI: () => square(['red']), + LifeBBI: () => square(['blue']), + LifeRGI: () => square(['red', 'green']), + LifeGBI: () => square(['green', 'blue']), + LifeRBI: () => square(['red', 'blue']), + + // Power Upgrades + PowerGGI: () => circle(['green']), + PowerRRI: () => circle(['red']), + PowerBBI: () => circle(['blue']), + PowerRGI: () => circle(['red', 'green']), + PowerGBI: () => circle(['green', 'blue']), + PowerRBI: () => circle(['red', 'blue']), + + // Speed Upgrades + SpeedGGI: () => triangle(['green']), + SpeedRRI: () => triangle(['red']), + SpeedBBI: () => triangle(['blue']), + SpeedRGI: () => triangle(['red', 'green']), + SpeedGBI: () => triangle(['green', 'blue']), + SpeedRBI: () => triangle(['red', 'blue']), }; diff --git a/client/src/components/svgs/circle.jsx b/client/src/components/svgs/circle.jsx index 895c7006..ce388243 100644 --- a/client/src/components/svgs/circle.jsx +++ b/client/src/components/svgs/circle.jsx @@ -1,20 +1,38 @@ const preact = require('preact'); -module.exports = function triangle(classes) { - return ( - - - - - - - - - - ); +module.exports = function circle(colours) { + if (colours.length === 1) { + return ( + + + + + + + + ); + } + + return ( + + + + + + + + + + + + + + + + + + + + + ); }; diff --git a/client/src/components/svgs/square.jsx b/client/src/components/svgs/square.jsx index 60e86f17..0cacc7a2 100644 --- a/client/src/components/svgs/square.jsx +++ b/client/src/components/svgs/square.jsx @@ -1,14 +1,40 @@ const preact = require('preact'); -module.exports = function triangle(classes) { +module.exports = function square(colours) { + if (colours.length === 1) { + return ( + + + + + + + + ); + } + return ( - - - - - + viewBox="0 0 199.33 199.99" > + + + + + + + + + + + + + + + + + + ); } diff --git a/client/src/components/svgs/triangle.jsx b/client/src/components/svgs/triangle.jsx index 14af355b..95d0a468 100644 --- a/client/src/components/svgs/triangle.jsx +++ b/client/src/components/svgs/triangle.jsx @@ -1,16 +1,38 @@ const preact = require('preact'); -module.exports = function triangle(classes) { +module.exports = function triangle(colours) { + if (colours.length === 1) { + return ( + + + + + + + + ); + } + return ( - - - - - - - - + + + + + + + + + + + + + + + + + + + ); -} +}; diff --git a/client/src/socket.jsx b/client/src/socket.jsx index 347b24aa..6597cdfe 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -300,15 +300,15 @@ function createSocket(events) { position: 'bottomCenter', }); + sendPing(); + sendItemInfo(); + if (account) { events.setAccount(account); sendAccountInstances(); sendAccountConstructs(); - setTimeout(sendItemInfo, 2000); } - sendPing(); - return true; }); diff --git a/client/src/utils.jsx b/client/src/utils.jsx index dc8ebc98..e84ca50a 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -130,178 +130,43 @@ function gameConstructImg(name, id, combatTextEl, selectSkillTarget) { const NULL_UUID = '00000000-0000-0000-0000-000000000000'; const STATS = { - redPower: { + RedPower: { stat: 'red_power', colour: 'red', svg: shapes.circle, }, - greenPower: { + GreenPower: { stat: 'green_power', colour: 'green', svg: shapes.circle, }, - bluePower: { + BluePower: { stat: 'blue_power', colour: 'blue', svg: shapes.circle, }, - speed: { + Speed: { stat: 'speed', colour: 'white', svg: shapes.triangle, }, - redLife: { + RedLife: { stat: 'red_life', colour: 'red', svg: shapes.square, }, - greenLife: { + GreenLife: { stat: 'green_life', colour: 'green', svg: shapes.square, }, - blueLife: { + BlueLife: { stat: 'blue_life', colour: 'blue', svg: shapes.square, }, }; -const SPECS = { - Life: { - colour: 'white', - caption: 'Life', - svg: shapes.square - }, - GreenLifeI: { - colour: 'green', - caption: 'Life', - thresholds: [5, 10, 20], - svg: shapes.square, - }, - RedLifeI: { - colour: 'red', - caption: 'Life', - thresholds: [2, 5, 10], - svg: shapes.square, - }, - BlueLifeI: { - colour: 'blue', - caption: 'Life', - thresholds: [2, 5, 10], - svg: shapes.square, - }, - GRLI: { - colour: 'yellow', - caption: 'Life', - thresholds: [2, 5, 10], - svg: shapes.square - }, - GBLI: { - colour: 'cyan', - caption: 'Life', - thresholds: [2, 5, 10], - svg: shapes.square - }, - RBLI: { - colour: 'purple', - caption: 'Life', - thresholds: [2, 5, 10], - svg: shapes.square - }, - - Power: { - colour: 'white', - caption: 'Power', - thresholds: [], - svg: shapes.circle - }, - RedPowerI: { - colour: 'red', - caption: 'PowerI', - thresholds: [5, 10, 20], - svg: shapes.circle - }, - BluePowerI: { - colour: 'blue', - caption: 'PowerI', - thresholds: [5, 10, 20], - svg: shapes.circle - }, - GreenPowerI: { - colour: 'green', - caption: 'PowerI', - thresholds: [5, 10, 20], - svg: shapes.circle, - }, - GRDI: { - colour: 'yellow', - caption: 'PowerI', - thresholds: [2, 5, 10], - svg: shapes.circle - }, - GBDI: { - colour: 'cyan', - caption: 'PowerI', - thresholds: [2, 5, 10], - svg: shapes.circle, - }, - RBDI: { - colour: 'purple', - caption: 'PowerI', - thresholds: [2, 5, 10], - svg: shapes.circle, - }, - - Speed: { - colour: 'white', - caption: 'Speed', - svg: shapes.triangle, - }, - RedSpeedI: { - colour: 'red', - caption: 'Speed', - thresholds: [5, 10, 20], - svg: shapes.triangle, - }, - BlueSpeedI: { - colour: 'blue', - caption: 'Speed', - thresholds: [2, 5, 10], - svg: shapes.triangle, - }, - GreenSpeedI: { - colour: 'green', - caption: 'Speed', - thresholds: [2, 5, 10], - svg: shapes.triangle, - }, - GRSpeedI: { - colour: 'yellow', - caption: 'Speed', - thresholds: [2, 5, 10], - svg: shapes.triangle, - }, - GBSpeedI: { - colour: 'cyan', - caption: 'Speed', - thresholds: [2, 5, 10], - svg: shapes.triangle, - }, - RBSpeedI: { - colour: 'purple', - caption: 'Speed', - thresholds: [2, 5, 10], - svg: shapes.triangle, - }, - -}; - -const COLOUR_ICONS = { - red: { colour: 'red', caption: 'red', svg: shapes.square }, - blue: { colour: 'blue', caption: 'blue', svg: shapes.square }, - green: { colour: 'green', caption: 'green', svg: shapes.square }, -}; function resoConstructHealth(resolution, currentGame) { if (!resolution) return false; @@ -599,6 +464,4 @@ module.exports = { resoConstructHealth, NULL_UUID, STATS, - SPECS, - COLOUR_ICONS, }; diff --git a/server/src/construct.rs b/server/src/construct.rs index 6d917ea7..f0db76e8 100644 --- a/server/src/construct.rs +++ b/server/src/construct.rs @@ -876,10 +876,10 @@ mod tests { .named(&"redboi".to_string()); construct.learn_mut(Skill::StrikeI); - construct.spec_add(Spec::GreenLifeI).unwrap(); - construct.spec_add(Spec::RedPowerI).unwrap(); - construct.spec_add(Spec::RedPowerI).unwrap(); - construct.spec_add(Spec::BlueLifeI).unwrap(); + construct.spec_add(Spec::LifeGGI).unwrap(); + construct.spec_add(Spec::PowerRRI).unwrap(); + construct.spec_add(Spec::PowerRRI).unwrap(); + construct.spec_add(Spec::LifeBBI).unwrap(); assert_eq!(construct.colours.red, 6); assert_eq!(construct.colours.green, 2); @@ -893,9 +893,9 @@ mod tests { let mut construct = Construct::new() .named(&"player player".to_string()); - construct.spec_add(Spec::RedPowerI).unwrap(); - construct.spec_add(Spec::GreenPowerI).unwrap(); - construct.spec_add(Spec::BluePowerI).unwrap(); + construct.spec_add(Spec::PowerRRI).unwrap(); + construct.spec_add(Spec::PowerGGI).unwrap(); + construct.spec_add(Spec::PowerBBI).unwrap(); let player_colours = Colours { red: 5, diff --git a/server/src/item.rs b/server/src/item.rs index 66db8759..295507d5 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -1,5 +1,5 @@ use skill::{Skill, Colour}; -use spec::{Spec}; +use spec::{Spec, SpecValues}; use construct::{Colours}; #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] @@ -23,28 +23,28 @@ pub enum Item { Speed, // Lifes Upgrades - GreenLifeI, - RedLifeI, - BlueLifeI, - GRLI, - GBLI, - RBLI, + LifeGGI, + LifeRRI, + LifeBBI, + LifeRGI, + LifeGBI, + LifeRBI, // Power Upgrades - RedPowerI, - BluePowerI, - GreenPowerI, - GRDI, - GBDI, - RBDI, + PowerRRI, + PowerBBI, + PowerGGI, + PowerRGI, + PowerGBI, + PowerRBI, // Speed Upgrades - RedSpeedI, - BlueSpeedI, - GreenSpeedI, - GRSpeedI, - GBSpeedI, - RBSpeedI, + SpeedRRI, + SpeedBBI, + SpeedGGI, + SpeedRGI, + SpeedGBI, + SpeedRBI, AmplifyI, AmplifyII, @@ -347,28 +347,28 @@ impl Item { pub fn into_spec(&self) -> Option { match *self { Item::Speed => Some(Spec::Speed), - Item::RedSpeedI => Some(Spec::RedSpeedI), - Item::BlueSpeedI => Some(Spec::BlueSpeedI), - Item::GreenSpeedI => Some(Spec::GreenSpeedI), - Item::GRSpeedI => Some(Spec::GRSpeedI), - Item::GBSpeedI => Some(Spec::GBSpeedI), - Item::RBSpeedI => Some(Spec::RBSpeedI), + Item::SpeedRRI => Some(Spec::SpeedRRI), + Item::SpeedBBI => Some(Spec::SpeedBBI), + Item::SpeedGGI => Some(Spec::SpeedGGI), + Item::SpeedRGI => Some(Spec::SpeedRGI), + Item::SpeedGBI => Some(Spec::SpeedGBI), + Item::SpeedRBI => Some(Spec::SpeedRBI), Item::Power => Some(Spec::Power), - Item::RedPowerI => Some(Spec::RedPowerI), - Item::BluePowerI => Some(Spec::BluePowerI), - Item::GreenPowerI => Some(Spec::GreenPowerI), - Item::GRDI => Some(Spec::GRDI), - Item::GBDI => Some(Spec::GBDI), - Item::RBDI => Some(Spec::RBDI), + Item::PowerRRI => Some(Spec::PowerRRI), + Item::PowerBBI => Some(Spec::PowerBBI), + Item::PowerGGI => Some(Spec::PowerGGI), + Item::PowerRGI => Some(Spec::PowerRGI), + Item::PowerGBI => Some(Spec::PowerGBI), + Item::PowerRBI => Some(Spec::PowerRBI), Item::Life => Some(Spec::Life), - Item::GRLI => Some(Spec::GRLI), - Item::GBLI => Some(Spec::GBLI), - Item::RBLI => Some(Spec::RBLI), - Item::GreenLifeI => Some(Spec::GreenLifeI), - Item::RedLifeI => Some(Spec::RedLifeI), - Item::BlueLifeI => Some(Spec::BlueLifeI), + Item::LifeRGI => Some(Spec::LifeRGI), + Item::LifeGBI => Some(Spec::LifeGBI), + Item::LifeRBI => Some(Spec::LifeRBI), + Item::LifeGGI => Some(Spec::LifeGGI), + Item::LifeRRI => Some(Spec::LifeRRI), + Item::LifeBBI => Some(Spec::LifeBBI), _ => None, } @@ -412,31 +412,31 @@ impl Item { SPEED determines the order in which skills resolve."), // Lifes Upgrades - Item::GreenLifeI => format!("Increases CONSTRUCT GreenLife. + Item::LifeGGI => format!("Increases CONSTRUCT GreenLife. When your CONSTRUCT reaches 0 GreenLife it becomes KO and cannot cast SKILLS."), - Item::RedLifeI => format!("Increases CONSTRUCT RedLife. + Item::LifeRRI => format!("Increases CONSTRUCT RedLife. RedDamage dealt to your construct reduces RedLife before GreenLife."), - Item::BlueLifeI => format!("Increases CONSTRUCT BlueLife. + Item::LifeBBI => format!("Increases CONSTRUCT BlueLife. BlueDamage dealt to your construct reduces BlueLife before GreenLife."), - Item::GRLI => format!("Increases CONSTRUCT GreenLife + RedLife"), - Item::GBLI => format!("Increases CONSTRUCT GreenLife + BlueLife"), - Item::RBLI => format!("Increases CONSTRUCT RedLife + BlueLife"), + Item::LifeRGI => format!("Increases CONSTRUCT GreenLife + RedLife"), + Item::LifeGBI => format!("Increases CONSTRUCT GreenLife + BlueLife"), + Item::LifeRBI => format!("Increases CONSTRUCT RedLife + BlueLife"), // Power Upgrades - Item::RedPowerI => format!("Increases CONSTRUCT RedPower."), - Item::BluePowerI => format!("Increases CONSTRUCT BluePower."), - Item::GreenPowerI => format!("Increases CONSTRUCT GreenPower."), - Item::GRDI => format!("Increases CONSTRUCT GreenPower + RedPower."), - Item::GBDI => format!("Increases CONSTRUCT GreenPower + BluePower."), - Item::RBDI => format!("Increases CONSTRUCT RedPower + BluePower."), + Item::PowerRRI => format!("Increases CONSTRUCT RedPower."), + Item::PowerBBI => format!("Increases CONSTRUCT BluePower."), + Item::PowerGGI => format!("Increases CONSTRUCT GreenPower."), + Item::PowerRGI => format!("Increases CONSTRUCT GreenPower + RedPower."), + Item::PowerGBI => format!("Increases CONSTRUCT GreenPower + BluePower."), + Item::PowerRBI => format!("Increases CONSTRUCT RedPower + BluePower."), // Speed Upgrades - Item::RedSpeedI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), - Item::BlueSpeedI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), - Item::GreenSpeedI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), - Item::GRSpeedI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), - Item::GBSpeedI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), - Item::RBSpeedI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), + Item::SpeedRRI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), + Item::SpeedBBI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), + Item::SpeedGGI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), + Item::SpeedRGI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), + Item::SpeedGBI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), + Item::SpeedRBI => format!("Increases CONSTRUCT SPEED and provides COLOUR BONUSES"), // Skills <- need to move effect mulltipliers into skills Item::AmplifyI | @@ -462,7 +462,7 @@ impl Item { self.into_skill().unwrap().multiplier()), Item::ClutchI | - Item::ClutchII | + Item::ClutchII | Item::ClutchIII => format!("Construct cannot be KO'd while active. Additionally provides immunity to disables."), Item::CorruptI | @@ -482,7 +482,7 @@ impl Item { self.into_skill().unwrap().effect().first().unwrap().get_duration()), Item::DecayI | - Item::DecayII | + Item::DecayII | Item::DecayIII => format!( "Reduces healing taken by {:?}% and deals blue damage {:?}% blue power each turn. Lasts {:?}T", 100 - self.into_skill().unwrap().effect().first().unwrap().get_multiplier(), @@ -513,7 +513,7 @@ impl Item { Item::HexI | Item::HexII | Item::HexIII => format!("Blue based skill that applies Hex for {:?}T. \ - Hexed targets cannot cast any skills.", + Hexed targets cannot cast any skills.", self.into_skill().unwrap().effect().first().unwrap().get_duration()), Item::ImpurityI | @@ -526,7 +526,7 @@ impl Item { self.into_skill().unwrap().effect().first().unwrap().get_duration()), Item::InvertI | - Item::InvertII | + Item::InvertII | Item::InvertIII => format!( "Reverse healing into damage and damage into healing. Any excess red or blue damage is converted into shield recharge."), @@ -557,7 +557,7 @@ impl Item { self.into_skill().unwrap().effect().first().unwrap().get_duration()), Item::RechargeI | - Item::RechargeII | + Item::RechargeII | Item::RechargeIII => format!( "Recharge Red and Blue Life based on {:?} RedPower and BluePower", self.into_skill().unwrap().multiplier()), @@ -567,7 +567,7 @@ impl Item { Item::RuinIII => format!( "Team wide Stun for {:?}T. Stunned constructs are unable to cast skills.", self.into_skill().unwrap().effect().first().unwrap().get_duration()), - + Item::ScatterI | Item::ScatterII | Item::ScatterIII => format!( @@ -637,7 +637,7 @@ impl Item { "Stun the target for {:?}T and applies Vulnerable increasing RedDamage taken by {:?}% for {:?}T", self.into_skill().unwrap().effect().first().unwrap().get_duration(), - self.into_skill().unwrap().effect().first().unwrap().get_multiplier() - 100, + self.into_skill().unwrap().effect().last().unwrap().get_multiplier() - 100, self.into_skill().unwrap().effect().last().unwrap().get_duration()), Item::TriageI | @@ -662,15 +662,15 @@ impl Item { Item::ScatterI => vec![Item::Buff, Item::Blue, Item::Blue], Item::ScatterII => vec![Item::ScatterI, Item::ScatterI, Item::ScatterI], Item::ScatterIII => vec![Item::ScatterIII, Item::ScatterIII, Item::ScatterIII], - + Item::HasteI => vec![Item::Buff, Item::Red, Item::Green], Item::HasteII => vec![Item::HasteI, Item::HasteI, Item::HasteI], Item::HasteIII => vec![Item::HasteII, Item::HasteII, Item::HasteII], Item::ImpurityI => vec![Item::Buff, Item::Green, Item::Blue], Item::ImpurityII => vec![Item::ImpurityI, Item::ImpurityI, Item::ImpurityI], Item::ImpurityIII => vec![Item::ImpurityII, Item::ImpurityII, Item::ImpurityII], - Item::AmplifyI => vec![Item::Buff, Item::Red, Item::Blue], - Item::AmplifyII => vec![Item::AmplifyI, Item::AmplifyI, Item::AmplifyI], + Item::AmplifyI => vec![Item::Buff, Item::Red, Item::Blue], + Item::AmplifyII => vec![Item::AmplifyI, Item::AmplifyI, Item::AmplifyI], Item::AmplifyIII => vec![Item::AmplifyII, Item::AmplifyII, Item::AmplifyII], Item::SnareI => vec![Item::Debuff, Item::Red, Item::Red], @@ -749,26 +749,26 @@ impl Item { Item::ChaosII => vec![Item::ChaosI, Item::ChaosI, Item::ChaosI], Item::ChaosIII => vec![Item::ChaosII, Item::ChaosII, Item::ChaosII], - Item::RedPowerI => vec![Item::Power, Item::Red, Item::Red], - Item::GreenPowerI => vec![Item::Power, Item::Green, Item::Green], - Item::BluePowerI => vec![Item::Power, Item::Blue, Item::Blue], - Item::GRDI => vec![Item::Power, Item::Red, Item::Green], - Item::GBDI => vec![Item::Power, Item::Green, Item::Blue], - Item::RBDI => vec![Item::Power, Item::Red, Item::Blue], + Item::PowerRRI => vec![Item::Power, Item::Red, Item::Red], + Item::PowerGGI => vec![Item::Power, Item::Green, Item::Green], + Item::PowerBBI => vec![Item::Power, Item::Blue, Item::Blue], + Item::PowerRGI => vec![Item::Power, Item::Red, Item::Green], + Item::PowerGBI => vec![Item::Power, Item::Green, Item::Blue], + Item::PowerRBI => vec![Item::Power, Item::Red, Item::Blue], - Item::RedLifeI => vec![Item::Life, Item::Red, Item::Red], - Item::GreenLifeI => vec![Item::Life, Item::Green, Item::Green], - Item::BlueLifeI => vec![Item::Life, Item::Blue, Item::Blue], - Item::GRLI => vec![Item::Life, Item::Red, Item::Green], - Item::GBLI => vec![Item::Life, Item::Green, Item::Blue], - Item::RBLI => vec![Item::Life, Item::Red, Item::Blue], + Item::LifeRRI => vec![Item::Life, Item::Red, Item::Red], + Item::LifeGGI => vec![Item::Life, Item::Green, Item::Green], + Item::LifeBBI => vec![Item::Life, Item::Blue, Item::Blue], + Item::LifeRGI => vec![Item::Life, Item::Red, Item::Green], + Item::LifeGBI => vec![Item::Life, Item::Green, Item::Blue], + Item::LifeRBI => vec![Item::Life, Item::Red, Item::Blue], - Item::RedSpeedI => vec![Item::Speed, Item::Red, Item::Red], - Item::GreenSpeedI => vec![Item::Speed, Item::Green, Item::Green], - Item::BlueSpeedI => vec![Item::Speed, Item::Blue, Item::Blue], - Item::GRSpeedI => vec![Item::Speed, Item::Red, Item::Green], - Item::GBSpeedI => vec![Item::Speed, Item::Green, Item::Blue], - Item::RBSpeedI => vec![Item::Speed, Item::Red, Item::Blue], + Item::SpeedRRI => vec![Item::Speed, Item::Red, Item::Red], + Item::SpeedGGI => vec![Item::Speed, Item::Green, Item::Green], + Item::SpeedBBI => vec![Item::Speed, Item::Blue, Item::Blue], + Item::SpeedRGI => vec![Item::Speed, Item::Red, Item::Green], + Item::SpeedGBI => vec![Item::Speed, Item::Green, Item::Blue], + Item::SpeedRBI => vec![Item::Speed, Item::Red, Item::Blue], _ => vec![*self], } @@ -890,29 +890,29 @@ impl From for Item { impl From for Item { fn from(spec: Spec) -> Item { match spec { - Spec::Speed => Item::Speed, - Spec::RedSpeedI => Item::RedSpeedI, - Spec::BlueSpeedI => Item::BlueSpeedI, - Spec::GreenSpeedI => Item::GreenSpeedI, - Spec::GRSpeedI => Item::GRSpeedI, - Spec::GBSpeedI => Item::GBSpeedI, - Spec::RBSpeedI => Item::RBSpeedI, + Spec::Speed => Item::Speed, + Spec::SpeedRRI => Item::SpeedRRI, + Spec::SpeedBBI => Item::SpeedBBI, + Spec::SpeedGGI => Item::SpeedGGI, + Spec::SpeedRGI => Item::SpeedRGI, + Spec::SpeedGBI => Item::SpeedGBI, + Spec::SpeedRBI => Item::SpeedRBI, - Spec::Power => Item::Power, - Spec::RedPowerI => Item::RedPowerI, - Spec::BluePowerI => Item::BluePowerI, - Spec::GreenPowerI => Item::GreenPowerI, - Spec::GRDI => Item::GRDI, - Spec::GBDI => Item::GBDI, - Spec::RBDI => Item::RBDI, + Spec::Power => Item::Power, + Spec::PowerRRI => Item::PowerRRI, + Spec::PowerBBI => Item::PowerBBI, + Spec::PowerGGI => Item::PowerGGI, + Spec::PowerRGI => Item::PowerRGI, + Spec::PowerGBI => Item::PowerGBI, + Spec::PowerRBI => Item::PowerRBI, - Spec::Life => Item::Life, - Spec::GRLI => Item::GRLI, - Spec::GBLI => Item::GBLI, - Spec::RBLI => Item::RBLI, - Spec::GreenLifeI => Item::GreenLifeI, - Spec::RedLifeI => Item::RedLifeI, - Spec::BlueLifeI => Item::BlueLifeI, + Spec::Life => Item::Life, + Spec::LifeRGI => Item::LifeRGI, + Spec::LifeGBI => Item::LifeGBI, + Spec::LifeRBI => Item::LifeRBI, + Spec::LifeGGI => Item::LifeGGI, + Spec::LifeRRI => Item::LifeRRI, + Spec::LifeBBI => Item::LifeBBI, // _ => panic!("{:?} not implemented as a item", spec), } } @@ -938,7 +938,7 @@ pub fn get_combos() -> Vec { Combo { components: Item::ScatterI.combo(), item: Item::ScatterI }, Combo { components: Item::ScatterII.combo(), item: Item::ScatterII }, Combo { components: Item::ScatterIII.combo(), item: Item::ScatterIII }, - + Combo { components: Item::HasteI.combo(), item: Item::HasteI }, Combo { components: Item::HasteII.combo(), item: Item::HasteII }, Combo { components: Item::HasteIII.combo(), item: Item::HasteIII }, @@ -948,7 +948,7 @@ pub fn get_combos() -> Vec { Combo { components: Item::ImpurityI.combo(), item: Item::ImpurityI }, Combo { components: Item::ImpurityII.combo(), item: Item::ImpurityII }, Combo { components: Item::ImpurityIII.combo(), item: Item::ImpurityIII }, - + Combo { components: Item::AmplifyI.combo(), item: Item::AmplifyI }, Combo { components: Item::AmplifyII.combo(), item: Item::AmplifyII }, Combo { components: Item::AmplifyIII.combo(), item: Item::AmplifyIII }, @@ -981,11 +981,11 @@ pub fn get_combos() -> Vec { Combo { components: Item::PurifyI.combo(), item: Item::PurifyI }, Combo { components: Item::PurifyII.combo(), item: Item::PurifyII }, Combo { components: Item::PurifyIII.combo(), item: Item::PurifyIII }, - + Combo { components: Item::CorruptI.combo(), item: Item::CorruptI }, Combo { components: Item::CorruptII.combo(), item: Item::CorruptII }, Combo { components: Item::CorruptIII.combo(), item: Item::CorruptIII }, - + Combo { components: Item::ClutchI.combo(), item: Item::ClutchI }, Combo { components: Item::ClutchII.combo(), item: Item::ClutchII }, Combo { components: Item::ClutchIII.combo(), item: Item::ClutchIII }, @@ -1038,26 +1038,26 @@ pub fn get_combos() -> Vec { Combo { components: Item::ChaosII.combo(), item: Item::ChaosII }, Combo { components: Item::ChaosIII.combo(), item: Item::ChaosIII }, - Combo { components: Item::RedPowerI.combo(), item: Item::RedPowerI }, - Combo { components: Item::GreenPowerI.combo(), item: Item::GreenPowerI }, - Combo { components: Item::BluePowerI.combo(), item: Item::BluePowerI }, - Combo { components: Item::GRDI.combo(), item: Item::GRDI }, - Combo { components: Item::GBDI.combo(), item: Item::GBDI }, - Combo { components: Item::RBDI.combo(), item: Item::RBDI }, + Combo { components: Item::PowerRRI.combo(), item: Item::PowerRRI }, + Combo { components: Item::PowerGGI.combo(), item: Item::PowerGGI }, + Combo { components: Item::PowerBBI.combo(), item: Item::PowerBBI }, + Combo { components: Item::PowerRGI.combo(), item: Item::PowerRGI }, + Combo { components: Item::PowerGBI.combo(), item: Item::PowerGBI }, + Combo { components: Item::PowerRBI.combo(), item: Item::PowerRBI }, - Combo { components: Item::RedLifeI.combo(), item: Item::RedLifeI }, - Combo { components: Item::GreenLifeI.combo(), item: Item::GreenLifeI }, - Combo { components: Item::BlueLifeI.combo(), item: Item::BlueLifeI }, - Combo { components: Item::GRLI.combo(), item: Item::GRLI }, - Combo { components: Item::GBLI.combo(), item: Item::GBLI }, - Combo { components: Item::RBLI.combo(), item: Item::RBLI }, + Combo { components: Item::LifeRRI.combo(), item: Item::LifeRRI }, + Combo { components: Item::LifeGGI.combo(), item: Item::LifeGGI }, + Combo { components: Item::LifeBBI.combo(), item: Item::LifeBBI }, + Combo { components: Item::LifeRGI.combo(), item: Item::LifeRGI }, + Combo { components: Item::LifeGBI.combo(), item: Item::LifeGBI }, + Combo { components: Item::LifeRBI.combo(), item: Item::LifeRBI }, - Combo { components: Item::RedSpeedI.combo(), item: Item::RedSpeedI }, - Combo { components: Item::GreenSpeedI.combo(), item: Item::GreenSpeedI }, - Combo { components: Item::BlueSpeedI.combo(), item: Item::BlueSpeedI }, - Combo { components: Item::GRSpeedI.combo(), item: Item::GRSpeedI }, - Combo { components: Item::GBSpeedI.combo(), item: Item::GBSpeedI }, - Combo { components: Item::RBSpeedI.combo(), item: Item::RBSpeedI }, + Combo { components: Item::SpeedRRI.combo(), item: Item::SpeedRRI }, + Combo { components: Item::SpeedGGI.combo(), item: Item::SpeedGGI }, + Combo { components: Item::SpeedBBI.combo(), item: Item::SpeedBBI }, + Combo { components: Item::SpeedRGI.combo(), item: Item::SpeedRGI }, + Combo { components: Item::SpeedGBI.combo(), item: Item::SpeedGBI }, + Combo { components: Item::SpeedRBI.combo(), item: Item::SpeedRBI }, ]; @@ -1071,6 +1071,7 @@ pub struct ItemInfo { pub item: Item, pub spec: bool, pub skill: bool, + pub values: Option, pub description: String, } @@ -1101,6 +1102,10 @@ pub fn item_info() -> ItemInfoCtr { spec: v.into_spec().is_some(), skill: v.into_skill().is_some(), description: v.into_description(), + values: match v.into_spec() { + Some(s) => Some(s.values()), + None => None + }, }) .collect::>(); @@ -1139,4 +1144,10 @@ mod tests { ]); } + + #[test] + fn item_info_test() { + let info = item_info(); + println!("{:#?}", info); + } } \ No newline at end of file diff --git a/server/src/spec.rs b/server/src/spec.rs index 014c3d18..72575664 100644 --- a/server/src/spec.rs +++ b/server/src/spec.rs @@ -1,61 +1,262 @@ use construct::{Stat, Colours}; use util::{IntPct}; +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct SpecBonus { + pub req: Colours, + pub bonus: u64, +} + +impl SpecBonus { + pub fn get_bonus(&self, c: &Colours) -> u64 { + if c.red >= self.req.red && c.blue >= self.req.blue && c.green >= self.req.green { + return self.bonus; + } + return 0; + } +} + +#[derive(Debug,Clone,Serialize,Deserialize)] +pub struct SpecValues { + pub base: u64, + pub bonuses: Vec, +} + #[derive(Debug,Copy,Clone,Serialize,Deserialize,PartialEq,PartialOrd,Ord,Eq)] pub enum Spec { Speed, - RedSpeedI, - BlueSpeedI, - GreenSpeedI, - GRSpeedI, - GBSpeedI, - RBSpeedI, + SpeedRRI, + SpeedBBI, + SpeedGGI, + SpeedRGI, + SpeedGBI, + SpeedRBI, // Pure redLife has to come first as it applies the base amount // that is multiplied Life, - GreenLifeI, - RedLifeI, - BlueLifeI, - GRLI, - GBLI, - RBLI, + LifeGGI, + LifeRRI, + LifeBBI, + LifeRGI, + LifeGBI, + LifeRBI, Power, - RedPowerI, - GreenPowerI, - BluePowerI, - GRDI, - GBDI, - RBDI, + PowerRRI, + PowerGGI, + PowerBBI, + PowerRGI, + PowerGBI, + PowerRBI, } impl Spec { pub fn affects(&self) -> Vec { match *self { - Spec::Power => vec![Stat::BluePower, Stat::RedPower, Stat::GreenPower], - Spec::RedPowerI => vec![Stat::RedPower], - Spec::GreenPowerI => vec![Stat::GreenPower], - Spec::BluePowerI => vec![Stat::BluePower], - Spec::GRDI => vec![Stat::GreenPower, Stat::RedPower], - Spec::GBDI => vec![Stat::GreenPower, Stat::BluePower], - Spec::RBDI => vec![Stat::RedPower, Stat::BluePower], + Spec::Power => vec![Stat::BluePower, Stat::RedPower, Stat::GreenPower], + Spec::PowerRRI => vec![Stat::RedPower], + Spec::PowerGGI => vec![Stat::GreenPower], + Spec::PowerBBI => vec![Stat::BluePower], + Spec::PowerRGI => vec![Stat::GreenPower, Stat::RedPower], + Spec::PowerGBI => vec![Stat::GreenPower, Stat::BluePower], + Spec::PowerRBI => vec![Stat::RedPower, Stat::BluePower], - Spec::Speed => vec![Stat::Speed], - Spec::RedSpeedI => vec![Stat::Speed], - Spec::BlueSpeedI => vec![Stat::Speed], - Spec::GreenSpeedI => vec![Stat::Speed], - Spec::GRSpeedI => vec![Stat::Speed], - Spec::GBSpeedI => vec![Stat::Speed], - Spec::RBSpeedI => vec![Stat::Speed], + Spec::Speed => vec![Stat::Speed], + Spec::SpeedRRI => vec![Stat::Speed], + Spec::SpeedBBI => vec![Stat::Speed], + Spec::SpeedGGI => vec![Stat::Speed], + Spec::SpeedRGI => vec![Stat::Speed], + Spec::SpeedGBI => vec![Stat::Speed], + Spec::SpeedRBI => vec![Stat::Speed], - Spec::Life => vec![Stat::GreenLife], - Spec::RedLifeI => vec![Stat::RedLife], - Spec::BlueLifeI => vec![Stat::BlueLife], - Spec::GreenLifeI => vec![Stat::GreenLife], - Spec::GRLI => vec![Stat::GreenLife, Stat::RedLife], - Spec::GBLI => vec![Stat::GreenLife, Stat::BlueLife], - Spec::RBLI => vec![Stat::BlueLife, Stat::RedLife], + Spec::Life => vec![Stat::GreenLife], + Spec::LifeRRI => vec![Stat::RedLife], + Spec::LifeBBI => vec![Stat::BlueLife], + Spec::LifeGGI => vec![Stat::GreenLife], + Spec::LifeRGI => vec![Stat::GreenLife, Stat::RedLife], + Spec::LifeGBI => vec![Stat::GreenLife, Stat::BlueLife], + Spec::LifeRBI => vec![Stat::BlueLife, Stat::RedLife], + } + } + pub fn values(&self) -> SpecValues { + match *self { + Spec::Power => SpecValues { + base: 5, + bonuses: vec![] + }, + + Spec::PowerRRI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 20 }, + SpecBonus { req: Colours { red: 20, green: 0, blue: 0 }, bonus: 40 } + ], + }, + + Spec::PowerGGI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 20 }, + SpecBonus { req: Colours { red: 0, green: 20, blue: 0 }, bonus: 40 } + ], + }, + + Spec::PowerBBI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 20 }, + SpecBonus { req: Colours { red: 0, green: 0, blue: 20 }, bonus: 40 } + ], + }, + + Spec::PowerRGI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 15 }, + SpecBonus { req: Colours { red: 10, green: 10, blue: 0 }, bonus: 30 } + ], + }, + + Spec::PowerGBI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 15 }, + SpecBonus { req: Colours { red: 0, green: 10, blue: 10 }, bonus: 30 } + ], + }, + + Spec::PowerRBI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 10 }, + SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 15 }, + SpecBonus { req: Colours { red: 10, green: 0, blue: 10 }, bonus: 30 } + ], + }, + + Spec::Speed => SpecValues { + base: 5, + bonuses: vec![] + }, + + Spec::SpeedRRI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 20 }, + SpecBonus { req: Colours { red: 20, green: 0, blue: 0 }, bonus: 40 } + ], + }, + + Spec::SpeedGGI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 20 }, + SpecBonus { req: Colours { red: 0, green: 20, blue: 0 }, bonus: 40 } + ], + }, + + Spec::SpeedBBI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 20 }, + SpecBonus { req: Colours { red: 0, green: 0, blue: 20 }, bonus: 40 } + ], + }, + + Spec::SpeedRGI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 15 }, + SpecBonus { req: Colours { red: 10, green: 10, blue: 0 }, bonus: 30 } + ], + }, + + Spec::SpeedGBI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 15 }, + SpecBonus { req: Colours { red: 0, green: 10, blue: 10 }, bonus: 30 } + ], + }, + + Spec::SpeedRBI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 10 }, + SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 15 }, + SpecBonus { req: Colours { red: 10, green: 0, blue: 10 }, bonus: 30 } + ], + }, + + Spec::Life => SpecValues { + base: 5, + bonuses: vec![]}, + + Spec::LifeRRI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 5, green: 0, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 10, green: 0, blue: 0 }, bonus: 20 }, + SpecBonus { req: Colours { red: 20, green: 0, blue: 0 }, bonus: 40 } + ], + }, + + Spec::LifeGGI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 5, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 10, blue: 0 }, bonus: 20 }, + SpecBonus { req: Colours { red: 0, green: 20, blue: 0 }, bonus: 40 } + ], + }, + + Spec::LifeBBI => SpecValues { + base: 10, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 0, blue: 5 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 0, blue: 10 }, bonus: 20 }, + SpecBonus { req: Colours { red: 0, green: 0, blue: 20 }, bonus: 40 } + ], + }, + + Spec::LifeRGI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 2, green: 2, blue: 0 }, bonus: 10 }, + SpecBonus { req: Colours { red: 5, green: 5, blue: 0 }, bonus: 15 }, + SpecBonus { req: Colours { red: 10, green: 10, blue: 0 }, bonus: 30 } + ], + }, + + + Spec::LifeGBI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 0, green: 2, blue: 2 }, bonus: 10 }, + SpecBonus { req: Colours { red: 0, green: 5, blue: 5 }, bonus: 15 }, + SpecBonus { req: Colours { red: 0, green: 10, blue: 10 }, bonus: 30 } + ], + }, + + Spec::LifeRBI => SpecValues { + base: 5, + bonuses: vec![ + SpecBonus { req: Colours { red: 2, green: 0, blue: 2 }, bonus: 10 }, + SpecBonus { req: Colours { red: 5, green: 0, blue: 5 }, bonus: 15 }, + SpecBonus { req: Colours { red: 10, green: 0, blue: 10 }, bonus: 30 } + ], + }, } } @@ -63,136 +264,35 @@ impl Spec { let construct_colour_total: u64 = (construct_colours.red + construct_colours.green + construct_colours.blue) as u64; match *self { // Upgrades to Power Spec - Spec::Power => modified + base.pct(5), - Spec::RedPowerI => modified + { - let mut pct = 10; - if player_colours.red >= 5 { pct += 10 }; - if player_colours.red >= 10 { pct += 20 }; - if player_colours.red >= 20 { pct += 40 }; - base.pct(pct) + Spec::Power | + Spec::PowerRRI | + Spec::PowerGGI | + Spec::PowerBBI | + Spec::PowerRGI | + Spec::PowerGBI | + Spec::PowerRBI | + Spec::Speed | + Spec::SpeedRRI | + Spec::SpeedGGI | + Spec::SpeedBBI | + Spec::SpeedRGI | + Spec::SpeedGBI | + Spec::SpeedRBI => modified + { + let spec_values = self.values(); + base.pct(spec_values.bonuses.iter() + .fold(spec_values.base, |acc, s| acc + s.get_bonus(player_colours))) }, - Spec::GreenPowerI => modified + { - let mut pct = 10; - if player_colours.green >= 5 { pct += 10 }; - if player_colours.green >= 10 { pct += 20 }; - if player_colours.green >= 20 { pct += 40 }; - base.pct(pct) - }, - Spec::BluePowerI => modified + { - let mut pct = 10; - if player_colours.blue >= 5 { pct += 10 }; - if player_colours.blue >= 10 { pct += 20 }; - if player_colours.blue >= 20 { pct += 40 }; - base.pct(pct) - }, - Spec::GRDI => modified + { - let mut pct = 5; - if player_colours.green >= 2 && player_colours.red >= 2 { pct += 10 }; - if player_colours.green >= 5 && player_colours.red >= 5 { pct += 15 }; - if player_colours.green >= 10 && player_colours.red >= 10 { pct += 30 }; - base.pct(pct) - }, - Spec::GBDI => modified + { - let mut pct = 5; - if player_colours.green >= 2 && player_colours.blue >= 2 { pct += 10 }; - if player_colours.green >= 5 && player_colours.blue >= 5 { pct += 15 }; - if player_colours.green >= 10 && player_colours.blue >= 10 { pct += 30 }; - base.pct(pct) - }, - Spec::RBDI => modified + { - let mut pct = 5; - if player_colours.blue >= 2 && player_colours.red >= 2 { pct += 10 }; - if player_colours.blue >= 5 && player_colours.red >= 5 { pct += 15 }; - if player_colours.blue >= 10 && player_colours.red >= 10 { pct += 30 }; - base.pct(pct) - }, - // Upgrades to speed Spec - Spec::Speed => modified + base.pct(5), - Spec::RedSpeedI => modified + { - let mut pct = 5; - if player_colours.red >= 5 { pct += 5 }; - if player_colours.red >= 10 { pct += 10 }; - if player_colours.red >= 20 { pct += 20 }; - base.pct(pct) - }, - Spec::GreenSpeedI => modified + { - let mut pct = 5; - if player_colours.green >= 5 { pct += 5 }; - if player_colours.green >= 10 { pct += 10 }; - if player_colours.green >= 20 { pct += 20 }; - base.pct(pct) - }, - Spec::BlueSpeedI => modified + { - let mut pct = 5; - if player_colours.blue >= 5 { pct += 5 }; - if player_colours.blue >= 10 { pct += 10 }; - if player_colours.blue >= 20 { pct += 20 }; - base.pct(pct) - }, - Spec::GRSpeedI => modified + { - let mut pct = 5; - if player_colours.green >= 2 && player_colours.red >= 2 { pct += 5 }; - if player_colours.green >= 5 && player_colours.red >= 5 { pct += 10 }; - if player_colours.green >= 10 && player_colours.red >= 10 { pct += 20 }; - base.pct(pct) - }, - Spec::GBSpeedI => modified + { - let mut pct = 5; - if player_colours.green >= 2 && player_colours.blue >= 2 { pct += 5 }; - if player_colours.green >= 5 && player_colours.blue >= 5 { pct += 10 }; - if player_colours.green >= 10 && player_colours.blue >= 10 { pct += 20 }; - base.pct(pct) - }, - Spec::RBSpeedI => modified + { - let mut pct = 5; - if player_colours.blue >= 2 && player_colours.red >= 2 { pct += 5 }; - if player_colours.blue >= 5 && player_colours.red >= 5 { pct += 10 }; - if player_colours.blue >= 10 && player_colours.red >= 10 { pct += 20 }; - base.pct(pct) - }, - // Upgrades to HP Spec - Spec::Life => modified + base.pct(5), - Spec::GreenLifeI => modified + { - let mut mult: u64 = 25; - if player_colours.green >= 5 { mult += 15 }; - if player_colours.green >= 10 { mult += 30 }; - if player_colours.green >= 20 { mult += 45 }; - mult * construct_colour_total - }, - Spec::RedLifeI => modified + { - let mut mult: u64 = 25; - if player_colours.red >= 5 { mult += 15 }; - if player_colours.red >= 10 { mult += 30 }; - if player_colours.red >= 20 { mult += 45 }; - mult * construct_colour_total - }, - Spec::BlueLifeI => modified + { - let mut mult: u64 = 25; - if player_colours.blue >= 5 { mult += 15 }; - if player_colours.blue >= 10 { mult += 30 }; - if player_colours.blue >= 20 { mult += 45 }; - mult * construct_colour_total - }, - Spec::GRLI => modified + { - let mut mult: u64 = 15; - if player_colours.green >= 2 && player_colours.red >= 2 { mult += 10 }; - if player_colours.green >= 5 && player_colours.red >= 5 { mult += 20 }; - if player_colours.green >= 10 && player_colours.red >= 10 { mult += 40 }; - mult * construct_colour_total - }, - Spec::GBLI => modified + { - let mut mult: u64 = 15; - if player_colours.green >= 2 && player_colours.red >= 2 { mult += 10 }; - if player_colours.green >= 5 && player_colours.red >= 5 { mult += 20 }; - if player_colours.green >= 10 && player_colours.red >= 10 { mult += 40 }; - mult * construct_colour_total - }, - Spec::RBLI => modified + { - let mut mult: u64 = 15; - if player_colours.blue >= 2 && player_colours.red >= 2 { mult += 10 }; - if player_colours.blue >= 5 && player_colours.red >= 5 { mult += 20 }; - if player_colours.blue >= 10 && player_colours.red >= 10 { mult += 40 }; - mult * construct_colour_total + + Spec::Life | + Spec::LifeRRI | + Spec::LifeGGI | + Spec::LifeBBI | + Spec::LifeRGI | + Spec::LifeGBI | + Spec::LifeRBI => modified + { + let spec_values = self.values(); + construct_colour_total * (spec_values.bonuses.iter() + .fold(spec_values.base, |acc, s| acc + s.get_bonus(player_colours))) }, } }