diff --git a/CHANGELOG.md b/CHANGELOG.md index 46d96690..a817f86d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,39 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed ### Changed -## [In Progress] +## [0.1.4 2019-09-17] + +### Changed +Removed self targetting, all skills can be used on any target + +`Reflect` No cooldown, 1T duration +`Purify` No cooldown +`Recharge` No cooldown + +`Link` reworked -> + Stuns caster for 3/2/1T + If target has higher green life than caster: + Deal blue damage to target equal to difference between green life + Heal with green damage to source equal to difference between green life + +`Counter` effect no longer applies immunities + Counter no cooldown + Counter applies for 1T + Counter skill now applies block at 40% / 60% / 80% reduction for 1T + Counter no longer recharges red life + +`Electrify` + No Cooldown + Duration -> 1T + Electrocute duration now 2/3/4T + +`Sustain` + Now has 1T cooldown at all levels + Has 1T duration at all levels + Now recharges red life to target (120 / 150 / 230)% + + +## [0.1.3 2019-??-??] ### Added @@ -20,20 +52,6 @@ Added `Buff` as a skill `Sustain` now grants immunity to disables. -*BALANCE* -- purify - - 1 effect from all constructs at level 2 - - removes all effects from all constructs at l3 - -- invert - - fx for buffs when applied to enemies - - invert + haste -> doubles all cooldowns - -var / skill info rpc - thresholds / bonuses - sell cost - etc - ## [0.1.2] - 2019-05-07 ### Added diff --git a/VERSION b/VERSION index 03e5161d..7b5753f5 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.4.5 \ No newline at end of file +1.4.6 \ No newline at end of file diff --git a/WORKLOG.md b/WORKLOG.md index 298e6f99..3b95543c 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -31,6 +31,7 @@ * fuck magic * empower on ko +var / skill info rpc -> sell cost / cooldown * rework vecs into sets * remove names so games/instances are copy diff --git a/acp/package.json b/acp/package.json index 2d6bcc99..9b9d7f41 100644 --- a/acp/package.json +++ b/acp/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.4.5", + "version": "1.4.6", "description": "", "main": "index.js", "scripts": { diff --git a/client/animations.test.js b/client/animations.test.js index fa76c5dd..3271b840 100644 --- a/client/animations.test.js +++ b/client/animations.test.js @@ -1,8 +1,14 @@ require('./assets/styles/styles.less'); -require('./assets/styles/styles.mobile.css'); +require('./assets/styles/menu.less'); +require('./assets/styles/nav.less'); +require('./assets/styles/footer.less'); +require('./assets/styles/account.less'); +require('./assets/styles/controls.less'); require('./assets/styles/instance.less'); +require('./assets/styles/vbox.less'); +require('./assets/styles/game.less'); +require('./assets/styles/player.less'); +require('./assets/styles/styles.mobile.css'); require('./assets/styles/instance.mobile.css'); -require('./assets/styles/game.css'); -// kick it off require('./src/animations.test.jsx'); diff --git a/client/assets/icons/mnml.png b/client/assets/icons/mnml.png new file mode 100644 index 00000000..068e30c1 Binary files /dev/null and b/client/assets/icons/mnml.png differ diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index e51237bc..0a71051c 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -28,30 +28,31 @@ .opponent { grid-area: opponent; -} -.opponent .combat-text { - top: 75%; -} + .game-construct { + align-items: flex-start; + grid-template-columns: 1fr 2fr; + grid-template-rows: 1fr; -.opponent .combat-anim { - top: 25%; -} + .right { + height: 100%; + display: grid; + grid-template-rows: min-content min-content 1fr; + grid-template-areas: + "stats" + "name" + "avatar"; + } -.opponent .game-construct { - align-items: flex-start; - grid-template-rows: min-content min-content min-content minmax(min-content, 2fr); - grid-template-columns: 1fr; - grid-template-areas: - "stats " - "name " - "effects " - "avatar "; -} + .effects { + align-self: flex-start; + } + } -.opponent .game-construct .name { - margin-bottom: 0; - margin-top: 0.25em; + .game-construct .name { + margin-bottom: 0; + margin-top: 0.25em; + } } .game-construct { @@ -65,19 +66,112 @@ justify-items: center; - grid-template-rows: min-content minmax(min-content, 1fr) min-content min-content min-content; - grid-template-columns: 1fr; - grid-template-areas: - "skills " - "avatar " - "effects " - "name " - "stats "; + grid-template-columns: 1fr 3fr; + + .left { + display: grid; + grid-template-rows: 1fr 1fr; + grid-template-areas: + "skills " + "effects"; + } + + .right { + display: grid; + grid-template-rows: minmax(min-content, 1fr) min-content min-content; + grid-template-areas: + "avatar" + "name" + "stats"; + width: 100%; + } transition-property: translate, opacity; transition-duration: 0.25s; transition-delay: 0; transition-timing-function: ease; + + .effects { + align-self: flex-end; + text-align: right; + } + + .stats { + align-self: flex-end; + } + + .name { + width: 100%; + margin-bottom: 0.25em; + text-align: center; + grid-area: name; + } + + .skills { + grid-area: skills; + width: 100%; + + button { + width: 100%; + height: 2em; + height: 25%; + } + } + + .effects { + grid-area: effects; + white-space: nowrap; + width: 100%; + text-align: center; + font-size: 1.5em; + } + + .stats { + grid-area: stats; + display: flex; + justify-content: center; + text-align: center; + } + + .stats div { + padding: 0 0.5em; + display: flex; + flex-flow: column; + white-space: nowrap; + text-align: center; + } + + .stats .value { + display: none; + } + + figcaption { + white-space: nowrap; + font-size: 100%; + } + + &.ko { + animation: none; + opacity: 0.20; + } + + &.ko button:hover { + color: #333; + } + + &.unfocus { + opacity: 0.35; + } + + &.unfocus.ko { + opacity: 0.20; + } +} + +@media (max-width: 1500px) { + .game-construct figure { + padding: 0 0.25em; + } } #targeting { @@ -88,153 +182,34 @@ stroke: whitesmoke; } +.resolving-skill { + grid-area: target; + align-self: center; + text-align: center; + height: auto; +} + /* some stupid bug in chrome makes it fill the entire screen */ @media screen and (-webkit-min-device-pixel-ratio:0) { #targeting { max-height: 10em; } } -/* -.resolving #targeting { - opacity: 0; -} -*/ -.game-construct .name { - width: 100%; - margin-bottom: 0.25em; - text-align: center; - grid-area: name; -} - -.game-construct .stats { - grid-area: stats; - display: flex; - justify-content: center; - text-align: center; -} - -.game-construct .stats div { - padding: 0 0.5em; - display: flex; - flex-flow: column; - white-space: nowrap; - text-align: center; -} - -.game-construct .stats .value { - display: none; -} - -.game-construct figcaption { - white-space: nowrap; - font-size: 100%; -} - -@media (max-width: 1500px) { - .game-construct figure { - padding: 0 0.25em; - } -} - -.game-construct .skills { - grid-area: skills; - display: flex; - flex-flow: column-reverse; - justify-self: center; - width: 100%; -} - -.game-construct .skills button { - width: 100%; -} - -.game-construct .effects { - grid-area: effects; - white-space: nowrap; - width: 100%; - text-align: center; - font-size: 1.5em; -} - -.game-btn { - flex: 0 0 25%; -} - -.game-btn:first-child { - margin-right: 0.5em; -} - -.game-construct button { - color: #888; - flex: 1 1 100%; - padding: 0; - margin: 0 0.5em; - border-width: 0px; -} - -.game-construct button.active { - color: whitesmoke; -} - -.game-construct button[disabled], .game-construct button[disabled]:hover { - color: #333333; - text-decoration: line-through -} - -.game-construct button:hover { - color: whitesmoke; -} - -.game-construct.ko { - animation: none; - opacity: 0.20; -/* filter: grayscale(100%); -*/} - -.game-construct.ko button:hover { - color: #333; -} - -.game-construct.unfocus { - opacity: 0.35; -/* filter: blur(5px); -*/} - -.game-construct.unfocus.ko { - opacity: 0.20; -/* filter: blur(5px) grayscale(100%); -*/} - -.combat-text { - font-size: 2em; - font-family: 'Jura'; - position: absolute; - top: 5%; -} - -.combat-text svg { - height: 7em; - max-width: 100%; -} .combat-anim { - font-size: 2em; - font-family: 'Jura'; + width: 100%; position: absolute; - object-fit: contain; - top: 15%; - max-width: 100%; + display: flex; + flex-flow: column; } .combat-anim svg { - height: 7em; + flex: 1; + // chrome shit width: 100%; + height: 100%; } -.game-construct.active-skill { -/* filter: drop-shadow(0 0 0.2em silver); -*/} - .game-construct.red-damage { color: #a52a2a; /*ensure construct doesn't get opacity lowered because of being KO before the KO animation*/ @@ -319,11 +294,11 @@ object-fit: contain; background-size: contain; background-repeat: no-repeat; - background-position: center; - pointer-events: none; + background-position: top; + // pointer-events: none; } -.resolving .skills button { +.animating .skills { opacity: 0; } diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index ee7a1898..9d3ea05a 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -201,7 +201,7 @@ background-size: contain; background-repeat: no-repeat; background-position: center; - pointer-events: none; + // pointer-events: none; } .name { diff --git a/client/assets/styles/menu.less b/client/assets/styles/menu.less index bafdaa29..a1320161 100644 --- a/client/assets/styles/menu.less +++ b/client/assets/styles/menu.less @@ -55,7 +55,7 @@ background-size: contain; background-repeat: no-repeat; background-position: center; - pointer-events: none; + // pointer-events: none; height: 100%; } } diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index 83ab40d9..29e06109 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -93,6 +93,18 @@ dl { "main ctrl"; padding: 0.5em 1em; + + &.animations-test { + grid-template-columns: 1fr 9fr 1fr; + grid-template-areas: + "nav hdr ctrl" + "nav main ctrl" + "nav main ctrl"; + + nav { + display: initial; + } + } } main { diff --git a/client/manifest.webmanifest b/client/manifest.webmanifest index 1e8a3408..afb2065e 100644 --- a/client/manifest.webmanifest +++ b/client/manifest.webmanifest @@ -4,12 +4,12 @@ "short_name": "mnml", "icons": [ { - "src": "./assets/icons/726.png", + "src": "./assets/icons/mnml.png", "sizes": "32x32", "type": "image/png" }, { - "src": "./assets/icons/726.png", + "src": "./assets/icons/mnml.png", "sizes": "512x512", "type": "image/png" } diff --git a/client/package.json b/client/package.json index f03cab0e..13676814 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.4.5", + "version": "1.4.6", "description": "", "main": "index.js", "scripts": { diff --git a/client/src/animations.socket.jsx b/client/src/animations.socket.jsx index c1567fa5..edd822c6 100644 --- a/client/src/animations.socket.jsx +++ b/client/src/animations.socket.jsx @@ -6,6 +6,7 @@ const eachSeries = require('async/eachSeries'); const actions = require('./actions'); const { TIMES } = require('./constants'); const animations = require('./animations.utils'); +const { removeTier } = require('./utils'); const SOCKET_URL = process.env.NODE_ENV === 'production' ? 'wss://mnml.gg/api/ws' : 'ws://localhost/api/ws'; @@ -28,6 +29,7 @@ function createSocket(store) { if (animating) return false; store.dispatch(actions.setAnimating(true)); + // stop fetching the game state til animations are done return eachSeries(newRes, (r, cb) => { if (['Disable', 'TargetKo'].includes(r.event[0])) return cb(); @@ -37,15 +39,14 @@ function createSocket(store) { const timeout = animations.getTime(sequence); const anims = animations.getObjects(r, sequence, game, account); const text = animations.getText(r, sequence); + store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r, game))); - store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r))); - - if (sequence.includes('START_SKILL')) store.dispatch(actions.setAnimSource(anims.animSource)); - if (sequence.includes('END_SKILL')) { + if (sequence.includes('START_SKILL') && anims.animSource) store.dispatch(actions.setAnimSource(anims.animSource)); + if (sequence.includes('END_SKILL') && anims.animTarget) { store.dispatch(actions.setAnimTarget(anims.animTarget)); - if (!['Banish', 'Invert'].includes(anims.animTarget.skill)) store.dispatch(actions.setAnimCb(cb)); + if (!['Banish', 'Invert'].includes(removeTier(anims.animTarget.skill))) store.dispatch(actions.setAnimCb(cb)); } - if (sequence.includes('POST_SKILL')) { + if (sequence.includes('POST_SKILL' && text)) { // timeout to prevent text classes from being added too soon setTimeout( () => store.dispatch(actions.setAnimText(text)), @@ -58,7 +59,7 @@ function createSocket(store) { store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimFocus([])); if (!sequence.includes('END_SKILL') - || ['Banish', 'Invert'].includes(anims.animTarget.skill)) return cb(); + || ['Banish', 'Invert'].includes(removeTier(anims.animTarget.skill))) return cb(); return true; }, timeout); }, err => { @@ -70,7 +71,6 @@ function createSocket(store) { store.dispatch(actions.setAnimating(false)); store.dispatch(actions.setSkip(false)); - store.dispatch(actions.setResolution(null)); // set the game state so resolutions don't fire twice store.dispatch(actions.setGame(game)); diff --git a/client/src/animations.test.jsx b/client/src/animations.test.jsx index 2127ab35..5a676a23 100644 --- a/client/src/animations.test.jsx +++ b/client/src/animations.test.jsx @@ -55,7 +55,7 @@ document.fonts.load('16pt "Jura"').then(() => { const Animations = () => ( -
+
@@ -69,24 +69,6 @@ document.fonts.load('16pt "Jura"').then(() => { }); const SKILLS = [ - 'Absorb', - 'Absorption', - 'Amplify', - 'Attack', - 'Banish', - 'Bash', - 'Blast', - 'Block', - 'Break', - 'Buff', - 'Chaos', - 'CounterAttack', - 'Counter', - 'Curse', - 'Debuff', - 'Decay', - 'DecayTick', - 'Electrify', 'Electrocute', 'ElectrocuteTick', 'Haste', @@ -113,4 +95,22 @@ const SKILLS = [ 'Sustain', 'Triage', 'TriageTick', + 'Absorb', + 'Absorption', + 'Amplify', + 'Attack', + 'Banish', + 'Bash', + 'Blast', + 'Block', + 'Break', + 'Buff', + 'Chaos', + 'CounterAttack', + 'Counter', + 'Curse', + 'Debuff', + 'Decay', + 'DecayTick', + 'Electrify', ]; diff --git a/client/src/components/anims/strike.jsx b/client/src/components/anims/strike.jsx index 37cac718..00dbbb18 100644 --- a/client/src/components/anims/strike.jsx +++ b/client/src/components/anims/strike.jsx @@ -1,9 +1,9 @@ const preact = require('preact'); const { Component } = require('preact'); -const anime = require('animejs').default; const { connect } = require('preact-redux'); +const anime = require('animejs').default; -const { TIMES } = require('../../constants'); +const { TIMES, COLOURS } = require('../../constants'); const addState = connect( function receiveState(state) { @@ -12,116 +12,74 @@ const addState = connect( } ); -function laser(dimensions, colour) { - const { x, y, length } = dimensions; - return ( - - ); -} - class Strike extends Component { constructor(props) { super(); - this.team = props.team; + this.props = props; this.animations = []; - this.colour = props.colour; - - const coord = [0, 50, 100, 150, 200]; - const points = coord.map(pos => ({ - x: pos + Math.random() * 40, - y: 50 + Math.random() * 100, - length: 150 + Math.random() * 150, - })); - this.charges = points.map(pos => laser(pos, this.colour)); } render() { + // const { x, y } = (this.props && this.props.direction) || { x: 0, y: 0 }; + // const angle = (Math.atan(y / x) * (180 / Math.PI)) + 90; + // console.log(x, -y); + // console.log(angle); + // can't get this shit to work + return ( - - - - - - - - - - + viewBox="0 0 400 400"> + + + - {this.charges} + + + ); } componentDidMount() { - let rotate = 0; // Self target value - if (this.props.direction.y) { - if (!this.props.direction.x) rotate = this.props.direction.y > 0 ? 0 : 180; - else { - rotate = this.props.direction.y > 0 - ? -Math.atan(this.props.direction.y / this.props.direction.x) * 180 / Math.PI - : -Math.atan(this.props.direction.y / this.props.direction.x) * 180 / Math.PI + 180; - } - } else if (this.props.direction.x) { - rotate = this.props.direction.x > 0 ? 270 : 90; - } - anime.set('#strike', { - rotate, - }); - - anime.set('#strike', { - translateY: (window.screen.height) * 0.35 * this.props.direction.y, - translateX: 0, - }); - this.animations.push(anime({ - targets: '#strike', - opacity: [ - { value: 1, delay: TIMES.TARGET_DELAY_MS, duration: TIMES.TARGET_DURATION_MS * 0.2 }, - { value: 0, delay: TIMES.TARGET_DURATION_MS * 0.6, duration: TIMES.TARGET_DURATION_MS * 0.2 }, - ], - easing: 'easeInOutSine', + targets: ['#strike rect'], + easing: 'easeOutExpo', + y: [800, 100, 100], + x: [200, 0, 200], + height: [200, 10, 0], + width: [20, 400, 0], + delay: TIMES.TARGET_DELAY_MS / 2, + duration: TIMES.TARGET_DURATION_MS, })); this.animations.push(anime({ - targets: '#strike', - translateY: 0, - translateX: 0, - loop: false, - delay: TIMES.TARGET_DELAY_MS, - duration: (TIMES.TARGET_DURATION_MS * 1 / 2), - easing: 'easeInQuad', - })); - this.animations.push(anime({ - targets: '#strikeFilter feDisplacementMap', - scale: 200, - loop: false, - delay: (TIMES.TARGET_DELAY_MS + TIMES.TARGET_DURATION_MS * 1 / 4), - easing: 'easeInQuad', + targets: ['#strikeFilter feTurbulence', '#strikeFilter feDisplacementMap'], + baseFrequency: 2, + scale: 50, + numOctaves: 5, + easing: 'easeOutSine', + delay: TIMES.TARGET_DELAY_MS + (TIMES.TARGET_DURATION_MS / 3), + duration: TIMES.TARGET_DURATION_MS / 2, })); } + // this is necessary because + // skipping / timing / unmounting race conditions + // can cause the animations to cut short, this will ensure the values are reset + // because preact will recycle all these components componentWillUnmount() { for (let i = this.animations.length - 1; i >= 0; i--) { this.animations[i].reset(); } this.props.animCb && this.props.animCb(); } + } module.exports = addState(Strike); diff --git a/client/src/components/anims/wiggle.jsx b/client/src/components/anims/wiggle.jsx new file mode 100644 index 00000000..c4f06b9b --- /dev/null +++ b/client/src/components/anims/wiggle.jsx @@ -0,0 +1,21 @@ +const anime = require('animejs').default; + +function wiggle(id, idle) { + const duration = 300; + const target = document.getElementById(id); + const x = (window.screen.width / anime.random(-100, 100)) * 0.1; + const y = (window.screen.height / anime.random(-20, 100)) * 0.1; + return anime({ + targets: target, + rotate: 0, + translateX: [x, -x, 0], + translateY: [y, -y, 0], + duration, + easing: 'easeInOutSine', + // direction: 'alternate', + begin: idle.pause, + complete: idle.restart, + }); +} + +module.exports = wiggle; diff --git a/client/src/components/construct.jsx b/client/src/components/construct.jsx index 964da49c..151b9846 100644 --- a/client/src/components/construct.jsx +++ b/client/src/components/construct.jsx @@ -7,12 +7,14 @@ const { connect } = require('preact-redux'); const banish = require('./anims/banish'); const idleAnimation = require('./anims/idle'); const invert = require('./anims/invert'); +const wiggle = require('./anims/wiggle'); const sourceCast = require('./anims/source.cast'); +const { ConstructAnimation } = require('./animations'); const addState = connect( function receiveState(state) { - const { animSource, animTarget } = state; - return { animSource, animTarget }; + const { animSource, animTarget, animText } = state; + return { animSource, animTarget, animText }; } ); @@ -27,15 +29,22 @@ class ConstructAvatar extends Component { } render() { + const { construct } = this.props; return (
+ id={construct.id} + onClick={this.onClick.bind(this)} + style={{ 'background-image': `url(/imgs/${construct.img}.svg)` }}> + +
); } + onClick() { + return this.animations.push(wiggle(this.props.construct.id, this.idle)); + } + componentDidMount() { this.idle = idleAnimation(this.props.construct.id); return this.animations.push(this.idle); @@ -51,11 +60,17 @@ class ConstructAvatar extends Component { this.resetAnimations(); } - shouldComponentUpdate({ animSource, animTarget, construct }) { + shouldComponentUpdate(newProps) { + const { animSource, animTarget, animText, construct } = newProps; + if (construct !== this.props.construct) { return true; } + if (animText && animText.constructId === construct.id) { + return wiggle(construct.id, this.idle); + } + if (animSource === this.props.animSource && animTarget === this.props.animTarget) { // console.warn(construct.name, 'thinks its same props') return false; @@ -70,6 +85,7 @@ class ConstructAvatar extends Component { return sourceCast(animSource.constructId, animSource.direction, this.idle); } + // this is the target if (animTarget && animTarget.constructId.includes(construct.id)) { // console.warn(construct.name, 'should update') @@ -94,13 +110,13 @@ const addStateText = connect( function constructText(props) { const { construct, animText } = props; - if (!construct || !animText) return false; + if (!construct) return false; - const text = animText.constructId === construct.id + const text = animText && animText.constructId === construct.id ? animText.text - : null; + : construct.name; - return
{text}
; + return

{text}

; } module.exports = { diff --git a/client/src/components/faceoff.jsx b/client/src/components/faceoff.jsx index f7634366..68de5481 100644 --- a/client/src/components/faceoff.jsx +++ b/client/src/components/faceoff.jsx @@ -33,8 +33,11 @@ function FaceoffConstruct(args) { return (
-

{construct.name}

- +
+
+

{construct.name}

+ +
) } diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 8976c78e..ea4db106 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -5,7 +5,6 @@ const range = require('lodash/range'); const { STATS } = require('../utils'); const { ConstructAvatar, ConstructText } = require('./construct'); -const { ConstructAnimation } = require('./animations'); const shapes = require('./shapes'); const SkillBtn = require('./skill.btn'); @@ -95,7 +94,7 @@ class GameConstruct extends Component { .map(j => ); let crypSkills =
 
; - if (player && !animating) crypSkills = (
{skills}
); + if (player) crypSkills = (
{skills}
); const effects = construct.effects.length ? construct.effects.map(c =>
{c.effect} - {c.duration}T
) @@ -106,13 +105,15 @@ class GameConstruct extends Component { onClick={() => selectSkillTarget(construct.id)} style={ activeSkill ? { cursor: 'pointer' } : {}} class={`game-construct ${ko} ${classes}`} > -

{construct.name}

- {crypSkills} -
{stats}
- - - -
{effects}
+
+ {crypSkills} +
{effects}
+
+
+
{stats}
+ + +
); } diff --git a/client/src/components/game.jsx b/client/src/components/game.jsx index 95c34691..88cc3a1d 100644 --- a/client/src/components/game.jsx +++ b/client/src/components/game.jsx @@ -12,7 +12,7 @@ const addState = connect( ws, game, account, - resolution, + animating, activeSkill, activeConstruct, } = state; @@ -32,7 +32,7 @@ const addState = connect( return { game, account, - resolution, + animating, activeSkill, activeConstruct, selectSkillTarget, @@ -57,7 +57,7 @@ function Game(props) { const { game, account, - resolution, + animating, setActiveSkill, setActiveConstruct, } = props; @@ -87,7 +87,7 @@ function Game(props) { ); } - const gameClasses = `game ${resolution ? 'resolving': ''}`; + const gameClasses = `game ${animating ? 'animating' : ''}`; function gameClick(e) { e.stopPropagation(); diff --git a/client/src/components/play.jsx b/client/src/components/play.jsx index b76feb0c..362ed057 100644 --- a/client/src/components/play.jsx +++ b/client/src/components/play.jsx @@ -92,13 +92,14 @@ function Play(args) {

v{VERSION}

-

use the buttons on the right to join an instance.

+

Use the buttons on the right to join an instance.

- select PVP to play against other players.
- click LEARN to practice the game without time controls. + Select PVP to play against other players.
+ Select INVITE then click COPY LINK to generate an instance invitation for a friend.
+ Click LEARN to practice the game without time controls.

- if you enjoy the game please support its development by subscribing or purchasing credits.
+ If you enjoy the game please support its development by subscribing or purchasing credits.
glhf

--ntr & mashy

diff --git a/client/src/components/skill.btn.jsx b/client/src/components/skill.btn.jsx index 3fa23031..d1f39939 100644 --- a/client/src/components/skill.btn.jsx +++ b/client/src/components/skill.btn.jsx @@ -44,7 +44,7 @@ function Skill(props) { return ( ); } diff --git a/client/src/components/targeting.arrows.jsx b/client/src/components/targeting.arrows.jsx index ac087830..6ea195f1 100644 --- a/client/src/components/targeting.arrows.jsx +++ b/client/src/components/targeting.arrows.jsx @@ -17,8 +17,9 @@ class TargetSvg extends Component { this.onResize = throttle(() => { const svg = document.getElementById('targeting'); + if (!svg) return setTimeout(this.onResize, 500); const { width, height } = svg.getBoundingClientRect(); - const path = document.querySelector('#targeting path'); + // const path = document.querySelector('#targeting path'); this.setState({ width, height }); }, 500); } @@ -34,15 +35,7 @@ class TargetSvg extends Component { if (!animTarget) return false; return ( - - - {animTarget.skill} - - +

{animTarget.skill}

); } @@ -59,17 +52,11 @@ class TargetSvg extends Component { ? playerTeam.constructs.findIndex(c => c.id === cast.target_construct_id) : otherTeam.constructs.findIndex(c => c.id === cast.target_construct_id); - const pathOffset = [ - [0, -1, -2], - [1, 0, -1], - [2, 1, 0], - ][source][target]; - const sourceY = height; - const sourceX = (source * width / 3) + width / 6; + const sourceX = (source * width / 3) + width / 24; const targetX = (target * width / 3) + width / 6 + (defensive ? width / 64 : 0) - + (pathOffset * width / 32); + + (source * width / 18); const targetY = defensive ? height : 0; const bendStart = height * (0.7 - 0.1 * source); const bendEnd = height * 0.20; diff --git a/client/src/events.jsx b/client/src/events.jsx index 79b6eed6..05b01677 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -74,12 +74,12 @@ function registerEvents(store) { const text = animations.getText(r, sequence); store.dispatch(actions.setAnimFocus(animations.getFocusTargets(r, game))); - if (sequence.includes('START_SKILL')) store.dispatch(actions.setAnimSource(anims.animSource)); - if (sequence.includes('END_SKILL')) { + if (sequence.includes('START_SKILL') && anims.animSource) store.dispatch(actions.setAnimSource(anims.animSource)); + if (sequence.includes('END_SKILL') && anims.animTarget) { store.dispatch(actions.setAnimTarget(anims.animTarget)); if (!['Banish', 'Invert'].includes(removeTier(anims.animTarget.skill))) store.dispatch(actions.setAnimCb(cb)); } - if (sequence.includes('POST_SKILL')) { + if (sequence.includes('POST_SKILL') && text) { // timeout to prevent text classes from being added too soon setTimeout( () => store.dispatch(actions.setAnimText(text)), diff --git a/client/src/test.game.js b/client/src/test.game.js index e17cb8e0..6ee80a0b 100644 --- a/client/src/test.game.js +++ b/client/src/test.game.js @@ -35,7 +35,7 @@ function testGame(uuid) { "constructs": [ { "id": "82e8b940-411c-42a1-8fc2-484ec7207734", - "img": "8446736d-d682-4588-b8a0-5b7ba53bdb55", + "img": "b1be1dfe-f8b5-4467-8406-11f22ffb9e95", "account": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1", "red_damage": { "base": 256, @@ -109,7 +109,7 @@ function testGame(uuid) { }, { "id": "96ca4a0e-fed2-4ea2-9ec5-ae308f8dde4b", - "img": "8446736d-d682-4588-b8a0-5b7ba53bdb55", + "img": "b1be1dfe-f8b5-4467-8406-11f22ffb9e95", "account": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1", "red_damage": { "base": 256, @@ -186,7 +186,7 @@ function testGame(uuid) { { "id": "ea302c35-d326-475c-a867-8ad5b162165a", "account": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1", - "img": "8446736d-d682-4588-b8a0-5b7ba53bdb55", + "img": "b1be1dfe-f8b5-4467-8406-11f22ffb9e95", "red_damage": { "base": 256, "value": Math.floor(Math.random() * 10000), @@ -302,7 +302,7 @@ function testGame(uuid) { { "id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd", "account": uuid, - "img": "8446736d-d682-4588-b8a0-5b7ba53bdb55", + "img": "b1be1dfe-f8b5-4467-8406-11f22ffb9e95", "red_damage": { "base": 256, "value": Math.floor(Math.random() * 10000), @@ -389,7 +389,7 @@ function testGame(uuid) { { "id": "50e5d94e-8ebe-495c-a916-3eb509ff4683", "account": uuid, - "img": "8446736d-d682-4588-b8a0-5b7ba53bdb55", + "img": "b1be1dfe-f8b5-4467-8406-11f22ffb9e95", "red_damage": { "base": 256, "value": Math.floor(Math.random() * 10000), @@ -470,7 +470,7 @@ function testGame(uuid) { { "id": "5d49fe65-27f0-4372-90a3-334ef906a0f5", "account": uuid, - "img": "8446736d-d682-4588-b8a0-5b7ba53bdb55", + "img": "b1be1dfe-f8b5-4467-8406-11f22ffb9e95", "red_damage": { "base": 256, "value": Math.floor(Math.random() * 10000), diff --git a/ops/package.json b/ops/package.json index 5314c598..a7f08e96 100755 --- a/ops/package.json +++ b/ops/package.json @@ -1,6 +1,6 @@ { "name": "mnml-ops", - "version": "1.4.5", + "version": "1.4.6", "description": "", "main": "index.js", "scripts": { diff --git a/server/Cargo.toml b/server/Cargo.toml index d3970fb5..89ecb188 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml" -version = "1.4.5" +version = "1.4.6" authors = ["ntr "] [dependencies] diff --git a/server/src/construct.rs b/server/src/construct.rs index 2d0e4fe8..80b4d7bb 100644 --- a/server/src/construct.rs +++ b/server/src/construct.rs @@ -46,7 +46,6 @@ impl Colours { #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub struct ConstructSkill { pub skill: Skill, - pub self_targeting: bool, pub cd: Cooldown, // used for Uon client pub disabled: bool, @@ -56,7 +55,6 @@ impl ConstructSkill { pub fn new(skill: Skill) -> ConstructSkill { ConstructSkill { skill, - self_targeting: skill.self_targeting(), cd: skill.base_cd(), disabled: false, } diff --git a/server/src/effect.rs b/server/src/effect.rs index 83c445d9..1e959e50 100644 --- a/server/src/effect.rs +++ b/server/src/effect.rs @@ -13,7 +13,6 @@ pub enum Effect { Sustain, Curse, Haste, - Hex, Hybrid, Invert, Counter, @@ -38,7 +37,6 @@ pub enum Effect { Absorption, // magic immunity - Link, // effects over time Triage, @@ -66,17 +64,9 @@ pub enum Effect { impl Effect { pub fn immune(&self, skill: Skill) -> bool { match self { - Effect::Counter => match skill { - Skill::Attack => true, - Skill::Stun => true, - _ => skill.colours().contains(&Colour::Red) - }, Effect::Banish => true, Effect::Sustain => [ Skill::Stun, - Skill::Hex, - Skill::HexPlus, - Skill::HexPlusPlus, Skill::Silence, Skill::SilencePlus, Skill::SilencePlusPlus, @@ -98,7 +88,6 @@ impl Effect { match self { Effect::Stun => true, - Effect::Hex => true, Effect::Banish => true, Effect::Silence => skill.colours().contains(&Colour::Blue), Effect::Restrict => skill.colours().contains(&Colour::Red), @@ -125,8 +114,6 @@ impl Effect { Effect::Haste => vec![Stat::Speed], Effect::Slow => vec![Stat::Speed], - Effect::Link => vec![Stat::BlueDamageTaken, Stat::GreenDamageTaken, Stat::RedDamageTaken], - _ => vec![], } } @@ -146,15 +133,13 @@ impl Effect { _ => 100, }), - Effect::Link => value >> 1, - Effect::Absorption => value + match meta { Some(EffectMeta::AddedDamage(d)) => d, _ => panic!("absorb meta not damage"), }, _ => { - info!("{:?} does not have a mod effect", self); + warn!("{:?} does not have a mod effect", self); return value; }, } @@ -173,7 +158,6 @@ impl Effect { Effect::Intercept => Some(Colour::Green), // magic - Effect::Hex => Some(Colour::Blue), Effect::Curse => Some(Colour::Blue), Effect::Banish => None, // Effect::Banish => rng.gen_bool(0.5), @@ -194,7 +178,6 @@ impl Effect { // magic Effect::Hybrid => Some(Colour::Green), - Effect::Link => Some(Colour::Green), Effect::Invert => Some(Colour::Green), // effects over time diff --git a/server/src/game.rs b/server/src/game.rs index caeb1e61..222ab0f6 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -236,7 +236,7 @@ impl Game { target = find_target(); } - pve_skills.push((mobs.id, mob.id, Some(target.id), s)); + pve_skills.push((mobs.id, mob.id, target.id, s)); }, None => continue, }; @@ -258,7 +258,7 @@ impl Game { self } - fn add_skill(&mut self, player_id: Uuid, source_construct_id: Uuid, target_construct_id: Option, skill: Skill) -> Result<&mut Game, Error> { + fn add_skill(&mut self, player_id: Uuid, source_construct_id: Uuid, target_construct_id: Uuid, skill: Skill) -> Result<&mut Game, Error> { // check player in game self.player_by_id(player_id)?; @@ -266,17 +266,9 @@ impl Game { return Err(err_msg("game not in skill phase")); } - let final_target_id = match skill.self_targeting() { - true => source_construct_id, - false => match target_construct_id { - Some(t) => t, - None => return Err(err_msg("skill requires a target")), - } - }; - // target checks { - let target = match self.construct_by_id(final_target_id) { + let target = match self.construct_by_id(target_construct_id) { Some(c) => c, None => return Err(err_msg("target construct not in game")), }; @@ -318,7 +310,7 @@ impl Game { self.stack.remove(s); } - let skill = Cast::new(source_construct_id, player_id, final_target_id, skill); + let skill = Cast::new(source_construct_id, player_id, target_construct_id, skill); self.stack.push(skill); return Ok(self); @@ -887,7 +879,7 @@ fn game_json_file_write(g: &Game) -> Result { Ok(dest) } -pub fn game_skill(tx: &mut Transaction, account: &Account, game_id: Uuid, construct_id: Uuid, target_construct_id: Option, skill: Skill) -> Result { +pub fn game_skill(tx: &mut Transaction, account: &Account, game_id: Uuid, construct_id: Uuid, target_construct_id: Uuid, skill: Skill) -> Result { let mut game = game_get(tx, game_id)?; game.add_skill(account.id, construct_id, target_construct_id, skill)?; @@ -1039,8 +1031,8 @@ mod tests { let x_construct = x_player.constructs[0].clone(); let y_construct = y_player.constructs[0].clone(); - game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Attack).unwrap(); - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Attack).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); @@ -1068,8 +1060,8 @@ mod tests { game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); } - game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Stun).unwrap(); - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Stun).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); @@ -1105,8 +1097,8 @@ mod tests { // remove all mitigation game.player_by_id(x_player.id).unwrap().construct_by_id(x_construct.id).unwrap().red_life.force(0); - game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Stun).unwrap(); - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Stun).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); @@ -1135,8 +1127,8 @@ mod tests { assert!(game.player_by_id(y_player.id).unwrap().constructs[0].skill_on_cd(Skill::Stun).is_some()); assert!(game.player_by_id(x_player.id).unwrap().constructs[0].skill_on_cd(Skill::Block).is_none()); - game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Attack).unwrap(); - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Attack).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); @@ -1149,8 +1141,8 @@ mod tests { // second round // now we block and it should go back on cd - // game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Stun).unwrap(); - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); + // game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Stun).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); @@ -1179,15 +1171,15 @@ mod tests { game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); } - game.add_skill(x_player.id, x_construct.id, None, Skill::Counter).unwrap(); - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Stun).unwrap(); + game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Counter).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); - // should not be stunned because of counter + // don't get stunned but not really stunning ¯\_(ツ)_/¯ assert!(game.player_by_id(x_player.id).unwrap().constructs[0].is_stunned() == false); // riposte assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), ( @@ -1214,14 +1206,14 @@ mod tests { } // apply buff - game.add_skill(x_player.id, x_construct.id, Some(x_construct.id), Skill::Electrify).unwrap(); + game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Electrify).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); - game = game.resolve_phase_start(); - assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Electric)); + // game = game.resolve_phase_start(); + // assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Electric)); // attack and receive debuff - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); + game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); @@ -1229,55 +1221,55 @@ mod tests { assert!(game.construct_by_id(y_construct.id).unwrap().affected(Effect::Electrocute)); } - #[test] - fn link_test() { - let mut game = create_test_game(); + // #[test] + // fn link_test() { + // let mut game = create_test_game(); - let x_player = game.players[0].clone(); - let y_player = game.players[1].clone(); + // let x_player = game.players[0].clone(); + // let y_player = game.players[1].clone(); - let x_construct = x_player.constructs[0].clone(); - let y_construct = y_player.constructs[0].clone(); + // let x_construct = x_player.constructs[0].clone(); + // let y_construct = y_player.constructs[0].clone(); - game.construct_by_id(x_construct.id).unwrap().learn_mut(Skill::Link); + // game.construct_by_id(x_construct.id).unwrap().learn_mut(Skill::Link); - while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::Link).is_some() { - game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); - } + // while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::Link).is_some() { + // game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); + // } - // apply buff - game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Link).unwrap(); - game.player_ready(x_player.id).unwrap(); - game.player_ready(y_player.id).unwrap(); - game = game.resolve_phase_start(); - assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Link)); + // // apply buff + // game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Link).unwrap(); + // game.player_ready(x_player.id).unwrap(); + // game.player_ready(y_player.id).unwrap(); + // game = game.resolve_phase_start(); + // assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Link)); - let Resolution { source: _, target: _, event, stages: _ } = game.resolved.pop().unwrap(); - match event { - Event::Effect { effect, skill: _, duration: _, construct_effects: _ } => assert_eq!(effect, Effect::Link), - _ => panic!("not siphon"), - }; + // let Resolution { source: _, target: _, event, stages: _ } = game.resolved.pop().unwrap(); + // match event { + // Event::Effect { effect, skill: _, duration: _, construct_effects: _ } => assert_eq!(effect, Effect::Link), + // _ => panic!("not siphon"), + // }; - let Resolution { source: _, target: _, event, stages: _ } = game.resolved.pop().unwrap(); - match event { - Event::Recharge { red: _, blue: _, skill: _ } => (), - _ => panic!("link result was not recharge"), - } + // let Resolution { source: _, target: _, event, stages: _ } = game.resolved.pop().unwrap(); + // match event { + // Event::Recharge { red: _, blue: _, skill: _ } => (), + // _ => panic!("link result was not recharge"), + // } - // attack and receive link hit - game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.player_ready(x_player.id).unwrap(); - game.player_ready(y_player.id).unwrap(); - game = game.resolve_phase_start(); + // // attack and receive link hit + // game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::Attack).unwrap(); + // game.player_ready(x_player.id).unwrap(); + // game.player_ready(y_player.id).unwrap(); + // game = game.resolve_phase_start(); - let Resolution { source: _, target, event, stages: _ } = game.resolved.pop().unwrap(); - assert_eq!(target.id, y_construct.id); - match event { - Event::Damage { amount, skill: _, mitigation: _, colour: _} => - assert_eq!(amount, x_construct.red_power().pct(Skill::Attack.multiplier()) >> 1), - _ => panic!("not damage link"), - }; - } + // let Resolution { source: _, target, event, stages: _ } = game.resolved.pop().unwrap(); + // assert_eq!(target.id, y_construct.id); + // match event { + // Event::Damage { amount, skill: _, mitigation: _, colour: _} => + // assert_eq!(amount, x_construct.red_power().pct(Skill::Attack.multiplier()) >> 1), + // _ => panic!("not damage link"), + // }; + // } // #[test] // fn absorb_test() { @@ -1296,14 +1288,14 @@ mod tests { // } // // apply buff - // game.add_skill(x_player.id, x_construct.id, Some(x_construct.id), Skill::Absorb).unwrap(); + // game.add_skill(x_player.id, x_construct.id, x_construct.id, Skill::Absorb).unwrap(); // game.player_ready(x_player.id).unwrap(); // game.player_ready(y_player.id).unwrap(); // game = game.resolve_phase_start(); // assert!(game.construct_by_id(x_construct.id).unwrap().affected(Effect::Absorb)); // // attack and receive debuff - // game.add_skill(y_player.id, y_construct.id, Some(x_construct.id), Skill::TestAttack).unwrap(); + // game.add_skill(y_player.id, y_construct.id, x_construct.id, Skill::TestAttack).unwrap(); // game.player_ready(x_player.id).unwrap(); // game.player_ready(y_player.id).unwrap(); // game = game.resolve_phase_start(); @@ -1330,10 +1322,10 @@ mod tests { game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); } - game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Ruin).unwrap(); - game.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap(); + game.add_skill(i_player.id, i_construct.id, x_construct.id, Skill::Attack).unwrap(); + game.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Ruin).unwrap(); + game.add_skill(x_player.id, y_construct.id, i_construct.id, Skill::Attack).unwrap(); game.player_ready(i_player.id).unwrap(); game.player_ready(x_player.id).unwrap(); @@ -1380,10 +1372,10 @@ mod tests { game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); } - game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Intercept).unwrap(); - game.add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap(); + game.add_skill(i_player.id, i_construct.id, x_construct.id, Skill::Attack).unwrap(); + game.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Intercept).unwrap(); + game.add_skill(x_player.id, y_construct.id, i_construct.id, Skill::Attack).unwrap(); game.player_ready(i_player.id).unwrap(); game.player_ready(x_player.id).unwrap(); @@ -1411,10 +1403,10 @@ mod tests { let x_construct = x_player.constructs[0].clone(); let y_construct = x_player.constructs[1].clone(); - game.add_skill(i_player.id, i_construct.id, Some(x_construct.id), Skill::Attack).unwrap() - .add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap() - .add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Attack).unwrap() - .add_skill(x_player.id, y_construct.id, Some(i_construct.id), Skill::Attack).unwrap() + game.add_skill(i_player.id, i_construct.id, x_construct.id, Skill::Attack).unwrap() + .add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap() + .add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Attack).unwrap() + .add_skill(x_player.id, y_construct.id, i_construct.id, Skill::Attack).unwrap() .player_ready(i_player.id).unwrap() .player_ready(x_player.id).unwrap(); @@ -1430,10 +1422,10 @@ mod tests { assert!(game.player_by_id(x_player.id).unwrap().skills_required() == 2); // add some more skills - game.add_skill(i_player.id, j_construct.id, Some(x_construct.id), Skill::Attack).unwrap(); - game.add_skill(x_player.id, x_construct.id, Some(j_construct.id), Skill::Attack).unwrap(); - game.add_skill(x_player.id, y_construct.id, Some(j_construct.id), Skill::Attack).unwrap(); - assert!(game.add_skill(x_player.id, x_construct.id, Some(i_construct.id), Skill::Attack).is_err()); + game.add_skill(i_player.id, j_construct.id, x_construct.id, Skill::Attack).unwrap(); + game.add_skill(x_player.id, x_construct.id, j_construct.id, Skill::Attack).unwrap(); + game.add_skill(x_player.id, y_construct.id, j_construct.id, Skill::Attack).unwrap(); + assert!(game.add_skill(x_player.id, x_construct.id, i_construct.id, Skill::Attack).is_err()); game.player_ready(i_player.id).unwrap(); game.player_ready(x_player.id).unwrap(); @@ -1475,7 +1467,7 @@ mod tests { } // apply buff - game.add_skill(x_player.id, x_construct.id, Some(y_construct.id), Skill::Decay).unwrap(); + game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Decay).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); @@ -1490,7 +1482,7 @@ mod tests { game.resolved.clear(); // remove - game.add_skill(y_player.id, y_construct.id, Some(y_construct.id), Skill::Purify).unwrap(); + game.add_skill(y_player.id, y_construct.id, y_construct.id, Skill::Purify).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); @@ -1503,14 +1495,14 @@ mod tests { } }; - game.add_skill(y_player.id, x_construct.id, Some(y_construct.id), Skill::Siphon).unwrap(); + game.add_skill(y_player.id, x_construct.id, y_construct.id, Skill::Siphon).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); game.resolved.clear(); - game.add_skill(y_player.id, y_construct.id, Some(y_construct.id), Skill::Purify).unwrap(); + game.add_skill(y_player.id, y_construct.id, y_construct.id, Skill::Purify).unwrap(); game.player_ready(x_player.id).unwrap(); game.player_ready(y_player.id).unwrap(); game = game.resolve_phase_start(); diff --git a/server/src/img.rs b/server/src/img.rs index 3fc746b3..d4c92bad 100644 --- a/server/src/img.rs +++ b/server/src/img.rs @@ -273,12 +273,12 @@ mod tests { // hieroglyph(); // } - #[test] - fn shapes_img_test() { - for i in 0..100 { - shapes_write(Uuid::new_v4()).unwrap(); - } - } + // #[test] + // fn shapes_img_test() { + // for i in 0..100 { + // shapes_write(Uuid::new_v4()).unwrap(); + // } + // } } diff --git a/server/src/item.rs b/server/src/item.rs index 55c883f9..928a2850 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -143,12 +143,6 @@ pub enum Item { #[serde(rename = "Decay++")] DecayPlusPlus, - Hex, - #[serde(rename = "Hex+")] - HexPlus, - #[serde(rename = "Hex++")] - HexPlusPlus, - Haste, #[serde(rename = "Haste+")] HastePlus, @@ -385,102 +379,102 @@ impl Item { pub fn into_skill(&self) -> Option { match self { - Item::Absorb => Some(Skill::Absorb), - Item::AbsorbPlus => Some(Skill::AbsorbPlus), - Item::AbsorbPlusPlus => Some(Skill::AbsorbPlusPlus), - Item::Amplify => Some(Skill::Amplify), - Item::AmplifyPlus => Some(Skill::AmplifyPlus), - Item::AmplifyPlusPlus => Some(Skill::AmplifyPlusPlus), - Item::Attack => Some(Skill::Attack), - Item::Banish => Some(Skill::Banish), - Item::BanishPlus => Some(Skill::BanishPlus), - Item::BanishPlusPlus => Some(Skill::BanishPlusPlus), - Item::Bash => Some(Skill::Bash), - Item::BashPlus => Some(Skill::BashPlus), - Item::BashPlusPlus => Some(Skill::BashPlusPlus), - Item::Blast => Some(Skill::Blast), - Item::BlastPlus => Some(Skill::BlastPlus), - Item::BlastPlusPlus => Some(Skill::BlastPlusPlus), - Item::Block => Some(Skill::Block), - Item::Buff => Some(Skill::Buff), - Item::Chaos => Some(Skill::Chaos), - Item::ChaosPlus => Some(Skill::ChaosPlus), - Item::ChaosPlusPlus => Some(Skill::ChaosPlusPlus), - Item::Counter => Some(Skill::Counter), - Item::CounterPlus => Some(Skill::CounterPlus), - Item::CounterPlusPlus => Some(Skill::CounterPlusPlus), - Item::Curse => Some(Skill::Curse), - Item::CursePlus => Some(Skill::CursePlus), - Item::CursePlusPlus => Some(Skill::CursePlusPlus), - Item::Debuff => Some(Skill::Debuff), - Item::Decay => Some(Skill::Decay), - Item::DecayPlus => Some(Skill::DecayPlus), - Item::DecayPlusPlus => Some(Skill::DecayPlusPlus), - Item::Electrify => Some(Skill::Electrify), - Item::ElectrifyPlus => Some(Skill::ElectrifyPlus), - Item::ElectrifyPlusPlus => Some(Skill::ElectrifyPlusPlus), - Item::Haste => Some(Skill::Haste), - Item::HastePlus => Some(Skill::HastePlus), - Item::HastePlusPlus => Some(Skill::HastePlusPlus), - Item::Heal => Some(Skill::Heal), - Item::HealPlus => Some(Skill::HealPlus), - Item::HealPlusPlus => Some(Skill::HealPlusPlus), - Item::Hybrid => Some(Skill::Hybrid), - Item::HybridPlus => Some(Skill::HybridPlus), - Item::HybridPlusPlus => Some(Skill::HybridPlusPlus), - Item::Intercept => Some(Skill::Intercept), - Item::InterceptPlus => Some(Skill::InterceptPlus), - Item::InterceptPlusPlus => Some(Skill::InterceptPlusPlus), - Item::Invert => Some(Skill::Invert), - Item::InvertPlus => Some(Skill::InvertPlus), - Item::InvertPlusPlus => Some(Skill::InvertPlusPlus), - Item::Purge => Some(Skill::Purge), - Item::PurgePlus => Some(Skill::PurgePlus), - Item::PurgePlusPlus => Some(Skill::PurgePlusPlus), - Item::Purify => Some(Skill::Purify), - Item::PurifyPlus => Some(Skill::PurifyPlus), - Item::PurifyPlusPlus => Some(Skill::PurifyPlusPlus), - Item::Recharge => Some(Skill::Recharge), - Item::RechargePlus => Some(Skill::RechargePlus), - Item::RechargePlusPlus => Some(Skill::RechargePlusPlus), - Item::Reflect => Some(Skill::Reflect), - Item::ReflectPlus => Some(Skill::ReflectPlus), - Item::ReflectPlusPlus => Some(Skill::ReflectPlusPlus), - Item::Restrict => Some(Skill::Restrict), - Item::RestrictPlus => Some(Skill::RestrictPlus), - Item::RestrictPlusPlus => Some(Skill::RestrictPlusPlus), - Item::Ruin => Some(Skill::Ruin), - Item::RuinPlus => Some(Skill::RuinPlus), - Item::RuinPlusPlus => Some(Skill::RuinPlusPlus), - Item::Link => Some(Skill::Link), - Item::LinkPlus => Some(Skill::LinkPlus), - Item::LinkPlusPlus => Some(Skill::LinkPlusPlus), - Item::Silence => Some(Skill::Silence), - Item::SilencePlus => Some(Skill::SilencePlus), - Item::SilencePlusPlus => Some(Skill::SilencePlusPlus), - Item::Siphon => Some(Skill::Siphon), - Item::SiphonPlus => Some(Skill::SiphonPlus), - Item::SiphonPlusPlus => Some(Skill::SiphonPlusPlus), - Item::Slay => Some(Skill::Slay), - Item::SlayPlus => Some(Skill::SlayPlus), - Item::SlayPlusPlus => Some(Skill::SlayPlusPlus), - Item::Sleep => Some(Skill::Sleep), - Item::SleepPlus => Some(Skill::SleepPlus), - Item::SleepPlusPlus => Some(Skill::SleepPlusPlus), - Item::Strike => Some(Skill::Strike), - Item::StrikePlus => Some(Skill::StrikePlus), - Item::StrikePlusPlus => Some(Skill::StrikePlusPlus), - Item::Stun => Some(Skill::Stun), - Item::Sustain => Some(Skill::Sustain), - Item::SustainPlus => Some(Skill::SustainPlus), - Item::SustainPlusPlus => Some(Skill::SustainPlusPlus), - Item::Break => Some(Skill::Break), - Item::BreakPlus => Some(Skill::BreakPlus), - Item::BreakPlusPlus => Some(Skill::BreakPlusPlus), - Item::Triage => Some(Skill::Triage), - Item::TriagePlus => Some(Skill::TriagePlus), - Item::TriagePlusPlus => Some(Skill::TriagePlusPlus), - _ => None, + Item::Absorb => Some(Skill::Absorb), + Item::AbsorbPlus => Some(Skill::AbsorbPlus), + Item::AbsorbPlusPlus => Some(Skill::AbsorbPlusPlus), + Item::Amplify => Some(Skill::Amplify), + Item::AmplifyPlus => Some(Skill::AmplifyPlus), + Item::AmplifyPlusPlus => Some(Skill::AmplifyPlusPlus), + Item::Attack => Some(Skill::Attack), + Item::Banish => Some(Skill::Banish), + Item::BanishPlus => Some(Skill::BanishPlus), + Item::BanishPlusPlus => Some(Skill::BanishPlusPlus), + Item::Bash => Some(Skill::Bash), + Item::BashPlus => Some(Skill::BashPlus), + Item::BashPlusPlus => Some(Skill::BashPlusPlus), + Item::Blast => Some(Skill::Blast), + Item::BlastPlus => Some(Skill::BlastPlus), + Item::BlastPlusPlus => Some(Skill::BlastPlusPlus), + Item::Block => Some(Skill::Block), + Item::Buff => Some(Skill::Buff), + Item::Chaos => Some(Skill::Chaos), + Item::ChaosPlus => Some(Skill::ChaosPlus), + Item::ChaosPlusPlus => Some(Skill::ChaosPlusPlus), + Item::Counter => Some(Skill::Counter), + Item::CounterPlus => Some(Skill::CounterPlus), + Item::CounterPlusPlus => Some(Skill::CounterPlusPlus), + Item::Curse => Some(Skill::Curse), + Item::CursePlus => Some(Skill::CursePlus), + Item::CursePlusPlus => Some(Skill::CursePlusPlus), + Item::Debuff => Some(Skill::Debuff), + Item::Decay => Some(Skill::Decay), + Item::DecayPlus => Some(Skill::DecayPlus), + Item::DecayPlusPlus => Some(Skill::DecayPlusPlus), + Item::Electrify => Some(Skill::Electrify), + Item::ElectrifyPlus => Some(Skill::ElectrifyPlus), + Item::ElectrifyPlusPlus => Some(Skill::ElectrifyPlusPlus), + Item::Haste => Some(Skill::Haste), + Item::HastePlus => Some(Skill::HastePlus), + Item::HastePlusPlus => Some(Skill::HastePlusPlus), + Item::Heal => Some(Skill::Heal), + Item::HealPlus => Some(Skill::HealPlus), + Item::HealPlusPlus => Some(Skill::HealPlusPlus), + Item::Hybrid => Some(Skill::Hybrid), + Item::HybridPlus => Some(Skill::HybridPlus), + Item::HybridPlusPlus => Some(Skill::HybridPlusPlus), + Item::Intercept => Some(Skill::Intercept), + Item::InterceptPlus => Some(Skill::InterceptPlus), + Item::InterceptPlusPlus => Some(Skill::InterceptPlusPlus), + Item::Invert => Some(Skill::Invert), + Item::InvertPlus => Some(Skill::InvertPlus), + Item::InvertPlusPlus => Some(Skill::InvertPlusPlus), + Item::Purge => Some(Skill::Purge), + Item::PurgePlus => Some(Skill::PurgePlus), + Item::PurgePlusPlus => Some(Skill::PurgePlusPlus), + Item::Purify => Some(Skill::Purify), + Item::PurifyPlus => Some(Skill::PurifyPlus), + Item::PurifyPlusPlus => Some(Skill::PurifyPlusPlus), + Item::Recharge => Some(Skill::Recharge), + Item::RechargePlus => Some(Skill::RechargePlus), + Item::RechargePlusPlus => Some(Skill::RechargePlusPlus), + Item::Reflect => Some(Skill::Reflect), + Item::ReflectPlus => Some(Skill::ReflectPlus), + Item::ReflectPlusPlus => Some(Skill::ReflectPlusPlus), + Item::Restrict => Some(Skill::Restrict), + Item::RestrictPlus => Some(Skill::RestrictPlus), + Item::RestrictPlusPlus => Some(Skill::RestrictPlusPlus), + Item::Ruin => Some(Skill::Ruin), + Item::RuinPlus => Some(Skill::RuinPlus), + Item::RuinPlusPlus => Some(Skill::RuinPlusPlus), + Item::Link => Some(Skill::Link), + Item::LinkPlus => Some(Skill::LinkPlus), + Item::LinkPlusPlus => Some(Skill::LinkPlusPlus), + Item::Silence => Some(Skill::Silence), + Item::SilencePlus => Some(Skill::SilencePlus), + Item::SilencePlusPlus => Some(Skill::SilencePlusPlus), + Item::Siphon => Some(Skill::Siphon), + Item::SiphonPlus => Some(Skill::SiphonPlus), + Item::SiphonPlusPlus => Some(Skill::SiphonPlusPlus), + Item::Slay => Some(Skill::Slay), + Item::SlayPlus => Some(Skill::SlayPlus), + Item::SlayPlusPlus => Some(Skill::SlayPlusPlus), + Item::Sleep => Some(Skill::Sleep), + Item::SleepPlus => Some(Skill::SleepPlus), + Item::SleepPlusPlus => Some(Skill::SleepPlusPlus), + Item::Strike => Some(Skill::Strike), + Item::StrikePlus => Some(Skill::StrikePlus), + Item::StrikePlusPlus => Some(Skill::StrikePlusPlus), + Item::Stun => Some(Skill::Stun), + Item::Sustain => Some(Skill::Sustain), + Item::SustainPlus => Some(Skill::SustainPlus), + Item::SustainPlusPlus => Some(Skill::SustainPlusPlus), + Item::Break => Some(Skill::Break), + Item::BreakPlus => Some(Skill::BreakPlus), + Item::BreakPlusPlus => Some(Skill::BreakPlusPlus), + Item::Triage => Some(Skill::Triage), + Item::TriagePlus => Some(Skill::TriagePlus), + Item::TriagePlusPlus => Some(Skill::TriagePlusPlus), + _ => None, } } @@ -726,12 +720,6 @@ impl Item { Item::HealPlus | Item::HealPlusPlus => format!("Heals target for {:?}% GreenPower.", self.into_skill().unwrap().multiplier()), - Item::Hex| - Item::HexPlus | - Item::HexPlusPlus => format!("Blue based skill that applies Hex for {:?}T. \ - Hexed targets cannot cast any skills.", - self.into_skill().unwrap().effect()[0].get_duration()), - Item::Hybrid| Item::HybridPlus | Item::HybridPlusPlus => format!( @@ -785,9 +773,11 @@ impl Item { Item::Link| Item::LinkPlus | Item::LinkPlusPlus => format!( - "Caster links with target. Linked constructs split incoming Damage evenly. - Recharges target BlueLife based on {:?}% of BluePower", - self.into_skill().unwrap().multiplier()), + "Form a link with target swapping relative life values. + If the target construct has more green life than caster, {:?}% of green life difference as blue damage to the target and heal to the caster. + Stuns caster for {:?}T in the process.", + self.into_skill().unwrap().multiplier(), + self.into_skill().unwrap().effect()[0].get_duration()), Item::Silence| Item::SilencePlus | @@ -813,10 +803,9 @@ impl Item { Item::Restrict| Item::RestrictPlus | Item::RestrictPlusPlus => format!( - "Block the target from using red skills for {:?}T and deals {:?}% RedPower as red damage. {}", + "Block the target from using red skills for {:?}T and deals {:?}% RedPower as red damage. Deals 35% more damage per red skill on target", self.into_skill().unwrap().effect()[0].get_duration(), - self.into_skill().unwrap().multiplier(), - "Deals 35% more damage per red skill on target"), + self.into_skill().unwrap().multiplier()), Item::Bash| Item::BashPlus | @@ -865,161 +854,157 @@ impl Item { fn combo(&self) -> Vec { match self { - Item::Intercept => vec![Item::Buff, Item::Red, Item::Red], - Item::InterceptPlus => vec![Item::Intercept, Item::Intercept, Item::Intercept], - Item::InterceptPlusPlus => vec![Item::InterceptPlus, Item::InterceptPlus, Item::InterceptPlus], - Item::Triage => vec![Item::Buff, Item::Green, Item::Green], - Item::TriagePlus => vec![Item::Triage, Item::Triage, Item::Triage], - Item::TriagePlusPlus => vec![Item::TriagePlus, Item::TriagePlus, Item::TriagePlus], - Item::Link => vec![Item::Buff, Item::Blue, Item::Blue], - Item::LinkPlus => vec![Item::Link, Item::Link, Item::Link], - Item::LinkPlusPlus => vec![Item::LinkPlusPlus, Item::LinkPlusPlus, Item::LinkPlusPlus], - Item::Haste => vec![Item::Buff, Item::Red, Item::Green], - Item::HastePlus => vec![Item::Haste, Item::Haste, Item::Haste], - Item::HastePlusPlus => vec![Item::HastePlus, Item::HastePlus, Item::HastePlus], - Item::Hybrid => vec![Item::Buff, Item::Green, Item::Blue], - Item::HybridPlus => vec![Item::Hybrid, Item::Hybrid, Item::Hybrid], - Item::HybridPlusPlus => vec![Item::HybridPlus, Item::HybridPlus, Item::HybridPlus], - Item::Amplify => vec![Item::Buff, Item::Red, Item::Blue], - Item::AmplifyPlus => vec![Item::Amplify, Item::Amplify, Item::Amplify], - Item::AmplifyPlusPlus => vec![Item::AmplifyPlus, Item::AmplifyPlus, Item::AmplifyPlus], + Item::Intercept => vec![Item::Buff, Item::Red, Item::Red], + Item::Triage => vec![Item::Buff, Item::Green, Item::Green], + Item::Absorb => vec![Item::Buff, Item::Blue, Item::Blue], + Item::Amplify => vec![Item::Buff, Item::Red, Item::Blue], + Item::Haste => vec![Item::Buff, Item::Red, Item::Green], + Item::Hybrid => vec![Item::Buff, Item::Green, Item::Blue], + Item::InterceptPlus => vec![Item::Intercept, Item::Intercept, Item::Intercept], + Item::InterceptPlusPlus => vec![Item::InterceptPlus, Item::InterceptPlus, Item::InterceptPlus], + Item::TriagePlus => vec![Item::Triage, Item::Triage, Item::Triage], + Item::TriagePlusPlus => vec![Item::TriagePlus, Item::TriagePlus, Item::TriagePlus], + Item::HastePlus => vec![Item::Haste, Item::Haste, Item::Haste], + Item::HastePlusPlus => vec![Item::HastePlus, Item::HastePlus, Item::HastePlus], + Item::HybridPlus => vec![Item::Hybrid, Item::Hybrid, Item::Hybrid], + Item::HybridPlusPlus => vec![Item::HybridPlus, Item::HybridPlus, Item::HybridPlus], + Item::AbsorbPlus => vec![Item::Absorb, Item::Absorb, Item::Absorb], + Item::AbsorbPlusPlus => vec![Item::AbsorbPlus, Item::AbsorbPlus, Item::AbsorbPlus], + Item::AmplifyPlus => vec![Item::Amplify, Item::Amplify, Item::Amplify], + Item::AmplifyPlusPlus => vec![Item::AmplifyPlus, Item::AmplifyPlus, Item::AmplifyPlus], - Item::Restrict => vec![Item::Debuff, Item::Red, Item::Red], - Item::RestrictPlus => vec![Item::Restrict, Item::Restrict, Item::Restrict], - Item::RestrictPlusPlus => vec![Item::RestrictPlus, Item::RestrictPlus, Item::RestrictPlus], - Item::Purge => vec![Item::Debuff, Item::Green, Item::Green], // Needs flavour - Item::PurgePlus => vec![Item::Purge, Item::Purge, Item::Purge], // Needs flavour - Item::PurgePlusPlus => vec![Item::PurgePlus, Item::PurgePlus, Item::PurgePlus], // Needs flavour - Item::Silence => vec![Item::Debuff, Item::Blue, Item::Blue], - Item::SilencePlus => vec![Item::Silence, Item::Silence, Item::Silence], - Item::SilencePlusPlus => vec![Item::SilencePlus, Item::SilencePlus, Item::SilencePlus], - Item::Curse => vec![Item::Debuff, Item::Red, Item::Green], - Item::CursePlus => vec![Item::Curse, Item::Curse, Item::Curse], - Item::CursePlusPlus => vec![Item::CursePlus, Item::CursePlus, Item::CursePlus], - Item::Decay => vec![Item::Debuff, Item::Green, Item::Blue], - Item::DecayPlus => vec![Item::Decay, Item::Decay, Item::Decay], - Item::DecayPlusPlus => vec![Item::DecayPlus, Item::DecayPlus, Item::DecayPlus], - Item::Invert => vec![Item::Debuff, Item::Red, Item::Blue], - Item::InvertPlus => vec![Item::Invert, Item::Invert, Item::Invert], - Item::InvertPlusPlus => vec![Item::InvertPlus, Item::InvertPlus, Item::InvertPlus], + Item::Purge => vec![Item::Debuff, Item::Green, Item::Green], // Needs flavour + Item::Invert => vec![Item::Debuff, Item::Red, Item::Blue], + Item::Restrict => vec![Item::Debuff, Item::Red, Item::Red], + Item::Silence => vec![Item::Debuff, Item::Blue, Item::Blue], + Item::Curse => vec![Item::Debuff, Item::Red, Item::Green], + Item::Decay => vec![Item::Debuff, Item::Green, Item::Blue], + Item::RestrictPlus => vec![Item::Restrict, Item::Restrict, Item::Restrict], + Item::RestrictPlusPlus => vec![Item::RestrictPlus, Item::RestrictPlus, Item::RestrictPlus], + Item::PurgePlus => vec![Item::Purge, Item::Purge, Item::Purge], // Needs flavour + Item::PurgePlusPlus => vec![Item::PurgePlus, Item::PurgePlus, Item::PurgePlus], // Needs flavour + Item::SilencePlus => vec![Item::Silence, Item::Silence, Item::Silence], + Item::SilencePlusPlus => vec![Item::SilencePlus, Item::SilencePlus, Item::SilencePlus], + Item::CursePlus => vec![Item::Curse, Item::Curse, Item::Curse], + Item::CursePlusPlus => vec![Item::CursePlus, Item::CursePlus, Item::CursePlus], + Item::DecayPlus => vec![Item::Decay, Item::Decay, Item::Decay], + Item::DecayPlusPlus => vec![Item::DecayPlus, Item::DecayPlus, Item::DecayPlus], + Item::InvertPlus => vec![Item::Invert, Item::Invert, Item::Invert], + Item::InvertPlusPlus => vec![Item::InvertPlus, Item::InvertPlus, Item::InvertPlus], - Item::Counter => vec![Item::Block, Item::Red, Item::Red], + Item::Counter => vec![Item::Block, Item::Red, Item::Red], + Item::Reflect => vec![Item::Block, Item::Green, Item::Blue], + Item::Purify => vec![Item::Block, Item::Green, Item::Green], + Item::Sustain => vec![Item::Block, Item::Red, Item::Green], + Item::Electrify => vec![Item::Block, Item::Blue, Item::Blue], + Item::Recharge => vec![Item::Block, Item::Red, Item::Blue], Item::CounterPlus => vec![Item::Counter, Item::Counter, Item::Counter], - Item::CounterPlusPlus => vec![Item::CounterPlus, Item::CounterPlus, Item::CounterPlus], // Add red recharge - Item::Purify => vec![Item::Block, Item::Green, Item::Green], - Item::PurifyPlus => vec![Item::Purify, Item::Purify, Item::Purify], - Item::PurifyPlusPlus => vec![Item::PurifyPlus, Item::PurifyPlus, Item::PurifyPlus], - Item::Electrify => vec![Item::Block, Item::Blue, Item::Blue], + Item::CounterPlusPlus => vec![Item::CounterPlus, Item::CounterPlus, Item::CounterPlus], // Add red recharge + Item::PurifyPlus => vec![Item::Purify, Item::Purify, Item::Purify], + Item::PurifyPlusPlus => vec![Item::PurifyPlus, Item::PurifyPlus, Item::PurifyPlus], Item::ElectrifyPlus => vec![Item::Electrify, Item::Electrify, Item::Electrify], - Item::ElectrifyPlusPlus => vec![Item::ElectrifyPlus, Item::ElectrifyPlus, Item::ElectrifyPlus], - Item::Sustain => vec![Item::Block, Item::Red, Item::Green], - Item::SustainPlus => vec![Item::Sustain, Item::Sustain, Item::Sustain], - Item::SustainPlusPlus => vec![Item::SustainPlus, Item::SustainPlus, Item::SustainPlus], - Item::Reflect => vec![Item::Block, Item::Green, Item::Blue], - Item::ReflectPlus => vec![Item::Reflect, Item::Reflect, Item::Reflect], - Item::ReflectPlusPlus => vec![Item::ReflectPlus, Item::ReflectPlus, Item::ReflectPlus], - Item::Recharge => vec![Item::Block, Item::Red, Item::Blue], - Item::RechargePlus => vec![Item::Recharge, Item::Recharge, Item::Recharge], - Item::RechargePlusPlus => vec![Item::RechargePlus, Item::RechargePlus, Item::RechargePlus], + Item::ElectrifyPlusPlus => vec![Item::ElectrifyPlus, Item::ElectrifyPlus, Item::ElectrifyPlus], + Item::SustainPlus => vec![Item::Sustain, Item::Sustain, Item::Sustain], + Item::SustainPlusPlus => vec![Item::SustainPlus, Item::SustainPlus, Item::SustainPlus], + Item::ReflectPlus => vec![Item::Reflect, Item::Reflect, Item::Reflect], + Item::ReflectPlusPlus => vec![Item::ReflectPlus, Item::ReflectPlus, Item::ReflectPlus], + Item::RechargePlus => vec![Item::Recharge, Item::Recharge, Item::Recharge], + Item::RechargePlusPlus => vec![Item::RechargePlus, Item::RechargePlus, Item::RechargePlus], - Item::Bash => vec![Item::Stun, Item::Red, Item::Red], - Item::BashPlus => vec![Item::Bash, Item::Bash, Item::Bash], - Item::BashPlusPlus => vec![Item::BashPlus, Item::BashPlus, Item::BashPlus], - Item::Sleep => vec![Item::Stun, Item::Green, Item::Green], - Item::SleepPlus => vec![Item::Sleep, Item::Sleep, Item::Sleep], - Item::SleepPlusPlus => vec![Item::SleepPlus, Item::SleepPlus, Item::SleepPlus], - Item::Ruin => vec![Item::Stun, Item::Blue, Item::Blue], - Item::RuinPlus => vec![Item::Ruin, Item::Ruin, Item::Ruin], - Item::RuinPlusPlus => vec![Item::RuinPlus, Item::RuinPlus, Item::RuinPlus], - Item::Break => vec![Item::Stun, Item::Red, Item::Green], - Item::BreakPlus => vec![Item::Break, Item::Break, Item::Break], - Item::BreakPlusPlus => vec![Item::BreakPlus, Item::BreakPlus, Item::BreakPlus], - Item::Absorb => vec![Item::Stun, Item::Green, Item::Blue], - Item::AbsorbPlus => vec![Item::Absorb, Item::Absorb, Item::Absorb], - Item::AbsorbPlusPlus => vec![Item::AbsorbPlus, Item::AbsorbPlus, Item::AbsorbPlus], - Item::Banish => vec![Item::Stun, Item::Red, Item::Blue], - Item::BanishPlus => vec![Item::Banish, Item::Banish, Item::Banish], - Item::BanishPlusPlus => vec![Item::BanishPlus, Item::BanishPlus, Item::BanishPlus], + Item::Bash => vec![Item::Stun, Item::Red, Item::Red], + Item::Sleep => vec![Item::Stun, Item::Green, Item::Green], + Item::Ruin => vec![Item::Stun, Item::Blue, Item::Blue], + Item::Link => vec![Item::Stun, Item::Blue, Item::Green], + Item::Banish => vec![Item::Stun, Item::Red, Item::Blue], + Item::Break => vec![Item::Stun, Item::Red, Item::Green], + Item::BashPlus => vec![Item::Bash, Item::Bash, Item::Bash], + Item::BashPlusPlus => vec![Item::BashPlus, Item::BashPlus, Item::BashPlus], + Item::SleepPlus => vec![Item::Sleep, Item::Sleep, Item::Sleep], + Item::SleepPlusPlus => vec![Item::SleepPlus, Item::SleepPlus, Item::SleepPlus], + Item::RuinPlus => vec![Item::Ruin, Item::Ruin, Item::Ruin], + Item::RuinPlusPlus => vec![Item::RuinPlus, Item::RuinPlus, Item::RuinPlus], + Item::BreakPlus => vec![Item::Break, Item::Break, Item::Break], + Item::BreakPlusPlus => vec![Item::BreakPlus, Item::BreakPlus, Item::BreakPlus], + Item::LinkPlus => vec![Item::Link, Item::Link, Item::Link], + Item::LinkPlusPlus => vec![Item::LinkPlusPlus, Item::LinkPlusPlus, Item::LinkPlusPlus], + Item::BanishPlus => vec![Item::Banish, Item::Banish, Item::Banish], + Item::BanishPlusPlus => vec![Item::BanishPlus, Item::BanishPlus, Item::BanishPlus], - Item::Strike => vec![Item::Attack, Item::Red, Item::Red], - Item::StrikePlus => vec![Item::Strike, Item::Strike, Item::Strike], - Item::StrikePlusPlus => vec![Item::StrikePlus, Item::StrikePlus, Item::StrikePlus], - Item::Heal => vec![Item::Attack, Item::Green, Item::Green], - Item::HealPlus => vec![Item::Heal, Item::Heal, Item::Heal], - Item::HealPlusPlus => vec![Item::HealPlus, Item::HealPlus, Item::HealPlus], - Item::Blast => vec![Item::Attack, Item::Blue, Item::Blue], - Item::BlastPlus => vec![Item::Blast, Item::Blast, Item::Blast], - Item::BlastPlusPlus => vec![Item::BlastPlus, Item::BlastPlus, Item::BlastPlus], - Item::Slay => vec![Item::Attack, Item::Red, Item::Green], - Item::SlayPlus => vec![Item::Slay, Item::Slay, Item::Slay], - Item::SlayPlusPlus => vec![Item::SlayPlus, Item::SlayPlus, Item::SlayPlus], - Item::Siphon => vec![Item::Attack, Item::Green, Item::Blue], - Item::SiphonPlus => vec![Item::Siphon, Item::Siphon, Item::Siphon], - Item::SiphonPlusPlus => vec![Item::SiphonPlus, Item::SiphonPlus, Item::SiphonPlus], - Item::Chaos => vec![Item::Attack, Item::Red, Item::Blue], - Item::ChaosPlus => vec![Item::Chaos, Item::Chaos, Item::Chaos], - Item::ChaosPlusPlus => vec![Item::ChaosPlus, Item::ChaosPlus, Item::ChaosPlus], + Item::Strike => vec![Item::Attack, Item::Red, Item::Red], + Item::Chaos => vec![Item::Attack, Item::Red, Item::Blue], + Item::Heal => vec![Item::Attack, Item::Green, Item::Green], + Item::Blast => vec![Item::Attack, Item::Blue, Item::Blue], + Item::Slay => vec![Item::Attack, Item::Red, Item::Green], + Item::Siphon => vec![Item::Attack, Item::Green, Item::Blue], + Item::StrikePlus => vec![Item::Strike, Item::Strike, Item::Strike], + Item::StrikePlusPlus => vec![Item::StrikePlus, Item::StrikePlus, Item::StrikePlus], + Item::HealPlus => vec![Item::Heal, Item::Heal, Item::Heal], + Item::HealPlusPlus => vec![Item::HealPlus, Item::HealPlus, Item::HealPlus], + Item::BlastPlus => vec![Item::Blast, Item::Blast, Item::Blast], + Item::BlastPlusPlus => vec![Item::BlastPlus, Item::BlastPlus, Item::BlastPlus], + Item::SlayPlus => vec![Item::Slay, Item::Slay, Item::Slay], + Item::SlayPlusPlus => vec![Item::SlayPlus, Item::SlayPlus, Item::SlayPlus], + Item::SiphonPlus => vec![Item::Siphon, Item::Siphon, Item::Siphon], + Item::SiphonPlusPlus => vec![Item::SiphonPlus, Item::SiphonPlus, Item::SiphonPlus], + Item::ChaosPlus => vec![Item::Chaos, Item::Chaos, Item::Chaos], + Item::ChaosPlusPlus => vec![Item::ChaosPlus, Item::ChaosPlus, Item::ChaosPlus], - Item::PowerRR => vec![Item::Power, Item::Red, Item::Red], - Item::PowerGG => vec![Item::Power, Item::Green, Item::Green], - Item::PowerBB => vec![Item::Power, Item::Blue, Item::Blue], - Item::PowerRG => vec![Item::Power, Item::Red, Item::Green], - Item::PowerGB => vec![Item::Power, Item::Green, Item::Blue], - Item::PowerRB => vec![Item::Power, Item::Red, Item::Blue], - Item::PowerRRPlus => vec![Item::PowerRR, Item::PowerRR, Item::PowerRR], - Item::PowerGGPlus => vec![Item::PowerGG, Item::PowerGG, Item::PowerGG], - Item::PowerBBPlus => vec![Item::PowerBB, Item::PowerBB, Item::PowerBB], - Item::PowerRGPlus => vec![Item::PowerRG, Item::PowerRG, Item::PowerRG], - Item::PowerGBPlus => vec![Item::PowerGB, Item::PowerGB, Item::PowerGB], - Item::PowerRBPlus => vec![Item::PowerRB, Item::PowerRB, Item::PowerRB], - Item::PowerRRPlusPlus => vec![Item::PowerRRPlus, Item::PowerRRPlus, Item::PowerRRPlus], - Item::PowerGGPlusPlus => vec![Item::PowerGGPlus, Item::PowerGGPlus, Item::PowerGGPlus], - Item::PowerBBPlusPlus => vec![Item::PowerBBPlus, Item::PowerBBPlus, Item::PowerBBPlus], - Item::PowerRGPlusPlus => vec![Item::PowerRGPlus, Item::PowerRGPlus, Item::PowerRGPlus], - Item::PowerGBPlusPlus => vec![Item::PowerGBPlus, Item::PowerGBPlus, Item::PowerGBPlus], - Item::PowerRBPlusPlus => vec![Item::PowerRBPlus, Item::PowerRBPlus, Item::PowerRBPlus], + Item::PowerRR => vec![Item::Power, Item::Red, Item::Red], + Item::PowerGG => vec![Item::Power, Item::Green, Item::Green], + Item::PowerBB => vec![Item::Power, Item::Blue, Item::Blue], + Item::PowerRG => vec![Item::Power, Item::Red, Item::Green], + Item::PowerGB => vec![Item::Power, Item::Green, Item::Blue], + Item::PowerRB => vec![Item::Power, Item::Red, Item::Blue], + Item::PowerRRPlus => vec![Item::PowerRR, Item::PowerRR, Item::PowerRR], + Item::PowerGGPlus => vec![Item::PowerGG, Item::PowerGG, Item::PowerGG], + Item::PowerBBPlus => vec![Item::PowerBB, Item::PowerBB, Item::PowerBB], + Item::PowerRGPlus => vec![Item::PowerRG, Item::PowerRG, Item::PowerRG], + Item::PowerGBPlus => vec![Item::PowerGB, Item::PowerGB, Item::PowerGB], + Item::PowerRBPlus => vec![Item::PowerRB, Item::PowerRB, Item::PowerRB], + Item::PowerRRPlusPlus => vec![Item::PowerRRPlus, Item::PowerRRPlus, Item::PowerRRPlus], + Item::PowerGGPlusPlus => vec![Item::PowerGGPlus, Item::PowerGGPlus, Item::PowerGGPlus], + Item::PowerBBPlusPlus => vec![Item::PowerBBPlus, Item::PowerBBPlus, Item::PowerBBPlus], + Item::PowerRGPlusPlus => vec![Item::PowerRGPlus, Item::PowerRGPlus, Item::PowerRGPlus], + Item::PowerGBPlusPlus => vec![Item::PowerGBPlus, Item::PowerGBPlus, Item::PowerGBPlus], + Item::PowerRBPlusPlus => vec![Item::PowerRBPlus, Item::PowerRBPlus, Item::PowerRBPlus], - Item::LifeRR => vec![Item::Life, Item::Red, Item::Red], - Item::LifeGG => vec![Item::Life, Item::Green, Item::Green], - Item::LifeBB => vec![Item::Life, Item::Blue, Item::Blue], - Item::LifeRG => vec![Item::Life, Item::Red, Item::Green], - Item::LifeGB => vec![Item::Life, Item::Green, Item::Blue], - Item::LifeRB => vec![Item::Life, Item::Red, Item::Blue], - Item::LifeRRPlus => vec![Item::LifeRR, Item::LifeRR, Item::LifeRR], - Item::LifeGGPlus => vec![Item::LifeGG, Item::LifeGG, Item::LifeGG], - Item::LifeBBPlus => vec![Item::LifeBB, Item::LifeBB, Item::LifeBB], - Item::LifeRGPlus => vec![Item::LifeRG, Item::LifeRG, Item::LifeRG], - Item::LifeGBPlus => vec![Item::LifeGB, Item::LifeGB, Item::LifeGB], - Item::LifeRBPlus => vec![Item::LifeRB, Item::LifeRB, Item::LifeRB], - Item::LifeRRPlusPlus => vec![Item::LifeRRPlus, Item::LifeRRPlus, Item::LifeRRPlus], - Item::LifeGGPlusPlus => vec![Item::LifeGGPlus, Item::LifeGGPlus, Item::LifeGGPlus], - Item::LifeBBPlusPlus => vec![Item::LifeBBPlus, Item::LifeBBPlus, Item::LifeBBPlus], - Item::LifeRGPlusPlus => vec![Item::LifeRGPlus, Item::LifeRGPlus, Item::LifeRGPlus], - Item::LifeGBPlusPlus => vec![Item::LifeGBPlus, Item::LifeGBPlus, Item::LifeGBPlus], - Item::LifeRBPlusPlus => vec![Item::LifeRBPlus, Item::LifeRBPlus, Item::LifeRBPlus], + Item::LifeRR => vec![Item::Life, Item::Red, Item::Red], + Item::LifeGG => vec![Item::Life, Item::Green, Item::Green], + Item::LifeBB => vec![Item::Life, Item::Blue, Item::Blue], + Item::LifeRG => vec![Item::Life, Item::Red, Item::Green], + Item::LifeGB => vec![Item::Life, Item::Green, Item::Blue], + Item::LifeRB => vec![Item::Life, Item::Red, Item::Blue], + Item::LifeRRPlus => vec![Item::LifeRR, Item::LifeRR, Item::LifeRR], + Item::LifeGGPlus => vec![Item::LifeGG, Item::LifeGG, Item::LifeGG], + Item::LifeBBPlus => vec![Item::LifeBB, Item::LifeBB, Item::LifeBB], + Item::LifeRGPlus => vec![Item::LifeRG, Item::LifeRG, Item::LifeRG], + Item::LifeGBPlus => vec![Item::LifeGB, Item::LifeGB, Item::LifeGB], + Item::LifeRBPlus => vec![Item::LifeRB, Item::LifeRB, Item::LifeRB], + Item::LifeRRPlusPlus => vec![Item::LifeRRPlus, Item::LifeRRPlus, Item::LifeRRPlus], + Item::LifeGGPlusPlus => vec![Item::LifeGGPlus, Item::LifeGGPlus, Item::LifeGGPlus], + Item::LifeBBPlusPlus => vec![Item::LifeBBPlus, Item::LifeBBPlus, Item::LifeBBPlus], + Item::LifeRGPlusPlus => vec![Item::LifeRGPlus, Item::LifeRGPlus, Item::LifeRGPlus], + Item::LifeGBPlusPlus => vec![Item::LifeGBPlus, Item::LifeGBPlus, Item::LifeGBPlus], + Item::LifeRBPlusPlus => vec![Item::LifeRBPlus, Item::LifeRBPlus, Item::LifeRBPlus], - - - Item::SpeedRR => vec![Item::Speed, Item::Red, Item::Red], - Item::SpeedGG => vec![Item::Speed, Item::Green, Item::Green], - Item::SpeedBB => vec![Item::Speed, Item::Blue, Item::Blue], - Item::SpeedRG => vec![Item::Speed, Item::Red, Item::Green], - Item::SpeedGB => vec![Item::Speed, Item::Green, Item::Blue], - Item::SpeedRB => vec![Item::Speed, Item::Red, Item::Blue], - - Item::SpeedRRPlus => vec![Item::SpeedRR, Item::SpeedRR, Item::SpeedRR], - Item::SpeedGGPlus => vec![Item::SpeedGG, Item::SpeedGG, Item::SpeedGG], - Item::SpeedBBPlus => vec![Item::SpeedBB, Item::SpeedBB, Item::SpeedBB], - Item::SpeedRGPlus => vec![Item::SpeedRG, Item::SpeedRG, Item::SpeedRG], - Item::SpeedGBPlus => vec![Item::SpeedGB, Item::SpeedGB, Item::SpeedGB], - Item::SpeedRBPlus => vec![Item::SpeedRB, Item::SpeedRB, Item::SpeedRB], - - Item::SpeedRRPlusPlus => vec![Item::SpeedRRPlus, Item::SpeedRRPlus, Item::SpeedRRPlus], - Item::SpeedGGPlusPlus => vec![Item::SpeedGGPlus, Item::SpeedGGPlus, Item::SpeedGGPlus], - Item::SpeedBBPlusPlus => vec![Item::SpeedBBPlus, Item::SpeedBBPlus, Item::SpeedBBPlus], - Item::SpeedRGPlusPlus => vec![Item::SpeedRGPlus, Item::SpeedRGPlus, Item::SpeedRGPlus], - Item::SpeedGBPlusPlus => vec![Item::SpeedGBPlus, Item::SpeedGBPlus, Item::SpeedGBPlus], - Item::SpeedRBPlusPlus => vec![Item::SpeedRBPlus, Item::SpeedRBPlus, Item::SpeedRBPlus], + Item::SpeedRR => vec![Item::Speed, Item::Red, Item::Red], + Item::SpeedGG => vec![Item::Speed, Item::Green, Item::Green], + Item::SpeedBB => vec![Item::Speed, Item::Blue, Item::Blue], + Item::SpeedRG => vec![Item::Speed, Item::Red, Item::Green], + Item::SpeedGB => vec![Item::Speed, Item::Green, Item::Blue], + Item::SpeedRB => vec![Item::Speed, Item::Red, Item::Blue], + Item::SpeedRRPlus => vec![Item::SpeedRR, Item::SpeedRR, Item::SpeedRR], + Item::SpeedGGPlus => vec![Item::SpeedGG, Item::SpeedGG, Item::SpeedGG], + Item::SpeedBBPlus => vec![Item::SpeedBB, Item::SpeedBB, Item::SpeedBB], + Item::SpeedRGPlus => vec![Item::SpeedRG, Item::SpeedRG, Item::SpeedRG], + Item::SpeedGBPlus => vec![Item::SpeedGB, Item::SpeedGB, Item::SpeedGB], + Item::SpeedRBPlus => vec![Item::SpeedRB, Item::SpeedRB, Item::SpeedRB], + Item::SpeedRRPlusPlus => vec![Item::SpeedRRPlus, Item::SpeedRRPlus, Item::SpeedRRPlus], + Item::SpeedGGPlusPlus => vec![Item::SpeedGGPlus, Item::SpeedGGPlus, Item::SpeedGGPlus], + Item::SpeedBBPlusPlus => vec![Item::SpeedBBPlus, Item::SpeedBBPlus, Item::SpeedBBPlus], + Item::SpeedRGPlusPlus => vec![Item::SpeedRGPlus, Item::SpeedRGPlus, Item::SpeedRGPlus], + Item::SpeedGBPlusPlus => vec![Item::SpeedGBPlus, Item::SpeedGBPlus, Item::SpeedGBPlus], + Item::SpeedRBPlusPlus => vec![Item::SpeedRBPlus, Item::SpeedRBPlus, Item::SpeedRBPlus], _ => vec![*self], } @@ -1029,129 +1014,126 @@ impl Item { impl From for Item { fn from(skill: Skill) -> Item { match skill { - Skill::Absorb => Item::Absorb, - Skill::AbsorbPlus => Item::AbsorbPlus, - Skill::AbsorbPlusPlus => Item::AbsorbPlusPlus, - Skill::Amplify => Item::Amplify, - Skill::AmplifyPlus => Item::AmplifyPlus, - Skill::AmplifyPlusPlus => Item::AmplifyPlusPlus, + Skill::Absorb => Item::Absorb, + Skill::AbsorbPlus => Item::AbsorbPlus, + Skill::AbsorbPlusPlus => Item::AbsorbPlusPlus, + Skill::Amplify => Item::Amplify, + Skill::AmplifyPlus => Item::AmplifyPlus, + Skill::AmplifyPlusPlus => Item::AmplifyPlusPlus, Skill::Attack => Item::Attack, - Skill::Banish => Item::Banish, - Skill::BanishPlus => Item::BanishPlus, - Skill::BanishPlusPlus => Item::BanishPlusPlus, - Skill::Bash => Item::Bash, - Skill::BashPlus => Item::BashPlus, - Skill::BashPlusPlus => Item::BashPlusPlus, - Skill::Blast => Item::Blast, - Skill::BlastPlus => Item::BlastPlus, - Skill::BlastPlusPlus => Item::BlastPlusPlus, + Skill::Banish => Item::Banish, + Skill::BanishPlus => Item::BanishPlus, + Skill::BanishPlusPlus => Item::BanishPlusPlus, + Skill::Bash => Item::Bash, + Skill::BashPlus => Item::BashPlus, + Skill::BashPlusPlus => Item::BashPlusPlus, + Skill::Blast => Item::Blast, + Skill::BlastPlus => Item::BlastPlus, + Skill::BlastPlusPlus => Item::BlastPlusPlus, Skill::Block => Item::Block, Skill::Buff => Item::Buff, - Skill::Chaos => Item::Chaos, - Skill::ChaosPlus => Item::ChaosPlus, - Skill::ChaosPlusPlus => Item::ChaosPlusPlus, - Skill::Counter => Item::Counter, - Skill::CounterPlus => Item::CounterPlus, - Skill::CounterPlusPlus => Item::CounterPlusPlus, - Skill::Curse => Item::Curse, - Skill::CursePlus => Item::CursePlus, - Skill::CursePlusPlus => Item::CursePlusPlus, + Skill::Chaos => Item::Chaos, + Skill::ChaosPlus => Item::ChaosPlus, + Skill::ChaosPlusPlus => Item::ChaosPlusPlus, + Skill::Counter => Item::Counter, + Skill::CounterPlus => Item::CounterPlus, + Skill::CounterPlusPlus => Item::CounterPlusPlus, + Skill::Curse => Item::Curse, + Skill::CursePlus => Item::CursePlus, + Skill::CursePlusPlus => Item::CursePlusPlus, Skill::Debuff => Item::Debuff, - Skill::Decay => Item::Decay, - Skill::DecayPlus => Item::DecayPlus, - Skill::DecayPlusPlus => Item::DecayPlusPlus, - Skill::Electrify => Item::Electrify, - Skill::ElectrifyPlus => Item::ElectrifyPlus, - Skill::ElectrifyPlusPlus => Item::ElectrifyPlusPlus, - Skill::Haste => Item::Haste, - Skill::HastePlus => Item::HastePlus, - Skill::HastePlusPlus => Item::HastePlusPlus, - Skill::Heal => Item::Heal, - Skill::HealPlus => Item::HealPlus, - Skill::HealPlusPlus => Item::HealPlusPlus, - Skill::Hex => Item::Hex, - Skill::HexPlus => Item::HexPlus, - Skill::HexPlusPlus => Item::HexPlusPlus, - Skill::Hybrid => Item::Hybrid, - Skill::HybridPlus => Item::HybridPlus, - Skill::HybridPlusPlus => Item::HybridPlusPlus, - Skill::Intercept => Item::Intercept, - Skill::InterceptPlus => Item::InterceptPlus, - Skill::InterceptPlusPlus => Item::InterceptPlusPlus, - Skill::Invert => Item::Invert, - Skill::InvertPlus => Item::InvertPlus, - Skill::InvertPlusPlus => Item::InvertPlusPlus, - Skill::Purge => Item::Purge, - Skill::PurgePlus => Item::PurgePlus, - Skill::PurgePlusPlus => Item::PurgePlusPlus, - Skill::Purify => Item::Purify, - Skill::PurifyPlus => Item::PurifyPlus, - Skill::PurifyPlusPlus => Item::PurifyPlusPlus, - Skill::Recharge => Item::Recharge, - Skill::RechargePlus => Item::RechargePlus, - Skill::RechargePlusPlus => Item::RechargePlusPlus, - Skill::Reflect => Item::Reflect, - Skill::ReflectPlus => Item::ReflectPlus, - Skill::ReflectPlusPlus => Item::ReflectPlusPlus, - Skill::Restrict => Item::Restrict, - Skill::RestrictPlus => Item::RestrictPlus, - Skill::RestrictPlusPlus => Item::RestrictPlusPlus, - Skill::Ruin => Item::Ruin, - Skill::RuinPlus => Item::RuinPlus, - Skill::RuinPlusPlus => Item::RuinPlusPlus, - Skill::Link => Item::Link, - Skill::LinkPlus => Item::LinkPlus, - Skill::LinkPlusPlus => Item::LinkPlusPlus, - Skill::Silence => Item::Silence, - Skill::SilencePlus => Item::SilencePlus, - Skill::SilencePlusPlus => Item::SilencePlusPlus, - Skill::Siphon => Item::Siphon, - Skill::SiphonPlus => Item::SiphonPlus, - Skill::SiphonPlusPlus => Item::SiphonPlusPlus, - Skill::Slay => Item::Slay, - Skill::SlayPlus => Item::SlayPlus, - Skill::SlayPlusPlus => Item::SlayPlusPlus, - Skill::Sleep => Item::Sleep, - Skill::SleepPlus => Item::SleepPlus, - Skill::SleepPlusPlus => Item::SleepPlusPlus, - Skill::Strike => Item::Strike, - Skill::StrikePlus => Item::StrikePlus, - Skill::StrikePlusPlus => Item::StrikePlusPlus, + Skill::Decay => Item::Decay, + Skill::DecayPlus => Item::DecayPlus, + Skill::DecayPlusPlus => Item::DecayPlusPlus, + Skill::Electrify => Item::Electrify, + Skill::ElectrifyPlus => Item::ElectrifyPlus, + Skill::ElectrifyPlusPlus=> Item::ElectrifyPlusPlus, + Skill::Haste => Item::Haste, + Skill::HastePlus => Item::HastePlus, + Skill::HastePlusPlus => Item::HastePlusPlus, + Skill::Heal => Item::Heal, + Skill::HealPlus => Item::HealPlus, + Skill::HealPlusPlus => Item::HealPlusPlus, + Skill::Hybrid => Item::Hybrid, + Skill::HybridPlus => Item::HybridPlus, + Skill::HybridPlusPlus => Item::HybridPlusPlus, + Skill::Intercept => Item::Intercept, + Skill::InterceptPlus => Item::InterceptPlus, + Skill::InterceptPlusPlus=> Item::InterceptPlusPlus, + Skill::Invert => Item::Invert, + Skill::InvertPlus => Item::InvertPlus, + Skill::InvertPlusPlus => Item::InvertPlusPlus, + Skill::Purge => Item::Purge, + Skill::PurgePlus => Item::PurgePlus, + Skill::PurgePlusPlus => Item::PurgePlusPlus, + Skill::Purify => Item::Purify, + Skill::PurifyPlus => Item::PurifyPlus, + Skill::PurifyPlusPlus => Item::PurifyPlusPlus, + Skill::Recharge => Item::Recharge, + Skill::RechargePlus => Item::RechargePlus, + Skill::RechargePlusPlus => Item::RechargePlusPlus, + Skill::Reflect => Item::Reflect, + Skill::ReflectPlus => Item::ReflectPlus, + Skill::ReflectPlusPlus => Item::ReflectPlusPlus, + Skill::Restrict => Item::Restrict, + Skill::RestrictPlus => Item::RestrictPlus, + Skill::RestrictPlusPlus => Item::RestrictPlusPlus, + Skill::Ruin => Item::Ruin, + Skill::RuinPlus => Item::RuinPlus, + Skill::RuinPlusPlus => Item::RuinPlusPlus, + Skill::Link => Item::Link, + Skill::LinkPlus => Item::LinkPlus, + Skill::LinkPlusPlus => Item::LinkPlusPlus, + Skill::Silence => Item::Silence, + Skill::SilencePlus => Item::SilencePlus, + Skill::SilencePlusPlus => Item::SilencePlusPlus, + Skill::Siphon => Item::Siphon, + Skill::SiphonPlus => Item::SiphonPlus, + Skill::SiphonPlusPlus => Item::SiphonPlusPlus, + Skill::Slay => Item::Slay, + Skill::SlayPlus => Item::SlayPlus, + Skill::SlayPlusPlus => Item::SlayPlusPlus, + Skill::Sleep => Item::Sleep, + Skill::SleepPlus => Item::SleepPlus, + Skill::SleepPlusPlus => Item::SleepPlusPlus, + Skill::Strike => Item::Strike, + Skill::StrikePlus => Item::StrikePlus, + Skill::StrikePlusPlus => Item::StrikePlusPlus, Skill::Stun => Item::Stun, - Skill::Sustain => Item::Sustain, - Skill::SustainPlus => Item::SustainPlus, - Skill::SustainPlusPlus => Item::SustainPlusPlus, - Skill::Break => Item::Break, - Skill::BreakPlus => Item::BreakPlus, - Skill::BreakPlusPlus => Item::BreakPlusPlus, - Skill::Triage => Item::Triage, - Skill::TriagePlus => Item::TriagePlus, - Skill::TriagePlusPlus => Item::TriagePlusPlus, + Skill::Sustain => Item::Sustain, + Skill::SustainPlus => Item::SustainPlus, + Skill::SustainPlusPlus => Item::SustainPlusPlus, + Skill::Break => Item::Break, + Skill::BreakPlus => Item::BreakPlus, + Skill::BreakPlusPlus => Item::BreakPlusPlus, + Skill::Triage => Item::Triage, + Skill::TriagePlus => Item::TriagePlus, + Skill::TriagePlusPlus => Item::TriagePlusPlus, // Convert subskills into parent skills - Skill::Electrocute => Item::Electrify, - Skill::ElectrocutePlus => Item::ElectrifyPlus, - Skill::ElectrocutePlusPlus => Item::ElectrifyPlusPlus, - Skill::ElectrocuteTick => Item::Electrify, - Skill::ElectrocuteTickPlus => Item::ElectrifyPlus, - Skill::ElectrocuteTickPlusPlus => Item::ElectrifyPlus, - Skill::DecayTick => Item::Decay, - Skill::DecayTickPlus => Item::DecayPlus, - Skill::DecayTickPlusPlus => Item::DecayPlusPlus, - Skill::Absorption => Item::Absorb, - Skill::AbsorptionPlus => Item::AbsorbPlus, - Skill::AbsorptionPlusPlus => Item::AbsorbPlusPlus, - Skill::HasteStrike => Item::Haste, - Skill::HybridBlast => Item::Hybrid, - Skill::CounterAttack => Item::Counter, - Skill::CounterAttackPlus => Item::CounterPlus, - Skill::CounterAttackPlusPlus => Item::CounterPlusPlus, - Skill::SiphonTick => Item::Siphon, - Skill::SiphonTickPlus => Item::SiphonPlus, - Skill::SiphonTickPlusPlus => Item::SiphonPlusPlus, - Skill::TriageTick => Item::Triage, - Skill::TriageTickPlus => Item::TriagePlus, - Skill::TriageTickPlusPlus => Item::TriagePlusPlus, + Skill::Electrocute => Item::Electrify, + Skill::ElectrocutePlus => Item::ElectrifyPlus, + Skill::ElectrocutePlusPlus => Item::ElectrifyPlusPlus, + Skill::ElectrocuteTick => Item::Electrify, + Skill::ElectrocuteTickPlus => Item::ElectrifyPlus, + Skill::ElectrocuteTickPlusPlus => Item::ElectrifyPlus, + Skill::DecayTick => Item::Decay, + Skill::DecayTickPlus => Item::DecayPlus, + Skill::DecayTickPlusPlus => Item::DecayPlusPlus, + Skill::Absorption => Item::Absorb, + Skill::AbsorptionPlus => Item::AbsorbPlus, + Skill::AbsorptionPlusPlus => Item::AbsorbPlusPlus, + Skill::HasteStrike => Item::Haste, + Skill::HybridBlast => Item::Hybrid, + Skill::CounterAttack => Item::Counter, + Skill::CounterAttackPlus => Item::CounterPlus, + Skill::CounterAttackPlusPlus => Item::CounterPlusPlus, + Skill::SiphonTick => Item::Siphon, + Skill::SiphonTickPlus => Item::SiphonPlus, + Skill::SiphonTickPlusPlus => Item::SiphonPlusPlus, + Skill::TriageTick => Item::Triage, + Skill::TriageTickPlus => Item::TriagePlus, + Skill::TriageTickPlusPlus => Item::TriagePlusPlus, } } } @@ -1159,7 +1141,7 @@ impl From for Item { impl From for Item { fn from(spec: Spec) -> Item { match spec { - Spec::Speed => Item::Speed, + Spec::Speed => Item::Speed, Spec::SpeedRR => Item::SpeedRR, Spec::SpeedBB => Item::SpeedBB, Spec::SpeedGG => Item::SpeedGG, @@ -1181,7 +1163,7 @@ impl From for Item { Spec::SpeedGBPlusPlus => Item::SpeedGBPlusPlus, Spec::SpeedRBPlusPlus => Item::SpeedRBPlusPlus, - Spec::Power => Item::Power, + Spec::Power => Item::Power, Spec::PowerRR => Item::PowerRR, Spec::PowerBB => Item::PowerBB, Spec::PowerGG => Item::PowerGG, diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 3439a6c4..be3071e8 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -82,7 +82,7 @@ pub enum RpcRequest { GameState { id: Uuid }, GameReady { id: Uuid }, - GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Option, skill: Skill }, + GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Uuid, skill: Skill }, GameSkillClear { game_id: Uuid }, AccountState {}, diff --git a/server/src/skill.rs b/server/src/skill.rs index d71ac47e..2f122399 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -177,10 +177,6 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut Skill::HealPlus | Skill::HealPlusPlus => heal(source, target, resolutions, skill), - Skill::Hex| - Skill::HexPlus | - Skill::HexPlusPlus => hex(source, target, resolutions, skill), - Skill::Absorb| Skill::AbsorbPlus | Skill::AbsorbPlusPlus => absorb(source, target, resolutions, skill), @@ -320,26 +316,16 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) -> }; } - // beware that link doesn't cause any damage - // because then applying it will proc this - if target.affected(Effect::Link) { - resolutions = link_hit(&source, &target, resolutions, game, event) - } - }, - - Event::Immunity { skill: _, immunity } => match immunity.contains(&Effect::Counter) { - true => { + if target.affected(Effect::Counter) { let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter() .find(|e| e.effect == Effect::Counter).unwrap().clone(); match meta { Some(EffectMeta::Skill(s)) => { - resolutions = riposte(&mut target, &mut source, resolutions, s); + resolutions = counter_attack(&mut target, &mut source, resolutions, s); }, _ => panic!("no counter skill"), }; - - }, - false => (), + } }, _ => (), }; @@ -558,12 +544,6 @@ pub enum Skill { #[serde(rename = "Decay++")] DecayPlusPlus, - Hex, - #[serde(rename = "Hex+")] - HexPlus, - #[serde(rename = "Hex++")] - HexPlusPlus, - Haste, #[serde(rename = "Haste+")] HastePlus, @@ -763,9 +743,6 @@ impl Skill { Skill::ElectrocuteTickPlus => 100, Skill::ElectrocuteTickPlusPlus => 130, - Skill::Counter=> 110, - Skill::CounterPlus => 145, - Skill::CounterPlusPlus => 200, Skill::CounterAttack=> 70, Skill::CounterAttackPlus => 95, Skill::CounterAttackPlusPlus => 120, @@ -774,14 +751,18 @@ impl Skill { Skill::PurifyPlus => 70, Skill::PurifyPlusPlus => 105, - Skill::Reflect=> 45, //restore blue life (heal) + Skill::Reflect=> 45, //Recharge blue life (heal) Skill::ReflectPlus => 70, Skill::ReflectPlusPlus => 100, - Skill::Recharge=> 85, //restore red and blue life (heal) + Skill::Recharge=> 85, //Recharge red and blue life (heal) Skill::RechargePlus => 130, Skill::RechargePlusPlus => 200, + Skill::Sustain => 120, // Recharge red life (heal) + Skill::SustainPlus => 150, + Skill::SustainPlusPlus => 230, + // Stun Base Skill::Sleep=> 240, //Green dmg (heal) Skill::SleepPlus => 300, @@ -805,9 +786,9 @@ impl Skill { // Buff base Skill::HybridBlast => 25, Skill::HasteStrike => 30, - Skill::Link=> 140, - Skill::LinkPlus => 200, - Skill::LinkPlusPlus => 300, + Skill::Link=> 75, + Skill::LinkPlus => 100, + Skill::LinkPlusPlus => 150, Skill::Intercept=> 80, Skill::InterceptPlus => 110, Skill::InterceptPlusPlus => 150, @@ -822,67 +803,67 @@ impl Skill { pub fn effect(&self) -> Vec { match self { // Modifiers - Skill::Amplify => vec![ConstructEffect {effect: Effect::Amplify, duration: 2, - meta: Some(EffectMeta::Multiplier(150)), tick: None}], - Skill::AmplifyPlus => vec![ConstructEffect {effect: Effect::Amplify, duration: 3, - meta: Some(EffectMeta::Multiplier(175)), tick: None}], - Skill::AmplifyPlusPlus => vec![ConstructEffect {effect: Effect::Amplify, duration: 4, - meta: Some(EffectMeta::Multiplier(200)), tick: None}], + Skill::Amplify => vec![ConstructEffect {effect: Effect::Amplify, duration: 2, + meta: Some(EffectMeta::Multiplier(150)), tick: None}], + Skill::AmplifyPlus => vec![ConstructEffect {effect: Effect::Amplify, duration: 3, + meta: Some(EffectMeta::Multiplier(175)), tick: None}], + Skill::AmplifyPlusPlus => vec![ConstructEffect {effect: Effect::Amplify, duration: 4, + meta: Some(EffectMeta::Multiplier(200)), tick: None}], - Skill::Banish => vec![ConstructEffect {effect: Effect::Banish, duration: 1,meta: None, tick: None}], - Skill::BanishPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 2,meta: None, tick: None}], - Skill::BanishPlusPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 3,meta: None, tick: None}], - Skill::Block => vec![ConstructEffect {effect: Effect::Block, duration: 1, - meta: Some(EffectMeta::Multiplier(50)), tick: None}], - Skill::Buff => vec![ConstructEffect {effect: Effect::Buff, duration: 2, - meta: Some(EffectMeta::Multiplier(125)), tick: None }], + Skill::Banish => vec![ConstructEffect {effect: Effect::Banish, duration: 1,meta: None, tick: None}], + Skill::BanishPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 2,meta: None, tick: None}], + Skill::BanishPlusPlus => vec![ConstructEffect {effect: Effect::Banish, duration: 3,meta: None, tick: None}], + Skill::Block => vec![ConstructEffect {effect: Effect::Block, duration: 1, + meta: Some(EffectMeta::Multiplier(50)), tick: None}], + Skill::Buff => vec![ConstructEffect {effect: Effect::Buff, duration: 2, + meta: Some(EffectMeta::Multiplier(125)), tick: None }], - Skill::Electrify => vec![ConstructEffect {effect: Effect::Electric, duration: 2, - meta: Some(EffectMeta::Skill(Skill::Electrocute)), tick: None}], - Skill::ElectrifyPlus => vec![ConstructEffect {effect: Effect::Electric, duration: 3, - meta: Some(EffectMeta::Skill(Skill::ElectrocutePlus)), tick: None}], - Skill::ElectrifyPlusPlus => vec![ConstructEffect {effect: Effect::Electric, duration: 4, - meta: Some(EffectMeta::Skill(Skill::ElectrocutePlusPlus)), tick: None}], - Skill::Electrocute => vec![ConstructEffect {effect: Effect::Electrocute, duration: 3, - meta: Some(EffectMeta::Skill(Skill::ElectrocuteTick)), tick: None}], - Skill::ElectrocutePlus => vec![ConstructEffect {effect: Effect::Electrocute, duration: 4, - meta: Some(EffectMeta::Skill(Skill::ElectrocuteTickPlus)), tick: None}], - Skill::ElectrocutePlusPlus => vec![ConstructEffect {effect: Effect::Electrocute, duration: 5, - meta: Some(EffectMeta::Skill(Skill::ElectrocuteTickPlusPlus)), tick: None}], + Skill::Electrify => vec![ConstructEffect {effect: Effect::Electric, duration: 1, + meta: Some(EffectMeta::Skill(Skill::Electrocute)), tick: None}], + Skill::ElectrifyPlus => vec![ConstructEffect {effect: Effect::Electric, duration: 1, + meta: Some(EffectMeta::Skill(Skill::ElectrocutePlus)), tick: None}], + Skill::ElectrifyPlusPlus => vec![ConstructEffect {effect: Effect::Electric, duration: 1, + meta: Some(EffectMeta::Skill(Skill::ElectrocutePlusPlus)), tick: None}], + Skill::Electrocute => vec![ConstructEffect {effect: Effect::Electrocute, duration: 2, + meta: Some(EffectMeta::Skill(Skill::ElectrocuteTick)), tick: None}], + Skill::ElectrocutePlus => vec![ConstructEffect {effect: Effect::Electrocute, duration: 3, + meta: Some(EffectMeta::Skill(Skill::ElectrocuteTickPlus)), tick: None}], + Skill::ElectrocutePlusPlus => vec![ConstructEffect {effect: Effect::Electrocute, duration: 4, + meta: Some(EffectMeta::Skill(Skill::ElectrocuteTickPlusPlus)), tick: None}], - Skill::Sustain => vec![ConstructEffect {effect: Effect::Sustain, duration: 1, meta: None, tick: None }], - Skill::SustainPlus => vec![ConstructEffect {effect: Effect::Sustain, duration: 2, meta: None, tick: None }], - Skill::SustainPlusPlus => vec![ConstructEffect {effect: Effect::Sustain, duration: 3, meta: None, tick: None }], + Skill::Sustain => vec![ConstructEffect {effect: Effect::Sustain, duration: 1, meta: None, tick: None }], + Skill::SustainPlus => vec![ConstructEffect {effect: Effect::Sustain, duration: 1, meta: None, tick: None }], + Skill::SustainPlusPlus => vec![ConstructEffect {effect: Effect::Sustain, duration: 1, meta: None, tick: None }], - Skill::Curse => vec![ConstructEffect {effect: Effect::Curse, duration: 2, - meta: Some(EffectMeta::Multiplier(150)), tick: None}], - Skill::CursePlus => vec![ConstructEffect {effect: Effect::Curse, duration: 2, - meta: Some(EffectMeta::Multiplier(200)), tick: None}], - Skill::CursePlusPlus => vec![ConstructEffect {effect: Effect::Curse, duration: 3, - meta: Some(EffectMeta::Multiplier(250)), tick: None}], + Skill::Curse => vec![ConstructEffect {effect: Effect::Curse, duration: 2, + meta: Some(EffectMeta::Multiplier(150)), tick: None}], + Skill::CursePlus => vec![ConstructEffect {effect: Effect::Curse, duration: 2, + meta: Some(EffectMeta::Multiplier(200)), tick: None}], + Skill::CursePlusPlus => vec![ConstructEffect {effect: Effect::Curse, duration: 3, + meta: Some(EffectMeta::Multiplier(250)), tick: None}], Skill::Debuff => vec![ConstructEffect {effect: Effect::Slow, duration: 3, - meta: Some(EffectMeta::Multiplier(50)), tick: None }], + meta: Some(EffectMeta::Multiplier(50)), tick: None }], - Skill::Decay => vec![ConstructEffect {effect: Effect::Wither, duration: 3, meta: Some(EffectMeta::Multiplier(50)), tick: None }, + Skill::Decay => vec![ConstructEffect {effect: Effect::Wither, duration: 3, + meta: Some(EffectMeta::Multiplier(50)), tick: None }, ConstructEffect {effect: Effect::Decay, duration: 3, meta: Some(EffectMeta::Skill(Skill::DecayTick)), tick: None}], - Skill::DecayPlus => vec![ConstructEffect {effect: Effect::Wither, duration: 3, meta: Some(EffectMeta::Multiplier(35)), tick: None }, - ConstructEffect {effect: Effect::Decay, duration: 3, + Skill::DecayPlus => vec![ConstructEffect {effect: Effect::Wither, duration: 3, + meta: Some(EffectMeta::Multiplier(35)), tick: None }, + ConstructEffect {effect: Effect::Decay, duration: 3, meta: Some(EffectMeta::Skill(Skill::DecayTickPlus)), tick: None}], - Skill::DecayPlusPlus => vec![ConstructEffect {effect: Effect::Wither, duration: 4, meta: Some(EffectMeta::Multiplier(20)), tick: None }, - ConstructEffect {effect: Effect::Decay, duration: 4, + Skill::DecayPlusPlus => vec![ConstructEffect {effect: Effect::Wither, duration: 4, + meta: Some(EffectMeta::Multiplier(20)), tick: None }, + ConstructEffect {effect: Effect::Decay, duration: 4, meta: Some(EffectMeta::Skill(Skill::DecayTickPlusPlus)), tick: None}], - Skill::Haste => vec![ConstructEffect {effect: Effect::Haste, duration: 2, - meta: Some(EffectMeta::Multiplier(150)), tick: None }], - Skill::HastePlus => vec![ConstructEffect {effect: Effect::Haste, duration: 3, - meta: Some(EffectMeta::Multiplier(175)), tick: None }], - Skill::HastePlusPlus => vec![ConstructEffect {effect: Effect::Haste, duration: 4, - meta: Some(EffectMeta::Multiplier(225)), tick: None }], - Skill::Hex => vec![ConstructEffect {effect: Effect::Hex, duration: 2, meta: None, tick: None}], - Skill::HexPlus => vec![ConstructEffect {effect: Effect::Hex, duration: 3, meta: None, tick: None}], - Skill::HexPlusPlus => vec![ConstructEffect {effect: Effect::Hex, duration: 4, meta: None, tick: None}], + Skill::Haste => vec![ConstructEffect {effect: Effect::Haste, duration: 2, + meta: Some(EffectMeta::Multiplier(150)), tick: None }], + Skill::HastePlus => vec![ConstructEffect {effect: Effect::Haste, duration: 3, + meta: Some(EffectMeta::Multiplier(175)), tick: None }], + Skill::HastePlusPlus => vec![ConstructEffect {effect: Effect::Haste, duration: 4, + meta: Some(EffectMeta::Multiplier(225)), tick: None }], Skill::Absorb => vec![ConstructEffect {effect: Effect::Absorb, duration: 2, meta: Some(EffectMeta::Skill(Skill::Absorption)), tick: None}], @@ -891,87 +872,96 @@ impl Skill { Skill::AbsorbPlusPlus => vec![ConstructEffect {effect: Effect::Absorb, duration: 4, meta: Some(EffectMeta::Skill(Skill::AbsorptionPlusPlus)), tick: None}], - Skill::Absorption => vec![ConstructEffect {effect: Effect::Absorption, duration: 5, meta: None, tick: None}], - Skill::AbsorptionPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 7, meta: None, tick: None}], - Skill::AbsorptionPlusPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 9, meta: None, tick: None}], + Skill::Absorption => vec![ConstructEffect {effect: Effect::Absorption, duration: 5, meta: None, tick: None}], + Skill::AbsorptionPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 7, meta: None, tick: None}], + Skill::AbsorptionPlusPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 9, meta: None, tick: None}], - Skill::Hybrid => vec![ConstructEffect {effect: Effect::Hybrid, duration: 2, + Skill::Hybrid => vec![ConstructEffect {effect: Effect::Hybrid, duration: 2, meta: Some(EffectMeta::Multiplier(150)), tick: None }], - Skill::HybridPlus => vec![ConstructEffect {effect: Effect::Hybrid, duration: 3, + Skill::HybridPlus => vec![ConstructEffect {effect: Effect::Hybrid, duration: 3, meta: Some(EffectMeta::Multiplier(175)), tick: None }], - Skill::HybridPlusPlus => vec![ConstructEffect {effect: Effect::Hybrid, duration: 4, + Skill::HybridPlusPlus => vec![ConstructEffect {effect: Effect::Hybrid, duration: 4, meta: Some(EffectMeta::Multiplier(225)), tick: None }], - Skill::Invert => vec![ConstructEffect {effect: Effect::Invert, duration: 2, meta: None, tick: None}], - Skill::InvertPlus => vec![ConstructEffect {effect: Effect::Invert, duration: 3, meta: None, tick: None}], - Skill::InvertPlusPlus => vec![ConstructEffect {effect: Effect::Invert, duration: 4, meta: None, tick: None}], + Skill::Invert => vec![ConstructEffect {effect: Effect::Invert, duration: 2, meta: None, tick: None}], + Skill::InvertPlus => vec![ConstructEffect {effect: Effect::Invert, duration: 3, meta: None, tick: None}], + Skill::InvertPlusPlus => vec![ConstructEffect {effect: Effect::Invert, duration: 4, meta: None, tick: None}], - Skill::Counter => vec![ConstructEffect {effect: Effect::Counter, duration: 2, - meta: Some(EffectMeta::Skill(Skill::CounterAttack)), tick: None}], - Skill::CounterPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 2, - meta: Some(EffectMeta::Skill(Skill::CounterAttackPlus)), tick: None}], - Skill::CounterPlusPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 2, - meta: Some(EffectMeta::Skill(Skill::CounterAttackPlusPlus)), tick: None}], + Skill::Counter => vec![ConstructEffect {effect: Effect::Counter, duration: 1, + meta: Some(EffectMeta::Skill(Skill::CounterAttack)), tick: None}, + ConstructEffect {effect: Effect::Block, duration: 1, + meta: Some(EffectMeta::Multiplier(60)), tick: None}], + Skill::CounterPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 1, + meta: Some(EffectMeta::Skill(Skill::CounterAttackPlus)), tick: None}, + ConstructEffect {effect: Effect::Block, duration: 1, + meta: Some(EffectMeta::Multiplier(40)), tick: None}], + Skill::CounterPlusPlus => vec![ConstructEffect {effect: Effect::Counter, duration: 1, + meta: Some(EffectMeta::Skill(Skill::CounterAttackPlusPlus)), tick: None}, + ConstructEffect {effect: Effect::Block, duration: 1, + meta: Some(EffectMeta::Multiplier(20)), tick: None}], - Skill::Reflect => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }], - Skill::ReflectPlus => vec![ConstructEffect {effect: Effect::Reflect, duration: 2, meta: None, tick: None }], - Skill::ReflectPlusPlus => vec![ConstructEffect {effect: Effect::Reflect, duration: 3, meta: None, tick: None }], + Skill::Reflect => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }], + Skill::ReflectPlus => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }], + Skill::ReflectPlusPlus => vec![ConstructEffect {effect: Effect::Reflect, duration: 1, meta: None, tick: None }], - Skill::Break => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}, - ConstructEffect {effect: Effect::Vulnerable, duration: 3, meta: Some(EffectMeta::Multiplier(150)), tick: None}], - Skill::BreakPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}, - ConstructEffect {effect: Effect::Vulnerable, duration: 4, meta: Some(EffectMeta::Multiplier(200)), tick: None}], - Skill::BreakPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}, - ConstructEffect {effect: Effect::Vulnerable, duration: 4, meta: Some(EffectMeta::Multiplier(250)), tick: None}], + Skill::Break => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}, + ConstructEffect {effect: Effect::Vulnerable, duration: 3, + meta: Some(EffectMeta::Multiplier(150)), tick: None}], + Skill::BreakPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}, + ConstructEffect {effect: Effect::Vulnerable, duration: 4, + meta: Some(EffectMeta::Multiplier(200)), tick: None}], + Skill::BreakPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}, + ConstructEffect {effect: Effect::Vulnerable, duration: 4, + meta: Some(EffectMeta::Multiplier(250)), tick: None}], - Skill::Ruin => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], - Skill::RuinPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], - Skill::RuinPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], + Skill::Ruin => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], + Skill::RuinPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], + Skill::RuinPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], - Skill::Purge => vec![ConstructEffect {effect: Effect::Purge, duration: 1, meta: None, tick: None}], - Skill::PurgePlus => vec![ConstructEffect {effect: Effect::Purge, duration: 2, meta: None, tick: None}], - Skill::PurgePlusPlus => vec![ConstructEffect {effect: Effect::Purge, duration: 3, meta: None, tick: None}], + Skill::Purge => vec![ConstructEffect {effect: Effect::Purge, duration: 2, meta: None, tick: None}], + Skill::PurgePlus => vec![ConstructEffect {effect: Effect::Purge, duration: 3, meta: None, tick: None}], + Skill::PurgePlusPlus => vec![ConstructEffect {effect: Effect::Purge, duration: 4, meta: None, tick: None}], - Skill::Link => vec![ConstructEffect {effect: Effect::Link, duration: 2, meta: None, tick: None}], - Skill::LinkPlus => vec![ConstructEffect {effect: Effect::Link, duration: 3, meta: None, tick: None}], - Skill::LinkPlusPlus => vec![ConstructEffect {effect: Effect::Link, duration: 4, meta: None, tick: None}], + Skill::Link => vec![ConstructEffect {effect: Effect::Stun, duration: 3, meta: None, tick: None}], + Skill::LinkPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], + Skill::LinkPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 1, meta: None, tick: None}], - Skill::Silence => vec![ConstructEffect {effect: Effect::Silence, duration: 2, meta: None, tick: None}], - Skill::SilencePlus => vec![ConstructEffect {effect: Effect::Silence, duration: 3, meta: None, tick: None}], - Skill::SilencePlusPlus => vec![ConstructEffect {effect: Effect::Silence, duration: 4, meta: None, tick: None}], + Skill::Silence => vec![ConstructEffect {effect: Effect::Silence, duration: 2, meta: None, tick: None}], + Skill::SilencePlus => vec![ConstructEffect {effect: Effect::Silence, duration: 3, meta: None, tick: None}], + Skill::SilencePlusPlus => vec![ConstructEffect {effect: Effect::Silence, duration: 4, meta: None, tick: None}], - Skill::Siphon => vec![ConstructEffect {effect: Effect::Siphon, duration: 2, - meta: Some(EffectMeta::Skill(Skill::SiphonTick)), tick: None}], - Skill::SiphonPlus => vec![ConstructEffect {effect: Effect::Siphon, duration: 3, - meta: Some(EffectMeta::Skill(Skill::SiphonTickPlus)), tick: None}], - Skill::SiphonPlusPlus => vec![ConstructEffect {effect: Effect::Siphon, duration: 4, - meta: Some(EffectMeta::Skill(Skill::SiphonTickPlusPlus)), tick: None}], + Skill::Siphon => vec![ConstructEffect {effect: Effect::Siphon, duration: 2, + meta: Some(EffectMeta::Skill(Skill::SiphonTick)), tick: None}], + Skill::SiphonPlus => vec![ConstructEffect {effect: Effect::Siphon, duration: 3, + meta: Some(EffectMeta::Skill(Skill::SiphonTickPlus)), tick: None}], + Skill::SiphonPlusPlus => vec![ConstructEffect {effect: Effect::Siphon, duration: 4, + meta: Some(EffectMeta::Skill(Skill::SiphonTickPlusPlus)), tick: None}], - Skill::Sleep => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], - Skill::SleepPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 3, meta: None, tick: None}], - Skill::SleepPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 4, meta: None, tick: None}], + Skill::Sleep => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], + Skill::SleepPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 3, meta: None, tick: None}], + Skill::SleepPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 4, meta: None, tick: None}], - Skill::Restrict => vec![ConstructEffect {effect: Effect::Restrict, duration: 2, meta: None, tick: None}], - Skill::RestrictPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 3, meta: None, tick: None}], - Skill::RestrictPlusPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 4, meta: None, tick: None}], + Skill::Restrict => vec![ConstructEffect {effect: Effect::Restrict, duration: 2, meta: None, tick: None}], + Skill::RestrictPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 3, meta: None, tick: None}], + Skill::RestrictPlusPlus => vec![ConstructEffect {effect: Effect::Restrict, duration: 4, meta: None, tick: None}], - Skill::Bash => vec![ConstructEffect {effect: Effect::Stun, duration: 2, - meta: Some(EffectMeta::Skill(Skill::Bash)), tick: None}], - Skill::BashPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, - meta: Some(EffectMeta::Skill(Skill::BashPlus)), tick: None}], - Skill::BashPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, - meta: Some(EffectMeta::Skill(Skill::BashPlusPlus)), tick: None}], - Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], + Skill::Bash => vec![ConstructEffect {effect: Effect::Stun, duration: 2, + meta: Some(EffectMeta::Skill(Skill::Bash)), tick: None}], + Skill::BashPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, + meta: Some(EffectMeta::Skill(Skill::BashPlus)), tick: None}], + Skill::BashPlusPlus => vec![ConstructEffect {effect: Effect::Stun, duration: 2, + meta: Some(EffectMeta::Skill(Skill::BashPlusPlus)), tick: None}], + Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, tick: None}], - Skill::Intercept => vec![ConstructEffect {effect: Effect::Intercept, duration: 2, meta: None, tick: None}], - Skill::InterceptPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 3, meta: None, tick: None}], - Skill::InterceptPlusPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 4, meta: None, tick: None}], + Skill::Intercept => vec![ConstructEffect {effect: Effect::Intercept, duration: 2, meta: None, tick: None}], + Skill::InterceptPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 3, meta: None, tick: None}], + Skill::InterceptPlusPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 4, meta: None, tick: None}], - Skill::Triage => vec![ConstructEffect {effect: Effect::Triage, duration: 2, - meta: Some(EffectMeta::Skill(Skill::TriageTick)), tick: None}], + Skill::Triage => vec![ConstructEffect {effect: Effect::Triage, duration: 2, + meta: Some(EffectMeta::Skill(Skill::TriageTick)), tick: None}], Skill::TriagePlus => vec![ConstructEffect {effect: Effect::Triage, duration: 3, meta: Some(EffectMeta::Skill(Skill::TriageTickPlus)), tick: None}], - Skill::TriagePlusPlus => vec![ConstructEffect {effect: Effect::Triage, duration: 4, + Skill::TriagePlusPlus => vec![ConstructEffect {effect: Effect::Triage, duration: 4, meta: Some(EffectMeta::Skill(Skill::TriageTickPlusPlus)), tick: None}], _ => { panic!("{:?} no skill effect", self); @@ -991,7 +981,7 @@ impl Skill { Skill::Block => None, // reduce damage Skill::Counter| Skill::CounterPlus | - Skill::CounterPlusPlus => Some(2), // avoid all damage + Skill::CounterPlusPlus => None, // avoid all damage Skill::Restrict=> Some(2), Skill::RestrictPlus => Some(2), @@ -1051,8 +1041,8 @@ impl Skill { Skill::SilencePlus => Some(2), Skill::SilencePlusPlus => Some(2), - Skill::Purify=> None, - Skill::PurifyPlus => None, + Skill::Purify | + Skill::PurifyPlus | Skill::PurifyPlusPlus => None, Skill::Purge=> None, @@ -1063,21 +1053,17 @@ impl Skill { Skill::BanishPlus => Some(1), Skill::BanishPlusPlus => Some(1), - Skill::Hex=> Some(1), - Skill::HexPlus => Some(2), - Skill::HexPlusPlus => Some(2), - Skill::Haste=> Some(2), Skill::HastePlus => Some(2), Skill::HastePlusPlus => Some(2), - Skill::Reflect=> Some(2), - Skill::ReflectPlus => Some(2), - Skill::ReflectPlusPlus => Some(2), + Skill::Reflect | + Skill::ReflectPlus | + Skill::ReflectPlusPlus => None, - Skill::Recharge=> Some(2), - Skill::RechargePlus => Some(2), - Skill::RechargePlusPlus => Some(2), + Skill::Recharge=> None, + Skill::RechargePlus => None, + Skill::RechargePlusPlus => None, Skill::Ruin=> Some(3), Skill::RuinPlus => Some(2), @@ -1091,17 +1077,17 @@ impl Skill { Skill::SleepPlus => Some(3), Skill::SleepPlusPlus => Some(3), - Skill::Sustain=> Some(1), - Skill::SustainPlus => Some(2), - Skill::SustainPlusPlus => Some(3), + Skill::Sustain | + Skill::SustainPlus | + Skill::SustainPlusPlus => Some(1), Skill::Intercept=> Some(2), Skill::InterceptPlus => Some(2), Skill::InterceptPlusPlus => Some(2), - Skill::Electrify=>Some(1), - Skill::ElectrifyPlus =>Some(1), - Skill::ElectrifyPlusPlus =>Some(1), + Skill::Electrify | + Skill::ElectrifyPlus | + Skill::ElectrifyPlusPlus => None, Skill::Absorb| @@ -1180,10 +1166,6 @@ impl Skill { pub fn speed(&self) -> u64 { match self { - Skill::Strike=> Item::from(Skill::Strike).speed().pct(150), - Skill::StrikePlus => Skill::Strike.speed(), - Skill::StrikePlusPlus => Skill::Strike.speed(), - Skill::SiphonTick| Skill::SiphonTickPlus | Skill::SiphonTickPlusPlus => Skill::Siphon.speed(), @@ -1213,20 +1195,6 @@ impl Skill { } } - pub fn self_targeting(&self) -> bool { - match self { - Skill::Block | - Skill::Sustain| - Skill::SustainPlus | - Skill::SustainPlusPlus | - Skill::Counter| - Skill::CounterPlus | - Skill::CounterPlusPlus => true, - - _ => false, - } - } - pub fn defensive(&self) -> bool { let mut rng = thread_rng(); @@ -1376,8 +1344,14 @@ fn sleep(source: &mut Construct, target: &mut Construct, mut results: Resolution } fn sustain(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - skill.effect().into_iter() - .for_each(|e| (results.push(Resolution::new(source, target).event(target.add_effect(skill, e))))); + let red_amount = source.red_power().pct(skill.multiplier()); + results.push(Resolution::new(source, target) + .event(target.recharge(skill, red_amount, 0))); + + results.push(Resolution::new(source, target) + .event(target.add_effect(skill, skill.effect()[0])) + .stages(EventStages::PostOnly)); + return results; } @@ -1413,19 +1387,17 @@ fn buff(source: &mut Construct, target: &mut Construct, mut results: Resolutions } fn counter(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let red_amount = source.red_power().pct(skill.multiplier()); results.push(Resolution::new(source, target) - .event(target.recharge(skill, red_amount, 0)) - .stages(EventStages::StartEnd)); + .event(target.add_effect(skill, skill.effect()[0]))); results.push(Resolution::new(source, target) - .event(target.add_effect(skill, skill.effect()[0])) + .event(target.add_effect(skill, skill.effect()[1])) .stages(EventStages::PostOnly)); return results; } -fn riposte(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { +fn counter_attack(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { let amount = source.red_power().pct(skill.multiplier()); target.deal_red_damage(skill, amount) .into_iter() @@ -1602,12 +1574,6 @@ fn ruin(source: &mut Construct, target: &mut Construct, mut results: Resolutions return results;; } - -fn hex(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); - return results;; -} - fn absorb(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); return results;; @@ -1688,42 +1654,25 @@ fn siphon_tick(source: &mut Construct, target: &mut Construct, mut results: Reso } fn link(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let blue_amount = source.blue_power().pct(skill.multiplier()); - results.push(Resolution::new(source, target).event(target.recharge(skill, 0, blue_amount))); + let swap = match target.green_life().checked_sub(source.green_life()) { + Some(s) => s.pct(skill.multiplier()), + None => 0 + }; - let link = skill.effect()[0].set_meta(EffectMeta::LinkTarget(target.id)); - results.push(Resolution::new(source, target).event(source.add_effect(skill, link)).stages(EventStages::PostOnly)); + target.deal_blue_damage(skill, swap) + .into_iter() + .for_each(|e| results.push(Resolution::new(source, target).event(e))); + + source.deal_green_damage(skill, swap) + .into_iter() + .for_each(|e| results.push(Resolution::new(source, source).event(e).stages(EventStages::PostOnly))); + + results.push(Resolution::new(source, source) + .event(source.add_effect(skill, skill.effect()[0])).stages(EventStages::PostOnly)); return results; } -fn link_hit(source: &Construct, target: &Construct, mut results: Resolutions, game: &mut Game, event: Event) -> Resolutions { - match event { - Event::Damage { amount, skill, mitigation: _, colour } => { - let link = target.effects.iter().find(|e| e.effect == Effect::Link).unwrap(); - - if let Some(EffectMeta::LinkTarget(link_target_id)) = link.meta { - let mut link_target = game.construct_by_id(link_target_id).unwrap(); - - let res = match colour { - Colour::Red => link_target.deal_red_damage(skill, amount), - Colour::Blue => link_target.deal_blue_damage(skill, amount), - Colour::Green => link_target.deal_green_damage(skill, amount), - }; - - results.push(Resolution::new(target, link_target).event(Event::Skill { skill: Skill::Link})); - res.into_iter().for_each(|e| results.push(Resolution::new(&source, &link_target) - .event(e).stages(EventStages::EndPost))); - } else { - panic!("not a link target {:?}", link); - } - - return results; - }, - _ => panic!("{:?} link hit not damage event", event), - } -} - fn silence(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0]))); @@ -1758,7 +1707,10 @@ fn purge(source: &mut Construct, target: &mut Construct, mut results: Resolution .event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() })); } - let mut turns = 1; + let effect = skill.effect()[0]; + results.push(Resolution::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); + + /*let mut turns = 1; for cs in target.skills.iter_mut() { if Effect::Purge.disables_skill(cs.skill) { turns += 1; @@ -1766,10 +1718,8 @@ fn purge(source: &mut Construct, target: &mut Construct, mut results: Resolution } if turns > 1 { - let mut effect = skill.effect()[0]; effect.duration = effect.duration * turns; - results.push(Resolution::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); - } + }*/ return results; } @@ -1878,7 +1828,7 @@ mod tests { sustain(&mut y.clone(), &mut y, vec![], Skill::Sustain); assert!(y.affected(Effect::Sustain)); - let mut results = hex(&mut x, &mut y, vec![], Skill::Hex); + let mut results = ruin(&mut x, &mut y, vec![], Skill::Ruin); let Resolution { source: _, target: _, event, stages: _ } = results.remove(0); match event { Event::Immunity { skill: _, immunity } => assert!(immunity.contains(&Effect::Sustain)), @@ -2113,8 +2063,8 @@ mod tests { .learn(Skill::HealPlus); purge(&mut x, &mut y, vec![], Skill::Purge); - // current turn + 2 turns at lvl 1 - assert!(y.effects.iter().any(|e| e.effect == Effect::Purge && e.duration == 3)); + // 2 turns at lvl 1 + assert!(y.effects.iter().any(|e| e.effect == Effect::Purge && e.duration == 2)); assert!(y.disabled(Skill::Heal).is_some()); } }