Merge branch 'release/1.5.5'

This commit is contained in:
ntr 2019-10-15 12:52:55 +11:00
commit 0ebe13f2c3
13 changed files with 88 additions and 52 deletions

View File

@ -2,17 +2,24 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/). This project adheres to [Semantic Versioning](http://semver.org/).
## [0.0.0] - YYYY-MM-DD ## [1.5.5] - 2019-10-15
### Added
### Fixed
### Changed ### Changed
* Purge
* Fixed bug where client animations would freeze when clearing a buff
* Cooldown increased to 1T
## [0.1.5] - YYYY-MM-DD * VBOX
* You can no longer select invalid combinations.
* Controls
* Abandon button now asks for confirmation.
## [1.1.5] - 2019-10-10
### Changed ### Changed
`Recharge` Skill multiplier reduced 85/130/200 -> 70/110/170 `Recharge` Skill multiplier reduced 85/130/200 -> 70/110/170
`Absorption` 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] ## [1.1.4 2019-09-18]
### Changed ### Changed
Removed self targetting, all skills can be used on any target Removed self targetting, all skills can be used on any target
@ -21,16 +28,16 @@ Removed self targetting, all skills can be used on any target
`Purify` No cooldown `Purify` No cooldown
`Recharge` No cooldown `Recharge` No cooldown
`Banish` `Banish`
Now deals 40 / 75 / 125% target red / blue life before applying banish debuff Now deals 40 / 75 / 125% target red / blue life before applying banish debuff
Constant 2T duration at all levels Constant 2T duration at all levels
Constant 3T cooldown at all levels Constant 3T cooldown at all levels
`Link` reworked -> `Link` reworked ->
Stuns caster for 3/2/1T Stuns caster for 3/2/1T
If target has higher green life than caster: If target has higher green life than caster:
Deal blue damage to target equal to difference between green life Deal blue damage to target equal to difference between green life
Heal with green damage to source equal to difference between green life Heal with green damage to source equal to difference between green life
`Counter` effect no longer applies immunities `Counter` effect no longer applies immunities
Counter no cooldown Counter no cooldown
@ -38,7 +45,7 @@ Removed self targetting, all skills can be used on any target
Counter skill now applies block at 40% / 60% / 80% reduction for 1T Counter skill now applies block at 40% / 60% / 80% reduction for 1T
Counter no longer recharges red life Counter no longer recharges red life
`Electrify` `Electrify`
No Cooldown No Cooldown
Duration -> 1T Duration -> 1T
Electrocute duration now 2/3/4T Electrocute duration now 2/3/4T

View File

@ -1 +1 @@
1.5.4 1.5.5

View File

@ -1,20 +1,25 @@
# WORK WORK # WORK WORK
## NOW (Before PAX) ## NOW
*PRODUCTION* *PRODUCTION*
* border colours for skills e.g. strike red border, slay half red half green
* rename vbox to shop
* combat phase info system
* drag and drop buy / equip / unequip items
* mobile styles * mobile styles
* mobile info page * mobile info page
* fix info page for tablet layout * fix info page for tablet layout
* Add TOS and accept to register page
* can't reset password without knowing password =\ * can't reset password without knowing password =\
## SOON (Before or After PAX)
* Invert recharge * Invert recharge
## SOON
* equip from shop (buy and equip without putting in your inventory) for bases
* bot game grind * bot game grind
* ACP * ACP
* essential * essential
@ -48,7 +53,7 @@
reconnect based on time delta reconnect based on time delta
consolidate game and instance consolidate game and instance
* return of the combat log (last few events with condensed descriptions) * return of the combat log (last few events with condensed descriptions)
- click in to scroll - click in to scroll
* elo + leaderboards * elo + leaderboards

View File

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

View File

