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,
}
}