animations env

This commit is contained in:
ntr
2019-06-29 14:42:34 +10:00
parent 6651735758
commit 214214e838
10 changed files with 289 additions and 39 deletions
+119
View File
@@ -0,0 +1,119 @@
const cbor = require('borc');
const toast = require('izitoast');
const eachSeries = require('async/eachSeries');
const actions = require('./actions');
const { TIMES } = require('./constants');
const { getCombatSequence } = require('./utils');
const SOCKET_URL = process.env.NODE_ENV === 'production' ? 'wss://mnml.gg/api/ws' : 'ws://localhost:40000/api/ws';
function createSocket(store) {
let ws = null;
// -------------
// Outgoing
// -------------
function send(msg) {
if (msg.method !== 'ping') console.log('outgoing msg', msg);
ws.send(cbor.encode(msg));
}
function sendDevResolve(a, b, skill) {
send({ method: 'dev_game_resolve', params: { a, b, skill } });
}
function onDevResolutions(newRes) {
const { game: currentGame } = store.getState();
return eachSeries(newRes, (r, cb) => {
if (['Disable', 'TargetKo'].includes(r.event[0])) return cb();
// Create sub events for combat animations
const sequence = getCombatSequence(r);
return eachSeries(sequence, (stage, sCb) => {
const { skip } = store.getState();
if (skip) return sCb('skip');
const stagedR = Object.create(r);
stagedR.stage = stage;
store.dispatch(actions.setResolution(stagedR));
return setTimeout(sCb, TIMES[stage]);
}, err => {
if (err) console.error(err);
// Finished this resolution
return cb();
});
}, err => {
if (err) return console.error(err);
store.dispatch(actions.setResolution(null));
// stop skipping resolutions
store.dispatch(actions.setSkip(false));
// update the game
store.dispatch(actions.setGame(currentGame));
// get the latest state and restart polling
return true;
});
}
const handlers = {
DevResolutions: onDevResolutions,
};
// decodes the cbor and
// calls the handlers defined above based on message type
function onMessage(event) {
// decode binary msg from server
const blob = new Uint8Array(event.data);
const res = cbor.decode(blob);
const [msgType, params] = res;
return handlers[msgType](params);
}
// Connection opened
function onOpen() {
toast.info({
message: 'connected',
position: 'topRight',
});
return true;
}
function onError(event) {
console.error('WebSocket error', event);
}
function onClose(event) {
console.error('WebSocket closed', event);
toast.warning({
message: 'disconnected',
position: 'topRight',
});
return setTimeout(connect, 5000);
}
function connect() {
if (ws) {
ws.removeEventListener('open', onOpen);
ws.removeEventListener('message', onMessage);
ws.removeEventListener('error', onError);
ws.removeEventListener('close', onClose);
ws = null;
}
ws = new WebSocket(SOCKET_URL);
ws.binaryType = 'arraybuffer';
// Listen for messages
ws.addEventListener('open', onOpen);
ws.addEventListener('message', onMessage);
ws.addEventListener('error', onError);
ws.addEventListener('close', onClose);
return ws;
}
return {
sendDevResolve,
connect,
};
}
module.exports = createSocket;
-16
View File
@@ -1,16 +0,0 @@
const preact = require('preact');
const TrippyTriangle = require('./components/svgs/trippy.triangle');
const Amplify = require('./components/svgs/amplify');
const Hex = require('./components/svgs/hex');
const Animations = () => (
<main>
<TrippyTriangle />
<Amplify />
<Hex />
</main>
);
// eslint-disable-next-line
preact.render(<Animations />, document.body);
+117
View File
@@ -0,0 +1,117 @@
const preact = require('preact');
const { Provider } = require('preact-redux');
const { createStore, combineReducers } = require('redux');
const reducers = require('./reducers');
const actions = require('./actions');
const createSocket = require('./animations.socket');
// const TrippyTriangle = require('./components/svgs/trippy.triangle');
// const Amplify = require('./components/svgs/amplify');
// const Hex = require('./components/svgs/hex');
const Game = require('./components/game');
const testGameBuilder = require('./test.game');
const testGame = testGameBuilder('8552e0bf-340d-4fc8-b6fc-cccccccccccc');
const testAccount = {
id: '8552e0bf-340d-4fc8-b6fc-cccccccccccc',
name: 'ntr',
};
// Redux Store
const store = createStore(
combineReducers(reducers)
);
store.subscribe(() => console.log(store.getState()));
store.dispatch(actions.setAccount(testAccount));
store.dispatch(actions.setGame(testGame));
function animationsNav(ws) {
function useSkill(skill) {
const ateam = Math.round(Math.random());
const bteam = Math.round(Math.random());
const acon = Math.floor(Math.random() * 3);
const bcon = Math.floor(Math.random() * 3);
const a = testGame.players[ateam].constructs[acon].id;
const b = testGame.players[bteam].constructs[bcon].id;
return ws.sendDevResolve(a, b, skill);
}
return SKILLS.map((s, i) => (
<button
key={i}
onClick={() => useSkill(s)}>
{s}
</button>
));
}
document.fonts.load('16pt "Jura"').then(() => {
const ws = createSocket(store);
ws.connect();
const Animations = () => (
<Provider store={store}>
<div id="mnml">
<nav>
{animationsNav(ws)}
</nav>
<Game />
</div>
</Provider>
);
// eslint-disable-next-line
preact.render(<Animations />, document.body);
});
const SKILLS = [
'Attack',
'Debuff',
'Buff',
'Block',
'Stun',
'AmplifyI',
'BanishI',
'BashI',
'BlastI',
'ChaosI',
'ClutchI',
'CorruptI',
'CorruptionI',
'CorruptionTickI',
'CurseI',
'DecayI',
'DecayTickI',
'HasteI',
'HasteStrike',
'HealI',
'HexI',
'HatredI',
'HostilityI',
'ImpureBlast',
'ImpurityI',
'InvertI',
'ParryI',
'PurgeI',
'PurifyI',
'RechargeI',
'ReflectI',
'RiposteI',
'RuinI',
'ScatterI',
'SilenceI',
'SiphonI',
'SiphonTickI',
'SlayI',
'SleepI',
'SnareI',
'StrikeI',
'TauntI',
'ThrowI',
'TriageI',
'TriageTickI',
];
+2 -2
View File
@@ -64,11 +64,11 @@ class SiphonTick extends Component {
componentDidMount() {
if (!this.props.team) {
anime.set('.skill-anim', {
rotate: Math.random() * 180 + 90,
rotate: 90
});
} else {
anime.set('.skill-anim', {
rotate: Math.random() * 180 + 270,
rotate: 270
});
}