Merge remote-tracking branch 'origin' into skilltiers
@ -22,8 +22,8 @@ Added `Buff` as a skill
|
||||
|
||||
*BALANCE*
|
||||
- purify
|
||||
- 1 effect from all cryps at level 2
|
||||
- removes all effects from all cryps at l3
|
||||
- 1 effect from all constructs at level 2
|
||||
- removes all effects from all constructs at l3
|
||||
|
||||
- invert
|
||||
- fx for buffs when applied to enemies
|
||||
|
||||
@ -5,7 +5,7 @@ specs [spec [bonus amount, [r g b]]
|
||||
|
||||
# Playthrough
|
||||
|
||||
cryps join game
|
||||
constructs join game
|
||||
stats randomised
|
||||
|
||||
initial stash drops
|
||||
|
||||
18
ECONOMY.md
@ -23,9 +23,9 @@ Base specs have a base 3 cost
|
||||
|
||||
### Actual Costs
|
||||
|
||||
- Costs increase as more of an item is used on cryps in the game
|
||||
- Costs increase as more of an item is used on constructs in the game
|
||||
- The cost increases by the base cost for every 6 allocations of base item
|
||||
- Allocation is based on all cryps in the game
|
||||
- Allocation is based on all constructs in the game
|
||||
|
||||
### Example ###
|
||||
|
||||
@ -33,15 +33,15 @@ Round #1
|
||||
|
||||
All costs are base costs
|
||||
# Player #1 and Player #2 (They both bought the same things)
|
||||
Cryp #1 Strike (Attack + RR), (2 + 1 + 1) = (4) cost
|
||||
Cryp #1 Empower (Buff + RR), (2 + 1 + 1) = (4) cost
|
||||
Cryp #3 Attack, 2 cost
|
||||
Construct #1 Strike (Attack + RR), (2 + 1 + 1) = (4) cost
|
||||
Construct #1 Empower (Buff + RR), (2 + 1 + 1) = (4) cost
|
||||
Construct #3 Attack, 2 cost
|
||||
|
||||
Total cost - 10
|
||||
|
||||
Round #2
|
||||
|
||||
Items used on cryps include:
|
||||
Items used on constructs include:
|
||||
|
||||
Red x 8
|
||||
Attack x 4
|
||||
@ -52,9 +52,9 @@ The costs of red for round #2 are now (1 + 1) = 2
|
||||
If they were to buy the same skill setup it would be as follows:
|
||||
|
||||
# Player #1 and Player #2 (They both bought the same things)
|
||||
Cryp #1 Strike (Attack + RR), (2 + 2 + 2) = (6) cost
|
||||
Cryp #1 Empower (Buff + RR), (2 + 2 + 2) = (6) cost
|
||||
Cryp #3 Attack, 2 cost
|
||||
Construct #1 Strike (Attack + RR), (2 + 2 + 2) = (6) cost
|
||||
Construct #1 Empower (Buff + RR), (2 + 2 + 2) = (6) cost
|
||||
Construct #3 Attack, 2 cost
|
||||
|
||||
Total cost - 14
|
||||
|
||||
|
||||
2
NODES.md
@ -46,4 +46,4 @@ Rare `increased speed, increased cooldowns`
|
||||
- Increased stat
|
||||
- ??? Related Notables
|
||||
|
||||
# ??? Cryps need to have a minimum of X of the cryp stat to learn a skill #
|
||||
# ??? Constructs need to have a minimum of X of the construct stat to learn a skill #
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Cryps ("creeps")
|
||||
# Constructs ("creeps")
|
||||
|
||||
## Combat
|
||||
|
||||
@ -30,7 +30,7 @@ resolve phase:
|
||||
| reduction | absorption? | durations |
|
||||
|
||||
|
||||
## Cryp Alignments
|
||||
## Construct Alignments
|
||||
|
||||
Natural Selection
|
||||
================
|
||||
@ -92,7 +92,7 @@ Path to Destruction
|
||||
Damage & Destruction
|
||||
-------------------------
|
||||
|
||||
cryps walking the path to destruction have forsaken themselves in order to gain ruinous power.
|
||||
constructs walking the path to destruction have forsaken themselves in order to gain ruinous power.
|
||||
no price is too high, they gladly harm themselves and allies to amplify the destruction they wreak on everything around them
|
||||
specialise in magical damage dealing
|
||||
|
||||
@ -124,7 +124,7 @@ Universal Chaos
|
||||
The only constant is change.
|
||||
----------------------------
|
||||
|
||||
Cryps aligning themselves with the forces of chaos believe that constant change is the only truth in the universe.
|
||||
Constructs aligning themselves with the forces of chaos believe that constant change is the only truth in the universe.
|
||||
They harness its power to manipulate physical reality as well as control and disrupt the flow of battle.
|
||||
They blend between physical and astral forms, constantly shifting throughout time and space.
|
||||
|
||||
|
||||
27
ROADMAP.md
@ -1,7 +1,7 @@
|
||||
|
||||
### Road Map ###
|
||||
|
||||
# NOW Phase 1 (Dev -> Alpha)
|
||||
# NOW Phase 1 (Dev -> Alpha)
|
||||
|
||||
Form company structure
|
||||
Brainstorm Names?
|
||||
@ -22,7 +22,7 @@ Combat animations
|
||||
Make in game shop
|
||||
Payment processors / CC etc
|
||||
Handler for game purchases
|
||||
MTX - Cryp Avatars
|
||||
MTX - Construct Avatars
|
||||
MTX - Skill anims
|
||||
|
||||
Setup company bank accounts
|
||||
@ -32,7 +32,7 @@ Setup company bank accounts
|
||||
|
||||
Player Events e.g. chatwheel
|
||||
Matchmaking + ELO / Leaderboard
|
||||
Game skill private fields
|
||||
Game skill private fields
|
||||
|
||||
Refine artwork, icons, scaling etc
|
||||
Music
|
||||
@ -41,4 +41,23 @@ Marketing materials
|
||||
Videos
|
||||
Twitch
|
||||
Advertisments?
|
||||
Information
|
||||
Information
|
||||
|
||||
|
||||
|
||||
# china shit
|
||||
You need to read the details more carefully. Playsaurus messed up:
|
||||
|
||||
1. They launched in China without registering a trademark
|
||||
|
||||
2. A competitor registered the trademark after 3 months of their launch
|
||||
|
||||
3. They continued to sell for 4 years under a name trademarked by another company, making $73,000+ yearly from that one country
|
||||
|
||||
Now, they complain about it on Reddit, even though China is a 'First to File' company.
|
||||
|
||||
The fault lies entirely with Playsaurus, nothing illegal occurred here.
|
||||
|
||||
https://www.trademarknow.com/blog/first-to-file-versus-first...
|
||||
|
||||
This situation could have occurred in many other countries - the difference is probably that the competitor is content to just sell in China, under a Chinese name, whereas products sold anywhere else would need to use the English name.
|
||||
52
SPECS.md
@ -4,16 +4,16 @@ Numbers are placeholder
|
||||
`Specs get a bonus dependent on the total of Red / Green / Blue in player skills & specs`
|
||||
|
||||
# Example to meet 5 red gem bonus from skills only
|
||||
In your player Cryp #1 has `Strike`, Cryp #2 has `Slay` and `Heal`, Cryp #3 has `Snare`
|
||||
In your player Construct #1 has `Strike`, Construct #2 has `Slay` and `Heal`, Construct #3 has `Snare`
|
||||
- RR skill `Strike` contributes 2 red gems to the total red gems (2 total)
|
||||
- RG skill `Slay` contributes 1 red gem to the total red gems (3 total)
|
||||
- GG skill `Heal` contirubtes 0 red gems to the total red gems (3 total)
|
||||
- RR skill `Snare` contirubtes 2 red gems to the total red gems (5 total)
|
||||
|
||||
# Advanced specs also require a minimum number of Red / Green / Blue gems on the cryp to take effect
|
||||
# Advanced specs also require a minimum number of Red / Green / Blue gems on the construct to take effect
|
||||
- Tier 1 Basic specs (Damage / Health / Defense) will have no requirements
|
||||
- Advanced specs will require a certain threshold of red / green / blue gems to be enabled
|
||||
- Provided spec requirements are met, all specs will add gems to the cryp
|
||||
- Provided spec requirements are met, all specs will add gems to the construct
|
||||
|
||||
# Starting from scratch with a vbox
|
||||
|
||||
@ -26,9 +26,9 @@ In your player Cryp #1 has `Strike`, Cryp #2 has `Slay` and `Heal`, Cryp #3 has
|
||||
Combine 2 Red + 'Attack' -> Strike
|
||||
Combine 2 Red + 'Basic Damage Spec' -> Red Damage
|
||||
|
||||
Cryp #1 -> Give Strike & Red Damage Spec -> Strike + 1 x Red Damage Spec
|
||||
Cryp #2 -> Give Attack -> Attack
|
||||
Cryp #3 -> Give Stun -> Stun
|
||||
Construct #1 -> Give Strike & Red Damage Spec -> Strike + 1 x Red Damage Spec
|
||||
Construct #2 -> Give Attack -> Attack
|
||||
Construct #3 -> Give Stun -> Stun
|
||||
|
||||
Player Total (4 Red + 2 Basic gems)
|
||||
|
||||
@ -37,17 +37,17 @@ In your player Cryp #1 has `Strike`, Cryp #2 has `Slay` and `Heal`, Cryp #3 has
|
||||
- Buy 2 reds & 2 green & 2 blue (all available colour items)
|
||||
- Buy 2 Basic Damage Spec (item)
|
||||
|
||||
- Cryp #2 Unequip Attack
|
||||
- Construct #2 Unequip Attack
|
||||
- Combine 2 Green + 'Attack' -> Heal
|
||||
|
||||
- Cryp #3 Unequip Stun
|
||||
- Construct #3 Unequip Stun
|
||||
- Combine 2 Blue + 'Stun' -> Ruin
|
||||
|
||||
- Combine 2 Red + 'Basic Damage Spec' -> Red Damage
|
||||
|
||||
Cryp #1 -> Give Red Damage items -> Strike + 2 x Red Damage Spec (6R)
|
||||
Cryp #2 -> Give Heal item -> Heal (2G)
|
||||
Cryp #3 -> Give Ruin item -> Ruin (2B)
|
||||
Construct #1 -> Give Red Damage items -> Strike + 2 x Red Damage Spec (6R)
|
||||
Construct #2 -> Give Heal item -> Heal (2G)
|
||||
Construct #3 -> Give Ruin item -> Ruin (2B)
|
||||
|
||||
## Round 3
|
||||
|
||||
@ -58,9 +58,9 @@ In your player Cryp #1 has `Strike`, Cryp #2 has `Slay` and `Heal`, Cryp #3 has
|
||||
- Combine 2 Red + 'Stun' -> Strangle
|
||||
- Combine 2 Red + 'Block' -> Parry
|
||||
|
||||
Cryp #1 -> Give 'Stun' & 'Strangle' -> Strike, Stun, Strangle + 2 x Red Damage Spec (10R)
|
||||
Cryp #2 -> 'No change' -> Heal (2G)
|
||||
Cryp #3 -> Give Attack item & 2 Basic Damage Spec -> Attack + Ruin + 2 x Basic Damage Spec (2B)
|
||||
Construct #1 -> Give 'Stun' & 'Strangle' -> Strike, Stun, Strangle + 2 x Red Damage Spec (10R)
|
||||
Construct #2 -> 'No change' -> Heal (2G)
|
||||
Construct #3 -> Give Attack item & 2 Basic Damage Spec -> Attack + Ruin + 2 x Basic Damage Spec (2B)
|
||||
|
||||
## Round 4
|
||||
|
||||
@ -70,18 +70,18 @@ In your player Cryp #1 has `Strike`, Cryp #2 has `Slay` and `Heal`, Cryp #3 has
|
||||
- Combine 2 Red + 'Attack' -> Strike
|
||||
- Combine 2 Red + 'Buff' -> Empower
|
||||
|
||||
- Cryp #1 Unequip 2 x Red Damage spec, Equip Empower -> Strike, Stun, Strangle, Empower (8R)
|
||||
- Construct #1 Unequip 2 x Red Damage spec, Equip Empower -> Strike, Stun, Strangle, Empower (8R)
|
||||
- Combine 'Strike' + 2 x Red Damage spec -> 'Increased Strike Damage spec'
|
||||
|
||||
### Note 'Increased Strike Damage spec' requires 8R on the cryp
|
||||
### Note 'Increased Strike Damage spec' requires 8R on the construct
|
||||
|
||||
Cryp #1 Equip Increased Strike Damage spec -> Strike, Stun, Strangle, Empower + Increased Strike Damage Spec (14R)
|
||||
Cryp #2 -> 'No change' -> Heal
|
||||
Cryp #3 -> 'No change' -> Attack + Ruin + 2 x Basic Damage Spec
|
||||
Construct #1 Equip Increased Strike Damage spec -> Strike, Stun, Strangle, Empower + Increased Strike Damage Spec (14R)
|
||||
Construct #2 -> 'No change' -> Heal
|
||||
Construct #3 -> 'No change' -> Attack + Ruin + 2 x Basic Damage Spec
|
||||
|
||||
## Round 5
|
||||
|
||||
We already lost cause we went all in on 1 red cryp like a noob
|
||||
We already lost cause we went all in on 1 red construct like a noob
|
||||
|
||||
### Generic Specs
|
||||
|
||||
@ -96,7 +96,7 @@ Maximum 35% inc hp
|
||||
Maximum 50% inc speed
|
||||
|
||||
# Basic Class Spec
|
||||
`Base` -> +2 red, +2 green +2 blue gems on cryp
|
||||
`Base` -> +2 red, +2 green +2 blue gems on construct
|
||||
# Basic Duration
|
||||
|
||||
### Increased Damage Combos ###
|
||||
@ -182,32 +182,32 @@ Maximum +35% inc blue shield and 35% inc red shield
|
||||
## Upgraded Attack Spec Combos
|
||||
|
||||
# Increased Strike Damage (Combine Strike + Red Damage Spec x 2)
|
||||
Cryp Requires `8 red gems`
|
||||
Construct Requires `8 red gems`
|
||||
Adds `6 red gems`
|
||||
`Base` -> 15% increased strike damage
|
||||
`Player Bonus` 15 red gems -> +15% // 20 red gems -> +20% // 30 red gems -> +30%
|
||||
Maximum 80% increased strike damage
|
||||
|
||||
# Improved Heal (Combine Heal + Healing Spec x 2)
|
||||
Cryp Requires `8 green gems`
|
||||
Construct Requires `8 green gems`
|
||||
`Base` -> 15% increased heal healing
|
||||
`Player Bonus` 15 green gems -> +15% // 20 green gems -> +20% // 30 green gems -> +30%
|
||||
Maximum 80% increased heal healing
|
||||
|
||||
# Increased Blast Damage (Combine Blast + Blue Spec x 2)
|
||||
Cryp Requires `8 blue gems`
|
||||
Construct Requires `8 blue gems`
|
||||
`Base` -> 15% increased blast damage
|
||||
`Player Bonus` 15 blue gems -> +15% // 20 blue gems -> +20% // 30 blue gems -> +30%
|
||||
Maximum 80% increased blast damage
|
||||
|
||||
# Increased Slay Damage (Combine Slay + Red Damage Spec + Healing Spec)
|
||||
Cryp Requires `4 red 4 green gems`
|
||||
Construct Requires `4 red 4 green gems`
|
||||
`Base` -> 15% increased slay damage
|
||||
`Player Bonus` (8R + 8G) gems -> +15% // (10R + 10G) gems -> +20% // (15R + 15G) gems -> +30%
|
||||
Maximum 80% increased slay damage
|
||||
|
||||
# Increased Banish Damage (Combine Slay + Red Damage Spec + Blue Damage Spec)
|
||||
Cryp Requires `4 red 4 blue gems`
|
||||
Construct Requires `4 red 4 blue gems`
|
||||
`Base` -> 15% increased slay damage
|
||||
`Player Bonus` (8R + 8B) gems -> +15% // (10R + 10B) gems -> +20% // (15R + 15B) gems -> +30%
|
||||
Maximum 80% increased banish damage
|
||||
|
||||
@ -24,8 +24,8 @@ Tidy edges on game UI
|
||||
blue + defensive green
|
||||
|
||||
- purify
|
||||
- 1 effect from all cryps at level 2
|
||||
- removes all effects from all cryps at l3
|
||||
- 1 effect from all constructs at level 2
|
||||
- removes all effects from all constructs at l3
|
||||
|
||||
- invert
|
||||
- fx for buffs when applied to enemies
|
||||
@ -102,7 +102,7 @@ push events
|
||||
$$$
|
||||
* Items
|
||||
* Colour scheme
|
||||
* number of cryps
|
||||
* number of constructs
|
||||
* Highlight (dota) colour
|
||||
* fx colours + styles
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@
|
||||
}
|
||||
|
||||
|
||||
.opponent .game-cryp {
|
||||
.opponent .game-construct {
|
||||
align-items: flex-start;
|
||||
grid-template-rows: min-content min-content min-content 2fr;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
@ -47,12 +47,12 @@
|
||||
"avatar target";
|
||||
}
|
||||
|
||||
.opponent .game-cryp .name {
|
||||
.opponent .game-construct .name {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0.25em;
|
||||
}
|
||||
|
||||
.game-cryp {
|
||||
.game-construct {
|
||||
display: grid;
|
||||
|
||||
/*justify-items: center;*/
|
||||
@ -74,7 +74,7 @@
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
|
||||
.game-cryp .targeting {
|
||||
.game-construct .targeting {
|
||||
grid-area: target;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
@ -84,40 +84,36 @@
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.game-cryp .img {
|
||||
.game-construct .img {
|
||||
grid-area: avatar;
|
||||
}
|
||||
|
||||
.game-cryp .name {
|
||||
.game-construct .name {
|
||||
width: 100%;
|
||||
margin-bottom: 0.25em;
|
||||
text-align: center;
|
||||
grid-area: name;
|
||||
}
|
||||
|
||||
.game-cryp .stats {
|
||||
.game-construct .stats {
|
||||
grid-area: stats;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
|
||||
.game-cryp figure {
|
||||
.game-construct figure {
|
||||
padding: 0 0.5em;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
.game-cryp figcaption {
|
||||
.game-construct figcaption {
|
||||
white-space: nowrap;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 1500px) {
|
||||
.game {
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.game-cryp figure {
|
||||
.game-construct figure {
|
||||
padding: 0 0.25em;
|
||||
}
|
||||
|
||||
@ -127,7 +123,7 @@
|
||||
}
|
||||
*/}
|
||||
|
||||
.game-cryp .skills {
|
||||
.game-construct .skills {
|
||||
grid-area: skills;
|
||||
display: flex;
|
||||
flex-flow: column-reverse;
|
||||
@ -135,13 +131,13 @@
|
||||
}
|
||||
|
||||
/*@media (max-width: 1000px) {
|
||||
.game-cryp .skills {
|
||||
.game-construct .skills {
|
||||
flex-flow: column;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
.game-cryp .effects {
|
||||
.game-construct .effects {
|
||||
grid-area: effects;
|
||||
font-size: 1.5em;
|
||||
white-space: nowrap;
|
||||
@ -157,7 +153,7 @@
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.game-cryp button {
|
||||
.game-construct button {
|
||||
color: #888;
|
||||
flex: 1 1 100%;
|
||||
padding: 0;
|
||||
@ -165,36 +161,35 @@
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.game-cryp button.active {
|
||||
.game-construct button.active {
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.game-cryp button[disabled], .game-cryp button[disabled]:hover {
|
||||
.game-construct button[disabled], .game-construct button[disabled]:hover {
|
||||
color: #333333;
|
||||
font-size: 14pt;
|
||||
text-decoration: line-through
|
||||
}
|
||||
|
||||
.game-cryp button:hover {
|
||||
.game-construct button:hover {
|
||||
color: whitesmoke;
|
||||
}
|
||||
|
||||
.game-cryp.ko {
|
||||
.game-construct.ko {
|
||||
animation: none;
|
||||
opacity: 0.35;
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.game-cryp.ko button:hover {
|
||||
.game-construct.ko button:hover {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.game-cryp.unfocus {
|
||||
.game-construct.unfocus {
|
||||
opacity: 0.65;
|
||||
filter: blur(5px);
|
||||
}
|
||||
|
||||
.game-cryp.unfocus.ko {
|
||||
.game-construct.unfocus.ko {
|
||||
filter: blur(5px) grayscale(100%);
|
||||
}
|
||||
|
||||
@ -207,18 +202,18 @@
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
CRYP DAMAGE
|
||||
CONSTRUCT DAMAGE
|
||||
|
||||
.game-cryp.active-skill {
|
||||
.game-construct.active-skill {
|
||||
filter: drop-shadow(0 0 0.2em silver);
|
||||
|
||||
/*border-color: silver;*/
|
||||
}
|
||||
|
||||
.game-cryp.red-damage {
|
||||
.game-construct.red-damage {
|
||||
filter: drop-shadow(0 0 0.2em red);
|
||||
color: red;
|
||||
/*ensure cryp doesn't get opacity lowered because of being KO before the KO animation*/
|
||||
/*ensure construct doesn't get opacity lowered because of being KO before the KO animation*/
|
||||
opacity: 1;
|
||||
|
||||
/*border-color: red;*/
|
||||
@ -237,7 +232,7 @@ CRYP DAMAGE
|
||||
/*border-top: 1px solid red;*/
|
||||
}
|
||||
|
||||
.game-cryp.blue-damage {
|
||||
.game-construct.blue-damage {
|
||||
filter: drop-shadow(0 0 0.2em blue);
|
||||
color: blue;
|
||||
opacity: 1;
|
||||
@ -257,7 +252,7 @@ CRYP DAMAGE
|
||||
/*border-top: 1px solid blue;*/
|
||||
}
|
||||
|
||||
.game-cryp.green-damage {
|
||||
.game-construct.green-damage {
|
||||
filter: drop-shadow(0 0 0.2em green);
|
||||
color: green;
|
||||
opacity: 1;
|
||||
@ -277,7 +272,7 @@ CRYP DAMAGE
|
||||
/*border-top: 1px solid green;*/
|
||||
}
|
||||
|
||||
.game-cryp.purple-damage {
|
||||
.game-construct.purple-damage {
|
||||
filter: drop-shadow(0 0 0.2em purple);
|
||||
color: purple;
|
||||
border-color: purple;
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
"top top info"
|
||||
"vbox vbox info"
|
||||
"equip equip info"
|
||||
"cryps cryps info";
|
||||
"constructs constructs info";
|
||||
}
|
||||
|
||||
@media (max-width: 1920px) {
|
||||
@ -22,6 +22,10 @@
|
||||
.instance .info table td svg {
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.instance svg {
|
||||
height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
.instance .top {
|
||||
@ -29,7 +33,7 @@
|
||||
}
|
||||
|
||||
.instance .scoreboard {
|
||||
grid-area: cryps;
|
||||
grid-area: constructs;
|
||||
}
|
||||
|
||||
.instance-ui-btn {
|
||||
@ -56,8 +60,8 @@
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.instance .cryps {
|
||||
grid-area: cryps;
|
||||
.instance .constructs {
|
||||
grid-area: constructs;
|
||||
}
|
||||
|
||||
.instance .equip {
|
||||
@ -144,16 +148,16 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* CRYP LIST */
|
||||
/* CONSTRUCT LIST */
|
||||
|
||||
.cryp-list {
|
||||
grid-area: cryps;
|
||||
.construct-list {
|
||||
grid-area: constructs;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
.instance-cryp, .instance-cryp-active {
|
||||
.instance-construct, .instance-construct-active {
|
||||
display: grid;
|
||||
grid-template-rows: min-content min-content min-content 1fr min-content;
|
||||
grid-template-areas:
|
||||
@ -173,17 +177,17 @@
|
||||
transition-timing-function: ease;
|
||||
*/}
|
||||
|
||||
.instance-cryp:first-child {
|
||||
.instance-construct:first-child, .instance-construct-active:first-child {
|
||||
margin-left: 0;
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.cryp-list .name {
|
||||
.construct-list .name {
|
||||
grid-area: name;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.cryp-list .avatar {
|
||||
.construct-list .avatar {
|
||||
grid-area: avatar;
|
||||
object-fit: contain;
|
||||
background-size: contain;
|
||||
@ -192,28 +196,28 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.cryp-list .name {
|
||||
.construct-list .name {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cryp-list .avatar figure {
|
||||
.construct-list .avatar figure {
|
||||
margin: 0;
|
||||
height: 80%;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.cryp-list .avatar figcaption {
|
||||
.construct-list .avatar figcaption {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.cryp-list .skills {
|
||||
.construct-list .skills {
|
||||
grid-area: skills;
|
||||
display: flex;
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.cryp-list .skills button {
|
||||
.construct-list .skills button {
|
||||
flex: 1;
|
||||
border-width: 0px;
|
||||
}
|
||||
@ -232,7 +236,7 @@
|
||||
}
|
||||
}
|
||||
*/
|
||||
.cryp-list .specs {
|
||||
.construct-list .specs {
|
||||
margin-top: 1em;
|
||||
grid-area: specs;
|
||||
display: flex;
|
||||
@ -241,18 +245,18 @@
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.cryp-list .specs figure {
|
||||
.construct-list .specs figure {
|
||||
flex: 1;
|
||||
border: 0;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.cryp-list .specs figcaption {
|
||||
.construct-list .specs figcaption {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.cryp-list .stats {
|
||||
.construct-list .stats {
|
||||
grid-area: stats;
|
||||
display: grid;
|
||||
grid-template-rows: 1fr 3fr;
|
||||
@ -263,11 +267,11 @@
|
||||
border-width: 0px;
|
||||
}
|
||||
|
||||
.cryp-list .stats figcaption {
|
||||
.construct-list .stats figcaption {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
.cryp-list .stats .icons {
|
||||
.construct-list .stats .icons {
|
||||
grid-area: st;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
@ -285,25 +289,25 @@
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.cryp-list .stat-icon {
|
||||
.construct-list .stat-icon {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cryp-list .stats .damage-label {
|
||||
.construct-list .stats .damage-label {
|
||||
grid-area: dl;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.cryp-list .stats .speed-label {
|
||||
.construct-list .stats .speed-label {
|
||||
grid-area: sl;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.cryp-list .stats .life-label {
|
||||
.construct-list .stats .life-label {
|
||||
grid-area: ll;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
@media (max-height: 800px), (max-width: 1000px) {
|
||||
.instance {
|
||||
display: grid;
|
||||
grid-template-columns: 100%;
|
||||
grid-template-rows: repeat(4, min-content);
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: min-content, min-content, min-content, 1fr;
|
||||
grid-template-areas:
|
||||
"top"
|
||||
"controls"
|
||||
"first"
|
||||
"second"
|
||||
"vbox"
|
||||
"constructs"
|
||||
}
|
||||
/* Default view */
|
||||
.instance .equip { display: none; }
|
||||
.instance .info { display: none; }
|
||||
.instance .cryp-list { display: none; }
|
||||
.instance .construct-list { display: none; }
|
||||
.vbox {
|
||||
grid-area: first;
|
||||
grid-area: vbox;
|
||||
display: grid;
|
||||
grid-template-rows: min-content min-content min-content;
|
||||
grid-template-columns: 1fr;
|
||||
@ -31,13 +31,13 @@
|
||||
.vbox-combiner {
|
||||
margin-left: 0;
|
||||
}
|
||||
/* Toggled view (cryps)*/
|
||||
/* Toggled view (constructs)*/
|
||||
#toggle-vbox-label {
|
||||
text-align: center;
|
||||
border: 2px solid #555;
|
||||
}
|
||||
#toggle-vbox-label:after{
|
||||
content: "Cryps";
|
||||
content: "Constructs";
|
||||
}
|
||||
|
||||
#toggle-vbox:checked ~ #toggle-vbox-label:after{
|
||||
@ -47,22 +47,21 @@
|
||||
#toggle-vbox:checked ~ .vbox { display: none; }
|
||||
#toggle-vbox:checked ~ .equip {
|
||||
display: initial;
|
||||
grid-area: first;
|
||||
grid-area: vbox;
|
||||
}
|
||||
|
||||
#toggle-vbox:checked ~ .highlight {
|
||||
display: initial;
|
||||
}
|
||||
|
||||
#toggle-vbox:checked ~ .cryp-list {
|
||||
grid-area: second;
|
||||
display: flex;
|
||||
#toggle-vbox:checked ~ .construct-list {
|
||||
grid-area: constructs;
|
||||
display: grid;
|
||||
justify-content: center;
|
||||
flex-flow: row wrap;
|
||||
flex: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: 1fr 1fr;
|
||||
}
|
||||
|
||||
#toggle-vbox { display: none; }
|
||||
|
||||
@ -76,15 +75,15 @@
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.cryp-list .skills {
|
||||
.construct-list .skills {
|
||||
flex-flow: row;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.instance-cryp {
|
||||
flex: 1;
|
||||
.instance-construct {
|
||||
grid-row: 2;
|
||||
display: grid;
|
||||
grid-template-rows: min-content min-content;
|
||||
grid-template-rows: min-content 1fr;
|
||||
grid-template-areas:
|
||||
"name "
|
||||
"avatar ";
|
||||
@ -95,28 +94,25 @@
|
||||
transition-delay: 0;
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
.instance-cryp img {
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
.instance-cryp .skills {
|
||||
.instance-construct .skills {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.instance-cryp .specs {
|
||||
.instance-construct .specs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.instance-cryp .stats {
|
||||
.instance-construct .stats {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.instance-cryp-active {
|
||||
flex: 1;
|
||||
order: -1;
|
||||
.instance-construct-active {
|
||||
grid-row: 1;
|
||||
grid-column: 1 / 3;
|
||||
display: grid;
|
||||
grid-template-rows: min-content min-content min-content min-content min-content;
|
||||
grid-template-rows: min-content min-content min-content 1fr min-content;
|
||||
grid-template-areas:
|
||||
"name "
|
||||
"skills "
|
||||
@ -133,11 +129,11 @@
|
||||
transition-timing-function: ease;
|
||||
}
|
||||
|
||||
.instance-cryp-active img {
|
||||
.instance-construct-active img {
|
||||
width: 55px;
|
||||
}
|
||||
|
||||
|
||||
/* Cryp Stuff */
|
||||
/* Construct Stuff */
|
||||
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
GLOBAL
|
||||
*/
|
||||
|
||||
html, body, #cryps {
|
||||
html, body, #constructs {
|
||||
/*width: 100%;*/
|
||||
margin: 0;
|
||||
|
||||
@ -61,7 +61,7 @@ figure {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#cryps {
|
||||
#constructs {
|
||||
padding: 0 2em;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 8fr;
|
||||
@ -170,6 +170,11 @@ button.left:hover, button.left:focus {
|
||||
box-shadow: inset 0.5em 0 0 0 whitesmoke;
|
||||
}
|
||||
|
||||
a {
|
||||
color: whitesmoke;
|
||||
font-size: 150%;
|
||||
}
|
||||
|
||||
svg {
|
||||
fill: none;
|
||||
stroke: whitesmoke;
|
||||
@ -277,13 +282,13 @@ button[disabled] {
|
||||
flex-flow: column;
|
||||
}
|
||||
|
||||
#cryps input, #cryps select {
|
||||
#constructs input, #constructs select {
|
||||
border-color: #444;
|
||||
background-color: #333;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
#cryps input:focus {
|
||||
#constructs input:focus {
|
||||
border-color: whitesmoke;
|
||||
}
|
||||
|
||||
@ -349,7 +354,7 @@ header {
|
||||
MENU
|
||||
*/
|
||||
|
||||
.menu-cryps {
|
||||
.menu-constructs {
|
||||
display: grid;
|
||||
grid-template-rows: min-content min-content;
|
||||
|
||||
@ -358,14 +363,14 @@ header {
|
||||
"list";
|
||||
}
|
||||
|
||||
.menu-cryps .list {
|
||||
.menu-constructs .list {
|
||||
grid-area: list;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
|
||||
.menu-cryp-ctr {
|
||||
.menu-construct-ctr {
|
||||
/*flex: 0 0 30%;*/
|
||||
|
||||
display: flex;
|
||||
@ -374,7 +379,7 @@ header {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.spawn-btn .menu-cryp {
|
||||
.spawn-btn .menu-construct {
|
||||
border: 1px solid #333;
|
||||
color: #333;
|
||||
display: flex;
|
||||
@ -399,7 +404,7 @@ header {
|
||||
opacity: 0
|
||||
}
|
||||
|
||||
.menu-cryp {
|
||||
.menu-construct {
|
||||
height: 100%;
|
||||
margin: 0.5em;
|
||||
box-sizing: border-box;
|
||||
@ -512,7 +517,7 @@ main .top {
|
||||
}
|
||||
|
||||
@media (max-height: 900px), (max-width: 1500px) {
|
||||
#cryps {
|
||||
#constructs {
|
||||
font-size: 75%;
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
@media (max-height: 800px), (max-width: 1000px) {
|
||||
#cryps {
|
||||
font-size: 12pt;
|
||||
#constructs {
|
||||
font-size: 8pt;
|
||||
padding: 0;
|
||||
grid-template-columns: min-content 1fr;
|
||||
grid-template-rows: min-content 1fr;
|
||||
@ -9,6 +9,10 @@
|
||||
"main main";
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
table td {
|
||||
height: 2.5em;
|
||||
}
|
||||
@ -27,15 +31,8 @@
|
||||
-moz-transition: all 0.5s ease-in-out;
|
||||
-o-transition: all 0.5s ease-in-out;
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
|
||||
}
|
||||
/* main {
|
||||
-webkit-transition: all 0.5s ease-in-out;
|
||||
-moz-transition: all 0.5s ease-in-out;
|
||||
-o-transition: all 0.5s ease-in-out;
|
||||
transition: all 0.5s ease-in-out;
|
||||
}
|
||||
*/
|
||||
#toggle-nav { display: none; }
|
||||
|
||||
#toggle-nav-label {
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>cryps.gg - mnml pvp atbs</title>
|
||||
<title>mnml.gg</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<meta name=apple-mobile-web-app-capable content=yes>
|
||||
<meta name=apple-mobile-web-app-status-bar-style content=black>
|
||||
<meta name="description" content="cryps.gg - mnml pvp atbs">
|
||||
<meta name="description" content="mnml pvp tbs">
|
||||
<meta name="author" content="ntr@smokestack.io">
|
||||
<link rel="manifest" href="manifest.webmanifest">
|
||||
<link rel="stylesheet" href="./node_modules/izitoast/dist/css/iziToast.min.css"></script>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "cryps.gg - mnml pvp atbs",
|
||||
"description": "cryps.gg - mnml pvp atbs",
|
||||
"short_name": "cryps.gg",
|
||||
"name": "constructs.gg - mnml pvp atbs",
|
||||
"description": "constructs.gg - mnml pvp atbs",
|
||||
"short_name": "constructs.gg",
|
||||
"icons": [
|
||||
{
|
||||
"src": "./assets/icons/726.png",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "cryps-client",
|
||||
"name": "mnml-client",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
export const setAccount = value => ({ type: 'SET_ACCOUNT', value });
|
||||
export const setCryps = value => ({ type: 'SET_CRYPS', value });
|
||||
export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value });
|
||||
export const setItemInfo = value => ({ type: 'SET_ITEM_INFO', value });
|
||||
export const setSkip = value => ({ type: 'SET_SKIP', value });
|
||||
export const setVboxHighlight = value => ({ type: 'SET_VBOX_HIGHLIGHT', value });
|
||||
@ -11,9 +11,9 @@ export const setGame = value => ({ type: 'SET_GAME', value });
|
||||
export const setResolution = value => ({ type: 'SET_RESOLUTION', value });
|
||||
export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value });
|
||||
export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) });
|
||||
export const setTeam = value => ({ type: 'SET_SELECTED_CRYPS', value: Array.from(value) });
|
||||
export const setActiveSkill = (crypId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: crypId ? { crypId, skill } : null });
|
||||
export const setActiveCryp = value => ({ type: 'SET_ACTIVE_CRYP', value });
|
||||
export const setTeam = value => ({ type: 'SET_SELECTED_CONSTRUCTS', value: Array.from(value) });
|
||||
export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null });
|
||||
export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value });
|
||||
export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value });
|
||||
export const setInfo = value => ({ type: 'SET_INFO', value });
|
||||
export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value });
|
||||
|
||||
@ -28,8 +28,8 @@ document.fonts.load('16pt "Jura"').then(() => {
|
||||
store.dispatch(actions.setWs(ws));
|
||||
ws.connect();
|
||||
|
||||
const Cryps = () => (
|
||||
<div id="cryps" >
|
||||
const Constructs = () => (
|
||||
<div id="constructs" >
|
||||
<input type="checkbox" id="toggle-nav"/>
|
||||
<label id="toggle-nav-label" htmlFor="toggle-nav"><i className="fa fa-bars"></i></label>
|
||||
<Header />
|
||||
@ -40,7 +40,7 @@ document.fonts.load('16pt "Jura"').then(() => {
|
||||
|
||||
const App = () => (
|
||||
<Provider store={store}>
|
||||
<Cryps />
|
||||
<Constructs />
|
||||
</Provider>
|
||||
);
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
const preact = require('preact');
|
||||
|
||||
function renderSpawnButton({ account, sendCrypSpawn }) {
|
||||
function renderSpawnButton({ account, sendConstructSpawn }) {
|
||||
let name = '';
|
||||
|
||||
if (!account) return <div>...</div>;
|
||||
@ -13,7 +13,7 @@ function renderSpawnButton({ account, sendCrypSpawn }) {
|
||||
<input
|
||||
className="input"
|
||||
type="text"
|
||||
placeholder="cryp name"
|
||||
placeholder="construct name"
|
||||
onChange={e => (name = e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
@ -21,7 +21,7 @@ function renderSpawnButton({ account, sendCrypSpawn }) {
|
||||
<button
|
||||
className="button"
|
||||
type="submit"
|
||||
onClick={() => sendCrypSpawn(name)}>
|
||||
onClick={() => sendConstructSpawn(name)}>
|
||||
Spawn 👾
|
||||
</button>
|
||||
</div>
|
||||
16
client/src/components/construct.spawn.container.js
Normal file
@ -0,0 +1,16 @@
|
||||
const { connect } = require('react-redux');
|
||||
|
||||
const ConstructSpawnButton = require('./construct.spawn.button');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws } = state;
|
||||
function sendConstructSpawn(name) {
|
||||
return ws.sendConstructSpawn(name);
|
||||
}
|
||||
|
||||
return { account: state.account, sendConstructSpawn };
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = addState(ConstructSpawnButton);
|
||||
@ -1,16 +0,0 @@
|
||||
const { connect } = require('react-redux');
|
||||
|
||||
const CrypSpawnButton = require('./cryp.spawn.button');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws } = state;
|
||||
function sendCrypSpawn(name) {
|
||||
return ws.sendCrypSpawn(name);
|
||||
}
|
||||
|
||||
return { account: state.account, sendCrypSpawn };
|
||||
}
|
||||
);
|
||||
|
||||
module.exports = addState(CrypSpawnButton);
|
||||
@ -1,7 +1,7 @@
|
||||
const preact = require('preact');
|
||||
const { STATS, eventClasses, getCombatText, crypAvatar } = require('../utils');
|
||||
const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils');
|
||||
const { animationDivs } = require('../animations');
|
||||
const GameCryp = require('./game.cryp');
|
||||
const GameConstruct = require('./game.construct');
|
||||
|
||||
function GamePanel(props) {
|
||||
const {
|
||||
@ -10,7 +10,7 @@ function GamePanel(props) {
|
||||
resolution,
|
||||
activeSkill,
|
||||
setActiveSkill,
|
||||
setActiveCryp,
|
||||
setActiveConstruct,
|
||||
selectSkillTarget,
|
||||
sendInstanceState,
|
||||
sendGameReady,
|
||||
@ -76,9 +76,9 @@ function GamePanel(props) {
|
||||
</div>
|
||||
);
|
||||
|
||||
function findCryp(id) {
|
||||
const team = game.players.find(t => t.cryps.find(c => c.id === id));
|
||||
if (team) return team.cryps.find(c => c.id === id);
|
||||
function findConstruct(id) {
|
||||
const team = game.players.find(t => t.constructs.find(c => c.id === id));
|
||||
if (team) return team.constructs.find(c => c.id === id);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -109,39 +109,39 @@ function GamePanel(props) {
|
||||
);
|
||||
|
||||
function PlayerTeam(team) {
|
||||
const cryps = team.cryps.map((c, i) => <GameCryp key={c.id} cryp={c} />);
|
||||
const constructs = team.constructs.map((c, i) => <GameConstruct key={c.id} construct={c} />);
|
||||
|
||||
return (
|
||||
<div className="team player">
|
||||
{cryps}
|
||||
{constructs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function OpponentCryp(cryp, i) {
|
||||
const ko = cryp.green_life.value === 0 ? 'ko' : '';
|
||||
const classes = eventClasses(resolution, cryp);
|
||||
function OpponentConstruct(construct, i) {
|
||||
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
||||
const classes = eventClasses(resolution, construct);
|
||||
|
||||
const stats = [STATS.greenLife, STATS.redLife, STATS.blueLife].map((s, j) => (
|
||||
<figure key={j} alt={s.stat}>
|
||||
{s.svg(`stat-icon ${s.colour}`)}
|
||||
<figcaption>{cryp[s.stat].value} / {cryp[s.stat].max}</figcaption>
|
||||
<figcaption>{construct[s.stat].value} / {construct[s.stat].max}</figcaption>
|
||||
</figure>
|
||||
));
|
||||
|
||||
const [combatText, combatClass] = getCombatText(cryp, resolution);
|
||||
const [combatText, combatClass] = getCombatText(construct, resolution);
|
||||
const combatTextClass = `combat-text ${combatClass}`;
|
||||
const combatTextEl = combatText
|
||||
? <div className={combatTextClass}>{combatText}</div>
|
||||
: null;
|
||||
|
||||
const effects = cryp.effects.length
|
||||
? cryp.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
|
||||
const effects = construct.effects.length
|
||||
? construct.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
|
||||
: <div> </div>;
|
||||
|
||||
const playerTeamIds = playerTeam.cryps.map(c => c.id);
|
||||
const playerTeamIds = playerTeam.constructs.map(c => c.id);
|
||||
const targeting = game.stack
|
||||
.filter(s => playerTeamIds.includes(s.source_cryp_id) && s.target_cryp_id === cryp.id)
|
||||
.filter(s => playerTeamIds.includes(s.source_construct_id) && s.target_construct_id === construct.id)
|
||||
.map((s, i) => <h3 key={i}>{`< ${s.skill}`}</h3>);
|
||||
|
||||
const anim = (
|
||||
@ -153,17 +153,17 @@ function GamePanel(props) {
|
||||
return (
|
||||
<div
|
||||
key={i}
|
||||
className={`game-cryp ${ko} ${classes}`}
|
||||
className={`game-construct ${ko} ${classes}`}
|
||||
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
||||
onClick={() => selectSkillTarget(cryp.id)} >
|
||||
onClick={() => selectSkillTarget(construct.id)} >
|
||||
<div className="stats">{stats}</div>
|
||||
<h3 className="name" >{cryp.name}</h3>
|
||||
<h3 className="name" >{construct.name}</h3>
|
||||
<div className="effects">{effects}</div>
|
||||
<div className="targeting">{targeting}</div>
|
||||
<figure
|
||||
className="img"
|
||||
onClick={() => selectSkillTarget(cryp.id)} >
|
||||
{crypAvatar(cryp.name)}
|
||||
onClick={() => selectSkillTarget(construct.id)} >
|
||||
{constructAvatar(construct.name, construct.id)}
|
||||
{combatTextEl}
|
||||
{anim}
|
||||
</figure>
|
||||
@ -173,10 +173,10 @@ function GamePanel(props) {
|
||||
|
||||
|
||||
function OpponentTeam(team) {
|
||||
const cryps = team.cryps.map(OpponentCryp);
|
||||
const constructs = team.constructs.map(OpponentConstruct);
|
||||
return (
|
||||
<div className="team opponent">
|
||||
{cryps}
|
||||
{constructs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -185,7 +185,7 @@ function GamePanel(props) {
|
||||
|
||||
function gameClick(e) {
|
||||
e.stopPropagation();
|
||||
setActiveCryp(null);
|
||||
setActiveConstruct(null);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -3,7 +3,7 @@ const preact = require('preact');
|
||||
const range = require('lodash/range');
|
||||
|
||||
const actions = require('../actions');
|
||||
const { STATS, eventClasses, getCombatText, crypAvatar } = require('../utils');
|
||||
const { STATS, eventClasses, getCombatText, constructAvatar } = require('../utils');
|
||||
const { animationDivs } = require('../animations');
|
||||
|
||||
const SkillBtn = require('./skill.btn');
|
||||
@ -18,16 +18,16 @@ const addState = connect(
|
||||
activeSkill,
|
||||
} = state;
|
||||
|
||||
function selectSkillTarget(targetCrypId) {
|
||||
function selectSkillTarget(targetConstructId) {
|
||||
if (activeSkill) {
|
||||
return ws.sendGameSkill(game.id, activeSkill.crypId, targetCrypId, activeSkill.skill);
|
||||
return ws.sendGameSkill(game.id, activeSkill.constructId, targetConstructId, activeSkill.skill);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// intercept self casting skills
|
||||
if (activeSkill && activeSkill.skill.self_targeting) {
|
||||
ws.sendGameSkill(game.id, activeSkill.crypId, null, activeSkill.skill.skill);
|
||||
ws.sendGameSkill(game.id, activeSkill.constructId, null, activeSkill.skill.skill);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -40,48 +40,48 @@ const addState = connect(
|
||||
},
|
||||
);
|
||||
|
||||
function GameCryp(props) {
|
||||
function GameConstruct(props) {
|
||||
const {
|
||||
game,
|
||||
account,
|
||||
cryp,
|
||||
construct,
|
||||
resolution,
|
||||
activeSkill,
|
||||
setActiveCryp,
|
||||
setActiveConstruct,
|
||||
selectSkillTarget,
|
||||
} = props;
|
||||
|
||||
const ko = cryp.green_life.value === 0 ? 'ko' : '';
|
||||
const classes = eventClasses(resolution, cryp);
|
||||
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
||||
const classes = eventClasses(resolution, construct);
|
||||
|
||||
const skills = range(0, 3)
|
||||
.map(i => <SkillBtn key={i} cryp={cryp} i={i} />);
|
||||
.map(i => <SkillBtn key={i} construct={construct} i={i} />);
|
||||
|
||||
const stats = [STATS.greenLife, STATS.redLife, STATS.blueLife].map((s, j) => {
|
||||
// i've seen this happen ;/
|
||||
if (cryp[s.stat].value < 0) console.warn(cryp);
|
||||
if (construct[s.stat].value < 0) console.warn(construct);
|
||||
return <figure key={j} alt={s.stat}>
|
||||
{s.svg(`stat-icon ${s.colour}`)}
|
||||
<figcaption>{cryp[s.stat].value} / {cryp[s.stat].max}</figcaption>
|
||||
<figcaption>{construct[s.stat].value} / {construct[s.stat].max}</figcaption>
|
||||
</figure>
|
||||
});
|
||||
|
||||
|
||||
const [combatText, combatClass] = getCombatText(cryp, resolution);
|
||||
const [combatText, combatClass] = getCombatText(construct, resolution);
|
||||
const combatTextClass = `combat-text ${combatClass}`;
|
||||
const combatTextEl = combatText
|
||||
? <div className={combatTextClass}>{combatText}</div>
|
||||
: null;
|
||||
|
||||
const effects = cryp.effects.length
|
||||
? cryp.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
|
||||
const effects = construct.effects.length
|
||||
? construct.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
|
||||
: <div> </div>;
|
||||
|
||||
const playerTeam = game.players.find(t => t.id === account.id);
|
||||
const playerTeamIds = playerTeam.cryps.map(c => c.id);
|
||||
const playerTeamIds = playerTeam.constructs.map(c => c.id);
|
||||
|
||||
const targeting = game.stack
|
||||
.filter(s => playerTeamIds.includes(s.source_cryp_id) && s.target_cryp_id === cryp.id)
|
||||
.filter(s => playerTeamIds.includes(s.source_construct_id) && s.target_construct_id === construct.id)
|
||||
.map((s, i) => <h3 key={i}>{`< ${s.skill}`}</h3>);
|
||||
|
||||
const anim = (
|
||||
@ -93,9 +93,9 @@ function GameCryp(props) {
|
||||
return (
|
||||
<div
|
||||
style={ activeSkill ? { cursor: 'pointer' } : {}}
|
||||
className={`game-cryp ${ko} ${classes}`} >
|
||||
className={`game-construct ${ko} ${classes}`} >
|
||||
<h3 className="name">
|
||||
{cryp.name}
|
||||
{construct.name}
|
||||
</h3>
|
||||
<div className="skills">
|
||||
{skills}
|
||||
@ -105,8 +105,8 @@ function GameCryp(props) {
|
||||
</div>
|
||||
<figure
|
||||
className="img"
|
||||
onClick={() => selectSkillTarget(cryp.id)} >
|
||||
{crypAvatar(cryp.name, cryp.id)}
|
||||
onClick={() => selectSkillTarget(construct.id)} >
|
||||
{constructAvatar(construct.name, construct.id)}
|
||||
{combatTextEl}
|
||||
{anim}
|
||||
</figure>
|
||||
@ -120,4 +120,4 @@ function GameCryp(props) {
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(GameCryp);
|
||||
module.exports = addState(GameConstruct);
|
||||
@ -13,12 +13,12 @@ const addState = connect(
|
||||
resolution,
|
||||
showLog,
|
||||
activeSkill,
|
||||
activeCryp,
|
||||
activeConstruct,
|
||||
} = state;
|
||||
|
||||
function selectSkillTarget(targetCrypId) {
|
||||
function selectSkillTarget(targetConstructId) {
|
||||
if (activeSkill) {
|
||||
return ws.sendGameSkill(game.id, activeSkill.crypId, targetCrypId, activeSkill.skill);
|
||||
return ws.sendGameSkill(game.id, activeSkill.constructId, targetConstructId, activeSkill.skill);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -34,7 +34,7 @@ const addState = connect(
|
||||
|
||||
// intercept self casting skills
|
||||
if (activeSkill && activeSkill.skill.self_targeting) {
|
||||
ws.sendGameSkill(game.id, activeSkill.crypId, null, activeSkill.skill.skill);
|
||||
ws.sendGameSkill(game.id, activeSkill.constructId, null, activeSkill.skill.skill);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -43,7 +43,7 @@ const addState = connect(
|
||||
account,
|
||||
resolution,
|
||||
activeSkill,
|
||||
activeCryp,
|
||||
activeConstruct,
|
||||
selectSkillTarget,
|
||||
sendInstanceState,
|
||||
sendGameReady,
|
||||
@ -51,13 +51,13 @@ const addState = connect(
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setActiveSkill(crypId, skill) {
|
||||
dispatch(actions.setActiveSkill(crypId, skill));
|
||||
// particlesJS(`particles-${crypId}`, config);
|
||||
function setActiveSkill(constructId, skill) {
|
||||
dispatch(actions.setActiveSkill(constructId, skill));
|
||||
// particlesJS(`particles-${constructId}`, config);
|
||||
}
|
||||
|
||||
function setActiveCryp(cryp) {
|
||||
dispatch(actions.setActiveCryp(cryp));
|
||||
function setActiveConstruct(construct) {
|
||||
dispatch(actions.setActiveConstruct(construct));
|
||||
}
|
||||
|
||||
function quit() {
|
||||
@ -73,7 +73,7 @@ const addState = connect(
|
||||
dispatch(actions.setSkip(true));
|
||||
}
|
||||
|
||||
return { setActiveSkill, setActiveCryp, quit, toggleLog, skip };
|
||||
return { setActiveSkill, setActiveConstruct, quit, toggleLog, skip };
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
@ -23,7 +23,7 @@ function renderHeader(args) {
|
||||
return (
|
||||
<header>
|
||||
<h1 className="header-title">
|
||||
cryps.gg
|
||||
mnml.gg
|
||||
</h1>
|
||||
{accountStatus}
|
||||
</header>
|
||||
|
||||
@ -27,10 +27,10 @@ function Info(args) {
|
||||
let red = 0;
|
||||
let blue = 0;
|
||||
let green = 0;
|
||||
player.cryps.forEach(cryp => {
|
||||
red += cryp.colours.red;
|
||||
blue += cryp.colours.blue;
|
||||
green += cryp.colours.green;
|
||||
player.constructs.forEach(construct => {
|
||||
red += construct.colours.red;
|
||||
blue += construct.colours.blue;
|
||||
green += construct.colours.green;
|
||||
});
|
||||
const teamColours = { red, blue, green };
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ const { connect } = require('react-redux');
|
||||
|
||||
const Vbox = require('./vbox.component');
|
||||
const InfoContainer = require('./info.container');
|
||||
const InstanceCrypsContainer = require('./instance.cryps');
|
||||
const InstanceConstructsContainer = require('./instance.constructs');
|
||||
const EquipmentContainer = require('./instance.equip');
|
||||
|
||||
const actions = require('../actions');
|
||||
@ -137,7 +137,7 @@ function Instance(args) {
|
||||
<Vbox />
|
||||
<InfoContainer />
|
||||
<EquipmentContainer />
|
||||
<InstanceCrypsContainer />
|
||||
<InstanceConstructsContainer />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
@ -3,24 +3,24 @@ const preact = require('preact');
|
||||
const range = require('lodash/range');
|
||||
|
||||
const shapes = require('./shapes');
|
||||
const { SPECS, STATS, instanceCryp } = require('../utils');
|
||||
const { SPECS, STATS, instanceConstruct } = require('../utils');
|
||||
const actions = require('../actions');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, instance, account, itemInfo, itemEquip, activeCryp } = state;
|
||||
const { ws, instance, account, itemInfo, itemEquip, activeConstruct } = state;
|
||||
const player = instance.players.find(p => p.id === account.id);
|
||||
|
||||
function sendInstanceReady() {
|
||||
return ws.sendInstanceReady(instance.id);
|
||||
}
|
||||
|
||||
function sendVboxApply(crypId, i) {
|
||||
return ws.sendVboxApply(instance.id, crypId, i);
|
||||
function sendVboxApply(constructId, i) {
|
||||
return ws.sendVboxApply(instance.id, constructId, i);
|
||||
}
|
||||
|
||||
function sendUnequip(crypId, item) {
|
||||
return ws.sendVboxUnequip(instance.id, crypId, item);
|
||||
function sendUnequip(constructId, item) {
|
||||
return ws.sendVboxUnequip(instance.id, constructId, item);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -31,7 +31,7 @@ const addState = connect(
|
||||
sendVboxApply,
|
||||
itemInfo,
|
||||
itemEquip,
|
||||
activeCryp,
|
||||
activeConstruct,
|
||||
sendUnequip,
|
||||
};
|
||||
},
|
||||
@ -45,8 +45,8 @@ const addState = connect(
|
||||
dispatch(actions.setInfo(item));
|
||||
}
|
||||
|
||||
function setActiveCryp(value) {
|
||||
dispatch(actions.setActiveCryp(value));
|
||||
function setActiveConstruct(value) {
|
||||
dispatch(actions.setActiveConstruct(value));
|
||||
}
|
||||
|
||||
function clearInfo() {
|
||||
@ -61,19 +61,19 @@ const addState = connect(
|
||||
return dispatch(actions.setItemUnequip(v));
|
||||
}
|
||||
|
||||
return { quit, clearInfo, setInfo, setActiveCryp, setItemUnequip, setItemEquip };
|
||||
return { quit, clearInfo, setInfo, setActiveConstruct, setItemUnequip, setItemEquip };
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
function Cryp(props) {
|
||||
function Construct(props) {
|
||||
const {
|
||||
activeCryp,
|
||||
activeConstruct,
|
||||
itemEquip,
|
||||
cryp,
|
||||
construct,
|
||||
player,
|
||||
sendVboxApply,
|
||||
setActiveCryp,
|
||||
setActiveConstruct,
|
||||
setItemUnequip,
|
||||
setItemEquip,
|
||||
itemInfo,
|
||||
@ -84,9 +84,9 @@ function Cryp(props) {
|
||||
function onClick(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
if (itemEquip !== null) sendVboxApply(cryp.id, itemEquip);
|
||||
if (itemEquip !== null) sendVboxApply(construct.id, itemEquip);
|
||||
setItemEquip(null);
|
||||
return setActiveCryp(cryp);
|
||||
return setActiveConstruct(construct);
|
||||
}
|
||||
|
||||
function hoverInfo(e, info) {
|
||||
@ -100,7 +100,7 @@ function Cryp(props) {
|
||||
const specList = itemInfo.items.filter(v => v.spec).map(v => v.item);
|
||||
|
||||
const skills = range(0, 3).map(i => {
|
||||
const skill = cryp.skills[i];
|
||||
const skill = construct.skills[i];
|
||||
const s = skill
|
||||
? skill.skill
|
||||
: (<span className="gray">+</span>);
|
||||
@ -108,15 +108,15 @@ function Cryp(props) {
|
||||
function skillClick(e) {
|
||||
if (!skill) return false;
|
||||
setItemUnequip(skill.skill);
|
||||
setActiveCryp(cryp);
|
||||
setActiveConstruct(construct);
|
||||
e.stopPropagation();
|
||||
return true;
|
||||
}
|
||||
|
||||
function skillDblClick(e) {
|
||||
if (!skill) return false;
|
||||
sendUnequip(cryp.id, skill.skill);
|
||||
setActiveCryp(null);
|
||||
sendUnequip(construct.id, skill.skill);
|
||||
setActiveConstruct(null);
|
||||
setItemUnequip(null);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@ -140,7 +140,7 @@ function Cryp(props) {
|
||||
});
|
||||
|
||||
const specs = range(0, 6).map(i => {
|
||||
const s = cryp.specs[i];
|
||||
const s = construct.specs[i];
|
||||
|
||||
if (!s) {
|
||||
const equip = specList.includes(vbox.bound[itemEquip]) ? 'equip-spec' : 'gray';
|
||||
@ -155,12 +155,12 @@ function Cryp(props) {
|
||||
function specClick(e) {
|
||||
e.stopPropagation();
|
||||
setItemUnequip(s);
|
||||
setActiveCryp(cryp);
|
||||
setActiveConstruct(construct);
|
||||
}
|
||||
|
||||
function specDblClick(e) {
|
||||
sendUnequip(cryp.id, s);
|
||||
setActiveCryp(null);
|
||||
sendUnequip(construct.id, s);
|
||||
setActiveConstruct(null);
|
||||
setItemUnequip(null);
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
@ -183,14 +183,14 @@ function Cryp(props) {
|
||||
const stats = Object.values(STATS).map(s => (
|
||||
<figure key={s.stat} alt={s.stat} className={s.stat}>
|
||||
{s.svg(`stat-icon ${s.colour} stat`)}
|
||||
<figcaption>{cryp[s.stat].value}</figcaption>
|
||||
<figcaption>{construct[s.stat].value}</figcaption>
|
||||
</figure>
|
||||
));
|
||||
const activeId = activeCryp ? activeCryp.id : false;
|
||||
const crypClass = activeId === cryp.id ? 'instance-cryp-active' : 'instance-cryp';
|
||||
const activeId = activeConstruct ? activeConstruct.id : false;
|
||||
const constructClass = activeId === construct.id ? 'instance-construct-active' : 'instance-construct';
|
||||
|
||||
// const cTotal = cryp.colours.red + cryp.colours.blue + cryp.colours.green;
|
||||
// const colours = mapValues(cryp.colours, c => {
|
||||
// const cTotal = construct.colours.red + construct.colours.blue + construct.colours.green;
|
||||
// const colours = mapValues(construct.colours, c => {
|
||||
// if (cTotal === 0) return 245;
|
||||
// return Math.floor(c / cTotal * 255);
|
||||
// });
|
||||
@ -204,18 +204,18 @@ function Cryp(props) {
|
||||
// const border = { border: `${thickness(cTotal)}px solid rgba(${colours.red}, ${colours.green}, ${colours.blue}, ${alpha})` };
|
||||
|
||||
return (
|
||||
<div key={cryp.id} className={crypClass} onClick={onClick} >
|
||||
{instanceCryp(cryp.name, cryp.id)}
|
||||
<h2 className="name" >{cryp.name}</h2>
|
||||
<div className="skills" onMouseOver={e => hoverInfo(e, 'crypSkills')} >
|
||||
<div key={construct.id} className={constructClass} onClick={onClick} >
|
||||
{instanceConstruct(construct.name, construct.id)}
|
||||
<h2 className="name" >{construct.name}</h2>
|
||||
<div className="skills" onMouseOver={e => hoverInfo(e, 'constructSkills')} >
|
||||
{skills}
|
||||
</div>
|
||||
<div className="specs" onMouseOver={e => hoverInfo(e, 'crypSpecs')} >
|
||||
<div className="specs" onMouseOver={e => hoverInfo(e, 'constructSpecs')} >
|
||||
{specs}
|
||||
</div>
|
||||
<div className="stats">
|
||||
<div className="damage-label label">
|
||||
Damage
|
||||
Power
|
||||
</div>
|
||||
<div className="speed-label label">
|
||||
Speed
|
||||
@ -231,15 +231,15 @@ function Cryp(props) {
|
||||
);
|
||||
}
|
||||
|
||||
function InstanceCryps(props) {
|
||||
function InstanceConstructs(props) {
|
||||
const {
|
||||
activeCryp,
|
||||
activeConstruct,
|
||||
itemEquip,
|
||||
player,
|
||||
instance,
|
||||
// clearInfo,
|
||||
setInfo,
|
||||
setActiveCryp,
|
||||
setActiveConstruct,
|
||||
|
||||
sendVboxApply,
|
||||
itemInfo,
|
||||
@ -252,27 +252,27 @@ function InstanceCryps(props) {
|
||||
if (!player) return false;
|
||||
if (instance.phase === 'Lobby') return false;
|
||||
|
||||
const cryps = player.cryps.map((c, i) => Cryp({
|
||||
cryp: c,
|
||||
activeCryp,
|
||||
const constructs = player.constructs.map((c, i) => Construct({
|
||||
construct: c,
|
||||
activeConstruct,
|
||||
itemEquip,
|
||||
setItemUnequip,
|
||||
setItemEquip,
|
||||
player,
|
||||
sendVboxApply,
|
||||
setInfo,
|
||||
setActiveCryp,
|
||||
setActiveConstruct,
|
||||
itemInfo,
|
||||
setVboxHighlight,
|
||||
sendUnequip,
|
||||
}));
|
||||
|
||||
const classes = `cryp-list`;
|
||||
const classes = `construct-list`;
|
||||
return (
|
||||
<div className={classes} onClick={() => setActiveCryp(null)}>
|
||||
{cryps}
|
||||
<div className={classes} onClick={() => setActiveConstruct(null)}>
|
||||
{constructs}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = addState(InstanceCryps);
|
||||
module.exports = addState(InstanceConstructs);
|
||||
@ -6,9 +6,9 @@ const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, team } = state;
|
||||
|
||||
function sendInstanceNew(sCryps, name, players) {
|
||||
if (sCryps.length) {
|
||||
return ws.sendInstanceNew(sCryps, name, players);
|
||||
function sendInstanceNew(sConstructs, name, players) {
|
||||
if (sConstructs.length) {
|
||||
return ws.sendInstanceNew(sConstructs, name, players);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -8,14 +8,14 @@ const { convertItem, SPECS } = require('./../utils');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { account, activeCryp, itemInfo, info, ws, instance, itemUnequip } = state;
|
||||
const { account, activeConstruct, itemInfo, info, ws, instance, itemUnequip } = state;
|
||||
const player = instance.players.find(p => p.id === account.id);
|
||||
|
||||
function sendUnequip(crypId, item) {
|
||||
return ws.sendVboxUnequip(instance.id, crypId, item);
|
||||
function sendUnequip(constructId, item) {
|
||||
return ws.sendVboxUnequip(instance.id, constructId, item);
|
||||
}
|
||||
|
||||
return { player, itemInfo, instance, info, sendUnequip, activeCryp, itemUnequip };
|
||||
return { player, itemInfo, instance, info, sendUnequip, activeConstruct, itemUnequip };
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
@ -48,7 +48,7 @@ function Equipment(props) {
|
||||
itemUnequip,
|
||||
setItemEquip,
|
||||
setItemUnequip,
|
||||
activeCryp,
|
||||
activeConstruct,
|
||||
|
||||
itemInfo,
|
||||
sendUnequip,
|
||||
@ -65,7 +65,7 @@ function Equipment(props) {
|
||||
const isSpec = fullInfo && fullInfo.spec;
|
||||
|
||||
function skillClick(e, i) {
|
||||
if (itemUnequip && activeCryp) return false;
|
||||
if (itemUnequip && activeConstruct) return false;
|
||||
const value = vbox.bound[i];
|
||||
setItemEquip(i);
|
||||
return false;
|
||||
@ -74,9 +74,9 @@ function Equipment(props) {
|
||||
function unequipClick(e) {
|
||||
e.stopPropagation();
|
||||
if (!itemUnequip) return false;
|
||||
if (!activeCryp) return false;
|
||||
if (!activeConstruct) return false;
|
||||
setItemUnequip(null);
|
||||
return sendUnequip(activeCryp.id, itemUnequip);
|
||||
return sendUnequip(activeConstruct.id, itemUnequip);
|
||||
}
|
||||
|
||||
function hoverInfo(e, info) {
|
||||
|
||||
@ -7,7 +7,7 @@ const InstanceCreateForm = require('./instance.create.form');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, cryps, team, instances, account } = state;
|
||||
const { ws, constructs, team, instances, account } = state;
|
||||
|
||||
function sendInstanceJoin(instance) {
|
||||
if (team.length) {
|
||||
@ -26,7 +26,7 @@ const addState = connect(
|
||||
|
||||
return {
|
||||
account,
|
||||
cryps,
|
||||
constructs,
|
||||
team,
|
||||
sendInstanceJoin,
|
||||
sendInstanceState,
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
// eslint-disable-next-line
|
||||
const preact = require('preact');
|
||||
const { useState } = require('preact/hooks');
|
||||
|
||||
function renderLogin({ submitLogin, submitRegister, submitDemo }) {
|
||||
const details = {
|
||||
name: '',
|
||||
password: '',
|
||||
};
|
||||
function renderLogin({ submitLogin, submitRegister }) {
|
||||
const [name, setName] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
return (
|
||||
<div className="login">
|
||||
@ -13,28 +12,28 @@ function renderLogin({ submitLogin, submitRegister, submitDemo }) {
|
||||
className="login-input"
|
||||
type="email"
|
||||
placeholder="username"
|
||||
onChange={e => (details.name = e.target.value)}
|
||||
onInput={e => setName(e.target.value)}
|
||||
/>
|
||||
<input
|
||||
className="login-input"
|
||||
type="password"
|
||||
placeholder="password"
|
||||
onChange={e => (details.password = e.target.value)}
|
||||
onInput={e => setPassword(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
className="login-btn"
|
||||
onClick={() => submitLogin(details.name, details.password)}>
|
||||
onClick={() => submitLogin(name, password)}>
|
||||
Login
|
||||
</button>
|
||||
<button
|
||||
className="login-btn"
|
||||
onClick={() => submitRegister(details.name, details.password)}>
|
||||
onClick={() => submitRegister(name, password)}>
|
||||
Register
|
||||
</button>
|
||||
<button
|
||||
className="login-btn"
|
||||
onClick={() => submitDemo()}>
|
||||
demo
|
||||
onClick={() => document.location.assign('https://discord.gg/YJJgurM')}>
|
||||
Discord + Invites
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -9,12 +9,10 @@ const addState = connect(
|
||||
return ws.sendAccountLogin(name, password);
|
||||
}
|
||||
function submitRegister(name, password) {
|
||||
console.log(name, password);
|
||||
return ws.sendAccountCreate(name, password);
|
||||
}
|
||||
function submitDemo() {
|
||||
return ws.sendAccountDemo();
|
||||
}
|
||||
return { account: state.account, submitLogin, submitRegister, submitDemo };
|
||||
return { account: state.account, submitLogin, submitRegister };
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ const range = require('lodash/range');
|
||||
|
||||
const { NULL_UUID } = require('./../utils');
|
||||
|
||||
const { stringSort, crypAvatar } = require('./../utils');
|
||||
const { stringSort, constructAvatar } = require('./../utils');
|
||||
const SpawnButton = require('./spawn.button');
|
||||
|
||||
const InstanceCreateForm = require('./instance.create.form');
|
||||
@ -19,14 +19,14 @@ const COLOURS = [
|
||||
function Menu(args) {
|
||||
const {
|
||||
account,
|
||||
cryps,
|
||||
constructs,
|
||||
team,
|
||||
setTeam,
|
||||
sendInstanceState,
|
||||
sendPlayerMmCrypsSet,
|
||||
sendPlayerMmConstructsSet,
|
||||
sendInstanceJoin,
|
||||
sendInstanceList,
|
||||
sendCrypSpawn,
|
||||
sendConstructSpawn,
|
||||
instances,
|
||||
} = args;
|
||||
|
||||
@ -61,7 +61,7 @@ function Menu(args) {
|
||||
// <button
|
||||
// className={'menu-instance-btn left'}
|
||||
// disabled={instanceJoinHidden}
|
||||
// onClick={() => sendPlayerMmCrypsSet()}>
|
||||
// onClick={() => sendPlayerMmConstructsSet()}>
|
||||
// Set Matchmaking Team
|
||||
// </button>
|
||||
// );
|
||||
@ -88,12 +88,12 @@ function Menu(args) {
|
||||
);
|
||||
}
|
||||
|
||||
function crypList() {
|
||||
if (!cryps) return <div></div>;
|
||||
function constructList() {
|
||||
if (!constructs) return <div></div>;
|
||||
|
||||
// redux limitation + suggested workaround
|
||||
// so much for dumb components
|
||||
function selectCryp(id) {
|
||||
function selectConstruct(id) {
|
||||
// remove
|
||||
const i = team.findIndex(sid => sid === id);
|
||||
if (i > -1) {
|
||||
@ -108,37 +108,37 @@ function Menu(args) {
|
||||
return setTeam(team);
|
||||
}
|
||||
|
||||
const crypPanels = cryps.sort(idSort).map(cryp => {
|
||||
const colour = team.indexOf(cryp.id);
|
||||
const constructPanels = constructs.sort(idSort).map(construct => {
|
||||
const colour = team.indexOf(construct.id);
|
||||
const selected = colour > -1;
|
||||
|
||||
const borderColour = selected ? COLOURS[colour] : '#000000';
|
||||
|
||||
return (
|
||||
<div
|
||||
key={cryp.id}
|
||||
className="menu-cryp-ctr">
|
||||
key={construct.id}
|
||||
className="menu-construct-ctr">
|
||||
<div
|
||||
className="menu-cryp"
|
||||
className="menu-construct"
|
||||
style={ { 'border-color': borderColour || 'whitesmoke' } }
|
||||
onClick={() => selectCryp(cryp.id)} >
|
||||
{crypAvatar(cryp.name)}
|
||||
<h2>{cryp.name}</h2>
|
||||
onClick={() => selectConstruct(construct.id)} >
|
||||
{constructAvatar(construct.name)}
|
||||
<h2>{construct.name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const spawnButtonsNum = cryps.length < 3
|
||||
? (3 - cryps.length)
|
||||
const spawnButtonsNum = constructs.length < 3
|
||||
? (3 - constructs.length)
|
||||
: 1;
|
||||
|
||||
const spawnButtons = range(spawnButtonsNum)
|
||||
.map(i => <SpawnButton key={i} i={i} spawn={name => sendCrypSpawn(name)} />);
|
||||
.map(i => <SpawnButton key={i} i={i} spawn={name => sendConstructSpawn(name)} />);
|
||||
|
||||
return (
|
||||
<div className="menu-cryps">
|
||||
{crypPanels}
|
||||
<div className="menu-constructs">
|
||||
{constructPanels}
|
||||
{spawnButtons}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -5,7 +5,7 @@ const actions = require('./../actions');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, cryps, team, instances, account } = state;
|
||||
const { ws, constructs, team, instances, account } = state;
|
||||
|
||||
function sendInstanceJoin(instance) {
|
||||
if (team.length) {
|
||||
@ -14,15 +14,15 @@ const addState = connect(
|
||||
return false;
|
||||
}
|
||||
|
||||
function sendPlayerMmCrypsSet() {
|
||||
function sendPlayerMmConstructsSet() {
|
||||
if (team.length) {
|
||||
return ws.sendPlayerMmCrypsSet(team);
|
||||
return ws.sendPlayerMmConstructsSet(team);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function sendCrypSpawn(name) {
|
||||
return ws.sendCrypSpawn(name);
|
||||
function sendConstructSpawn(name) {
|
||||
return ws.sendConstructSpawn(name);
|
||||
}
|
||||
|
||||
function sendInstanceState(instance) {
|
||||
@ -35,20 +35,20 @@ const addState = connect(
|
||||
|
||||
return {
|
||||
account,
|
||||
cryps,
|
||||
constructs,
|
||||
team,
|
||||
sendInstanceJoin,
|
||||
sendInstanceState,
|
||||
sendInstanceList,
|
||||
sendCrypSpawn,
|
||||
sendPlayerMmCrypsSet,
|
||||
sendConstructSpawn,
|
||||
sendPlayerMmConstructsSet,
|
||||
instances,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setTeam(crypIds) {
|
||||
dispatch(actions.setTeam(crypIds));
|
||||
function setTeam(constructIds) {
|
||||
dispatch(actions.setTeam(constructIds));
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
const { connect } = require('react-redux');
|
||||
const preact = require('preact');
|
||||
const { Fragment } = require('preact');
|
||||
const actions = require('../actions');
|
||||
|
||||
const testGame = require('./../test.game');
|
||||
const testInstance = require('./../test.instance');
|
||||
const testGame = process.env.NODE_ENV === 'development' && require('./../test.game');
|
||||
const testInstance = process.env.NODE_ENV === 'development' && require('./../test.instance');
|
||||
|
||||
console.log('env', process.env.NODE_ENV);
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
@ -12,7 +15,7 @@ const addState = connect(
|
||||
account,
|
||||
instances,
|
||||
team,
|
||||
cryps,
|
||||
constructs,
|
||||
game,
|
||||
} = state;
|
||||
|
||||
@ -24,7 +27,7 @@ const addState = connect(
|
||||
account,
|
||||
instances,
|
||||
team,
|
||||
cryps,
|
||||
constructs,
|
||||
game,
|
||||
sendInstanceState,
|
||||
};
|
||||
@ -57,7 +60,7 @@ function Nav(args) {
|
||||
account,
|
||||
sendInstanceState,
|
||||
team,
|
||||
cryps,
|
||||
constructs,
|
||||
instances,
|
||||
game,
|
||||
|
||||
@ -78,12 +81,21 @@ function Nav(args) {
|
||||
|
||||
const teamElements = team.map((c, i) => {
|
||||
if (c) {
|
||||
const cryp = cryps.find(f => f.id === c);
|
||||
return <button key={c} onClick={() => navTo('team')}>{cryp.name}</button>;
|
||||
const construct = constructs.find(f => f.id === c);
|
||||
return <button key={c} onClick={() => navTo('team')}>{construct.name}</button>;
|
||||
}
|
||||
return <button key={i} onClick={() => navTo('team')}>+</button>;
|
||||
});
|
||||
|
||||
const haxSection = process.env.NODE_ENV === 'development'
|
||||
? (
|
||||
<Fragment>
|
||||
<h2>Hax</h2>
|
||||
<button onClick={() => setTestGame(account.id)}>Test Game</button>
|
||||
<button onClick={() => setTestInstance(account.id)}>Test Instance</button>
|
||||
</Fragment>)
|
||||
: null;
|
||||
|
||||
return (
|
||||
<nav>
|
||||
<h2>Team</h2>
|
||||
@ -93,9 +105,7 @@ function Nav(args) {
|
||||
<button onClick={() => navTo('list')}>2. Join</button>
|
||||
<hr />
|
||||
{joined}
|
||||
<h2>Hax</h2>
|
||||
<button onClick={() => setTestGame(account.id)}>Test Game</button>
|
||||
<button onClick={() => setTestInstance(account.id)}>Test Instance</button>
|
||||
{haxSection}
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
|
||||
@ -17,8 +17,8 @@ const addState = connect(
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setActiveSkill(crypId, skill) {
|
||||
dispatch(actions.setActiveSkill(crypId, skill));
|
||||
function setActiveSkill(constructId, skill) {
|
||||
dispatch(actions.setActiveSkill(constructId, skill));
|
||||
}
|
||||
|
||||
return { setActiveSkill };
|
||||
@ -28,7 +28,7 @@ const addState = connect(
|
||||
|
||||
function Skill(props) {
|
||||
const {
|
||||
cryp,
|
||||
construct,
|
||||
game,
|
||||
i,
|
||||
mobile,
|
||||
@ -36,14 +36,14 @@ function Skill(props) {
|
||||
setActiveSkill,
|
||||
} = props;
|
||||
|
||||
const s = cryp.skills[i];
|
||||
const ko = cryp.green_life.value === 0 ? 'ko' : '';
|
||||
const s = construct.skills[i];
|
||||
const ko = construct.green_life.value === 0 ? 'ko' : '';
|
||||
|
||||
if (!s) {
|
||||
return (
|
||||
<button
|
||||
disabled='true'
|
||||
className='cryp-skill-btn disabled'>
|
||||
className='construct-skill-btn disabled'>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
@ -52,25 +52,25 @@ function Skill(props) {
|
||||
? 'top'
|
||||
: '';
|
||||
|
||||
const cdText = cryp.skills[i].cd > 0
|
||||
const cdText = construct.skills[i].cd > 0
|
||||
? `- ${s.cd}T`
|
||||
: '';
|
||||
|
||||
const highlight = activeSkill
|
||||
? activeSkill.crypId === cryp.id && activeSkill.skill === s.skill
|
||||
? activeSkill.constructId === construct.id && activeSkill.skill === s.skill
|
||||
: false;
|
||||
|
||||
function onClick(e) {
|
||||
e.stopPropagation();
|
||||
return setActiveSkill(cryp.id, s.skill);
|
||||
return setActiveSkill(construct.id, s.skill);
|
||||
}
|
||||
|
||||
const targeting = game.stack.some(stack => stack.source_cryp_id === cryp.id && stack.skill === s.skill);
|
||||
const targeting = game.stack.some(stack => stack.source_construct_id === construct.id && stack.skill === s.skill);
|
||||
|
||||
return (
|
||||
<button
|
||||
disabled={!!cdText || ko}
|
||||
className={`cryp-skill-btn ${side} ${(targeting || highlight) ? 'active' : ''}`}
|
||||
className={`construct-skill-btn ${side} ${(targeting || highlight) ? 'active' : ''}`}
|
||||
type="submit"
|
||||
onClick={onClick}>
|
||||
{s.skill} {cdText}
|
||||
|
||||
@ -13,7 +13,6 @@ class SpawnButton extends Component {
|
||||
}
|
||||
|
||||
handleInput(event) {
|
||||
console.log(event.target.value);
|
||||
this.setState({ value: event.target.value });
|
||||
}
|
||||
|
||||
@ -31,9 +30,9 @@ class SpawnButton extends Component {
|
||||
return (
|
||||
<div
|
||||
key={this.props.i}
|
||||
className="menu-cryp-ctr spawn-btn">
|
||||
className="menu-construct-ctr spawn-btn">
|
||||
<div
|
||||
className="menu-cryp"
|
||||
className="menu-construct"
|
||||
onClick={() => this.enable()} >
|
||||
<h2>+</h2>
|
||||
<input
|
||||
|
||||
@ -11,17 +11,17 @@ function TargetSvg(args) {
|
||||
const playerTeam = game.players.find(t => t.id === account.id);
|
||||
const otherTeam = game.players.find(t => t.id !== account.id);
|
||||
|
||||
const playerTeamIds = playerTeam.cryps.map(c => c.id);
|
||||
const outgoing = game.stack.filter(stack => playerTeamIds.includes(stack.source_cryp_id));
|
||||
const playerTeamIds = playerTeam.constructs.map(c => c.id);
|
||||
const outgoing = game.stack.filter(stack => playerTeamIds.includes(stack.source_construct_id));
|
||||
|
||||
function getPath(cast) {
|
||||
const source = playerTeam.cryps.findIndex(c => c.id === cast.source_cryp_id);
|
||||
const defensive = playerTeamIds.includes(cast.target_cryp_id);
|
||||
const source = playerTeam.constructs.findIndex(c => c.id === cast.source_construct_id);
|
||||
const defensive = playerTeamIds.includes(cast.target_construct_id);
|
||||
const target = defensive
|
||||
? playerTeam.cryps.findIndex(c => c.id === cast.target_cryp_id)
|
||||
: otherTeam.cryps.findIndex(c => c.id === cast.target_cryp_id);
|
||||
? playerTeam.constructs.findIndex(c => c.id === cast.target_construct_id)
|
||||
: otherTeam.constructs.findIndex(c => c.id === cast.target_construct_id);
|
||||
|
||||
const skillIndex = playerTeam.cryps[source].skills.findIndex(s => s.skill === cast.skill);
|
||||
const skillIndex = playerTeam.constructs[source].skills.findIndex(s => s.skill === cast.skill);
|
||||
|
||||
const skillOffset = (100 * skillIndex) + 50;
|
||||
const sourceY = 0;
|
||||
|
||||
@ -4,7 +4,7 @@ const range = require('lodash/range');
|
||||
|
||||
const actions = require('./../actions');
|
||||
const { NULL_UUID } = require('./../utils');
|
||||
const { stringSort, crypAvatar } = require('./../utils');
|
||||
const { stringSort, constructAvatar } = require('./../utils');
|
||||
const SpawnButton = require('./spawn.button');
|
||||
|
||||
const idSort = stringSort('id');
|
||||
@ -17,23 +17,23 @@ const COLOURS = [
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const { ws, cryps, team, account } = state;
|
||||
const { ws, constructs, team, account } = state;
|
||||
|
||||
function sendCrypSpawn(name) {
|
||||
return ws.sendCrypSpawn(name);
|
||||
function sendConstructSpawn(name) {
|
||||
return ws.sendConstructSpawn(name);
|
||||
}
|
||||
|
||||
return {
|
||||
account,
|
||||
cryps,
|
||||
constructs,
|
||||
team,
|
||||
sendCrypSpawn,
|
||||
sendConstructSpawn,
|
||||
};
|
||||
},
|
||||
|
||||
function receiveDispatch(dispatch) {
|
||||
function setTeam(crypIds) {
|
||||
dispatch(actions.setTeam(crypIds));
|
||||
function setTeam(constructIds) {
|
||||
dispatch(actions.setTeam(constructIds));
|
||||
}
|
||||
|
||||
function navToList() {
|
||||
@ -53,19 +53,19 @@ const addState = connect(
|
||||
function Team(args) {
|
||||
const {
|
||||
account,
|
||||
cryps,
|
||||
constructs,
|
||||
team,
|
||||
|
||||
setTeam,
|
||||
sendCrypSpawn,
|
||||
sendConstructSpawn,
|
||||
navToList,
|
||||
} = args;
|
||||
|
||||
if (!cryps) return <div></div>;
|
||||
if (!constructs) return <div></div>;
|
||||
|
||||
// redux limitation + suggested workaround
|
||||
// so much for dumb components
|
||||
function selectCryp(id) {
|
||||
function selectConstruct(id) {
|
||||
// remove
|
||||
const i = team.findIndex(sid => sid === id);
|
||||
if (i > -1) {
|
||||
@ -80,31 +80,31 @@ function Team(args) {
|
||||
return setTeam(team);
|
||||
}
|
||||
|
||||
const crypPanels = cryps.sort(idSort).map(cryp => {
|
||||
const colour = team.indexOf(cryp.id);
|
||||
const constructPanels = constructs.sort(idSort).map(construct => {
|
||||
const colour = team.indexOf(construct.id);
|
||||
const selected = colour > -1;
|
||||
|
||||
const borderColour = selected ? COLOURS[colour] : '#000000';
|
||||
|
||||
return (
|
||||
<div
|
||||
key={cryp.id}
|
||||
className="menu-cryp-ctr">
|
||||
key={construct.id}
|
||||
className="menu-construct-ctr">
|
||||
<div
|
||||
className="menu-cryp"
|
||||
className="menu-construct"
|
||||
style={ { 'border-color': borderColour || 'whitesmoke' } }
|
||||
onClick={() => selectCryp(cryp.id)} >
|
||||
{crypAvatar(cryp.name, cryp.id)}
|
||||
<h2>{cryp.name}</h2>
|
||||
onClick={() => selectConstruct(construct.id)} >
|
||||
{constructAvatar(construct.name, construct.id)}
|
||||
<h2>{construct.name}</h2>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
const spawnButtonsNum = (3 - cryps.length % 3);
|
||||
const spawnButtonsNum = (3 - constructs.length % 3);
|
||||
|
||||
const spawnButtons = range(spawnButtonsNum)
|
||||
.map(i => <SpawnButton key={i} i={i} spawn={name => sendCrypSpawn(name)} />);
|
||||
.map(i => <SpawnButton key={i} i={i} spawn={name => sendConstructSpawn(name)} />);
|
||||
|
||||
|
||||
const header = (
|
||||
@ -119,10 +119,10 @@ function Team(args) {
|
||||
);
|
||||
|
||||
return (
|
||||
<main className="menu-cryps">
|
||||
<main className="menu-constructs">
|
||||
{header}
|
||||
<div className="list">
|
||||
{crypPanels}
|
||||
{constructPanels}
|
||||
{spawnButtons}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@ -45,19 +45,19 @@ module.exports = {
|
||||
},
|
||||
equipSkills: {
|
||||
item: 'QUICK ACCESS - SKILLS',
|
||||
description: 'Click to select \nClick target CRYP to equip',
|
||||
description: 'Click to select \nClick target CONSTRUCT to equip',
|
||||
},
|
||||
equipSpecs: {
|
||||
item: 'QUICK ACCESS - SPECS',
|
||||
description: 'Click to select \nClick target CRYP to equip',
|
||||
description: 'Click to select \nClick target CONSTRUCT to equip',
|
||||
},
|
||||
crypSkills: {
|
||||
constructSkills: {
|
||||
item: 'SKILLS',
|
||||
description: 'Skills are used by Cryps in-game.\nClick a SKILL above and select a CRYP to equip.\nDouble-click to unequip.',
|
||||
description: 'Skills are used by Constructs in-game.\nClick a SKILL above and select a CONSTRUCT to equip.\nDouble-click to unequip.',
|
||||
},
|
||||
crypSpecs: {
|
||||
constructSpecs: {
|
||||
item: 'SPECS',
|
||||
description: 'SPECS increase the STATS of a CRYP.\nSPECS have increased effect once they reach a THRESHOLD across your whole team.\nClick a SPEC above and select a CRYP to equip.\nDouble-click to unequip.',
|
||||
description: 'SPECS increase the STATS of a CONSTRUCT.\nSPECS have increased effect once they reach a THRESHOLD across your whole team.\nClick a SPEC above and select a CONSTRUCT to equip.\nDouble-click to unequip.',
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
@ -3,13 +3,13 @@ const eachSeries = require('async/eachSeries');
|
||||
|
||||
const actions = require('./actions');
|
||||
const { TIMES } = require('./constants');
|
||||
const { getCombatSequence, resoCrypHealth } = require('./utils');
|
||||
const { getCombatSequence, resoConstructHealth } = require('./utils');
|
||||
|
||||
function registerEvents(store) {
|
||||
|
||||
// timeout handlers
|
||||
store.subscribe(() => {
|
||||
const { game, instance, cryps, ws } = store.getState();
|
||||
const { game, instance, constructs, ws } = store.getState();
|
||||
|
||||
if (!game) ws.clearGameStateTimeout();
|
||||
if (!instance) ws.clearInstanceStateTimeout();
|
||||
@ -19,12 +19,12 @@ function registerEvents(store) {
|
||||
store.dispatch(actions.setPing(ping));
|
||||
}
|
||||
|
||||
function setCryps(cryps) {
|
||||
console.log('EVENT ->', 'cryps', cryps);
|
||||
function setConstructs(constructs) {
|
||||
console.log('EVENT ->', 'constructs', constructs);
|
||||
}
|
||||
|
||||
function setCrypList(cryps) {
|
||||
store.dispatch(actions.setCryps(cryps));
|
||||
function setConstructList(constructs) {
|
||||
store.dispatch(actions.setConstructs(constructs));
|
||||
}
|
||||
|
||||
function setWs(ws) {
|
||||
@ -50,8 +50,8 @@ function registerEvents(store) {
|
||||
const stagedR = Object.create(r);
|
||||
stagedR.stage = stage;
|
||||
|
||||
// Apply damage for each cryp
|
||||
if (stage === 'POST_SKILL') resoCrypHealth(stagedR, currentGame);
|
||||
// Apply damage for each construct
|
||||
if (stage === 'POST_SKILL') resoConstructHealth(stagedR, currentGame);
|
||||
store.dispatch(actions.setResolution(stagedR));
|
||||
|
||||
return setTimeout(sCb, TIMES[stage]);
|
||||
@ -98,7 +98,7 @@ function registerEvents(store) {
|
||||
|
||||
function clearInfo() {
|
||||
store.dispatch(actions.setInfo(null));
|
||||
store.dispatch(actions.setActiveCryp(null));
|
||||
store.dispatch(actions.setActiveConstruct(null));
|
||||
console.log('event clear item');
|
||||
}
|
||||
|
||||
@ -132,8 +132,8 @@ function registerEvents(store) {
|
||||
console.log('EVENT ->', 'gameList', gameList);
|
||||
}
|
||||
|
||||
function setCrypStatusUpdate(id, skill, target) {
|
||||
console.log('EVENT ->', 'crypStatusUpdate', { id, skill, target });
|
||||
function setConstructStatusUpdate(id, skill, target) {
|
||||
console.log('EVENT ->', 'constructStatusUpdate', { id, skill, target });
|
||||
}
|
||||
|
||||
function setItemInfo(v) {
|
||||
@ -142,22 +142,22 @@ function registerEvents(store) {
|
||||
|
||||
// events.on('SET_PLAYER', setInstance);
|
||||
|
||||
// events.on('SEND_SKILL', function skillActive(gameId, crypId, targetCrypId, skill) {
|
||||
// ws.sendGameSkill(gameId, crypId, targetCrypId, skill);
|
||||
// setCrypStatusUpdate(crypId, skill, targetCrypId);
|
||||
// events.on('SEND_SKILL', function skillActive(gameId, constructId, targetConstructId, skill) {
|
||||
// ws.sendGameSkill(gameId, constructId, targetConstructId, skill);
|
||||
// setConstructStatusUpdate(constructId, skill, targetConstructId);
|
||||
// });
|
||||
|
||||
// events.on('CRYP_ACTIVE', function crypActiveCb(cryp) {
|
||||
// for (let i = 0; i < cryps.length; i += 1) {
|
||||
// if (cryps[i].id === cryp.id) cryps[i].active = !cryps[i].active;
|
||||
// events.on('CONSTRUCT_ACTIVE', function constructActiveCb(construct) {
|
||||
// for (let i = 0; i < constructs.length; i += 1) {
|
||||
// if (constructs[i].id === construct.id) constructs[i].active = !constructs[i].active;
|
||||
// }
|
||||
// return setCryps(cryps);
|
||||
// return setConstructs(constructs);
|
||||
// });
|
||||
|
||||
const errMessages = {
|
||||
select_cryps: 'Select your cryps before battle using the numbered buttons next to the cryp avatar',
|
||||
select_constructs: 'Select your constructs before battle using the numbered buttons next to the construct avatar',
|
||||
complete_nodes: 'You need to complete the previously connected nodes first',
|
||||
max_skills: 'Your cryp can only learn a maximum of 4 skills',
|
||||
max_skills: 'Your construct can only learn a maximum of 4 skills',
|
||||
|
||||
};
|
||||
|
||||
@ -185,8 +185,8 @@ function registerEvents(store) {
|
||||
setAccount,
|
||||
setActiveSkill,
|
||||
setActiveItem,
|
||||
setCryps,
|
||||
setCrypList,
|
||||
setConstructs,
|
||||
setConstructList,
|
||||
setGame,
|
||||
clearInfo,
|
||||
setMenu,
|
||||
|
||||
@ -7,7 +7,7 @@ function setupKeys(store) {
|
||||
key('esc', () => store.dispatch(actions.setCombiner([null, null, null])));
|
||||
key('esc', () => store.dispatch(actions.setReclaiming(false)));
|
||||
key('esc', () => store.dispatch(actions.setActiveSkill(null)));
|
||||
key('esc', () => store.dispatch(actions.setActiveCryp(null)));
|
||||
key('esc', () => store.dispatch(actions.setActiveConstruct(null)));
|
||||
key('esc', () => store.dispatch(actions.setInfo(null)));
|
||||
key('esc', () => store.dispatch(actions.setItemEquip(null)));
|
||||
key('esc', () => store.dispatch(actions.setItemUnequip(null)));
|
||||
|
||||
@ -12,11 +12,11 @@ function createReducer(defaultState, actionType) {
|
||||
/* eslint-disable key-spacing */
|
||||
module.exports = {
|
||||
account: createReducer(null, 'SET_ACCOUNT'),
|
||||
activeCryp: createReducer(null, 'SET_ACTIVE_CRYP'),
|
||||
activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'),
|
||||
activeItem: createReducer(null, 'SET_ACTIVE_VAR'),
|
||||
activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'),
|
||||
combiner: createReducer([null, null, null], 'SET_COMBINER'),
|
||||
cryps: createReducer([], 'SET_CRYPS'),
|
||||
constructs: createReducer([], 'SET_CONSTRUCTS'),
|
||||
game: createReducer(null, 'SET_GAME'),
|
||||
info: createReducer(null, 'SET_INFO'),
|
||||
instance: createReducer(null, 'SET_INSTANCE'),
|
||||
@ -30,7 +30,7 @@ module.exports = {
|
||||
resolution: createReducer(null, 'SET_RESOLUTION'),
|
||||
showLog: createReducer(false, 'SET_SHOW_LOG'),
|
||||
skip: createReducer(false, 'SET_SKIP'),
|
||||
team: createReducer([null, null, null], 'SET_SELECTED_CRYPS'),
|
||||
team: createReducer([null, null, null], 'SET_SELECTED_CONSTRUCTS'),
|
||||
vboxHighlight: createReducer([], 'SET_VBOX_HIGHLIGHT'),
|
||||
ws: createReducer(null, 'SET_WS'),
|
||||
};
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
const toast = require('izitoast');
|
||||
const cbor = require('borc');
|
||||
|
||||
const SOCKET_URL = process.env.NODE_ENV === 'production' ? 'wss://cryps.gg/ws' : 'ws://localhost:40000';
|
||||
const SOCKET_URL = process.env.NODE_ENV === 'production' ? 'wss://mnml.gg/ws' : 'ws://localhost:40000';
|
||||
|
||||
function errorToast(err) {
|
||||
console.error(err);
|
||||
@ -47,12 +47,8 @@ function createSocket(events) {
|
||||
send({ method: 'account_create', params: { name, password } });
|
||||
}
|
||||
|
||||
function sendAccountDemo() {
|
||||
send({ method: 'account_demo', params: {} });
|
||||
}
|
||||
|
||||
function sendAccountCryps() {
|
||||
send({ method: 'account_cryps', params: {} });
|
||||
function sendAccountConstructs() {
|
||||
send({ method: 'account_constructs', params: {} });
|
||||
}
|
||||
|
||||
function sendAccountInstances() {
|
||||
@ -63,8 +59,8 @@ function createSocket(events) {
|
||||
send({ method: 'account_zone', params: {} });
|
||||
}
|
||||
|
||||
function sendCrypSpawn(name) {
|
||||
send({ method: 'cryp_spawn', params: { name } });
|
||||
function sendConstructSpawn(name) {
|
||||
send({ method: 'construct_spawn', params: { name } });
|
||||
}
|
||||
|
||||
function sendGameState(id) {
|
||||
@ -76,11 +72,11 @@ function createSocket(events) {
|
||||
}
|
||||
|
||||
function sendSpecForget(id, spec) {
|
||||
send({ method: 'cryp_unspec', params: { id, spec } });
|
||||
send({ method: 'construct_unspec', params: { id, spec } });
|
||||
}
|
||||
|
||||
function sendPlayerMmCrypsSet(crypIds) {
|
||||
send({ method: 'player_mm_cryps_set', params: { cryp_ids: crypIds } });
|
||||
function sendPlayerMmConstructsSet(constructIds) {
|
||||
send({ method: 'player_mm_constructs_set', params: { construct_ids: constructIds } });
|
||||
}
|
||||
|
||||
function sendInstanceState(instanceId) {
|
||||
@ -91,13 +87,13 @@ function createSocket(events) {
|
||||
send({ method: 'player_vbox_accept', params: { instance_id: instanceId, group, index } });
|
||||
}
|
||||
|
||||
function sendVboxApply(instanceId, crypId, index) {
|
||||
send({ method: 'player_vbox_apply', params: { instance_id: instanceId, cryp_id: crypId, index } });
|
||||
function sendVboxApply(instanceId, constructId, index) {
|
||||
send({ method: 'player_vbox_apply', params: { instance_id: instanceId, construct_id: constructId, index } });
|
||||
events.setActiveItem(null);
|
||||
}
|
||||
|
||||
function sendVboxUnequip(instanceId, crypId, target) {
|
||||
send({ method: 'player_vbox_unequip', params: { instance_id: instanceId, cryp_id: crypId, target } });
|
||||
function sendVboxUnequip(instanceId, constructId, target) {
|
||||
send({ method: 'player_vbox_unequip', params: { instance_id: instanceId, construct_id: constructId, target } });
|
||||
events.clearInfo();
|
||||
}
|
||||
|
||||
@ -118,18 +114,18 @@ function createSocket(events) {
|
||||
send({ method: 'item_info', params: {} });
|
||||
}
|
||||
|
||||
function sendGameSkill(gameId, crypId, targetCrypId, skill) {
|
||||
function sendGameSkill(gameId, constructId, targetConstructId, skill) {
|
||||
send({
|
||||
method: 'game_skill',
|
||||
params: {
|
||||
game_id: gameId, cryp_id: crypId, target_cryp_id: targetCrypId, skill,
|
||||
game_id: gameId, construct_id: constructId, target_construct_id: targetConstructId, skill,
|
||||
},
|
||||
});
|
||||
events.setActiveSkill(null);
|
||||
}
|
||||
|
||||
function sendGameTarget(gameId, crypId, skillId) {
|
||||
send({ method: 'game_target', params: { game_id: gameId, cryp_id: crypId, skill_id: skillId } });
|
||||
function sendGameTarget(gameId, constructId, skillId) {
|
||||
send({ method: 'game_target', params: { game_id: gameId, construct_id: constructId, skill_id: skillId } });
|
||||
events.setActiveSkill(null);
|
||||
}
|
||||
|
||||
@ -137,20 +133,20 @@ function createSocket(events) {
|
||||
send({ method: 'zone_create', params: {} });
|
||||
}
|
||||
|
||||
function sendZoneJoin(zoneId, nodeId, crypIds) {
|
||||
send({ method: 'zone_join', params: { zone_id: zoneId, node_id: nodeId, cryp_ids: crypIds } });
|
||||
function sendZoneJoin(zoneId, nodeId, constructIds) {
|
||||
send({ method: 'zone_join', params: { zone_id: zoneId, node_id: nodeId, construct_ids: constructIds } });
|
||||
}
|
||||
|
||||
function sendZoneClose(zoneId) {
|
||||
send({ method: 'zone_close', params: { zone_id: zoneId } });
|
||||
}
|
||||
|
||||
function sendInstanceJoin(instanceId, cryps) {
|
||||
send({ method: 'instance_join', params: { instance_id: instanceId, cryp_ids: cryps } });
|
||||
function sendInstanceJoin(instanceId, constructs) {
|
||||
send({ method: 'instance_join', params: { instance_id: instanceId, construct_ids: constructs } });
|
||||
}
|
||||
|
||||
function sendInstanceNew(cryps, name, players) {
|
||||
send({ method: 'instance_new', params: { cryp_ids: cryps, name, players } });
|
||||
function sendInstanceNew(constructs, name, players) {
|
||||
send({ method: 'instance_new', params: { construct_ids: constructs, name, players } });
|
||||
}
|
||||
|
||||
function sendInstanceReady(instanceId) {
|
||||
@ -171,7 +167,7 @@ function createSocket(events) {
|
||||
account = login;
|
||||
localStorage.setItem('account', JSON.stringify(login));
|
||||
events.setAccount(login);
|
||||
sendAccountCryps();
|
||||
sendAccountConstructs();
|
||||
sendAccountInstances();
|
||||
}
|
||||
|
||||
@ -180,9 +176,9 @@ function createSocket(events) {
|
||||
events.setInstanceList(playerList);
|
||||
}
|
||||
|
||||
function accountCryps(response) {
|
||||
const [structName, cryps] = response;
|
||||
events.setCrypList(cryps);
|
||||
function accountConstructs(response) {
|
||||
const [structName, constructs] = response;
|
||||
events.setConstructList(constructs);
|
||||
}
|
||||
|
||||
function gameState(response) {
|
||||
@ -201,8 +197,8 @@ function createSocket(events) {
|
||||
clearTimeout(gameStateTimeout);
|
||||
}
|
||||
|
||||
function crypSpawn(response) {
|
||||
const [structName, cryp] = response;
|
||||
function constructSpawn(response) {
|
||||
const [structName, construct] = response;
|
||||
}
|
||||
|
||||
function zoneState(response) {
|
||||
@ -244,11 +240,11 @@ function createSocket(events) {
|
||||
// when the server sends a reply it will have one of these message types
|
||||
// this object wraps the reply types to a function
|
||||
const handlers = {
|
||||
cryp_spawn: crypSpawn,
|
||||
construct_spawn: constructSpawn,
|
||||
game_state: gameState,
|
||||
account_login: accountLogin,
|
||||
account_create: accountLogin,
|
||||
account_cryps: accountCryps,
|
||||
account_constructs: accountConstructs,
|
||||
account_instances: accountInstanceList,
|
||||
zone_create: res => console.log(res),
|
||||
zone_state: zoneState,
|
||||
@ -268,9 +264,9 @@ function createSocket(events) {
|
||||
switch (error) {
|
||||
case 'invalid token': return logout();
|
||||
case 'no active zone': return sendZoneCreate();
|
||||
case 'no cryps selected': return events.errorPrompt('select_cryps');
|
||||
case 'no constructs selected': return events.errorPrompt('select_constructs');
|
||||
case 'node requirements not met': return events.errorPrompt('complete_nodes');
|
||||
case 'cryp at max skills (4)': return events.errorPrompt('max_skills');
|
||||
case 'construct at max skills (4)': return events.errorPrompt('max_skills');
|
||||
|
||||
default: return errorToast(error);
|
||||
|
||||
@ -307,7 +303,7 @@ function createSocket(events) {
|
||||
if (account) {
|
||||
events.setAccount(account);
|
||||
sendAccountInstances();
|
||||
sendAccountCryps();
|
||||
sendAccountConstructs();
|
||||
setTimeout(sendItemInfo, 2000);
|
||||
}
|
||||
|
||||
@ -342,15 +338,14 @@ function createSocket(events) {
|
||||
clearInstanceStateTimeout,
|
||||
sendAccountLogin,
|
||||
sendAccountCreate,
|
||||
sendAccountDemo,
|
||||
sendAccountCryps,
|
||||
sendAccountConstructs,
|
||||
sendAccountInstances,
|
||||
sendAccountZone,
|
||||
sendGameState,
|
||||
sendGameReady,
|
||||
sendGameSkill,
|
||||
sendGameTarget,
|
||||
sendCrypSpawn,
|
||||
sendConstructSpawn,
|
||||
sendSpecForget,
|
||||
sendZoneCreate,
|
||||
sendZoneJoin,
|
||||
@ -359,7 +354,7 @@ function createSocket(events) {
|
||||
sendInstanceReady,
|
||||
sendInstanceNew,
|
||||
sendInstanceScores,
|
||||
sendPlayerMmCrypsSet,
|
||||
sendPlayerMmConstructsSet,
|
||||
sendInstanceState,
|
||||
sendVboxAccept,
|
||||
sendVboxApply,
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
function testGame(uuid) {
|
||||
return {
|
||||
"id": "667ad344-dc76-40b9-bb9c-0d20f0f7f5d2",
|
||||
"player_cryps": 3,
|
||||
"player_constructs": 3,
|
||||
"player_num": 2,
|
||||
"players": [
|
||||
{
|
||||
@ -19,9 +19,9 @@ function testGame(uuid) {
|
||||
],
|
||||
[
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life",
|
||||
"Life"
|
||||
]
|
||||
@ -32,7 +32,7 @@ function testGame(uuid) {
|
||||
"wins": 0,
|
||||
"losses": 0
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "96ca4a0e-fed2-4ea2-9ec5-ae308f8dde4b",
|
||||
"account": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1",
|
||||
@ -282,7 +282,7 @@ function testGame(uuid) {
|
||||
],
|
||||
[
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Life",
|
||||
"Speed",
|
||||
@ -295,7 +295,7 @@ function testGame(uuid) {
|
||||
"wins": 0,
|
||||
"losses": 0
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd",
|
||||
"account": uuid,
|
||||
@ -543,8 +543,8 @@ function testGame(uuid) {
|
||||
{
|
||||
"id": "15ef2068-0eec-4eda-b2b2-5abe78e4ff9a",
|
||||
"source_player_id": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1",
|
||||
"source_cryp_id": "96ca4a0e-fed2-4ea2-9ec5-ae308f8dde4b",
|
||||
"target_cryp_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"source_construct_id": "96ca4a0e-fed2-4ea2-9ec5-ae308f8dde4b",
|
||||
"target_construct_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"skill": "Attack",
|
||||
"speed": 0,
|
||||
"resolutions": []
|
||||
@ -552,8 +552,8 @@ function testGame(uuid) {
|
||||
{
|
||||
"id": "4fbe9c95-8f40-4f65-9f0e-b77d5eb64b17",
|
||||
"source_player_id": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1",
|
||||
"source_cryp_id": "ea302c35-d326-475c-a867-8ad5b162165a",
|
||||
"target_cryp_id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd",
|
||||
"source_construct_id": "ea302c35-d326-475c-a867-8ad5b162165a",
|
||||
"target_construct_id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd",
|
||||
"skill": "Attack",
|
||||
"speed": 0,
|
||||
"resolutions": []
|
||||
@ -561,8 +561,8 @@ function testGame(uuid) {
|
||||
{
|
||||
"id": "c2f398b8-6f5a-4fda-8c8d-b1be53819040",
|
||||
"source_player_id": "8552e0bf-340d-4fc8-b6fc-3d56b68fe2a1",
|
||||
"source_cryp_id": "82e8b940-411c-42a1-8fc2-484ec7207734",
|
||||
"target_cryp_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"source_construct_id": "82e8b940-411c-42a1-8fc2-484ec7207734",
|
||||
"target_construct_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"skill": "Attack",
|
||||
"speed": 0,
|
||||
"resolutions": []
|
||||
@ -570,8 +570,8 @@ function testGame(uuid) {
|
||||
{
|
||||
"id": "6bc9c3ce-587e-4bbe-ac81-2bc536ebbce4",
|
||||
"source_player_id": uuid,
|
||||
"source_cryp_id": "5d49fe65-27f0-4372-90a3-334ef906a0f5",
|
||||
"target_cryp_id": "82e8b940-411c-42a1-8fc2-484ec7207734",
|
||||
"source_construct_id": "5d49fe65-27f0-4372-90a3-334ef906a0f5",
|
||||
"target_construct_id": "82e8b940-411c-42a1-8fc2-484ec7207734",
|
||||
"skill": "Attack",
|
||||
"speed": 0,
|
||||
"resolutions": []
|
||||
@ -579,8 +579,8 @@ function testGame(uuid) {
|
||||
{
|
||||
"id": "9d2fc857-51c7-4640-a17c-a08496480830",
|
||||
"source_player_id": uuid,
|
||||
"source_cryp_id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd",
|
||||
"target_cryp_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"source_construct_id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd",
|
||||
"target_construct_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"skill": "Attack",
|
||||
"speed": 0,
|
||||
"resolutions": []
|
||||
@ -588,8 +588,8 @@ function testGame(uuid) {
|
||||
{
|
||||
"id": "e1bd2d77-181a-4f2d-a4f6-78c9ad3c5b3b",
|
||||
"source_player_id": uuid,
|
||||
"source_cryp_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"target_cryp_id": "96ca4a0e-fed2-4ea2-9ec5-ae308f8dde4b",
|
||||
"source_construct_id": "50e5d94e-8ebe-495c-a916-3eb509ff4683",
|
||||
"target_construct_id": "96ca4a0e-fed2-4ea2-9ec5-ae308f8dde4b",
|
||||
"skill": "Attack",
|
||||
"speed": 0,
|
||||
"resolutions": []
|
||||
|
||||
@ -22,9 +22,9 @@ function testInstance(uuid) {
|
||||
"Block"
|
||||
],
|
||||
[
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed"
|
||||
]
|
||||
],
|
||||
@ -34,7 +34,7 @@ function testInstance(uuid) {
|
||||
"wins": 12,
|
||||
"losses": 4
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "32ffeb78-e69d-4796-ba16-624a8db678c1",
|
||||
"account": "681626d4-1c39-4968-a159-0921cf0fe497",
|
||||
@ -308,7 +308,7 @@ function testInstance(uuid) {
|
||||
"Attack"
|
||||
],
|
||||
[
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Life"
|
||||
]
|
||||
@ -319,7 +319,7 @@ function testInstance(uuid) {
|
||||
"wins": 13,
|
||||
"losses": 3
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "d9bb5a7f-86d4-4075-9783-c899c91b48f4",
|
||||
"account": "04e4bdbb-54d6-4d3a-9987-366520c05a04",
|
||||
@ -608,7 +608,7 @@ function testInstance(uuid) {
|
||||
"wins": 1,
|
||||
"losses": 15
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "4098d753-2196-46dc-98e0-bd5c86e3fbaa",
|
||||
"account": "cbb7a327-1cec-464d-972c-96e4298d3941",
|
||||
@ -886,7 +886,7 @@ function testInstance(uuid) {
|
||||
],
|
||||
[
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Speed"
|
||||
]
|
||||
@ -897,7 +897,7 @@ function testInstance(uuid) {
|
||||
"wins": 4,
|
||||
"losses": 12
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "b9c41633-73c1-4ce5-b9c6-3f18196b94d4",
|
||||
"account": "04a13f79-145f-4cd4-bb4c-9108637f4c04",
|
||||
@ -1174,7 +1174,7 @@ function testInstance(uuid) {
|
||||
"Debuff"
|
||||
],
|
||||
[
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life",
|
||||
"Speed",
|
||||
"Speed"
|
||||
@ -1186,7 +1186,7 @@ function testInstance(uuid) {
|
||||
"wins": 6,
|
||||
"losses": 10
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "c7106871-91b4-4e13-96c8-13cf95878896",
|
||||
"account": "d59b2bd4-01b3-4802-9e4d-d716b9f63114",
|
||||
@ -1466,7 +1466,7 @@ function testInstance(uuid) {
|
||||
"Speed",
|
||||
"Speed",
|
||||
"Speed",
|
||||
"Damage"
|
||||
"Power"
|
||||
]
|
||||
],
|
||||
"bound": []
|
||||
@ -1475,7 +1475,7 @@ function testInstance(uuid) {
|
||||
"wins": 6,
|
||||
"losses": 10
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "52e54ac6-a254-4f74-aee7-0c8df4e92133",
|
||||
"account": "64ddef5a-0af4-480d-8ed3-24e7fc3c0761",
|
||||
@ -1754,7 +1754,7 @@ function testInstance(uuid) {
|
||||
[
|
||||
"Life",
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life"
|
||||
]
|
||||
],
|
||||
@ -1764,7 +1764,7 @@ function testInstance(uuid) {
|
||||
"wins": 8,
|
||||
"losses": 8
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "13d638ba-d738-42eb-9080-e0b9c6bbccd2",
|
||||
"account": "fcdfcb93-da2e-4027-a360-7bc5a6328cd1",
|
||||
@ -2044,7 +2044,7 @@ function testInstance(uuid) {
|
||||
"Speed",
|
||||
"Life",
|
||||
"Speed",
|
||||
"Damage"
|
||||
"Power"
|
||||
]
|
||||
],
|
||||
"bound": []
|
||||
@ -2053,7 +2053,7 @@ function testInstance(uuid) {
|
||||
"wins": 11,
|
||||
"losses": 5
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "363f3902-8410-4984-bde8-cb7f77dc621f",
|
||||
"account": "1f1145ad-def5-4e0e-b4f9-97310c1a58fb",
|
||||
@ -2342,7 +2342,7 @@ function testInstance(uuid) {
|
||||
"wins": 9,
|
||||
"losses": 7
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "9c490d3e-5509-439b-b197-f6fa80b8bee5",
|
||||
"account": "eba6a766-7a95-4dc7-95a1-00a5a203921d",
|
||||
@ -2622,7 +2622,7 @@ function testInstance(uuid) {
|
||||
"Life",
|
||||
"Speed",
|
||||
"Speed",
|
||||
"Damage"
|
||||
"Power"
|
||||
]
|
||||
],
|
||||
"bound": []
|
||||
@ -2631,7 +2631,7 @@ function testInstance(uuid) {
|
||||
"wins": 9,
|
||||
"losses": 7
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "104f82e0-a053-4b77-b01b-7598998d5014",
|
||||
"account": "78531f40-7e44-4ac9-90ae-23f51c3dea5a",
|
||||
@ -2908,10 +2908,10 @@ function testInstance(uuid) {
|
||||
"Stun"
|
||||
],
|
||||
[
|
||||
"Damage",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Damage"
|
||||
"Power"
|
||||
]
|
||||
],
|
||||
"bound": []
|
||||
@ -2920,7 +2920,7 @@ function testInstance(uuid) {
|
||||
"wins": 12,
|
||||
"losses": 4
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "6f1b51bd-b9ff-4269-b92e-b9d6629650f7",
|
||||
"account": "74980fc0-c0ad-4a1d-a28e-e1f6ddc6bdc2",
|
||||
@ -3197,10 +3197,10 @@ function testInstance(uuid) {
|
||||
"Stun"
|
||||
],
|
||||
[
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Damage"
|
||||
"Power",
|
||||
"Power"
|
||||
]
|
||||
],
|
||||
"bound": []
|
||||
@ -3209,7 +3209,7 @@ function testInstance(uuid) {
|
||||
"wins": 6,
|
||||
"losses": 10
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "55116a6e-c872-464a-a470-e021cc7e80b6",
|
||||
"account": "1dc41566-262e-4a95-b5f8-b347b532acec",
|
||||
@ -3486,9 +3486,9 @@ function testInstance(uuid) {
|
||||
"Buff"
|
||||
],
|
||||
[
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life"
|
||||
]
|
||||
],
|
||||
@ -3498,7 +3498,7 @@ function testInstance(uuid) {
|
||||
"wins": 14,
|
||||
"losses": 2
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "8a34f320-ddc0-4d4b-99da-479da18fdb3a",
|
||||
"account": "43e54b00-627d-459c-9d89-931e5c163602",
|
||||
@ -3783,7 +3783,7 @@ function testInstance(uuid) {
|
||||
"wins": 15,
|
||||
"losses": 1
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "0f93d522-3dce-429d-b373-9d3c0f97c4c1",
|
||||
"account": "06e8a7b5-ca97-45cb-a8db-9aa1bfec5d23",
|
||||
@ -4068,7 +4068,7 @@ function testInstance(uuid) {
|
||||
"wins": 2,
|
||||
"losses": 14
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "ad0ba069-c20a-403e-b90e-024af247e5d6",
|
||||
"account": "a5867e13-b591-47c7-b9e8-3bd7fe56e17e",
|
||||
@ -4348,9 +4348,9 @@ function testInstance(uuid) {
|
||||
[
|
||||
"Life",
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Speed",
|
||||
"Damage",
|
||||
"Power",
|
||||
"Life"
|
||||
]
|
||||
],
|
||||
@ -4367,7 +4367,7 @@ function testInstance(uuid) {
|
||||
"wins": 0,
|
||||
"losses": 16
|
||||
},
|
||||
"cryps": [
|
||||
"constructs": [
|
||||
{
|
||||
"id": "3aa0f284-1e1b-4054-b38a-b2d50db471bd",
|
||||
"account": uuid,
|
||||
|
||||
@ -56,8 +56,34 @@ function requestAvatar(name) {
|
||||
.then(svg => svg);
|
||||
}
|
||||
|
||||
function crypAvatar(name, id) {
|
||||
useEffect(() => animateCryp(id));
|
||||
const animations = {};
|
||||
function animateConstruct(id) {
|
||||
if (animations[id]) return false;
|
||||
animations[id] = true;
|
||||
const duration = anime.random(2000, 8000);
|
||||
const target = document.getElementById(id);
|
||||
return anime({
|
||||
targets: target,
|
||||
translateX: () => anime.random(-20, 20),
|
||||
translateY: () => anime.random(0, -40),
|
||||
rotate: () => anime.random(-15, 15),
|
||||
duration,
|
||||
direction: 'alternate',
|
||||
easing: 'linear',
|
||||
loop: true,
|
||||
complete: () => animations[id] = false,
|
||||
});
|
||||
}
|
||||
|
||||
function clearAnimation(id) {
|
||||
animations[id] = false;
|
||||
}
|
||||
|
||||
function constructAvatar(name, id) {
|
||||
useEffect(() => {
|
||||
animateConstruct(id);
|
||||
return () => clearAnimation(id);
|
||||
});
|
||||
|
||||
return (
|
||||
<img
|
||||
@ -69,8 +95,11 @@ function crypAvatar(name, id) {
|
||||
);
|
||||
}
|
||||
|
||||
function instanceCryp(name, id) {
|
||||
useEffect(() => animateCryp(id));
|
||||
function instanceConstruct(name, id) {
|
||||
useEffect(() => {
|
||||
animateConstruct(id);
|
||||
return () => clearAnimation(id);
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
@ -84,18 +113,18 @@ function instanceCryp(name, id) {
|
||||
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
const STATS = {
|
||||
redDamage: {
|
||||
stat: 'red_damage',
|
||||
redPower: {
|
||||
stat: 'red_power',
|
||||
colour: 'red',
|
||||
svg: shapes.circle,
|
||||
},
|
||||
greenDamage: {
|
||||
stat: 'green_damage',
|
||||
greenPower: {
|
||||
stat: 'green_power',
|
||||
colour: 'green',
|
||||
svg: shapes.circle,
|
||||
},
|
||||
blueDamage: {
|
||||
stat: 'blue_damage',
|
||||
bluePower: {
|
||||
stat: 'blue_power',
|
||||
colour: 'blue',
|
||||
svg: shapes.circle,
|
||||
},
|
||||
@ -164,45 +193,45 @@ const SPECS = {
|
||||
svg: shapes.square
|
||||
},
|
||||
|
||||
Damage: {
|
||||
Power: {
|
||||
colour: 'white',
|
||||
caption: 'Damage',
|
||||
caption: 'Power',
|
||||
thresholds: [],
|
||||
svg: shapes.circle
|
||||
},
|
||||
RedDamageI: {
|
||||
RedPowerI: {
|
||||
colour: 'red',
|
||||
caption: 'DamageI',
|
||||
caption: 'PowerI',
|
||||
thresholds: [5, 10, 20],
|
||||
svg: shapes.circle
|
||||
},
|
||||
BlueDamageI: {
|
||||
BluePowerI: {
|
||||
colour: 'blue',
|
||||
caption: 'DamageI',
|
||||
caption: 'PowerI',
|
||||
thresholds: [5, 10, 20],
|
||||
svg: shapes.circle
|
||||
},
|
||||
GreenDamageI: {
|
||||
GreenPowerI: {
|
||||
colour: 'green',
|
||||
caption: 'DamageI',
|
||||
caption: 'PowerI',
|
||||
thresholds: [5, 10, 20],
|
||||
svg: shapes.circle,
|
||||
},
|
||||
GRDI: {
|
||||
colour: 'yellow',
|
||||
caption: 'DamageI',
|
||||
caption: 'PowerI',
|
||||
thresholds: [2, 5, 10],
|
||||
svg: shapes.circle
|
||||
},
|
||||
GBDI: {
|
||||
colour: 'cyan',
|
||||
caption: 'DamageI',
|
||||
caption: 'PowerI',
|
||||
thresholds: [2, 5, 10],
|
||||
svg: shapes.circle,
|
||||
},
|
||||
RBDI: {
|
||||
colour: 'purple',
|
||||
caption: 'DamageI',
|
||||
caption: 'PowerI',
|
||||
thresholds: [2, 5, 10],
|
||||
svg: shapes.circle,
|
||||
},
|
||||
@ -257,52 +286,52 @@ const COLOUR_ICONS = {
|
||||
green: { colour: 'green', caption: 'green', svg: shapes.square },
|
||||
};
|
||||
|
||||
function resoCrypHealth(resolution, currentGame) {
|
||||
function resoConstructHealth(resolution, currentGame) {
|
||||
if (!resolution) return false;
|
||||
|
||||
const modifyHealth = cryp => {
|
||||
if (cryp.id !== resolution.target.id) return false; // not target
|
||||
const modifyHealth = construct => {
|
||||
if (construct.id !== resolution.target.id) return false; // not target
|
||||
const [type, event] = resolution.event;
|
||||
if (type === 'Damage') {
|
||||
const { amount, mitigation, colour } = event;
|
||||
cryp.green_life.value -= amount;
|
||||
construct.green_life.value -= amount;
|
||||
if (colour === 'Red') {
|
||||
cryp.red_life.value -= mitigation;
|
||||
construct.red_life.value -= mitigation;
|
||||
}
|
||||
if (colour === 'Blue') {
|
||||
cryp.blue_life.value -= mitigation;
|
||||
construct.blue_life.value -= mitigation;
|
||||
}
|
||||
}
|
||||
|
||||
if (type === 'Healing') {
|
||||
const { amount } = event;
|
||||
cryp.green_life.value += amount;
|
||||
construct.green_life.value += amount;
|
||||
}
|
||||
|
||||
if (type === 'Recharge') {
|
||||
const { red, blue } = event;
|
||||
cryp.red_life.value += red;
|
||||
cryp.blue_life.value += blue;
|
||||
construct.red_life.value += red;
|
||||
construct.blue_life.value += blue;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
currentGame.players.forEach(player => player.cryps.forEach(modifyHealth));
|
||||
currentGame.players.forEach(player => player.constructs.forEach(modifyHealth));
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
function eventClasses(resolution, cryp) {
|
||||
function eventClasses(resolution, construct) {
|
||||
if (!resolution) return '';
|
||||
const startSkill = resolution.stage === 'START_SKILL';
|
||||
const endSkill = resolution.stage === 'END_SKILL';
|
||||
const postSkill = resolution.stage === 'POST_SKILL';
|
||||
const source = cryp.id === resolution.source.id;
|
||||
const target = cryp.id === resolution.target.id;
|
||||
const source = construct.id === resolution.source.id;
|
||||
const target = construct.id === resolution.target.id;
|
||||
// not involved at all. blur them
|
||||
if (!(source || target)) return 'unfocus';
|
||||
|
||||
// not the target. just ignore for now
|
||||
// if (cryp.id !== resolution.target.id) return '';
|
||||
// if (construct.id !== resolution.target.id) return '';
|
||||
|
||||
const [type, event] = resolution.event;
|
||||
|
||||
@ -328,7 +357,7 @@ function eventClasses(resolution, cryp) {
|
||||
if (source && startSkill) return 'active-skill';
|
||||
if (target && endSkill) return 'active-skill';
|
||||
|
||||
// Deal damage to cryp and return effect
|
||||
// Deal damage to construct and return effect
|
||||
if (target && postSkill) {
|
||||
if (colour === 'Red') {
|
||||
return 'red-damage';
|
||||
@ -416,7 +445,7 @@ function getCombatSequence(event) {
|
||||
&& (['Ruin', 'Taunt', 'Strangling', 'Parry'].includes(event[1].skill)
|
||||
|| (event[1].skill === 'Decay' && event[1].effect === 'Wither'))) return ['POST_SKILL'];
|
||||
|
||||
if (['Damage'].includes(event[0])
|
||||
if (['Power'].includes(event[0])
|
||||
&& ((event[1].skill === 'Chaos' && event[1].colour === 'Red')
|
||||
|| event[1].skill === 'Silence'
|
||||
|| event[1].skill === 'Snare')) return ['POST_SKILL'];
|
||||
@ -428,13 +457,13 @@ function getCombatSequence(event) {
|
||||
return ['START_SKILL', 'END_SKILL', 'POST_SKILL'];
|
||||
}
|
||||
|
||||
function getCombatText(cryp, resolution) {
|
||||
function getCombatText(construct, resolution) {
|
||||
if (!resolution) return ['', ''];
|
||||
|
||||
|
||||
const [type, event] = resolution.event;
|
||||
const source = cryp.id === resolution.source.id;
|
||||
const target = cryp.id === resolution.target.id;
|
||||
const source = construct.id === resolution.source.id;
|
||||
const target = construct.id === resolution.target.id;
|
||||
const startSkill = resolution.stage === 'START_SKILL';
|
||||
const endSkill = resolution.stage === 'END_SKILL';
|
||||
const postSkill = resolution.stage === 'POST_SKILL';
|
||||
@ -537,34 +566,19 @@ function convertItem(v) {
|
||||
// return;
|
||||
}
|
||||
|
||||
function animateCryp(id) {
|
||||
const target = document.getElementById(id);
|
||||
return anime({
|
||||
targets: target,
|
||||
translateX: () => anime.random(-20, 20),
|
||||
translateY: () => anime.random(0, -40),
|
||||
rotate: () => anime.random(-15, 15),
|
||||
duration: () => anime.random(2000, 5000),
|
||||
delay: () => anime.random(0, 2000),
|
||||
direction: 'alternate',
|
||||
easing: 'linear',
|
||||
loop: true,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
animateCryp,
|
||||
animateConstruct,
|
||||
stringSort,
|
||||
convertItem,
|
||||
numSort,
|
||||
genAvatar,
|
||||
crypAvatar,
|
||||
instanceCryp,
|
||||
constructAvatar,
|
||||
instanceConstruct,
|
||||
requestAvatar,
|
||||
eventClasses,
|
||||
getCombatSequence,
|
||||
getCombatText,
|
||||
resoCrypHealth,
|
||||
resoConstructHealth,
|
||||
NULL_UUID,
|
||||
STATS,
|
||||
SPECS,
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
|
||||
# sudo apt-get install -y postgresql postgresql-contrib
|
||||
sudo service postgresql start
|
||||
sudo -u postgres dropdb cryps
|
||||
sudo -u postgres createdb cryps
|
||||
sudo -u postgres createuser --encrypted cryps
|
||||
sudo -u postgres psql -c "alter user cryps with encrypted password 'craftbeer';"
|
||||
sudo -u postgres dropdb mnml
|
||||
sudo -u postgres createdb mnml
|
||||
sudo -u postgres createuser --encrypted mnml
|
||||
sudo -u postgres psql -c "alter user mnml with encrypted password 'craftbeer';"
|
||||
|
||||
# npm i
|
||||
npm run migrate
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
const local = {
|
||||
client: 'postgresql',
|
||||
connection: {
|
||||
database: 'cryps',
|
||||
user: 'cryps',
|
||||
database: 'mnml',
|
||||
user: 'mnml',
|
||||
password: 'craftbeer'
|
||||
},
|
||||
pool: {
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
exports.up = async knex => {
|
||||
return knex.schema.createTable('cryps', table => {
|
||||
return knex.schema.createTable('constructs', table => {
|
||||
table.uuid('id').primary();
|
||||
table.timestamps(true, true);
|
||||
table.uuid('account').notNullable()
|
||||
table.foreign('account')
|
||||
.references('id')
|
||||
@ -1,5 +1,3 @@
|
||||
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
exports.up = async knex => {
|
||||
await knex.schema.createTable('games', table => {
|
||||
table.uuid('id').primary();
|
||||
@ -67,14 +65,6 @@ exports.up = async knex => {
|
||||
.inTable('games')
|
||||
.onDelete('NO ACTION');
|
||||
});
|
||||
|
||||
|
||||
// not really sure if this is a good idea
|
||||
await knex('instances').insert({
|
||||
id: NULL_UUID,
|
||||
data: 'INVALID',
|
||||
open: false,
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = async () => {};
|
||||
@ -1,28 +0,0 @@
|
||||
exports.up = async knex => {
|
||||
await knex.schema.createTable('zones', async (table) => {
|
||||
table.uuid('id').primary();
|
||||
table.index('id');
|
||||
table.timestamps(true, true);
|
||||
|
||||
table.binary('data').notNullable();
|
||||
|
||||
table.boolean('active')
|
||||
.defaultTo(true)
|
||||
.notNullable();
|
||||
|
||||
table.uuid('account').notNullable()
|
||||
table.foreign('account')
|
||||
.references('id')
|
||||
.inTable('accounts')
|
||||
.onDelete('CASCADE');
|
||||
|
||||
table.index('account');
|
||||
|
||||
await knex.schema.raw(
|
||||
// eslint-disable-next-line max-len
|
||||
'CREATE UNIQUE INDEX zones_account_active ON zones (account) WHERE active = true;'
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
exports.down = async () => {};
|
||||
@ -1,4 +1,4 @@
|
||||
upstream cryps {
|
||||
upstream mnml {
|
||||
server 127.0.0.1:40000;
|
||||
}
|
||||
|
||||
@ -8,10 +8,18 @@ map $http_upgrade $connection_upgrade {
|
||||
}
|
||||
|
||||
server {
|
||||
root /home/git/cryps/client/dist/;
|
||||
root /home/git/mnml/client/dist/;
|
||||
index index.html;
|
||||
|
||||
server_name cryps.gg; # managed by Certbot
|
||||
server_name mnml.gg; # managed by Certbot
|
||||
|
||||
if ($host = minimal.gg) {
|
||||
return 301 https://mnml.gg$request_uri;
|
||||
} # managed by Certbot
|
||||
|
||||
if ($host = cryps.gg) {
|
||||
return 301 https://mnml.gg$request_uri;
|
||||
} # managed by Certbot
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
@ -19,13 +27,13 @@ server {
|
||||
|
||||
listen [::]:443 ssl ipv6only=on; # managed by Certbot
|
||||
listen 443 ssl; # managed by Certbot
|
||||
ssl_certificate /etc/letsencrypt/live/cryps.gg/fullchain.pem; # managed by Certbot
|
||||
ssl_certificate_key /etc/letsencrypt/live/cryps.gg/privkey.pem; # managed by Certbot
|
||||
ssl_certificate /etc/letsencrypt/live/mnml.gg/fullchain.pem; # managed by Certbot
|
||||
ssl_certificate_key /etc/letsencrypt/live/mnml.gg/privkey.pem; # managed by Certbot
|
||||
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||
|
||||
location /ws {
|
||||
proxy_pass http://cryps;
|
||||
proxy_pass http://mnml;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection $connection_upgrade;
|
||||
@ -33,13 +41,18 @@ server {
|
||||
}
|
||||
}
|
||||
|
||||
# http -> https
|
||||
server {
|
||||
if ($host = cryps.gg) {
|
||||
return 301 https://$host$request_uri;
|
||||
} # managed by Certbot
|
||||
|
||||
listen 80 ;
|
||||
listen [::]:80 ;
|
||||
server_name cryps.gg;
|
||||
return 404; # managed by Certbot
|
||||
server_name mnml.gg;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name minimal.gg;
|
||||
return 301 https://mnml.gg$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
server_name cryps.gg;
|
||||
return 301 https://mnml.gg$request_uri;
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "cryps-ops",
|
||||
"name": "constructs-ops",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
5
phaser-client/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
package-lock.json
|
||||
node_modules/
|
||||
dist/
|
||||
.cache/
|
||||
assets/molecules
|
||||
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 28 KiB |
@ -1,444 +0,0 @@
|
||||
{
|
||||
"textures": [
|
||||
{
|
||||
"format": "RGBA8888",
|
||||
"size": {
|
||||
"w": 1024,
|
||||
"h": 1024
|
||||
},
|
||||
"scale": 1,
|
||||
"frames":[
|
||||
{
|
||||
"filename":"sprite0",
|
||||
"frame":{
|
||||
"x":655,
|
||||
"y":100,
|
||||
"w":110,
|
||||
"h":97
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":110,
|
||||
"h":97
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":110,
|
||||
"h":97
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite1",
|
||||
"frame":{
|
||||
"x":180,
|
||||
"y":105,
|
||||
"w":140,
|
||||
"h":88
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":88
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":88
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite2",
|
||||
"frame":{
|
||||
"x":20,
|
||||
"y":106,
|
||||
"w":140,
|
||||
"h":86
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":86
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":86
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite3",
|
||||
"frame":{
|
||||
"x":475,
|
||||
"y":106,
|
||||
"w":150,
|
||||
"h":86
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":150,
|
||||
"h":86
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":150,
|
||||
"h":86
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite4",
|
||||
"frame":{
|
||||
"x":330,
|
||||
"y":112,
|
||||
"w":140,
|
||||
"h":74
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":74
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":74
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite5",
|
||||
"frame":{
|
||||
"x":198,
|
||||
"y":274,
|
||||
"w":104,
|
||||
"h":110
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":104,
|
||||
"h":110
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":104,
|
||||
"h":110
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite6",
|
||||
"frame":{
|
||||
"x":342,
|
||||
"y":279,
|
||||
"w":116,
|
||||
"h":100
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":116,
|
||||
"h":100
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":116,
|
||||
"h":100
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite7",
|
||||
"frame":{
|
||||
"x":480,
|
||||
"y":283,
|
||||
"w":140,
|
||||
"h":92
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":92
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":92
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite8",
|
||||
"frame":{
|
||||
"x":24,
|
||||
"y":284,
|
||||
"w":132,
|
||||
"h":90
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":132,
|
||||
"h":90
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":132,
|
||||
"h":90
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite9",
|
||||
"frame":{
|
||||
"x":645,
|
||||
"y":287,
|
||||
"w":130,
|
||||
"h":84
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":130,
|
||||
"h":84
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":130,
|
||||
"h":84
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite10",
|
||||
"frame":{
|
||||
"x":514,
|
||||
"y":434,
|
||||
"w":74,
|
||||
"h":110
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":74,
|
||||
"h":110
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":74,
|
||||
"h":110
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite11",
|
||||
"frame":{
|
||||
"x":222,
|
||||
"y":439,
|
||||
"w":56,
|
||||
"h":100
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":56,
|
||||
"h":100
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":56,
|
||||
"h":100
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite12",
|
||||
"frame":{
|
||||
"x":667,
|
||||
"y":439,
|
||||
"w":86,
|
||||
"h":100
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":86,
|
||||
"h":100
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":86,
|
||||
"h":100
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite13",
|
||||
"frame":{
|
||||
"x":20,
|
||||
"y":451,
|
||||
"w":140,
|
||||
"h":74
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":74
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":74
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite14",
|
||||
"frame":{
|
||||
"x":335,
|
||||
"y":453,
|
||||
"w":130,
|
||||
"h":72
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":130,
|
||||
"h":72
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":130,
|
||||
"h":72
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite15",
|
||||
"frame":{
|
||||
"x":493,
|
||||
"y":619,
|
||||
"w":114,
|
||||
"h":100
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":114,
|
||||
"h":100
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":114,
|
||||
"h":100
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite16",
|
||||
"frame":{
|
||||
"x":180,
|
||||
"y":626,
|
||||
"w":140,
|
||||
"h":86
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":86
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":86
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite17",
|
||||
"frame":{
|
||||
"x":640,
|
||||
"y":632,
|
||||
"w":140,
|
||||
"h":94
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":140,
|
||||
"h":94
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":140,
|
||||
"h":94
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite18",
|
||||
"frame":{
|
||||
"x":329,
|
||||
"y":635,
|
||||
"w":141,
|
||||
"h":88
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":141,
|
||||
"h":88
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":141,
|
||||
"h":88
|
||||
}
|
||||
},
|
||||
{
|
||||
"filename":"sprite19",
|
||||
"frame":{
|
||||
"x":25,
|
||||
"y":641,
|
||||
"w":130,
|
||||
"h":76
|
||||
},
|
||||
"rotated":false,
|
||||
"trimmed":false,
|
||||
"spriteSourceSize":{
|
||||
"x":0,
|
||||
"y":0,
|
||||
"w":130,
|
||||
"h":76
|
||||
},
|
||||
"sourceSize":{
|
||||
"w":130,
|
||||
"h":76
|
||||
}
|
||||
}
|
||||
],
|
||||
"meta":{
|
||||
"app":"https://www.leshylabs.com/apps/sstool/",
|
||||
"version":"Leshy SpriteSheet Tool v0.8.4",
|
||||
"image":"spritesheet.png",
|
||||
"size":{
|
||||
"w":800,
|
||||
"h":800
|
||||
},
|
||||
"scale":1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 431 KiB |
|
Before Width: | Height: | Size: 187 KiB |
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="13.8889in" height="13.8889in"
|
||||
viewBox="0 0 1000 1000">
|
||||
<path id="Unnamed"
|
||||
fill="none" stroke="black" stroke-width="1"
|
||||
d="M 250.00,-1.00
|
||||
C 250.00,-1.00 0.00,300.00 0.00,300.00
|
||||
0.00,300.00 1000.00,300.00 1000.00,300.00
|
||||
1000.00,300.00 750.00,2.00 750.00,2.00M 500.00,300.00
|
||||
C 500.00,300.00 500.00,700.00 500.00,700.00M 250.00,1000.00
|
||||
C 250.00,1000.00 0.00,700.00 0.00,700.00
|
||||
0.00,700.00 999.00,700.00 1000.00,700.00
|
||||
1001.00,700.00 750.00,1000.00 750.00,1000.00" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 811 B |
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="13.8889in" height="13.8889in"
|
||||
viewBox="0 0 1000 1000">
|
||||
<path id="c2"
|
||||
fill="none" stroke="black" stroke-width="1"
|
||||
d="M 250.00,-1.00
|
||||
C 250.00,-1.00 250.00,300.00 250.00,300.00
|
||||
250.00,300.00 750.00,299.00 750.00,299.00
|
||||
750.00,299.00 750.00,2.00 750.00,2.00M 500.00,100.00
|
||||
C 500.00,100.00 500.00,300.00 500.00,300.00
|
||||
500.00,300.00 500.00,700.00 500.00,700.00M 250.00,1000.00
|
||||
C 250.00,1000.00 500.00,700.00 500.00,700.00
|
||||
500.00,700.00 750.00,1000.00 750.00,1000.00M 750.00,700.00
|
||||
C 750.00,700.00 500.00,400.00 500.00,400.00
|
||||
500.00,400.00 249.00,699.00 249.00,699.00" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 938 B |
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="13.8889in" height="13.8889in"
|
||||
viewBox="0 0 1000 1000">
|
||||
<path id="c3"
|
||||
fill="none" stroke="black" stroke-width="1"
|
||||
d="M 250.00,-1.00
|
||||
C 250.00,-1.00 250.00,300.00 250.00,300.00
|
||||
250.00,300.00 750.00,299.00 750.00,299.00
|
||||
750.00,299.00 750.00,2.00 750.00,2.00M 500.00,300.00
|
||||
C 500.00,300.00 500.00,700.00 500.00,700.00M 250.00,1000.00
|
||||
C 250.00,1000.00 250.00,700.00 250.00,700.00
|
||||
250.00,700.00 500.00,700.00 500.00,700.00
|
||||
500.00,700.00 750.00,700.00 750.00,700.00
|
||||
750.00,700.00 750.00,1000.00 750.00,1000.00M 250.00,500.00
|
||||
C 250.00,500.00 750.00,500.00 750.00,500.00" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 938 B |
|
Before Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 9.3 KiB |
@ -1,24 +0,0 @@
|
||||
/*@font-face {
|
||||
font-family: 'nowayregular';
|
||||
src: url('./assets/fonts/noway-regular-webfont.eot');
|
||||
src: url('./assets/fonts/noway-regular-webfont.eot?#iefix') format('embedded-opentype'),
|
||||
url('./assets/fonts/noway-regular-webfont.woff2') format('woff2'),
|
||||
url('./assets/fonts/noway-regular-webfont.woff') format('woff'),
|
||||
url('./assets/fonts/noway-regular-webfont.ttf') format('truetype'),
|
||||
url('./assets/fonts/noway-regular-webfont.svg#nowayregular') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
*/
|
||||
body {
|
||||
background-color: #181818;
|
||||
}
|
||||
|
||||
canvas{
|
||||
display:block;
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>cryps.gg - mnml pvp atbs</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
||||
<link rel="stylesheet" href="./node_modules/izitoast/dist/css/iziToast.min.css"></script>
|
||||
<link href="https://fonts.googleapis.com/css?family=Jura" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||
<script defer src="https://use.fontawesome.com/releases/v5.1.0/js/all.js"></script>
|
||||
</head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
<script src="./index.js"></script>
|
||||
</html>
|
||||
@ -1,4 +0,0 @@
|
||||
require('./cryps.css');
|
||||
|
||||
// kick it off
|
||||
require('./src/main');
|
||||
@ -1,189 +0,0 @@
|
||||
// http://mrl.nyu.edu/~perlin/noise/
|
||||
|
||||
const ImprovedNoise = function () {
|
||||
const p = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10,
|
||||
23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87,
|
||||
174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211,
|
||||
133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208,
|
||||
89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5,
|
||||
202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119,
|
||||
248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232,
|
||||
178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249,
|
||||
14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205,
|
||||
93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180];
|
||||
|
||||
for (let i = 0; i < 256; i++) {
|
||||
p[256 + i] = p[i];
|
||||
}
|
||||
|
||||
function fade(t) {
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
function lerp(t, a, b) {
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
function grad(hash, x, y, z) {
|
||||
const h = hash & 15;
|
||||
const u = h < 8 ? x : y; const
|
||||
v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
noise(x, y, z) {
|
||||
const floorX = Math.floor(x); const floorY = Math.floor(y); const
|
||||
floorZ = Math.floor(z);
|
||||
|
||||
const X = floorX & 255; const Y = floorY & 255; const
|
||||
Z = floorZ & 255;
|
||||
|
||||
x -= floorX;
|
||||
y -= floorY;
|
||||
z -= floorZ;
|
||||
|
||||
const xMinus1 = x - 1; const yMinus1 = y - 1; const
|
||||
zMinus1 = z - 1;
|
||||
|
||||
const u = fade(x); const v = fade(y); const
|
||||
w = fade(z);
|
||||
|
||||
const A = p[X] + Y; const AA = p[A] + Z; const AB = p[A + 1] + Z; const B = p[X + 1] + Y; const BA = p[B] + Z; const
|
||||
BB = p[B + 1] + Z;
|
||||
|
||||
return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z),
|
||||
grad(p[BA], xMinus1, y, z)),
|
||||
lerp(u, grad(p[AB], x, yMinus1, z),
|
||||
grad(p[BB], xMinus1, yMinus1, z))),
|
||||
lerp(v, lerp(u, grad(p[AA + 1], x, y, zMinus1),
|
||||
grad(p[BA + 1], xMinus1, y, z - 1)),
|
||||
lerp(u, grad(p[AB + 1], x, yMinus1, zMinus1),
|
||||
grad(p[BB + 1], xMinus1, yMinus1, zMinus1))));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const currentRandom = Math.random;
|
||||
|
||||
// Pseudo-random generator
|
||||
function Marsaglia(i1, i2) {
|
||||
// from http://www.math.uni-bielefeld.de/~sillke/ALGORITHMS/random/marsaglia-c
|
||||
let z = i1 || 362436069; let
|
||||
w = i2 || 521288629;
|
||||
const nextInt = function () {
|
||||
z = (36969 * (z & 65535) + (z >>> 16)) & 0xFFFFFFFF;
|
||||
w = (18000 * (w & 65535) + (w >>> 16)) & 0xFFFFFFFF;
|
||||
return (((z & 0xFFFF) << 16) | (w & 0xFFFF)) & 0xFFFFFFFF;
|
||||
};
|
||||
|
||||
this.nextDouble = function () {
|
||||
const i = nextInt() / 4294967296;
|
||||
return i < 0 ? 1 + i : i;
|
||||
};
|
||||
this.nextInt = nextInt;
|
||||
}
|
||||
Marsaglia.createRandomized = function () {
|
||||
const now = new Date();
|
||||
return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF);
|
||||
};
|
||||
|
||||
// Noise functions and helpers
|
||||
function PerlinNoise(seed) {
|
||||
const rnd = seed !== undefined ? new Marsaglia(seed) : Marsaglia.createRandomized();
|
||||
let i; let
|
||||
j;
|
||||
// http://www.noisemachine.com/talk1/17b.html
|
||||
// http://mrl.nyu.edu/~perlin/noise/
|
||||
// generate permutation
|
||||
const p = new Array(512);
|
||||
for (i = 0; i < 256; ++i) { p[i] = i; }
|
||||
for (i = 0; i < 256; ++i) { const t = p[j = rnd.nextInt() & 0xFF]; p[j] = p[i]; p[i] = t; }
|
||||
// copy to avoid taking mod in p[0];
|
||||
for (i = 0; i < 256; ++i) { p[i + 256] = p[i]; }
|
||||
|
||||
function grad3d(i, x, y, z) {
|
||||
const h = i & 15; // convert into 12 gradient directions
|
||||
const u = h < 8 ? x : y;
|
||||
|
||||
|
||||
const v = h < 4 ? y : h === 12 || h === 14 ? x : z;
|
||||
return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v);
|
||||
}
|
||||
|
||||
function grad2d(i, x, y) {
|
||||
const v = (i & 1) === 0 ? x : y;
|
||||
return (i & 2) === 0 ? -v : v;
|
||||
}
|
||||
|
||||
function grad1d(i, x) {
|
||||
return (i & 1) === 0 ? -x : x;
|
||||
}
|
||||
|
||||
function lerp(t, a, b) { return a + t * (b - a); }
|
||||
|
||||
this.noise3d = function (x, y, z) {
|
||||
const X = Math.floor(x) & 255; const Y = Math.floor(y) & 255; const
|
||||
Z = Math.floor(z) & 255;
|
||||
x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z);
|
||||
const fx = (3 - 2 * x) * x * x; const fy = (3 - 2 * y) * y * y; const
|
||||
fz = (3 - 2 * z) * z * z;
|
||||
const p0 = p[X] + Y; const p00 = p[p0] + Z; const p01 = p[p0 + 1] + Z; const p1 = p[X + 1] + Y; const p10 = p[p1] + Z; const
|
||||
p11 = p[p1 + 1] + Z;
|
||||
return lerp(fz,
|
||||
lerp(fy, lerp(fx, grad3d(p[p00], x, y, z), grad3d(p[p10], x - 1, y, z)),
|
||||
lerp(fx, grad3d(p[p01], x, y - 1, z), grad3d(p[p11], x - 1, y - 1, z))),
|
||||
lerp(fy, lerp(fx, grad3d(p[p00 + 1], x, y, z - 1), grad3d(p[p10 + 1], x - 1, y, z - 1)),
|
||||
lerp(fx, grad3d(p[p01 + 1], x, y - 1, z - 1), grad3d(p[p11 + 1], x - 1, y - 1, z - 1))));
|
||||
};
|
||||
|
||||
this.noise2d = function (x, y) {
|
||||
const X = Math.floor(x) & 255; const
|
||||
Y = Math.floor(y) & 255;
|
||||
x -= Math.floor(x); y -= Math.floor(y);
|
||||
const fx = (3 - 2 * x) * x * x; const
|
||||
fy = (3 - 2 * y) * y * y;
|
||||
const p0 = p[X] + Y; const
|
||||
p1 = p[X + 1] + Y;
|
||||
return lerp(fy,
|
||||
lerp(fx, grad2d(p[p0], x, y), grad2d(p[p1], x - 1, y)),
|
||||
lerp(fx, grad2d(p[p0 + 1], x, y - 1), grad2d(p[p1 + 1], x - 1, y - 1)));
|
||||
};
|
||||
|
||||
this.noise1d = function (x) {
|
||||
const X = Math.floor(x) & 255;
|
||||
x -= Math.floor(x);
|
||||
const fx = (3 - 2 * x) * x * x;
|
||||
return lerp(fx, grad1d(p[X], x), grad1d(p[X + 1], x - 1));
|
||||
};
|
||||
}
|
||||
|
||||
// these are lifted from Processing.js
|
||||
// processing defaults
|
||||
const noiseProfile = {
|
||||
generator: undefined, octaves: 4, fallout: 0.5, seed: undefined,
|
||||
};
|
||||
|
||||
module.exports = function noise(x, y, z) {
|
||||
if (noiseProfile.generator === undefined) {
|
||||
// caching
|
||||
noiseProfile.generator = new PerlinNoise(noiseProfile.seed);
|
||||
}
|
||||
const generator = noiseProfile.generator;
|
||||
let effect = 1; let k = 1; let
|
||||
sum = 0;
|
||||
for (let i = 0; i < noiseProfile.octaves; ++i) {
|
||||
effect *= noiseProfile.fallout;
|
||||
switch (arguments.length) {
|
||||
case 1:
|
||||
sum += effect * (1 + generator.noise1d(k * x)) / 2; break;
|
||||
case 2:
|
||||
sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; break;
|
||||
case 3:
|
||||
sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; break;
|
||||
}
|
||||
k *= 2;
|
||||
}
|
||||
return sum;
|
||||
};
|
||||
@ -1,220 +0,0 @@
|
||||
const noise = require('./fizzy-noise');
|
||||
|
||||
function fizzyText(message) {
|
||||
const that = this;
|
||||
|
||||
// These are the variables that we manipulate with gui-dat.
|
||||
// Notice they're all defined with "this". That makes them public.
|
||||
// Otherwise, gui-dat can't see them.
|
||||
|
||||
this.growthSpeed = 0.8; // how fast do particles change size?
|
||||
this.minSize = 1;
|
||||
this.maxSize = 4; // how big can they get?
|
||||
this.noiseStrength = 10; // how turbulent is the flow?
|
||||
this.speed = 0.4; // how fast do particles move?
|
||||
this.displayOutline = false; // should we draw the message as a stroke?
|
||||
this.framesRendered = 0;
|
||||
|
||||
// //////////////////////////////////////////////////////////////
|
||||
|
||||
const _this = this;
|
||||
|
||||
const width = 550;
|
||||
const height = 200;
|
||||
const textAscent = 101;
|
||||
const textOffsetLeft = 80;
|
||||
const noiseScale = 300;
|
||||
const frameTime = 30;
|
||||
|
||||
const colors = ['#000000', '#1A1A1A', '#163C50', '#205A79', '#2A78A2'];
|
||||
|
||||
// This is the context we use to get a bitmap of text using
|
||||
// the getImageData function.
|
||||
const r = document.createElement('canvas');
|
||||
const s = r.getContext('2d');
|
||||
|
||||
// This is the context we actually use to draw.
|
||||
const c = document.createElement('canvas');
|
||||
const g = c.getContext('2d');
|
||||
|
||||
r.setAttribute('width', width);
|
||||
c.setAttribute('width', width);
|
||||
r.setAttribute('height', height);
|
||||
c.setAttribute('height', height);
|
||||
|
||||
// Add our demo to the HTML
|
||||
document.getElementById('fizzytext').appendChild(c);
|
||||
|
||||
// Stores bitmap image
|
||||
let pixels = [];
|
||||
|
||||
// Stores a list of particles
|
||||
const particles = [];
|
||||
|
||||
// Set g.font to the same font as the bitmap canvas, incase we
|
||||
// want to draw some outlines.
|
||||
s.font = g.font = '800 82px monospace, monospace';
|
||||
|
||||
// Instantiate some particles
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
particles.push(new Particle(Math.random() * width, Math.random() * height));
|
||||
}
|
||||
|
||||
// This function creates a bitmap of pixels based on your message
|
||||
// It's called every time we change the message property.
|
||||
const createBitmap = function (msg) {
|
||||
s.fillStyle = '#fff';
|
||||
s.fillRect(0, 0, width, height);
|
||||
|
||||
s.fillStyle = '#222';
|
||||
s.fillText(msg, textOffsetLeft, textAscent);
|
||||
|
||||
// Pull reference
|
||||
const imageData = s.getImageData(0, 0, width, height);
|
||||
pixels = imageData.data;
|
||||
};
|
||||
|
||||
// Called once per frame, updates the animation.
|
||||
const render = function () {
|
||||
that.framesRendered++;
|
||||
|
||||
g.clearRect(0, 0, width, height);
|
||||
|
||||
if (_this.displayOutline) {
|
||||
g.globalCompositeOperation = 'source-over';
|
||||
g.strokeStyle = '#000';
|
||||
g.lineWidth = 0.5;
|
||||
g.strokeText(message, textOffsetLeft, textAscent);
|
||||
}
|
||||
|
||||
g.globalCompositeOperation = 'darker';
|
||||
|
||||
for (let i = 0; i < particles.length; i++) {
|
||||
g.fillStyle = colors[i % colors.length];
|
||||
particles[i].render();
|
||||
}
|
||||
};
|
||||
|
||||
// Returns x, y coordinates for a given index in the pixel array.
|
||||
const getPosition = function (i) {
|
||||
return {
|
||||
x: (i - (width * 4) * Math.floor(i / (width * 4))) / 4,
|
||||
y: Math.floor(i / (width * 4)),
|
||||
};
|
||||
};
|
||||
|
||||
// Returns a color for a given pixel in the pixel array.
|
||||
const getColor = function (x, y) {
|
||||
const base = (Math.floor(y) * width + Math.floor(x)) * 4;
|
||||
const c = {
|
||||
r: pixels[base + 0],
|
||||
g: pixels[base + 1],
|
||||
b: pixels[base + 2],
|
||||
a: pixels[base + 3],
|
||||
};
|
||||
|
||||
return `rgb(${c.r},${c.g},${c.b})`;
|
||||
};
|
||||
|
||||
this.message = message;
|
||||
createBitmap(message);
|
||||
|
||||
var loop = function () {
|
||||
requestAnimationFrame(loop);
|
||||
render();
|
||||
};
|
||||
|
||||
// This calls the render function every 30 milliseconds.
|
||||
loop();
|
||||
|
||||
// This class is responsible for drawing and moving those little
|
||||
// colored dots.
|
||||
function Particle(x, y, c) {
|
||||
// Position
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
||||
// Size of particle
|
||||
this.r = 1;
|
||||
|
||||
// This velocity is used by the explode function.
|
||||
this.vx = 0;
|
||||
this.vy = 0;
|
||||
|
||||
this.constrain = function constrainFn(v, o1, o2) {
|
||||
if (v < o1) v = o1;
|
||||
else if (v > o2) v = o2;
|
||||
return v;
|
||||
};
|
||||
|
||||
// Called every frame
|
||||
this.render = function renderFrame() {
|
||||
// What color is the pixel we're sitting on top of?
|
||||
const c = getColor(this.x, this.y);
|
||||
|
||||
// Where should we move?
|
||||
const angle = noise(this.x / noiseScale, this.y / noiseScale) * _this.noiseStrength;
|
||||
// var angle = -Math.PI/2;
|
||||
|
||||
// Are we within the boundaries of the image?
|
||||
const onScreen = this.x > 0 && this.x < width && this.y > 0 && this.y < height;
|
||||
|
||||
const isBlack = c !== 'rgb(255,255,255)' && onScreen;
|
||||
|
||||
// If we're on top of a black pixel, grow.
|
||||
// If not, shrink.
|
||||
if (isBlack) {
|
||||
this.r += _this.growthSpeed;
|
||||
} else {
|
||||
this.r -= _this.growthSpeed;
|
||||
}
|
||||
|
||||
// This velocity is used by the explode function.
|
||||
this.vx *= 0.5;
|
||||
this.vy *= 0.5;
|
||||
|
||||
// Change our position based on the flow field and our
|
||||
// explode velocity.
|
||||
this.x += Math.cos(angle) * _this.speed + this.vx;
|
||||
this.y += -Math.sin(angle) * _this.speed + this.vy;
|
||||
|
||||
if (this.r > _this.maxSize) {
|
||||
this.r = _this.maxSize;
|
||||
} else if (this.r < 0) {
|
||||
this.r = 0;
|
||||
this.x = Math.random() * width;
|
||||
this.y = Math.random() * height;
|
||||
return false;
|
||||
}
|
||||
|
||||
// this.r = 3;
|
||||
// debugger
|
||||
// console.log(DAT.GUI.constrain(this.r, 0, _this.maxSize));
|
||||
// this.r = this.constrain(this.r, _this.minSize, _this.maxSize);
|
||||
|
||||
// If we're tiny, keep moving around until we find a black
|
||||
// pixel.
|
||||
if (this.r <= 0) {
|
||||
this.x = Math.random() * width;
|
||||
this.y = Math.random() * height;
|
||||
return false; // Don't draw!
|
||||
}
|
||||
|
||||
// If we're off the screen, go over to other side
|
||||
if (this.x < 0) this.x = width;
|
||||
if (this.x > width) this.x = 0;
|
||||
if (this.y < 0) this.y = height;
|
||||
if (this.y > height) this.y = 0;
|
||||
|
||||
// Draw the circle.
|
||||
g.beginPath();
|
||||
// g.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);
|
||||
g.rect(this.x, this.y, this.r, this.r);
|
||||
g.fill();
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = fizzyText;
|
||||
@ -1,33 +0,0 @@
|
||||
{
|
||||
"name": "cryps-client",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "parcel index.html --port 40080 --no-hmr --no-source-maps",
|
||||
"build": "rm -rf dist && parcel build --no-source-maps index.html",
|
||||
"lint": "eslint --fix src/",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"async": "^2.6.1",
|
||||
"borc": "^2.0.3",
|
||||
"docco": "^0.7.0",
|
||||
"izitoast": "^1.4.0",
|
||||
"jdenticon": "^2.1.0",
|
||||
"key": "^0.1.11",
|
||||
"keymaster": "^1.6.2",
|
||||
"lodash": "^4.17.11",
|
||||
"parcel": "^1.11.0",
|
||||
"phaser": "^3.16.1",
|
||||
"redux": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^5.6.0",
|
||||
"eslint-config-airbnb-base": "^13.1.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"jest": "^18.0.0"
|
||||
}
|
||||
}
|
||||
@ -1,219 +0,0 @@
|
||||
const toast = require('izitoast');
|
||||
|
||||
function registerEvents(registry, events, tutorial) {
|
||||
function setCryps(cryps) {
|
||||
registry.set('cryps', cryps);
|
||||
tutorial('homepage');
|
||||
}
|
||||
|
||||
function setCrypList(cryps) {
|
||||
registry.set('crypList', cryps);
|
||||
}
|
||||
|
||||
|
||||
function setWs(ws) {
|
||||
registry.set('ws', ws);
|
||||
}
|
||||
|
||||
function setGame(game) {
|
||||
if (game.phase === 'Skill') tutorial('skillPhase');
|
||||
if (game.phase === 'Target') tutorial('targetPhase');
|
||||
if (game.resolved.length) tutorial('resolutionPhase');
|
||||
if (game.phase === 'Finish') tutorial('finishPhase');
|
||||
return registry.set('game', game);
|
||||
}
|
||||
|
||||
function setAccount(account) {
|
||||
registry.set('account', account);
|
||||
registry.set('home', true);
|
||||
events.emit('ACCOUNT', account);
|
||||
}
|
||||
|
||||
function setActiveSkill(skill) {
|
||||
registry.set('activeSkill', skill);
|
||||
}
|
||||
|
||||
function setMenu() {
|
||||
registry.set('menu', true);
|
||||
}
|
||||
|
||||
function setVbox(items) {
|
||||
registry.set('vbox', items);
|
||||
}
|
||||
|
||||
function setScores(scores) {
|
||||
registry.set('scores', scores);
|
||||
}
|
||||
|
||||
function setPlayerList(list) {
|
||||
registry.set('playerList', list);
|
||||
registry.set('homeInstances', true);
|
||||
}
|
||||
|
||||
function setPlayer(player) {
|
||||
registry.set('player', player);
|
||||
if (!registry.get('inMenu')) {
|
||||
setMenu();
|
||||
}
|
||||
}
|
||||
|
||||
function setZone(zone) {
|
||||
registry.set('zone', zone);
|
||||
}
|
||||
|
||||
function setGameList(gameList) {
|
||||
registry.set('gameList', gameList);
|
||||
}
|
||||
|
||||
function setCrypStatusUpdate(id, skill, target) {
|
||||
registry.set('crypStatusUpdate', { id, skill, target });
|
||||
}
|
||||
|
||||
events.on('SET_PLAYER', setPlayer);
|
||||
|
||||
events.on('SEND_SKILL', function skillActive(gameId, crypId, targetCrypId, skill) {
|
||||
const ws = registry.get('ws');
|
||||
ws.sendGameSkill(gameId, crypId, targetCrypId, skill);
|
||||
setCrypStatusUpdate(crypId, skill, targetCrypId);
|
||||
});
|
||||
|
||||
events.on('CRYP_ACTIVE', function crypActiveCb(cryp) {
|
||||
const cryps = registry.get('cryps');
|
||||
for (let i = 0; i < cryps.length; i += 1) {
|
||||
if (cryps[i].id === cryp.id) cryps[i].active = !cryps[i].active;
|
||||
}
|
||||
return setCryps(cryps);
|
||||
});
|
||||
|
||||
const errMessages = {
|
||||
select_cryps: 'Select your cryps before battle using the numbered buttons next to the cryp avatar',
|
||||
complete_nodes: 'You need to complete the previously connected nodes first',
|
||||
max_skills: 'Your cryp can only learn a maximum of 4 skills',
|
||||
|
||||
};
|
||||
|
||||
function errorPrompt(type) {
|
||||
const message = errMessages[type];
|
||||
const OK_BUTTON = '<button type="submit">OK</button>';
|
||||
toast.info({
|
||||
theme: 'dark',
|
||||
color: 'black',
|
||||
timeout: false,
|
||||
drag: false,
|
||||
position: 'center',
|
||||
maxWidth: window.innerWidth / 2,
|
||||
close: false,
|
||||
buttons: [
|
||||
[OK_BUTTON, (instance, thisToast) => instance.hide({ transitionOut: 'fadeOut' }, thisToast)],
|
||||
],
|
||||
message,
|
||||
});
|
||||
}
|
||||
|
||||
function loginPrompt() {
|
||||
const USER_INPUT = '<input className="input" type="email" placeholder="username" />';
|
||||
const PASSWORD_INPUT = '<input className="input" type="password" placeholder="password" />';
|
||||
const LOGIN_BUTTON = '<button type="submit">Login</button>';
|
||||
const REGISTER_BUTTON = '<button type="submit">Register</button>';
|
||||
const DEMO_BUTTON = '<button type="submit">Demo</button>';
|
||||
|
||||
const ws = registry.get('ws');
|
||||
|
||||
function submitLogin(instance, thisToast, button, e, inputs) {
|
||||
const USERNAME = inputs[0].value;
|
||||
const PASSWORD = inputs[1].value;
|
||||
ws.sendAccountLogin(USERNAME, PASSWORD);
|
||||
}
|
||||
|
||||
function submitRegister(instance, thisToast, button, e, inputs) {
|
||||
const USERNAME = inputs[0].value;
|
||||
const PASSWORD = inputs[1].value;
|
||||
ws.sendAccountCreate(USERNAME, PASSWORD);
|
||||
}
|
||||
|
||||
function submitDemo() {
|
||||
ws.sendAccountDemo();
|
||||
}
|
||||
|
||||
const existing = document.querySelector('#login'); // Selector of your toast
|
||||
if (existing) toast.hide({}, existing, 'reconnect');
|
||||
|
||||
toast.question({
|
||||
id: 'login',
|
||||
theme: 'dark',
|
||||
color: 'black',
|
||||
timeout: false,
|
||||
// overlay: true,
|
||||
drag: false,
|
||||
close: false,
|
||||
title: 'LOGIN',
|
||||
position: 'center',
|
||||
inputs: [
|
||||
[USER_INPUT, 'change', () => true, true], // true to focus
|
||||
[PASSWORD_INPUT, 'change', () => true],
|
||||
],
|
||||
buttons: [
|
||||
[LOGIN_BUTTON, submitLogin], // true to focus
|
||||
[REGISTER_BUTTON, submitRegister], // true to focus
|
||||
[DEMO_BUTTON, submitDemo], // true to focus
|
||||
],
|
||||
});
|
||||
|
||||
events.once('ACCOUNT', function closeLoginCb() {
|
||||
const prompt = document.querySelector('#login'); // Selector of your toast
|
||||
if (prompt) toast.hide({ transitionOut: 'fadeOut' }, prompt, 'event');
|
||||
});
|
||||
}
|
||||
|
||||
events.on('CRYP_SPAWN', function spawnPrompt() {
|
||||
const NAME_INPUT = '<input className="input" type="email" placeholder="name" />';
|
||||
const SPAWN_BUTTON = '<button type="submit">SPAWN</button>';
|
||||
|
||||
const ws = registry.get('ws');
|
||||
|
||||
function submitSpawn(instance, thisToast, button, e, inputs) {
|
||||
const NAME = inputs[0].value;
|
||||
ws.sendCrypSpawn(NAME);
|
||||
instance.hide({ transitionOut: 'fadeOut' }, thisToast, 'button');
|
||||
}
|
||||
|
||||
toast.question({
|
||||
theme: 'dark',
|
||||
color: 'black',
|
||||
timeout: false,
|
||||
// overlay: true,
|
||||
drag: false,
|
||||
close: true,
|
||||
title: 'SPAWN CRYP',
|
||||
position: 'center',
|
||||
inputs: [
|
||||
[NAME_INPUT, 'change', null, true], // true to focus
|
||||
],
|
||||
buttons: [
|
||||
[SPAWN_BUTTON, submitSpawn], // true to focus
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
tutorial('welcome');
|
||||
|
||||
return {
|
||||
errorPrompt,
|
||||
loginPrompt,
|
||||
setAccount,
|
||||
setActiveSkill,
|
||||
setCryps,
|
||||
setCrypList,
|
||||
setGame,
|
||||
setMenu,
|
||||
setPlayer,
|
||||
setPlayerList,
|
||||
setVbox,
|
||||
setWs,
|
||||
setGameList,
|
||||
setZone,
|
||||
setScores,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = registerEvents;
|
||||
@ -1,17 +0,0 @@
|
||||
const renderCryps = require('./scenes/cryps');
|
||||
|
||||
const createSocket = require('./socket');
|
||||
const registerEvents = require('./events');
|
||||
const createTutorial = require('./tutorial');
|
||||
|
||||
document.fonts.load('10pt "Jura"').then(() => {
|
||||
const game = renderCryps();
|
||||
const tutorial = createTutorial();
|
||||
const events = registerEvents(game.registry, game.events, tutorial);
|
||||
const ws = createSocket(events);
|
||||
|
||||
// events.setWs(ws);
|
||||
// events.setGameList([]);
|
||||
|
||||
ws.connect();
|
||||
});
|
||||
@ -1,13 +0,0 @@
|
||||
const genAvatar = (name) => {
|
||||
let hash = 0;
|
||||
if (name.length === 0) return hash;
|
||||
// Probs don't need to hash using the whole string
|
||||
for (let i = 0; i < name.length; i += 1) {
|
||||
const chr = name.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
hash = hash & 10000; // We have avatars named 0-19
|
||||
}
|
||||
return `sprite${hash}`;
|
||||
};
|
||||
|
||||
module.exports = genAvatar;
|
||||
@ -1,166 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
|
||||
const CHART = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
uniform float time;
|
||||
uniform vec2 mouse;
|
||||
uniform vec2 resolution;
|
||||
|
||||
float rand(float n){return fract(sin(n) * 43758.5453123 * time * 0.00001);}
|
||||
|
||||
float noise(float p){
|
||||
float fl = floor(p);
|
||||
float fc = fract(p);
|
||||
// return mix(rand(fl), rand(fl + 1.0), p);
|
||||
return mix(rand(fl), rand(fl + 1.0), p);
|
||||
}
|
||||
|
||||
float getLine(vec2 p, float y){
|
||||
float margin = 0.;
|
||||
|
||||
vec2 pos = p;
|
||||
float a = time * 100. + y * 31.;
|
||||
vec2 lineCenter = vec2(0.5, y);
|
||||
|
||||
pos -= lineCenter;
|
||||
pos *- mat2(cos(a), -sin(a), sin(a), cos(a));
|
||||
pos += lineCenter;
|
||||
|
||||
|
||||
float marginb = 0.005;
|
||||
float b = 0.004;
|
||||
float t = y + (noise((pos.x + y) * 100.) - 0.5) * 0.02;
|
||||
float f = (smoothstep(t - b, t, pos.y) - smoothstep(t, t + b, pos.y));
|
||||
f *= smoothstep(margin - marginb, margin, pos.x) - smoothstep(1. - margin, 1. - margin + marginb, pos.x);
|
||||
f *= 0.8;
|
||||
|
||||
float light = 0.5 + 0.5 * sin(time * .2);
|
||||
vec2 point = vec2(margin + light * (1. - margin * 2.), t);
|
||||
f += .008 / distance(pos, point);
|
||||
return f;
|
||||
}
|
||||
|
||||
void main( void ) {
|
||||
vec2 p = gl_FragCoord.xy / resolution.xy;
|
||||
float f = 0.;
|
||||
|
||||
for(int i = 0; i < 10; i++){
|
||||
f += getLine(p, 0.1 + (0.8) / 10. * float(i));
|
||||
}
|
||||
|
||||
vec3 color = vec3(0., .4, .6) * f;
|
||||
gl_FragColor = vec4(color, 1.);
|
||||
}`;
|
||||
|
||||
const STARS = `
|
||||
//--- hatsuyuki ---
|
||||
// by Catzpaw 2016
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
uniform float time;
|
||||
uniform vec2 resolution;
|
||||
float hash(float x){
|
||||
return fract(sin(x*133.3)*12.13);
|
||||
}
|
||||
void main(void){
|
||||
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
|
||||
vec3 c=vec3(.2,.2,.2);
|
||||
float a=4.4;
|
||||
float si=sin(a),co=cos(a);
|
||||
uv*=mat2(co,-si,si,co);
|
||||
uv*=length(uv+vec2(0,1.9))*.5+1.;
|
||||
float v=1.-sin(hash(floor(uv.x*200.))*2.);
|
||||
float b=clamp(abs(sin(5.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;
|
||||
c*=v*b;
|
||||
gl_FragColor = vec4(c,2);
|
||||
}
|
||||
`;
|
||||
|
||||
const PLASMA = `
|
||||
precision mediump float;
|
||||
|
||||
uniform sampler2D uMainSampler;
|
||||
uniform vec2 resolution;
|
||||
uniform float time;
|
||||
|
||||
varying vec2 outTexCoord;
|
||||
varying vec4 outTint;
|
||||
|
||||
#define MAX_ITER 4
|
||||
|
||||
void main( void )
|
||||
{
|
||||
vec2 v_texCoord = gl_FragCoord.xy / resolution;
|
||||
|
||||
vec2 p = v_texCoord * 8.0 - vec2(20.0);
|
||||
vec2 i = p;
|
||||
float c = 1.0;
|
||||
float inten = .05;
|
||||
|
||||
for (int n = 0; n < MAX_ITER; n++)
|
||||
{
|
||||
float t = time * (1.0 - (3.0 / float(n+1)));
|
||||
|
||||
i = p + vec2(cos(t - i.x) + sin(t + i.y),
|
||||
sin(t - i.y) + cos(t + i.x));
|
||||
|
||||
c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten),
|
||||
p.y / (cos(i.y+t)/inten)));
|
||||
}
|
||||
|
||||
c /= float(MAX_ITER);
|
||||
c = 1.5 - sqrt(c);
|
||||
|
||||
vec4 texColor = vec4(0.01, 0.01, 0.01, 1.0);
|
||||
|
||||
texColor.rgb *= (1.0 / (1.0 - (c + 0.05)));
|
||||
|
||||
gl_FragColor = texColor;
|
||||
}
|
||||
`;
|
||||
|
||||
const CustomPipeline = new Phaser.Class({
|
||||
Extends: Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline,
|
||||
initialize: function CustomPipeline (game) {
|
||||
Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline.call(this, {
|
||||
game,
|
||||
renderer: game.renderer,
|
||||
fragShader: STARS,
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
class Background extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'Background', active: true });
|
||||
this.bgTime = 10.0;
|
||||
}
|
||||
|
||||
create() {
|
||||
const game = this.game;
|
||||
this.customPipeline = game.renderer.addPipeline('Custom', new CustomPipeline(game));
|
||||
this.customPipeline.setFloat2('resolution', 1600, 1000);
|
||||
|
||||
const sprite = this.add.sprite(800, 500);
|
||||
sprite.setPipeline('Custom');
|
||||
sprite.displayWidth = 1600 * window.devicePixelRatio;
|
||||
sprite.displayHeight = 1000 * window.devicePixelRatio;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.customPipeline.setFloat1('time', this.bgTime);
|
||||
this.bgTime += 0.005;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Background;
|
||||
@ -1,250 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { POSITIONS: { COMBAT }, DELAYS } = require('./constants');
|
||||
|
||||
const randomColour = () => {
|
||||
const colours = ['green', 'blue', 'red', 'white', 'yellow'];
|
||||
return colours[Math.floor(Math.random() * 5)];
|
||||
};
|
||||
|
||||
const animationParams = (sourceAlly) => {
|
||||
const spawnLocation = sourceAlly ? COMBAT.width() * 0.35 : COMBAT.width() * 0.65;
|
||||
const speed = sourceAlly ? 250 : -250;
|
||||
const img = randomColour();
|
||||
const angleMin = sourceAlly ? 320 : 180;
|
||||
const angleMax = sourceAlly ? 360 : 220;
|
||||
return { spawnLocation, speed, img, angleMin, angleMax };
|
||||
};
|
||||
|
||||
const randomAttack = () => {
|
||||
const animations = ['wall', 'spit', 'gravBlast', 'gravBomb', 'chargeBall'];
|
||||
return animations[Math.floor(Math.random() * 5)];
|
||||
};
|
||||
|
||||
class CombatSkills extends Phaser.GameObjects.Group {
|
||||
constructor(scene) {
|
||||
super(scene);
|
||||
this.scene = scene;
|
||||
}
|
||||
|
||||
getSkill(type, sourceAlly, targetAlly, castLocation) {
|
||||
const genericHeal = ['Heal', 'Triage', 'TriageTick', 'DecayTick'];
|
||||
const genericBlock = ['Block', 'Parry', 'Evasion', 'Shield'];
|
||||
|
||||
if (genericHeal.includes(type)) {
|
||||
this.genericHeal(targetAlly, castLocation);
|
||||
} else if (genericBlock.includes(type)) {
|
||||
this.genericBlock(sourceAlly);
|
||||
} else {
|
||||
this[randomAttack()](sourceAlly);
|
||||
}
|
||||
}
|
||||
|
||||
genericHeal(sourceAlly, castLocation) {
|
||||
// const { sourceX, sourceY } = getCrypPosition(sourcePos, 0);
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
const colour = randomColour();
|
||||
const particles = this.scene.add.particles(colour);
|
||||
const x = sourceAlly ? COMBAT.width() * 0.3 : COMBAT.width() * 0.7;
|
||||
|
||||
const emitter2 = particles.createEmitter({
|
||||
x: castLocation.x,
|
||||
y: castLocation.y,
|
||||
moveToX: x,
|
||||
moveToY: COMBAT.height() * 0.2,
|
||||
speed: 500,
|
||||
lifespan: lifespan / 3,
|
||||
scale: { start: 0.5, end: 1 },
|
||||
quantity: 3,
|
||||
_frequency: 20,
|
||||
blendMode: 'ADD',
|
||||
emitZone: { source: new Phaser.Geom.Rectangle(-200, -100, 400, 200) },
|
||||
});
|
||||
|
||||
const emitter = particles.createEmitter({
|
||||
x,
|
||||
y: COMBAT.height() * 0.2,
|
||||
angle: { min: 250, max: 290 },
|
||||
speed: 250,
|
||||
gravityY: 1000,
|
||||
quantity: 4,
|
||||
scale: { start: 0.1, end: 1 },
|
||||
blendMode: 'ADD',
|
||||
lifespan,
|
||||
active: false,
|
||||
});
|
||||
|
||||
|
||||
this.add(particles);
|
||||
this.scene.time.delayedCall(lifespan / 3, () => { emitter2.stop(); }, [], this);
|
||||
this.scene.time.delayedCall(lifespan / 3, () => { emitter.active = true; }, [], this);
|
||||
|
||||
this.scene.time.delayedCall(lifespan, () => { emitter.stop(); }, [], this);
|
||||
}
|
||||
|
||||
genericBlock(sourceAlly) {
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
const colour = randomColour();
|
||||
const x = sourceAlly ? COMBAT.width() * 0.3 : COMBAT.width() * 0.7;
|
||||
const emitter1 = this.scene.add.particles(colour).createEmitter({
|
||||
x,
|
||||
y: COMBAT.height() * 0.4,
|
||||
scale: { start: 0.75, end: 0.25 },
|
||||
blendMode: 'ADD',
|
||||
emitZone: {
|
||||
source: new Phaser.Geom.Rectangle(-100, -100, 200, 200),
|
||||
type: 'edge',
|
||||
quantity: 24,
|
||||
yoyo: true,
|
||||
},
|
||||
});
|
||||
const emitter2 = this.scene.add.particles(colour).createEmitter({
|
||||
x,
|
||||
y: COMBAT.height() * 0.4,
|
||||
blendMode: 'SCREEN',
|
||||
scale: { start: 0.2, end: 0 },
|
||||
speed: { min: -100, max: 100 },
|
||||
quantity: 50,
|
||||
active: false,
|
||||
emitZone: {
|
||||
source: new Phaser.Geom.Rectangle(-100, -100, 200, 200),
|
||||
type: 'edge',
|
||||
quantity: 50,
|
||||
},
|
||||
});
|
||||
this.scene.time.delayedCall(lifespan / 2, () => { emitter1.stop(); }, [], this);
|
||||
this.scene.time.delayedCall(lifespan / 2, () => { emitter2.active = true; }, [], this);
|
||||
this.scene.time.delayedCall(lifespan, () => { emitter2.stop(); }, [], this);
|
||||
}
|
||||
|
||||
wall(sourceAlly) {
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
const { spawnLocation, speed, img } = animationParams(sourceAlly);
|
||||
const particles = this.scene.add.particles(img);
|
||||
const emitter = particles.createEmitter({
|
||||
x: spawnLocation,
|
||||
y: { min: COMBAT.height() * 0.2, max: COMBAT.height() * 0.5 },
|
||||
speedX: { min: speed, max: speed * 2 },
|
||||
scale: { start: 0.4, end: 0 },
|
||||
quantity: 4,
|
||||
blendMode: 'ADD',
|
||||
lifespan,
|
||||
});
|
||||
this.add(particles);
|
||||
this.scene.time.delayedCall(1000, () => { emitter.stop(); }, [], this.scene);
|
||||
}
|
||||
|
||||
spit(sourceAlly) {
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
const { spawnLocation, speed, img, angleMin, angleMax } = animationParams(sourceAlly);
|
||||
const particles = this.scene.add.particles(img);
|
||||
const emitter = particles.createEmitter({
|
||||
x: spawnLocation,
|
||||
y: COMBAT.height() * 0.35,
|
||||
angle: { min: angleMin, max: angleMax },
|
||||
speed: speed * 2,
|
||||
scale: { start: 0.4, end: 1 },
|
||||
gravityY: 250,
|
||||
quantity: 4,
|
||||
blendMode: 'ADD',
|
||||
lifespan,
|
||||
});
|
||||
this.add(particles);
|
||||
this.scene.time.delayedCall(lifespan, () => { emitter.stop(); }, [], this);
|
||||
}
|
||||
|
||||
gravBomb(sourceAlly) {
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
|
||||
const { spawnLocation, img } = animationParams(!sourceAlly);
|
||||
const particles = this.scene.add.particles(img);
|
||||
const well = particles.createGravityWell({
|
||||
x: spawnLocation,
|
||||
y: COMBAT.height() * 0.25,
|
||||
power: 4,
|
||||
gravity: 500,
|
||||
});
|
||||
this.emitter = particles.createEmitter({
|
||||
x: spawnLocation,
|
||||
y: COMBAT.height() * 0.25,
|
||||
speed: 1000,
|
||||
scale: { start: 0.7, end: 1 },
|
||||
blendMode: 'ADD',
|
||||
lifespan,
|
||||
});
|
||||
this.add(particles);
|
||||
this.scene.time.delayedCall(lifespan, () => { this.emitter.stop(); well.active = false; }, [], this.scene);
|
||||
}
|
||||
|
||||
gravBlast(sourceAlly) {
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
const WELL_END = lifespan / 2;
|
||||
|
||||
const img = randomColour();
|
||||
const spawnLocation = sourceAlly ? COMBAT.width() * 0.35 : COMBAT.width() * 0.65;
|
||||
const isEnemyLocation = sourceAlly ? COMBAT.width() * 0.7 : COMBAT.width() * 0.3;
|
||||
const particles = this.scene.add.particles(img);
|
||||
const bounds = sourceAlly
|
||||
? { x: COMBAT.width() * 0.3, y: COMBAT.height() * 0.2, w: COMBAT.width() * 0.5, h: COMBAT.height() * 0.2 }
|
||||
: { x: 0.2 * COMBAT.width(), y: COMBAT.height() * 0.2, w: COMBAT.width() * 0.5, h: COMBAT.height() * 0.2 };
|
||||
const well = particles.createGravityWell({
|
||||
x: spawnLocation,
|
||||
y: COMBAT.height() * 0.35,
|
||||
power: 4,
|
||||
gravity: 500,
|
||||
});
|
||||
const emitter = particles.createEmitter({
|
||||
x: spawnLocation,
|
||||
y: COMBAT.height() * 0.35,
|
||||
speed: 1000,
|
||||
scale: { start: 0.7, end: 1 },
|
||||
blendMode: 'ADD',
|
||||
bounds,
|
||||
lifespan,
|
||||
});
|
||||
this.add(particles);
|
||||
this.scene.time.delayedCall(WELL_END, () => { emitter.stop(); well.x = isEnemyLocation; }, [], this.scene);
|
||||
this.scene.time.delayedCall(lifespan, () => { well.active = false; }, [], this.scene);
|
||||
}
|
||||
|
||||
chargeBall(sourceAlly) {
|
||||
const lifespan = DELAYS.ANIMATION_DURATION;
|
||||
const CHARGE_LIFESPAN = lifespan / 3;
|
||||
|
||||
const { img, spawnLocation } = animationParams(sourceAlly);
|
||||
const targetLocation = sourceAlly ? 0.7 * COMBAT.width() : 0.25 * COMBAT.width();
|
||||
const particles = this.scene.add.particles(img);
|
||||
const emitter = particles.createEmitter({
|
||||
x: 0,
|
||||
y: 0,
|
||||
moveToX: spawnLocation,
|
||||
moveToY: COMBAT.height() * 0.1,
|
||||
scale: 0.75,
|
||||
quantity: 4,
|
||||
_frequency: 20,
|
||||
blendMode: 'ADD',
|
||||
emitZone: { source: new Phaser.Geom.Rectangle(0, 0, COMBAT.width(), COMBAT.height()) },
|
||||
lifespan: CHARGE_LIFESPAN,
|
||||
});
|
||||
const emitter2 = particles.createEmitter({
|
||||
radial: false,
|
||||
x: { min: spawnLocation, max: targetLocation, steps: 90 },
|
||||
y: { min: COMBAT.height() * 0.1, max: COMBAT.height() * 0.4, steps: 90 },
|
||||
quantity: 4,
|
||||
gravityY: 0,
|
||||
scale: { start: 2, end: 0.1, ease: 'Power3' },
|
||||
blendMode: 'ADD',
|
||||
active: false,
|
||||
lifespan: CHARGE_LIFESPAN,
|
||||
});
|
||||
this.add(particles);
|
||||
this.scene.time.delayedCall(CHARGE_LIFESPAN, () => { emitter.stop(); }, [], this.scene);
|
||||
this.scene.time.delayedCall(CHARGE_LIFESPAN * 2, () => { emitter2.active = true; }, [], this.scene);
|
||||
this.scene.time.delayedCall(lifespan, () => { emitter2.stop(); }, [], this.scene);
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
this.children.entries.forEach(obj => obj.destroy());
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CombatSkills;
|
||||
@ -1,239 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const genAvatar = require('./avatar');
|
||||
const StatBar = require('./elements/combat.statbar');
|
||||
|
||||
const { DELAYS, TEXT, POSITIONS: { COMBAT } } = require('./constants');
|
||||
|
||||
const CRYP_MARGIN = COMBAT.crypMargin();
|
||||
const TEXT_MARGIN = COMBAT.textMargin();
|
||||
|
||||
const crypAvatarText = (team, iter) => {
|
||||
const nameX = COMBAT.width() * team;
|
||||
const nameY = COMBAT.y() + CRYP_MARGIN * iter + COMBAT.height() * 0.07;
|
||||
const statusX = COMBAT.width() * team;
|
||||
const statusY = COMBAT.y() + TEXT_MARGIN * 6 + CRYP_MARGIN * iter + COMBAT.height() * 0.07;
|
||||
return { statusX, statusY, nameX, nameY };
|
||||
};
|
||||
|
||||
const crypEffects = (team, iter) => {
|
||||
const crypEffectsX = team ? COMBAT.width() - COMBAT.width() / 6.5 : COMBAT.width() / 6.5;
|
||||
const crypEffectsY = TEXT_MARGIN * 2 + CRYP_MARGIN * iter;
|
||||
return { crypEffectsX, crypEffectsY };
|
||||
};
|
||||
|
||||
const crypPosition = (team, iter) => {
|
||||
const crypAvatarX = team ? COMBAT.width() - COMBAT.width() / 6 : COMBAT.width() / 6;
|
||||
const crypAvatarY = TEXT_MARGIN * 5 + CRYP_MARGIN * iter;
|
||||
return { crypAvatarX, crypAvatarY };
|
||||
};
|
||||
|
||||
|
||||
class Effects extends Phaser.GameObjects.Group {
|
||||
constructor(scene, team, iter) {
|
||||
super(scene);
|
||||
this.scene = scene;
|
||||
const { crypEffectsX, crypEffectsY } = crypEffects(team, iter);
|
||||
this.x = crypEffectsX; this.y = crypEffectsY;
|
||||
this.effectCount = 0;
|
||||
}
|
||||
|
||||
addEffect(effect) {
|
||||
const y = this.y + this.effectCount * TEXT_MARGIN;
|
||||
const text = `${effect.effect} for ${effect.duration} turn`;
|
||||
const e = this.scene.add.text(this.x, y, text, TEXT.NORMAL);
|
||||
e.effect = effect.effect;
|
||||
this.add(e);
|
||||
this.effectCount += 1;
|
||||
}
|
||||
|
||||
removeEffect(effect) {
|
||||
this.children.entries.forEach((e) => {
|
||||
if (e.effect === effect) e.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
update(effects) {
|
||||
this.effectCount = 0;
|
||||
this.children.entries.forEach(e => e.destroy());
|
||||
effects.forEach((effect) => {
|
||||
this.addEffect(effect);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class CrypImage extends Phaser.GameObjects.Image {
|
||||
constructor(scene, team, iter, cryp) {
|
||||
// Get coords
|
||||
const { crypAvatarX, crypAvatarY } = crypPosition(team, iter);
|
||||
const { statusX, statusY, nameX, nameY } = crypAvatarText(team, iter);
|
||||
|
||||
// Cryp display
|
||||
// const avatar = team ? 'magmar' : 'alk';
|
||||
super(scene, crypAvatarX, crypAvatarY, 'aztec', genAvatar(cryp.name));
|
||||
this.setScale(0.5);
|
||||
|
||||
if (!team) this.flipX = true;
|
||||
|
||||
// Save position and cryp details
|
||||
this.scene = scene;
|
||||
this.iter = iter;
|
||||
this.team = team;
|
||||
this.cryp = cryp;
|
||||
this.state = 'deselect';
|
||||
// Add cryp name
|
||||
scene.add.text(nameX, nameY, cryp.name, TEXT.NORMAL).setOrigin(team, 0);
|
||||
// Add cryp stat bars
|
||||
this.health = scene.add.existing(new StatBar(scene, this, 'HP'));
|
||||
this.red_shield = scene.add.existing(new StatBar(scene, this, 'Red Shield'));
|
||||
this.blue_shield = scene.add.existing(new StatBar(scene, this, 'Blue Shield'));
|
||||
// this.evasion = scene.add.existing(new StatBar(scene, this, 'Evasion'));
|
||||
|
||||
this.effects = scene.add.existing(new Effects(scene, team, iter));
|
||||
this.statusText = scene.add.text(statusX, statusY, '', TEXT.NORMAL);
|
||||
}
|
||||
|
||||
select() {
|
||||
this.setTint('0x00bb00');
|
||||
this.state = 'select';
|
||||
}
|
||||
|
||||
setKo() {
|
||||
this.state = 'ko';
|
||||
this.setTint('0x9d9ea0');
|
||||
}
|
||||
|
||||
deselect() {
|
||||
if (this.state !== 'ko') {
|
||||
this.clearTint();
|
||||
this.state = 'deselect';
|
||||
}
|
||||
}
|
||||
|
||||
clearStatus() {
|
||||
this.statusText.text = '';
|
||||
}
|
||||
|
||||
reduceDefense(amount, type) {
|
||||
if (type === 'PhysDmg') {
|
||||
this.red_shield.takeDamage(amount);
|
||||
} else if (type === 'BlueDmg') {
|
||||
this.blue_shield.takeDamage(amount);
|
||||
}
|
||||
}
|
||||
|
||||
takeDamage(props) {
|
||||
const { amount, mitigation, category } = props;
|
||||
if (mitigation) this.reduceDefense(mitigation, category);
|
||||
this.setTint(0xff0000);
|
||||
this.health.takeDamage(amount);
|
||||
this.scene.time.delayedCall(DELAYS.DAMAGE_TICK, () => {
|
||||
if (this.state !== 'ko') this.clearTint();
|
||||
});
|
||||
}
|
||||
|
||||
takeHealing(amount) {
|
||||
this.setTint(0x00bb00);
|
||||
this.health.takeDamage(amount * -1);
|
||||
this.scene.time.delayedCall(DELAYS.DAMAGE_TICK, () => {
|
||||
if (this.state !== 'ko') this.clearTint();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class CombatCryps extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'CombatCryps' });
|
||||
}
|
||||
|
||||
create(game) {
|
||||
this.cryps = this.add.group();
|
||||
this.phase = game.phase;
|
||||
this.account = this.registry.get('account');
|
||||
this.drawCryps(game);
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
this.registry.set('crypStatusUpdate', false);
|
||||
this.teams = game.teams.length;
|
||||
}
|
||||
|
||||
updateData(parent, key, data) {
|
||||
if (key === 'game' && data) {
|
||||
if (data.teams.length !== this.teams) this.scene.restart(data);
|
||||
const isAnimating = this.phase === 'animating';
|
||||
this.game = data;
|
||||
if (isAnimating) return false;
|
||||
}
|
||||
|
||||
if (key === 'gamePhase' && data) {
|
||||
const shouldUpdate = data !== this.phase;
|
||||
this.phase = data;
|
||||
if (shouldUpdate) {
|
||||
this.cryps.children.entries.forEach(c => c.clearStatus());
|
||||
this.drawCryps(this.game);
|
||||
}
|
||||
}
|
||||
|
||||
if (key === 'crypStatusUpdate' && data) {
|
||||
this.updateCrypStatus(data);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
drawCryps(game) {
|
||||
const renderCryp = (cryp, iter, team) => {
|
||||
// Add Image Avatar Class
|
||||
const crypObj = new CrypImage(this, team, iter, cryp);
|
||||
this.add.existing(crypObj);
|
||||
this.cryps.add(crypObj);
|
||||
return crypObj;
|
||||
};
|
||||
|
||||
const renderTeam = (cryp, iter, team) => {
|
||||
const crypObj = this.cryps.children.entries
|
||||
.find(c => c.cryp.id === cryp.id)
|
||||
|| renderCryp(cryp, iter, team);
|
||||
crypObj.health.val = cryp.hp.value;
|
||||
crypObj.red_shield.val = cryp.red_shield.value;
|
||||
crypObj.blue_shield.val = cryp.red_shield.value;
|
||||
|
||||
crypObj.health.drawStatBar();
|
||||
crypObj.red_shield.drawStatBar();
|
||||
crypObj.blue_shield.drawStatBar();
|
||||
crypObj.effects.update(cryp.effects);
|
||||
};
|
||||
|
||||
const allyTeam = game.teams.find(t => t.id === this.account.id);
|
||||
// in future there will be more than one
|
||||
const [enemyTeam] = game.teams.filter(t => t.id !== this.account.id);
|
||||
|
||||
allyTeam.cryps.forEach((cryp, i) => renderTeam(cryp, i, 0));
|
||||
if (!enemyTeam) return false;
|
||||
enemyTeam.cryps.forEach((cryp, i) => renderTeam(cryp, i, 1));
|
||||
return true;
|
||||
}
|
||||
|
||||
selectCryp(crypId) {
|
||||
this.cryps.children.entries.forEach(c => c.deselect());
|
||||
if (crypId) this.cryps.children.entries.find(c => c.cryp.id === crypId).select();
|
||||
}
|
||||
|
||||
updateCrypStatus(status) {
|
||||
const sourceCryp = this.cryps.children.entries
|
||||
.find(c => c.cryp.id === status.id);
|
||||
|
||||
const targetCryp = this.cryps.children.entries
|
||||
.find(c => c.cryp.id === status.target);
|
||||
|
||||
if (this.phase === 'Skill') {
|
||||
sourceCryp.statusText.text = `${status.skill} on ${targetCryp.cryp.name}`;
|
||||
}
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CombatCryps;
|
||||
@ -1,89 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { POSITIONS: { COMBAT } } = require('./constants');
|
||||
|
||||
const CRYP_MARGIN = COMBAT.crypMargin();
|
||||
const BOX_HEIGHT = CRYP_MARGIN * 0.8;
|
||||
const BOX_WIDTH = COMBAT.width() * 0.2;
|
||||
|
||||
|
||||
class CrypHitBox extends Phaser.GameObjects.Rectangle {
|
||||
constructor(scene, iter, team, cback) {
|
||||
const y = COMBAT.y() + COMBAT.height() * 0.05 + CRYP_MARGIN * iter;
|
||||
super(scene, (COMBAT.width() - BOX_WIDTH) * team, y, BOX_WIDTH, BOX_HEIGHT, 0x222222);
|
||||
this.setOrigin(0);
|
||||
this.clickHandler = () => cback();
|
||||
}
|
||||
|
||||
select() {
|
||||
this.setFillStyle(0x003300);
|
||||
}
|
||||
|
||||
deselect() {
|
||||
this.setFillStyle(0x222222);
|
||||
}
|
||||
}
|
||||
|
||||
class CombatHitBox extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'CombatHitBox' });
|
||||
}
|
||||
|
||||
create(phase) {
|
||||
this.phase = phase;
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
if (phase === 'animating') return true;
|
||||
this.selectHitBox(phase);
|
||||
return true;
|
||||
}
|
||||
|
||||
updateData(parent, key, data) {
|
||||
if (key === 'game' && data) {
|
||||
// In the case that we hit skill phase but teams change we restart
|
||||
if (data.teams.length !== this.teams) this.scene.restart(data.phase);
|
||||
}
|
||||
if (key === 'gamePhase' && data) {
|
||||
const shouldUpdate = data !== this.phase;
|
||||
if (shouldUpdate) this.scene.restart(data);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
selectHitBox(phase) {
|
||||
const game = this.registry.get('game');
|
||||
this.teams = game.teams.length;
|
||||
if (phase === 'Skill') return this.skillHitBox(game);
|
||||
return false;
|
||||
}
|
||||
|
||||
skillHitBox(game) {
|
||||
const account = this.registry.get('account');
|
||||
const group = this.scene.get('CombatCryps').cryps;
|
||||
const skillScene = this.scene.get('CombatSkills');
|
||||
game.teams.forEach((t) => {
|
||||
t.cryps.forEach((c) => {
|
||||
const cback = () => {
|
||||
const { activeSkill } = skillScene;
|
||||
if (activeSkill) {
|
||||
this.scene.get('CombatSkills').clearCrypActive(activeSkill.cryp.id);
|
||||
activeSkill.activate();
|
||||
skillScene.activeSkill = null;
|
||||
this.game.events.emit('SEND_SKILL', game.id, activeSkill.cryp.id, c.id, activeSkill.skill.skill);
|
||||
}
|
||||
};
|
||||
const crypSpawn = group.children.entries.find(s => s.cryp.id === c.id);
|
||||
const team = c.account === account.id ? 0 : 1;
|
||||
if (crypSpawn) this.add.existing(new CrypHitBox(this, crypSpawn.iter, team, cback));
|
||||
});
|
||||
});
|
||||
this.scene.moveBelow('Combat');
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CombatHitBox;
|
||||
@ -1,138 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { throttle } = require('lodash');
|
||||
|
||||
const { TEXT, POSITIONS: { COMBAT } } = require('./constants');
|
||||
const CombatLog = require('./combat.log');
|
||||
const CombatCryps = require('./combat.cryps');
|
||||
const CombatSkills = require('./combat.skills');
|
||||
const CombatHitBox = require('./combat.hitbox');
|
||||
|
||||
const renderResolutions = require('./combat.render.resolutions');
|
||||
|
||||
|
||||
class Combat extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'Combat' });
|
||||
}
|
||||
|
||||
preload() {
|
||||
this.load.image('proj', 'https://labs.phaser.io/assets/sprites/bullet.png');
|
||||
this.load.image('blue', 'https://labs.phaser.io/assets/particles/blue.png');
|
||||
this.load.image('green', 'https://labs.phaser.io/assets/particles/green.png');
|
||||
this.load.image('red', 'https://labs.phaser.io/assets/particles/red.png');
|
||||
this.load.image('white', 'https://labs.phaser.io/assets/particles/white.png');
|
||||
this.load.image('yellow', 'https://labs.phaser.io/assets/particles/yellow.png');
|
||||
}
|
||||
|
||||
create() {
|
||||
console.log('creating game');
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
this.addLeaveGame();
|
||||
|
||||
this.registry.set('gamePhase', false);
|
||||
this.registry.set('inGame', true);
|
||||
this.registry.set('gameAnimating', false);
|
||||
this.account = this.registry.get('account');
|
||||
this.fetchGame = throttle(() => {
|
||||
const game = this.registry.get('game');
|
||||
if (game) {
|
||||
const ws = this.registry.get('ws');
|
||||
return ws.sendGameState(game.id);
|
||||
}
|
||||
return false;
|
||||
}, 500);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
startGame(game) {
|
||||
this.scene.manager.add('CombatCryps', CombatCryps, true, game);
|
||||
this.scene.manager.add('CombatLog', CombatLog, true, game);
|
||||
this.renderedResolves = game.resolved.length; // In case you rejoin mid way
|
||||
this.scene.manager.add('CombatSkills', CombatSkills, true, game.phase);
|
||||
this.scene.manager.add('CombatHitBox', CombatHitBox, true, game.phase);
|
||||
this.registry.set('gamePhase', game.phase);
|
||||
this.phase = game.phase;
|
||||
return true;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.fetchGame();
|
||||
return true;
|
||||
}
|
||||
|
||||
updateData(parent, key, data) {
|
||||
if (key === 'game') {
|
||||
if (!data) return false;
|
||||
const startGame = this.registry.get('gamePhase') === false;
|
||||
if (startGame) { this.startGame(data); return true; }
|
||||
this.checkAnimation(data);
|
||||
// Game over?
|
||||
// if (data.phase === 'Finish') {
|
||||
// this.time.delayedCall(10000, () => {
|
||||
// this.endGame();
|
||||
// });
|
||||
// }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
checkAnimation(game) {
|
||||
// Check cryps are loaded and whether game is animating
|
||||
const cantAnimate = this.registry.get('gamePhase') === 'animating';
|
||||
if (cantAnimate) return false;
|
||||
if (game.resolved.length !== this.renderedResolves) {
|
||||
const newResolutions = game.resolved.slice(this.renderedResolves);
|
||||
renderResolutions(this, game, newResolutions);
|
||||
this.renderedResolves = game.resolved.length;
|
||||
return true;
|
||||
}
|
||||
if (this.phase !== game.phase) {
|
||||
this.phase = game.phase;
|
||||
this.registry.set('gamePhase', game.phase);
|
||||
}
|
||||
if (this.registry.get('gameLog') !== game.log.length) {
|
||||
this.registry.set('gameLog', game.log.length);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
addLeaveGame() {
|
||||
const leaveGame = () => this.cleanUp();
|
||||
this.input.keyboard.on('keydown_BACKSPACE', leaveGame, 0, this);
|
||||
const LEAVE_HEIGHT = COMBAT.height() / 6;
|
||||
const LEAVE_WIDTH = COMBAT.width() / 5;
|
||||
const LEAVE_X = COMBAT.width() * 0.8;
|
||||
const LEAVE_Y = COMBAT.height() * 0.9;
|
||||
|
||||
const menu = this.add
|
||||
.rectangle(LEAVE_X, LEAVE_Y, LEAVE_WIDTH, LEAVE_HEIGHT, 0x440000)
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', leaveGame);
|
||||
|
||||
this.add
|
||||
.text(menu.getCenter().x, menu.getCenter().y, 'Menu', TEXT.HEADER)
|
||||
.setOrigin(0.5, 0.5);
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.registry.events.off('changedata', this.updateData, this);
|
||||
this.registry.events.off('setdata', this.updateData, this);
|
||||
|
||||
this.registry.set('inGame', null);
|
||||
this.registry.set('menu', true);
|
||||
this.registry.set('game', null);
|
||||
|
||||
const ACTIVE_SCENES = ['CombatLog', 'CombatCryps', 'CombatSkills', 'CombatHitBox'];
|
||||
ACTIVE_SCENES.forEach((sKey) => {
|
||||
if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp();
|
||||
});
|
||||
this.scene.remove();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Combat;
|
||||
@ -1,50 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { POSITIONS: { COMBAT }, TEXT } = require('./constants');
|
||||
|
||||
class CombatLog extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'CombatLog' });
|
||||
}
|
||||
|
||||
create(game) {
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
this.cameras.main.setViewport(COMBAT.LOG.x(), COMBAT.LOG.y(), COMBAT.LOG.width(), COMBAT.LOG.height());
|
||||
this.log = this.add.text(0, 0, '', TEXT.NORMAL);
|
||||
this.logIndex = game.log.length;
|
||||
this.logData = game.log;
|
||||
this.log.setWordWrapWidth(COMBAT.LOG.width());
|
||||
this.log.setText(Array.from(game.log).reverse());
|
||||
}
|
||||
|
||||
updateData(parent, key, data) {
|
||||
const UPDATE_KEYS = ['game', 'gameLog'];
|
||||
if (UPDATE_KEYS.includes(key) && data) {
|
||||
if (key === 'game') {
|
||||
this.logData = data.log;
|
||||
}
|
||||
if (key === 'gameLog') {
|
||||
this.logIndex = data;
|
||||
}
|
||||
this.updateLog();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
updateLog() {
|
||||
// shallow copy because reverse mutates
|
||||
if (this.logData.length > this.logIndex + 1
|
||||
&& Array.from(this.logData)[this.logIndex].slice(-2) === 'KO') {
|
||||
this.logIndex += 1;
|
||||
this.registry.set('gameLog', this.logIndex);
|
||||
}
|
||||
// }
|
||||
this.log.setText(Array.from(this.logData).slice(0, this.logIndex).reverse());
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CombatLog;
|
||||
@ -1,135 +0,0 @@
|
||||
const { eachSeries } = require('async');
|
||||
|
||||
const CombatAnimations = require('./combat.animations');
|
||||
const {
|
||||
DELAYS: { ANIMATION_DURATION, MOVE_CREEP, DAMAGE_TICK },
|
||||
POSITIONS: { COMBAT },
|
||||
} = require('./constants');
|
||||
|
||||
function findResolutionCryps(scene, group, resolution, game) {
|
||||
const sourceSpawn = group.children.entries.find(c => c.cryp.id === resolution.source.id);
|
||||
|
||||
/* const sourceCryp = game.teams.find(t => t.cryps.find(c => c.id === resolution.source_cryp_id))
|
||||
.cryps.find(c => c.id === resolution.source_cryp_id);
|
||||
|
||||
const targetCryp = game.teams.find(t => t.cryps.find(c => c.id === resolution.target_cryp_id))
|
||||
.cryps.find(c => c.id === resolution.target_cryp_id);
|
||||
*/
|
||||
const targetSpawn = group.children.entries.find(c => c.cryp.id === resolution.target.id);
|
||||
|
||||
return { sourceSpawn, targetSpawn };
|
||||
}
|
||||
|
||||
function calculateTweenParams(sourceSpawn, targetSpawn, account, skill) {
|
||||
const tweenParams = (targets, centreSpot) => {
|
||||
const enemy = targets.cryp.account !== account.id;
|
||||
let x = centreSpot ? COMBAT.width() * 0.3 : targets.x;
|
||||
x = (enemy && centreSpot) ? x + COMBAT.width() * 0.4 : x;
|
||||
const y = centreSpot ? COMBAT.height() * 13.25 / 35 : targets.y;
|
||||
const ease = 'Power1';
|
||||
const duration = MOVE_CREEP;
|
||||
return {
|
||||
targets, x, y, ease, duration,
|
||||
};
|
||||
};
|
||||
let moveSourceBattle = false;
|
||||
let moveSourceOrig = false;
|
||||
const targetOnlySkill = ['DecayTick'];
|
||||
if (!(targetOnlySkill.includes(skill))) {
|
||||
if (sourceSpawn.cryp.account !== targetSpawn.cryp.account) {
|
||||
moveSourceBattle = tweenParams(sourceSpawn, true);
|
||||
moveSourceOrig = tweenParams(sourceSpawn, false);
|
||||
}
|
||||
}
|
||||
|
||||
const moveTargetBattle = tweenParams(targetSpawn, true);
|
||||
const moveTargetOrig = tweenParams(targetSpawn, false);
|
||||
|
||||
return {
|
||||
moveSourceBattle, moveSourceOrig, moveTargetBattle, moveTargetOrig,
|
||||
};
|
||||
}
|
||||
|
||||
function animatePhase(scene, game, resolution, cb) {
|
||||
// return early for disabled skills
|
||||
if (resolution.length === 0) return cb();
|
||||
if (resolution.event[0] === 'Disable'
|
||||
|| resolution.event[0] === 'TargetKo'
|
||||
|| resolution.event === 'Ko') return cb();
|
||||
|
||||
const group = scene.scene.get('CombatCryps').cryps;
|
||||
const animations = new CombatAnimations(scene);
|
||||
const account = scene.registry.get('account');
|
||||
|
||||
// Find cryps, targets
|
||||
const { sourceSpawn, targetSpawn } = findResolutionCryps(scene, group, resolution, game);
|
||||
const {
|
||||
moveSourceBattle, moveSourceOrig, moveTargetBattle, moveTargetOrig,
|
||||
} = calculateTweenParams(sourceSpawn, targetSpawn, account, resolution.event[1].skill);
|
||||
|
||||
const castParams = () => {
|
||||
const x = (sourceSpawn === targetSpawn) ? moveTargetBattle.x : sourceSpawn.x;
|
||||
const y = (sourceSpawn === targetSpawn) ? moveTargetBattle.y : sourceSpawn.y;
|
||||
return { x, y };
|
||||
};
|
||||
const castLocation = castParams();
|
||||
|
||||
// Move cryps into position
|
||||
if (moveSourceBattle) scene.tweens.add(moveSourceBattle);
|
||||
scene.tweens.add(moveTargetBattle);
|
||||
|
||||
return scene.time.delayedCall(MOVE_CREEP, () => {
|
||||
const sourceAlly = sourceSpawn.cryp.account === account.id;
|
||||
const targetAlly = targetSpawn.cryp.account === account.id;
|
||||
// animate animation
|
||||
animations.getSkill(resolution.event[1].skill, sourceAlly, targetAlly, castLocation);
|
||||
// Target cryp takes damage
|
||||
scene.time.delayedCall(ANIMATION_DURATION, () => {
|
||||
console.log(resolution);
|
||||
if (resolution.event[0] === 'Damage') {
|
||||
targetSpawn.takeDamage(resolution.event[1]);
|
||||
scene.registry.set('gameLog', scene.registry.get('gameLog') + 1);
|
||||
}
|
||||
if (resolution.event[0] === 'Healing') {
|
||||
targetSpawn.takeHealing(resolution.event[1]);
|
||||
scene.registry.set('gameLog', scene.registry.get('gameLog') + 1);
|
||||
}
|
||||
if (resolution.event[0] === 'Effect') {
|
||||
targetSpawn.effects.addEffect(resolution.event[1]);
|
||||
console.log('target has new effect', resolution.event[1].effect);
|
||||
}
|
||||
|
||||
if (resolution.event[0] === 'Removal') {
|
||||
targetSpawn.effects.removeEffect(resolution.event[1].effect);
|
||||
console.log('target effect removed', resolution.event[1].effect);
|
||||
}
|
||||
if (moveSourceOrig) scene.tweens.add(moveSourceOrig);
|
||||
scene.tweens.add(moveTargetOrig);
|
||||
|
||||
// all done
|
||||
scene.time.delayedCall(MOVE_CREEP, () => {
|
||||
animations.destroy(true);
|
||||
return cb();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderResolutions(scene, game, resolutions) {
|
||||
scene.registry.set('gamePhase', 'animating');
|
||||
scene.registry.set('gameLog', scene.registry.get('gameLog') + 1);
|
||||
|
||||
eachSeries(
|
||||
resolutions,
|
||||
(resolution, cb) => animatePhase(scene, game, resolution, cb),
|
||||
(err) => {
|
||||
if (err) return console.error(err);
|
||||
scene.registry.set('gamePhase', 'Skill');
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = renderResolutions;
|
||||
@ -1,235 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
|
||||
const { TEXT, POSITIONS: { COMBAT } } = require('./constants');
|
||||
|
||||
const CRYP_KEY_MAP = ['keydown_ONE', 'keydown_TWO', 'keydown_THREE'];
|
||||
const SKILL_KEY_MAP = ['keydown_Q', 'keydown_W', 'keydown_E', 'keydown_R'];
|
||||
const TARGET_KEY_MAP = ['keydown_SEVEN', 'keydown_EIGHT', 'keydown_NINE', 'keydown_ZERO'];
|
||||
|
||||
const CRYP_MARGIN = COMBAT.crypMargin();
|
||||
const TEXT_MARGIN = COMBAT.textMargin();
|
||||
const SKILL_WIDTH = COMBAT.width() / 10;
|
||||
const SKILL_HEIGHT = COMBAT.height() / 30;
|
||||
|
||||
const skillPosition = (crypIter, skillIter) => {
|
||||
const skillTextX = COMBAT.width() / 3.8;
|
||||
const skillTextY = (TEXT_MARGIN * skillIter) * 1.5 + CRYP_MARGIN * crypIter + COMBAT.y() + COMBAT.height() * 0.07;
|
||||
return [skillTextX, skillTextY];
|
||||
};
|
||||
|
||||
const skillCheckHitBox = (scenePlugin, pointer) => {
|
||||
const { list } = scenePlugin.get('CombatHitBox').children;
|
||||
for (let i = 0; i < list.length; i += 1) {
|
||||
if (Phaser.Geom.Rectangle.ContainsPoint(list[i].getBounds(),
|
||||
pointer.position)) return list[i];
|
||||
}
|
||||
// If we didn't find a hitbox deselect them all
|
||||
for (let i = 0; i < list.length; i += 1) list[i].deselect();
|
||||
return false;
|
||||
};
|
||||
|
||||
class CrypSkill extends Phaser.GameObjects.Container {
|
||||
constructor(scene, x, y, skill, cryp) {
|
||||
// Avatar will be a property of cryp
|
||||
super(scene, x, y);
|
||||
const CD_TEXT = skill.cd ? `(${skill.cd}T)` : '';
|
||||
const SKILL_TEXT = `${skill.skill} ${CD_TEXT}`;
|
||||
this.origX = x; this.origY = y;
|
||||
|
||||
this.skillBox = scene.add.rectangle(0, 0, SKILL_WIDTH, SKILL_HEIGHT, 0x222222);
|
||||
this.skillText = scene.add.text(0, 0, SKILL_TEXT, TEXT.NORMAL).setOrigin(0.5, 0.5);
|
||||
this.add(this.skillBox);
|
||||
this.add(this.skillText);
|
||||
|
||||
this.state = 'deselect';
|
||||
this.cryp = cryp;
|
||||
this.skill = skill;
|
||||
this.scene = scene;
|
||||
|
||||
this.setSize(SKILL_WIDTH, SKILL_HEIGHT);
|
||||
this.setInteractive();
|
||||
}
|
||||
|
||||
clickHandler() {
|
||||
if (this.scene.phase === 'Skill') this.scene.activeSkill = this;
|
||||
this.select();
|
||||
}
|
||||
|
||||
select() {
|
||||
this.scene.children.list.forEach((skill) => {
|
||||
if (skill.state === 'select') skill.deselect();
|
||||
});
|
||||
this.skillBox.setFillStyle(0x004bfe);
|
||||
this.state = 'select';
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.scene.children.list.forEach((skill) => {
|
||||
if (skill.state === 'select') skill.deselect();
|
||||
});
|
||||
this.skillBox.setFillStyle(0xff0000);
|
||||
this.state = 'activate';
|
||||
}
|
||||
|
||||
deselect() {
|
||||
this.skillBox.setFillStyle(0x222222);
|
||||
this.state = 'deselect';
|
||||
}
|
||||
}
|
||||
|
||||
class CombatSkills extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'CombatSkills' });
|
||||
}
|
||||
|
||||
create(phase) {
|
||||
this.phase = phase;
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
this.account = this.registry.get('account');
|
||||
|
||||
this.input.on('dragstart', (pointer, box) => {
|
||||
box.clickHandler();
|
||||
});
|
||||
this.input.on('drag', (pointer, box, dragX, dragY) => {
|
||||
const hitBox = skillCheckHitBox(this.scene, pointer);
|
||||
if (hitBox) hitBox.select();
|
||||
box.setPosition(dragX, dragY);
|
||||
});
|
||||
this.input.on('dragend', (pointer, box) => {
|
||||
box.deselect();
|
||||
const hitBox = skillCheckHitBox(this.scene, pointer);
|
||||
if (hitBox) {
|
||||
hitBox.clickHandler();
|
||||
}
|
||||
box.setPosition(box.origX, box.origY);
|
||||
});
|
||||
|
||||
if (phase === 'animating') return true;
|
||||
// can't set this.game cause of phaser class named the same
|
||||
const game = this.registry.get('game');
|
||||
this.renderSkills(game, phase);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
updateData(parent, key, data) {
|
||||
if (key === 'gamePhase' && data) {
|
||||
const shouldUpdate = data !== this.phase;
|
||||
if (shouldUpdate) {
|
||||
this.scene.get('CombatCryps').selectCryp(null);
|
||||
return this.scene.restart(data);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
renderSkills(game, phase) {
|
||||
if (phase === 'Skill') return this.renderSkillPhase(game);
|
||||
return false;
|
||||
}
|
||||
|
||||
renderSkillPhase(game) {
|
||||
const { account } = this;
|
||||
const { keyboard } = this.input;
|
||||
const { events } = this.game;
|
||||
|
||||
const addSkill = (i, j, skill, cryp) => {
|
||||
const skillTextPos = skillPosition(i, j);
|
||||
const skillObj = new CrypSkill(this, skillTextPos[0], skillTextPos[1], skill, cryp);
|
||||
if (skill.cd) {
|
||||
skillObj.skillBox.setFillStyle(0x9d9ea0);
|
||||
} else {
|
||||
this.input.setDraggable(skillObj);
|
||||
}
|
||||
this.add.existing(skillObj);
|
||||
return skillObj;
|
||||
};
|
||||
|
||||
const team = game.teams.find(t => t.id === account.id);
|
||||
const enemyTeam = game.teams.find(t => t.id !== account.id);
|
||||
|
||||
team.cryps.forEach((cryp) => {
|
||||
// return early if KOd
|
||||
if (cryp.hp.value === 0) return true;
|
||||
|
||||
// find the cryp position
|
||||
const { iter } = this.scene.get('CombatCryps').cryps.children.entries.find(c => c.cryp.id === cryp.id);
|
||||
|
||||
// draw the skills
|
||||
const skillButtons = cryp.skills.map((skill, j) => addSkill(iter, j, skill, cryp));
|
||||
|
||||
const bindCrypKeys = () => this.mapSkillKeys(skillButtons, game.id, cryp.id, team.id, enemyTeam.id, iter);
|
||||
|
||||
// reset everything
|
||||
keyboard.on('keydown_ESC', bindCrypKeys, this);
|
||||
events.on('SEND_SKILL', bindCrypKeys, this);
|
||||
bindCrypKeys();
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
// needs to send crypId not team
|
||||
mapSkillKeys(skillButtons, gameId, crypId, alliesId, enemyId, i) {
|
||||
const { keyboard } = this.input;
|
||||
|
||||
keyboard.removeListener(CRYP_KEY_MAP[i]);
|
||||
|
||||
keyboard.on(CRYP_KEY_MAP[i], () => {
|
||||
SKILL_KEY_MAP.forEach(k => keyboard.removeListener(k));
|
||||
|
||||
this.scene.get('CombatCryps').selectCryp(crypId);
|
||||
|
||||
skillButtons.forEach((button, j) => {
|
||||
keyboard.on(SKILL_KEY_MAP[j], () => {
|
||||
this.activeSkill = button;
|
||||
button.select();
|
||||
|
||||
// clear existing keys
|
||||
CRYP_KEY_MAP.forEach(k => keyboard.removeListener(k));
|
||||
TARGET_KEY_MAP.forEach(k => keyboard.removeListener(k));
|
||||
|
||||
CRYP_KEY_MAP.forEach(k => keyboard.on(k, () => {
|
||||
this.clearCrypActive(crypId);
|
||||
button.activate();
|
||||
this.activeSkill = null;
|
||||
this.game.events.emit('SEND_SKILL', gameId, crypId, alliesId, button.skill.skill);
|
||||
}));
|
||||
|
||||
TARGET_KEY_MAP.forEach(k => keyboard.on(k, () => {
|
||||
this.clearCrypActive(crypId);
|
||||
button.activate();
|
||||
this.activeSkill = null;
|
||||
this.game.events.emit('SEND_SKILL', gameId, crypId, enemyId, button.skill.skill);
|
||||
}));
|
||||
}, this);
|
||||
});
|
||||
}, this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
clearCrypActive(crypId) {
|
||||
this.scene.scene.children.list.forEach((s) => {
|
||||
if (s.cryp.id === crypId && s.state === 'activate') s.deselect();
|
||||
});
|
||||
}
|
||||
|
||||
clearKeys() {
|
||||
TARGET_KEY_MAP.forEach(tKey => this.input.keyboard.removeListener(tKey));
|
||||
CRYP_KEY_MAP.forEach(tKey => this.input.keyboard.removeListener(tKey));
|
||||
SKILL_KEY_MAP.forEach(tKey => this.input.keyboard.removeListener(tKey));
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.registry.events.off('changedata', this.updateData);
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CombatSkills;
|
||||
@ -1,388 +0,0 @@
|
||||
// POSITIONING FNS
|
||||
// floors prevent subpixel rendering which looks trash
|
||||
|
||||
const CANVAS_WIDTH = () => Math.floor(window.innerHeight * 1.6);
|
||||
const CANVAS_HEIGHT = () => Math.floor(window.innerHeight);
|
||||
|
||||
const headerWidth = () => CANVAS_WIDTH();
|
||||
const headerHeight = () => Math.floor(CANVAS_HEIGHT() * 0.05);
|
||||
|
||||
const menuCrypListWidth = () => Math.floor(CANVAS_WIDTH() * 0.3);
|
||||
const menuCrypListHeight = () => Math.floor(CANVAS_HEIGHT() - headerHeight());
|
||||
const menuCrypListX = () => Math.floor(CANVAS_WIDTH() * 0.3);
|
||||
const menuCrypListY = () => headerHeight();
|
||||
|
||||
const itemListWidth = () => Math.floor(CANVAS_WIDTH() * 0.5);
|
||||
const itemListHeight = () => Math.floor(CANVAS_HEIGHT() * 0.95);
|
||||
const itemListX = () => 0;
|
||||
const itemListY = () => headerHeight();
|
||||
const itemBlockWidth = () => Math.floor(itemListWidth() * 0.12);
|
||||
const itemBlockHeight = () => Math.floor(itemListHeight() * 0.04);
|
||||
|
||||
const menuNavigationWidth = () => Math.floor(CANVAS_WIDTH() * 0.5);
|
||||
const menuNavigationHeight = () => Math.floor(CANVAS_HEIGHT() * 0.3);
|
||||
const menuNavigationX = () => Math.floor(CANVAS_WIDTH() * 0.5);
|
||||
const menuNavigationY = () => Math.floor(CANVAS_HEIGHT() * 0.7);
|
||||
|
||||
const menuMainWidth = () => Math.floor(CANVAS_WIDTH() * 0.4);
|
||||
const menuMainHeight = () => Math.floor(CANVAS_HEIGHT() * 0.5);
|
||||
const menuMainX = () => Math.floor(CANVAS_WIDTH() * 0.65);
|
||||
const menuMainY = () => headerHeight();
|
||||
|
||||
const homeMainWidth = () => Math.floor(CANVAS_WIDTH() * 0.6);
|
||||
const homeMainHeight = () => Math.floor(CANVAS_HEIGHT() * 0.5);
|
||||
const homeMainX = () => Math.floor(CANVAS_WIDTH() * 0.4);
|
||||
const homeMainY = () => headerHeight();
|
||||
|
||||
const combatWidth = () => CANVAS_WIDTH();
|
||||
const combatHeight = () => CANVAS_HEIGHT() - headerHeight();
|
||||
const combatY = () => headerHeight();
|
||||
const combatX = () => 0;
|
||||
const combatCrypMargin = () => Math.floor((CANVAS_HEIGHT() - headerHeight()) / 4.5);
|
||||
const combatTextMargin = () => Math.floor((CANVAS_HEIGHT() - headerHeight()) / 35);
|
||||
|
||||
const statsWidth = () => Math.floor(CANVAS_WIDTH() - menuCrypListWidth());
|
||||
const statsHeight = () => CANVAS_HEIGHT() - headerHeight();
|
||||
const statsY = () => headerHeight();
|
||||
const statsX = () => menuCrypListWidth();
|
||||
const statsKnownX = () => Math.floor(statsX() + statsWidth() / 4);
|
||||
const statsLearnableX = () => Math.floor(statsX() + statsWidth() / 2);
|
||||
const statsTextMargin = () => 24;
|
||||
const statsLearnableMargin = () => 12;
|
||||
|
||||
const logWidth = () => Math.floor(combatWidth() * 0.5);
|
||||
const logHeight = () => Math.floor(combatHeight() * 0.3);
|
||||
const logY = () => Math.floor(headerHeight() + (combatHeight() * 0.7));
|
||||
const logX = () => Math.floor(combatWidth() * 0.2);
|
||||
|
||||
|
||||
module.exports = {
|
||||
TEXT: {
|
||||
NORMAL: { fontFamily: 'Jura', fontSize: 18, color: '#ffffff' },
|
||||
LEARNABLE: { fontFamily: 'Jura', fontSize: 18, color: '#ffffff' },
|
||||
HEADER: { fontFamily: 'Jura', fontSize: 24, color: '#ffffff', fontStyle: 'bold' },
|
||||
HOVER: { fontFamily: 'Jura', fontSize: 16, color: '#ffffff', backgroundColor: '#222222' },
|
||||
},
|
||||
|
||||
POSITIONS: {
|
||||
HEADER: {
|
||||
width: headerWidth,
|
||||
height: headerHeight,
|
||||
},
|
||||
|
||||
CRYP_LIST: {
|
||||
x: menuCrypListX,
|
||||
y: menuCrypListY,
|
||||
width: menuCrypListWidth,
|
||||
height: menuCrypListHeight,
|
||||
},
|
||||
|
||||
MENU_MAIN: {
|
||||
x: menuMainX,
|
||||
y: menuMainY,
|
||||
width: menuMainWidth,
|
||||
height: menuMainHeight,
|
||||
|
||||
},
|
||||
|
||||
HOME_MAIN: {
|
||||
x: homeMainX,
|
||||
y: homeMainY,
|
||||
width: homeMainWidth,
|
||||
height: homeMainHeight,
|
||||
|
||||
},
|
||||
|
||||
|
||||
NAVIGATION: {
|
||||
x: menuNavigationX,
|
||||
y: menuNavigationY,
|
||||
width: menuNavigationWidth,
|
||||
height: menuNavigationHeight,
|
||||
},
|
||||
|
||||
ITEM_LIST: {
|
||||
x: itemListX,
|
||||
y: itemListY,
|
||||
width: itemListWidth,
|
||||
height: itemListHeight,
|
||||
itemWidth: itemBlockWidth,
|
||||
itemHeight: itemBlockHeight,
|
||||
|
||||
},
|
||||
|
||||
STATS: {
|
||||
x: statsX,
|
||||
y: statsY,
|
||||
width: statsWidth,
|
||||
height: statsHeight,
|
||||
knownX: statsKnownX,
|
||||
learnableX: statsLearnableX,
|
||||
textMargin: statsTextMargin,
|
||||
learnableMargin: statsLearnableMargin,
|
||||
},
|
||||
|
||||
COMBAT: {
|
||||
x: combatX,
|
||||
y: combatY,
|
||||
width: combatWidth,
|
||||
height: combatHeight,
|
||||
crypMargin: combatCrypMargin,
|
||||
textMargin: combatTextMargin,
|
||||
|
||||
|
||||
LOG: {
|
||||
x: logX,
|
||||
y: logY,
|
||||
width: logWidth,
|
||||
height: logHeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
COLOURS: {
|
||||
BLUE: 0x004bfe,
|
||||
CYAN: 0x27e7c0,
|
||||
PURPLE: 0x61008c,
|
||||
YELLOW: 0xfdfe02,
|
||||
ORANGE: 0xff9215,
|
||||
PINK: 0xe766b6,
|
||||
GRAY: 0x9d9ea0,
|
||||
LBLUE: 0x87c6f2,
|
||||
GREEN: 0x166c4f,
|
||||
BROWN: 0x583108,
|
||||
BLACK: 0x000000,
|
||||
RED: 0xff0000,
|
||||
WHITE: 0xffffff,
|
||||
|
||||
SELECT: 0x003300,
|
||||
},
|
||||
|
||||
DELAYS: {
|
||||
MOVE_CREEP: 500,
|
||||
DAMAGE_TICK: 500,
|
||||
ANIMATION_DURATION: 1000,
|
||||
// wall: [500],
|
||||
// spit: [300, 500],
|
||||
// gravBomb: [300, 500],
|
||||
// gravBlast: [300, 500],
|
||||
// chargeBall: [300, 500],
|
||||
},
|
||||
|
||||
ITEMS: {
|
||||
SKILLS: {
|
||||
Amplify: {
|
||||
description: 'increase the magic damage dealt by a cryp',
|
||||
colours: '1 Green 1 Blue',
|
||||
},
|
||||
|
||||
Attack: {
|
||||
description: 'a fast attack with red damage',
|
||||
upgrades: 'combine with 2 red / blue / green - red + blue attack not implemented',
|
||||
},
|
||||
|
||||
Banish: {
|
||||
description: 'target cryp is prevented from casting any skills and taking any damage',
|
||||
colours: '1 Red 1 Green',
|
||||
|
||||
},
|
||||
|
||||
Blast: {
|
||||
description: 'blast the target with magic damage',
|
||||
colours: '2 Blue',
|
||||
},
|
||||
|
||||
Block: {
|
||||
description: 'decreases incoming red damage for 1T',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
},
|
||||
|
||||
Buff: {
|
||||
description: 'increase target cryp speed',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
},
|
||||
|
||||
Clutch: {
|
||||
description: '??????',
|
||||
colours: '1 Red 1 Green',
|
||||
},
|
||||
|
||||
Corrupt: {
|
||||
description: 'Inflicts a dot to attacker while active',
|
||||
colours: '2 Blue',
|
||||
},
|
||||
|
||||
Curse: {
|
||||
description: 'target cryp takes increased magic damage',
|
||||
colours: '2 Blue',
|
||||
},
|
||||
|
||||
Debuff: {
|
||||
description: 'reduce target cryp speed',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
},
|
||||
|
||||
Decay: {
|
||||
description: 'afflict a cryp with a blue damage based damage over time debuff',
|
||||
colours: '1 Green 1 Blue',
|
||||
},
|
||||
|
||||
Empower: {
|
||||
description: 'increase the red damage dealt by a cryp',
|
||||
colours: '2 Red',
|
||||
},
|
||||
|
||||
Haste: {
|
||||
description: 'magical skill that increases speed of target cryp',
|
||||
colours: '1 Red 1 Blue',
|
||||
},
|
||||
|
||||
Heal: {
|
||||
description: 'heal a cryp with blue damage',
|
||||
colours: '2 Green',
|
||||
},
|
||||
|
||||
Hex: {
|
||||
description: 'magical bsed skill that prevents target cryp from using any skills',
|
||||
colours: '1 Red 1 Blue',
|
||||
},
|
||||
|
||||
Hostility: {
|
||||
description: 'magical bsed skill that prevents target cryp from using any skills',
|
||||
colours: '2 Blue',
|
||||
},
|
||||
|
||||
Invert: {
|
||||
description: 'reverse ???',
|
||||
colours: '1 Red 1 Blue',
|
||||
},
|
||||
|
||||
Parry: {
|
||||
description: 'prevents all red damage for 1T',
|
||||
colours: '2 Red',
|
||||
},
|
||||
|
||||
Purge: {
|
||||
description: 'remove magical buffs from target cryp',
|
||||
colours: '2 Green',
|
||||
},
|
||||
|
||||
Purify: {
|
||||
description: 'remove magical debuffs from target cryp',
|
||||
colours: '1 Red 1 Green',
|
||||
},
|
||||
|
||||
Recharge: {
|
||||
description: 'restore something',
|
||||
colours: '1 Red 1 Blue',
|
||||
},
|
||||
|
||||
Reflect: {
|
||||
description: 'reflect damage back to attacker',
|
||||
colours: '2 Green',
|
||||
},
|
||||
|
||||
Riposte: {
|
||||
description: '???',
|
||||
},
|
||||
|
||||
Ruin: {
|
||||
description: 'Stun the entire enemy team',
|
||||
colours: '2 Blue',
|
||||
},
|
||||
|
||||
Shield: {
|
||||
description: 'grants immunity to magical skills to target cryp',
|
||||
colours: '1 Green 1 Blue',
|
||||
},
|
||||
|
||||
Silence: {
|
||||
description: 'prevent target cryp from casting magical skills',
|
||||
colours: '1 Green 1 Blue',
|
||||
},
|
||||
|
||||
Siphon: {
|
||||
description: 'siphon hp from target cryp with a blue damage based debuff',
|
||||
colours: '1 Green 1 Blue',
|
||||
},
|
||||
|
||||
Slay: {
|
||||
description: '????',
|
||||
},
|
||||
|
||||
Slow: {
|
||||
description: 'magical skill that reduces speed of target cryp',
|
||||
colours: '1 Red 1 Green',
|
||||
},
|
||||
|
||||
Snare: {
|
||||
description: 'prevents red skills from being used for 2T',
|
||||
colours: '2 Red',
|
||||
},
|
||||
|
||||
Strangle: {
|
||||
description: 'Stun the enemy and inflict physical damage over 3T',
|
||||
colours: '2 Red',
|
||||
},
|
||||
|
||||
Strike: {
|
||||
description: 'Fast attacking red skill',
|
||||
colours: '2 Red',
|
||||
},
|
||||
|
||||
Stun: {
|
||||
description: 'red skill hat prevents target cryp from using any skills',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
|
||||
},
|
||||
|
||||
Taunt: {
|
||||
description: 'Enemy skills will prioritise cryps with this skill active',
|
||||
colours: '1 Red 1 Green',
|
||||
},
|
||||
|
||||
Throw: {
|
||||
description: 'stuns and makes the target take increased red damage',
|
||||
colours: '2 Green',
|
||||
},
|
||||
|
||||
Triage: {
|
||||
description: 'grants a blue damage based healing over time buff',
|
||||
colours: '2 Green',
|
||||
},
|
||||
},
|
||||
|
||||
SPECS: {
|
||||
Damage: {
|
||||
description: 'Increase red / green / blue power stats cryp',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
|
||||
},
|
||||
|
||||
Hp: {
|
||||
description: 'Increases health of cryp',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
|
||||
},
|
||||
|
||||
Speed: {
|
||||
description: 'Increases speed of cryp',
|
||||
upgrades: 'combine with 2 red / blue / green',
|
||||
},
|
||||
},
|
||||
|
||||
COLOURS: {
|
||||
Red: {
|
||||
description: 'Used to create offensive type combos - fast and chaotic',
|
||||
},
|
||||
|
||||
Green: {
|
||||
description: 'Used to create defensive / healing type combos',
|
||||
},
|
||||
|
||||
Blue: {
|
||||
description: 'Used to create offensive type combos - slow and reliable',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@ -1,77 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
|
||||
const Header = require('./header');
|
||||
const Home = require('./home');
|
||||
const Menu = require('./menu');
|
||||
const Combat = require('./combat');
|
||||
|
||||
// const Background = require('./background');
|
||||
|
||||
function renderCryps() {
|
||||
const config = {
|
||||
type: Phaser.CANVAS,
|
||||
// backgroundColor: '#181818',
|
||||
resolution: window.devicePixelRatio,
|
||||
scale: {
|
||||
mode: Phaser.Scale.FIT,
|
||||
width: Math.floor(window.innerHeight * 1.6),
|
||||
height: Math.floor(window.innerHeight),
|
||||
max: {
|
||||
width: Math.floor(window.innerHeight * 1.6),
|
||||
height: Math.floor(window.innerHeight),
|
||||
},
|
||||
|
||||
},
|
||||
antialias: true,
|
||||
physics: {
|
||||
default: 'arcade',
|
||||
arcade: {
|
||||
debug: false,
|
||||
gravity: { y: 0 },
|
||||
},
|
||||
},
|
||||
scene: [
|
||||
// Background,
|
||||
Header,
|
||||
],
|
||||
};
|
||||
|
||||
const game = new Phaser.Game(config);
|
||||
|
||||
|
||||
function changeData(parent, key, data) {
|
||||
// Don't load other scenes if you're not logged in
|
||||
if (!game.registry.get('account')) return false;
|
||||
|
||||
if (key === 'home') {
|
||||
if (data) return game.scene.add('Home', Home, true);
|
||||
}
|
||||
|
||||
if (key === 'menu') {
|
||||
if (!data || game.registry.get('inMenu')) return false;
|
||||
if (data) return game.scene.add('Menu', Menu, true);
|
||||
}
|
||||
|
||||
if (key === 'game') {
|
||||
if (!data || game.registry.get('inGame')) return false;
|
||||
return game.scene.add('Combat', Combat, true);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
game.registry.events.on('changedata', changeData);
|
||||
game.registry.events.on('setdata', changeData);
|
||||
|
||||
window.addEventListener('mouseup', () => game.registry.set('pan', false));
|
||||
window.addEventListener('mousedown', () => game.registry.set('pan', true));
|
||||
window.addEventListener('resize', () => {
|
||||
game.scale.displaySize.maxWidth = window.innerHeight * 1.6;
|
||||
game.scale.displaySize.maxHeight = window.innerHeight;
|
||||
});
|
||||
|
||||
|
||||
return game;
|
||||
}
|
||||
|
||||
module.exports = renderCryps;
|
||||
@ -1,132 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { TEXT } = require('.././constants');
|
||||
|
||||
const BOX = `
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
#ifdef GL_ES
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
#extension GL_OES_standard_derivatives : enable
|
||||
|
||||
uniform float time;
|
||||
uniform vec2 resolution;
|
||||
uniform vec2 dimensions;
|
||||
uniform vec2 offset;
|
||||
uniform vec3 colour;
|
||||
uniform sampler2D uMainSampler;
|
||||
|
||||
|
||||
varying vec2 outTexCoord;
|
||||
varying vec4 outTint;
|
||||
|
||||
float sdBox( in vec2 p, in vec2 b )
|
||||
{
|
||||
vec2 d = abs(p)-b;
|
||||
return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
|
||||
vec2 p = (gl_FragCoord.xy / resolution.xy);
|
||||
p.x -= offset.x / resolution.x + dimensions.x / (2.0 * resolution.x);
|
||||
p.y -= -1.0 * offset.y / resolution.y + ((resolution.y - dimensions.y) / (2.0 * resolution.y)) + 0.5;
|
||||
vec2 dim = 0.5 * dimensions / resolution.xy;
|
||||
float d = sdBox(p, dim);
|
||||
float tb = abs(sin(time)) + 0.9;
|
||||
|
||||
vec3 col = tb * colour - sign(d) * vec3(0.1);
|
||||
col *= 0.0 + exp(-100.0 * abs(d));
|
||||
col += colour * 0.8;
|
||||
vec4 texel = texture2D(uMainSampler, outTexCoord);
|
||||
texel *= vec4(outTint.rgb * outTint.a, outTint.a);
|
||||
|
||||
gl_FragColor = vec4(col, 1.0);
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
class CustomPipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline {
|
||||
constructor(game) {
|
||||
super({ game, renderer: game.renderer, fragShader: BOX });
|
||||
}
|
||||
}
|
||||
|
||||
function rgbToHex(rgb) {
|
||||
const getHex = (c) => {
|
||||
const hex = Math.floor(c * 255).toString(16);
|
||||
return hex.length === 1 ? `0${hex}` : hex;
|
||||
};
|
||||
return `0x${getHex(rgb[0])}${getHex(rgb[1])}${getHex(rgb[2])}`;
|
||||
}
|
||||
|
||||
|
||||
class BoxEffect extends Phaser.GameObjects.Graphics {
|
||||
constructor(scene, x, y, width, height, colour, tag) {
|
||||
super(scene);
|
||||
this.tag = tag;
|
||||
this.customPipeline = scene.game.renderer.addPipeline(tag, new CustomPipeline(scene.game));
|
||||
this.customPipeline.setFloat2('resolution', 1600, 1000);
|
||||
this.customPipeline.setFloat2('offset', x, y);
|
||||
this.customPipeline.setFloat2('dimensions', width, height);
|
||||
this.customPipeline.setFloat3('colour', colour[0], colour[1], colour[2]);
|
||||
this.bgTime = 10.0;
|
||||
|
||||
const radius = height / 2;
|
||||
this.fillStyle(rgbToHex(colour), 1.0);
|
||||
this.fillRect(x + radius, y, width - radius * 2, height);
|
||||
this.fillCircle(x + radius, y + radius, radius);
|
||||
this.fillCircle(x + width - radius, y + radius, radius);
|
||||
|
||||
|
||||
this.on('destroy', () => {
|
||||
scene.game.renderer.removePipeline(tag);
|
||||
});
|
||||
}
|
||||
|
||||
activate() {
|
||||
this.setPipeline(this.tag);
|
||||
}
|
||||
|
||||
deactivate() {
|
||||
this.resetPipeline();
|
||||
}
|
||||
|
||||
update() {
|
||||
this.bgTime += 0.05;
|
||||
this.customPipeline.setFloat1('time', this.bgTime);
|
||||
}
|
||||
}
|
||||
|
||||
class Button extends Phaser.GameObjects.Group {
|
||||
constructor(scene, props) {
|
||||
const {
|
||||
x, y, width, height, colour, glTag, bText, callback,
|
||||
} = props;
|
||||
|
||||
super(scene, { classType: BoxEffect, runChildUpdate: true });
|
||||
|
||||
const leaveGame = scene.add
|
||||
.rectangle(x, y, width, height, 0xaaaaaa, 0xffffff)
|
||||
.setInteractive()
|
||||
.setOrigin(0);
|
||||
|
||||
const effect = scene.add.existing(new BoxEffect(scene, x, y, width, height, colour, glTag));
|
||||
this.add(effect);
|
||||
|
||||
leaveGame
|
||||
.on('pointerdown', callback)
|
||||
.on('pointerover', () => effect.activate())
|
||||
.on('pointerout', () => effect.deactivate());
|
||||
|
||||
this.buttonText = scene.add.text(leaveGame.getCenter().x, leaveGame.getCenter().y, bText, TEXT.HEADER).setOrigin(0.5, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Button;
|
||||
@ -1,86 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { TEXT, POSITIONS: { COMBAT }, COLOURS } = require('.././constants');
|
||||
|
||||
const CRYP_MARGIN = COMBAT.crypMargin();
|
||||
const TEXT_MARGIN = COMBAT.textMargin();
|
||||
|
||||
const statBarDimensions = (team, iter, margin) => {
|
||||
const statBarWidth = COMBAT.width() * 0.07;
|
||||
const statBarHeight = TEXT_MARGIN / 1.5;
|
||||
const statBarX = (COMBAT.width() - statBarWidth) * team;
|
||||
const statBarY = COMBAT.y() + TEXT_MARGIN * (margin + 1) + CRYP_MARGIN * iter + COMBAT.height() * 0.07;
|
||||
return { statBarX, statBarY, statBarWidth, statBarHeight };
|
||||
};
|
||||
|
||||
const statTextCoord = (team, iter, margin) => {
|
||||
const statTextX = team ? COMBAT.width() - COMBAT.width() * 0.075 : COMBAT.width() * 0.075;
|
||||
const statTextY = COMBAT.y() + TEXT_MARGIN * (margin + 1) + CRYP_MARGIN * iter + COMBAT.height() * 0.07;
|
||||
return { statTextX, statTextY };
|
||||
};
|
||||
|
||||
|
||||
class StatBar extends Phaser.GameObjects.Graphics {
|
||||
constructor(scene, cryp, type) {
|
||||
super(scene);
|
||||
this.crypObj = cryp;
|
||||
this.type = type;
|
||||
|
||||
if (type === 'HP') {
|
||||
this.val = this.crypObj.cryp.hp.value;
|
||||
this.max = this.crypObj.cryp.hp.max;
|
||||
this.margin = 0;
|
||||
} else if (type === 'Red Shield') {
|
||||
this.val = this.crypObj.cryp.red_shield.value;
|
||||
this.max = this.crypObj.cryp.red_shield.max;
|
||||
this.margin = 1;
|
||||
} else if (type === 'Blue Shield') {
|
||||
this.val = this.crypObj.cryp.blue_shield.value;
|
||||
this.max = this.crypObj.cryp.blue_shield.max;
|
||||
this.margin = 2;
|
||||
} else if (type === 'Evasion') {
|
||||
this.val = this.crypObj.cryp.evasion.value;
|
||||
this.max = this.crypObj.cryp.evasion.max;
|
||||
this.margin = 3;
|
||||
}
|
||||
const { statTextX, statTextY } = statTextCoord(cryp.team, cryp.iter, this.margin);
|
||||
this.statText = scene.add.text(statTextX, statTextY, '', TEXT.NORMAL).setOrigin(cryp.team, 0);
|
||||
this.drawStatBar();
|
||||
}
|
||||
|
||||
drawStatBar() {
|
||||
this.clear();
|
||||
const {
|
||||
statBarX, statBarY, statBarWidth, statBarHeight,
|
||||
} = statBarDimensions(this.crypObj.team, this.crypObj.iter, this.margin);
|
||||
this.statText.text = `${this.val.toString()} / ${this.max.toString()} ${this.type}`;
|
||||
// Draw Black Border
|
||||
this.fillStyle(COLOURS.BLACK);
|
||||
this.fillRect(statBarX, statBarY, statBarWidth, statBarHeight);
|
||||
// White fill
|
||||
this.fillStyle(COLOURS.WHITE);
|
||||
this.fillRect(statBarX + 2, statBarY + 2, statBarWidth - 4, statBarHeight - 4);
|
||||
// Fill the health bar
|
||||
const statPercentage = this.val / this.max;
|
||||
if (statPercentage < 0.3) {
|
||||
this.fillStyle(COLOURS.RED);
|
||||
} else if (statPercentage < 0.65) {
|
||||
this.fillStyle(COLOURS.YELLOW);
|
||||
} else {
|
||||
this.fillStyle(0x00ff00); // str8 up green
|
||||
}
|
||||
const statWidth = statBarWidth * statPercentage;
|
||||
this.fillRect(statBarX + 2, statBarY + 2, statWidth, statBarHeight - 4);
|
||||
}
|
||||
|
||||
takeDamage(value) {
|
||||
if (value > 0) {
|
||||
this.val = (value >= this.val) ? 0 : this.val -= value;
|
||||
} else {
|
||||
this.val = (this.val - value > this.max) ? this.max : this.val -= value;
|
||||
}
|
||||
if (this.val === 0 && this.type === 'HP') this.crypObj.setKo();
|
||||
this.drawStatBar();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StatBar;
|
||||
@ -1,56 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
|
||||
const {
|
||||
TEXT,
|
||||
COLOURS,
|
||||
} = require('../constants');
|
||||
|
||||
function FindColour(item) {
|
||||
// Future add skills and use a constants lookup file ??
|
||||
switch (item) {
|
||||
case 'Green': return 0x396E26;
|
||||
case 'Red': return 0x622433;
|
||||
case 'Blue': return 0x223158;
|
||||
// case 'Green': return 0x043003;
|
||||
// case 'Red': return 0x5C0202;
|
||||
// case 'Blue': return 0x040345;
|
||||
|
||||
default: return 0x222222;
|
||||
}
|
||||
}
|
||||
|
||||
class Item extends Phaser.GameObjects.Container {
|
||||
constructor(scene, item, index, x, y, width, height) {
|
||||
super(scene, x, y);
|
||||
|
||||
this.scene = scene;
|
||||
this.item = item;
|
||||
this.index = index;
|
||||
this.origX = x;
|
||||
this.origY = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.colour = FindColour(item);
|
||||
this.box = scene.add
|
||||
.rectangle(0, 0, width, height, this.colour);
|
||||
|
||||
this.text = scene.add
|
||||
// .text(0, 0, `${action} x${count}`, TEXT.NORMAL)
|
||||
.text(0, 0, `${item}`, TEXT.NORMAL)
|
||||
.setOrigin(0.5, 0.5);
|
||||
|
||||
this.add(this.box);
|
||||
this.add(this.text);
|
||||
|
||||
this.setSize(width, height);
|
||||
this.setInteractive();
|
||||
}
|
||||
|
||||
changeOrigin(x, y) {
|
||||
this.origX = x + this.width / 2;
|
||||
this.origY = y + this.height / 2;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Item;
|
||||
@ -1,73 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
|
||||
class LineBox extends Phaser.GameObjects.Graphics {
|
||||
constructor(scene, x, y, width, height, colour, speed) {
|
||||
super(scene);
|
||||
this.colour = colour;
|
||||
this.x0 = x; this.x1 = x + width;
|
||||
this.y0 = y; this.y1 = y + height;
|
||||
const margin = Math.abs(Math.floor((this.x1 - this.x0) / 4));
|
||||
this.lineCoord = [this.x0 + margin, this.x1 - margin, this.y0, this.y0, 0];
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.clear();
|
||||
|
||||
let vertX = this.x1;
|
||||
let horizY = this.y0;
|
||||
const genLine = () => {
|
||||
switch (this.lineCoord[4]) {
|
||||
case 0:
|
||||
if (this.lineCoord[1] < this.x1) return [1, 1, 0, 0, 0];
|
||||
return [0, 0, 0, 0, 1];
|
||||
case 1:
|
||||
if (this.lineCoord[0] < this.x1) return [1, 0, 0, 1, 1];
|
||||
return [0, 0, 0, 0, 2];
|
||||
case 2:
|
||||
if (this.lineCoord[3] < this.y1) return [0, 0, 1, 1, 2];
|
||||
return [0, 0, 0, 0, 3];
|
||||
case 3:
|
||||
horizY = this.y1;
|
||||
if (this.lineCoord[2] < this.y1) return [-1, 0, 1, 0, 3];
|
||||
return [0, 0, 0, 0, 4];
|
||||
case 4:
|
||||
horizY = this.y1;
|
||||
if (this.lineCoord[0] > this.x0) return [-1, -1, 0, 0, 4];
|
||||
return [0, 0, 0, 0, 5];
|
||||
case 5:
|
||||
horizY = this.y1;
|
||||
vertX = this.x0;
|
||||
if (this.lineCoord[1] > this.x0) return [0, -1, -1, 0, 5];
|
||||
return [0, 0, 0, 0, 6];
|
||||
case 6:
|
||||
vertX = this.x0;
|
||||
if (this.lineCoord[2] >= this.y0) return [0, 0, -1, -1, 6];
|
||||
return [0, 0, 0, 0, 7];
|
||||
case 7:
|
||||
vertX = this.x0;
|
||||
if (this.lineCoord[3] >= this.y0) return [0, 1, 0, -1, 7];
|
||||
return [0, 0, 0, 0, 0];
|
||||
default: return false;
|
||||
}
|
||||
};
|
||||
for (let i = 0; i < this.speed; i += 1) {
|
||||
const delta = genLine();
|
||||
this.lineCoord = this.lineCoord.map((x, j) => {
|
||||
if (j < 4) return (x + delta[j]);
|
||||
return delta[j];
|
||||
});
|
||||
}
|
||||
this.lineStyle(5, this.colour, 1);
|
||||
this.lineBetween(this.lineCoord[0], horizY, this.lineCoord[1], horizY);
|
||||
this.lineBetween(vertX, this.lineCoord[2], vertX, this.lineCoord[3]);
|
||||
}
|
||||
}
|
||||
|
||||
class LineGroup extends Phaser.GameObjects.Group {
|
||||
constructor(scene) {
|
||||
super(scene, { classType: LineBox, runChildUpdate: true });
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { LineGroup, LineBox }
|
||||
@ -1,53 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { TEXT, POSITIONS: { MENU_MAIN } } = require('./constants');
|
||||
|
||||
const X = MENU_MAIN.x();
|
||||
const Y = MENU_MAIN.y();
|
||||
const WIDTH = MENU_MAIN.width();
|
||||
const HEIGHT = MENU_MAIN.height();
|
||||
const ROW_SIZE = 50;
|
||||
const LOBBY_WIDTH = WIDTH / 2;
|
||||
|
||||
class GameList extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'GameList' });
|
||||
}
|
||||
|
||||
create(gameList) {
|
||||
this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT);
|
||||
const ws = this.registry.get('ws');
|
||||
|
||||
this.add.text(WIDTH / 3, 0, 'PVP open games', TEXT.HEADER);
|
||||
const gameRow = (game, i) => {
|
||||
const GAME_X = WIDTH / 6;
|
||||
const GAME_Y = 1.3 * ROW_SIZE * (i + 1);
|
||||
|
||||
const gameBox = this.add
|
||||
.rectangle(GAME_X, GAME_Y, LOBBY_WIDTH, ROW_SIZE, 0x222222)
|
||||
.setInteractive()
|
||||
.setOrigin(0);
|
||||
|
||||
const TITLE = `${game.teams[0].cryps.map(c => c.name).join(', ')} - ${game.team_size}v${game.team_size}`;
|
||||
|
||||
this.add
|
||||
.text(gameBox.getCenter().x, gameBox.getCenter().y, TITLE, TEXT.NORMAL)
|
||||
.setOrigin(0.5, 0.5);
|
||||
|
||||
gameBox.on('pointerdown', () => {
|
||||
const cryps = this.registry.get('cryps');
|
||||
const team = cryps.filter(c => c.active).map(c => c.id);
|
||||
ws.sendGameJoin(game.id, team);
|
||||
});
|
||||
};
|
||||
|
||||
gameList.forEach(gameRow);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GameList;
|
||||
@ -1,27 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const fs = require('fs');
|
||||
|
||||
const { TEXT } = require('./constants');
|
||||
|
||||
const aztecAtlas = require('../../assets/aztec.atlas.json');
|
||||
|
||||
|
||||
class Header extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'Header', active: true });
|
||||
}
|
||||
|
||||
preload() {
|
||||
const aztecImg = new Image();
|
||||
aztecImg.src = `data:image/png;base64,${new Buffer.from(fs.readFileSync('./assets/aztec.clean.png')).toString('base64')}`;
|
||||
aztecImg.onload = () => {
|
||||
this.textures.addAtlas('aztec', aztecImg, aztecAtlas);
|
||||
};
|
||||
}
|
||||
|
||||
create() {
|
||||
this.add.text(0, 0, 'cryps.gg', TEXT.HEADER);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Header;
|
||||
@ -1,142 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { remove } = require('lodash');
|
||||
|
||||
const { TEXT, COLOURS, POSITIONS: { CRYP_LIST } } = require('./constants');
|
||||
const genAvatar = require('./avatar');
|
||||
const { LineGroup, LineBox } = require('./elements/outline.rotate');
|
||||
|
||||
const ROW_HEIGHT = CRYP_LIST.height() * 0.1;
|
||||
const ROW_WIDTH = CRYP_LIST.width();
|
||||
|
||||
const menuY = CRYP_LIST.height() * 0.8;
|
||||
|
||||
const KEY_MAP = [
|
||||
'keydown-ONE',
|
||||
'keydown-TWO',
|
||||
'keydown-THREE',
|
||||
];
|
||||
|
||||
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
class HomeCrypList extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'HomeCryps' });
|
||||
}
|
||||
|
||||
|
||||
updateData(parent, key, data) {
|
||||
if (key === 'crypList') {
|
||||
KEY_MAP.forEach(k => this.input.keyboard.removeListener(k));
|
||||
this.scene.restart();
|
||||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
// this.cameras.main.setViewport(CRYP_LIST.x(), CRYP_LIST.y(), CRYP_LIST.width(), CRYP_LIST.height());
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
this.registry.events.on('setdata', this.updateData, this);
|
||||
const cryps = this.registry.get('crypList');
|
||||
const lineGroup = this.add.existing(new LineGroup(this));
|
||||
|
||||
if (!cryps) return true;
|
||||
const ws = this.registry.get('ws');
|
||||
this.activeCryps = [];
|
||||
// We only display 3 cryps others can be viewed in cryp list (soon TM)
|
||||
for (let i = 0; i < cryps.length; i += 1) {
|
||||
const cryp = cryps[i];
|
||||
const BOX_WIDTH = Math.floor(ROW_WIDTH / 5);
|
||||
const ROW_X = BOX_WIDTH * 2 * (i % 3);
|
||||
const ROW_Y = CRYP_LIST.y() + (Math.floor(i / 3)) * ROW_HEIGHT * 1.5;
|
||||
const ACTIVE_FILL = 0.2;
|
||||
|
||||
const FILL = Object.values(COLOURS)[i];
|
||||
// Selection of cryps
|
||||
|
||||
// Cryp avatar and interaction box
|
||||
const cReady = this.add
|
||||
.rectangle(ROW_X, ROW_Y + ROW_HEIGHT * 0.2, BOX_WIDTH * 2, ROW_HEIGHT, FILL)
|
||||
.setInteractive()
|
||||
.setOrigin(0);
|
||||
cReady.setAlpha(0.2);
|
||||
cReady.on('pointerdown', () => {
|
||||
lineGroup.clear(true, true);
|
||||
if (this.activeCryps.includes(cReady)) {
|
||||
remove(this.activeCryps, n => n === cReady);
|
||||
cReady.setAlpha(0.2);
|
||||
} else {
|
||||
this.activeCryps.push(cReady);
|
||||
cReady.setAlpha(0.75);
|
||||
lineGroup.add(this.add.existing(
|
||||
new LineBox(this, cReady.x, cReady.y, cReady.width, cReady.height, cReady.fillColor, 3)
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
cReady.itemSelect = () => {
|
||||
cReady.setFillStyle(COLOURS.SELECT);
|
||||
};
|
||||
cReady.itemDeselect = () => {
|
||||
cReady.setFillStyle(FILL, ACTIVE_FILL);
|
||||
};
|
||||
|
||||
cReady.cryp = cryp;
|
||||
this.add.image(
|
||||
cReady.getCenter().x,
|
||||
cReady.getCenter().y,
|
||||
'aztec',
|
||||
genAvatar(cryp.name)
|
||||
);
|
||||
this.add.text(ROW_X + BOX_WIDTH, ROW_Y, cryp.name, TEXT.HEADER)
|
||||
.setOrigin(0.5, 0.5);
|
||||
}
|
||||
|
||||
// Add Spawn Cryp Option
|
||||
const spawn = this.add
|
||||
.rectangle(ROW_WIDTH * 0.05, menuY, ROW_WIDTH * 0.2, ROW_HEIGHT * 0.5, 0x888888)
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', () => {
|
||||
this.game.events.emit('CRYP_SPAWN');
|
||||
});
|
||||
this.add
|
||||
.text(spawn.getCenter().x, spawn.getCenter().y, '+', TEXT.HEADER)
|
||||
.setOrigin(0.5, 0.5);
|
||||
|
||||
const joinNormal = this.add
|
||||
.rectangle(ROW_WIDTH * 0.3, menuY, ROW_WIDTH * 0.4, ROW_HEIGHT * 0.5, 0x888888)
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', () => {
|
||||
const playerCryps = [];
|
||||
this.activeCryps.forEach(obj => playerCryps.push(obj.cryp.id));
|
||||
ws.sendPlayerCrypsSet(NULL_UUID, playerCryps);
|
||||
});
|
||||
this.add
|
||||
.text(joinNormal.getCenter().x, joinNormal.getCenter().y, 'Join Normal', TEXT.HEADER)
|
||||
.setOrigin(0.5, 0.5);
|
||||
|
||||
const joinInstance = this.add
|
||||
.rectangle(ROW_WIDTH * 0.8, menuY, ROW_WIDTH * 0.4, ROW_HEIGHT * 0.5, 0x888888)
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', () => {
|
||||
const playerCryps = [];
|
||||
this.activeCryps.forEach(obj => playerCryps.push(obj.cryp.id));
|
||||
ws.sendInstanceJoin(playerCryps);
|
||||
});
|
||||
this.add
|
||||
.text(joinInstance.getCenter().x, joinInstance.getCenter().y, 'New Instance', TEXT.HEADER)
|
||||
.setOrigin(0.5, 0.5);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
KEY_MAP.forEach(k => this.input.keyboard.removeListener(k));
|
||||
this.registry.events.off('changedata', this.updateData, this);
|
||||
this.registry.events.off('setdata', this.updateData, this);
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HomeCrypList;
|
||||
@ -1,48 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
const { POSITIONS: { HOME_MAIN }, TEXT } = require('./constants');
|
||||
|
||||
const X = HOME_MAIN.x();
|
||||
const Y = HOME_MAIN.y();
|
||||
const WIDTH = HOME_MAIN.width();
|
||||
const HEIGHT = HOME_MAIN.height();
|
||||
|
||||
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
|
||||
|
||||
class HomeRankings extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'HomeInstances' });
|
||||
}
|
||||
|
||||
create() {
|
||||
this.add.text(X, Y, 'Instances Scene', TEXT.HEADER);
|
||||
const playerList = this.registry.get('playerList');
|
||||
const addInstance = (player, i) => {
|
||||
const joinNormal = this.add
|
||||
.rectangle(X, Y + HEIGHT * 0.15 * (i + 1), WIDTH * 0.5, HEIGHT * 0.1, 0x888888)
|
||||
.setInteractive()
|
||||
.setOrigin(0)
|
||||
.on('pointerdown', () => {
|
||||
if (player.ready) {
|
||||
this.registry.set('player', player);
|
||||
this.registry.get('ws').sendInstanceReady(player.instance);
|
||||
} else {
|
||||
this.game.events.emit('SET_PLAYER', player);
|
||||
this.registry.get('ws').sendInstanceScores(player.instance);
|
||||
}
|
||||
});
|
||||
const name = player.instance === NULL_UUID ? 'Normal Mode' : `${player.instance.substring(0, 5)}`;
|
||||
const disp = player.ready ? name.concat(' - in progress') : name;
|
||||
this.add
|
||||
.text(joinNormal.getCenter().x, joinNormal.getCenter().y, disp, TEXT.NORMAL)
|
||||
.setOrigin(0.5, 0.5);
|
||||
};
|
||||
|
||||
playerList.forEach(addInstance);
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HomeRankings;
|
||||
@ -1,91 +0,0 @@
|
||||
const Phaser = require('phaser');
|
||||
|
||||
|
||||
const HomeCryps = require('./home.cryps');
|
||||
const HomeNavigation = require('./home.navigation');
|
||||
|
||||
const HomeRankings = require('./home.rankings');
|
||||
const HomeNews = require('./home.news');
|
||||
const HomeShop = require('./home.shop');
|
||||
const HomeInstances = require('./home.instances');
|
||||
|
||||
const FIXED_SCENES = [
|
||||
'HomeCryps',
|
||||
'HomeNavigation',
|
||||
];
|
||||
|
||||
const VAR_SCENES = [
|
||||
'HomeRankings',
|
||||
'HomeNews',
|
||||
'HomeShop',
|
||||
'HomeInstances',
|
||||
];
|
||||
|
||||
class Home extends Phaser.Scene {
|
||||
constructor() {
|
||||
super({ key: 'Home', active: true });
|
||||
}
|
||||
|
||||
create() {
|
||||
this.registry.get('ws').sendAccountInstances();
|
||||
|
||||
this.registry.events.on('changedata', this.updateData, this);
|
||||
this.registry.events.on('setdata', this.updateData, this);
|
||||
this.scene.manager.add('HomeCryps', HomeCryps, true);
|
||||
this.scene.manager.add('HomeNavigation', HomeNavigation, true);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
updateData(parent, key, data) {
|
||||
if (!data) return false;
|
||||
// Controls which scene shows in the main top right section
|
||||
switch (key) {
|
||||
case 'game': return this.cleanUp();
|
||||
case 'menu': return this.cleanUp();
|
||||
case 'homeInstances': return this.newMainScene('HomeInstances', HomeInstances, data);
|
||||
case 'homeRankings': return this.newMainScene('HomeRankings', HomeRankings, data);
|
||||
case 'homeNews': return this.newMainScene('HomeNews', HomeNews, data);
|
||||
case 'homeShop': return this.newMainScene('HomeShop', HomeShop, data);
|
||||
|
||||
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
newMainScene(key, scene, data) {
|
||||
let addScene = true;
|
||||
// List of scenes which could be occupying the main section of the menu
|
||||
VAR_SCENES.forEach((sKey) => {
|
||||
if (this.scene.manager.keys[sKey]) {
|
||||
if (key === sKey) {
|
||||
// If there is new data for the current scene restart
|
||||
this.scene.manager.keys[sKey].scene.restart(data);
|
||||
addScene = false;
|
||||
} else {
|
||||
// Delete the old scene
|
||||
this.scene.manager.keys[sKey].cleanUp();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (addScene) this.scene.manager.add(key, scene, true, data);
|
||||
}
|
||||
|
||||
cleanUp() {
|
||||
this.registry.events.off('changedata', this.updateData, this);
|
||||
this.registry.events.off('setdata', this.updateData, this);
|
||||
// Delete scenes which could be showing before switching to battle scene
|
||||
|
||||
const removeScenes = (sKey) => {
|
||||
if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp();
|
||||
};
|
||||
FIXED_SCENES.forEach(removeScenes);
|
||||
VAR_SCENES.forEach(removeScenes);
|
||||
|
||||
|
||||
this.scene.remove();
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Home;
|
||||