236 lines
7.8 KiB
JavaScript
236 lines
7.8 KiB
JavaScript
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.base === 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;
|