mnml/client/src/utils.jsx
2019-07-02 12:23:35 +10:00

409 lines
11 KiB
JavaScript

const preact = require('preact');
const get = require('lodash/get');
const shapes = require('./components/shapes');
const stringSort = (k, desc) => {
if (desc) {
return (a, b) => {
if (!get(a, k)) return 1;
if (!get(b, k)) return -1;
return get(b, k).localeCompare(get(a, k));
};
}
return (a, b) => {
if (!get(a, k)) return 1;
if (!get(b, k)) return -1;
return get(a, k).localeCompare(get(b, k));
};
};
const numSort = (k, desc) => {
if (desc) {
return (a, b) => {
if (!get(a, k)) return 1;
if (!get(b, k)) return -1;
return get(b, k) - get(a, k);
};
}
return (a, b) => {
if (!get(a, k)) return 1;
if (!get(b, k)) return -1;
return get(a, k) - get(b, k);
};
};
const NULL_UUID = '00000000-0000-0000-0000-000000000000';
const STATS = {
RedPower: {
stat: 'red_power',
colour: 'red',
svg: shapes.circle,
},
GreenPower: {
stat: 'green_power',
colour: 'green',
svg: shapes.circle,
},
BluePower: {
stat: 'blue_power',
colour: 'blue',
svg: shapes.circle,
},
Speed: {
stat: 'speed',
colour: 'white',
svg: shapes.triangle,
},
RedLife: {
stat: 'red_life',
colour: 'red',
svg: shapes.square,
},
GreenLife: {
stat: 'green_life',
colour: 'green',
svg: shapes.square,
},
BlueLife: {
stat: 'blue_life',
colour: 'blue',
svg: shapes.square,
},
};
function eventClasses(resolution, construct) {
if (!resolution) return '';
const postSkill = resolution.stages.includes('POST_SKILL');
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 (construct.id !== resolution.target.id) return '';
const [type, event] = resolution.event;
if (type === 'Ko') {
if (target) return 'ko';
}
if (type === 'Disable') {
const { skill, disable } = event;
}
if (type === 'Immunity') {
const { skill, immunity } = event;
}
if (type === 'TargetKo') {
const { skill } = event;
}
if (type === 'Damage') {
const { skill, amount, mitigation, colour } = event;
// Highlight the flow of damage from source -> target
// Deal damage to construct and return effect
if (target && postSkill) {
construct.green_life.value = resolution.target.green;
if (colour === 'Red') {
construct.red_life.value = resolution.target.red;
return 'red-damage';
}
if (colour === 'Blue') {
construct.blue_life.value = resolution.target.blue;
return 'blue-damage';
}
if (colour === 'Green') {
construct.green_life.value = resolution.target.green;
return 'green-damage';
}
}
}
if (type === 'Healing') {
const { skill, amount, overhealing } = event;
if (target && postSkill) {
construct.green_life.value = resolution.target.green;
return 'green-damage';
}
}
if (type === 'Inversion') {
const { skill } = event;
}
if (type === 'Reflection') {
const { skill } = event;
}
if (type === 'Effect') {
const { skill, effect, duration, construct_effects: constructEffects } = event;
if (target && postSkill) construct.effects = constructEffects;
}
if (type === 'Skill') {
const { skill } = event;
// Highlight the flow of damage from source -> target
}
if (type === 'Removal') {
const { effect, construct_effects: constructEffects } = event;
if (target && postSkill) construct.effects = constructEffects;
}
if (type === 'Recharge') {
const { skill, red, blue } = event;
if (target && postSkill) {
if (red > 0 && blue > 0) {
construct.red_life.value = resolution.target.red;
construct.blue_life.value = resolution.target.blue;
return 'purple-damage';
}
if (red > 0) {
construct.red_life.value = resolution.target.red;
return 'red-damage';
}
if (blue > 0) {
construct.blue_life.value = resolution.target.blue;
return 'blue-damage';
}
}
}
if (type === 'Evasion') {
const { skill, evasion_rating } = event;
}
return '';
}
function getCombatSequence(resolution) {
if (!resolution.event) return false;
if (resolution.event[0] === 'Inversion') return false;
if (resolution.event[0] === 'Skill') return [['START_SKILL', 'END_SKILL']];
if (resolution.event[0] === 'Ko') return [['POST_SKILL']];
switch (resolution.stages) {
case 1: return [['START_SKILL', 'END_SKILL']];
case 2: return [['START_SKILL'], ['POST_SKILL']];
case 3: return [['START_SKILL']];
case 4: return [['END_SKILL'], ['POST_SKILL']];
case 5: return [['END_SKILL']];
case 6: return [['POST_SKILL']];
case 7: return false;
default: return [['START_SKILL', 'END_SKILL'], ['POST_SKILL']];
}
}
function getCombatText(resolution, construct) {
if (!resolution) return false;
if (!resolution.stages.includes('POST_SKILL')) return false;
if (construct.id !== resolution.target.id) return false;
const [type, event] = resolution.event;
if (type === 'Ko') {
return 'KO!';
}
if (type === 'Disable') {
const { disable } = event;
return `${disable}`;
}
if (type === 'Immunity') {
return 'IMMUNE';
}
if (type === 'Damage') {
const { mitigation, colour } = event;
let { amount } = event;
if (colour === 'Green') amount *= -1;
const mitigationText = mitigation
? `(${mitigation})`
: '';
return `${amount} ${mitigationText}`;
}
if (type === 'Healing') {
const { amount, overhealing } = event;
return `${amount} (${overhealing} OH)`;
}
if (type === 'Inversion') {
return 'INVERT';
}
if (type === 'Reflection') {
return 'REFLECT';
}
if (type === 'Effect') {
const { effect, duration } = event;
return `+ ${effect} ${duration}T`;
}
if (type === 'Recharge') {
const { red, blue } = event;
return [`+${red}R ${blue}B`, ''];
}
if (type === 'Removal') {
const { effect } = event;
return `-${effect}`;
}
return false;
}
function convertItem(v) {
if (['Red', 'Green', 'Blue'].includes(v)) {
return (
shapes.vboxColour(v.toLowerCase())
);
}
return v || <span>&nbsp;</span>;
// uncomment for double borders in vbox;
// if (v) {
// return <div>{v}</div>;
// }
// return;
}
const COLOURS = [
'#a52a2a',
'#1FF01F',
'#3498db',
];
const TARGET_COLOURS = {
BLUE: '#004bfe',
CYAN: '#27e7c0',
PURPLE: '#61008c',
YELLOW: '#fdfe02',
ORANGE: '#ff9215',
PINK: '#e766b6',
GRAY: '#9d9ea0',
LBLUE: '#87c6f2',
GREEN: '#166c4f',
BROWN: '#583108',
};
function randomPoints(numPoints, radius, dimensions) {
const {
x,
y,
width,
height,
} = dimensions;
const points = [];
let infCheck = 0;
while (points.length < numPoints) {
const c = [
Math.floor(Math.random() * (x + width - 2 * radius) + x + radius),
Math.floor(Math.random() * (y + height - 2 * radius) + y + radius),
];
let overlapping = false;
for (let j = 0; j < points.length; j += 1) {
const o = points[j];
const dx = c[0] - o[0];
const dy = c[1] - o[1];
const d = Math.floor(Math.sqrt(dx * dx + dy * dy));
if (d < radius) {
overlapping = true;
}
}
if (!overlapping) {
points.push(c);
infCheck = 0;
} else {
infCheck += 1;
if (infCheck > 100) {
break;
}
}
}
return points;
}
const removeTier = skill => {
if (skill.includes('SiphonTick')) return 'SiphonTick';
if (skill.includes('Strike')) return 'Strike';
if (skill.includes('Heal')) return 'Heal';
if (skill.includes('Blast')) return 'Blast';
if (skill.includes('Chaos')) return 'Chaos';
if (skill.includes('Slay')) return 'Slay';
if (skill.includes('Siphon')) return 'Siphon';
if (skill.includes('Snare')) return 'Snare';
if (skill.includes('Purge')) return 'Purge';
if (skill.includes('Silence')) return 'Silence';
if (skill.includes('Curse')) return 'Curse';
if (skill.includes('Decay')) return 'Decay';
if (skill.includes('Invert')) return 'Invert';
if (skill.includes('Taunt')) return 'Taunt';
if (skill.includes('Triage')) return 'Triage';
if (skill.includes('Scatter')) return 'Scatter';
if (skill.includes('Haste')) return 'Haste';
if (skill.includes('Impurity')) return 'Impurity';
if (skill.includes('Amplify')) return 'Amplify';
if (skill.includes('Parry')) return 'Parry';
if (skill.includes('Purify')) return 'Purify';
if (skill.includes('Electrify')) return 'Electrify';
if (skill.includes('Clutch')) return 'Clutch';
if (skill.includes('Reflect')) return 'Reflect';
if (skill.includes('Recharge')) return 'Recharge';
if (skill.includes('Bash')) return 'Bash';
if (skill.includes('Sleep')) return 'Sleep';
if (skill.includes('Ruin')) return 'Ruin';
if (skill.includes('Throw')) return 'Throw';
if (skill.includes('Hex')) return 'Hex';
if (skill.includes('Banish')) return 'Banish';
return skill;
};
const SERVER = process.env.NODE_ENV === 'production' ? '/api/' : 'http://localhost:40000/api';
function postData(url = '/', data = {}) {
// Default options are marked with *
return fetch(`${SERVER}${url}`, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
// mode: "no-cors", // no-cors, cors, *same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "include", // include, same-origin, *omit
headers: {
'Accept': 'application/json',
'content-type': 'application/json'
},
redirect: "error", // manual, *follow, error
// referrer: "", // no-referrer, *client
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
}
module.exports = {
stringSort,
convertItem,
numSort,
eventClasses,
getCombatSequence,
getCombatText,
postData,
SERVER,
NULL_UUID,
STATS,
COLOURS,
TARGET_COLOURS,
randomPoints,
removeTier,
};