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

View File

@ -9,6 +9,7 @@
<meta name="description" content="mnml pvp tbs">
<meta name="author" content="ntr@smokestack.io">
<link rel="manifest" href="manifest.webmanifest">
<link href="https://fonts.googleapis.com/css?family=Jura" rel="stylesheet">
<link rel="stylesheet" href="./node_modules/izitoast/dist/css/iziToast.min.css"></script>
<link rel="stylesheet" href="assets/styles/normalize.css">
<link rel="stylesheet" href="assets/styles/skeleton.css">

View File

@ -3,7 +3,6 @@ require('./assets/styles/styles.mobile.css');
require('./assets/styles/instance.css');
require('./assets/styles/instance.mobile.css');
require('./assets/styles/game.css');
require('./assets/styles/anims.css');
// kick it off
require('./src/animations.test');
require('./src/animations.test.jsx');

View File

@ -72,7 +72,7 @@
"name "
"stats ";
transition-property: all;
transition-property: translate;
transition-duration: 0.25s;
transition-delay: 0;
transition-timing-function: ease;
@ -186,8 +186,8 @@
.game-construct.ko {
animation: none;
opacity: 0.35;
filter: grayscale(100%);
}
/* filter: grayscale(100%);
*/}
.game-construct.ko button:hover {
color: #333;
@ -195,12 +195,12 @@
.game-construct.unfocus {
opacity: 0.65;
filter: blur(5px);
}
/* filter: blur(5px);
*/}
.game-construct.unfocus.ko {
filter: blur(5px) grayscale(100%);
}
/* filter: blur(5px) grayscale(100%);
*/}
.combat-text {
font-size: 2em;
@ -227,12 +227,12 @@
}
.game-construct.active-skill {
filter: drop-shadow(0 0 0.2em silver);
}
/* filter: drop-shadow(0 0 0.2em silver);
*/}
.game-construct.red-damage {
filter: drop-shadow(0 0 0.2em red);
color: red;
/* filter: drop-shadow(0 0 0.2em red);
*/ color: red;
/*ensure construct doesn't get opacity lowered because of being KO before the KO animation*/
opacity: 1;
@ -253,8 +253,8 @@
}
.game-construct.blue-damage {
filter: drop-shadow(0 0 0.2em blue);
color: blue;
/* filter: drop-shadow(0 0 0.2em blue);
*/ color: blue;
opacity: 1;
/*border-color: blue;*/
}
@ -273,8 +273,8 @@
}
.game-construct.green-damage {
filter: drop-shadow(0 0 0.2em green);
color: green;
/* filter: drop-shadow(0 0 0.2em green);
*/ color: green;
opacity: 1;
/*border-color: green;*/
}
@ -293,8 +293,8 @@
}
.game-construct.purple-damage {
filter: drop-shadow(0 0 0.2em purple);
color: purple;
/* filter: drop-shadow(0 0 0.2em purple);
*/ color: purple;
border-color: purple;
}

View File

@ -80,6 +80,7 @@ nav {
grid-area: nav;
padding-left: 2em;
margin-right: 2em;
max-height: 100%;
}
nav h2:first-child {

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;

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);

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',
];

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
});
}

View File

@ -13,7 +13,7 @@ use ws::{MnmlSocket};
use construct::{Construct, construct_spawn, construct_delete};
use game::{Game, game_state, game_skill, game_ready};
use account::{Account, account_constructs, account_instances};
use skill::{Skill};
use skill::{Skill, dev_resolve, Resolutions};
use instance::{Instance, instance_state, instance_list, instance_new, instance_ready, instance_join};
use vbox::{vbox_accept, vbox_apply, vbox_discard, vbox_combine, vbox_reclaim, vbox_unequip};
use item::{Item, ItemInfoCtr, item_info};
@ -39,6 +39,7 @@ pub fn receive(data: Vec<u8>, db: &Db, _client: &mut MnmlWs, begin: Instant, acc
// if no auth required
match v.method.as_ref() {
"item_info" => return Ok(RpcResult::ItemInfo(item_info())),
"dev_game_resolve" => return handle_dev_resolve(data),
_ => match account {
Some(_) => (),
None => return Err(err_msg("auth required")),
@ -209,6 +210,11 @@ fn handle_vbox_unequip(data: Vec<u8>, tx: &mut Transaction, account: &Account) -
Ok(RpcResult::InstanceState(vbox_unequip(msg.params, tx, &account)?))
}
fn handle_dev_resolve(data: Vec<u8>) -> Result<RpcResult, Error> {
let msg = from_slice::<DevResolveMsg>(&data).or(Err(err_msg("invalid params")))?;
Ok(RpcResult::DevResolutions(dev_resolve(msg.params.a, msg.params.b, msg.params.skill)))
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct RpcErrorResponse {
pub err: String
@ -226,6 +232,8 @@ pub enum RpcResult {
InstanceState(Instance),
Pong(()),
DevResolutions(Resolutions),
}
#[derive(Debug,Clone,Serialize,Deserialize)]
@ -434,6 +442,19 @@ pub struct VboxReclaimParams {
pub index: usize,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
struct DevResolveMsg {
method: String,
params: DevResolveParams,
}
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct DevResolveParams {
pub a: Uuid,
pub b: Uuid,
pub skill: Skill,
}
// #[cfg(test)]
// mod tests {
// use super::*;

View File

@ -8,6 +8,14 @@ use item::{Item};
use game::{Game};
use effect::{Effect, Colour, Cooldown};
pub fn dev_resolve(a_id: Uuid, b_id: Uuid, skill: Skill) -> Resolutions {
let mut a = Construct::new();
a.id = a_id;
let mut b = Construct::new();
b.id = b_id;
return resolve(skill, &mut a, &mut b, vec![]);
}
pub fn resolution_steps(cast: &Cast, game: &mut Game) -> Resolutions {
let mut resolutions = vec![];
@ -464,7 +472,7 @@ pub enum Event {
Evasion { skill: Skill, evasion_rating: u64 },
}
type Resolutions = Vec<Resolution>;
pub type Resolutions = Vec<Resolution>;
#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)]
pub enum Skill {