Merge tag '1.5.4' into develop

1.5.4
This commit is contained in:
ntr 2019-10-10 18:33:49 +11:00
commit 349c74c08e
21 changed files with 1247 additions and 101 deletions

View File

@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [0.1.5] - YYYY-MM-DD
### Changed
`Recharge` Skill multiplier reduced 85/130/200 -> 70/110/170
`Absorbption` Skill duration reduced 5/7/9 -> 3/5/7
`Absorption` Skill duration reduced 5/7/9 -> 3/5/7
## [0.1.4 2019-09-18]

View File

@ -1 +1 @@
1.5.3
1.5.4

View File

@ -1,6 +1,6 @@
{
"name": "mnml-client",
"version": "1.5.3",
"version": "1.5.4",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -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

View File

@ -50,19 +50,31 @@ aside {
}
}
button.ready:enabled {
&:hover {
color: forestgreen;
border-color: forestgreen;
}
// button.ready:enabled {
// &:hover {
// color: forestgreen;
// border-color: forestgreen;
// }
&:active, &:focus, &.enabled {
// &:active, &:focus, &.enabled {
// background: forestgreen;
// color: black;
// border-color: forestgreen;
// }
// }
button.ready:enabled {
color: forestgreen;
border-color: forestgreen;
&: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;
@ -137,4 +150,14 @@ aside {
color: black;
border: 2px solid black;
}
}
@keyframes ready {
from {
border-color: @gray-exists;
}
to {
border-color: forestgreen;
}
}

View File

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

View File

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

View File

@ -123,4 +123,8 @@
padding: 0;
}
}
.play-p {
display: none;
}
}

View File

@ -1,6 +1,6 @@
{
"name": "mnml-client",
"version": "1.5.3",
"version": "1.5.4",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -84,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()}
@ -116,39 +116,48 @@ 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}>
<h2 class="name" >{c.name}</h2>
<ConstructAvatar construct={c} />
<div class="skills">
{i === 0 && equipped
? <button>Strike</button>
: <button disabled={!equipping} class={btnClass}>SKILL</button>
}
<button disabled={!equipping} class={btnClass}>SKILL</button>
<button disabled={!equipping} class={btnClass}>SKILL</button>
</div>
<div class="specs">
</div>
<div class="stats">
</div>
</div>
))}
const constructEl = c => (
<div class="instance-construct visible">
<h2 class="name" >{c.name}</h2>
<ConstructAvatar construct={c} />
<div class="skills">
{equipped
? <button>Strike</button>
: <button disabled={!equipping} class={btnClass}>SKILL</button>
}
<button disabled={!equipping} class={btnClass}>SKILL</button>
<button disabled={!equipping} class={btnClass}>SKILL</button>
</div>
<div class="specs">
</div>
<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 damage dealt by skills, cast order and construct life depend on your decisions in the VBOX 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">
<div class="game-construct">
@ -165,7 +174,7 @@ function Demo(args) {
</div>
</div>
</div>
</div>
</section>
);
};

View File

@ -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> &nbsp; </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>&nbsp;</div>;
: null;
return (
<div

View File

@ -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>

View File

@ -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 />

View File

@ -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')
}/>
&nbsp; Confirm agreement to terms of service &nbsp;
<button onClick={() => window.open('/tos.html')}>VIEW</button>
</div>
<button
class="login-btn"
disabled={registerDisabled()}

1098
client/tos.html Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,6 +1,6 @@
{
"name": "mnml-ops",
"version": "1.5.3",
"version": "1.5.4",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -1,6 +1,6 @@
[package]
name = "mnml"
version = "1.5.3"
version = "1.5.4"
authors = ["ntr <ntr@smokestack.io>"]
[dependencies]

View File

@ -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"))?;

View File

@ -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",

View File

@ -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 {