Merge branch 'release/1.9.0'
This commit is contained in:
commit
816470e879
21
CHANGELOG.md
21
CHANGELOG.md
@ -1,4 +1,23 @@
|
|||||||
## [1.8.3] - 2019-11-10
|
## [1.9.0] - 2019-11-21
|
||||||
|
### Changed
|
||||||
|
- VBOX
|
||||||
|
- You can now buy and combine from the VBOX and your inventory at the same time.
|
||||||
|
- Performance
|
||||||
|
- Websocket messages are now compressed in transit.
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Concede Round
|
||||||
|
- You can now concede game rounds, coward.
|
||||||
|
|
||||||
|
## [1.8.5] - 2019-11-16
|
||||||
|
### Fixed
|
||||||
|
- Multiple ko event bug
|
||||||
|
|
||||||
|
## [1.8.4] - 2019-11-14
|
||||||
|
### Fixed
|
||||||
|
- Bug with tutorial introduced in last patch
|
||||||
|
|
||||||
|
## [1.8.3] - 2019-11-13
|
||||||
### Added
|
### Added
|
||||||
- Preview combos by hovering over recipes
|
- Preview combos by hovering over recipes
|
||||||
- Condensed recipe display
|
- Condensed recipe display
|
||||||
|
|||||||
91
WORKLOG.md
91
WORKLOG.md
@ -4,40 +4,53 @@
|
|||||||
*PRODUCTION*
|
*PRODUCTION*
|
||||||
|
|
||||||
* can't reset password without knowing password =\
|
* can't reset password without knowing password =\
|
||||||
* ws gzip encoding
|
|
||||||
|
|
||||||
* Graphics
|
* Graphics
|
||||||
* Img
|
* Img
|
||||||
* Skill Icons
|
* Skill Icons
|
||||||
* Buttons / General UI Theming
|
* Buttons / General UI Theming
|
||||||
* Front Page
|
* Front Page
|
||||||
|
* Power / Speed / Life Icons - "Make use of piggybacking"
|
||||||
|
- Power (e.g. lightning bolt)
|
||||||
|
- Speed (e.g. boots)
|
||||||
|
- Life (e.g. heart)
|
||||||
|
|
||||||
|
* reduce inventory size and consolidate vbox and inventory on left side
|
||||||
|
|
||||||
|
* audio
|
||||||
|
* background music
|
||||||
|
* animation effects
|
||||||
|
* vbox combine / buy / equip etc
|
||||||
|
|
||||||
|
* reclaim change colour from red (clashes with red items)
|
||||||
|
|
||||||
|
* represent construct colours during game phase (coloured border?)
|
||||||
|
* supporter gold name in instance (anyone whos put any money into game)
|
||||||
|
|
||||||
|
* Give the bots some ai / make stronger so its a challenge for new people to beat
|
||||||
|
- train a few games of with some round losses to get them into the game
|
||||||
|
|
||||||
|
* Speed up animations slightly (3s per normal event too long)
|
||||||
|
- Improve combat text to start at the opposite end of construct and float towards health stats
|
||||||
|
- Show combat text for skill cast possibly? Watch some pokemans etc for modern combat smoothing
|
||||||
|
|
||||||
|
* skip faceoff on server side
|
||||||
|
|
||||||
## SOON
|
## SOON
|
||||||
* Graphical status effects instead of text
|
|
||||||
* Improve colour contrast / buttons
|
|
||||||
|
|
||||||
* supporter gold name in instance (anyone whos put any money into game)
|
* buy from preview if you have the required bases in vbox / inventory
|
||||||
|
- a "buy" becomes available under the current info / preview section
|
||||||
|
- clicking the buy automatically purchases / combine items
|
||||||
|
- could also be used to upgrade already equipped skills / specs
|
||||||
|
- e.g. an equipped white power spec could be upgraded by clicking under preview
|
||||||
|
- if this was added we could reduce inventory size to 3 and rearrange vbox (see mockup img)
|
||||||
|
|
||||||
|
|
||||||
* change cooldowns to delay & recharge
|
* change cooldowns to delay & recharge
|
||||||
- delay is cooldown before skill can first be used
|
- delay is cooldown before skill can first be used
|
||||||
- recharge is cooldown after using skill
|
- recharge is cooldown after using skill
|
||||||
- every x speed reduces delay of skills
|
- every x speed reduces delay of skills
|
||||||
|
|
||||||
* audio
|
|
||||||
|
|
||||||
* elo + leaderboards
|
|
||||||
* reconnect based on time delta
|
|
||||||
|
|
||||||
* ACP
|
|
||||||
* essential
|
|
||||||
|
|
||||||
## LATER
|
|
||||||
|
|
||||||
* theme toasts
|
|
||||||
* rework vecs into sets
|
|
||||||
* remove names so games/instances are copy
|
|
||||||
* consolidate game and instance
|
|
||||||
|
|
||||||
* combo rework
|
* combo rework
|
||||||
- reduce number of items for creating t2/t3 items from 3 -> 2
|
- reduce number of items for creating t2/t3 items from 3 -> 2
|
||||||
- add lost complexity by adding skill spec items
|
- add lost complexity by adding skill spec items
|
||||||
@ -48,18 +61,46 @@
|
|||||||
- Strike + SpeedRR -> StrikeSpeed (strike has Y% more speed)
|
- Strike + SpeedRR -> StrikeSpeed (strike has Y% more speed)
|
||||||
- Strike + LifeRR -> StrikeLife (Strike recharges X% of damage as red life)
|
- Strike + LifeRR -> StrikeLife (Strike recharges X% of damage as red life)
|
||||||
|
|
||||||
|
- Can also work as module style passive keystones
|
||||||
|
* troll life -> dmg -> Invert life spec?
|
||||||
|
* prince of peace
|
||||||
|
* bonus healing / no damage -> Heal power spec?
|
||||||
|
* fuck magic -> Some sort of reflect spec?
|
||||||
|
* empower on ko -> Amplify + Power spec
|
||||||
|
|
||||||
|
* elo + leaderboards
|
||||||
|
* reconnect based on time delta
|
||||||
|
|
||||||
|
* ACP
|
||||||
|
* essential
|
||||||
|
|
||||||
|
## LATER
|
||||||
|
|
||||||
|
* Graphical status effects instead of text
|
||||||
|
|
||||||
|
* theme toasts
|
||||||
|
|
||||||
|
* rework vecs into sets
|
||||||
|
* constructs
|
||||||
|
* effects
|
||||||
|
* parent
|
||||||
|
* children
|
||||||
|
|
||||||
|
* remove names so games/instances are copy
|
||||||
|
* consolidate game and instance
|
||||||
|
|
||||||
|
* Energy generators / spenders
|
||||||
|
- Current skills generate team wide red / blue / green energy
|
||||||
|
- New special skill base consumes team energy to do "special" powerful moves
|
||||||
|
- Working as cooldowns in reverse by building up to the skill rather than waiting
|
||||||
|
|
||||||
* constants
|
* constants
|
||||||
* (maybe) return of the combat log (last few events with condensed descriptions)
|
* (maybe) return of the combat log (last few events with condensed descriptions)
|
||||||
- click in to scroll
|
- click in to scroll
|
||||||
|
|
||||||
* mnml tv
|
* mnml tv
|
||||||
|
|
||||||
* modules
|
|
||||||
* troll life -> dmg
|
|
||||||
* prince of peace
|
|
||||||
* bonus healing / no damage
|
|
||||||
* fuck magic
|
|
||||||
* empower on ko
|
|
||||||
|
|
||||||
## $$$
|
## $$$
|
||||||
* Items
|
* Items
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml-client",
|
"name": "mnml-client",
|
||||||
"version": "1.8.3",
|
"version": "1.9.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -162,6 +162,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.construct-list {
|
.construct-list {
|
||||||
|
button {
|
||||||
|
&.highlight {
|
||||||
|
color: black;
|
||||||
|
background: @white;
|
||||||
|
// border: 1px solid @white; (this bangs around the vbox)
|
||||||
|
|
||||||
|
// overwrite the classes on white svg elements
|
||||||
|
svg {
|
||||||
|
stroke-width: 0.75em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.white {
|
||||||
|
stroke: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
grid-area: name;
|
grid-area: name;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
|
|||||||
13
client/assets/styles/skeleton.css
vendored
13
client/assets/styles/skeleton.css
vendored
@ -188,19 +188,6 @@ input[type="button"] {
|
|||||||
border: 1px solid #bbb;
|
border: 1px solid #bbb;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-sizing: border-box; }
|
box-sizing: border-box; }
|
||||||
.button:hover,
|
|
||||||
button:hover,
|
|
||||||
input[type="submit"]:hover,
|
|
||||||
input[type="reset"]:hover,
|
|
||||||
input[type="button"]:hover,
|
|
||||||
.button:focus,
|
|
||||||
button:focus,
|
|
||||||
input[type="submit"]:focus,
|
|
||||||
input[type="reset"]:focus,
|
|
||||||
input[type="button"]:focus {
|
|
||||||
color: #333;
|
|
||||||
border-color: #888;
|
|
||||||
outline: 0; }
|
|
||||||
.button.button-primary,
|
.button.button-primary,
|
||||||
button.button-primary,
|
button.button-primary,
|
||||||
input[type="submit"].button-primary,
|
input[type="submit"].button-primary,
|
||||||
|
|||||||
@ -147,8 +147,8 @@ button, input {
|
|||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
/*colour necesary to bash skellington*/
|
/*colour necesary to bash skellington*/
|
||||||
color: @gray-focus;
|
|
||||||
border-color: @gray-focus;
|
outline: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -731,7 +731,21 @@ pre {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style><title>CHANGELOG</title></head><body><article class="markdown-body"><h2>
|
</style><title>CHANGELOG</title></head><body><article class="markdown-body"><h2>
|
||||||
<a id="user-content-183---2019-11-10" class="anchor" href="#183---2019-11-10" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.3] - 2019-11-10</h2>
|
<a id="user-content-185---2019-11-16" class="anchor" href="#185---2019-11-16" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.5] - 2019-11-16</h2>
|
||||||
|
<h3>
|
||||||
|
<a id="user-content-fixed" class="anchor" href="#fixed" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Multiple ko event bug</li>
|
||||||
|
</ul>
|
||||||
|
<h2>
|
||||||
|
<a id="user-content-184---2019-11-14" class="anchor" href="#184---2019-11-14" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.4] - 2019-11-14</h2>
|
||||||
|
<h3>
|
||||||
|
<a id="user-content-fixed-1" class="anchor" href="#fixed-1" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
|
<ul>
|
||||||
|
<li>Bug with tutorial introduced in last patch</li>
|
||||||
|
</ul>
|
||||||
|
<h2>
|
||||||
|
<a id="user-content-183---2019-11-13" class="anchor" href="#183---2019-11-13" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.3] - 2019-11-13</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-added" class="anchor" href="#added" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Added</h3>
|
<a id="user-content-added" class="anchor" href="#added" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Added</h3>
|
||||||
<ul>
|
<ul>
|
||||||
@ -739,7 +753,7 @@ pre {
|
|||||||
<li>Condensed recipe display</li>
|
<li>Condensed recipe display</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed" class="anchor" href="#fixed" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-2" class="anchor" href="#fixed-2" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Construct display on info / demo page</li>
|
<li>Construct display on info / demo page</li>
|
||||||
<li>Case where a skill could send multiple ko events to target</li>
|
<li>Case where a skill could send multiple ko events to target</li>
|
||||||
@ -754,7 +768,7 @@ pre {
|
|||||||
<li>Purify
|
<li>Purify
|
||||||
<ul>
|
<ul>
|
||||||
<li>Now removes all effects on target</li>
|
<li>Now removes all effects on target</li>
|
||||||
<li>Applies "Purified" increasing healing taken</li>
|
<li>Applies "Pure" increasing healing taken</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
<li>Purge
|
<li>Purge
|
||||||
@ -766,14 +780,14 @@ pre {
|
|||||||
<h2>
|
<h2>
|
||||||
<a id="user-content-182---2019-11-10" class="anchor" href="#182---2019-11-10" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.2] - 2019-11-10</h2>
|
<a id="user-content-182---2019-11-10" class="anchor" href="#182---2019-11-10" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.2] - 2019-11-10</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed-1" class="anchor" href="#fixed-1" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-3" class="anchor" href="#fixed-3" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Duplicate button issue in reshape tab</li>
|
<li>Duplicate button issue in reshape tab</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2>
|
<h2>
|
||||||
<a id="user-content-181---2019-11-09" class="anchor" href="#181---2019-11-09" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.1] - 2019-11-09</h2>
|
<a id="user-content-181---2019-11-09" class="anchor" href="#181---2019-11-09" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.8.1] - 2019-11-09</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed-2" class="anchor" href="#fixed-2" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-4" class="anchor" href="#fixed-4" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>An issue where skills would not be put on cooldown after being used.</li>
|
<li>An issue where skills would not be put on cooldown after being used.</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1070,7 +1084,7 @@ pre {
|
|||||||
<h2>
|
<h2>
|
||||||
<a id="user-content-165---2019-10-25" class="anchor" href="#165---2019-10-25" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.6.5] - 2019-10-25</h2>
|
<a id="user-content-165---2019-10-25" class="anchor" href="#165---2019-10-25" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.6.5] - 2019-10-25</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed-3" class="anchor" href="#fixed-3" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-5" class="anchor" href="#fixed-5" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Stripe being blocked no longer causes unrecoverable error</li>
|
<li>Stripe being blocked no longer causes unrecoverable error</li>
|
||||||
<li>Automatic ready up is now throttled after abandons</li>
|
<li>Automatic ready up is now throttled after abandons</li>
|
||||||
@ -1102,7 +1116,7 @@ pre {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed-4" class="anchor" href="#fixed-4" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-6" class="anchor" href="#fixed-6" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Fixed issue where dots / hots would not trigger when reapplied at a higher speed</li>
|
<li>Fixed issue where dots / hots would not trigger when reapplied at a higher speed</li>
|
||||||
<li>Changed layout of home page. UI elements for rerolling construct avatars moved to a separate tab.</li>
|
<li>Changed layout of home page. UI elements for rerolling construct avatars moved to a separate tab.</li>
|
||||||
@ -1113,7 +1127,7 @@ pre {
|
|||||||
<h2>
|
<h2>
|
||||||
<a id="user-content-162---2019-10-20" class="anchor" href="#162---2019-10-20" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.6.2] - 2019-10-20</h2>
|
<a id="user-content-162---2019-10-20" class="anchor" href="#162---2019-10-20" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>[1.6.2] - 2019-10-20</h2>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed-5" class="anchor" href="#fixed-5" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-7" class="anchor" href="#fixed-7" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Combiner bug where it would preview items for different combinations</li>
|
<li>Combiner bug where it would preview items for different combinations</li>
|
||||||
<li>Skill descriptions are cleared when animations start</li>
|
<li>Skill descriptions are cleared when animations start</li>
|
||||||
@ -1152,7 +1166,7 @@ pre {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>
|
<h3>
|
||||||
<a id="user-content-fixed-6" class="anchor" href="#fixed-6" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
<a id="user-content-fixed-8" class="anchor" href="#fixed-8" aria-hidden="true"><span aria-hidden="true" class="octicon octicon-link"></span></a>Fixed</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Matchmaking bug where server matches you with yourself</li>
|
<li>Matchmaking bug where server matches you with yourself</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml-client",
|
"name": "mnml-client",
|
||||||
"version": "1.8.3",
|
"version": "1.9.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -16,7 +16,6 @@ export const setInstanceChat = value => ({ type: 'SET_INSTANCE_CHAT', value });
|
|||||||
|
|
||||||
export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value });
|
export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value });
|
||||||
export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null });
|
export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null });
|
||||||
export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) });
|
|
||||||
export const setConstructEditId = value => ({ type: 'SET_CONSTRUCT_EDIT_ID', value });
|
export const setConstructEditId = value => ({ type: 'SET_CONSTRUCT_EDIT_ID', value });
|
||||||
export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value });
|
export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value });
|
||||||
export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', value });
|
export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', value });
|
||||||
@ -30,7 +29,6 @@ export const setEmail = value => ({ type: 'SET_EMAIL', value });
|
|||||||
export const setInvite = value => ({ type: 'SET_INVITE', value });
|
export const setInvite = value => ({ type: 'SET_INVITE', value });
|
||||||
export const setInstance = value => ({ type: 'SET_INSTANCE', value });
|
export const setInstance = value => ({ type: 'SET_INSTANCE', value });
|
||||||
export const setInstances = value => ({ type: 'SET_INSTANCES', value });
|
export const setInstances = value => ({ type: 'SET_INSTANCES', value });
|
||||||
export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value });
|
|
||||||
export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
|
export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
|
||||||
export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value });
|
export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value });
|
||||||
export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value });
|
export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value });
|
||||||
|
|||||||
@ -33,11 +33,9 @@ const addState = connect(
|
|||||||
function accountPage() {
|
function accountPage() {
|
||||||
dispatch(actions.setGame(null));
|
dispatch(actions.setGame(null));
|
||||||
dispatch(actions.setInstance(null));
|
dispatch(actions.setInstance(null));
|
||||||
dispatch(actions.setCombiner([]));
|
|
||||||
dispatch(actions.setReclaiming(false));
|
dispatch(actions.setReclaiming(false));
|
||||||
dispatch(actions.setActiveSkill(null));
|
dispatch(actions.setActiveSkill(null));
|
||||||
dispatch(actions.setInfo(null));
|
dispatch(actions.setInfo(null));
|
||||||
dispatch(actions.setItemEquip(null));
|
|
||||||
dispatch(actions.setItemUnequip([]));
|
dispatch(actions.setItemUnequip([]));
|
||||||
dispatch(actions.setVboxHighlight([]));
|
dispatch(actions.setVboxHighlight([]));
|
||||||
return dispatch(actions.setNav('account'));
|
return dispatch(actions.setNav('account'));
|
||||||
|
|||||||
@ -35,7 +35,7 @@ class ConstructAvatar extends Component {
|
|||||||
class="avatar"
|
class="avatar"
|
||||||
id={construct.id}
|
id={construct.id}
|
||||||
onMouseDown={this.onClick.bind(this)}
|
onMouseDown={this.onClick.bind(this)}
|
||||||
onMouseOver={mouseOver ? mouseOver : null}
|
onMouseOver={mouseOver}
|
||||||
style={{ 'background-image': `url(/imgs/${construct.img}.svg)` }}>
|
style={{ 'background-image': `url(/imgs/${construct.img}.svg)` }}>
|
||||||
<ConstructAnimation construct={construct} />
|
<ConstructAnimation construct={construct} />
|
||||||
</div>
|
</div>
|
||||||
@ -86,11 +86,12 @@ class ConstructAvatar extends Component {
|
|||||||
|
|
||||||
|
|
||||||
shouldComponentUpdate(newProps) {
|
shouldComponentUpdate(newProps) {
|
||||||
const { animSource, animTarget, animText, construct } = newProps;
|
const { animSource, animTarget, animText, construct, mouseOver } = newProps;
|
||||||
if (animSource !== this.props.animSource) return true;
|
if (animSource !== this.props.animSource) return true;
|
||||||
if (animTarget !== this.props.animTarget) return true;
|
if (animTarget !== this.props.animTarget) return true;
|
||||||
if (animText !== this.props.animText) return true;
|
if (animText !== this.props.animText) return true;
|
||||||
if (construct !== this.props.construct) return true;
|
if (construct !== this.props.construct) return true;
|
||||||
|
if (mouseOver !== this.props.mouseOver) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,12 +20,17 @@ const addState = connect(
|
|||||||
return ws.sendGameOfferDraw(game.id);
|
return ws.sendGameOfferDraw(game.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendConcede() {
|
||||||
|
return ws.sendGameConcede(game.id);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
game,
|
game,
|
||||||
account,
|
account,
|
||||||
|
|
||||||
sendAbandon,
|
sendAbandon,
|
||||||
sendDraw,
|
sendDraw,
|
||||||
|
sendConcede,
|
||||||
animating,
|
animating,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -49,11 +54,12 @@ function GameCtrlTopBtns(args) {
|
|||||||
leave,
|
leave,
|
||||||
sendAbandon,
|
sendAbandon,
|
||||||
sendDraw,
|
sendDraw,
|
||||||
|
sendConcede,
|
||||||
animating,
|
animating,
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
const finished = game && game.phase === 'Finished';
|
const finished = game && game.phase === 'Finished';
|
||||||
const { abandonState, drawState } = this.state;
|
const { abandonState, drawState, concedeState } = this.state;
|
||||||
|
|
||||||
const player = game.players.find(p => p.id === account.id);
|
const player = game.players.find(p => p.id === account.id);
|
||||||
const drawOffered = player && player.draw_offered;
|
const drawOffered = player && player.draw_offered;
|
||||||
@ -70,6 +76,12 @@ function GameCtrlTopBtns(args) {
|
|||||||
setTimeout(() => this.setState({ drawState: false }), 2000);
|
setTimeout(() => this.setState({ drawState: false }), 2000);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const concedeStateTrue = e => {
|
||||||
|
e.stopPropagation();
|
||||||
|
this.setState({ concedeState: true });
|
||||||
|
setTimeout(() => this.setState({ concedeState: false }), 2000);
|
||||||
|
};
|
||||||
|
|
||||||
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
|
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
|
||||||
const abandonText = abandonState ? 'Confirm' : 'Abandon';
|
const abandonText = abandonState ? 'Confirm' : 'Abandon';
|
||||||
const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
|
const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
|
||||||
@ -83,9 +95,15 @@ function GameCtrlTopBtns(args) {
|
|||||||
const drawAction = drawState ? sendDraw : drawStateTrue;
|
const drawAction = drawState ? sendDraw : drawStateTrue;
|
||||||
const drawBtn = <button class={drawClasses} disabled={finished || animating || drawOffered} onClick={drawAction}>{drawText}</button>;
|
const drawBtn = <button class={drawClasses} disabled={finished || animating || drawOffered} onClick={drawAction}>{drawText}</button>;
|
||||||
|
|
||||||
|
const concedeClasses = `draw ${concedeState ? 'confirming' : ''}`;
|
||||||
|
const concedeText = concedeState ? 'Round' : 'Concede';
|
||||||
|
const concedeAction = concedeState ? sendConcede : concedeStateTrue;
|
||||||
|
const concedeBtn = <button class={concedeClasses} disabled={finished || animating } onClick={concedeAction}>{concedeText}</button>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="instance-ctrl-btns">
|
<div class="instance-ctrl-btns">
|
||||||
{abandonBtn}
|
{abandonBtn}
|
||||||
|
{concedeBtn}
|
||||||
{drawBtn}
|
{drawBtn}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -32,11 +32,9 @@ const addState = connect(
|
|||||||
function setNav(place) {
|
function setNav(place) {
|
||||||
dispatch(actions.setGame(null));
|
dispatch(actions.setGame(null));
|
||||||
dispatch(actions.setInstance(null));
|
dispatch(actions.setInstance(null));
|
||||||
dispatch(actions.setCombiner([]));
|
|
||||||
dispatch(actions.setReclaiming(false));
|
dispatch(actions.setReclaiming(false));
|
||||||
dispatch(actions.setActiveSkill(null));
|
dispatch(actions.setActiveSkill(null));
|
||||||
dispatch(actions.setInfo(null));
|
dispatch(actions.setInfo(null));
|
||||||
dispatch(actions.setItemEquip(null));
|
|
||||||
dispatch(actions.setItemUnequip([]));
|
dispatch(actions.setItemUnequip([]));
|
||||||
dispatch(actions.setVboxHighlight([]));
|
dispatch(actions.setVboxHighlight([]));
|
||||||
dispatch(actions.setMtxActive(null));
|
dispatch(actions.setMtxActive(null));
|
||||||
|
|||||||
@ -7,7 +7,6 @@ const addState = connect(
|
|||||||
function receiveState(state) {
|
function receiveState(state) {
|
||||||
const {
|
const {
|
||||||
ws,
|
ws,
|
||||||
combiner,
|
|
||||||
info,
|
info,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
instance,
|
instance,
|
||||||
@ -18,7 +17,6 @@ const addState = connect(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
ws,
|
ws,
|
||||||
combiner,
|
|
||||||
info,
|
info,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
instance,
|
instance,
|
||||||
|
|||||||
@ -27,12 +27,10 @@ const addState = connect(
|
|||||||
|
|
||||||
|
|
||||||
function clearItems() {
|
function clearItems() {
|
||||||
dispatch(actions.setCombiner([]));
|
|
||||||
dispatch(actions.setReclaiming(false));
|
dispatch(actions.setReclaiming(false));
|
||||||
dispatch(actions.setItemEquip(null));
|
|
||||||
dispatch(actions.setItemUnequip([]));
|
dispatch(actions.setItemUnequip([]));
|
||||||
dispatch(actions.setVboxHighlight([]));
|
dispatch(actions.setVboxHighlight([]));
|
||||||
dispatch(actions.setVboxSelected([]));
|
dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] }));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,24 +19,19 @@ const addState = connect(
|
|||||||
player,
|
player,
|
||||||
account,
|
account,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
itemEquip,
|
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
vboxSelected,
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
function sendVboxAcceptEquip(constructId) {
|
function sendVboxAcceptEquip(constructId) {
|
||||||
return ws.sendVboxAcceptEquip(instance.id, vboxSelected[0], vboxSelected[1], constructId);
|
return ws.sendVboxAcceptEquip(instance.id, vboxSelected.shopSelect[0][0], vboxSelected.shopSelect[0][1], constructId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendVboxApply(constructId, i) {
|
function sendVboxApply(constructId, i) {
|
||||||
return ws.sendVboxApply(instance.id, constructId, i);
|
return ws.sendVboxApply(instance.id, constructId, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendUnequip(constructId, item) {
|
|
||||||
return ws.sendVboxUnequip(instance.id, constructId, item);
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendVboxUnequipApply(targetConstructId) {
|
function sendVboxUnequipApply(targetConstructId) {
|
||||||
return ws.sendVboxUnequipApply(instance.id, itemUnequip[0], itemUnequip[1], targetConstructId);
|
return ws.sendVboxUnequipApply(instance.id, itemUnequip[0], itemUnequip[1], targetConstructId);
|
||||||
}
|
}
|
||||||
@ -49,9 +44,7 @@ const addState = connect(
|
|||||||
sendVboxUnequipApply,
|
sendVboxUnequipApply,
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
itemEquip,
|
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
sendUnequip,
|
|
||||||
vboxSelected,
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
};
|
};
|
||||||
@ -66,15 +59,12 @@ const addState = connect(
|
|||||||
dispatch(actions.setInfo(item));
|
dispatch(actions.setInfo(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setItemEquip(v) {
|
|
||||||
return dispatch(actions.setItemEquip(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setItemUnequip(v) {
|
function setItemUnequip(v) {
|
||||||
|
dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] }));
|
||||||
return dispatch(actions.setItemUnequip(v));
|
return dispatch(actions.setItemUnequip(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
return { quit, setInfo, setItemUnequip, setItemEquip };
|
return { quit, setInfo, setItemUnequip };
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
@ -84,7 +74,6 @@ function Construct(props) {
|
|||||||
// Changing state variables
|
// Changing state variables
|
||||||
construct,
|
construct,
|
||||||
iter,
|
iter,
|
||||||
itemEquip,
|
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
instance,
|
instance,
|
||||||
player,
|
player,
|
||||||
@ -96,13 +85,16 @@ function Construct(props) {
|
|||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
sendVboxAcceptEquip,
|
sendVboxAcceptEquip,
|
||||||
sendVboxUnequipApply,
|
sendVboxUnequipApply,
|
||||||
sendUnequip,
|
|
||||||
setItemUnequip,
|
setItemUnequip,
|
||||||
setItemEquip,
|
|
||||||
setInfo,
|
setInfo,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const { vbox } = player;
|
const { vbox } = player;
|
||||||
|
|
||||||
|
const itemEquip = vboxSelected.shopSelect.length === 0 && vboxSelected.stashSelect.length === 1
|
||||||
|
? vboxSelected.stashSelect[0]
|
||||||
|
: -1;
|
||||||
|
|
||||||
const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => {
|
const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => {
|
||||||
if (!itemEquip && itemEquip !== 0) return false;
|
if (!itemEquip && itemEquip !== 0) return false;
|
||||||
if (!sk) return false;
|
if (!sk) return false;
|
||||||
@ -113,17 +105,16 @@ function Construct(props) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (duplicateSkill || tutorialDisableEquip) return true;
|
if (duplicateSkill || tutorialDisableEquip) return true;
|
||||||
if (itemEquip !== null) return sendVboxApply(construct.id, itemEquip);
|
if (itemEquip !== -1) return sendVboxApply(construct.id, itemEquip);
|
||||||
if (vboxSelected[0]) return sendVboxAcceptEquip(construct.id);
|
if (vboxSelected.shopSelect.length === 1) return sendVboxAcceptEquip(construct.id);
|
||||||
if (itemUnequip.length && itemUnequip[0] !== construct.id) return sendVboxUnequipApply(construct.id);
|
if (itemUnequip.length && itemUnequip[0] !== construct.id) return sendVboxUnequipApply(construct.id);
|
||||||
setItemEquip(null);
|
|
||||||
setItemUnequip([]);
|
setItemUnequip([]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hoverInfo(e, info) {
|
function hoverInfo(e, info) {
|
||||||
if (!info) return false;
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
if (!info) return false;
|
||||||
|
if (vboxSelected.shopSelect.length || vboxSelected.stashSelect.length) return false;
|
||||||
return setInfo(info);
|
return setInfo(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,20 +129,11 @@ function Construct(props) {
|
|||||||
|
|
||||||
function skillClick(e) {
|
function skillClick(e) {
|
||||||
if (!skill) return false;
|
if (!skill) return false;
|
||||||
setItemUnequip([construct.id, skill.skill]);
|
setItemUnequip([construct.id, skill.skill, i]);
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function skillDblClick(e) {
|
|
||||||
if (!skill) return false;
|
|
||||||
sendUnequip(construct.id, skill.skill);
|
|
||||||
setItemUnequip([]);
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const equipping = skillList.includes(vbox.bound[itemEquip]) && !skill
|
const equipping = skillList.includes(vbox.bound[itemEquip]) && !skill
|
||||||
&& !tutorialDisableEquip && !duplicateSkill && i === construct.skills.length;
|
&& !tutorialDisableEquip && !duplicateSkill && i === construct.skills.length;
|
||||||
const border = () => {
|
const border = () => {
|
||||||
@ -161,7 +143,9 @@ function Construct(props) {
|
|||||||
return borderFn();
|
return borderFn();
|
||||||
};
|
};
|
||||||
|
|
||||||
const classes = `${equipping ? 'equipping' : ''} ${!skill ? 'empty' : ''} ${border()}`;
|
const highlight = itemUnequip[0] === construct.id && itemUnequip[1] === s ? 'highlight' : '';
|
||||||
|
|
||||||
|
const classes = `${highlight} ${equipping ? 'equipping' : ''} ${!skill ? 'empty' : ''} ${border()}`;
|
||||||
return (
|
return (
|
||||||
<label onDragStart={ev => {
|
<label onDragStart={ev => {
|
||||||
ev.dataTransfer.setData('text', '');
|
ev.dataTransfer.setData('text', '');
|
||||||
@ -172,7 +156,6 @@ function Construct(props) {
|
|||||||
disabled={!skill && !equipping}
|
disabled={!skill && !equipping}
|
||||||
class={classes}
|
class={classes}
|
||||||
onClick={skillClick}
|
onClick={skillClick}
|
||||||
onDblClick={skillDblClick}
|
|
||||||
onMouseOver={e => hoverInfo(e, skill && skill.skill)} >
|
onMouseOver={e => hoverInfo(e, skill && skill.skill)} >
|
||||||
{s}
|
{s}
|
||||||
</button>
|
</button>
|
||||||
@ -195,18 +178,10 @@ function Construct(props) {
|
|||||||
|
|
||||||
function specClick(e) {
|
function specClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setItemUnequip([construct.id, s]);
|
setItemUnequip([construct.id, s, i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function specDblClick(e) {
|
const highlight = itemUnequip[0] === construct.id && itemUnequip[1] === s && i === itemUnequip[2];
|
||||||
sendUnequip(construct.id, s);
|
|
||||||
setItemUnequip([]);
|
|
||||||
e.stopPropagation();
|
|
||||||
e.preventDefault();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label onDragStart={ev => {
|
<label onDragStart={ev => {
|
||||||
ev.dataTransfer.setData('text', '');
|
ev.dataTransfer.setData('text', '');
|
||||||
@ -214,8 +189,8 @@ function Construct(props) {
|
|||||||
}} key={i} draggable="true" onDragEnd={() => setItemUnequip([])}>
|
}} key={i} draggable="true" onDragEnd={() => setItemUnequip([])}>
|
||||||
<button
|
<button
|
||||||
key={i}
|
key={i}
|
||||||
|
class={`${highlight ? 'highlight' : ''}`}
|
||||||
onClick={specClick}
|
onClick={specClick}
|
||||||
onDblClick={specDblClick}
|
|
||||||
onMouseOver={e => hoverInfo(e, s)} >
|
onMouseOver={e => hoverInfo(e, s)} >
|
||||||
{shapes[s]()}
|
{shapes[s]()}
|
||||||
</button>
|
</button>
|
||||||
@ -259,7 +234,6 @@ function Construct(props) {
|
|||||||
|
|
||||||
class InstanceConstructs extends preact.Component {
|
class InstanceConstructs extends preact.Component {
|
||||||
shouldComponentUpdate(newProps) {
|
shouldComponentUpdate(newProps) {
|
||||||
if (newProps.itemEquip !== this.props.itemEquip) return true;
|
|
||||||
if (newProps.itemUnequip !== this.props.itemUnequip) return true;
|
if (newProps.itemUnequip !== this.props.itemUnequip) return true;
|
||||||
if (newProps.tutorial !== this.props.tutorial) return true;
|
if (newProps.tutorial !== this.props.tutorial) return true;
|
||||||
// JSON or Array objects
|
// JSON or Array objects
|
||||||
@ -272,7 +246,6 @@ class InstanceConstructs extends preact.Component {
|
|||||||
render(props) {
|
render(props) {
|
||||||
const {
|
const {
|
||||||
// Changing state variables
|
// Changing state variables
|
||||||
itemEquip,
|
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
instance,
|
instance,
|
||||||
player,
|
player,
|
||||||
@ -287,8 +260,6 @@ class InstanceConstructs extends preact.Component {
|
|||||||
sendVboxUnequipApply,
|
sendVboxUnequipApply,
|
||||||
setVboxHighlight,
|
setVboxHighlight,
|
||||||
setItemUnequip,
|
setItemUnequip,
|
||||||
setItemEquip,
|
|
||||||
sendUnequip,
|
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
if (!player) return false;
|
if (!player) return false;
|
||||||
@ -301,11 +272,9 @@ class InstanceConstructs extends preact.Component {
|
|||||||
return Construct({
|
return Construct({
|
||||||
iter: i,
|
iter: i,
|
||||||
construct: player.constructs[i],
|
construct: player.constructs[i],
|
||||||
itemEquip,
|
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
instance,
|
instance,
|
||||||
setItemUnequip,
|
setItemUnequip,
|
||||||
setItemEquip,
|
|
||||||
player,
|
player,
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
sendVboxAcceptEquip,
|
sendVboxAcceptEquip,
|
||||||
@ -313,7 +282,6 @@ class InstanceConstructs extends preact.Component {
|
|||||||
setInfo,
|
setInfo,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
setVboxHighlight,
|
setVboxHighlight,
|
||||||
sendUnequip,
|
|
||||||
vboxSelected,
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
});
|
});
|
||||||
|
|||||||
@ -33,11 +33,9 @@ const addState = connect(
|
|||||||
function setNav(place) {
|
function setNav(place) {
|
||||||
dispatch(actions.setGame(null));
|
dispatch(actions.setGame(null));
|
||||||
dispatch(actions.setInstance(null));
|
dispatch(actions.setInstance(null));
|
||||||
dispatch(actions.setCombiner([]));
|
|
||||||
dispatch(actions.setReclaiming(false));
|
dispatch(actions.setReclaiming(false));
|
||||||
dispatch(actions.setActiveSkill(null));
|
dispatch(actions.setActiveSkill(null));
|
||||||
dispatch(actions.setInfo(null));
|
dispatch(actions.setInfo(null));
|
||||||
dispatch(actions.setItemEquip(null));
|
|
||||||
dispatch(actions.setItemUnequip([]));
|
dispatch(actions.setItemUnequip([]));
|
||||||
dispatch(actions.setVboxHighlight([]));
|
dispatch(actions.setVboxHighlight([]));
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const { connect } = require('preact-redux');
|
|||||||
const range = require('lodash/range');
|
const range = require('lodash/range');
|
||||||
const countBy = require('lodash/countBy');
|
const countBy = require('lodash/countBy');
|
||||||
const without = require('lodash/without');
|
const without = require('lodash/without');
|
||||||
|
const forEach = require('lodash/forEach');
|
||||||
|
|
||||||
const { removeTier } = require('../utils');
|
const { removeTier } = require('../utils');
|
||||||
const shapes = require('./shapes');
|
const shapes = require('./shapes');
|
||||||
@ -15,7 +16,6 @@ const addState = connect(
|
|||||||
ws,
|
ws,
|
||||||
instance,
|
instance,
|
||||||
player,
|
player,
|
||||||
combiner,
|
|
||||||
reclaiming,
|
reclaiming,
|
||||||
vboxSelected,
|
vboxSelected,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
@ -33,7 +33,7 @@ const addState = connect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sendVboxCombine() {
|
function sendVboxCombine() {
|
||||||
return ws.sendVboxCombine(instance.id, combiner);
|
return ws.sendVboxCombine(instance.id, vboxSelected.stashSelect, vboxSelected.shopSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendVboxReclaim(i) {
|
function sendVboxReclaim(i) {
|
||||||
@ -45,7 +45,6 @@ const addState = connect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
combiner,
|
|
||||||
instance,
|
instance,
|
||||||
player,
|
player,
|
||||||
reclaiming,
|
reclaiming,
|
||||||
@ -62,11 +61,9 @@ const addState = connect(
|
|||||||
},
|
},
|
||||||
|
|
||||||
function receiveDispatch(dispatch) {
|
function receiveDispatch(dispatch) {
|
||||||
function setCombiner(c) {
|
|
||||||
return dispatch(actions.setCombiner(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
function setReclaiming(v) {
|
function setReclaiming(v) {
|
||||||
|
dispatch(actions.setItemUnequip([]));
|
||||||
|
dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] }));
|
||||||
return dispatch(actions.setReclaiming(v));
|
return dispatch(actions.setReclaiming(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,28 +72,52 @@ const addState = connect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setVboxSelected(v) {
|
function setVboxSelected(v) {
|
||||||
|
dispatch(actions.setItemUnequip([]));
|
||||||
|
dispatch(actions.setVboxSelected(v));
|
||||||
return dispatch(actions.setVboxSelected(v));
|
return dispatch(actions.setVboxSelected(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setItemEquip(v) {
|
|
||||||
return dispatch(actions.setItemEquip(v));
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setCombiner,
|
|
||||||
setReclaiming,
|
setReclaiming,
|
||||||
setInfo,
|
setInfo,
|
||||||
setVboxSelected,
|
setVboxSelected,
|
||||||
setItemEquip,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
function validVboxSelect(vbox, itemInfo, shopSelect, stashSelect) {
|
||||||
|
if (shopSelect.length === 0 && stashSelect.length === 0) return false;
|
||||||
|
|
||||||
|
const validSelects = [];
|
||||||
|
|
||||||
|
const stashItems = stashSelect.map(j => vbox.bound[j]);
|
||||||
|
const shopItems = shopSelect.map(j => vbox.free[j[0]][j[1]]);
|
||||||
|
|
||||||
|
const selectedItems = stashItems.concat(shopItems);
|
||||||
|
const itemCount = countBy(selectedItems, co => co);
|
||||||
|
|
||||||
|
itemInfo.combos.forEach(combo => {
|
||||||
|
const comboCount = countBy(combo.components, co => co);
|
||||||
|
const buyCount = countBy(combo.components, co => co);
|
||||||
|
const valid = selectedItems.every(c => {
|
||||||
|
if (!combo.components.includes(c)) return false;
|
||||||
|
if (itemCount[c] > comboCount[c]) return false;
|
||||||
|
buyCount[c] -= itemCount[c];
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (valid) {
|
||||||
|
forEach(buyCount, (value, key) => {
|
||||||
|
if (value > 0 && !validSelects.includes(key)) validSelects.push(key);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return validSelects;
|
||||||
|
}
|
||||||
|
|
||||||
class Vbox extends preact.Component {
|
class Vbox extends preact.Component {
|
||||||
shouldComponentUpdate(newProps) {
|
shouldComponentUpdate(newProps) {
|
||||||
// Single variable props
|
// Single variable props
|
||||||
if (newProps.combiner !== this.props.combiner) return true;
|
|
||||||
if (newProps.itemUnequip !== this.props.itemUnequip) return true;
|
if (newProps.itemUnequip !== this.props.itemUnequip) return true;
|
||||||
if (newProps.reclaiming !== this.props.reclaiming) return true;
|
if (newProps.reclaiming !== this.props.reclaiming) return true;
|
||||||
if (newProps.tutorial !== this.props.tutorial) return true;
|
if (newProps.tutorial !== this.props.tutorial) return true;
|
||||||
@ -109,7 +130,6 @@ class Vbox extends preact.Component {
|
|||||||
render(args) {
|
render(args) {
|
||||||
const {
|
const {
|
||||||
// Changing state variables
|
// Changing state variables
|
||||||
combiner,
|
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
player,
|
player,
|
||||||
reclaiming,
|
reclaiming,
|
||||||
@ -126,37 +146,29 @@ class Vbox extends preact.Component {
|
|||||||
sendVboxDiscard,
|
sendVboxDiscard,
|
||||||
sendVboxReclaim,
|
sendVboxReclaim,
|
||||||
setVboxSelected,
|
setVboxSelected,
|
||||||
setItemEquip,
|
|
||||||
setInfo,
|
setInfo,
|
||||||
setCombiner,
|
|
||||||
setReclaiming,
|
setReclaiming,
|
||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
if (!player) return false;
|
if (!player) return false;
|
||||||
const { vbox } = player;
|
const { vbox } = player;
|
||||||
const vboxSelecting = vboxSelected.length;
|
const { shopSelect, stashSelect } = vboxSelected;
|
||||||
|
const vboxSelecting = shopSelect.length === 1 && stashSelect.length === 0;
|
||||||
|
|
||||||
function combinerChange(newCombiner) {
|
function combinerChange(newStashSelect) {
|
||||||
setCombiner(newCombiner);
|
return setVboxSelected({ shopSelect, stashSelect: newStashSelect });
|
||||||
|
|
||||||
if (newCombiner.length === 1) {
|
|
||||||
setItemEquip(newCombiner[0]);
|
|
||||||
} else {
|
|
||||||
setItemEquip(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const vboxHighlight = validVboxSelect(vbox, itemInfo, shopSelect, stashSelect);
|
||||||
//
|
//
|
||||||
// VBOX
|
// VBOX
|
||||||
//
|
//
|
||||||
function vboxHover(e, v) {
|
function vboxHover(e, v) {
|
||||||
if (v) {
|
if (v) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (vboxSelected[0]) return true; // There is a base skill or spec selected in the vbox
|
if (shopSelect.find(c => c[0])) return true; // There is a base skill or spec selected in the vbox
|
||||||
if (combiner.length !== 0) {
|
if (stashSelect.length !== 0) {
|
||||||
const base = combiner.find(c => !['Red', 'Blue', 'Green'].includes(vbox.bound[c]));
|
const base = stashSelect.find(c => !['Red', 'Blue', 'Green'].includes(vbox.bound[c]));
|
||||||
if (base || base === 0) return true;
|
if (base || base === 0) return true;
|
||||||
}
|
}
|
||||||
setInfo(v);
|
setInfo(v);
|
||||||
@ -165,50 +177,36 @@ class Vbox extends preact.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearVboxSelected() {
|
function clearVboxSelected() {
|
||||||
setVboxSelected([]);
|
setVboxSelected({ shopSelect: [], stashSelect: [] });
|
||||||
}
|
}
|
||||||
|
|
||||||
function vboxBuySelected() {
|
function vboxBuySelected() {
|
||||||
if (!vboxSelecting) return false;
|
if (!vboxSelecting) return false;
|
||||||
document.activeElement.blur();
|
document.activeElement.blur();
|
||||||
clearVboxSelected();
|
sendVboxAccept(shopSelect[0][0], shopSelect[0][1]);
|
||||||
sendVboxAccept(vboxSelected[0], vboxSelected[1]);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function availableBtn(v, group, index) {
|
function availableBtn(v, group, index) {
|
||||||
if (!v) return <button disabled class='empty' key={(group * 10) + index} > </button>;
|
if (!v) return <button disabled class='empty' key={(group * 10) + index} > </button>;
|
||||||
const selected = vboxSelected[0] === group && vboxSelected[1] === index;
|
const selected = shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index);
|
||||||
|
|
||||||
// state not yet set in double click handler
|
const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : '';
|
||||||
function onDblClick(e) {
|
|
||||||
clearVboxSelected();
|
|
||||||
sendVboxAccept(group, index);
|
|
||||||
e.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onClick(e) {
|
function onClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setItemEquip(null);
|
if (!comboHighlight) setInfo(vbox.free[group][index]);
|
||||||
setCombiner([]);
|
if (shopSelect.length && shopSelect.some(vs => vs[0] === group && vs[1] === index)) {
|
||||||
setInfo(vbox.free[group][index]);
|
return setVboxSelected({ shopSelect: shopSelect.filter(vs => !(vs[0] === group && vs[1] === index)), stashSelect });
|
||||||
return setVboxSelected([group, index]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const combinerItems = combiner.map(j => vbox.bound[j]);
|
if (!shopSelect.length && !stashSelect.length) return setVboxSelected({ shopSelect: [[group, index]], stashSelect });
|
||||||
const combinerCount = countBy(combinerItems, co => co);
|
if (comboHighlight !== 'combo-border') {
|
||||||
|
return setVboxSelected({ shopSelect: [[group, index]], stashSelect: [] });
|
||||||
|
}
|
||||||
|
return setVboxSelected({ shopSelect: [...shopSelect, [group, index]], stashSelect });
|
||||||
|
}
|
||||||
|
|
||||||
const comboHighlight = combinerItems.length > 0 && itemInfo.combos.some(combo => {
|
|
||||||
if (combo.components.includes(v)) {
|
|
||||||
return combinerItems.every(c => {
|
|
||||||
if (!combo.components.includes(c)) return false;
|
|
||||||
const comboCount = countBy(combo.components, co => co);
|
|
||||||
if (combinerCount[c] > comboCount[c]) return false;
|
|
||||||
if (c === v && combinerCount[c] + 1 > comboCount[c]) return false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
} return false;
|
|
||||||
}) ? 'combo-border' : '';
|
|
||||||
|
|
||||||
const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`;
|
const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`;
|
||||||
|
|
||||||
@ -216,10 +214,7 @@ class Vbox extends preact.Component {
|
|||||||
const disabled = vbox.bits <= group;
|
const disabled = vbox.bits <= group;
|
||||||
return (
|
return (
|
||||||
<label draggable='true'
|
<label draggable='true'
|
||||||
onDragStart={ev => {
|
onDragStart={ev => ev.dataTransfer.setData('text', '')}
|
||||||
onClick(ev);
|
|
||||||
ev.dataTransfer.setData('text', '')
|
|
||||||
}}
|
|
||||||
key={group * 10 + index}
|
key={group * 10 + index}
|
||||||
onDragEnd={clearVboxSelected}>
|
onDragEnd={clearVboxSelected}>
|
||||||
<button
|
<button
|
||||||
@ -228,7 +223,6 @@ class Vbox extends preact.Component {
|
|||||||
onMouseOver={e => vboxHover(e, v)}
|
onMouseOver={e => vboxHover(e, v)}
|
||||||
onMouseDown={onClick}
|
onMouseDown={onClick}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
onDblClick={onDblClick}
|
|
||||||
> {vboxObject}
|
> {vboxObject}
|
||||||
</button>
|
</button>
|
||||||
</label>
|
</label>
|
||||||
@ -239,7 +233,6 @@ class Vbox extends preact.Component {
|
|||||||
function vboxElement() {
|
function vboxElement() {
|
||||||
return (
|
return (
|
||||||
<div class='vbox-vbox'
|
<div class='vbox-vbox'
|
||||||
onMouseDown={() => setReclaiming(false)}
|
|
||||||
onClick={e => e.stopPropagation()}>
|
onClick={e => e.stopPropagation()}>
|
||||||
<div class="vbox-hdr">
|
<div class="vbox-hdr">
|
||||||
<h3
|
<h3
|
||||||
@ -258,7 +251,9 @@ class Vbox extends preact.Component {
|
|||||||
<button
|
<button
|
||||||
class='vbox-btn'
|
class='vbox-btn'
|
||||||
onMouseOver={e => hoverInfo(e, 'refill')}
|
onMouseOver={e => hoverInfo(e, 'refill')}
|
||||||
disabled={tutorial && tutorial < 7 && instance.time_control === 'Practice' && instance.rounds.length === 1}
|
disabled={vbox.bits < 2
|
||||||
|
|| (tutorial && tutorial < 7 && instance.time_control === 'Practice' && instance.rounds.length === 1)
|
||||||
|
}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
onMouseDown={() => sendVboxDiscard()}>
|
onMouseDown={() => sendVboxDiscard()}>
|
||||||
refill - 2b
|
refill - 2b
|
||||||
@ -275,60 +270,42 @@ class Vbox extends preact.Component {
|
|||||||
return setReclaiming(!reclaiming);
|
return setReclaiming(!reclaiming);
|
||||||
}
|
}
|
||||||
|
|
||||||
const inventoryClass = `vbox-section ${reclaiming ? 'reclaiming' : ''}`;
|
|
||||||
|
|
||||||
function inventoryBtn(v, i) {
|
function inventoryBtn(v, i) {
|
||||||
const inventoryHighlight = vboxSelecting || itemUnequip.length;
|
const inventoryHighlight = vboxSelecting || itemUnequip.length;
|
||||||
|
|
||||||
if (!v && v !== 0) {
|
if (!v && v !== 0) {
|
||||||
return <button key={i} disabled={!inventoryHighlight} class={inventoryHighlight ? 'receiving' : 'empty'} > </button>;
|
const emptyInvClick = () => {
|
||||||
|
if (vboxSelecting) return vboxBuySelected();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
return <button key={i} onClick={emptyInvClick} disabled={!inventoryHighlight} class={inventoryHighlight ? 'receiving' : 'empty'} > </button>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const combinerItems = combiner.map(j => vbox.bound[j]);
|
const comboHighlight = vboxHighlight && vboxHighlight.includes(v) ? 'combo-border' : '';
|
||||||
const combinerCount = countBy(combinerItems, co => co);
|
|
||||||
|
|
||||||
const comboItem = itemInfo.combos.find(combo => {
|
|
||||||
if (combo.components.includes(v)) {
|
|
||||||
return combinerItems.every(c => {
|
|
||||||
if (!combo.components.includes(c)) return false;
|
|
||||||
const comboCount = countBy(combo.components, co => co);
|
|
||||||
if (combinerCount[c] > comboCount[c]) return false;
|
|
||||||
if (c === v && combinerCount[c] + 1 > comboCount[c]) return false;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
} return false;
|
|
||||||
});
|
|
||||||
const comboHighlight = combinerItems.length > 0 && comboItem ? 'combo-border' : '';
|
|
||||||
|
|
||||||
function onClick(type) {
|
function onClick(type) {
|
||||||
if (vboxSelecting) clearVboxSelected();
|
|
||||||
if (reclaiming) return sendVboxReclaim(i);
|
if (reclaiming) return sendVboxReclaim(i);
|
||||||
|
|
||||||
const combinerContainsIndex = combiner.indexOf(i) > -1;
|
const combinerContainsIndex = stashSelect.indexOf(i) > -1;
|
||||||
// 4 things selected
|
|
||||||
if (combiner.length > 2 && !combinerContainsIndex) {
|
|
||||||
setInfo(vbox.bound[i]);
|
|
||||||
return combinerChange([i]);
|
|
||||||
}
|
|
||||||
// removing
|
// removing
|
||||||
if (combinerContainsIndex) {
|
if (combinerContainsIndex) {
|
||||||
if (type === 'click') {
|
if (type === 'click') {
|
||||||
return combinerChange(without(combiner, i));
|
return combinerChange(without(stashSelect, i));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!comboHighlight && !combinerContainsIndex) {
|
if (!comboHighlight) {
|
||||||
setInfo(vbox.bound[i]);
|
setInfo(vbox.bound[i]);
|
||||||
return combinerChange([i]);
|
return setVboxSelected({ shopSelect: [], stashSelect: [i] });
|
||||||
}
|
}
|
||||||
|
|
||||||
combiner.push(i);
|
stashSelect.push(i);
|
||||||
if (combiner.length === 3) setInfo(comboItem.item);
|
// if (stashSelect.length === 3) setInfo(comboItem.item);
|
||||||
return combinerChange(combiner);
|
return combinerChange(stashSelect);
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlighted = combiner.indexOf(i) > -1;
|
const highlighted = stashSelect.indexOf(i) > -1;
|
||||||
const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : '';
|
const border = buttons[removeTier(v)] ? buttons[removeTier(v)]() : '';
|
||||||
const classes = `${highlighted ? 'highlight' : border} ${comboHighlight}`;
|
const classes = `${highlighted ? 'highlight' : border} ${comboHighlight}`;
|
||||||
|
|
||||||
@ -355,37 +332,49 @@ class Vbox extends preact.Component {
|
|||||||
|
|
||||||
function combinerBtn() {
|
function combinerBtn() {
|
||||||
let text = '';
|
let text = '';
|
||||||
let comboItem = '';
|
let mouseEvent = false;
|
||||||
if (combiner.length < 3) {
|
const combineLength = stashSelect.length + shopSelect.length;
|
||||||
for (let i = 0; i < 3; i++) {
|
if (vboxHighlight && vboxHighlight.length === 0) {
|
||||||
if (combiner.length > i) {
|
// The selected items can't be combined with additional items therefore valid combo
|
||||||
text += '■ ';
|
const stashItems = stashSelect.map(j => vbox.bound[j]);
|
||||||
} else {
|
const shopItems = shopSelect.map(j => vbox.free[j[0]][j[1]]);
|
||||||
text += '▫ ';
|
const selectedItems = stashItems.concat(shopItems);
|
||||||
}
|
const combinerCount = countBy(selectedItems, co => co);
|
||||||
}
|
|
||||||
} else {
|
const comboItemObj = itemInfo.combos.find(combo => selectedItems.every(c => {
|
||||||
// Since theres 3 items in combiner and you can't have invalid combos we can preview it
|
|
||||||
const combinerItems = combiner.map(j => vbox.bound[j]);
|
|
||||||
const combinerCount = countBy(combinerItems, co => co);
|
|
||||||
const comboItemObj = itemInfo.combos.find(combo => combinerItems.every(c => {
|
|
||||||
if (!combo.components.includes(c)) return false;
|
if (!combo.components.includes(c)) return false;
|
||||||
const comboCount = countBy(combo.components, co => co);
|
const comboCount = countBy(combo.components, co => co);
|
||||||
if (combinerCount[c] > comboCount[c]) return false;
|
if (combinerCount[c] > comboCount[c]) return false;
|
||||||
return true;
|
return true;
|
||||||
}));
|
}));
|
||||||
comboItem = comboItemObj ? comboItemObj.item : 'refine';
|
let comboItem = comboItemObj ? comboItemObj.item : 'refine';
|
||||||
|
setInfo(comboItem);
|
||||||
comboItem = comboItem.replace('Plus', '+');
|
comboItem = comboItem.replace('Plus', '+');
|
||||||
text = `Combine - ${comboItem}`;
|
let bits = 0;
|
||||||
|
shopSelect.forEach(item => bits += item[0] + 1);
|
||||||
|
text = bits
|
||||||
|
? `Buy ${comboItem} - ${bits}b`
|
||||||
|
: `Combine - ${comboItem}`;
|
||||||
|
if (vbox.bits >= bits) mouseEvent = sendVboxCombine;
|
||||||
|
} else if (stashSelect.length === 0 && shopSelect.length === 1) {
|
||||||
|
const item = shopSelect[0];
|
||||||
|
text = `Buy ${vbox.free[item[0]][item[1]]} ${item[0] + 1}b`;
|
||||||
|
mouseEvent = vboxBuySelected;
|
||||||
|
} else {
|
||||||
|
for (let i = 0; i < 3; i++) {
|
||||||
|
if (combineLength > i) {
|
||||||
|
text += '■ ';
|
||||||
|
} else {
|
||||||
|
text += '▫ ';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
class='vbox-btn'
|
class='vbox-btn'
|
||||||
disabled={combiner.length !== 3}
|
disabled={!mouseEvent}
|
||||||
onMouseOver={e => hoverInfo(e, comboItem)}
|
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
onMouseDown={() => sendVboxCombine()}>
|
onMouseDown={() => mouseEvent()}>
|
||||||
{text}
|
{text}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
@ -394,21 +383,18 @@ class Vbox extends preact.Component {
|
|||||||
function inventoryElement() {
|
function inventoryElement() {
|
||||||
function inventoryClick(e) {
|
function inventoryClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setReclaiming(false);
|
|
||||||
if (vboxSelecting) return vboxBuySelected();
|
|
||||||
if (itemUnequip.length) return sendItemUnequip(itemUnequip);
|
if (itemUnequip.length) return sendItemUnequip(itemUnequip);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class={inventoryClass}
|
<div
|
||||||
onMouseDown={inventoryClick}
|
onMouseDown={inventoryClick}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
style={vboxSelecting || (itemUnequip.length) ? { cursor: 'pointer' } : null}
|
|
||||||
onDragOver={ev => ev.preventDefault()}
|
onDragOver={ev => ev.preventDefault()}
|
||||||
onDrop={inventoryClick}
|
onDrop={inventoryClick}
|
||||||
>
|
>
|
||||||
<div class="vbox-hdr">
|
<div class={`vbox-hdr ${reclaiming ? 'reclaiming' : ''}`}>
|
||||||
<h3
|
<h3
|
||||||
onTouchStart={e => e.target.scrollIntoView(true)}
|
onTouchStart={e => e.target.scrollIntoView(true)}
|
||||||
onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY
|
onMouseOver={e => hoverInfo(e, 'inventory')}> INVENTORY
|
||||||
@ -422,7 +408,8 @@ class Vbox extends preact.Component {
|
|||||||
reclaim
|
reclaim
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class='vbox-items'>
|
|
||||||
|
<div class={`vbox-items ${reclaiming ? 'reclaiming' : ''}`}>
|
||||||
{range(0, 9).map(i => inventoryBtn(vbox.bound[i], i))}
|
{range(0, 9).map(i => inventoryBtn(vbox.bound[i], i))}
|
||||||
</div>
|
</div>
|
||||||
{combinerBtn()}
|
{combinerBtn()}
|
||||||
@ -434,11 +421,15 @@ class Vbox extends preact.Component {
|
|||||||
// EVERYTHING
|
// EVERYTHING
|
||||||
//
|
//
|
||||||
function hoverInfo(e, newInfo) {
|
function hoverInfo(e, newInfo) {
|
||||||
e.stopPropagation();
|
if (shopSelect.find(c => c[0])) return true;
|
||||||
|
if (stashSelect.length !== 0) {
|
||||||
|
const base = stashSelect.find(c => !['Red', 'Blue', 'Green'].includes(vbox.bound[c]));
|
||||||
|
if (base || base === 0) return true;
|
||||||
|
}
|
||||||
return setInfo(newInfo);
|
return setInfo(newInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = `vbox`;
|
const classes = 'vbox';
|
||||||
return (
|
return (
|
||||||
<div class={classes}>
|
<div class={classes}>
|
||||||
{vboxElement()}
|
{vboxElement()}
|
||||||
|
|||||||
@ -157,11 +157,6 @@ function registerEvents(store) {
|
|||||||
store.dispatch(actions.setShop(v));
|
store.dispatch(actions.setShop(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearCombiner() {
|
|
||||||
store.dispatch(actions.setInfo([]));
|
|
||||||
store.dispatch(actions.setCombiner([]));
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearConstructRename() {
|
function clearConstructRename() {
|
||||||
store.dispatch(actions.setConstructRename(null));
|
store.dispatch(actions.setConstructRename(null));
|
||||||
}
|
}
|
||||||
@ -184,14 +179,12 @@ function registerEvents(store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clearInstance() {
|
function clearInstance() {
|
||||||
store.dispatch(actions.setCombiner([]));
|
|
||||||
store.dispatch(actions.setReclaiming(false));
|
store.dispatch(actions.setReclaiming(false));
|
||||||
store.dispatch(actions.setActiveSkill(null));
|
store.dispatch(actions.setActiveSkill(null));
|
||||||
store.dispatch(actions.setInfo(null));
|
store.dispatch(actions.setInfo(null));
|
||||||
store.dispatch(actions.setItemEquip(null));
|
|
||||||
store.dispatch(actions.setItemUnequip([]));
|
store.dispatch(actions.setItemUnequip([]));
|
||||||
store.dispatch(actions.setVboxHighlight([]));
|
store.dispatch(actions.setVboxHighlight([]));
|
||||||
store.dispatch(actions.setVboxSelected([]));
|
store.dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] }));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAccountInstances(v) {
|
function setAccountInstances(v) {
|
||||||
@ -345,7 +338,6 @@ function registerEvents(store) {
|
|||||||
window.addEventListener('hashchange', urlHashChange, false);
|
window.addEventListener('hashchange', urlHashChange, false);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clearCombiner,
|
|
||||||
clearConstructRename,
|
clearConstructRename,
|
||||||
clearInfo,
|
clearInfo,
|
||||||
clearInstance,
|
clearInstance,
|
||||||
|
|||||||
@ -6,14 +6,12 @@ function setupKeys(store) {
|
|||||||
key.unbind('esc');
|
key.unbind('esc');
|
||||||
|
|
||||||
key('esc', () => document.activeElement.blur());
|
key('esc', () => document.activeElement.blur());
|
||||||
key('esc', () => store.dispatch(actions.setCombiner([])));
|
|
||||||
key('esc', () => store.dispatch(actions.setReclaiming(false)));
|
key('esc', () => store.dispatch(actions.setReclaiming(false)));
|
||||||
key('esc', () => store.dispatch(actions.setActiveSkill(null)));
|
key('esc', () => store.dispatch(actions.setActiveSkill(null)));
|
||||||
key('esc', () => store.dispatch(actions.setInfo(null)));
|
key('esc', () => store.dispatch(actions.setInfo(null)));
|
||||||
key('esc', () => store.dispatch(actions.setItemEquip(null)));
|
|
||||||
key('esc', () => store.dispatch(actions.setItemUnequip([])));
|
key('esc', () => store.dispatch(actions.setItemUnequip([])));
|
||||||
key('esc', () => store.dispatch(actions.setVboxHighlight([])));
|
key('esc', () => store.dispatch(actions.setVboxHighlight([])));
|
||||||
key('esc', () => store.dispatch(actions.setVboxSelected([])));
|
key('esc', () => store.dispatch(actions.setVboxSelected({ shopSelect: [], stashSelect: [] })));
|
||||||
key('esc', () => store.dispatch(actions.setMtxActive(null)));
|
key('esc', () => store.dispatch(actions.setMtxActive(null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,6 @@ module.exports = {
|
|||||||
chatShow: createReducer(null, 'SET_CHAT_SHOW'),
|
chatShow: createReducer(null, 'SET_CHAT_SHOW'),
|
||||||
chatWheel: createReducer([], 'SET_CHAT_WHEEL'),
|
chatWheel: createReducer([], 'SET_CHAT_WHEEL'),
|
||||||
|
|
||||||
combiner: createReducer([], 'SET_COMBINER'),
|
|
||||||
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
||||||
constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'),
|
constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'),
|
||||||
constructRename: createReducer(null, 'SET_CONSTRUCT_RENAME'),
|
constructRename: createReducer(null, 'SET_CONSTRUCT_RENAME'),
|
||||||
@ -39,7 +38,6 @@ module.exports = {
|
|||||||
instance: createReducer(null, 'SET_INSTANCE'),
|
instance: createReducer(null, 'SET_INSTANCE'),
|
||||||
instanceChat: createReducer(null, 'SET_INSTANCE_CHAT'),
|
instanceChat: createReducer(null, 'SET_INSTANCE_CHAT'),
|
||||||
instances: createReducer([], 'SET_INSTANCES'),
|
instances: createReducer([], 'SET_INSTANCES'),
|
||||||
itemEquip: createReducer(null, 'SET_ITEM_EQUIP'),
|
|
||||||
itemInfo: createReducer({ combos: [], items: [] }, 'SET_ITEM_INFO'),
|
itemInfo: createReducer({ combos: [], items: [] }, 'SET_ITEM_INFO'),
|
||||||
itemUnequip: createReducer([], 'SET_ITEM_UNEQUIP'),
|
itemUnequip: createReducer([], 'SET_ITEM_UNEQUIP'),
|
||||||
mtxActive: createReducer(null, 'SET_MTX_ACTIVE'),
|
mtxActive: createReducer(null, 'SET_MTX_ACTIVE'),
|
||||||
@ -59,7 +57,7 @@ module.exports = {
|
|||||||
tutorial: createReducer(1, 'SET_TUTORIAL'),
|
tutorial: createReducer(1, 'SET_TUTORIAL'),
|
||||||
tutorialGame: createReducer(1, 'SET_TUTORIAL_GAME'),
|
tutorialGame: createReducer(1, 'SET_TUTORIAL_GAME'),
|
||||||
|
|
||||||
vboxSelected: createReducer([], 'SET_VBOX_SELECTED'),
|
vboxSelected: createReducer({ shopSelect: [], stashSelect: [] }, 'SET_VBOX_SELECTED'),
|
||||||
|
|
||||||
ws: createReducer(null, 'SET_WS'),
|
ws: createReducer(null, 'SET_WS'),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -107,8 +107,8 @@ function createSocket(events) {
|
|||||||
events.clearInstance();
|
events.clearInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendVboxCombine(instanceId, indices) {
|
function sendVboxCombine(instanceId, invIndicies, vboxIndicies) {
|
||||||
send(['VboxCombine', { instance_id: instanceId, indices }]);
|
send(['VboxCombine', { instance_id: instanceId, inv_indices: invIndicies, vbox_indices: vboxIndicies }]);
|
||||||
events.clearInstance();
|
events.clearInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +138,11 @@ function createSocket(events) {
|
|||||||
events.setActiveSkill(null);
|
events.setActiveSkill(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendGameConcede(gameId) {
|
||||||
|
send(['GameConcede', { game_id: gameId }]);
|
||||||
|
events.setActiveSkill(null);
|
||||||
|
}
|
||||||
|
|
||||||
function sendGameTarget(gameId, constructId, skillId) {
|
function sendGameTarget(gameId, constructId, skillId) {
|
||||||
send(['GameTarget', { game_id: gameId, construct_id: constructId, skill_id: skillId }]);
|
send(['GameTarget', { game_id: gameId, construct_id: constructId, skill_id: skillId }]);
|
||||||
events.setActiveSkill(null);
|
events.setActiveSkill(null);
|
||||||
@ -391,6 +396,7 @@ function createSocket(events) {
|
|||||||
sendGameSkill,
|
sendGameSkill,
|
||||||
sendGameSkillClear,
|
sendGameSkillClear,
|
||||||
sendGameOfferDraw,
|
sendGameOfferDraw,
|
||||||
|
sendGameConcede,
|
||||||
sendGameTarget,
|
sendGameTarget,
|
||||||
|
|
||||||
sendInstanceAbandon,
|
sendInstanceAbandon,
|
||||||
|
|||||||
@ -4,7 +4,7 @@ const actions = require('./actions');
|
|||||||
function tutorialConstructDisplay(player, instance, tutorial, i) {
|
function tutorialConstructDisplay(player, instance, tutorial, i) {
|
||||||
if (instance.time_control === 'Practice' && instance.rounds.length === 1 && tutorial && tutorial < 6) {
|
if (instance.time_control === 'Practice' && instance.rounds.length === 1 && tutorial && tutorial < 6) {
|
||||||
if (tutorial <= 2 || (tutorial > 2 && i > 0)) {
|
if (tutorial <= 2 || (tutorial > 2 && i > 0)) {
|
||||||
const classes = `instance-construct`;
|
const classes = 'instance-construct';
|
||||||
return (<div key={player.constructs[i].id} class={classes}></div>);
|
return (<div key={player.constructs[i].id} class={classes}></div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -21,7 +21,7 @@ function tutorialVbox(player, store, tutorial) {
|
|||||||
let stage = tutorial;
|
let stage = tutorial;
|
||||||
const { vbox } = player;
|
const { vbox } = player;
|
||||||
if (stage === 1) {
|
if (stage === 1) {
|
||||||
if (vbox.bits < 17) {
|
if (vbox.bits < 29) {
|
||||||
stage += 1;
|
stage += 1;
|
||||||
} else {
|
} else {
|
||||||
vbox.free[0] = vbox.free[0].slice(0, 2);
|
vbox.free[0] = vbox.free[0].slice(0, 2);
|
||||||
@ -54,7 +54,7 @@ function tutorialVbox(player, store, tutorial) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stage === 4) {
|
if (stage === 4) {
|
||||||
if (!vbox.free[2][0] || vbox.bits < 12) {
|
if (!vbox.free[2][0] || vbox.bits < 24) {
|
||||||
stage += 1;
|
stage += 1;
|
||||||
} else {
|
} else {
|
||||||
vbox.free[0] = [];
|
vbox.free[0] = [];
|
||||||
@ -86,7 +86,7 @@ function tutorialVbox(player, store, tutorial) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stage === 7) {
|
if (stage === 7) {
|
||||||
if (vbox.bits < 13) {
|
if (vbox.bits < 25) {
|
||||||
stage += 1;
|
stage += 1;
|
||||||
} else {
|
} else {
|
||||||
vbox.free[0] = [];
|
vbox.free[0] = [];
|
||||||
@ -112,9 +112,8 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) {
|
|||||||
<div class='info-item'>
|
<div class='info-item'>
|
||||||
<h2>Tutorial</h2>
|
<h2>Tutorial</h2>
|
||||||
<p> Welcome to the vbox phase tutorial.</p>
|
<p> Welcome to the vbox phase tutorial.</p>
|
||||||
<p> Colours are used to create powerful combinations. </p>
|
<p> Colours are used to create powerful combinations with base items. </p>
|
||||||
<p> Buy two colours from the vbox by double clicking. <br />
|
<p> Buy the two colours from the vbox to continue. </p>
|
||||||
You can also click the colour once and then click the inventory. </p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -151,8 +150,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) {
|
|||||||
<h2>Tutorial</h2>
|
<h2>Tutorial</h2>
|
||||||
<p> You can also buy specialisation items for your constructs. <br />
|
<p> You can also buy specialisation items for your constructs. <br />
|
||||||
Specialisation items increase stats including power, speed and life. </p>
|
Specialisation items increase stats including power, speed and life. </p>
|
||||||
<p> Buy the specialisation item from the vbox by double clicking. <br />
|
<p> Buy the specialisation item from the vbox to continue. </p>
|
||||||
You can also click the specialisation once and then click the inventory. </p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml-ops",
|
"name": "mnml-ops",
|
||||||
"version": "1.8.3",
|
"version": "1.9.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mnml"
|
name = "mnml"
|
||||||
version = "1.8.3"
|
version = "1.9.0"
|
||||||
authors = ["ntr <ntr@smokestack.io>"]
|
authors = ["ntr <ntr@smokestack.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -34,7 +34,7 @@ router = "0.6"
|
|||||||
mount = "0.4"
|
mount = "0.4"
|
||||||
cookie = "0.12"
|
cookie = "0.12"
|
||||||
crossbeam-channel = "0.3"
|
crossbeam-channel = "0.3"
|
||||||
ws = { version = "0.8", features = ["ssl"] }
|
ws = { version = "0.8", features = ["ssl", "permessage-deflate"] }
|
||||||
|
|
||||||
lettre = "0.9"
|
lettre = "0.9"
|
||||||
lettre_email = "0.9"
|
lettre_email = "0.9"
|
||||||
|
|||||||
@ -349,6 +349,18 @@ impl Game {
|
|||||||
return Ok(self);
|
return Ok(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn concede(mut self, player_id: Uuid) -> Result<Game, Error> {
|
||||||
|
if self.phase != Phase::Skill {
|
||||||
|
return Err(err_msg("game not in skill phase"));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.player_by_id(player_id)?
|
||||||
|
.forfeit();
|
||||||
|
|
||||||
|
return Ok(self.finish());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn clear_skill(&mut self, player_id: Uuid) -> Result<&mut Game, Error> {
|
fn clear_skill(&mut self, player_id: Uuid) -> Result<&mut Game, Error> {
|
||||||
self.player_by_id(player_id)?;
|
self.player_by_id(player_id)?;
|
||||||
if self.phase != Phase::Skill {
|
if self.phase != Phase::Skill {
|
||||||
@ -940,6 +952,16 @@ pub fn game_offer_draw(tx: &mut Transaction, account: &Account, game_id: Uuid) -
|
|||||||
Ok(game)
|
Ok(game)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn game_concede(tx: &mut Transaction, account: &Account, game_id: Uuid) -> Result<Game, Error> {
|
||||||
|
let game = game_get(tx, game_id)?
|
||||||
|
.concede(account.id)?;
|
||||||
|
|
||||||
|
game_update(tx, &game)?;
|
||||||
|
|
||||||
|
Ok(game)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn game_skill_clear(tx: &mut Transaction, account: &Account, game_id: Uuid) -> Result<Game, Error> {
|
pub fn game_skill_clear(tx: &mut Transaction, account: &Account, game_id: Uuid) -> Result<Game, Error> {
|
||||||
let mut game = game_get(tx, game_id)?;
|
let mut game = game_get(tx, game_id)?;
|
||||||
|
|
||||||
|
|||||||
@ -480,10 +480,10 @@ impl Instance {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_combine(mut self, account: Uuid, indices: Vec<usize>) -> Result<Instance, Error> {
|
pub fn vbox_combine(mut self, account: Uuid, inv_indices: Vec<usize>, vbox_indices: Vec<Vec<usize>>) -> Result<Instance, Error> {
|
||||||
self.vbox_action_allowed(account)?;
|
self.vbox_action_allowed(account)?;
|
||||||
self.account_player(account)?
|
self.account_player(account)?
|
||||||
.vbox_combine(indices)?;
|
.vbox_combine(inv_indices, vbox_indices)?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,6 +62,7 @@ use std::path::{Path};
|
|||||||
use fern::colors::{Color, ColoredLevelConfig};
|
use fern::colors::{Color, ColoredLevelConfig};
|
||||||
use crossbeam_channel::{unbounded};
|
use crossbeam_channel::{unbounded};
|
||||||
|
|
||||||
|
#[cfg(unix)]
|
||||||
pub fn setup_logger() -> Result<(), fern::InitError> {
|
pub fn setup_logger() -> Result<(), fern::InitError> {
|
||||||
let formatter = syslog::Formatter3164 {
|
let formatter = syslog::Formatter3164 {
|
||||||
facility: syslog::Facility::LOG_USER,
|
facility: syslog::Facility::LOG_USER,
|
||||||
@ -109,6 +110,7 @@ pub fn setup_logger() -> Result<(), fern::InitError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn start() {
|
pub fn start() {
|
||||||
|
#[cfg(unix)]
|
||||||
setup_logger().unwrap();
|
setup_logger().unwrap();
|
||||||
dotenv::from_path(Path::new("/etc/mnml/gs.conf")).ok();
|
dotenv::from_path(Path::new("/etc/mnml/gs.conf")).ok();
|
||||||
|
|
||||||
|
|||||||
@ -229,7 +229,7 @@ impl Player {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// first 2 colours can be whatever
|
// first 2 colours can be whatever
|
||||||
self.vbox_combine(vec![0, 1, combo_i]).ok();
|
self.vbox_combine(vec![0, 1, combo_i], vec![]).ok();
|
||||||
let item_i = self.vbox.bound.len() - 1;
|
let item_i = self.vbox.bound.len() - 1;
|
||||||
self.vbox_apply(item_i, target_construct_id).ok();
|
self.vbox_apply(item_i, target_construct_id).ok();
|
||||||
}
|
}
|
||||||
@ -257,8 +257,8 @@ impl Player {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_combine(&mut self, indices: Vec<usize>) -> Result<&mut Player, Error> {
|
pub fn vbox_combine(&mut self, inv_indices: Vec<usize>, vbox_indices: Vec<Vec<usize>>) -> Result<&mut Player, Error> {
|
||||||
self.vbox.combine(indices)?;
|
self.vbox.combine(inv_indices, vbox_indices)?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -16,12 +16,13 @@ use stripe::{Client as StripeClient, Subscription};
|
|||||||
|
|
||||||
use crossbeam_channel::{unbounded, Sender as CbSender};
|
use crossbeam_channel::{unbounded, Sender as CbSender};
|
||||||
use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender};
|
use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender};
|
||||||
|
use ws::deflate::DeflateHandler;
|
||||||
|
|
||||||
use account::{Account};
|
use account::{Account};
|
||||||
use account;
|
use account;
|
||||||
use construct::{Construct};
|
use construct::{Construct};
|
||||||
use events::{Event};
|
use events::{Event};
|
||||||
use game::{Game, game_state, game_skill, game_skill_clear, game_ready, game_offer_draw};
|
use game::{Game, game_state, game_skill, game_skill_clear, game_ready, game_offer_draw, game_concede};
|
||||||
use instance::{Instance, ChatState, instance_state, instance_practice, instance_ready, instance_abandon, demo};
|
use instance::{Instance, ChatState, instance_state, instance_practice, instance_ready, instance_abandon, demo};
|
||||||
use item::{Item, ItemInfoCtr, item_info};
|
use item::{Item, ItemInfoCtr, item_info};
|
||||||
use mtx;
|
use mtx;
|
||||||
@ -91,6 +92,7 @@ pub enum RpcRequest {
|
|||||||
GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Uuid, skill: Skill },
|
GameSkill { game_id: Uuid, construct_id: Uuid, target_construct_id: Uuid, skill: Skill },
|
||||||
GameSkillClear { game_id: Uuid },
|
GameSkillClear { game_id: Uuid },
|
||||||
GameOfferDraw { game_id: Uuid },
|
GameOfferDraw { game_id: Uuid },
|
||||||
|
GameConcede { game_id: Uuid },
|
||||||
|
|
||||||
AccountState {},
|
AccountState {},
|
||||||
AccountShop {},
|
AccountShop {},
|
||||||
@ -115,7 +117,7 @@ pub enum RpcRequest {
|
|||||||
VboxAccept { instance_id: Uuid, group: usize, index: usize },
|
VboxAccept { instance_id: Uuid, group: usize, index: usize },
|
||||||
VboxAcceptEquip { instance_id: Uuid, group: usize, index: usize, construct_id: Uuid },
|
VboxAcceptEquip { instance_id: Uuid, group: usize, index: usize, construct_id: Uuid },
|
||||||
VboxDiscard { instance_id: Uuid },
|
VboxDiscard { instance_id: Uuid },
|
||||||
VboxCombine { instance_id: Uuid, indices: Vec<usize> },
|
VboxCombine { instance_id: Uuid, inv_indices: Vec<usize>, vbox_indices: Vec<Vec<usize>> },
|
||||||
VboxApply { instance_id: Uuid, construct_id: Uuid, index: usize },
|
VboxApply { instance_id: Uuid, construct_id: Uuid, index: usize },
|
||||||
VboxUnequip { instance_id: Uuid, construct_id: Uuid, target: Item },
|
VboxUnequip { instance_id: Uuid, construct_id: Uuid, target: Item },
|
||||||
VboxUnequipApply { instance_id: Uuid, construct_id: Uuid, target: Item, target_construct_id: Uuid },
|
VboxUnequipApply { instance_id: Uuid, construct_id: Uuid, target: Item, target_construct_id: Uuid },
|
||||||
@ -226,6 +228,9 @@ impl Connection {
|
|||||||
RpcRequest::GameReady { id } =>
|
RpcRequest::GameReady { id } =>
|
||||||
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
|
Ok(RpcMessage::GameState(game_ready(&mut tx, account, id)?)),
|
||||||
|
|
||||||
|
RpcRequest::GameConcede { game_id } =>
|
||||||
|
Ok(RpcMessage::GameState(game_concede(&mut tx, account, game_id)?)),
|
||||||
|
|
||||||
RpcRequest::GameOfferDraw { game_id } =>
|
RpcRequest::GameOfferDraw { game_id } =>
|
||||||
Ok(RpcMessage::GameState(game_offer_draw(&mut tx, account, game_id)?)),
|
Ok(RpcMessage::GameState(game_offer_draw(&mut tx, account, game_id)?)),
|
||||||
|
|
||||||
@ -249,8 +254,8 @@ impl Connection {
|
|||||||
RpcRequest::VboxApply { instance_id, construct_id, index } =>
|
RpcRequest::VboxApply { instance_id, construct_id, index } =>
|
||||||
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
|
Ok(RpcMessage::InstanceState(vbox_apply(&mut tx, account, instance_id, construct_id, index)?)),
|
||||||
|
|
||||||
RpcRequest::VboxCombine { instance_id, indices } =>
|
RpcRequest::VboxCombine { instance_id, inv_indices, vbox_indices } =>
|
||||||
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, indices)?)),
|
Ok(RpcMessage::InstanceState(vbox_combine(&mut tx, account, instance_id, inv_indices, vbox_indices)?)),
|
||||||
|
|
||||||
RpcRequest::VboxDiscard { instance_id } =>
|
RpcRequest::VboxDiscard { instance_id } =>
|
||||||
Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
|
Ok(RpcMessage::InstanceState(vbox_discard(&mut tx, account, instance_id)?)),
|
||||||
@ -448,7 +453,8 @@ impl Handler for Connection {
|
|||||||
|
|
||||||
pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
|
pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
Builder::new()
|
|
||||||
|
let ws = Builder::new()
|
||||||
.with_settings(Settings {
|
.with_settings(Settings {
|
||||||
max_connections: 10_000,
|
max_connections: 10_000,
|
||||||
..Settings::default()
|
..Settings::default()
|
||||||
@ -478,6 +484,7 @@ pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
DeflateHandler::new(
|
||||||
Connection {
|
Connection {
|
||||||
id: rng.gen::<usize>(),
|
id: rng.gen::<usize>(),
|
||||||
account: None,
|
account: None,
|
||||||
@ -486,6 +493,7 @@ pub fn start(pool: PgPool, events_tx: CbSender<Event>, stripe: StripeClient) {
|
|||||||
stripe: stripe.clone(),
|
stripe: stripe.clone(),
|
||||||
events: events_tx.clone(),
|
events: events_tx.clone(),
|
||||||
}
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.listen("127.0.0.1:40055")
|
.listen("127.0.0.1:40055")
|
||||||
|
|||||||
@ -348,15 +348,16 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
_ => (),
|
|
||||||
};
|
|
||||||
|
|
||||||
if target.is_ko() && event_target.green == 0 {
|
if target.is_ko() && event_target.green == 0 {
|
||||||
// Make sure target ko is from this event
|
// Make sure target ko is from this event
|
||||||
target.effects.clear();
|
target.effects.clear();
|
||||||
resolutions.push(Resolution::new(&source, &target).event(Event::Ko()).stages(EventStages::PostOnly));
|
resolutions.push(Resolution::new(&source, &target).event(Event::Ko()).stages(EventStages::PostOnly));
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
_ => (),
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
game.update_construct(&mut source);
|
game.update_construct(&mut source);
|
||||||
game.update_construct(&mut target);
|
game.update_construct(&mut target);
|
||||||
|
|||||||
@ -142,19 +142,20 @@ impl Vbox {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn combine(&mut self, mut indices: Vec<usize>) -> Result<&mut Vbox, Error> {
|
pub fn combine(&mut self, mut inv_indices: Vec<usize>, vbox_indicies: Vec<Vec<usize>>) -> Result<&mut Vbox, Error> {
|
||||||
if indices.len() != 3 {
|
if !inv_indices.iter().all(|i| self.bound.get(*i).is_some()) {
|
||||||
return Err(err_msg("exactly 3 indices required"));
|
|
||||||
}
|
|
||||||
|
|
||||||
if !indices.iter().all(|i| self.bound.get(*i).is_some()) {
|
|
||||||
return Err(err_msg("item missing index"));
|
return Err(err_msg("item missing index"));
|
||||||
}
|
}
|
||||||
|
// try to buy up the vbox indicies and add them to the inventory indicies for combining
|
||||||
|
for vi in vbox_indicies.iter() {
|
||||||
|
inv_indices.push(self.bound.len());
|
||||||
|
self.accept(vi[0], vi[1], Some(Uuid::nil()))?;
|
||||||
|
}
|
||||||
|
|
||||||
// have to sort the indices and keep track of the iteration
|
// have to sort the indices and keep track of the iteration
|
||||||
// because when removing the elements the array shifts
|
// because when removing the elements the array shifts
|
||||||
indices.sort_unstable();
|
inv_indices.sort_unstable();
|
||||||
let mut input = indices
|
let mut input = inv_indices
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, index)| {
|
.map(|(i, index)| {
|
||||||
@ -170,7 +171,9 @@ impl Vbox {
|
|||||||
|
|
||||||
self.bound.push(combo.item);
|
self.bound.push(combo.item);
|
||||||
// self.bound.sort_unstable();
|
// self.bound.sort_unstable();
|
||||||
|
if self.bound.len() >= 10 {
|
||||||
|
return Err(err_msg("too many items bound"));
|
||||||
|
}
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,9 +190,9 @@ pub fn vbox_accept(tx: &mut Transaction, account: &Account, instance_id: Uuid, g
|
|||||||
return instance_update(tx, instance);
|
return instance_update(tx, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_combine(tx: &mut Transaction, account: &Account, instance_id: Uuid, indices: Vec<usize>) -> Result<Instance, Error> {
|
pub fn vbox_combine(tx: &mut Transaction, account: &Account, instance_id: Uuid, inv_indices: Vec<usize>, vbox_indices: Vec<Vec<usize>>) -> Result<Instance, Error> {
|
||||||
let instance = instance_get(tx, instance_id)?
|
let instance = instance_get(tx, instance_id)?
|
||||||
.vbox_combine(account.id, indices)?;
|
.vbox_combine(account.id, inv_indices, vbox_indices)?;
|
||||||
return instance_update(tx, instance);
|
return instance_update(tx, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,7 +222,7 @@ mod tests {
|
|||||||
fn combine_test() {
|
fn combine_test() {
|
||||||
let mut vbox = Vbox::new();
|
let mut vbox = Vbox::new();
|
||||||
vbox.bound = vec![Item::Attack, Item::Green, Item::Green];
|
vbox.bound = vec![Item::Attack, Item::Green, Item::Green];
|
||||||
vbox.combine(vec![1,2,0]).unwrap();
|
vbox.combine(vec![1,2,0], vec![]).unwrap();
|
||||||
assert_eq!(vbox.bound[0], Item::Heal);
|
assert_eq!(vbox.bound[0], Item::Heal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,7 +243,7 @@ mod tests {
|
|||||||
let mut vbox = Vbox::new();
|
let mut vbox = Vbox::new();
|
||||||
vbox.bound = vec![Item::Strike];
|
vbox.bound = vec![Item::Strike];
|
||||||
vbox.reclaim(0).unwrap();
|
vbox.reclaim(0).unwrap();
|
||||||
assert_eq!(vbox.bits, 20);
|
assert_eq!(vbox.bits, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user