@ -205,7 +205,6 @@
.resolving-skill { .resolving-skill {
grid-area: target; grid-area: target;
align-self: center; align-self: center;
text-align: center;
height: auto; height: auto;
svg { svg {
display: inline; display: inline;

View File

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

View File

@ -30,23 +30,21 @@ const store = createStore(
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
); );
document.fonts.load('16pt "Jura"').then(() => { const events = registerEvents(store);
const events = registerEvents(store); // store.subscribe(() => console.log(store.getState()));
// store.subscribe(() => console.log(store.getState())); setupKeys(store);
setupKeys(store);
const ws = createSocket(events); const ws = createSocket(events);
ws.connect(); ws.connect();
events.setWs(ws); events.setWs(ws);
const App = () => ( const App = () => (
<Provider store={store}> <Provider store={store}>
<StripeProvider apiKey={stripeKey()}> <StripeProvider apiKey={stripeKey()}>
<Mnml /> <Mnml />
</StripeProvider> </StripeProvider>
</Provider> </Provider>
); );
// eslint-disable-next-line // eslint-disable-next-line
preact.render(<App />, document.body); preact.render(<App />, document.body);
});

View File

@ -49,9 +49,10 @@ function GameCtrlTopBtns(args) {
}; };
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`; const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
const abandonText = abandonState ? 'Confirm' : 'Abandon';
const abandonAction = abandonState ? sendAbandon : abandonStateTrue; const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
const abandonBtn = <button class={abandonClasses} disabled={finished} onClick={abandonAction}>Abandon</button>; const abandonBtn = <button class={abandonClasses} disabled={finished} onClick={abandonAction}>{abandonText}</button>;
const leaveBtn = <button class='abandon confirming' onClick={leave}>Leave</button>; const leaveBtn = <button class='abandon confirming' onClick={leave}>Leave</button>;
return ( return (

View File

@ -49,9 +49,10 @@ function InstanceTopBtns(args) {
}; };
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`; const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
const abandonText = abandonState ? 'Confirm' : 'Abandon';
const abandonAction = abandonState ? sendAbandon : abandonStateTrue; const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
const abandonBtn = <button class={abandonClasses} disabled={finished} onClick={abandonAction}>Abandon</button>; const abandonBtn = <button class={abandonClasses} disabled={finished} onClick={abandonAction}>{abandonText}</button>;
const leaveBtn = <button class='abandon confirming' onClick={leave}>Leave</button>; const leaveBtn = <button class='abandon confirming' onClick={leave}>Leave</button>;
return ( return (

View File

@ -1,5 +1,6 @@
const preact = require('preact'); const preact = require('preact');
const range = require('lodash/range'); const range = require('lodash/range');
const countBy = require('lodash/countBy');
const without = require('lodash/without'); const without = require('lodash/without');
const { connect } = require('preact-redux'); const { connect } = require('preact-redux');
@ -249,12 +250,35 @@ function Vbox(args) {
if (vboxSelecting) clearVboxSelected(); if (vboxSelecting) clearVboxSelected();
if (reclaiming) return sendVboxReclaim(i); if (reclaiming) return sendVboxReclaim(i);
// 4 things selected
if (combiner.length > 2) return combinerChange([i]);
// removing
const combinerIndex = combiner.indexOf(i); const combinerIndex = combiner.indexOf(i);
if (combinerIndex > -1) { if (combinerIndex > -1) {
return combinerChange(without(combiner, i)); return combinerChange(without(combiner, i));
} }
combiner.push(i); combiner.push(i);
// invalid combo
const combinerItems = combiner.map(j => vbox.bound[j]);
const combinerCounts = countBy(combinerItems, c => c);
// unless some combo
// contains every combinerItems
// and combinerItems.count of item >= components.count(item)
if (!itemInfo.combos
.some(combo => {
const comboCount = countBy(combo.components, c => c);
return combinerItems.every(c =>
combo.components.includes(c) && comboCount[c] >= combinerCounts[c]
);
})) {
return combinerChange([i]);
}
return combinerChange(combiner); return combinerChange(combiner);
} }

View File

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

View File

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

View File

@ -415,7 +415,7 @@ pub enum EventStages {
EndPost, // Skip Anim Anim EndPost, // Skip Anim Anim
EndOnly, // Skip Anim Skip EndOnly, // Skip Anim Skip
PostOnly, // Skip Skip Anim PostOnly, // Skip Skip Anim
NoStages, // Skip Skip Skip NoStages, // Skip Skip Skip
} }
#[derive(Debug,Clone,PartialEq,Serialize,Deserialize)] #[derive(Debug,Clone,PartialEq,Serialize,Deserialize)]
@ -1080,9 +1080,9 @@ impl Skill {
Skill::PurifyPlus | Skill::PurifyPlus |
Skill::PurifyPlusPlus => None, Skill::PurifyPlusPlus => None,
Skill::Purge=> None, Skill::Purge=> Some(1),
Skill::PurgePlus => None, Skill::PurgePlus => Some(1),
Skill::PurgePlusPlus => None, Skill::PurgePlusPlus => Some(1),
Skill::Banish | Skill::Banish |
Skill::BanishPlus | Skill::BanishPlus |
@ -1395,7 +1395,7 @@ fn sustain(source: &mut Construct, target: &mut Construct, mut results: Resoluti
fn intercept(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { fn intercept(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
let intercept = skill.effect()[0]; let intercept = skill.effect()[0];
results.push(Resolution::new(source, target).event(target.add_effect(skill, intercept))); results.push(Resolution::new(source, target).event(target.add_effect(skill, intercept)));
let red_amount = source.red_power().pct(skill.multiplier()); let red_amount = source.red_power().pct(skill.multiplier());
let e = target.recharge(skill, red_amount, 0); let e = target.recharge(skill, red_amount, 0);
let stages = match e { let stages = match e {
@ -1614,7 +1614,7 @@ fn electrocute(source: &mut Construct, target: &mut Construct, mut results: Reso
None => () None => ()
} }
} }
let ConstructEffect { effect, duration, meta, tick: _ } = skill.effect()[0]; let ConstructEffect { effect, duration, meta, tick: _ } = skill.effect()[0];
let tick_skill = match meta { let tick_skill = match meta {
Some(EffectMeta::Skill(s)) => s, Some(EffectMeta::Skill(s)) => s,
@ -1660,10 +1660,10 @@ fn absorption(source: &mut Construct, target: &mut Construct, mut results: Resol
results.push(Resolution::new(source, target) results.push(Resolution::new(source, target)
.event(target.add_effect(reflect_skill, absorb)) .event(target.add_effect(reflect_skill, absorb))
.stages(EventStages::PostOnly)); .stages(EventStages::PostOnly));
let absorb_index = target.effects.iter().position(|e| e.effect == Effect::Absorb).expect("No absorb"); let absorb_index = target.effects.iter().position(|e| e.effect == Effect::Absorb).expect("No absorb");
let ce = target.effects.remove(absorb_index); let ce = target.effects.remove(absorb_index);
results.push(Resolution::new(source, target) results.push(Resolution::new(source, target)
.event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() }) .event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() })
.stages(EventStages::PostOnly)); .stages(EventStages::PostOnly));
@ -1717,7 +1717,7 @@ fn recharge(source: &mut Construct, target: &mut Construct, mut results: Resolut
} }
fn siphon(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { fn siphon(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions {
let skip_tick = target.effects.iter().any(|e| e.effect == Effect::Siphon); let skip_tick = target.effects.iter().any(|e| e.effect == Effect::Siphon);
let ConstructEffect { effect, duration, meta, tick: _ } = skill.effect()[0]; let ConstructEffect { effect, duration, meta, tick: _ } = skill.effect()[0];
let tick_skill = match meta { let tick_skill = match meta {
@ -1804,7 +1804,8 @@ fn purge(source: &mut Construct, target: &mut Construct, mut results: Resolution
}) { }) {
let ce = target.effects.remove(i); let ce = target.effects.remove(i);
results.push(Resolution::new(source, target) results.push(Resolution::new(source, target)
.event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() })); .event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() })
.stages(EventStages::PostOnly));
} }
let effect = skill.effect()[0]; let effect = skill.effect()[0];