Merge branch 'release/1.5.4'
This commit is contained in:
commit
74f16bc25c
@ -7,6 +7,11 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
### Fixed
|
||||
### Changed
|
||||
|
||||
## [0.1.5] - YYYY-MM-DD
|
||||
### Changed
|
||||
`Recharge` Skill multiplier reduced 85/130/200 -> 70/110/170
|
||||
`Absorption` Skill duration reduced 5/7/9 -> 3/5/7
|
||||
|
||||
## [0.1.4 2019-09-18]
|
||||
|
||||
### Changed
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
|
||||
## SOON (Before or After PAX)
|
||||
|
||||
* Invert recharge
|
||||
* bot game grind
|
||||
* ACP
|
||||
* essential
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.5.3",
|
||||
"version": "1.5.4",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -13,6 +13,8 @@ rm -rf dist
|
||||
npm i
|
||||
npm run build
|
||||
|
||||
cp tos.html dist/
|
||||
|
||||
# echo "Building acp version $VERSION"
|
||||
# cd $MNML_PATH/acp
|
||||
# rm -rf dist
|
||||
|
||||
@ -50,19 +50,31 @@ aside {
|
||||
}
|
||||
}
|
||||
|
||||
// button.ready:enabled {
|
||||
// &:hover {
|
||||
// color: forestgreen;
|
||||
// border-color: forestgreen;
|
||||
// }
|
||||
|
||||
// &:active, &:focus, &.enabled {
|
||||
// background: forestgreen;
|
||||
// color: black;
|
||||
// border-color: forestgreen;
|
||||
// }
|
||||
// }
|
||||
|
||||
button.ready:enabled {
|
||||
&:hover {
|
||||
color: forestgreen;
|
||||
border-color: forestgreen;
|
||||
}
|
||||
|
||||
&:active, &:focus, &.enabled {
|
||||
&:hover {
|
||||
background: forestgreen;
|
||||
color: black;
|
||||
border-color: forestgreen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.timer-container {
|
||||
grid-area: timer;
|
||||
|
||||
@ -94,6 +106,7 @@ aside {
|
||||
|
||||
.ready {
|
||||
color: forestgreen;
|
||||
// animation: ready 2s linear 0s infinite alternate;
|
||||
transition-property: color, background;
|
||||
transition-duration: 0.25s;
|
||||
transition-timing-function: ease;
|
||||
@ -138,3 +151,13 @@ aside {
|
||||
border: 2px solid black;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ready {
|
||||
from {
|
||||
border-color: @gray-exists;
|
||||
}
|
||||
|
||||
to {
|
||||
border-color: forestgreen;
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,7 @@
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.instance {
|
||||
overflow-y: scroll;
|
||||
font-size: 8pt;
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
@ -129,13 +129,30 @@ section {
|
||||
.demo {
|
||||
margin-top: 1em;
|
||||
|
||||
display: grid;
|
||||
grid-template-areas:
|
||||
"vinfo game"
|
||||
"vcons game";
|
||||
display: block;
|
||||
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-rows: min-content 1fr;
|
||||
button {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 0.5em;
|
||||
|
||||
div:first-child {
|
||||
padding-right: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
.construct-section {
|
||||
.construct-list {
|
||||
height: 25em;
|
||||
grid-area: unset;
|
||||
|
||||
.instance-construct {
|
||||
// border: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.colour-info {
|
||||
grid-area: vinfo;
|
||||
@ -152,17 +169,9 @@ section {
|
||||
}
|
||||
}
|
||||
|
||||
.vbox-demo {
|
||||
grid-area: vinfo;
|
||||
}
|
||||
|
||||
.game-demo {
|
||||
grid-area: game;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
|
||||
.game {
|
||||
height: 25em;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
@ -171,15 +180,6 @@ section {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.construct-list {
|
||||
grid-area: vcons;
|
||||
height: 100%;
|
||||
|
||||
svg {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
@ -191,24 +191,6 @@ section {
|
||||
}
|
||||
}
|
||||
|
||||
.demo {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"vinfo"
|
||||
"vcons"
|
||||
"game"
|
||||
"game";
|
||||
|
||||
|
||||
.construct-list .instance-construct:not(:first-child) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.game-demo {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.menu .team {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ html body {
|
||||
-ms-user-select: none;
|
||||
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
// overflow-y: hidden;
|
||||
}
|
||||
|
||||
#mnml {
|
||||
@ -26,14 +26,14 @@ html body {
|
||||
|
||||
/* stops inspector going skitz*/
|
||||
overflow-x: hidden;
|
||||
overflow-y: hidden;
|
||||
// overflow-y: hidden;
|
||||
}
|
||||
|
||||
@media (min-width: 1921px) {
|
||||
html, body, #mnml {
|
||||
font-size: 16pt;
|
||||
}
|
||||
}
|
||||
// @media (min-width: 1921px) {
|
||||
// html, body, #mnml {
|
||||
// font-size: 16pt;
|
||||
// }
|
||||
// }
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
@ -162,13 +162,12 @@ svg {
|
||||
fill: none;
|
||||
stroke: whitesmoke;
|
||||
stroke-width: 0.5em;
|
||||
height: 2em;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
/*margin-bottom: 2em;*/
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
@ -123,4 +123,8 @@
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.play-p {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
],
|
||||
"start_url": "/index.html",
|
||||
"display": "fullscreen",
|
||||
"orientation": "portrait",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#000000"
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.5.3",
|
||||
"version": "1.5.4",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -45,8 +45,6 @@ function Demo(args) {
|
||||
|
||||
const { combiner, items, equipping, equipped, players } = demo;
|
||||
|
||||
console.log(items);
|
||||
|
||||
const vboxDemo = () => {
|
||||
function inventoryBtn(i, j) {
|
||||
if (!i) return <button disabled class='empty' > </button>;
|
||||
@ -86,7 +84,7 @@ function Demo(args) {
|
||||
|
||||
function inventoryElement() {
|
||||
return (
|
||||
<div class="vbox">
|
||||
<div class="vbox visible">
|
||||
<div class='vbox-section'>
|
||||
<h2 class='colour-info'>
|
||||
VBOX PHASE {shapes.Red()} {shapes.Green()} {shapes.Blue()}
|
||||
@ -118,14 +116,12 @@ function Demo(args) {
|
||||
? 'equipping empty gray'
|
||||
: 'empty gray';
|
||||
|
||||
return (
|
||||
<div class='news construct-list'>
|
||||
{players[0].constructs.map((c, i) => (
|
||||
<div class="instance-construct" key={i}>
|
||||
const constructEl = c => (
|
||||
<div class="instance-construct visible">
|
||||
<h2 class="name" >{c.name}</h2>
|
||||
<ConstructAvatar construct={c} />
|
||||
<div class="skills">
|
||||
{i === 0 && equipped
|
||||
{equipped
|
||||
? <button>Strike</button>
|
||||
: <button disabled={!equipping} class={btnClass}>SKILL</button>
|
||||
}
|
||||
@ -137,19 +133,30 @@ function Demo(args) {
|
||||
<div class="stats">
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
);
|
||||
|
||||
return (
|
||||
<section class="construct-section">
|
||||
<div>
|
||||
<h2>CONSTRUCTS</h2>
|
||||
<p><b>Constructs</b> are the units you control. They are reset every game and their initial appearance is randomly generated.</p>
|
||||
<p><b>Skills</b> and <b>Specs</b> you create in the <b>VBOX Phase</b> are equipped to your constructs to create a build.</p>
|
||||
</div>
|
||||
<div class='construct-list'>
|
||||
{constructEl(players[0].constructs[0])}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
const gameDemo = () => {
|
||||
return (
|
||||
<div class="game-demo">
|
||||
<section class="game-demo">
|
||||
<div>
|
||||
<h2>COMBAT PHASE</h2>
|
||||
<p>Battle your opponent using dynamic team builds from the VBOX phase.</p>
|
||||
<p>Crafted skills can be used to damage the opponent or support your team.</p>
|
||||
<p>Turn based combat, each team picks targets for their skills during this phase.</p>
|
||||
<p>The skills crafted can be used to damage the opponent or support your team.</p>
|
||||
<p>Simultaneous turn based combat: each team picks targets for their skills during this phase.</p>
|
||||
<p>The damage dealt by skills, cast order and construct life depend on your decisions in the VBOX phase.</p>
|
||||
</div>
|
||||
<div class="game">
|
||||
@ -167,7 +174,7 @@ function Demo(args) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -93,12 +93,12 @@ class GameConstruct extends Component {
|
||||
const skills = range(0, 3)
|
||||
.map(j => <SkillBtn key={j} construct={construct} i={j} j={i} animating={animating} />);
|
||||
|
||||
let crypSkills = <div> </div>;
|
||||
let crypSkills = <div></div>;
|
||||
if (player) crypSkills = (<div class="skills"> {skills} </div>);
|
||||
|
||||
const effects = construct.effects.length
|
||||
? construct.effects.map(c => <div key={c.effect}>{c.effect} - {c.duration}T</div>)
|
||||
: <div> </div>;
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@ -76,7 +76,7 @@ class Instance extends Component {
|
||||
}
|
||||
|
||||
return (
|
||||
<main id="instance" class='instance' onClick={instanceClick} onMouseOver={() => setInfo(null)} onTouchMove={onTouchMove}>
|
||||
<main id="instance" class='instance' onClick={instanceClick} onMouseOver={() => setInfo(null)}>
|
||||
<Vbox />
|
||||
<InfoContainer />
|
||||
<InstanceConstructsContainer />
|
||||
@ -85,12 +85,19 @@ class Instance extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.bindSwipes();
|
||||
if (!this.h) this.bindSwipes();
|
||||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
if (!this.h) this.bindSwipes();
|
||||
}
|
||||
|
||||
bindSwipes() {
|
||||
const instance = document.getElementById('instance');
|
||||
if (!instance) return setTimeout(this.bindSwipes, 50);
|
||||
if (!instance) {
|
||||
console.log('no instance, binding in 50');
|
||||
return setTimeout(this.bindSwipes, 50);
|
||||
}
|
||||
if (this.h) this.h.destroy();
|
||||
this.h = new Hammer(instance);
|
||||
this.h.on('swiperight', () => {
|
||||
|
||||
@ -38,6 +38,15 @@ function InstanceCtrlBtns(args) {
|
||||
|
||||
const finished = instance && instance.phase === 'Finished';
|
||||
|
||||
// cheeky to make sure nubs don't just abandon their first game
|
||||
const beingNub = instance.phase_end
|
||||
&& instance.phase === 'Lobby'
|
||||
&& Date.parse(instance.phase_end) - Date.now() < 2000;
|
||||
|
||||
if (beingNub) {
|
||||
sendReady();
|
||||
}
|
||||
|
||||
return (
|
||||
<div class="instance-ctrl-btns">
|
||||
<button disabled={true} >Chat</button>
|
||||
|
||||
@ -94,7 +94,7 @@ function Play(args) {
|
||||
<section class="top">
|
||||
<div class="news">
|
||||
<h1>v{VERSION}</h1>
|
||||
<p>Use the buttons on the right to join an instance.</p>
|
||||
<p class="play-p">Use the buttons on the right to join an instance.</p>
|
||||
<p>
|
||||
Select <b>PVP</b> to play against other players.<br />
|
||||
Select <b>INVITE</b> then click <b>COPY LINK</b> to generate an instance invitation for a friend.<br />
|
||||
|
||||
@ -34,7 +34,7 @@ function Register(args) {
|
||||
submitRegister,
|
||||
} = args;
|
||||
|
||||
const { password, confirm, name } = this.state;
|
||||
const { password, confirm, name, terms } = this.state;
|
||||
|
||||
const registerSubmit = (event) => {
|
||||
event.preventDefault();
|
||||
@ -45,7 +45,7 @@ function Register(args) {
|
||||
password === confirm;
|
||||
|
||||
const registerDisabled = () => {
|
||||
return !(registerConfirm() && password && name);
|
||||
return !(registerConfirm() && password && name && terms);
|
||||
}
|
||||
|
||||
return (
|
||||
@ -74,6 +74,14 @@ function Register(args) {
|
||||
value={this.state.confirm}
|
||||
onInput={linkState(this, 'confirm')}
|
||||
/>
|
||||
<div>
|
||||
<input
|
||||
type="checkbox"
|
||||
onInput={linkState(this, 'terms')
|
||||
}/>
|
||||
Confirm agreement to terms of service
|
||||
<button onClick={() => window.open('/tos.html')}>VIEW</button>
|
||||
</div>
|
||||
<button
|
||||
class="login-btn"
|
||||
disabled={registerDisabled()}
|
||||
|
||||
1098
client/tos.html
Normal file
1098
client/tos.html
Normal file
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,9 @@ map $http_upgrade $connection_upgrade {
|
||||
server {
|
||||
server_name sixtysix.pro;
|
||||
|
||||
auth_basic "who dis";
|
||||
auth_basic_user_file /etc/mnml/htpasswd.users;
|
||||
|
||||
location / {
|
||||
root /var/lib/mnml/public/current;
|
||||
index index.html;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-ops",
|
||||
"version": "1.5.3",
|
||||
"version": "1.5.4",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mnml"
|
||||
version = "1.5.3"
|
||||
version = "1.5.4"
|
||||
authors = ["ntr <ntr@smokestack.io>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -161,12 +161,12 @@ impl Game {
|
||||
self.skill_phase_start(0)
|
||||
}
|
||||
|
||||
fn skill_phase_start(mut self, resolution_time: i64) -> Game {
|
||||
fn skill_phase_start(mut self, resolution_animation_ms: i64) -> Game {
|
||||
self.phase_start = Utc::now()
|
||||
.checked_add_signed(Duration::milliseconds(resolution_time))
|
||||
.checked_add_signed(Duration::milliseconds(resolution_animation_ms))
|
||||
.expect("could not set phase start");
|
||||
|
||||
self.phase_end = self.time_control.game_phase_end(resolution_time);
|
||||
self.phase_end = self.time_control.game_phase_end(resolution_animation_ms);
|
||||
|
||||
for player in self.players.iter_mut() {
|
||||
if player.skills_required() == 0 {
|
||||
@ -426,12 +426,12 @@ impl Game {
|
||||
// temp vec of this round's resolving skills
|
||||
// because need to check cooldown use before pushing them into the complete list
|
||||
let mut casts = vec![];
|
||||
let mut resolution_delay = 0;
|
||||
let mut r_animation_ms = 0;
|
||||
while let Some(cast) = self.stack.pop() {
|
||||
// info!("{:} casts ", cast);
|
||||
|
||||
let mut resolutions = resolution_steps(&cast, &mut self);
|
||||
resolution_delay = resolutions.iter().fold(resolution_delay, |acc, r| acc + r.clone().get_delay());
|
||||
r_animation_ms = resolutions.iter().fold(r_animation_ms, |acc, r| acc + r.clone().get_delay());
|
||||
self.resolved.append(&mut resolutions);
|
||||
|
||||
// while let Some(resolution) = resolutions.pop() {
|
||||
@ -457,7 +457,7 @@ impl Game {
|
||||
return self.finish()
|
||||
}
|
||||
|
||||
self.skill_phase_start(resolution_delay)
|
||||
self.skill_phase_start(r_animation_ms)
|
||||
}
|
||||
|
||||
fn progress_durations(&mut self, resolved: &Vec<Cast>) -> &mut Game {
|
||||
|
||||
@ -530,13 +530,13 @@ pub fn instance_create(tx: &mut Transaction, instance: Instance) -> Result<Insta
|
||||
let instance_bytes = to_vec(&instance)?;
|
||||
|
||||
let query = "
|
||||
INSERT INTO instances (id, data)
|
||||
VALUES ($1, $2)
|
||||
INSERT INTO instances (id, data, upkeep)
|
||||
VALUES ($1, $2, $3)
|
||||
RETURNING id;
|
||||
";
|
||||
|
||||
let result = tx
|
||||
.query(query, &[&instance.id, &instance_bytes])?;
|
||||
.query(query, &[&instance.id, &instance_bytes, &instance.phase_end])?;
|
||||
|
||||
result.iter().next().ok_or(format_err!("no instances written"))?;
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use rand::prelude::*;
|
||||
use rand::{thread_rng};
|
||||
|
||||
const FIRSTS: [&'static str; 51] = [
|
||||
const FIRSTS: [&'static str; 53] = [
|
||||
"artificial",
|
||||
"ambient",
|
||||
"borean",
|
||||
@ -43,9 +43,11 @@ const FIRSTS: [&'static str; 51] = [
|
||||
"ossified",
|
||||
"orbiting",
|
||||
"piscine",
|
||||
"polar",
|
||||
"purified",
|
||||
"recalcitrant",
|
||||
"rogue",
|
||||
"sealed",
|
||||
"subversive",
|
||||
"subterranean",
|
||||
"supercooled",
|
||||
@ -55,13 +57,16 @@ const FIRSTS: [&'static str; 51] = [
|
||||
"weary",
|
||||
];
|
||||
|
||||
const LASTS: [&'static str; 56] = [
|
||||
const LASTS: [&'static str; 63] = [
|
||||
"artifact",
|
||||
"assembly",
|
||||
"antenna",
|
||||
"alloy",
|
||||
"carrier",
|
||||
"carbon",
|
||||
"console",
|
||||
"construct",
|
||||
"coordinates",
|
||||
"craft",
|
||||
"core",
|
||||
"design",
|
||||
@ -77,18 +82,22 @@ const LASTS: [&'static str; 56] = [
|
||||
"fossil",
|
||||
"frequency",
|
||||
"function",
|
||||
"fusion",
|
||||
"fission",
|
||||
"information",
|
||||
"insulator",
|
||||
"layout",
|
||||
"lifeform",
|
||||
"liquid",
|
||||
"landmass",
|
||||
"lens",
|
||||
"mass",
|
||||
"mantle",
|
||||
"magnetism",
|
||||
"mechanism",
|
||||
"mountain",
|
||||
"nectar",
|
||||
"oak",
|
||||
"nebula",
|
||||
"oxide",
|
||||
"orbit",
|
||||
"pattern",
|
||||
|
||||
@ -294,7 +294,7 @@ fn post_resolve(_skill: Skill, game: &mut Game, mut resolutions: Resolutions) ->
|
||||
|
||||
match event {
|
||||
Event::Damage { amount, skill, mitigation: _, colour: c } => {
|
||||
if target.affected(Effect::Electric) {
|
||||
if target.affected(Effect::Electric) && !skill.is_tick() {
|
||||
let ConstructEffect { effect: _, duration: _, meta, tick: _ } = target.effects.iter()
|
||||
.find(|e| e.effect == Effect::Electric).unwrap().clone();
|
||||
match meta {
|
||||
@ -786,9 +786,9 @@ impl Skill {
|
||||
Skill::ReflectPlus => 70,
|
||||
Skill::ReflectPlusPlus => 100,
|
||||
|
||||
Skill::Recharge=> 85, //Recharge red and blue life (heal)
|
||||
Skill::RechargePlus => 130,
|
||||
Skill::RechargePlusPlus => 200,
|
||||
Skill::Recharge=> 70, //Recharge red and blue life (heal)
|
||||
Skill::RechargePlus => 110,
|
||||
Skill::RechargePlusPlus => 170,
|
||||
|
||||
Skill::Sustain => 120, // Recharge red life (heal)
|
||||
Skill::SustainPlus => 150,
|
||||
@ -907,9 +907,9 @@ impl Skill {
|
||||
Skill::AbsorbPlusPlus => vec![ConstructEffect {effect: Effect::Absorb, duration: 4,
|
||||
meta: Some(EffectMeta::Skill(Skill::AbsorptionPlusPlus)), tick: None}],
|
||||
|
||||
Skill::Absorption => vec![ConstructEffect {effect: Effect::Absorption, duration: 5, meta: None, tick: None}],
|
||||
Skill::AbsorptionPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 7, meta: None, tick: None}],
|
||||
Skill::AbsorptionPlusPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 9, meta: None, tick: None}],
|
||||
Skill::Absorption => vec![ConstructEffect {effect: Effect::Absorption, duration: 3, meta: None, tick: None}],
|
||||
Skill::AbsorptionPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 5, meta: None, tick: None}],
|
||||
Skill::AbsorptionPlusPlus => vec![ConstructEffect {effect: Effect::Absorption, duration: 7, meta: None, tick: None}],
|
||||
|
||||
Skill::Hybrid => vec![ConstructEffect {effect: Effect::Hybrid, duration: 2,
|
||||
meta: Some(EffectMeta::Multiplier(150)), tick: None }],
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user