diff --git a/client/assets/alakazam-f.png b/client/assets/alakazam-f.png new file mode 100644 index 00000000..f792d270 Binary files /dev/null and b/client/assets/alakazam-f.png differ diff --git a/client/assets/aztec.jpg b/client/assets/aztec.jpg new file mode 100644 index 00000000..e9700f56 Binary files /dev/null and b/client/assets/aztec.jpg differ diff --git a/client/assets/magmar.png b/client/assets/magmar.png new file mode 100644 index 00000000..c59cad7a Binary files /dev/null and b/client/assets/magmar.png differ diff --git a/client/index.html b/client/index.html index 10683ea8..eebdb5ff 100644 --- a/client/index.html +++ b/client/index.html @@ -1,20 +1,11 @@ -
- + - - - - \ No newline at end of file + \ No newline at end of file diff --git a/client/package.json b/client/package.json index 4fd5f66c..2c6590f8 100755 --- a/client/package.json +++ b/client/package.json @@ -4,7 +4,7 @@ "description": "", "main": "index.js", "scripts": { - "start": "parcel index.html --port 40080", + "start": "parcel index.html --port 40080 --no-hmr", "build": "rm -rf dist && parcel build index.html", "lint": "eslint --fix --ext .jsx src/", "test": "echo \"Error: no test specified\" && exit 1" @@ -12,6 +12,7 @@ "author": "", "license": "UNLICENSED", "dependencies": { + "@orange-games/phaser-input": "^2.0.5", "borc": "^2.0.3", "bulma-toast": "^1.2.0", "docco": "^0.7.0", diff --git a/client/src/main.jsx b/client/src/main.jsx index 1df4f0c3..ac2e90b5 100755 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -1,18 +1,12 @@ -const preact = require('preact'); -const jdenticon = require('jdenticon'); - -const { Provider } = require('preact-redux'); const { createStore, combineReducers } = require('redux'); +const renderCryps = require('./scenes/cryps'); + const reducers = require('./reducers'); const actions = require('./actions'); const setupKeys = require('./keyboard'); -// const fizzyText = require('../lib/fizzy-text'); const createSocket = require('./socket'); -const Header = require('./components/header.component'); -const Body = require('./components/body.component'); - // Redux Store const store = createStore( combineReducers({ @@ -34,26 +28,4 @@ const ws = createSocket(store); store.dispatch(actions.setWs(ws)); ws.connect(); -// tells jdenticon to look for new svgs and render them -// so we don't have to setInnerHtml or manually call update -jdenticon.config = { - replaceMode: 'observe', -}; - -const Cryps = () => ( -
-
- -
-); - -const Main = () => ( - - - -); - -// eslint-disable-next-line -preact.render(
, document.body); - -// fizzyText('cryps.gg'); +renderCryps(store); diff --git a/client/src/scenes/cryp.list.js b/client/src/scenes/cryp.list.js new file mode 100644 index 00000000..4d3adea9 --- /dev/null +++ b/client/src/scenes/cryp.list.js @@ -0,0 +1,42 @@ +const Phaser = require('phaser'); + +const crypRow = require('./cryp.row'); + +class CrypList extends Phaser.Scene { + constructor() { + super({ key: 'CrypList', active: true }); + } + + create() { + this.registry.events.on('changedata', this.updateData, this); + + const cryps = this.registry.get('cryps'); + this.graphics = this.add.graphics(); + this.graphics.originX = 0; + this.graphics.originY = 0; + this.renderCryps(cryps); + return true; + } + + updateData(parent, key, data) { + if (key === 'cryps') { + return this.scene.restart(); + } + return true; + } + + renderCryps(cryps) { + if (!cryps) return true; + + const crypRows = cryps.forEach((cryp, i) => { + crypRow(this, cryp, i); + }); + + // seal the boxes in and stop rerendering them + this.graphics.generateTexture(); + + return true; + } +} + +module.exports = CrypList; diff --git a/client/src/scenes/cryp.row.js b/client/src/scenes/cryp.row.js new file mode 100644 index 00000000..514c57dd --- /dev/null +++ b/client/src/scenes/cryp.row.js @@ -0,0 +1,26 @@ +const Phaser = require('phaser'); + +const ROW_WIDTH = 400; +const ROW_HEIGHT = 200; +const ROW_FILL = 0x888888; + +const TOP_MARGIN = 50; +const ROW_MARGIN = 50; +const TEXT_MARGIN = 24; + +const xPos = i => 0; +const yPos = i => (i * ROW_HEIGHT + ROW_MARGIN) + TOP_MARGIN; + +function crypRow(list, cryp, i) { + const X_ORIGIN = xPos(i); + const Y_ORIGIN = yPos(i); + + list.graphics.fillStyle(ROW_FILL * Math.random(), 1.0); + list.graphics.fillRect(X_ORIGIN, Y_ORIGIN, ROW_WIDTH, ROW_HEIGHT); + list.add.text(X_ORIGIN, Y_ORIGIN + (TEXT_MARGIN * 0), cryp.name, { fontFamily: 'Arial', fontSize: 24, color: '#ffffff', fontStyle: 'bold' }); + list.add.text(X_ORIGIN, Y_ORIGIN + (TEXT_MARGIN * 1), cryp.stamina.base, { fontFamily: 'Arial', fontSize: 24, color: '#ffffff', fontStyle: 'bold' }); + + return true; +} + +module.exports = crypRow; diff --git a/client/src/scenes/cryps.js b/client/src/scenes/cryps.js new file mode 100644 index 00000000..79bddaf9 --- /dev/null +++ b/client/src/scenes/cryps.js @@ -0,0 +1,38 @@ +const Phaser = require('phaser'); + +const CrypList = require('./cryp.list'); +const Menu = require('./menu'); +// const Passives = require('./passives'); + +function renderCryps(store) { + const config = { + type: Phaser.AUTO, + // parent: 'cryps', + backgroundColor: '#181818', + resolution: window.devicePixelRatio, + width: window.innerWidth, + height: window.innerHeight, + physics: { + default: 'arcade', + arcade: { + debug: false, + gravity: { y: 0 }, + }, + }, + scene: [ + Menu, + CrypList, + ], + }; + + const game = new Phaser.Game(config); + + store.subscribe(() => { + const state = store.getState(); + game.registry.set('cryps', state.cryps); + }); + + window.addEventListener('resize', () => game.resize(window.innerWidth, window.innerHeight), false); +} + +module.exports = renderCryps; diff --git a/client/src/scenes/menu.js b/client/src/scenes/menu.js new file mode 100644 index 00000000..0012d59e --- /dev/null +++ b/client/src/scenes/menu.js @@ -0,0 +1,13 @@ +const Phaser = require('phaser'); + +class Menu extends Phaser.Scene { + constructor(props) { + super({ key: 'Menu', active: true }); + } + + create() { + this.add.text(0, 0, 'cryps.gg', { fontFamily: 'Arial', fontSize: 24, color: '#ffffff', fontStyle: 'bold' }); + } +} + +module.exports = Menu; diff --git a/client/src/components/passive.data.edge.js b/client/src/scenes/passive.data.edge.js similarity index 100% rename from client/src/components/passive.data.edge.js rename to client/src/scenes/passive.data.edge.js diff --git a/client/src/components/passive.data.node.js b/client/src/scenes/passive.data.node.js similarity index 100% rename from client/src/components/passive.data.node.js rename to client/src/scenes/passive.data.node.js diff --git a/client/src/components/passive.node.js b/client/src/scenes/passive.node.js similarity index 100% rename from client/src/components/passive.node.js rename to client/src/scenes/passive.node.js diff --git a/client/src/scenes/passives.js b/client/src/scenes/passives.js new file mode 100644 index 00000000..1869d8c9 --- /dev/null +++ b/client/src/scenes/passives.js @@ -0,0 +1,126 @@ +const Phaser = require('phaser'); +const PassiveNode = require('./passive.node'); +const passiveDataNode = require('./passive.data.node'); +const passiveDataEdge = require('./passive.data.edge'); + +// Passive tree generator - proof of concept visuals need work +// Mouse click hold to move, Q + E to zoom in and out +// Press 'A' to reset allocated passive nodes + +class Passives extends Phaser.Scene { + preload() { + this.load.image('eye', 'https://labs.phaser.io/assets/particles/green-orb.png'); + this.load.image('background', 'http://labs.phaser.io/assets/skies/nebula.jpg'); + } + + create() { + this.background = this.add.image(0, 0, 'background'); + this.background.setScale(5); + this.background.setInteractive(); + this.graphics = this.add.graphics(); + this.nodeText = this.add.text(10000, 10000, 'grep', { + fontSize: '32px', + fontFamily: 'Arial', + color: '#ffffff', + backgroundColor: '#000000', + }).setPadding(32); + + this.passiveNodeData = passiveDataNode; + this.passiveEdgeData = passiveDataEdge; + this.addPassiveNodes(); + this.drawPassiveEdges(); + this.addCanmeraControl(); + } + + addPassiveNodes() { + this.passiveNodes = []; + this.passiveNodeData.forEach((n) => { + this.passiveNodes[n.id] = this.add.existing( + new PassiveNode(this, n.x, n.y, n.id, n.alloc, n.text) + ).setInteractive(); + }); + + this.input.on('pointerover', (pointer, gameObjects) => { + if (gameObjects[0] instanceof PassiveNode) { + if (!gameObjects[0].alloc) gameObjects[0].setTint(0xff00ff); + this.nodeText.x = pointer.x + this.cameras.main.scrollX; + this.nodeText.y = pointer.y + this.cameras.main.scrollY; + this.nodeText.text = gameObjects[0].text; + } else { + this.nodeText.text = ''; + } + }); + this.input.on('pointerout', (pointer, gameObjects) => { + if (gameObjects[0] instanceof PassiveNode) { + if (!gameObjects[0].alloc) gameObjects[0].clearTint(); + } + }); + this.input.on('pointerup', (pointer, gameObjects) => { + if (Math.abs(pointer.upX - pointer.downX) < 5 + && Math.abs(pointer.upY - pointer.downY) < 5) { + // Check cursor hasn't significantly moved during point allocation + // If panning and mouse release is on node it won't allocate + if (gameObjects[0] instanceof PassiveNode) { + gameObjects[0].allocate(); + } + } + }); + + this.input.keyboard.on('keydown_A', () => { + this.updatePassives(); // Will update nodes from state + }, 0, this); + } + + drawPassiveEdges() { + this.graphics.clear(); + this.passiveEdgeData.forEach((e) => { + const drawEdge = this.passiveNodeData.filter(n => ( + e[0] === n.id || e[1] === n.id + )); + if (drawEdge[0].alloc && drawEdge[1].alloc) { + this.graphics.lineStyle(10, 0xfff00f, 0.2); + } else { + this.graphics.lineStyle(2, 0xffffff, 0.2); + } + // console.log(drawEdge); + this.graphics.lineBetween(drawEdge[0].x, drawEdge[0].y, drawEdge[1].x, drawEdge[1].y); + }); + } + + addCanmeraControl() { + this.input.on('pointermove', (pointer) => { + if (this.pan) { + const points = pointer.getInterpolatedPosition(2); + this.cameras.main.scrollX -= (points[1].x - points[0].x) * 2; + this.cameras.main.scrollY -= (points[1].y - points[0].y) * 2; + } + }, this); + this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl({ + camera: this.cameras.main, + zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q), + zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E), + acceleration: 0.005, + drag: 0.0005, + maxSpeed: 0.001, + }); + } + + updatePassives() { + this.passiveNodeData.forEach((n) => { + this.passiveNodes[n.id].alloc = false; + this.passiveNodes[n.id].updateNode(); + }); + // This function will be modified to just update from state + // State will update n.alloc instead of false + } + + camPan(bool) { + this.pan = bool; + } + + update(delta) { + this.controls.update(delta); + } +} + +module.exports = Passives; diff --git a/client/src/socket.jsx b/client/src/socket.jsx index 80ed137b..91fe55b3 100755 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -28,7 +28,7 @@ function createSocket(store) { // Connection opened ws.addEventListener('open', (event) => { - // send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } }); + send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } }); }); // Listen for messages @@ -61,7 +61,7 @@ function createSocket(store) { account = login; store.dispatch(actions.setAccount(login)); - // send({ method: 'cryp_spawn', params: { name: 'muji' } }); + // send({ method: 'cryp_spawn', params: { name: 'bees' } }); send({ method: 'account_cryps', params: {} }); send({ method: 'item_list', params: {} }); console.log(account); diff --git a/server/src/skill.rs b/server/src/skill.rs index e8dd7753..24077b5e 100755 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -114,7 +114,8 @@ impl Effect { Effect::Shield => match skill.cast_type() { Damage::Magic => true, Damage::Physical => false, - } + }, + Effect::Banish => true, _ => false, } }