Merge branch 'release/1.8.0'
This commit is contained in:
commit
2ea86fd6b8
47
CHANGELOG.md
47
CHANGELOG.md
@ -2,6 +2,53 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [1.8.0] - 2019-10-31
|
||||||
|
# Added
|
||||||
|
- Drag and drop for vbox interactions can be used instead of single click / double click
|
||||||
|
|
||||||
|
- Base white items and be directly equipped from vbox rather than going through the inventory
|
||||||
|
- Useful if you want to equip an item without further combining with colours
|
||||||
|
|
||||||
|
- You can swap skills and specs between constructs without using the inventory
|
||||||
|
|
||||||
|
# Changed
|
||||||
|
|
||||||
|
- Construct life changed
|
||||||
|
- You now start with 800 green life (down from 950)
|
||||||
|
- You now start with 125 red life and blue life (up from 0)
|
||||||
|
|
||||||
|
- Game phase layout
|
||||||
|
- Enemy team effects appear under your construct instead of next to it
|
||||||
|
- Game phase constructs line up symmetrically now
|
||||||
|
|
||||||
|
- Mobile
|
||||||
|
- Tutorial is disabled for mobile view
|
||||||
|
- Landscape is now default view
|
||||||
|
- Vbox phase everything is now in one view
|
||||||
|
- Game constructs and animations are much larger in mobile view
|
||||||
|
|
||||||
|
- Amplify
|
||||||
|
Now increases green power
|
||||||
|
|
||||||
|
- Absorb
|
||||||
|
- Reduced duration and cooldown from 2T -> 1T (Absorption duration unchanged)
|
||||||
|
- Absorption damage is now based on all damage taken (previously only green damage taken)
|
||||||
|
- Now recharges blue life based on 95 / 120 / 155 blue power
|
||||||
|
|
||||||
|
- Banish
|
||||||
|
Reduced cooldown to 1T
|
||||||
|
|
||||||
|
- Decay
|
||||||
|
Removed cooldown
|
||||||
|
|
||||||
|
- Haste / Hybrid
|
||||||
|
Fixed issue when hybridblast and hastestrike wouldn't trigger from upgraded + skills
|
||||||
|
|
||||||
|
- Intercept
|
||||||
|
- Reduced duration to 1T down from 2T
|
||||||
|
- Reduced cooldown to 1T down from 2T
|
||||||
|
|
||||||
|
|
||||||
## [1.7.0] - 2019-10-31
|
## [1.7.0] - 2019-10-31
|
||||||
# Added
|
# Added
|
||||||
- Step by step tutorial
|
- Step by step tutorial
|
||||||
|
|||||||
22
WORKLOG.md
22
WORKLOG.md
@ -3,22 +3,33 @@
|
|||||||
|
|
||||||
*PRODUCTION*
|
*PRODUCTION*
|
||||||
|
|
||||||
* vbox phase skill list navigator (overlay maybe?)
|
|
||||||
* can't reset password without knowing password =\
|
* can't reset password without knowing password =\
|
||||||
|
* ws gzip encoding
|
||||||
|
|
||||||
* mobile styles
|
|
||||||
* mobile info page
|
* mobile info page
|
||||||
* fix info page for tablet layout
|
|
||||||
|
|
||||||
* Invert recharge
|
* Invert recharge
|
||||||
|
|
||||||
## SOON
|
## SOON
|
||||||
|
|
||||||
* equip from shop (buy and equip without putting in your inventory) for bases
|
* change cooldowns to delay & recharge
|
||||||
* move item from one construct to another
|
- delay is cooldown before skill can first be used
|
||||||
|
- recharge is cooldown after using skill
|
||||||
|
- every x speed reduces delay of skills
|
||||||
|
|
||||||
|
* combo rework
|
||||||
|
- reduce number of items for creating t2/t3 items from 3 -> 2
|
||||||
|
- add lost complexity by adding skill spec items
|
||||||
|
- Created by combining a skill with corresponding spec
|
||||||
|
e.g.
|
||||||
|
- Strike + PowerRR -> StrikePower (Will be the power symbol with strike text under)
|
||||||
|
- Construct does Y% more damage with Strike
|
||||||
|
- Strike + SpeedRR -> StrikeSpeed (strike has Y% more speed)
|
||||||
|
- Strike + LifeRR -> StrikeLife (Strike recharges X% of damage as red life)
|
||||||
|
|
||||||
* ACP
|
* ACP
|
||||||
* essential
|
* essential
|
||||||
|
|
||||||
* audio
|
* audio
|
||||||
* treats
|
* treats
|
||||||
* susbcriber gold name in instance
|
* susbcriber gold name in instance
|
||||||
@ -66,7 +77,6 @@ $$$
|
|||||||
* Highlight (dota) colour
|
* Highlight (dota) colour
|
||||||
* fx colours + styles
|
* fx colours + styles
|
||||||
|
|
||||||
* ??? (PROBS NOT) drag and drop buy / equip / unequip items ???
|
|
||||||
* modules
|
* modules
|
||||||
* troll life -> dmg
|
* troll life -> dmg
|
||||||
* prince of peace
|
* prince of peace
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml-client",
|
"name": "mnml-client",
|
||||||
"version": "1.7.1",
|
"version": "1.8.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 9.6 KiB |
2593
client/assets/rotate.svg
Normal file
2593
client/assets/rotate.svg
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 96 KiB |
@ -4,7 +4,7 @@
|
|||||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
grid-template-columns: 1fr 1fr 1fr 1fr;
|
||||||
|
|
||||||
div {
|
div {
|
||||||
padding-right: 2em;
|
padding-right: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|||||||
@ -169,3 +169,15 @@ button {
|
|||||||
color: @green;
|
color: @green;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes rb-text {
|
||||||
|
0% {
|
||||||
|
color: @red;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
color: @white;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
color: @blue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -96,6 +96,20 @@ aside {
|
|||||||
border-color: forestgreen;
|
border-color: forestgreen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// all green
|
||||||
|
// &:enabled {
|
||||||
|
// background: forestgreen;
|
||||||
|
// color: black;
|
||||||
|
// border-color: forestgreen;
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// color: forestgreen;
|
||||||
|
// border-color: forestgreen;
|
||||||
|
// background: 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.team-page-ctrl {
|
.team-page-ctrl {
|
||||||
|
|||||||
@ -10,15 +10,22 @@
|
|||||||
// "opponent"
|
// "opponent"
|
||||||
// "target "
|
// "target "
|
||||||
// "player ";
|
// "player ";
|
||||||
|
|
||||||
|
.skill-description {
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.game .team {
|
.game .team, .faceoff .team {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
|
||||||
/* stops overflow */
|
/* stops overflow */
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
|
// timer is 0.25 w/ 1em margin
|
||||||
|
width: calc(90% - 1.25em);
|
||||||
}
|
}
|
||||||
|
|
||||||
.player {
|
.player {
|
||||||
@ -28,7 +35,6 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
height: 50%;
|
height: 50%;
|
||||||
width: 90%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.opponent {
|
.opponent {
|
||||||
@ -37,13 +43,15 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
height: 35%;
|
height: 35%;
|
||||||
width: 90%;
|
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
|
|
||||||
.game-construct {
|
.game-construct {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
grid-template-columns: 1fr 2fr;
|
grid-template-rows: 2fr min-content;
|
||||||
grid-template-rows: 1fr;
|
grid-template-rows: 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"right"
|
||||||
|
"left";
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -78,12 +86,16 @@
|
|||||||
justify-items: center;
|
justify-items: center;
|
||||||
|
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-template-rows: min-content 1fr;
|
grid-template-rows: 1fr 2fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"left"
|
||||||
|
"right";
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
|
||||||
|
grid-area: left;
|
||||||
grid-template-columns: 1fr 2fr;
|
grid-template-columns: 1fr 2fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"skills effects";
|
"skills effects";
|
||||||
@ -91,6 +103,7 @@
|
|||||||
|
|
||||||
.right {
|
.right {
|
||||||
display: grid;
|
display: grid;
|
||||||
|
grid-area: right;
|
||||||
grid-template-rows: minmax(min-content, 1fr) min-content min-content;
|
grid-template-rows: minmax(min-content, 1fr) min-content min-content;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"avatar"
|
"avatar"
|
||||||
@ -120,6 +133,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.skills {
|
.skills {
|
||||||
|
z-index: 2;
|
||||||
button {
|
button {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 2em;
|
height: 2em;
|
||||||
@ -131,6 +145,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.effects {
|
.effects {
|
||||||
|
z-index: 2;
|
||||||
grid-area: effects;
|
grid-area: effects;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -198,7 +213,7 @@
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 35%;
|
top: 35%;
|
||||||
height: 15%;
|
height: 15%;
|
||||||
width: 90%;
|
width: calc(90% - 1.25em);
|
||||||
}
|
}
|
||||||
|
|
||||||
.resolving-skill {
|
.resolving-skill {
|
||||||
@ -238,6 +253,9 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.combat-anim svg {
|
.combat-anim svg {
|
||||||
@ -257,14 +275,6 @@
|
|||||||
color: #a52a2a;
|
color: #a52a2a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.red-damage text {
|
|
||||||
fill: #a52a2a;
|
|
||||||
}
|
|
||||||
|
|
||||||
.red-damage .stats {
|
|
||||||
/*border-top: 1px solid #a52a2a;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-construct.blue-damage {
|
.game-construct.blue-damage {
|
||||||
color: #3050f8;
|
color: #3050f8;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -274,13 +284,6 @@
|
|||||||
color: #3050f8;
|
color: #3050f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.blue-damage text {
|
|
||||||
fill: #3050f8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue-damage .stats {
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-construct.green-damage {
|
.game-construct.green-damage {
|
||||||
color: #1FF01F;
|
color: #1FF01F;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
@ -290,31 +293,8 @@
|
|||||||
color: #1FF01F;
|
color: #1FF01F;
|
||||||
}
|
}
|
||||||
|
|
||||||
.green-damage text {
|
.game-construct.rb-damage {
|
||||||
fill: #1FF01F;
|
animation: rb-text 1s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite;
|
||||||
}
|
|
||||||
|
|
||||||
.green-damage .stats {
|
|
||||||
/*border-top: 1px solid #1FF01F;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.game-construct.purple-damage {
|
|
||||||
/* filter: drop-shadow(0 0 0.2em purple);
|
|
||||||
*/ color: purple;
|
|
||||||
border-color: purple;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purple-damage button {
|
|
||||||
border: 1px solid purple;
|
|
||||||
color: purple;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purple-damage text {
|
|
||||||
fill: purple;
|
|
||||||
}
|
|
||||||
|
|
||||||
.purple-damage .stats {
|
|
||||||
border-top: 1px solid purple;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.game .img, .faceoff .img {
|
.game .img, .faceoff .img {
|
||||||
@ -345,104 +325,4 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
// height: 5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
|
||||||
.game {
|
|
||||||
grid-template-areas:
|
|
||||||
"opponent"
|
|
||||||
"target "
|
|
||||||
"player ";
|
|
||||||
|
|
||||||
grid-template-rows: 1fr 0.2fr 1.5fr;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
|
|
||||||
.game-construct {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: min-content 1fr;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
width: 100%;
|
|
||||||
grid-template-areas:
|
|
||||||
"skills"
|
|
||||||
"effects";
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: min-content min-content;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skills {
|
|
||||||
button {
|
|
||||||
padding: 0 0.5em ;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
button.active {
|
|
||||||
background: #2c2c2c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats div {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats .max {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats .value {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats svg {
|
|
||||||
height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats div {
|
|
||||||
margin: 0 0.2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.effects {
|
|
||||||
font-size: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats, .name {
|
|
||||||
font-size: 75%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skills button {
|
|
||||||
font-size: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.skill-description {
|
|
||||||
font-size: 65%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.player {
|
|
||||||
width: calc(100% - 1em);
|
|
||||||
bottom: 3em;
|
|
||||||
height: calc(50% - 3em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.opponent {
|
|
||||||
width: calc(100% - 1em);
|
|
||||||
.game-construct {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-rows: min-content 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#targeting, .resolving-skill {
|
|
||||||
width: calc(100% - 1em);
|
|
||||||
}
|
|
||||||
|
|
||||||
.player {
|
|
||||||
width: calc(100% - 1em);
|
|
||||||
bottom: 3em;
|
|
||||||
height: calc(50% - 3em);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,10 +9,6 @@
|
|||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"vbox info"
|
"vbox info"
|
||||||
"constructs constructs";
|
"constructs constructs";
|
||||||
|
|
||||||
hr {
|
|
||||||
grid-area: rule;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1920px) {
|
@media (max-width: 1920px) {
|
||||||
@ -88,65 +84,6 @@
|
|||||||
border-right-width: 0;
|
border-right-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* VBOX */
|
|
||||||
.vbox {
|
|
||||||
align-content: space-between;
|
|
||||||
grid-area: vbox;
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: min-content min-content min-content;
|
|
||||||
grid-template-columns: 1fr min-content 1fr;
|
|
||||||
grid-template-areas:
|
|
||||||
"vbox varrow inventory"
|
|
||||||
"vbox varrow combiner";
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-inventory {
|
|
||||||
grid-area: inventory;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-combiner {
|
|
||||||
grid-area: combiner;
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-arrow, .vbox-arrow-mobile {
|
|
||||||
display: flex;
|
|
||||||
justify-content:center;
|
|
||||||
align-content:center;
|
|
||||||
flex-direction:column;
|
|
||||||
|
|
||||||
margin: 1em 0.25em 0 0.25em;
|
|
||||||
grid-area: varrow;
|
|
||||||
font-size: 2em;
|
|
||||||
color: @gray-hint;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-combiner button {
|
|
||||||
flex: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.vbox-hdr {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-hdr h3 {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-hdr .bits {
|
|
||||||
font-size: 2em;
|
|
||||||
line-height: 1em;
|
|
||||||
animation: bits 1s ease-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
grid-area: arrow;
|
|
||||||
color: @gray-hint;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes action {
|
@keyframes action {
|
||||||
0% {
|
0% {
|
||||||
color: palegoldenrod;
|
color: palegoldenrod;
|
||||||
@ -195,6 +132,7 @@
|
|||||||
grid-area: skills;
|
grid-area: skills;
|
||||||
padding: 0 0.5em;
|
padding: 0 0.5em;
|
||||||
margin-bottom: 0.75em;
|
margin-bottom: 0.75em;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
@ -203,12 +141,16 @@
|
|||||||
button {
|
button {
|
||||||
height: 3em;
|
height: 3em;
|
||||||
}
|
}
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.specs {
|
.specs {
|
||||||
grid-area: specs;
|
grid-area: specs;
|
||||||
padding: 0 0.5em;
|
padding: 0 0.5em;
|
||||||
margin-bottom: 0.75em;
|
margin-bottom: 0.75em;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
@ -225,9 +167,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
figcaption {
|
figcaption {
|
||||||
font-size: 75%;
|
// font-size: 75%;
|
||||||
line-height: initial;
|
line-height: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stats {
|
.stats {
|
||||||
@ -239,7 +185,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
figcaption {
|
figcaption {
|
||||||
font-size: 75%;
|
// font-size: 75%;
|
||||||
}
|
}
|
||||||
|
|
||||||
// give speed some space
|
// give speed some space
|
||||||
|
|||||||
@ -17,9 +17,7 @@
|
|||||||
|
|
||||||
@media (max-width: 800px) {
|
@media (max-width: 800px) {
|
||||||
.instance {
|
.instance {
|
||||||
overflow-y: scroll;
|
font-size: 6pt;
|
||||||
font-size: 8pt;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-template-rows: min-content 1fr;
|
grid-template-rows: min-content 1fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
@ -30,141 +28,4 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.instance .nav-btn { display: initial; }
|
|
||||||
|
|
||||||
.vbox {
|
|
||||||
grid-area: vbox;
|
|
||||||
margin-bottom: 0;
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: min-content min-content min-content min-content;
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-areas:
|
|
||||||
"vbox"
|
|
||||||
"varrow"
|
|
||||||
"inventory"
|
|
||||||
"combiner";
|
|
||||||
|
|
||||||
&:not(.visible) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-vbox {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-arrow {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-inventory .vbox-hdr {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-arrow-mobile {
|
|
||||||
display: block;
|
|
||||||
grid-area: varrow;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.construct-list {
|
|
||||||
display: grid;
|
|
||||||
grid-auto-rows: 1fr;
|
|
||||||
|
|
||||||
.instance-construct:not(.visible) {
|
|
||||||
display: none;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-inventory {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.vbox-combiner {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.equip .specs {
|
|
||||||
margin-top: 0.5em;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.equip .skills {
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct {
|
|
||||||
display: grid;
|
|
||||||
grid-template-rows: min-content min-content min-content 1fr min-content;
|
|
||||||
grid-template-areas:
|
|
||||||
"name "
|
|
||||||
"skills "
|
|
||||||
"specs "
|
|
||||||
"avatar "
|
|
||||||
"stats ";
|
|
||||||
|
|
||||||
border: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
transition-property: all;
|
|
||||||
transition-duration: 0.25s;
|
|
||||||
transition-delay: 0;
|
|
||||||
transition-timing-function: ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct:first-child {
|
|
||||||
border-left-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct:not(:last-child) {
|
|
||||||
border-right: 1px solid #222;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct .skills {
|
|
||||||
flex-flow: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct .skills button {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct .specs {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.construct-list .stats {
|
|
||||||
flex-flow: row wrap;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct .stats div.speed {
|
|
||||||
order: -1;
|
|
||||||
flex: 1 0 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-construct .stats div {
|
|
||||||
flex: 1 1 33%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-nav {
|
|
||||||
display: flex;
|
|
||||||
grid-area: nav;
|
|
||||||
margin-right: 0;
|
|
||||||
border-top: 2px solid #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-nav button {
|
|
||||||
font-size: 150%;
|
|
||||||
border-right: 2px solid #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.instance-nav button:last-child {
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -142,6 +142,19 @@ section {
|
|||||||
border-color: forestgreen;
|
border-color: forestgreen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// // all green
|
||||||
|
// button.ready:enabled {
|
||||||
|
// background: forestgreen;
|
||||||
|
// color: black;
|
||||||
|
// border-color: forestgreen;
|
||||||
|
|
||||||
|
// &:hover {
|
||||||
|
// color: forestgreen;
|
||||||
|
// border-color: forestgreen;
|
||||||
|
// background: 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,29 +228,3 @@ section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 800px) {
|
|
||||||
section {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
|
|
||||||
.list {
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
|
|
||||||
&.play {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu .team {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
|
|
||||||
.construct {
|
|
||||||
height: 10em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.account {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -309,6 +309,7 @@ li {
|
|||||||
background-size: contain;
|
background-size: contain;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
z-index: 0;
|
||||||
// pointer-events: none;
|
// pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,3 +318,28 @@ li {
|
|||||||
height: 1px;
|
height: 1px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#rotate {
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
z-index: 1000;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background-image: url("./../rotate.svg");
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
|
&.show {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -1,115 +1,187 @@
|
|||||||
@media (max-width: 800px) {
|
@media (max-width: 1000px) {
|
||||||
body {
|
body {
|
||||||
overflow-y: initial;
|
overflow-y: initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mnml {
|
#mnml {
|
||||||
font-size: 12pt;
|
font-size: 8pt;
|
||||||
padding: 0;
|
padding: 0.25em;
|
||||||
|
|
||||||
|
.instance {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: min-content 1fr;
|
||||||
|
|
||||||
|
grid-template-areas:
|
||||||
|
"vbox"
|
||||||
|
"constructs";
|
||||||
|
|
||||||
|
svg {
|
||||||
|
stroke-width: 1.25em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.game {
|
||||||
|
.team, #targeting, .resolving-skill {
|
||||||
|
width: calc(90% - 3em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-construct {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: min-content 1fr;
|
||||||
|
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
grid-area: initial;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
svg {
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skills {
|
||||||
|
button[disabled] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.effects {
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.player {
|
||||||
|
.game-construct {
|
||||||
|
grid-template-areas:
|
||||||
|
"left"
|
||||||
|
"right";
|
||||||
|
|
||||||
|
.left {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
grid-template-rows: 1fr min-content;
|
||||||
|
grid-template-areas:
|
||||||
|
"skills"
|
||||||
|
"effects";
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.opponent {
|
||||||
|
.game-construct {
|
||||||
|
grid-template-rows: 2fr min-content;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"right"
|
||||||
|
"left";
|
||||||
|
|
||||||
|
.left {
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
bottom: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.instance-construct {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.skills, .specs {
|
||||||
|
font-size: 75%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
grid-area: initial;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aside {
|
||||||
|
button {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// portrait menu
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
#mnml {
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
grid-template-rows: 10fr 1fr;
|
grid-template-rows: 1fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"main"
|
"main"
|
||||||
"footer";
|
|
||||||
|
|
||||||
height: 100vh;
|
|
||||||
max-height: initial;
|
|
||||||
min-height: initial;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
table td {
|
section {
|
||||||
height: 2.5em;
|
grid-template-columns: 1fr;
|
||||||
|
|
||||||
|
.list {
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
|
||||||
|
&.play {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
.account {
|
||||||
display: none;
|
grid-template-columns: 1fr;
|
||||||
}
|
|
||||||
|
|
||||||
aside {
|
div {
|
||||||
display: none;
|
padding: 0;
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
display: flex;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
button {
|
|
||||||
font-size: 90%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#nav-btn, #instance-nav {
|
.play-ctrl {
|
||||||
display: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mnml.nav-visible nav {
|
|
||||||
padding: 0.5em;
|
|
||||||
margin: 0;
|
|
||||||
display: block;
|
|
||||||
grid-area: main;
|
|
||||||
}
|
|
||||||
|
|
||||||
#mnml.nav-visible main {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
|
||||||
overflow-x: hidden;
|
|
||||||
overflow-y: initial;
|
|
||||||
max-height: 100vh;
|
|
||||||
padding: 0 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome .login {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome .options {
|
|
||||||
width: 100%;
|
|
||||||
flex-flow: row wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome .options button {
|
|
||||||
flex: 1 0 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.timer-container {
|
|
||||||
margin: 0.5em 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-title {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-instances {
|
|
||||||
display: grid;
|
|
||||||
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
grid-template-areas:
|
|
||||||
"constructs"
|
|
||||||
"inventory"
|
|
||||||
"games";
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
.menu {
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
|
||||||
.options {
|
.options {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
|
||||||
button:not(:last-child) {
|
button:not(:last-child) {
|
||||||
border: 2px solid #222;
|
border: 2px solid #222;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.logo {
|
button.logo {
|
||||||
|
grid-column-end: span 2;
|
||||||
border: none;
|
border: none;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
margin-top: 0.5em;
|
margin-top: 0.5em;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.team {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
|
||||||
|
.construct {
|
||||||
|
height: 10em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.news {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
section {
|
section {
|
||||||
@ -117,14 +189,4 @@
|
|||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.account {
|
|
||||||
div {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.play-p {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -22,10 +22,6 @@
|
|||||||
grid-gap: 0.5em 1em;
|
grid-gap: 0.5em 1em;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
|
|
||||||
button {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.vbox-btn {
|
.vbox-btn {
|
||||||
@ -73,6 +69,7 @@
|
|||||||
button {
|
button {
|
||||||
height: 4em;
|
height: 4em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
// text-transform: none;
|
// text-transform: none;
|
||||||
|
|
||||||
@ -83,7 +80,7 @@
|
|||||||
&.highlight {
|
&.highlight {
|
||||||
color: black;
|
color: black;
|
||||||
background: @white;
|
background: @white;
|
||||||
border: 1px solid @white;
|
// border: 1px solid @white; (this bangs around the vbox)
|
||||||
|
|
||||||
// overwrite the classes on white svg elements
|
// overwrite the classes on white svg elements
|
||||||
svg {
|
svg {
|
||||||
@ -100,7 +97,7 @@
|
|||||||
figure {
|
figure {
|
||||||
svg {
|
svg {
|
||||||
height: 2em;
|
height: 2em;
|
||||||
stroke-width: 8px;
|
stroke-width: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
figcaption {
|
figcaption {
|
||||||
@ -108,3 +105,62 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* VBOX */
|
||||||
|
.vbox {
|
||||||
|
align-content: space-between;
|
||||||
|
grid-area: vbox;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: min-content min-content min-content;
|
||||||
|
grid-template-columns: 1fr min-content 1fr;
|
||||||
|
grid-template-areas:
|
||||||
|
"vbox varrow inventory"
|
||||||
|
"vbox varrow combiner";
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox-inventory {
|
||||||
|
grid-area: inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox-combiner {
|
||||||
|
grid-area: combiner;
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox-arrow, .vbox-arrow-mobile {
|
||||||
|
display: flex;
|
||||||
|
justify-content:center;
|
||||||
|
align-content:center;
|
||||||
|
flex-direction:column;
|
||||||
|
|
||||||
|
margin: 1em 0.25em 0 0.25em;
|
||||||
|
grid-area: varrow;
|
||||||
|
font-size: 2em;
|
||||||
|
color: @gray-hint;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox-combiner button {
|
||||||
|
flex: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.vbox-hdr {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox-hdr h3 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vbox-hdr .bits {
|
||||||
|
font-size: 2em;
|
||||||
|
line-height: 1em;
|
||||||
|
animation: bits 1s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arrow {
|
||||||
|
grid-area: arrow;
|
||||||
|
color: @gray-hint;
|
||||||
|
}
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
<link href="https://fonts.googleapis.com/css?family=Jura" rel="stylesheet">
|
<link href="https://fonts.googleapis.com/css?family=Jura" rel="stylesheet">
|
||||||
<link rel="stylesheet" href="assets/styles/normalize.css">
|
<link rel="stylesheet" href="assets/styles/normalize.css">
|
||||||
<link rel="stylesheet" href="assets/styles/skeleton.css">
|
<link rel="stylesheet" href="assets/styles/skeleton.css">
|
||||||
|
<link rel="icon" sizes="512x512" href="assets/icons/mnml.png">
|
||||||
|
<link rel="apple-touch-icon" href="assets/icons/mnml.png">
|
||||||
</head>
|
</head>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml",
|
"name": "MNML",
|
||||||
"description": "mnml pvp atbs",
|
"description": "abstract strategy",
|
||||||
"short_name": "mnml",
|
"short_name": "MNML",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "./assets/icons/mnml.png",
|
"src": "./assets/icons/mnml.png",
|
||||||
@ -15,7 +15,8 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"start_url": "/index.html",
|
"start_url": "/index.html",
|
||||||
"display": "fullscreen",
|
"display": "standalone",
|
||||||
|
"orientation": "landscape",
|
||||||
"theme_color": "#000000",
|
"theme_color": "#000000",
|
||||||
"background_color": "#000000"
|
"background_color": "#000000"
|
||||||
}
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml-client",
|
"name": "mnml-client",
|
||||||
"version": "1.7.1",
|
"version": "1.8.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -36,12 +36,10 @@ export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
|
|||||||
export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value });
|
export const setItemUnequip = value => ({ type: 'SET_ITEM_UNEQUIP', value });
|
||||||
export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value });
|
export const setMtxActive = value => ({ type: 'SET_MTX_ACTIVE', value });
|
||||||
export const setNav = value => ({ type: 'SET_NAV', value });
|
export const setNav = value => ({ type: 'SET_NAV', value });
|
||||||
export const setNavInstance = value => ({ type: 'SET_NAV_INSTANCE', value });
|
|
||||||
export const setPing = value => ({ type: 'SET_PING', value });
|
export const setPing = value => ({ type: 'SET_PING', value });
|
||||||
export const setPlayer = value => ({ type: 'SET_PLAYER', value });
|
export const setPlayer = value => ({ type: 'SET_PLAYER', value });
|
||||||
export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value });
|
export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value });
|
||||||
export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value });
|
export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value });
|
||||||
export const setShowNav = value => ({ type: 'SET_SHOW_NAV', value });
|
|
||||||
export const setSkip = value => ({ type: 'SET_SKIP', value });
|
export const setSkip = value => ({ type: 'SET_SKIP', value });
|
||||||
export const setShop = value => ({ type: 'SET_SHOP', value });
|
export const setShop = value => ({ type: 'SET_SHOP', value });
|
||||||
export const setSubscription = value => ({ type: 'SET_SUBSCRIPTION', value });
|
export const setSubscription = value => ({ type: 'SET_SUBSCRIPTION', value });
|
||||||
|
|||||||
@ -160,7 +160,7 @@ function getText(resolution) {
|
|||||||
|
|
||||||
if (type === 'Recharge') {
|
if (type === 'Recharge') {
|
||||||
const { red, blue } = event;
|
const { red, blue } = event;
|
||||||
if (red > 0 && blue > 0) return { text: [`+${red}R +${blue}B`, ''], css: 'purple-damage' };
|
if (red > 0 && blue > 0) return { text: [`+${red}R +${blue}B`, ''], css: 'rb-damage' };
|
||||||
if (red > 0) return { text: [`+${red}R`, ''], css: 'red-damage' };
|
if (red > 0) return { text: [`+${red}R`, ''], css: 'red-damage' };
|
||||||
if (blue > 0) return { text: [`+${blue}B`, ''], css: 'blue-damage' };
|
if (blue > 0) return { text: [`+${blue}B`, ''], css: 'blue-damage' };
|
||||||
return nullText;
|
return nullText;
|
||||||
|
|||||||
@ -38,7 +38,7 @@ class SiphonTick extends Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<svg
|
<svg
|
||||||
class={'skill-anim'}
|
class='skill-anim'
|
||||||
version="1.1"
|
version="1.1"
|
||||||
id="Layer_1"
|
id="Layer_1"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
module.exports = { // This will need to be edited if we change server recipes
|
// This will need to be edited if we change server recipes
|
||||||
|
module.exports = {
|
||||||
// Attack
|
// Attack
|
||||||
Strike: () => 'red-border',
|
Strike: () => 'red-border',
|
||||||
Blast: () => 'blue-border',
|
Blast: () => 'blue-border',
|
||||||
@ -7,7 +8,7 @@ module.exports = { // This will need to be edited if we change server recipes
|
|||||||
Slay: () => 'red-green-border',
|
Slay: () => 'red-green-border',
|
||||||
Siphon: () => 'blue-green-border',
|
Siphon: () => 'blue-green-border',
|
||||||
// Stun
|
// Stun
|
||||||
Link: () => 'blue-greenborder',
|
Link: () => 'blue-green-border',
|
||||||
Bash: () => 'red-border',
|
Bash: () => 'red-border',
|
||||||
Sleep: () => 'green-border',
|
Sleep: () => 'green-border',
|
||||||
Ruin: () => 'blue-border',
|
Ruin: () => 'blue-border',
|
||||||
@ -31,9 +32,9 @@ module.exports = { // This will need to be edited if we change server recipes
|
|||||||
Restrict: () => 'red-border',
|
Restrict: () => 'red-border',
|
||||||
Purge: () => 'green-border',
|
Purge: () => 'green-border',
|
||||||
Silence: () => 'blue-border',
|
Silence: () => 'blue-border',
|
||||||
Curse: () => 'red-green-border',
|
Invert: () => 'red-green-border',
|
||||||
Decay: () => 'blue-green-border',
|
Decay: () => 'blue-green-border',
|
||||||
Invert: () => 'red-blue-border',
|
Curse: () => 'red-blue-border',
|
||||||
|
|
||||||
// // Lifes Upgrades
|
// // Lifes Upgrades
|
||||||
// LifeGG: () => 'green-border',
|
// LifeGG: () => 'green-border',
|
||||||
|
|||||||
@ -84,7 +84,7 @@ function Demo(args) {
|
|||||||
|
|
||||||
function inventoryElement() {
|
function inventoryElement() {
|
||||||
return (
|
return (
|
||||||
<div class="vbox visible">
|
<div class="vbox">
|
||||||
<div class='vbox-section'>
|
<div class='vbox-section'>
|
||||||
<h2 class='colour-info'>
|
<h2 class='colour-info'>
|
||||||
VBOX PHASE {shapes.Red()} {shapes.Green()} {shapes.Blue()}
|
VBOX PHASE {shapes.Red()} {shapes.Green()} {shapes.Blue()}
|
||||||
@ -117,7 +117,7 @@ function Demo(args) {
|
|||||||
: 'empty gray';
|
: 'empty gray';
|
||||||
|
|
||||||
const constructEl = c => (
|
const constructEl = c => (
|
||||||
<div class="instance-construct visible">
|
<div class="instance-construct">
|
||||||
<h2 class="name" >{c.name}</h2>
|
<h2 class="name" >{c.name}</h2>
|
||||||
<ConstructAvatar construct={c} />
|
<ConstructAvatar construct={c} />
|
||||||
<div class="skills">
|
<div class="skills">
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
const { Component } = require('preact');
|
|
||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
const { connect } = require('preact-redux');
|
const { connect } = require('preact-redux');
|
||||||
|
|
||||||
const Hammer = require('hammerjs');
|
|
||||||
|
|
||||||
const Vbox = require('./vbox.component');
|
const Vbox = require('./vbox.component');
|
||||||
const InfoContainer = require('./info.container');
|
const InfoContainer = require('./info.container');
|
||||||
const InstanceConstructsContainer = require('./instance.constructs');
|
const InstanceConstructsContainer = require('./instance.constructs');
|
||||||
@ -16,12 +13,10 @@ const addState = connect(
|
|||||||
const {
|
const {
|
||||||
instance,
|
instance,
|
||||||
nav,
|
nav,
|
||||||
navInstance,
|
|
||||||
} = state;
|
} = state;
|
||||||
return {
|
return {
|
||||||
instance,
|
instance,
|
||||||
nav,
|
nav,
|
||||||
navInstance,
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -30,10 +25,6 @@ const addState = connect(
|
|||||||
return dispatch(actions.setInfo(c));
|
return dispatch(actions.setInfo(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNavInstance(c) {
|
|
||||||
return dispatch(actions.setNavInstance(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function clearItems() {
|
function clearItems() {
|
||||||
dispatch(actions.setCombiner([]));
|
dispatch(actions.setCombiner([]));
|
||||||
@ -48,80 +39,38 @@ const addState = connect(
|
|||||||
return {
|
return {
|
||||||
setInfo,
|
setInfo,
|
||||||
clearItems,
|
clearItems,
|
||||||
setNavInstance,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
class Instance extends Component {
|
function Instance(args) {
|
||||||
shouldComponentUpdate(newProps) {
|
const {
|
||||||
if (newProps.instance !== this.props.instance) return true;
|
instance,
|
||||||
return false;
|
clearItems,
|
||||||
|
} = args;
|
||||||
|
|
||||||
|
if (!instance) return false;
|
||||||
|
|
||||||
|
if (instance.phase !== 'InProgress') {
|
||||||
|
return <Faceoff />;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(args) {
|
function instanceClick(e) {
|
||||||
const {
|
e.stopPropagation();
|
||||||
instance,
|
clearItems();
|
||||||
clearItems,
|
|
||||||
} = args;
|
|
||||||
|
|
||||||
if (!instance) return false;
|
|
||||||
|
|
||||||
if (instance.phase !== 'InProgress') {
|
|
||||||
return <Faceoff />;
|
|
||||||
}
|
|
||||||
|
|
||||||
function instanceClick(e) {
|
|
||||||
e.stopPropagation();
|
|
||||||
clearItems();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onTouchMove(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<main id="instance" class='instance' onClick={instanceClick}>
|
|
||||||
<Vbox />
|
|
||||||
<InfoContainer />
|
|
||||||
<InstanceConstructsContainer />
|
|
||||||
</main>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
function onTouchMove(e) {
|
||||||
if (!this.h) this.bindSwipes();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate() {
|
return (
|
||||||
if (!this.h) this.bindSwipes();
|
<main id="instance" class='instance' onClick={instanceClick}>
|
||||||
}
|
<Vbox />
|
||||||
|
<InfoContainer />
|
||||||
bindSwipes() {
|
<InstanceConstructsContainer />
|
||||||
const instance = document.getElementById('instance');
|
</main>
|
||||||
if (!instance) {
|
);
|
||||||
return setTimeout(this.bindSwipes, 50);
|
|
||||||
}
|
|
||||||
if (this.h) this.h.destroy();
|
|
||||||
this.h = new Hammer(instance);
|
|
||||||
this.h.on('swiperight', () => {
|
|
||||||
const {
|
|
||||||
navInstance,
|
|
||||||
setNavInstance,
|
|
||||||
} = this.props;
|
|
||||||
setNavInstance(navInstance === 0 ? 3 : navInstance - 1);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.h.on('swipeleft', () => {
|
|
||||||
const {
|
|
||||||
navInstance,
|
|
||||||
setNavInstance,
|
|
||||||
} = this.props;
|
|
||||||
setNavInstance((navInstance + 1) % 4);
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = addState(Instance);
|
module.exports = addState(Instance);
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
const { connect } = require('preact-redux');
|
const { connect } = require('preact-redux');
|
||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
|
|
||||||
const range = require('lodash/range');
|
const range = require('lodash/range');
|
||||||
|
|
||||||
const buttons = require('./buttons');
|
const buttons = require('./buttons');
|
||||||
@ -19,10 +20,15 @@ const addState = connect(
|
|||||||
account,
|
account,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
itemEquip,
|
itemEquip,
|
||||||
navInstance,
|
itemUnequip,
|
||||||
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
|
function sendVboxAcceptEquip(constructId) {
|
||||||
|
return ws.sendVboxAcceptEquip(instance.id, vboxSelected[0], vboxSelected[1], constructId);
|
||||||
|
}
|
||||||
|
|
||||||
function sendVboxApply(constructId, i) {
|
function sendVboxApply(constructId, i) {
|
||||||
return ws.sendVboxApply(instance.id, constructId, i);
|
return ws.sendVboxApply(instance.id, constructId, i);
|
||||||
}
|
}
|
||||||
@ -31,15 +37,22 @@ const addState = connect(
|
|||||||
return ws.sendVboxUnequip(instance.id, constructId, item);
|
return ws.sendVboxUnequip(instance.id, constructId, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendVboxUnequipApply(targetConstructId) {
|
||||||
|
return ws.sendVboxUnequipApply(instance.id, itemUnequip[0], itemUnequip[1], targetConstructId);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
instance,
|
instance,
|
||||||
player,
|
player,
|
||||||
account,
|
account,
|
||||||
|
sendVboxAcceptEquip,
|
||||||
|
sendVboxUnequipApply,
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
itemEquip,
|
itemEquip,
|
||||||
navInstance,
|
itemUnequip,
|
||||||
sendUnequip,
|
sendUnequip,
|
||||||
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -76,21 +89,23 @@ function Construct(props) {
|
|||||||
construct,
|
construct,
|
||||||
iter,
|
iter,
|
||||||
itemEquip,
|
itemEquip,
|
||||||
|
itemUnequip,
|
||||||
instance,
|
instance,
|
||||||
mobileVisible,
|
|
||||||
player,
|
player,
|
||||||
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
// Static Info
|
// Static Info
|
||||||
itemInfo,
|
itemInfo,
|
||||||
// Function Calls
|
// Function Calls
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
|
sendVboxAcceptEquip,
|
||||||
|
sendVboxUnequipApply,
|
||||||
sendUnequip,
|
sendUnequip,
|
||||||
setActiveConstruct,
|
setActiveConstruct,
|
||||||
setItemUnequip,
|
setItemUnequip,
|
||||||
setItemEquip,
|
setItemEquip,
|
||||||
setInfo,
|
setInfo,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const { vbox } = player;
|
const { vbox } = player;
|
||||||
|
|
||||||
const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => {
|
const duplicateSkill = construct.skills.length !== 0 && construct.skills.every(sk => {
|
||||||
@ -99,14 +114,16 @@ function Construct(props) {
|
|||||||
return sk.skill === vbox.bound[itemEquip];
|
return sk.skill === vbox.bound[itemEquip];
|
||||||
});
|
});
|
||||||
const tutorialDisableEquip = tutorialShouldDisableEquip(tutorial, iter, instance, construct);
|
const tutorialDisableEquip = tutorialShouldDisableEquip(tutorial, iter, instance, construct);
|
||||||
|
|
||||||
function onClick(e) {
|
function onClick(e) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (duplicateSkill || tutorialDisableEquip) return true;
|
if (duplicateSkill || tutorialDisableEquip) return true;
|
||||||
if (itemEquip !== null) sendVboxApply(construct.id, itemEquip);
|
if (itemEquip !== null) return sendVboxApply(construct.id, itemEquip);
|
||||||
|
if (vboxSelected[0]) return sendVboxAcceptEquip(construct.id);
|
||||||
|
if (itemUnequip.length && itemUnequip[0] !== construct.id) return sendVboxUnequipApply(construct.id);
|
||||||
setItemEquip(null);
|
setItemEquip(null);
|
||||||
return setActiveConstruct(construct);
|
setItemUnequip([]);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hoverInfo(e, info) {
|
function hoverInfo(e, info) {
|
||||||
@ -153,15 +170,20 @@ function Construct(props) {
|
|||||||
|
|
||||||
const classes = `${equipping ? 'equipping' : ''} ${!skill ? 'empty' : ''} ${border()}`;
|
const classes = `${equipping ? 'equipping' : ''} ${!skill ? 'empty' : ''} ${border()}`;
|
||||||
return (
|
return (
|
||||||
<button
|
<label onDragStart={ev => {
|
||||||
key={i}
|
ev.dataTransfer.setData('text', '');
|
||||||
disabled={!skill && !equipping}
|
skillClick(ev);
|
||||||
class={classes}
|
}} key={i} draggable="true" onDragEnd={() => setItemUnequip([])}>
|
||||||
onClick={skillClick}
|
<button
|
||||||
onDblClick={skillDblClick}
|
key={i}
|
||||||
onMouseOver={e => hoverInfo(e, skill && skill.skill)} >
|
disabled={!skill && !equipping}
|
||||||
{s}
|
class={classes}
|
||||||
</button>
|
onClick={skillClick}
|
||||||
|
onDblClick={skillDblClick}
|
||||||
|
onMouseOver={e => hoverInfo(e, skill && skill.skill)} >
|
||||||
|
{s}
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -195,13 +217,18 @@ function Construct(props) {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button
|
<label onDragStart={ev => {
|
||||||
key={i}
|
ev.dataTransfer.setData('text', '');
|
||||||
onClick={specClick}
|
specClick(ev);
|
||||||
onDblClick={specDblClick}
|
}} key={i} draggable="true" onDragEnd={() => setItemUnequip([])}>
|
||||||
onMouseOver={e => hoverInfo(e, s)} >
|
<button
|
||||||
{shapes[s]()}
|
key={i}
|
||||||
</button>
|
onClick={specClick}
|
||||||
|
onDblClick={specDblClick}
|
||||||
|
onMouseOver={e => hoverInfo(e, s)} >
|
||||||
|
{shapes[s]()}
|
||||||
|
</button>
|
||||||
|
</label>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -220,10 +247,10 @@ function Construct(props) {
|
|||||||
</div>;
|
</div>;
|
||||||
});
|
});
|
||||||
|
|
||||||
const classes = `instance-construct ${mobileVisible ? 'visible' : ''}`;
|
const classes = `instance-construct`;
|
||||||
const avatarMouseOver = e => hoverInfo(e, `constructAvatar ${construct.name}`);
|
const avatarMouseOver = e => hoverInfo(e, `constructAvatar ${construct.name}`);
|
||||||
return (
|
return (
|
||||||
<div key={construct.id} class={classes} onClick={onClick}>
|
<div key={construct.id} class={classes} onClick={onClick} onDragOver={ev => ev.preventDefault()} onDrop={onClick}>
|
||||||
<ConstructAvatar construct={construct} mouseOver={avatarMouseOver}/>
|
<ConstructAvatar construct={construct} mouseOver={avatarMouseOver}/>
|
||||||
<h2 class="name" onMouseOver={e => hoverInfo(e, `constructName ${construct.name}`)}>{construct.name}</h2>
|
<h2 class="name" onMouseOver={e => hoverInfo(e, `constructName ${construct.name}`)}>{construct.name}</h2>
|
||||||
<div class="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} >
|
<div class="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} >
|
||||||
@ -242,11 +269,12 @@ 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.itemEquip !== this.props.itemEquip) 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;
|
||||||
if (newProps.navInstance !== this.props.navInstance) return true;
|
|
||||||
// JSON or Array objects
|
// JSON or Array objects
|
||||||
if (newProps.player !== this.props.player) return true;
|
if (newProps.player !== this.props.player) return true;
|
||||||
if (newProps.instance !== this.props.instance) return true;
|
if (newProps.instance !== this.props.instance) return true;
|
||||||
|
if (newProps.vboxSelected !== this.props.vboxSelected) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,16 +282,19 @@ class InstanceConstructs extends preact.Component {
|
|||||||
const {
|
const {
|
||||||
// Changing state variables
|
// Changing state variables
|
||||||
itemEquip,
|
itemEquip,
|
||||||
|
itemUnequip,
|
||||||
instance,
|
instance,
|
||||||
navInstance,
|
|
||||||
player,
|
player,
|
||||||
tutorial,
|
tutorial,
|
||||||
|
vboxSelected,
|
||||||
// Static data
|
// Static data
|
||||||
itemInfo,
|
itemInfo,
|
||||||
// Function calls
|
// Function calls
|
||||||
setInfo,
|
setInfo,
|
||||||
setActiveConstruct,
|
setActiveConstruct,
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
|
sendVboxAcceptEquip,
|
||||||
|
sendVboxUnequipApply,
|
||||||
setVboxHighlight,
|
setVboxHighlight,
|
||||||
setItemUnequip,
|
setItemUnequip,
|
||||||
setItemEquip,
|
setItemEquip,
|
||||||
@ -274,25 +305,28 @@ class InstanceConstructs extends preact.Component {
|
|||||||
if (instance.phase === 'Lobby') return false;
|
if (instance.phase === 'Lobby') return false;
|
||||||
|
|
||||||
const constructs = range(0, 3).map(i => {
|
const constructs = range(0, 3).map(i => {
|
||||||
const tutorialConstruct = tutorialConstructDisplay(player, instance, tutorial, navInstance, i);
|
const tutorialConstruct = tutorialConstructDisplay(player, instance, tutorial, i);
|
||||||
if (tutorialConstruct) return (tutorialConstruct);
|
if (tutorialConstruct) return (tutorialConstruct);
|
||||||
|
|
||||||
return Construct({
|
return Construct({
|
||||||
iter: i,
|
iter: i,
|
||||||
construct: player.constructs[i],
|
construct: player.constructs[i],
|
||||||
itemEquip,
|
itemEquip,
|
||||||
|
itemUnequip,
|
||||||
instance,
|
instance,
|
||||||
setItemUnequip,
|
setItemUnequip,
|
||||||
setItemEquip,
|
setItemEquip,
|
||||||
player,
|
player,
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
|
sendVboxAcceptEquip,
|
||||||
|
sendVboxUnequipApply,
|
||||||
setInfo,
|
setInfo,
|
||||||
setActiveConstruct,
|
setActiveConstruct,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
setVboxHighlight,
|
setVboxHighlight,
|
||||||
sendUnequip,
|
sendUnequip,
|
||||||
|
vboxSelected,
|
||||||
tutorial,
|
tutorial,
|
||||||
mobileVisible: navInstance === i + 1,
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -7,24 +7,28 @@ const Controls = require('./controls');
|
|||||||
const Footer = require('./footer');
|
const Footer = require('./footer');
|
||||||
|
|
||||||
const addState = connect(
|
const addState = connect(
|
||||||
state => ({ showNav: state.showNav })
|
({ game, instance }) => ({ game, instance })
|
||||||
);
|
);
|
||||||
|
|
||||||
class Mnml extends preact.Component {
|
function Mnml(args) {
|
||||||
shouldComponentUpdate(newProps) {
|
const {
|
||||||
if (newProps.showNav !== this.props.showNav) return true;
|
game,
|
||||||
return false;
|
instance,
|
||||||
}
|
} = args;
|
||||||
|
|
||||||
render(args) {
|
const rotateClass = (game || instance) && window.innerWidth < window.innerHeight
|
||||||
return (
|
? 'show'
|
||||||
<div id="mnml" class={args.showNav ? 'nav-visible' : ''}>
|
: '';
|
||||||
<Main />
|
|
||||||
<Controls />
|
return (
|
||||||
<Footer />
|
<div id="mnml">
|
||||||
|
<Main />
|
||||||
|
<Controls />
|
||||||
|
<Footer />
|
||||||
|
<div id="rotate" class={rotateClass} >
|
||||||
</div>
|
</div>
|
||||||
);
|
</div>
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = addState(Mnml);
|
module.exports = addState(Mnml);
|
||||||
|
|||||||
@ -60,10 +60,10 @@ function Scoreboard(args) {
|
|||||||
} = args;
|
} = args;
|
||||||
|
|
||||||
const scoreText = () => {
|
const scoreText = () => {
|
||||||
if (player.score === 'Zero' || player.score === 'Lose') return [<span i={0}>▫</span>, <span i={1}>▫</span>, <span i={2}>▫</span>];
|
if (player.score === 'Zero' || player.score === 'Lose') return [<span i={0}>▫</span>, <span i={1}>▫</span>, <span i={2}>▫</span>];
|
||||||
if (player.score === 'One') return [<span i={0}>■</span>, <span i={1}>▫</span>, <span i={2}>▫</span>];
|
if (player.score === 'One') return [<span i={0}>■</span>, <span i={1}>▫</span>, <span i={2}>▫</span>];
|
||||||
if (player.score === 'Two') return [<span i={0}>■</span>, <span i={1}>■</span>, <span i={2}>▫</span>];
|
if (player.score === 'Two') return [<span i={0}>■</span>, <span i={1}>■</span>, <span i={2}>▫</span>];
|
||||||
if (player.score === 'Win') return [<span i={0}>■</span>, <span i={1}>■</span>, <span i={2}>■</span>];
|
if (player.score === 'Win') return [<span i={0}>■</span>, <span i={1}>■</span>, <span i={2}>■</span>];
|
||||||
return '';
|
return '';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -117,8 +117,6 @@ function Reshape(args) {
|
|||||||
</div>
|
</div>
|
||||||
<div class='list'>
|
<div class='list'>
|
||||||
{shop.owned.map(useMtx)}
|
{shop.owned.map(useMtx)}
|
||||||
</div>
|
|
||||||
<div class='list'>
|
|
||||||
{shop.available.map(availableMtx)}
|
{shop.available.map(availableMtx)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -59,7 +59,7 @@ class TargetSvg extends Component {
|
|||||||
if (tutorialGame) {
|
if (tutorialGame) {
|
||||||
return (
|
return (
|
||||||
<div class="resolving-skill">
|
<div class="resolving-skill">
|
||||||
<h2> Select your skills, click on targets and then hit <b>ready</b>.</h2>
|
<h2> Select your skills, click on targets and then hit <b>READY</b>.</h2>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,6 @@ const addState = connect(
|
|||||||
vboxSelected,
|
vboxSelected,
|
||||||
itemInfo,
|
itemInfo,
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
navInstance,
|
|
||||||
tutorial,
|
tutorial,
|
||||||
} = state;
|
} = state;
|
||||||
|
|
||||||
@ -29,6 +28,7 @@ const addState = connect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sendVboxAccept(group, index) {
|
function sendVboxAccept(group, index) {
|
||||||
|
document.activeElement.blur();
|
||||||
return ws.sendVboxAccept(instance.id, group, index);
|
return ws.sendVboxAccept(instance.id, group, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,6 @@ const addState = connect(
|
|||||||
itemInfo,
|
itemInfo,
|
||||||
itemUnequip,
|
itemUnequip,
|
||||||
sendItemUnequip,
|
sendItemUnequip,
|
||||||
navInstance,
|
|
||||||
tutorial,
|
tutorial,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -100,7 +99,6 @@ class Vbox extends preact.Component {
|
|||||||
if (newProps.combiner !== this.props.combiner) return true;
|
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.navInstance !== this.props.navInstance) return true;
|
|
||||||
if (newProps.tutorial !== this.props.tutorial) return true;
|
if (newProps.tutorial !== this.props.tutorial) return true;
|
||||||
if (newProps.vboxSelected !== this.props.vboxSelected) return true;
|
if (newProps.vboxSelected !== this.props.vboxSelected) return true;
|
||||||
if (newProps.player !== this.props.player) return true;
|
if (newProps.player !== this.props.player) return true;
|
||||||
@ -116,7 +114,6 @@ class Vbox extends preact.Component {
|
|||||||
player,
|
player,
|
||||||
reclaiming,
|
reclaiming,
|
||||||
tutorial,
|
tutorial,
|
||||||
navInstance,
|
|
||||||
vboxSelected,
|
vboxSelected,
|
||||||
instance,
|
instance,
|
||||||
|
|
||||||
@ -180,7 +177,7 @@ class Vbox extends preact.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function availableBtn(v, group, index) {
|
function availableBtn(v, group, index) {
|
||||||
if (!v) return <button disabled class='empty' > </button>;
|
if (!v) return <button disabled class='empty' key={(group * 10) + index} > </button>;
|
||||||
const selected = vboxSelected[0] === group && vboxSelected[1] === index;
|
const selected = vboxSelected[0] === group && vboxSelected[1] === index;
|
||||||
|
|
||||||
// state not yet set in double click handler
|
// state not yet set in double click handler
|
||||||
@ -194,8 +191,6 @@ class Vbox extends preact.Component {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setItemEquip(null);
|
setItemEquip(null);
|
||||||
setCombiner([]);
|
setCombiner([]);
|
||||||
|
|
||||||
if (selected) return clearVboxSelected();
|
|
||||||
setInfo(vbox.free[group][index]);
|
setInfo(vbox.free[group][index]);
|
||||||
return setVboxSelected([group, index]);
|
return setVboxSelected([group, index]);
|
||||||
}
|
}
|
||||||
@ -217,28 +212,24 @@ class Vbox extends preact.Component {
|
|||||||
|
|
||||||
const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`;
|
const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`;
|
||||||
|
|
||||||
if (shapes[v]) {
|
const vboxObject = shapes[v] ? shapes[v]() : v;
|
||||||
return (
|
return (
|
||||||
|
<label draggable='true'
|
||||||
|
onDragStart={ev => {
|
||||||
|
onClick(ev);
|
||||||
|
ev.dataTransfer.setData('text', '')
|
||||||
|
}}
|
||||||
|
key={group * 10 + index}
|
||||||
|
onDragEnd={clearVboxSelected}>
|
||||||
<button
|
<button
|
||||||
class={classes}
|
class={classes}
|
||||||
onMouseOver={e => vboxHover(e, v)}
|
onMouseOver={e => vboxHover(e, v)}
|
||||||
onMouseDown={onClick}
|
onMouseDown={onClick}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
onDblClick={onDblClick} >
|
onDblClick={onDblClick}
|
||||||
{shapes[v]()}
|
> {vboxObject}
|
||||||
</button>
|
</button>
|
||||||
);
|
</label>
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
class={classes}
|
|
||||||
onMouseDown={onClick}
|
|
||||||
onClick={e => e.stopPropagation()}
|
|
||||||
onDblClick={onDblClick}
|
|
||||||
onMouseOver={e => vboxHover(e, v)}>
|
|
||||||
{v}
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -288,7 +279,7 @@ class Vbox extends preact.Component {
|
|||||||
const inventoryHighlight = vboxSelecting || itemUnequip.length;
|
const inventoryHighlight = vboxSelecting || itemUnequip.length;
|
||||||
|
|
||||||
if (!v && v !== 0) {
|
if (!v && v !== 0) {
|
||||||
return <button disabled={!inventoryHighlight} class={inventoryHighlight ? 'receiving' : 'empty'} > </button>;
|
return <button key={i} disabled={!inventoryHighlight} class={inventoryHighlight ? 'receiving' : 'empty'} > </button>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const combinerItems = combiner.map(j => vbox.bound[j]);
|
const combinerItems = combiner.map(j => vbox.bound[j]);
|
||||||
@ -306,54 +297,55 @@ class Vbox extends preact.Component {
|
|||||||
} return false;
|
} return false;
|
||||||
}) ? 'combo-border' : '';
|
}) ? 'combo-border' : '';
|
||||||
|
|
||||||
function onClick(e) {
|
function onClick(type) {
|
||||||
if (vboxSelecting) clearVboxSelected();
|
if (vboxSelecting) clearVboxSelected();
|
||||||
if (reclaiming) return sendVboxReclaim(i);
|
if (reclaiming) return sendVboxReclaim(i);
|
||||||
|
|
||||||
|
const combinerContainsIndex = combiner.indexOf(i) > -1;
|
||||||
// 4 things selected
|
// 4 things selected
|
||||||
if (combiner.length > 2) {
|
if (combiner.length > 2 && !combinerContainsIndex) {
|
||||||
setInfo(vbox.bound[i]);
|
setInfo(vbox.bound[i]);
|
||||||
return combinerChange([i]);
|
return combinerChange([i]);
|
||||||
}
|
}
|
||||||
// removing
|
// removing
|
||||||
const combinerIndex = combiner.indexOf(i);
|
if (combinerContainsIndex) {
|
||||||
if (combinerIndex > -1) {
|
if (type === 'click') {
|
||||||
return combinerChange(without(combiner, i));
|
return combinerChange(without(combiner, i));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
combiner.push(i);
|
if (!comboHighlight && !combinerContainsIndex) {
|
||||||
|
|
||||||
if (!comboHighlight) {
|
|
||||||
setInfo(vbox.bound[i]);
|
setInfo(vbox.bound[i]);
|
||||||
return combinerChange([i]);
|
return combinerChange([i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
combiner.push(i);
|
||||||
return combinerChange(combiner);
|
return combinerChange(combiner);
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlighted = combiner.indexOf(i) > -1;
|
const highlighted = combiner.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}`;
|
||||||
if (shapes[v]) {
|
|
||||||
return (
|
const invObject = shapes[v] ? shapes[v]() : v;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<label
|
||||||
|
key={i}
|
||||||
|
draggable='true'
|
||||||
|
onDragStart={ev => {
|
||||||
|
onClick('drag');
|
||||||
|
ev.dataTransfer.setData('text', '');
|
||||||
|
}}>
|
||||||
<button
|
<button
|
||||||
class={classes}
|
class={classes}
|
||||||
onMouseOver={e => vboxHover(e, v)}
|
onMouseOver={e => vboxHover(e, v)}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
onMouseDown={onClick}>
|
onMouseDown={() => onClick('click')}>
|
||||||
{shapes[v]()}
|
{invObject}
|
||||||
</button>
|
</button>
|
||||||
);
|
</label>
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button
|
|
||||||
class={classes}
|
|
||||||
onMouseDown={onClick}
|
|
||||||
onClick={e => e.stopPropagation()}
|
|
||||||
onMouseOver={e => vboxHover(e, v)}>
|
|
||||||
{v}
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,7 +400,10 @@ class Vbox extends preact.Component {
|
|||||||
<div class={inventoryClass}
|
<div class={inventoryClass}
|
||||||
onMouseDown={inventoryClick}
|
onMouseDown={inventoryClick}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
style={vboxSelecting || (itemUnequip.length) ? { cursor: 'pointer' } : null}>
|
style={vboxSelecting || (itemUnequip.length) ? { cursor: 'pointer' } : null}
|
||||||
|
onDragOver={ev => ev.preventDefault()}
|
||||||
|
onDrop={inventoryClick}
|
||||||
|
>
|
||||||
<div class="vbox-hdr">
|
<div class="vbox-hdr">
|
||||||
<h3
|
<h3
|
||||||
onTouchStart={e => e.target.scrollIntoView(true)}
|
onTouchStart={e => e.target.scrollIntoView(true)}
|
||||||
@ -439,7 +434,7 @@ class Vbox extends preact.Component {
|
|||||||
return setInfo(newInfo);
|
return setInfo(newInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = `vbox ${navInstance === 0 ? 'visible' : ''}`;
|
const classes = `vbox`;
|
||||||
return (
|
return (
|
||||||
<div class={classes}>
|
<div class={classes}>
|
||||||
{vboxElement()}
|
{vboxElement()}
|
||||||
|
|||||||
@ -12,6 +12,13 @@ const { tutorialVbox } = require('./tutorial.utils');
|
|||||||
|
|
||||||
function registerEvents(store) {
|
function registerEvents(store) {
|
||||||
function notify(msg) {
|
function notify(msg) {
|
||||||
|
if (window.Notification && window.Notification.permission === 'granted') {
|
||||||
|
const n = new Notification('MNML', {
|
||||||
|
body: msg,
|
||||||
|
tag: 'MNML',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return infoToast(msg);
|
return infoToast(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,9 +134,13 @@ function registerEvents(store) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setAccount(account) {
|
function setAccount(account) {
|
||||||
if (account) {
|
if (account && process.env.NODE_ENV !== 'development') {
|
||||||
LogRocket.init('yh0dy3/mnml');
|
LogRocket.init('yh0dy3/mnml');
|
||||||
LogRocket.identify(account.id, account);
|
LogRocket.identify(account.id, account);
|
||||||
|
|
||||||
|
if (window.Notification) {
|
||||||
|
window.Notification.requestPermission();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch(actions.setAccount(account));
|
store.dispatch(actions.setAccount(account));
|
||||||
@ -179,6 +190,7 @@ function registerEvents(store) {
|
|||||||
store.dispatch(actions.setItemEquip(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([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
function setAccountInstances(v) {
|
function setAccountInstances(v) {
|
||||||
@ -212,7 +224,9 @@ function registerEvents(store) {
|
|||||||
if (v.phase === 'Finished') {
|
if (v.phase === 'Finished') {
|
||||||
ws.sendAccountInstances();
|
ws.sendAccountInstances();
|
||||||
}
|
}
|
||||||
if (localStorage.getItem('tutorial-complete')) {
|
|
||||||
|
// instance.mobile.less hides info at @media 1000
|
||||||
|
if (localStorage.getItem('tutorial-complete') || window.innerWidth <= 1100) {
|
||||||
store.dispatch(actions.setTutorial(null));
|
store.dispatch(actions.setTutorial(null));
|
||||||
} else if (v.time_control === 'Practice' && v.rounds.length === 1 && tutorial) {
|
} else if (v.time_control === 'Practice' && v.rounds.length === 1 && tutorial) {
|
||||||
tutorialVbox(player, store, tutorial);
|
tutorialVbox(player, store, tutorial);
|
||||||
|
|||||||
@ -45,8 +45,6 @@ module.exports = {
|
|||||||
itemUnequip: createReducer([], 'SET_ITEM_UNEQUIP'),
|
itemUnequip: createReducer([], 'SET_ITEM_UNEQUIP'),
|
||||||
mtxActive: createReducer(null, 'SET_MTX_ACTIVE'),
|
mtxActive: createReducer(null, 'SET_MTX_ACTIVE'),
|
||||||
nav: createReducer(null, 'SET_NAV'),
|
nav: createReducer(null, 'SET_NAV'),
|
||||||
navInstance: createReducer(0, 'SET_NAV_INSTANCE'),
|
|
||||||
showNav: createReducer(null, 'SET_SHOW_NAV'),
|
|
||||||
ping: createReducer(null, 'SET_PING'),
|
ping: createReducer(null, 'SET_PING'),
|
||||||
player: createReducer(null, 'SET_PLAYER'),
|
player: createReducer(null, 'SET_PLAYER'),
|
||||||
reclaiming: createReducer(false, 'SET_RECLAIMING'),
|
reclaiming: createReducer(false, 'SET_RECLAIMING'),
|
||||||
|
|||||||
@ -82,6 +82,11 @@ function createSocket(events) {
|
|||||||
events.clearInstance();
|
events.clearInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendVboxAcceptEquip(instanceId, group, index, constructId) {
|
||||||
|
send(['VboxAcceptEquip', { instance_id: instanceId, group, index, construct_id: constructId }]);
|
||||||
|
events.clearInstance();
|
||||||
|
}
|
||||||
|
|
||||||
function sendVboxApply(instanceId, constructId, index) {
|
function sendVboxApply(instanceId, constructId, index) {
|
||||||
send(['VboxApply', { instance_id: instanceId, construct_id: constructId, index }]);
|
send(['VboxApply', { instance_id: instanceId, construct_id: constructId, index }]);
|
||||||
events.clearInstance();
|
events.clearInstance();
|
||||||
@ -92,6 +97,11 @@ function createSocket(events) {
|
|||||||
events.clearInstance();
|
events.clearInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function sendVboxUnequipApply(instanceId, constructId, target, targetConstructId) {
|
||||||
|
send(['VboxUnequipApply', { instance_id: instanceId, construct_id: constructId, target, target_construct_id: targetConstructId }]);
|
||||||
|
events.clearInstance();
|
||||||
|
}
|
||||||
|
|
||||||
function sendVboxDiscard(instanceId) {
|
function sendVboxDiscard(instanceId) {
|
||||||
send(['VboxDiscard', { instance_id: instanceId }]);
|
send(['VboxDiscard', { instance_id: instanceId }]);
|
||||||
events.clearInstance();
|
events.clearInstance();
|
||||||
@ -99,7 +109,7 @@ function createSocket(events) {
|
|||||||
|
|
||||||
function sendVboxCombine(instanceId, indices) {
|
function sendVboxCombine(instanceId, indices) {
|
||||||
send(['VboxCombine', { instance_id: instanceId, indices }]);
|
send(['VboxCombine', { instance_id: instanceId, indices }]);
|
||||||
events.clearCombiner();
|
events.clearInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendVboxReclaim(instanceId, index) {
|
function sendVboxReclaim(instanceId, index) {
|
||||||
@ -264,13 +274,14 @@ function createSocket(events) {
|
|||||||
Pong: onPong,
|
Pong: onPong,
|
||||||
Demo: onDemo,
|
Demo: onDemo,
|
||||||
|
|
||||||
QueueRequested: () => events.notify('pvp queue request received'),
|
QueueRequested: () => events.notify('PVP queue request received.'),
|
||||||
QueueJoined: () => events.notify('you have joined the pvp queue'),
|
QueueJoined: () => events.notify('You have joined the PVP queue.'),
|
||||||
InviteRequested: () => events.notify('pvp invite request received'),
|
QueueFound: () => events.notify('Your PVP game has started.'),
|
||||||
|
InviteRequested: () => events.notify('PVP invite request received.'),
|
||||||
Invite: code => events.setInvite(code),
|
Invite: code => events.setInvite(code),
|
||||||
InstanceChat: chat => events.setInstanceChat(chat),
|
InstanceChat: chat => events.setInstanceChat(chat),
|
||||||
ChatWheel: wheel => events.setChatWheel(wheel),
|
ChatWheel: wheel => events.setChatWheel(wheel),
|
||||||
Joining: () => events.notify('searching for instance...'),
|
// Joining: () => events.notify('Searching for instance...'),
|
||||||
|
|
||||||
Processing: () => true,
|
Processing: () => true,
|
||||||
Error: errHandler,
|
Error: errHandler,
|
||||||
@ -307,8 +318,11 @@ function createSocket(events) {
|
|||||||
return handlers[msgType](params);
|
return handlers[msgType](params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let attempts = 1;
|
||||||
|
|
||||||
// Connection opened
|
// Connection opened
|
||||||
function onOpen() {
|
function onOpen() {
|
||||||
|
attempts = 0;
|
||||||
toast.info({
|
toast.info({
|
||||||
message: 'connected',
|
message: 'connected',
|
||||||
position: 'topRight',
|
position: 'topRight',
|
||||||
@ -327,12 +341,21 @@ function createSocket(events) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function onClose(event) {
|
function onClose(event) {
|
||||||
|
attempts *= 2;
|
||||||
|
if (attempts > 10) {
|
||||||
|
toast.warning({
|
||||||
|
message: 'unable to connect, refreshing...',
|
||||||
|
position: 'topRight',
|
||||||
|
});
|
||||||
|
setTimeout(() => window.location.reload(true), 2000);
|
||||||
|
}
|
||||||
|
|
||||||
console.error('WebSocket closed', event);
|
console.error('WebSocket closed', event);
|
||||||
toast.warning({
|
toast.warning({
|
||||||
message: 'disconnected',
|
message: 'disconnected',
|
||||||
position: 'topRight',
|
position: 'topRight',
|
||||||
});
|
});
|
||||||
return setTimeout(connect, 5000);
|
return setTimeout(connect, attempts * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function connect() {
|
function connect() {
|
||||||
@ -381,11 +404,13 @@ function createSocket(events) {
|
|||||||
sendInstanceChat,
|
sendInstanceChat,
|
||||||
|
|
||||||
sendVboxAccept,
|
sendVboxAccept,
|
||||||
|
sendVboxAcceptEquip,
|
||||||
sendVboxApply,
|
sendVboxApply,
|
||||||
sendVboxReclaim,
|
sendVboxReclaim,
|
||||||
sendVboxCombine,
|
sendVboxCombine,
|
||||||
sendVboxDiscard,
|
sendVboxDiscard,
|
||||||
sendVboxUnequip,
|
sendVboxUnequip,
|
||||||
|
sendVboxUnequipApply,
|
||||||
|
|
||||||
sendItemInfo,
|
sendItemInfo,
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
const preact = require('preact');
|
const preact = require('preact');
|
||||||
const actions = require('./actions');
|
const actions = require('./actions');
|
||||||
|
|
||||||
function tutorialConstructDisplay(player, instance, tutorial, navInstance, 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 mobileVisible = navInstance === i + 1;
|
const classes = `instance-construct`;
|
||||||
const classes = `instance-construct ${mobileVisible ? 'visible' : ''}`;
|
|
||||||
return (<div key={player.constructs[i].id} class={classes}></div>);
|
return (<div key={player.constructs[i].id} class={classes}></div>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,13 +199,16 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tutorial === 8) {
|
if (tutorial === 8) {
|
||||||
|
if (window.innerWidth < 1000) {
|
||||||
|
return exit();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>Tutorial</h2>
|
<h2>Tutorial</h2>
|
||||||
<p>You've completed the tutorial! Try to create more skill and spec combinations. </p>
|
<p>You've completed the tutorial! Try to create more skill and spec combinations. </p>
|
||||||
<p>You can unequip skills and specs back into the inventory by double clicking. <br />
|
<p>You can unequip skills and specs back into the inventory by double clicking. <br />
|
||||||
Reclaim can be used to refund the cost of items in your inventory. </p>
|
Reclaim can be used to refund the cost of items in your inventory. </p>
|
||||||
<p>Click the <b>EXIT TUTORIAL</b> button to replace this section with more information.</p>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -214,10 +216,11 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const classes = tutorial === 8 ? 'focus' : '';
|
const classes = tutorial === 8 ? 'focus' : '';
|
||||||
|
const text = tutorial === 8 ? 'Continue' : 'Close Tutorial'
|
||||||
const exitTutorial = <button
|
const exitTutorial = <button
|
||||||
class={classes}
|
class={classes}
|
||||||
onClick={e => e.stopPropagation()}
|
onClick={e => e.stopPropagation()}
|
||||||
onMouseDown={exit}> Exit Tutorial </button>;
|
onMouseDown={exit}> {text} </button>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class='tutorial'>
|
<div class='tutorial'>
|
||||||
|
|||||||
@ -264,7 +264,7 @@ function effectInfo(i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (i.effect) {
|
switch (i.effect) {
|
||||||
case 'Amplify': return `Increases construct RedPower and BluePower by ${i.meta[1] - 100}%`;
|
case 'Amplify': return `Increases construct RedPower BluePower GreenPower by ${i.meta[1] - 100}%`;
|
||||||
case 'Banish': return 'Banished construct cannot cast or take damage';
|
case 'Banish': return 'Banished construct cannot cast or take damage';
|
||||||
case 'Block': return `Reduces construct red damage and blue damage taken by ${100 - i.meta[1]}%`;
|
case 'Block': return `Reduces construct red damage and blue damage taken by ${100 - i.meta[1]}%`;
|
||||||
case 'Buff': return `Increases construct RedPower BluePower SpeedStat by ${i.meta[1] - 100}%`;
|
case 'Buff': return `Increases construct RedPower BluePower SpeedStat by ${i.meta[1] - 100}%`;
|
||||||
|
|||||||
@ -15,6 +15,12 @@ map $http_upgrade $connection_upgrade {
|
|||||||
server {
|
server {
|
||||||
server_name mnml.gg;
|
server_name mnml.gg;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /var/lib/mnml/public/current;
|
root /var/lib/mnml/public/current;
|
||||||
index index.html;
|
index index.html;
|
||||||
|
|||||||
@ -15,8 +15,14 @@ map $http_upgrade $connection_upgrade {
|
|||||||
server {
|
server {
|
||||||
server_name sixtysix.pro;
|
server_name sixtysix.pro;
|
||||||
|
|
||||||
auth_basic "who dis";
|
gzip on;
|
||||||
auth_basic_user_file /etc/mnml/htpasswd.users;
|
gzip_vary on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
|
||||||
|
|
||||||
|
# auth_basic "who dis";
|
||||||
|
# auth_basic_user_file /etc/mnml/htpasswd.users;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
root /var/lib/mnml/public/current;
|
root /var/lib/mnml/public/current;
|
||||||
|
|||||||
@ -1,82 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
const renderer = require('sdftosvg');
|
|
||||||
|
|
||||||
const SVG_OPTS = {
|
|
||||||
backgroundColor: 'none',
|
|
||||||
}
|
|
||||||
|
|
||||||
function convert(i) {
|
|
||||||
const output = `./../client/assets/molecules/${i}.svg`;
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
fs.readFile(`./molecules/mol${i}`, 'utf8', function rfCb(err, sdf) {
|
|
||||||
if (err) return reject(err);
|
|
||||||
// write svg
|
|
||||||
renderer.renderSdfToSvg(sdf, SVG_OPTS, function(err, svg) {
|
|
||||||
if (err) return reject(err);
|
|
||||||
fs.writeFile(output, svg, function written(err) {
|
|
||||||
if (err) reject(err);
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function loop() {
|
|
||||||
for (var i = 10000; i >= 0; i--) {
|
|
||||||
try {
|
|
||||||
await convert(i);
|
|
||||||
console.log('finished record', i);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('record error', i, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loop();
|
|
||||||
|
|
||||||
// const request = require('request');
|
|
||||||
// const fs = require('fs');
|
|
||||||
// const renderer = require('sdftosvg');
|
|
||||||
|
|
||||||
// const SVG_OPTS = {
|
|
||||||
// backgroundColor: 'none',
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function fetch(i) {
|
|
||||||
// return new Promise((resolve, reject) => {
|
|
||||||
// const url = `https://pubchem.ncbi.nlm.nih.gov/rest/pug/compound/CID/${i}/record/SDF/?record_type=2d&response_type=save&response_basename=Structure2D_CID_2519`;
|
|
||||||
// const output = `./../client/assets/molecules/${i}.svg`;
|
|
||||||
|
|
||||||
// request(url, function cb(err, res, body) {
|
|
||||||
// if (err) reject(err);
|
|
||||||
|
|
||||||
// // write file
|
|
||||||
// fs.writeFile(`./molecules/Structure2D_CID_${i}.sdf`, body, function written(err) {
|
|
||||||
// if (err) reject(err);
|
|
||||||
// });
|
|
||||||
|
|
||||||
// // write svg
|
|
||||||
// renderer.renderSdfToSvg(body, SVG_OPTS, function(err, svg) {
|
|
||||||
// if (err) reject(err);
|
|
||||||
// fs.writeFile(output, svg, function written(err) {
|
|
||||||
// if (err) reject(err);
|
|
||||||
// resolve();
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async function loop() {
|
|
||||||
// for (var i = 10000; i >= 0; i--) {
|
|
||||||
// try {
|
|
||||||
// await fetch(i);
|
|
||||||
// console.log('finished record', i);
|
|
||||||
// } catch (e) {
|
|
||||||
// console.error(e);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
for (let i = 10000; i >= 0; i--) {
|
|
||||||
fs.access(`./../client/assets/molecules/${i}.svg`, (err) => {
|
|
||||||
if (err) {
|
|
||||||
fs.copyFileSync(`./../client/assets/molecules/726.svg`, `./../client/assets/molecules/${i}.svg`);
|
|
||||||
console.log('defaulted', i);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
10
ops/migrations/20191031203812_remove-molecular.js
Normal file
10
ops/migrations/20191031203812_remove-molecular.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
const uuidv4 = require('uuid/v4');
|
||||||
|
|
||||||
|
// give everybody the shapes mtx
|
||||||
|
exports.up = async knex => {
|
||||||
|
await knex.raw(`
|
||||||
|
DELETE from mtx
|
||||||
|
WHERE variant = 'Molecular';
|
||||||
|
`);
|
||||||
|
};
|
||||||
|
exports.down = async () => {};
|
||||||
@ -1,18 +0,0 @@
|
|||||||
const renderer = require('sdftosvg');
|
|
||||||
const uuidv4 = require('uuid/v4');
|
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
function convert(f) {
|
|
||||||
const uuid = uuidv4();
|
|
||||||
const input = `./molecules/${f}`;
|
|
||||||
const output = `./../client/assets/molecules/${uuid}.svg`;
|
|
||||||
fs.readFile(input, 'utf8', (err, sdf) => {
|
|
||||||
renderer.renderSdfToSvg(sdf, {}, function(err, svg) {
|
|
||||||
if (err) console.error(input, err);
|
|
||||||
fs.writeFile(output, svg, 'utf8', err => {
|
|
||||||
if (err) console.error(err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "mnml-ops",
|
"name": "mnml-ops",
|
||||||
"version": "1.7.1",
|
"version": "1.8.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "mnml"
|
name = "mnml"
|
||||||
version = "1.7.1"
|
version = "1.8.0"
|
||||||
authors = ["ntr <ntr@smokestack.io>"]
|
authors = ["ntr <ntr@smokestack.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|||||||
@ -67,13 +67,13 @@ pub fn select(db: &Db, id: Uuid) -> Result<Account, Error> {
|
|||||||
|
|
||||||
pub fn chat_wheel(_db: &Db, _id: Uuid) -> Result<Vec<String>, Error> {
|
pub fn chat_wheel(_db: &Db, _id: Uuid) -> Result<Vec<String>, Error> {
|
||||||
return Ok(vec![
|
return Ok(vec![
|
||||||
"gl".to_string(),
|
|
||||||
"hf".to_string(),
|
|
||||||
"gg".to_string(),
|
"gg".to_string(),
|
||||||
"thx".to_string(),
|
"glhf".to_string(),
|
||||||
"nice".to_string(),
|
|
||||||
"hmm".to_string(),
|
"hmm".to_string(),
|
||||||
"ok".to_string(),
|
"ok".to_string(),
|
||||||
|
"rekt".to_string(),
|
||||||
|
"thx".to_string(),
|
||||||
|
"nice".to_string(),
|
||||||
"...".to_string(),
|
"...".to_string(),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -220,11 +220,11 @@ impl Construct {
|
|||||||
account: id,
|
account: id,
|
||||||
img: Uuid::new_v4(),
|
img: Uuid::new_v4(),
|
||||||
red_power: ConstructStat { base: 320, value: 320, max: 320, stat: Stat::RedPower },
|
red_power: ConstructStat { base: 320, value: 320, max: 320, stat: Stat::RedPower },
|
||||||
red_life: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::RedLife },
|
red_life: ConstructStat { base: 125, value: 125, max: 125, stat: Stat::RedLife },
|
||||||
blue_power: ConstructStat { base: 320, value: 320, max: 320, stat: Stat::BluePower },
|
blue_power: ConstructStat { base: 320, value: 320, max: 320, stat: Stat::BluePower },
|
||||||
blue_life: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::BlueLife },
|
blue_life: ConstructStat { base: 125, value: 125, max: 125, stat: Stat::BlueLife },
|
||||||
green_power: ConstructStat { base: 300, value: 300, max: 300, stat: Stat::GreenPower },
|
green_power: ConstructStat { base: 300, value: 300, max: 300, stat: Stat::GreenPower },
|
||||||
green_life: ConstructStat { base: 950, value: 950, max: 950, stat: Stat::GreenLife },
|
green_life: ConstructStat { base: 800, value: 800, max: 800, stat: Stat::GreenLife },
|
||||||
speed: ConstructStat { base: 100, value: 100, max: 100, stat: Stat::Speed },
|
speed: ConstructStat { base: 100, value: 100, max: 100, stat: Stat::Speed },
|
||||||
// evasion: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::Evasion },
|
// evasion: ConstructStat { base: 0, value: 0, max: 0, stat: Stat::Evasion },
|
||||||
skills: vec![],
|
skills: vec![],
|
||||||
|
|||||||
@ -105,7 +105,7 @@ impl Effect {
|
|||||||
|
|
||||||
Effect::Absorption => vec![Stat::RedPower, Stat::BluePower],
|
Effect::Absorption => vec![Stat::RedPower, Stat::BluePower],
|
||||||
|
|
||||||
Effect::Amplify => vec![Stat::RedPower, Stat::BluePower],
|
Effect::Amplify => vec![Stat::GreenPower, Stat::RedPower, Stat::BluePower],
|
||||||
Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken],
|
Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken],
|
||||||
|
|
||||||
Effect::Hybrid => vec![Stat::GreenPower],
|
Effect::Hybrid => vec![Stat::GreenPower],
|
||||||
|
|||||||
@ -1229,7 +1229,7 @@ mod tests {
|
|||||||
assert!(game.player_by_id(x_player.id).unwrap().constructs[0].is_stunned() == false);
|
assert!(game.player_by_id(x_player.id).unwrap().constructs[0].is_stunned() == false);
|
||||||
// riposte
|
// riposte
|
||||||
assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), (
|
assert_eq!(game.player_by_id(y_player.id).unwrap().constructs[0].green_life(), (
|
||||||
y_construct.green_life() - x_construct.red_power().pct(Skill::CounterAttack.multiplier())));
|
y_construct.green_life() + y_construct.red_life() - x_construct.red_power().pct(Skill::CounterAttack.multiplier())));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use std::f64;
|
use std::f64;
|
||||||
use std::fs::copy;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::prelude::*;
|
use std::io::prelude::*;
|
||||||
use std::char::from_u32;
|
use std::char::from_u32;
|
||||||
@ -9,25 +8,7 @@ use rand::prelude::*;
|
|||||||
use rand::distributions::{Normal, WeightedIndex};
|
use rand::distributions::{Normal, WeightedIndex};
|
||||||
|
|
||||||
use failure::Error;
|
use failure::Error;
|
||||||
use failure::err_msg;
|
// use failure::err_msg;
|
||||||
|
|
||||||
pub fn molecular_write(id: Uuid) -> Result<Uuid, Error> {
|
|
||||||
let mut rng = thread_rng();
|
|
||||||
|
|
||||||
for _i in 0..100 {
|
|
||||||
let mol: u32 = rng.gen_range(0, 10000);
|
|
||||||
let src = format!("/var/lib/mnml/data/molecules/{}.svg", mol);
|
|
||||||
let dest = format!("/var/lib/mnml/public/imgs/{}.svg", id);
|
|
||||||
debug!("molecule src={:?}", src);
|
|
||||||
debug!("molecule dest={:?}", dest);
|
|
||||||
if let Ok(_bytes) = copy(&src, &dest) {
|
|
||||||
info!("new molecule img generated src={:?} dest={:?}", src, dest);
|
|
||||||
return Ok(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Err(err_msg("too many missing molecules. wrong directory?"))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn invader_write(id: Uuid) -> Result<Uuid, Error> {
|
pub fn invader_write(id: Uuid) -> Result<Uuid, Error> {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
@ -257,6 +238,118 @@ fn _hieroglyph() -> String {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn smile(id: Uuid) -> Result<Uuid, Error> {
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
let mut svg = Vec::new();
|
||||||
|
|
||||||
|
// distribution for lightness
|
||||||
|
// bellcurve around 75%
|
||||||
|
let l_dist = Normal::new(50.0, 10.0);
|
||||||
|
let s_dist = Normal::new(50.0, 20.0);
|
||||||
|
|
||||||
|
// let stroke_width = rng.gen_range(1, 3);
|
||||||
|
let stroke_width = 3;
|
||||||
|
|
||||||
|
let h = rng.gen_range(0, 360);
|
||||||
|
let s = s_dist.sample(&mut rng) as usize;
|
||||||
|
let l = l_dist.sample(&mut rng) as usize;
|
||||||
|
let eye_colour = format!("hsl({:}, {:}%, {:}%)", h, s, l);
|
||||||
|
|
||||||
|
let h = rng.gen_range(0, 360);
|
||||||
|
let s = s_dist.sample(&mut rng) as usize;
|
||||||
|
let l = l_dist.sample(&mut rng) as usize;
|
||||||
|
let mouth_colour = format!("hsl({:}, {:}%, {:}%)", h, s, l);
|
||||||
|
|
||||||
|
// basic layout is 200x200 box w/ 100 padding
|
||||||
|
// 2:1 for each x,y
|
||||||
|
|
||||||
|
// left eye is at 0,0
|
||||||
|
// 50W 25H
|
||||||
|
let eyes_left = [
|
||||||
|
("M0,0 L25,25 L50,0", 1), // v
|
||||||
|
("M0,25 L25,0 L50,25", 1), // ^
|
||||||
|
("M0,0 L50,0", 1), // -
|
||||||
|
("M0,25 L50,25", 1), // _
|
||||||
|
("M0,0 L50,25 M50,0 L0,25", 1), // x
|
||||||
|
("M0,0 L50,12.5 L0,25", 1), // >
|
||||||
|
("M50,0 L0,12.5 L50,25", 1), // <
|
||||||
|
("M0,0 L0,25 L50,25", 1), // L
|
||||||
|
("M50,0 L50,25 L0,25", 1), // J
|
||||||
|
("M0,0 L50,0 M50,6.25 L50,12.5 M50,18.75 L50,25", 1), // ;
|
||||||
|
("M12.5,0 L37.5,0 L37.5,25 L12.5,25 L12.5,0", 1), // o
|
||||||
|
];
|
||||||
|
let eye_left_dist = WeightedIndex::new(eyes_left.iter().map(|v| v.1))?;
|
||||||
|
|
||||||
|
// right eye is 150,0
|
||||||
|
// 50W 25H
|
||||||
|
let eyes_right = [
|
||||||
|
("M150,0 L175,25 L200,0", 1), // v
|
||||||
|
("M150,25 L175,0 L200,25", 1), // ^
|
||||||
|
("M150,0 L200,0", 1), // -
|
||||||
|
("M150,25 L200,25", 1), // _
|
||||||
|
("M150,0 L200,25 M200,0 L150,25", 1), // x
|
||||||
|
("M150,0 L200,12.5 L150,25", 1), // >
|
||||||
|
("M200,0 L150,12.5 L200,25", 1), // <
|
||||||
|
("M150,0 L150,25 L200,25", 1), // L
|
||||||
|
("M200,0 L200,25 L150,25", 1), // J
|
||||||
|
("M150,0 L200,0 M150,6.25 L150,12.5 M150,18.75 L150,25", 1), // ;
|
||||||
|
("M162.5,0 L187.5,0 L187.5,25 L162.5,25 L162.5,0", 1), // o
|
||||||
|
];
|
||||||
|
let eye_right_dist= WeightedIndex::new(eyes_right.iter().map(|v| v.1))?;
|
||||||
|
|
||||||
|
// mouth is 50,75
|
||||||
|
// 100W 25H
|
||||||
|
let mouths = [
|
||||||
|
("M50,100 L150,100", 1), // _
|
||||||
|
("M50,75 L150,75 L125,100 L75,100 L50,75", 1), // D
|
||||||
|
("M50,75 L75,100 L100,75 L125,100 L150,75", 1), // w
|
||||||
|
("M50,75 L75,75 L75,87.5 M75,75 L125,75 L125,87.5 M125,75 L150,75", 1), // vamp
|
||||||
|
("M50,75 L150,75 M50,75 L50,87.5 M75,75 L75,87.5 M100,75 L100,87.5 M125,75 L125,87.5 M150,75 L150,87.5", 1), // mm
|
||||||
|
("M75,75 L125,75 L125,100 L75,100 L75,75", 1), // o
|
||||||
|
("M50,75 L150,100 M150,75 L50,100", 1), // x
|
||||||
|
("M50,75 L150,75 L150,100 L125,100 L125,75", 1), // p
|
||||||
|
("M50,75 L150,75 M50,75 L50,100 L75,100 L75,75", 1), // d
|
||||||
|
// ("M50,75 L50,100 L150,100 L150,75", 1), // u
|
||||||
|
("M50,100 L50,75 L150,75 L150,100", 1), // n
|
||||||
|
("M50,75 L50,100 L150,75 L150,100", 1), // Z
|
||||||
|
("M50,87.5 L100,75 L150,87.5 L100,100 L50,87.5", 1), // Z
|
||||||
|
];
|
||||||
|
let mouth_dist = WeightedIndex::new(mouths.iter().map(|v| v.1))?;
|
||||||
|
|
||||||
|
write!(&mut svg, "<svg xmlns='http://www.w3.org/2000/svg' version='1.1' viewBox='-50 -100 300 300' width='200' height='200'><g>")?;
|
||||||
|
|
||||||
|
let left_eye_path = eyes_left[eye_left_dist.sample(&mut rng)].0;
|
||||||
|
|
||||||
|
// left eye
|
||||||
|
write!(&mut svg,
|
||||||
|
"<path fill=\"none\" stroke=\"{:}\" stroke-width=\"{:}px\" d=\"{:}\" />",
|
||||||
|
eye_colour, stroke_width, left_eye_path)?;
|
||||||
|
|
||||||
|
let right_eye_path = eyes_right[eye_right_dist.sample(&mut rng)].0;
|
||||||
|
// right eye
|
||||||
|
write!(&mut svg,
|
||||||
|
"<path fill=\"none\" stroke=\"{:}\" stroke-width=\"{:}px\" d=\"{:}\" />",
|
||||||
|
eye_colour, stroke_width, right_eye_path)?;
|
||||||
|
|
||||||
|
let mouth_path = mouths[mouth_dist.sample(&mut rng)].0;
|
||||||
|
// mouth
|
||||||
|
write!(&mut svg,
|
||||||
|
"<path fill=\"none\" stroke=\"{:}\" stroke-width=\"{:}px\" d=\"{:}\" />",
|
||||||
|
mouth_colour, stroke_width, mouth_path)?;
|
||||||
|
|
||||||
|
write!(&mut svg, "</g></svg>")?;
|
||||||
|
|
||||||
|
// let dest = format!("/var/lib/mnml/face.svg");
|
||||||
|
let dest = format!("/var/lib/mnml/public/imgs/{}.svg", id);
|
||||||
|
|
||||||
|
let mut file = File::create(dest)?;
|
||||||
|
file.write_all(&svg)?;
|
||||||
|
|
||||||
|
Ok(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn exists(id: Uuid) -> bool {
|
pub fn exists(id: Uuid) -> bool {
|
||||||
std::path::Path::new(&format!("/var/lib/mnml/public/imgs/{}.svg", id)).exists()
|
std::path::Path::new(&format!("/var/lib/mnml/public/imgs/{}.svg", id)).exists()
|
||||||
}
|
}
|
||||||
@ -264,7 +357,6 @@ pub fn exists(id: Uuid) -> bool {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn invader_img_test() {
|
// fn invader_img_test() {
|
||||||
// for i in 0..100 {
|
// for i in 0..100 {
|
||||||
@ -283,107 +375,9 @@ mod tests {
|
|||||||
// shapes_write(Uuid::new_v4()).unwrap();
|
// shapes_write(Uuid::new_v4()).unwrap();
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn smile_test() {
|
||||||
|
smile(Uuid::new_v4()).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// function createColor() {
|
|
||||||
// //saturation is the whole color spectrum
|
|
||||||
// var h = Math.floor(rand() * 360);
|
|
||||||
// //saturation goes from 40 to 100, it avoids greyish colors
|
|
||||||
// var s = ((rand() * 60) + 40) + '%';
|
|
||||||
// //lightness can be anything from 0 to 100, but probabilities are a bell curve around 75%
|
|
||||||
// var l = ((rand()+rand()+rand()+rand()) * 25) + '%';
|
|
||||||
|
|
||||||
// var color = 'hsl(' + h + ',' + s + ',' + l + ')';
|
|
||||||
// return color;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function createImageData(size) {
|
|
||||||
// var width = size; // Only support square icons for now
|
|
||||||
// var height = size;
|
|
||||||
|
|
||||||
// var dataWidth = Math.ceil(width / 2);
|
|
||||||
// var mirrorWidth = width - dataWidth;
|
|
||||||
|
|
||||||
// var data = [];
|
|
||||||
// for(var y = 0; y < height; y++) {
|
|
||||||
// var row = [];
|
|
||||||
// for(var x = 0; x < dataWidth; x++) {
|
|
||||||
// // this makes foreground and background color to have a 43% (1/2.3) probability
|
|
||||||
// // spot color has 13% chance
|
|
||||||
// row[x] = Math.floor(rand()*2.3);
|
|
||||||
// }
|
|
||||||
// var r = row.slice(0, mirrorWidth);
|
|
||||||
// r.reverse();
|
|
||||||
// row = row.concat(r);
|
|
||||||
|
|
||||||
// for(var i = 0; i < row.length; i++) {
|
|
||||||
// data.push(row[i]);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return data;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// function buildOpts(opts) {
|
|
||||||
// var newOpts = {};
|
|
||||||
|
|
||||||
// newOpts.seed = opts.seed || Math.floor((Math.random()*Math.pow(10,16))).toString(16);
|
|
||||||
|
|
||||||
// seedrand(newOpts.seed);
|
|
||||||
|
|
||||||
// newOpts.size = opts.size || 8;
|
|
||||||
// newOpts.scale = opts.scale || 4;
|
|
||||||
// newOpts.color = opts.color || createColor();
|
|
||||||
// newOpts.bgcolor = opts.bgcolor || createColor();
|
|
||||||
// newOpts.spotcolor = opts.spotcolor || createColor();
|
|
||||||
|
|
||||||
// return newOpts;
|
|
||||||
// }
|
|
||||||
// ],
|
|
||||||
// - _ => vec![
|
|
||||||
// - (ItemAction::RerollStamina, 1),
|
|
||||||
// - (ItemAction::RerollPhysDamage, 1),
|
|
||||||
// - (ItemAction::RerollSpellDamage, 1),
|
|
||||||
// - (ItemAction::RerollSpeed, 1),
|
|
||||||
// - (ItemAction::RerollArmour, 1),
|
|
||||||
// - (ItemAction::RerollSpellShield, 1),
|
|
||||||
// - (ItemAction::RerollEvasion, 1),
|
|
||||||
// - ],
|
|
||||||
// + // _ => vec![
|
|
||||||
// + // (ItemAction::RerollStamina, 1),
|
|
||||||
// + // (ItemAction::RerollPhysDamage, 1),
|
|
||||||
// + // (ItemAction::RerollSpellDamage, 1),
|
|
||||||
// + // (ItemAction::RerollSpeed, 1),
|
|
||||||
// + // (ItemAction::RerollArmour, 1),
|
|
||||||
// + // (ItemAction::RerollSpellShield, 1),
|
|
||||||
// + // (ItemAction::RerollEvasion, 1),
|
|
||||||
// + // ],
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// -pub fn item_drop(tx: &mut Transaction, account_id: Uuid, mode: GameMode) -> Result<Item, Error> {
|
|
||||||
// +pub fn item_drop(tx: &mut Transaction, account_id: Uuid, mode: GameMode) -> Result<(), Error> {
|
|
||||||
// let mut rng = thread_rng();
|
|
||||||
|
|
||||||
// - let actions = mode_drops(mode);
|
|
||||||
// + let log_normal = LogNormal::new(1.0, 1.0);
|
|
||||||
// + let num_drops = log_normal.sample(&mut rng).floor() as usize;
|
|
||||||
// +
|
|
||||||
// + println!("{:?} drops", num_drops);
|
|
||||||
|
|
||||||
// - let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap();
|
|
||||||
// - let kind = actions[dist.sample(&mut rng)].0;
|
|
||||||
// - let item = Item::new(kind, account_id);
|
|
||||||
// + for _i in 0..num_drops {
|
|
||||||
// + let actions = mode_drops(mode);
|
|
||||||
|
|
||||||
// - println!("{:?} dropped {:?}", account_id, item);
|
|
||||||
// + let dist = WeightedIndex::new(actions.iter().map(|item| item.1)).unwrap();
|
|
||||||
// + let kind = actions[dist.sample(&mut rng)].0;
|
|
||||||
// + let item = Item::new(kind, account_id);
|
|
||||||
|
|
||||||
// - return item_create(item, tx, account_id);
|
|
||||||
// + println!("{:?} dropped {:?}", account_id, item);
|
|
||||||
// + item_create(item, tx, account_id)?;V
|
|
||||||
@ -473,10 +473,10 @@ impl Instance {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_accept(mut self, account: Uuid, group: usize, index: usize) -> Result<Instance, Error> {
|
pub fn vbox_accept(mut self, account: Uuid, group: usize, index: usize, construct_id: Option<Uuid>) -> Result<Instance, Error> {
|
||||||
self.vbox_action_allowed(account)?;
|
self.vbox_action_allowed(account)?;
|
||||||
self.account_player(account)?
|
self.account_player(account)?
|
||||||
.vbox_accept(group, index)?;
|
.vbox_accept(group, index, construct_id)?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,10 +501,10 @@ impl Instance {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_unequip(mut self, account: Uuid, target: Item, construct_id: Uuid) -> Result<Instance, Error> {
|
pub fn vbox_unequip(mut self, account: Uuid, target: Item, construct_id: Uuid, target_construct_id: Option<Uuid>) -> Result<Instance, Error> {
|
||||||
self.vbox_action_allowed(account)?;
|
self.vbox_action_allowed(account)?;
|
||||||
self.account_player(account)?
|
self.account_player(account)?
|
||||||
.vbox_unequip(target, construct_id)?;
|
.vbox_unequip(target, construct_id, target_construct_id)?;
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -712,14 +712,14 @@ impl Item {
|
|||||||
// Skills <- need to move effect mulltipliers into skills
|
// Skills <- need to move effect mulltipliers into skills
|
||||||
Item::Amplify|
|
Item::Amplify|
|
||||||
Item::AmplifyPlus |
|
Item::AmplifyPlus |
|
||||||
Item::AmplifyPlusPlus => format!("Increase RedPower and BluePower by {:?}%. Lasts {:?}T.",
|
Item::AmplifyPlusPlus => format!("Increase RedPower BluePower GreenPower by {:?}%. Lasts {:?}T.",
|
||||||
self.into_skill().unwrap().effect()[0].get_multiplier() - 100,
|
self.into_skill().unwrap().effect()[0].get_multiplier() - 100,
|
||||||
self.into_skill().unwrap().effect()[0].get_duration()),
|
self.into_skill().unwrap().effect()[0].get_duration()),
|
||||||
|
|
||||||
Item::Banish|
|
Item::Banish|
|
||||||
Item::BanishPlus |
|
Item::BanishPlus |
|
||||||
Item::BanishPlusPlus => format!("Banish target for {:?}T.
|
Item::BanishPlusPlus => format!("Banish target for {:?}T.
|
||||||
Deal blue damage and red damage equal to {:?}% target red and blue life.
|
Deal {:?}% target RedLife and BlueLife as red and blue damage respectively.
|
||||||
Banished constructs are immune to all skills and effects.",
|
Banished constructs are immune to all skills and effects.",
|
||||||
self.into_skill().unwrap().effect()[0].get_duration(),
|
self.into_skill().unwrap().effect()[0].get_duration(),
|
||||||
self.into_skill().unwrap().multiplier()),
|
self.into_skill().unwrap().multiplier()),
|
||||||
@ -773,11 +773,12 @@ impl Item {
|
|||||||
Item::Absorb|
|
Item::Absorb|
|
||||||
Item::AbsorbPlus |
|
Item::AbsorbPlus |
|
||||||
Item::AbsorbPlusPlus => format!(
|
Item::AbsorbPlusPlus => format!(
|
||||||
"Gain Absorb for {:?}T. When attacked with Absorb you gain Absorption.
|
"Gain Absorb for {:?}T. Taking damage replaces Absorb with Absorption.
|
||||||
Absorption increases RedPower and BluePower based on Damage taken.
|
Absorption increases RedPower and BluePower based on damage taken.
|
||||||
Absorption lasts {:?}T.",
|
Absorption lasts {:?}T. Recharges BlueLife based on {:?}% BluePower.",
|
||||||
self.into_skill().unwrap().effect()[0].get_duration(),
|
self.into_skill().unwrap().effect()[0].get_duration(),
|
||||||
self.into_skill().unwrap().effect()[0].get_skill().unwrap().effect()[0].get_duration()),
|
self.into_skill().unwrap().effect()[0].get_skill().unwrap().effect()[0].get_duration(),
|
||||||
|
self.into_skill().unwrap().multiplier()),
|
||||||
|
|
||||||
Item::Haste|
|
Item::Haste|
|
||||||
Item::HastePlus |
|
Item::HastePlus |
|
||||||
@ -943,6 +944,11 @@ impl Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!!!!!
|
||||||
|
// IF YOU CHANGE A COMBO
|
||||||
|
// BE SURE TO EDIT BUTTONS.JSX TOO
|
||||||
|
// !!!!!!
|
||||||
|
|
||||||
fn combo(&self) -> Vec<Item> {
|
fn combo(&self) -> Vec<Item> {
|
||||||
match self {
|
match self {
|
||||||
Item::Intercept => vec![Item::Buff, Item::Red, Item::Red],
|
Item::Intercept => vec![Item::Buff, Item::Red, Item::Red],
|
||||||
|
|||||||
@ -20,8 +20,8 @@ pub const FREE_MTX: [MtxVariant; 2] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
pub const SHOP_LISTINGS: [Listing; 2] = [
|
pub const SHOP_LISTINGS: [Listing; 2] = [
|
||||||
Listing { variant: MtxVariant::Molecular, credits: 10 },
|
|
||||||
Listing { variant: MtxVariant::Invader, credits: 10 },
|
Listing { variant: MtxVariant::Invader, credits: 10 },
|
||||||
|
Listing { variant: MtxVariant::Smile, credits: 10 },
|
||||||
];
|
];
|
||||||
|
|
||||||
const NEW_IMAGE_COST: i64 = 1;
|
const NEW_IMAGE_COST: i64 = 1;
|
||||||
@ -43,9 +43,9 @@ pub struct Listing {
|
|||||||
#[derive(Debug,Copy,Clone,PartialEq,Serialize,Deserialize)]
|
#[derive(Debug,Copy,Clone,PartialEq,Serialize,Deserialize)]
|
||||||
pub enum MtxVariant {
|
pub enum MtxVariant {
|
||||||
Rename,
|
Rename,
|
||||||
Molecular,
|
|
||||||
Invader,
|
Invader,
|
||||||
Shapes,
|
Shapes,
|
||||||
|
Smile,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MtxVariant {
|
impl MtxVariant {
|
||||||
@ -61,8 +61,8 @@ impl TryFrom<String> for MtxVariant {
|
|||||||
fn try_from(v: String) -> Result<MtxVariant, Error> {
|
fn try_from(v: String) -> Result<MtxVariant, Error> {
|
||||||
match v.as_ref() {
|
match v.as_ref() {
|
||||||
"Rename" => Ok(MtxVariant::Rename),
|
"Rename" => Ok(MtxVariant::Rename),
|
||||||
"Molecular" => Ok(MtxVariant::Molecular),
|
|
||||||
"Invader" => Ok(MtxVariant::Invader),
|
"Invader" => Ok(MtxVariant::Invader),
|
||||||
|
"Smile" => Ok(MtxVariant::Smile),
|
||||||
"Shapes" => Ok(MtxVariant::Shapes),
|
"Shapes" => Ok(MtxVariant::Shapes),
|
||||||
_ => Err(format_err!("mtx variant not found variant={:?}", v)),
|
_ => Err(format_err!("mtx variant not found variant={:?}", v)),
|
||||||
}
|
}
|
||||||
@ -81,7 +81,6 @@ impl Mtx {
|
|||||||
match variant {
|
match variant {
|
||||||
_ => Mtx { id: Uuid::new_v4(), account, variant },
|
_ => Mtx { id: Uuid::new_v4(), account, variant },
|
||||||
// MtxVariant::Invader => Mtx { id: Uuid::new_v4(), account, variant: self },
|
// MtxVariant::Invader => Mtx { id: Uuid::new_v4(), account, variant: self },
|
||||||
// MtxVariant::Molecular => Mtx { id: Uuid::new_v4(), account, variant: self },
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +157,8 @@ pub fn apply(tx: &mut Transaction, account: &Account, variant: MtxVariant, const
|
|||||||
|
|
||||||
match mtx.variant {
|
match mtx.variant {
|
||||||
MtxVariant::Invader => img::invader_write(construct.img)?,
|
MtxVariant::Invader => img::invader_write(construct.img)?,
|
||||||
MtxVariant::Molecular => img::molecular_write(construct.img)?,
|
|
||||||
MtxVariant::Shapes => img::shapes_write(construct.img)?,
|
MtxVariant::Shapes => img::shapes_write(construct.img)?,
|
||||||
|
MtxVariant::Smile => img::smile(construct.img)?,
|
||||||
_ => construct.img,
|
_ => construct.img,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -179,8 +178,8 @@ pub fn account_apply(tx: &mut Transaction, account: &Account, variant: MtxVarian
|
|||||||
|
|
||||||
match mtx.variant {
|
match mtx.variant {
|
||||||
MtxVariant::Invader => img::invader_write(account.img)?,
|
MtxVariant::Invader => img::invader_write(account.img)?,
|
||||||
MtxVariant::Molecular => img::molecular_write(account.img)?,
|
|
||||||
MtxVariant::Shapes => img::shapes_write(account.img)?,
|
MtxVariant::Shapes => img::shapes_write(account.img)?,
|
||||||
|
MtxVariant::Smile => img::smile(account.img)?,
|
||||||
_ => account.img,
|
_ => account.img,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -256,8 +256,12 @@ impl Player {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_accept(&mut self, group: usize, index: usize) -> Result<&mut Player, Error> {
|
pub fn vbox_accept(&mut self, group: usize, index: usize, construct_id: Option<Uuid>) -> Result<&mut Player, Error> {
|
||||||
self.vbox.accept(group, index)?;
|
self.vbox.accept(group, index, construct_id)?;
|
||||||
|
if construct_id.is_some() {
|
||||||
|
let equip_index = self.vbox.bound.len() - 1;
|
||||||
|
self.vbox_apply(equip_index, construct_id.expect("no construct"))?;
|
||||||
|
}
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,8 +324,8 @@ impl Player {
|
|||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_unequip(&mut self, target: Item, construct_id: Uuid) -> Result<&mut Player, Error> {
|
pub fn vbox_unequip(&mut self, target: Item, construct_id: Uuid, target_construct_id: Option<Uuid>) -> Result<&mut Player, Error> {
|
||||||
if self.vbox.bound.len() >= 9 {
|
if self.vbox.bound.len() >= 9 && !target_construct_id.is_some() {
|
||||||
return Err(err_msg("too many items bound"));
|
return Err(err_msg("too many items bound"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -354,7 +358,12 @@ impl Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.vbox.bound.push(target);
|
self.vbox.bound.push(target);
|
||||||
self.vbox.bound.sort_unstable();
|
|
||||||
|
if target_construct_id.is_some() {
|
||||||
|
let equip_index = self.vbox.bound.len() - 1;
|
||||||
|
self.vbox_apply(equip_index, target_construct_id.expect("no construct"))?;
|
||||||
|
}
|
||||||
|
// self.vbox.bound.sort_unstable();
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
use std::time::{Instant};
|
use std::time::{Instant};
|
||||||
use std::thread::{spawn, sleep};
|
use std::thread::{spawn};
|
||||||
use std::time;
|
|
||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
|
|
||||||
@ -65,6 +64,7 @@ pub enum RpcMessage {
|
|||||||
QueueRequested(()),
|
QueueRequested(()),
|
||||||
QueueJoined(()),
|
QueueJoined(()),
|
||||||
QueueCancelled(()),
|
QueueCancelled(()),
|
||||||
|
QueueFound(()),
|
||||||
|
|
||||||
InviteRequested(()),
|
InviteRequested(()),
|
||||||
Invite(String),
|
Invite(String),
|
||||||
@ -112,10 +112,12 @@ pub enum RpcRequest {
|
|||||||
InstanceChat { instance_id: Uuid, index: usize },
|
InstanceChat { instance_id: Uuid, index: usize },
|
||||||
|
|
||||||
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 },
|
||||||
VboxDiscard { instance_id: Uuid },
|
VboxDiscard { instance_id: Uuid },
|
||||||
VboxCombine { instance_id: Uuid, indices: Vec<usize> },
|
VboxCombine { instance_id: Uuid, indices: 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 },
|
||||||
VboxReclaim { instance_id: Uuid, index: usize },
|
VboxReclaim { instance_id: Uuid, index: usize },
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +236,10 @@ impl Connection {
|
|||||||
Ok(instance_abandon(&mut tx, account, instance_id)?),
|
Ok(instance_abandon(&mut tx, account, instance_id)?),
|
||||||
|
|
||||||
RpcRequest::VboxAccept { instance_id, group, index } =>
|
RpcRequest::VboxAccept { instance_id, group, index } =>
|
||||||
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index)?)),
|
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index, None)?)),
|
||||||
|
|
||||||
|
RpcRequest::VboxAcceptEquip { instance_id, group, index, construct_id } =>
|
||||||
|
Ok(RpcMessage::InstanceState(vbox_accept(&mut tx, account, instance_id, group, index, Some(construct_id))?)),
|
||||||
|
|
||||||
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)?)),
|
||||||
@ -249,7 +254,10 @@ impl Connection {
|
|||||||
Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
|
Ok(RpcMessage::InstanceState(vbox_reclaim(&mut tx, account, instance_id, index)?)),
|
||||||
|
|
||||||
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
|
RpcRequest::VboxUnequip { instance_id, construct_id, target } =>
|
||||||
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target)?)),
|
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target, None)?)),
|
||||||
|
|
||||||
|
RpcRequest::VboxUnequipApply { instance_id, construct_id, target, target_construct_id } =>
|
||||||
|
Ok(RpcMessage::InstanceState(vbox_unequip(&mut tx, account, instance_id, construct_id, target, Some(target_construct_id))?)),
|
||||||
|
|
||||||
RpcRequest::MtxConstructSpawn {} =>
|
RpcRequest::MtxConstructSpawn {} =>
|
||||||
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
|
Ok(RpcMessage::ConstructSpawn(mtx::new_construct(&mut tx, account)?)),
|
||||||
|
|||||||
@ -89,10 +89,15 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut
|
|||||||
|
|
||||||
if source.affected(Effect::Haste) {
|
if source.affected(Effect::Haste) {
|
||||||
match skill {
|
match skill {
|
||||||
Skill::Attack |
|
Skill::Slay |
|
||||||
Skill::Slay|
|
Skill::SlayPlus |
|
||||||
Skill::Chaos|
|
Skill::SlayPlusPlus |
|
||||||
Skill::Strike=> {
|
Skill::Chaos |
|
||||||
|
Skill::ChaosPlus |
|
||||||
|
Skill::ChaosPlusPlus |
|
||||||
|
Skill::Strike |
|
||||||
|
Skill::StrikePlus |
|
||||||
|
Skill::StrikePlusPlus => {
|
||||||
let amount = source.speed().pct(Skill::HasteStrike.multiplier());
|
let amount = source.speed().pct(Skill::HasteStrike.multiplier());
|
||||||
target.deal_red_damage(Skill::HasteStrike, amount)
|
target.deal_red_damage(Skill::HasteStrike, amount)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -105,8 +110,14 @@ pub fn resolve(skill: Skill, source: &mut Construct, target: &mut Construct, mut
|
|||||||
if source.affected(Effect::Hybrid) {
|
if source.affected(Effect::Hybrid) {
|
||||||
match skill {
|
match skill {
|
||||||
Skill::Blast|
|
Skill::Blast|
|
||||||
Skill::Chaos|
|
Skill::BlastPlus |
|
||||||
Skill::Siphon=> {
|
Skill::BlastPlusPlus |
|
||||||
|
Skill::Chaos |
|
||||||
|
Skill::ChaosPlus |
|
||||||
|
Skill::ChaosPlusPlus |
|
||||||
|
Skill::Siphon |
|
||||||
|
Skill::SiphonPlus |
|
||||||
|
Skill::SiphonPlusPlus => {
|
||||||
let amount = source.green_power().pct(Skill::HybridBlast.multiplier());
|
let amount = source.green_power().pct(Skill::HybridBlast.multiplier());
|
||||||
target.deal_blue_damage(Skill::HybridBlast, amount)
|
target.deal_blue_damage(Skill::HybridBlast, amount)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -293,7 +304,7 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
|
|||||||
let mut target = game.construct_by_id(target.id).unwrap().clone();
|
let mut target = game.construct_by_id(target.id).unwrap().clone();
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::Damage { amount, skill, mitigation: _, colour: c } => {
|
Event::Damage { amount, skill, mitigation, colour: c } => {
|
||||||
if target.affected(Effect::Electric) && !skill.is_tick() {
|
if target.affected(Effect::Electric) && !skill.is_tick() {
|
||||||
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
|
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
|
||||||
.find(|e| e.effect == Effect::Electric).unwrap().clone();
|
.find(|e| e.effect == Effect::Electric).unwrap().clone();
|
||||||
@ -320,7 +331,7 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
|
|||||||
.find(|e| e.effect == Effect::Absorb).unwrap().clone();
|
.find(|e| e.effect == Effect::Absorb).unwrap().clone();
|
||||||
match meta {
|
match meta {
|
||||||
Some(EffectMeta::Skill(s)) => {
|
Some(EffectMeta::Skill(s)) => {
|
||||||
resolutions = absorption(&mut source, &mut target, resolutions, skill, amount, s);
|
resolutions = absorption(&mut source, &mut target, resolutions, skill, amount + mitigation, s);
|
||||||
},
|
},
|
||||||
_ => panic!("no absorb skill"),
|
_ => panic!("no absorb skill"),
|
||||||
};
|
};
|
||||||
@ -834,6 +845,10 @@ impl Skill {
|
|||||||
|
|
||||||
Skill::HasteStrike => 60,
|
Skill::HasteStrike => 60,
|
||||||
|
|
||||||
|
Skill::Absorb=> 95,
|
||||||
|
Skill::AbsorbPlus => 120,
|
||||||
|
Skill::AbsorbPlusPlus => 155,
|
||||||
|
|
||||||
Skill::Intercept=> 80,
|
Skill::Intercept=> 80,
|
||||||
Skill::InterceptPlus => 110,
|
Skill::InterceptPlus => 110,
|
||||||
Skill::InterceptPlusPlus => 150,
|
Skill::InterceptPlusPlus => 150,
|
||||||
@ -911,11 +926,11 @@ impl Skill {
|
|||||||
Skill::HastePlusPlus => vec![ConstructEffect {effect: Effect::Haste, duration: 5,
|
Skill::HastePlusPlus => vec![ConstructEffect {effect: Effect::Haste, duration: 5,
|
||||||
meta: Some(EffectMeta::Multiplier(225)), tick: None }],
|
meta: Some(EffectMeta::Multiplier(225)), tick: None }],
|
||||||
|
|
||||||
Skill::Absorb => vec![ConstructEffect {effect: Effect::Absorb, duration: 2,
|
Skill::Absorb => vec![ConstructEffect {effect: Effect::Absorb, duration: 1,
|
||||||
meta: Some(EffectMeta::Skill(Skill::Absorption)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::Absorption)), tick: None}],
|
||||||
Skill::AbsorbPlus => vec![ConstructEffect {effect: Effect::Absorb, duration: 3,
|
Skill::AbsorbPlus => vec![ConstructEffect {effect: Effect::Absorb, duration: 1,
|
||||||
meta: Some(EffectMeta::Skill(Skill::AbsorptionPlus)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::AbsorptionPlus)), tick: None}],
|
||||||
Skill::AbsorbPlusPlus => vec![ConstructEffect {effect: Effect::Absorb, duration: 4,
|
Skill::AbsorbPlusPlus => vec![ConstructEffect {effect: Effect::Absorb, duration: 1,
|
||||||
meta: Some(EffectMeta::Skill(Skill::AbsorptionPlusPlus)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::AbsorptionPlusPlus)), tick: None}],
|
||||||
|
|
||||||
Skill::Absorption => vec![ConstructEffect {effect: Effect::Absorption, duration: 3, meta: None, tick: None}],
|
Skill::Absorption => vec![ConstructEffect {effect: Effect::Absorption, duration: 3, meta: None, tick: None}],
|
||||||
@ -993,9 +1008,9 @@ impl Skill {
|
|||||||
meta: Some(EffectMeta::Skill(Skill::BashPlusPlus)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::BashPlusPlus)), tick: None}],
|
||||||
Skill::Stun => vec![ConstructEffect {effect: Effect::Stun, duration: 2, meta: None, 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::Intercept => vec![ConstructEffect {effect: Effect::Intercept, duration: 1, meta: None, tick: None}],
|
||||||
Skill::InterceptPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 3, meta: None, tick: None}],
|
Skill::InterceptPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 1, meta: None, tick: None}],
|
||||||
Skill::InterceptPlusPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 4, meta: None, tick: None}],
|
Skill::InterceptPlusPlus => vec![ConstructEffect {effect: Effect::Intercept, duration: 1, meta: None, tick: None}],
|
||||||
|
|
||||||
Skill::Triage => vec![ConstructEffect {effect: Effect::Triage, duration: 2,
|
Skill::Triage => vec![ConstructEffect {effect: Effect::Triage, duration: 2,
|
||||||
meta: Some(EffectMeta::Skill(Skill::TriageTick)), tick: None}],
|
meta: Some(EffectMeta::Skill(Skill::TriageTick)), tick: None}],
|
||||||
@ -1062,9 +1077,11 @@ impl Skill {
|
|||||||
Skill::Invert=> Some(2),
|
Skill::Invert=> Some(2),
|
||||||
Skill::InvertPlus => Some(2),
|
Skill::InvertPlus => Some(2),
|
||||||
Skill::InvertPlusPlus => Some(2),
|
Skill::InvertPlusPlus => Some(2),
|
||||||
Skill::Decay=> Some(1), // dot
|
|
||||||
Skill::DecayPlus => Some(1),
|
Skill::Decay=> None, // dot
|
||||||
Skill::DecayPlusPlus => Some(1),
|
Skill::DecayPlus => None,
|
||||||
|
Skill::DecayPlusPlus => None,
|
||||||
|
|
||||||
Skill::Siphon|
|
Skill::Siphon|
|
||||||
Skill::SiphonPlus |
|
Skill::SiphonPlus |
|
||||||
Skill::SiphonPlusPlus => None,
|
Skill::SiphonPlusPlus => None,
|
||||||
@ -1091,7 +1108,7 @@ impl Skill {
|
|||||||
|
|
||||||
Skill::Banish |
|
Skill::Banish |
|
||||||
Skill::BanishPlus |
|
Skill::BanishPlus |
|
||||||
Skill::BanishPlusPlus => Some(2),
|
Skill::BanishPlusPlus => Some(1),
|
||||||
|
|
||||||
Skill::Haste=> Some(1),
|
Skill::Haste=> Some(1),
|
||||||
Skill::HastePlus => Some(1),
|
Skill::HastePlus => Some(1),
|
||||||
@ -1121,9 +1138,9 @@ impl Skill {
|
|||||||
Skill::SustainPlus |
|
Skill::SustainPlus |
|
||||||
Skill::SustainPlusPlus => Some(1),
|
Skill::SustainPlusPlus => Some(1),
|
||||||
|
|
||||||
Skill::Intercept=> Some(2),
|
Skill::Intercept=> Some(1),
|
||||||
Skill::InterceptPlus => Some(2),
|
Skill::InterceptPlus => Some(1),
|
||||||
Skill::InterceptPlusPlus => Some(2),
|
Skill::InterceptPlusPlus => Some(1),
|
||||||
|
|
||||||
Skill::Electrify |
|
Skill::Electrify |
|
||||||
Skill::ElectrifyPlus |
|
Skill::ElectrifyPlus |
|
||||||
@ -1394,7 +1411,7 @@ fn sustain(source: &mut Construct, target: &mut Construct, mut results: Resoluti
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warn!("no recharge event found {:?}", e);
|
warn!("no recharge event found {:?}", e);
|
||||||
return results;
|
EventStages::NoStages
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1416,7 +1433,7 @@ fn intercept(source: &mut Construct, target: &mut Construct, mut results: Resolu
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warn!("no recharge event found {:?}", e);
|
warn!("no recharge event found {:?}", e);
|
||||||
return results;
|
EventStages::NoStages
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
results.push(Resolution::new(source, target).event(e).stages(stages));
|
results.push(Resolution::new(source, target).event(e).stages(stages));
|
||||||
@ -1675,6 +1692,19 @@ fn ruin(source: &mut Construct, target: &mut Construct, mut results: Resolutions
|
|||||||
|
|
||||||
fn absorb(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
|
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])));
|
results.push(Resolution::new(source, target).event(target.add_effect(skill, skill.effect()[0])));
|
||||||
|
let blue_amount = source.blue_power().pct(skill.multiplier());
|
||||||
|
let e = target.recharge(skill, 0, blue_amount);
|
||||||
|
let stages = match e {
|
||||||
|
Event::Recharge { red, blue, skill: _ } => {
|
||||||
|
if red > 0 || blue > 0 { EventStages::PostOnly }
|
||||||
|
else { EventStages::NoStages }
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("no recharge event found {:?}", e);
|
||||||
|
EventStages::NoStages
|
||||||
|
}
|
||||||
|
};
|
||||||
|
results.push(Resolution::new(source, target).event(e).stages(stages));
|
||||||
return results;;
|
return results;;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1721,7 +1751,7 @@ fn reflect(source: &mut Construct, target: &mut Construct, mut results: Resoluti
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warn!("no recharge event found {:?}", e);
|
warn!("no recharge event found {:?}", e);
|
||||||
return results;
|
EventStages::NoStages
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
results.push(Resolution::new(source, target).event(e).stages(stages));
|
results.push(Resolution::new(source, target).event(e).stages(stages));
|
||||||
@ -1739,7 +1769,7 @@ fn recharge(source: &mut Construct, target: &mut Construct, mut results: Resolut
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
warn!("no recharge event found {:?}", e);
|
warn!("no recharge event found {:?}", e);
|
||||||
return results;
|
EventStages::NoStages
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
results.push(Resolution::new(source, target).event(e).stages(stages));
|
results.push(Resolution::new(source, target).event(e).stages(stages));
|
||||||
@ -1794,13 +1824,19 @@ fn link(source: &mut Construct, target: &mut Construct, mut results: Resolutions
|
|||||||
None => 0
|
None => 0
|
||||||
};
|
};
|
||||||
|
|
||||||
target.deal_blue_damage(skill, swap)
|
let link_events = target.deal_blue_damage(skill, swap);
|
||||||
.into_iter()
|
for e in link_events {
|
||||||
.for_each(|e| results.push(Resolution::new(source, target).event(e)));
|
match e {
|
||||||
|
Event::Damage { amount, mitigation: _, colour: _, skill: _ } => {
|
||||||
source.deal_green_damage(skill, swap)
|
results.push(Resolution::new(source, target).event(e));
|
||||||
.into_iter()
|
let heal = source.deal_green_damage(skill, amount);
|
||||||
.for_each(|e| results.push(Resolution::new(source, source).event(e).stages(EventStages::PostOnly)));
|
for h in heal {
|
||||||
|
results.push(Resolution::new(source, source).event(h).stages(EventStages::PostOnly));
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_ => results.push(Resolution::new(source, target).event(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
results.push(Resolution::new(source, source)
|
results.push(Resolution::new(source, source)
|
||||||
.event(source.add_effect(skill, skill.effect()[0])).stages(EventStages::PostOnly));
|
.event(source.add_effect(skill, skill.effect()[0])).stages(EventStages::PostOnly));
|
||||||
@ -2076,6 +2112,7 @@ mod tests {
|
|||||||
x.blue_power.force(256);
|
x.blue_power.force(256);
|
||||||
x.green_power.force(220);
|
x.green_power.force(220);
|
||||||
x.green_life.force(1024);
|
x.green_life.force(1024);
|
||||||
|
y.blue_life.force(0);
|
||||||
x.green_life.reduce(512);
|
x.green_life.reduce(512);
|
||||||
|
|
||||||
let mut results = resolve(Skill::Siphon, &mut x, &mut y, vec![]);
|
let mut results = resolve(Skill::Siphon, &mut x, &mut y, vec![]);
|
||||||
|
|||||||
@ -99,8 +99,8 @@ impl Vbox {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn accept(&mut self, i: usize, j: usize) -> Result<&mut Vbox, Error> {
|
pub fn accept(&mut self, i: usize, j: usize, construct_id: Option<Uuid>) -> Result<&mut Vbox, Error> {
|
||||||
if self.bound.len() >= 9 {
|
if self.bound.len() >= 9 && !construct_id.is_some() {
|
||||||
return Err(err_msg("too many items bound"));
|
return Err(err_msg("too many items bound"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ impl Vbox {
|
|||||||
|
|
||||||
pub fn bot_accept(&mut self, i: usize) -> Result<&mut Vbox, Error> {
|
pub fn bot_accept(&mut self, i: usize) -> Result<&mut Vbox, Error> {
|
||||||
let buy_index = self.free[i].iter().position(|item| item.is_some());
|
let buy_index = self.free[i].iter().position(|item| item.is_some());
|
||||||
self.accept(i, buy_index.expect("no valid buys"))
|
self.accept(i, buy_index.expect("no valid buys"), None)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reclaim(&mut self, i: usize) -> Result<&mut Vbox, Error> {
|
pub fn reclaim(&mut self, i: usize) -> Result<&mut Vbox, Error> {
|
||||||
@ -181,9 +181,9 @@ pub fn vbox_discard(tx: &mut Transaction, account: &Account, instance_id: Uuid)
|
|||||||
return instance_update(tx, instance);
|
return instance_update(tx, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_accept(tx: &mut Transaction, account: &Account, instance_id: Uuid, group: usize, index: usize) -> Result<Instance, Error> {
|
pub fn vbox_accept(tx: &mut Transaction, account: &Account, instance_id: Uuid, group: usize, index: usize, construct_id: Option<Uuid>) -> Result<Instance, Error> {
|
||||||
let instance = instance_get(tx, instance_id)?
|
let instance = instance_get(tx, instance_id)?
|
||||||
.vbox_accept(account.id, group, index)?;
|
.vbox_accept(account.id, group, index, construct_id)?;
|
||||||
return instance_update(tx, instance);
|
return instance_update(tx, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,9 +205,9 @@ pub fn vbox_apply(tx: &mut Transaction, account: &Account, instance_id: Uuid, co
|
|||||||
return instance_update(tx, instance);
|
return instance_update(tx, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vbox_unequip(tx: &mut Transaction, account: &Account, instance_id: Uuid, construct_id: Uuid, target: Item) -> Result<Instance, Error> {
|
pub fn vbox_unequip(tx: &mut Transaction, account: &Account, instance_id: Uuid, construct_id: Uuid, target: Item, target_construct_id: Option<Uuid>) -> Result<Instance, Error> {
|
||||||
let instance = instance_get(tx, instance_id)?
|
let instance = instance_get(tx, instance_id)?
|
||||||
.vbox_unequip(account.id, target, construct_id)?;
|
.vbox_unequip(account.id, target, construct_id, target_construct_id)?;
|
||||||
return instance_update(tx, instance);
|
return instance_update(tx, instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -112,6 +112,10 @@ impl Warden {
|
|||||||
pair.0.tx.send(msg.clone())?;
|
pair.0.tx.send(msg.clone())?;
|
||||||
pair.1.tx.send(msg)?;
|
pair.1.tx.send(msg)?;
|
||||||
|
|
||||||
|
// send msgs for browser notifications
|
||||||
|
pair.0.tx.send(RpcMessage::QueueFound(()))?;
|
||||||
|
pair.1.tx.send(RpcMessage::QueueFound(()))?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user