From 4c0a9088a104b26ee37b05f9722cf8adbc193aab Mon Sep 17 00:00:00 2001 From: Mashy Date: Sat, 9 Nov 2019 15:57:32 +1000 Subject: [PATCH 01/53] fix reshape available mtx bug --- client/src/components/reshape.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/components/reshape.jsx b/client/src/components/reshape.jsx index 68ca09b0..835f4a8e 100644 --- a/client/src/components/reshape.jsx +++ b/client/src/components/reshape.jsx @@ -56,7 +56,7 @@ function Reshape(args) { const useMtx = (item, i) => { const price = item === 'Rename' ? 5 : 1; return ( -
{ +
{ e.stopPropagation(); setMtxActive(item); }}> @@ -67,7 +67,7 @@ function Reshape(args) { }; const availableMtx = (item, i) => ( -
+
Enable {item.variant}
From 7acf060093c9df4b9b68affb8e7a795cc5575704 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sun, 10 Nov 2019 08:13:42 +1000 Subject: [PATCH 02/53] 1.8.2 --- VERSION | 2 +- acp/package.json | 2 +- client/package.json | 2 +- ops/package.json | 2 +- server/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index b9268dae..0bfbd573 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.8.1 \ No newline at end of file +1.8.2 \ No newline at end of file diff --git a/acp/package.json b/acp/package.json index 904e91c6..3a0fffbb 100644 --- a/acp/package.json +++ b/acp/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.8.1", + "version": "1.8.2", "description": "", "main": "index.js", "scripts": { diff --git a/client/package.json b/client/package.json index 119c92f2..a6fc3780 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.8.1", + "version": "1.8.2", "description": "", "main": "index.js", "scripts": { diff --git a/ops/package.json b/ops/package.json index 0032bde9..e1198adc 100644 --- a/ops/package.json +++ b/ops/package.json @@ -1,6 +1,6 @@ { "name": "mnml-ops", - "version": "1.8.1", + "version": "1.8.2", "description": "", "main": "index.js", "scripts": { diff --git a/server/Cargo.toml b/server/Cargo.toml index 70ecb662..3f9b7bfb 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml" -version = "1.8.1" +version = "1.8.2" authors = ["ntr "] [dependencies] From 19a1e799c5896fe959ef8cbcf0c2d131627dcd35 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sun, 10 Nov 2019 08:24:19 +1000 Subject: [PATCH 03/53] changelog --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dca06b3..d54d2180 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,7 @@ -## [1.8.1] - 2019-11-07 +## [1.8.2] - 2019-11-10 +- Fixed a duplicate button issue in reshape tab + +## [1.8.1] - 2019-11-09 ### Fixed - An issue where skills would not be put on cooldown after being used. From 6fdff259ec88d077057cc0367be8612836ed8190 Mon Sep 17 00:00:00 2001 From: Mashy Date: Sun, 10 Nov 2019 11:21:50 +1000 Subject: [PATCH 04/53] host changelog --- bin/client.sh | 1 + client/changelog.html | 1176 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1177 insertions(+) mode change 100755 => 100644 bin/client.sh create mode 100644 client/changelog.html diff --git a/bin/client.sh b/bin/client.sh old mode 100755 new mode 100644 index 06daf871..8d1f9c5b --- a/bin/client.sh +++ b/bin/client.sh @@ -14,6 +14,7 @@ npm i npm run build cp tos.html dist/ +cp changelog.html dist/ # echo "Building acp version $VERSION" # cd $MNML_PATH/acp diff --git a/client/changelog.html b/client/changelog.html new file mode 100644 index 00000000..d43f4593 --- /dev/null +++ b/client/changelog.html @@ -0,0 +1,1176 @@ +CHANGELOG

+[1.8.2] - 2019-11-10

+
    +
  • Fixed a duplicate button issue in reshape tab
  • +
+

+[1.8.1] - 2019-11-09

+

+Fixed

+
    +
  • An issue where skills would not be put on cooldown after being used.
  • +
+

+Changed

+
    +
  • +

    Game phase

    +
      +
    • Background for text overlapping with avatars in game phase (mobile)
    • +
    • Fixed issue where effect text would show when not highlighted
    • +
    • Avatar size doesn't decrease as effects are applied (now overlap)
    • +
    • Added back KO! event when a construct is knocked out
    • +
    +
  • +
  • +

    Invert

    +
      +
    • Now reverses recharge into damage
    • +
    +
  • +
  • +

    Link

    +
      +
    • Reworked completely
    • +
    • Now stuns target for 1T with 1T CD
    • +
    • Deals 20/45/70% blue power multiplied by number of effects on target as blue damage
    • +
    • Applies stun before effect multiplier calculation
    • +
    +
  • +
  • +

    Restrict

    +
      +
    • Changed cooldown from 2T -> 1T
    • +
    • Duration now 2T at all levels
    • +
    +
  • +
  • +

    Ruin

    +
      +
    • Cooldown now 2T at all levels (down from 3T)
    • +
    • Now deals damage to each target (40/70/100)%
    • +
    +
  • +
  • +

    Silence

    +
      +
    • Changed cooldown from 2T -> 1T
    • +
    • Duration now 2T at all levels
    • +
    +
  • +
+

+[1.8.0] - 2019-11-06

+

+Added

+
    +
  • +

    Drag and drop for vbox interactions can be used instead of single click / double click

    +
  • +
  • +

    Base white items and be directly equipped from vbox rather than going through the inventory

    +
      +
    • Useful if you want to equip an item without further combining with colours
    • +
    +
  • +
  • +

    You can swap skills and specs between constructs without using the inventory

    +
  • +
+

+Changed

+
    +
  • +

    Construct life changed

    +
      +
    • You now start with 800 green life (down from 950)
    • +
    • You now start with 125 red life and blue life (up from 0)
    • +
    +
  • +
  • +

    Game phase layout

    +
      +
    • Enemy team effects appear under your construct instead of next to it
    • +
    • Game phase constructs line up symmetrically now
    • +
    +
  • +
  • +

    Mobile

    +
      +
    • Tutorial is disabled for mobile view
    • +
    • Landscape is now default view
    • +
    • Vbox phase everything is now in one view
    • +
    • Game constructs and animations are much larger in mobile view
    • +
    +
  • +
  • +

    Amplify

    +
      +
    • Now increases green power
    • +
    +
  • +
  • +

    Absorb

    +
      +
    • Reduced duration and cooldown from 2T -> 1T (Absorption duration unchanged)
    • +
    • Absorption damage is now based on all damage taken (previously only green damage taken)
    • +
    • Now recharges blue life based on 95 / 120 / 155 blue power
    • +
    +
  • +
  • +

    Banish

    +
      +
    • Reduced cooldown to 1T
    • +
    +
  • +
  • +

    Decay

    +
      +
    • Removed cooldown
    • +
    +
  • +
  • +

    Haste / Hybrid

    +
      +
    • Fixed issue when hybridblast and hastestrike wouldn't trigger from upgraded + skills
    • +
    +
  • +
  • +

    Intercept

    +
      +
    • Reduced duration to 1T down from 2T
    • +
    • Reduced cooldown to 1T down from 2T
    • +
    +
  • +
+

+[1.7.0] - 2019-10-31

+

+Added

+
    +
  • +

    Step by step tutorial

    +
      +
    • Will activate during the learn game for the first round
    • +
    • There is a button which will exit tutorial so you can continune the normal practice mode
    • +
    +
  • +
  • +

    Skill combo previews

    +
      +
    • You can now preview what item combos will create!
    • +
    • Click into the item in the info section table (top right) and it will be replaced with the new item
    • +
    +
  • +
+

+Changed

+
    +
  • +

    Vbox phase

    +
      +
    • Made general performance improvements
    • +
    • Removed the default info state (should be smoother to navigate now)
    • +
    • When combining or selecting base items (skills/specs) the base item info won't be replaced with other vbox items
    • +
    • Added info text for construct names and avatars
    • +
    • Changed a number of info descriptions for clarity
    • +
    +
  • +
  • +

    Game phase

    +
      +
    • Made general performance improvements
    • +
    • Now has default tutorial text for the first round (tells the player to select skills and then the targets)
    • +
    +
  • +
  • +

    Moved the login page demo to a new info tab

    +
  • +
  • +

    Increased the speed of demo and it now creates random combos

    +
  • +
  • +

    Banish

    +
      +
    • Cooldown reduced to 2T (was 3T)
    • +
    +
  • +
  • +

    Bash

    +
      +
    • Skill multiplier reduced from 65/95/140 -> 45/65/100
    • +
    +
  • +
  • +

    Blast

    +
      +
    • Damage multiplier reduced 110/145/210 -> 105/140/200
    • +
    +
  • +
  • +

    Block

    +
      +
    • Previously reduced red damage taken by 50%
    • +
    • Now reduces red damage and blue damage taken by 65%
    • +
    +
  • +
  • +

    Buff

    +
      +
    • Previously increased red power and speed stat by 25%
    • +
    • Now increases red power, blue power and speed stat by 30%
    • +
    • Increased duration from 2T -> 3T
    • +
    +
  • +
  • +

    Counter

    +
      +
    • No longer applies block effect
    • +
    • CounterAttack multiplier increased from 70/95/120 -> 120/160/230
    • +
    • Will now animate an attack animation on counter attack
    • +
    +
  • +
  • +

    Curse

    +
      +
    • Now created by combining Debuff + RB was Debuff + RG
    • +
    • Fixed issue where curse was only increasing blue damage taken instead of red and blue
    • +
    • Fixed an issue where the animation would not display if it occured already
    • +
    +
  • +
  • +

    Haste

    +
      +
    • Cooldown reduced to 1T (was 2T)
    • +
    • Duration increased from 2/3/4T -> 3/4/5T
    • +
    • HasteStrike damage multiplier changed from 30% -> 60%
    • +
    +
  • +
  • +

    Hybrid

    +
      +
    • Cooldown reduced to 1T (was 3T)
    • +
    • Duration increased from 2/3/4T -> 3/4/5T
    • +
    • HybridBlast damage multiplier changed from 25% -> 50%
    • +
    +
  • +
  • +

    Invert

    +
      +
    • Now created by combining Debuff + RG was debuff + RB
    • +
    +
  • +
  • +

    Silence

    +
      +
    • Cooldown reduced to 2T (was 3T)
    • +
    +
  • +
  • +

    Siphon

    +
      +
    • Skill multiplier increased from 20/25/30 -> 25/30/40
    • +
    • Reworded part of description "Construct heals self for 100% of damage dealt to target construct GreenLife."
    • +
    +
  • +
  • +

    Slay

    +
      +
    • Self healing is now 50% of damage dealt to green life (was 100%)
    • +
    • Damage multiplier increased from (40/60/90)% -> (45/65/100)%
    • +
    +
  • +
  • +

    Sleep

    +
      +
    • Cooldown reduced to 2T (was 3T)
    • +
    • Skill multiplier reduced from 240/300/400 -> 200/290/400
    • +
    +
  • +
+

+[1.6.6] - 2019-10-27

+

+Added

+
    +
  • Offering of draws +
      +
    • Neither player receives a point if they agree to a draw
    • +
    • Bots automatically agree to draws
    • +
    +
  • +
+

+[1.6.5] - 2019-10-25

+

+Fixed

+
    +
  • Stripe being blocked no longer causes unrecoverable error
  • +
  • Automatic ready up is now throttled after abandons
  • +
  • Player width styling
  • +
+

+Changed

+
    +
  • Improved wiggle animation
  • +
  • Intercept is now considered defensive by bots
  • +
  • Password restrictions relaxed
  • +
+

+[1.6.4] - 2019-10-24

+

+Changed

+
    +
  • Animations processing on client side reduced.
  • +
+

+[1.6.3] - 2019-10-23

+

+Added

+
    +
  • MNNI: the MNML guide +
      +
    • Delivers the message of the day
    • +
    +
  • +
+

+Fixed

+
    +
  • Fixed issue where dots / hots would not trigger when reapplied at a higher speed
  • +
  • Changed layout of home page. UI elements for rerolling construct avatars moved to a separate tab.
  • +
  • Added highlighting to first round of a game against the bots to guide new users
  • +
  • Fixed UI issues related to scrolling
  • +
  • Improved the invite link
  • +
+

+[1.6.2] - 2019-10-20

+

+Fixed

+
    +
  • Combiner bug where it would preview items for different combinations
  • +
  • Skill descriptions are cleared when animations start
  • +
+

+[1.6.1] - Skipped

+

+[1.6.0] - 2019-10-18

+

+Added

+
    +
  • Subscriber chat!
  • +
+

+Changed

+
    +
  • +

    Made available skill / effect information during the combat phase.

    +
      +
    • Highlighting a skill replace the effect area with the skill description including speed multiplier.
    • +
    • Highlighting an effect will replace the targetting arrow / anim skill text with effect info.
    • +
    +
  • +
  • +

    You can now preview combinations before you create them

    +
      +
    • After selecting the three items for a combo hover over the combine button for info
    • +
    +
  • +
  • +

    Damage formula for Slay and Siphon reworked

    +
      +
    • Slay now deals red damage based RedPower and GreenPower. Previously only based on RedPower.
    • +
    • Siphon now deals blue damage based BluePower and GreenPower. Previously only based on BluePower.
    • +
    +
  • +
+

+Fixed

+
    +
  • Matchmaking bug where server matches you with yourself
  • +
+

+[1.5.6] - 2019-10-17

+

We've updated the UI during the vbox / buy phase to give a better indication of valid actions.

+

+Changed

+
    +
  • +

    Borders for skill combo's represent the base colours.

    +
      +
    • Heal (GG) has a green border, Siphon (BG) has an alternating blue / green border etc.
    • +
    • Borders are shown for items in inventory and as equipped skills during both phases.
    • +
    +
  • +
  • +

    Improvements to making item combo's

    +
      +
    • If you select an item in your inventory it will now highlight other items that are valid for combining.
    • +
    • This includes items that can be bought and in your inventory.
    • +
    +
  • +
  • +

    Improved the indicator for where to click for equipping and buying items where its valid.

    +
      +
    • Now slowly flashes between black and grey, previously changed the border once.
    • +
    +
  • +
+

+[1.5.5] - 2019-10-15

+

+Changed

+
    +
  • +

    Purge

    +
      +
    • Fixed bug where client animations would freeze when clearing a buff
    • +
    • Cooldown increased to 1T
    • +
    +
  • +
  • +

    VBOX

    +
      +
    • You can no longer select invalid combinations.
    • +
    +
  • +
  • +

    Controls

    +
      +
    • Abandon button now asks for confirmation.
    • +
    +
  • +
+
\ No newline at end of file From 6f453c45fc2de6bd8b24e9d6c3515b06757a61ae Mon Sep 17 00:00:00 2001 From: Mashy Date: Sun, 10 Nov 2019 21:50:25 +1000 Subject: [PATCH 05/53] fix demo animation issue --- client/assets/styles/game.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index ad9c7f47..4ddacc63 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -94,7 +94,7 @@ justify-items: center; grid-template-columns: 1fr; - grid-template-rows: minmax(min-content, 1fr) min-content; + grid-template-rows: min-content 1fr; grid-template-areas: "left" "right"; From ab7625def002dbde62c4e9155b96975f67401e1d Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 11 Nov 2019 11:58:29 +1000 Subject: [PATCH 06/53] purge / purify removes all effects --- client/src/animations.utils.jsx | 3 ++ server/src/skill.rs | 61 +++++++++------------------------ 2 files changed, 20 insertions(+), 44 deletions(-) diff --git a/client/src/animations.utils.jsx b/client/src/animations.utils.jsx index ad926a8f..21b38925 100644 --- a/client/src/animations.utils.jsx +++ b/client/src/animations.utils.jsx @@ -168,6 +168,9 @@ function getText(resolution) { if (type === 'Removal') { const { effect, construct_effects: effects } = event; + if (!effect) { + return { text: 'Effect Removal', css: '', effects }; + } return { text: `-${effect}`, css: '', effects }; } return false; diff --git a/server/src/skill.rs b/server/src/skill.rs index 33f7ea3c..6b621d5c 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -505,7 +505,7 @@ pub enum Event { AoeSkill { skill: Skill }, Skill { skill: Skill }, Effect { skill: Skill, effect: Effect, duration: u8, construct_effects: Vec }, - Removal { effect: Effect, construct_effects: Vec }, + Removal { effect: Option, construct_effects: Vec }, TargetKo { skill: Skill }, // skill not necessary but makes it neater as all events are arrays in js Ko (), @@ -1630,7 +1630,7 @@ fn electrocute(source: &mut Construct, target: &mut Construct, mut results: Reso Some(eff) => { let ce = source.effects.remove(eff); results.push(Resolution::new(source, source) - .event(Event::Removal { effect: ce.effect, construct_effects: source.effects.clone() }) + .event(Event::Removal { effect: Some(ce.effect), construct_effects: source.effects.clone() }) .stages(EventStages::PostOnly)); } None => () @@ -1701,7 +1701,7 @@ fn absorption(source: &mut Construct, target: &mut Construct, mut results: Resol let ce = target.effects.remove(absorb_index); results.push(Resolution::new(source, target) - .event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() }) + .event(Event::Removal { effect: Some(ce.effect), construct_effects: target.effects.clone() }) .stages(EventStages::PostOnly)); return results;; } @@ -1816,58 +1816,31 @@ fn silence(source: &mut Construct, target: &mut Construct, mut results: Resoluti fn purge(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { results.push(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); - while let Some(i) = target.effects - .iter() - .position(|ce| { - if let Some(c) = ce.effect.colour() { - c == Colour::Green - } else { - false - } - }) { - let ce = target.effects.remove(i); - results.push(Resolution::new(source, target) - .event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() }) - .stages(EventStages::PostOnly)); - } + if target.effects.len() > 0 { + target.effects.clear(); + results.push(Resolution::new(source, target) + .event(Event::Removal { effect: None, construct_effects: target.effects.clone() }) + .stages(EventStages::PostOnly)); + } let effect = skill.effect()[0]; results.push(Resolution::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); - /*let mut turns = 1; - for cs in target.skills.iter_mut() { - if Effect::Purge.disables_skill(cs.skill) { - turns += 1; - } - } - - if turns > 1 { - effect.duration = effect.duration * turns; - }*/ - return results; } fn purify(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { results.push(Resolution::new(source, target).event(Event::Skill { skill }).stages(EventStages::StartEnd)); - let amount = source.green_power().pct(skill.multiplier()); - while let Some(i) = target.effects - .iter() - .position(|ce| { - if let Some(c) = ce.effect.colour() { - [Colour::Red, Colour::Blue].contains(&c) - } else { - false - } - }) { - let ce = target.effects.remove(i); - results.push(Resolution::new(source, target) - .event(Event::Removal { effect: ce.effect, construct_effects: target.effects.clone() }) - .stages(EventStages::PostOnly)); - target.deal_green_damage(skill, amount) + if target.effects.len() > 0 { + let amount = source.green_power().pct(skill.multiplier().saturating_mul(target.effects.len() as u64)); + target.effects.clear(); + results.push(Resolution::new(source, target) + .event(Event::Removal { effect: None, construct_effects: target.effects.clone() }) + .stages(EventStages::PostOnly)); + target.deal_green_damage(skill, amount) .into_iter() .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); - } + } return results; } From d77dd00e011d68be39ab81ee30037bed4f657f01 Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 11 Nov 2019 12:07:15 +1000 Subject: [PATCH 07/53] add skill to removal event --- server/src/skill.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/src/skill.rs b/server/src/skill.rs index 6b621d5c..01de62c7 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -505,7 +505,7 @@ pub enum Event { AoeSkill { skill: Skill }, Skill { skill: Skill }, Effect { skill: Skill, effect: Effect, duration: u8, construct_effects: Vec }, - Removal { effect: Option, construct_effects: Vec }, + Removal { skill: Skill, effect: Option, construct_effects: Vec }, TargetKo { skill: Skill }, // skill not necessary but makes it neater as all events are arrays in js Ko (), @@ -1630,7 +1630,7 @@ fn electrocute(source: &mut Construct, target: &mut Construct, mut results: Reso Some(eff) => { let ce = source.effects.remove(eff); results.push(Resolution::new(source, source) - .event(Event::Removal { effect: Some(ce.effect), construct_effects: source.effects.clone() }) + .event(Event::Removal { skill, effect: Some(ce.effect), construct_effects: source.effects.clone() }) .stages(EventStages::PostOnly)); } None => () @@ -1701,7 +1701,7 @@ fn absorption(source: &mut Construct, target: &mut Construct, mut results: Resol let ce = target.effects.remove(absorb_index); results.push(Resolution::new(source, target) - .event(Event::Removal { effect: Some(ce.effect), construct_effects: target.effects.clone() }) + .event(Event::Removal { skill, effect: Some(ce.effect), construct_effects: target.effects.clone() }) .stages(EventStages::PostOnly)); return results;; } @@ -1819,7 +1819,7 @@ fn purge(source: &mut Construct, target: &mut Construct, mut results: Resolution if target.effects.len() > 0 { target.effects.clear(); results.push(Resolution::new(source, target) - .event(Event::Removal { effect: None, construct_effects: target.effects.clone() }) + .event(Event::Removal { skill, effect: None, construct_effects: target.effects.clone() }) .stages(EventStages::PostOnly)); } @@ -1835,7 +1835,7 @@ fn purify(source: &mut Construct, target: &mut Construct, mut results: Resolutio let amount = source.green_power().pct(skill.multiplier().saturating_mul(target.effects.len() as u64)); target.effects.clear(); results.push(Resolution::new(source, target) - .event(Event::Removal { effect: None, construct_effects: target.effects.clone() }) + .event(Event::Removal { skill, effect: None, construct_effects: target.effects.clone() }) .stages(EventStages::PostOnly)); target.deal_green_damage(skill, amount) .into_iter() From 8eaa3dc1c0c5222679e82a27fe2abc7cbc59a815 Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 11 Nov 2019 12:09:33 +1000 Subject: [PATCH 08/53] amplify no longer increases green power --- client/src/utils.jsx | 2 +- server/src/effect.rs | 2 +- server/src/item.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/utils.jsx b/client/src/utils.jsx index 05513adb..e792b780 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -266,7 +266,7 @@ function effectInfo(i) { } switch (i.effect) { - case 'Amplify': return `Increases construct RedPower BluePower GreenPower by ${i.meta[1] - 100}%`; + case 'Amplify': return `Increases construct RedPower BluePower by ${i.meta[1] - 100}%`; case 'Banish': return 'Banished construct cannot cast or take damage'; case 'Block': return `Reduces construct red damage and blue damage taken by ${100 - i.meta[1]}%`; case 'Buff': return `Increases construct RedPower BluePower SpeedStat by ${i.meta[1] - 100}%`; diff --git a/server/src/effect.rs b/server/src/effect.rs index 9e3076bc..c2c77392 100644 --- a/server/src/effect.rs +++ b/server/src/effect.rs @@ -105,7 +105,7 @@ impl Effect { Effect::Absorption => vec![Stat::RedPower, Stat::BluePower], - Effect::Amplify => vec![Stat::GreenPower, Stat::RedPower, Stat::BluePower], + Effect::Amplify => vec![Stat::RedPower, Stat::BluePower], Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken], Effect::Hybrid => vec![Stat::GreenPower], diff --git a/server/src/item.rs b/server/src/item.rs index 3a547063..abb9578b 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -712,7 +712,7 @@ impl Item { // Skills <- need to move effect mulltipliers into skills Item::Amplify| Item::AmplifyPlus | - Item::AmplifyPlusPlus => format!("Increase RedPower BluePower GreenPower by {:?}%. Lasts {:?}T.", + Item::AmplifyPlusPlus => format!("Increase RedPower BluePower by {:?}%. Lasts {:?}T.", self.into_skill().unwrap().effect()[0].get_multiplier() - 100, self.into_skill().unwrap().effect()[0].get_duration()), From 1a2d2995cc27d7df92d63f07597bc4d278d09d1b Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 11 Nov 2019 12:34:14 +1000 Subject: [PATCH 09/53] add "Purified" effect to Purify --- client/src/utils.jsx | 1 + server/src/effect.rs | 46 +++++++++++++++++++++++++++----------------- server/src/item.rs | 8 +++++--- server/src/skill.rs | 10 ++++++++++ 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/client/src/utils.jsx b/client/src/utils.jsx index e792b780..c23e9012 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -282,6 +282,7 @@ function effectInfo(i) { case 'Restrict': return 'Disable construct from casting any red skills'; case 'Stun': return 'Stunned construct cannot use skills'; case 'Intercept': return 'Redirect any skills on team to this target construct'; + case 'Purified': return `Construct will take ${i.meta[1] - 100}% increased healing`; case 'Vulnerable': return `Construct will take ${i.meta[1] - 100}% increased red damage`; case 'Silence': return 'Disable construct from casting any blue skills'; case 'Wither': return `Construct will take ${100 - i.meta[1]}% reduced healing`; // diff --git a/server/src/effect.rs b/server/src/effect.rs index c2c77392..77d110f9 100644 --- a/server/src/effect.rs +++ b/server/src/effect.rs @@ -10,20 +10,21 @@ pub enum Effect { Banish, Block, Buff, - Sustain, + Counter, Curse, Haste, Hybrid, + Intercept, Invert, - Counter, + Purified, Purge, Reflect, - Slow, Restrict, - Stun, - Intercept, - Vulnerable, Silence, + Slow, + Stun, + Sustain, + Vulnerable, Wither, // Reduce green dmg (healing) taken // electric is the buff that applies @@ -99,20 +100,24 @@ impl Effect { pub fn modifications(&self) -> Vec { match self { - Effect::Vulnerable => vec![Stat::RedDamageTaken], + // Bases Effect::Block => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken], Effect::Buff => vec![Stat::BluePower, Stat::RedPower, Stat::Speed], - - Effect::Absorption => vec![Stat::RedPower, Stat::BluePower], - - Effect::Amplify => vec![Stat::RedPower, Stat::BluePower], - Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken], - - Effect::Hybrid => vec![Stat::GreenPower], - Effect::Wither => vec![Stat::GreenDamageTaken], - - Effect::Haste => vec![Stat::Speed], Effect::Slow => vec![Stat::Speed], + + // Power changes + Effect::Absorption => vec![Stat::RedPower, Stat::BluePower], + Effect::Amplify => vec![Stat::RedPower, Stat::BluePower], + Effect::Hybrid => vec![Stat::GreenPower], + + // Damage taken changes + Effect::Curse => vec![Stat::RedDamageTaken, Stat::BlueDamageTaken], + Effect::Purified => vec![Stat::GreenDamageTaken], // increased green taken + Effect::Vulnerable => vec![Stat::RedDamageTaken], + Effect::Wither => vec![Stat::GreenDamageTaken], // reduced green taken + + // Speed + Effect::Haste => vec![Stat::Speed], _ => vec![], } @@ -128,6 +133,7 @@ impl Effect { Effect::Haste | Effect::Slow | Effect::Hybrid | + Effect::Purified | Effect::Wither => value.pct(match meta { Some(EffectMeta::Multiplier(d)) => d, _ => 100, @@ -135,7 +141,10 @@ impl Effect { Effect::Absorption => value + match meta { Some(EffectMeta::AddedDamage(d)) => d, - _ => panic!("absorb meta not damage"), + _ => { + warn!("absorb meta not damage"); + return 0; + } }, _ => { @@ -185,6 +194,7 @@ impl Effect { Effect::Decay => Some(Colour::Blue), Effect::Regen => Some(Colour::Green), Effect::Siphon => Some(Colour::Blue), + Effect::Purified => Some(Colour::Green), Effect::Ko => None, } diff --git a/server/src/item.rs b/server/src/item.rs index abb9578b..92848763 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -824,15 +824,17 @@ impl Item { Item::Purge| Item::PurgePlus | Item::PurgePlusPlus => format!( - "Remove buffs from target construct. + "Remove all effects from target construct. Applies purge disabling target green skills for {:?}T.", self.into_skill().unwrap().effect()[0].get_duration()), Item::Purify| Item::PurifyPlus | Item::PurifyPlusPlus => format!( - "Remove debuffs and heals for {:?}% GreenPower per debuff removed.", - self.into_skill().unwrap().multiplier()), + "Remove all effects and heals for {:?}% GreenPower per effect removed. + Applies Purified increasing healing taken by {:?}%.", + self.into_skill().unwrap().multiplier(), + self.into_skill().unwrap().effect()[0].get_multiplier() - 100), Item::Reflect| Item::ReflectPlus | diff --git a/server/src/skill.rs b/server/src/skill.rs index 01de62c7..3d3fb3ce 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -1022,6 +1022,14 @@ impl Skill { meta: Some(EffectMeta::Skill(Skill::TriageTickPlus)), tick: None}], Skill::TriagePlusPlus => vec![ConstructEffect {effect: Effect::Triage, duration: 4, meta: Some(EffectMeta::Skill(Skill::TriageTickPlusPlus)), tick: None}], + + Skill::Purify => vec![ConstructEffect { effect: Effect::Purified, duration: 2, + meta: Some(EffectMeta::Multiplier(150)), tick: None}], + Skill::PurifyPlus => vec![ConstructEffect { effect: Effect::Purified, duration: 2, + meta: Some(EffectMeta::Multiplier(175)), tick: None}], + Skill::PurifyPlusPlus => vec![ConstructEffect { effect: Effect::Purified, duration: 2, + meta: Some(EffectMeta::Multiplier(200)), tick: None}], + _ => { panic!("{:?} no skill effect", self); }, @@ -1841,6 +1849,8 @@ fn purify(source: &mut Construct, target: &mut Construct, mut results: Resolutio .into_iter() .for_each(|e| results.push(Resolution::new(source, target).event(e).stages(EventStages::PostOnly))); } + let effect = skill.effect()[0]; + results.push(Resolution::new(source, target).event(target.add_effect(skill, effect)).stages(EventStages::PostOnly)); return results; } From eb51cad03619d6b01807c3309ca4cf8df592463d Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 11 Nov 2019 12:37:14 +1000 Subject: [PATCH 10/53] break line for speed description in game phase --- client/src/components/game.construct.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 68df7d47..4ffede73 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -148,7 +148,7 @@ class GameConstruct extends Component { return (

{gameSkillInfo.skill}

- {infoDescription} + {infoDescription}
{speed}
); } From d43d89adb221392b108147eda303a3c4162c41db Mon Sep 17 00:00:00 2001 From: Mashy Date: Mon, 11 Nov 2019 12:40:47 +1000 Subject: [PATCH 11/53] changelog --- CHANGELOG.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d54d2180..4c6d3469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ +## [1.8.3] - 2019-11-10 +### Fixed +- Construct display on info / demo page + +### Changed +- Amplify no longer increase GreenPower + +- Purify + - Now removes all effects on target + - Applies "Purified" increasing healing taken + +- Purge + - Now removes all effects on target + ## [1.8.2] - 2019-11-10 -- Fixed a duplicate button issue in reshape tab +### Fixed +- Duplicate button issue in reshape tab ## [1.8.1] - 2019-11-09 From 61a8db708bb602d49c9d78c98d437861df418bbf Mon Sep 17 00:00:00 2001 From: ntr Date: Mon, 11 Nov 2019 14:00:23 +1100 Subject: [PATCH 12/53] slamma jamma into instance when you first register --- client/src/socket.jsx | 14 +------------- server/src/account.rs | 23 +++++++++++++++++++++++ server/src/rpc.rs | 4 ++++ 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/client/src/socket.jsx b/client/src/socket.jsx index fbc6b296..9ab92870 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -318,11 +318,8 @@ function createSocket(events) { return handlers[msgType](params); } - let attempts = 1; - // Connection opened function onOpen() { - attempts = 0; toast.info({ message: 'connected', position: 'topRight', @@ -341,21 +338,12 @@ function createSocket(events) { } function onClose(event) { - attempts *= 2; - if (attempts > 10) { - toast.warning({ - message: 'unable to connect, refreshing...', - position: 'topRight', - }); - setTimeout(() => window.location.reload(true), 2000); - } - console.error('WebSocket closed', event); toast.warning({ message: 'disconnected', position: 'topRight', }); - return setTimeout(connect, attempts * 1000); + return setTimeout(connect, 2000); } function connect() { diff --git a/server/src/account.rs b/server/src/account.rs index 8e8a1b6f..90d3f431 100644 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -12,6 +12,7 @@ use http::MnmlHttpError; use names::{name as generate_name}; use construct::{Construct, ConstructSkeleton, construct_spawn}; use instance::{Instance, instance_delete}; +use instance; use mtx::{Mtx, FREE_MTX}; use pg::Db; use img; @@ -502,3 +503,25 @@ pub fn img_check(account: &Account) -> Result { false => Ok(account.img), } } + +pub fn tutorial(tx: &mut Transaction, account: &Account) -> Result, Error> { + let query = " + SELECT count(id) + FROM players + WHERE account = $1; + "; + + let result = tx + .query(query, &[&account.id])?; + + let row = result.iter().next() + .ok_or(format_err!("unable to fetch joined games account={:?}", account))?; + + let count: i64 = row.get(0); + + if count == 0 { + return Ok(Some(instance::instance_practice(tx, account)?)); + } + + return Ok(None); +} \ No newline at end of file diff --git a/server/src/rpc.rs b/server/src/rpc.rs index e0db439a..fbd8a2f8 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -353,6 +353,10 @@ impl Handler for Connection { let wheel = account::chat_wheel(&db, a.id).unwrap(); self.send(RpcMessage::ChatWheel(wheel)).unwrap(); + if let Some(instance) = account::tutorial(&mut tx, &a).unwrap() { + self.send(RpcMessage::InstanceState(instance)).unwrap(); + } + // tx should do nothing tx.commit().unwrap(); } else { From 27c562d41b0a85f6608c686620931289a90f9695 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 12 Nov 2019 11:39:34 +1000 Subject: [PATCH 13/53] preview item combos in table --- WORKLOG.md | 6 +++ client/assets/styles/colours.less | 9 +++++ client/assets/styles/instance.less | 40 +++++++++++++++----- client/src/components/info.component.jsx | 48 +++++++++++++++--------- client/src/tutorial.utils.jsx | 18 ++++----- server/src/item.rs | 9 ++--- 6 files changed, 90 insertions(+), 40 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 57b663fc..27d5432e 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -8,8 +8,14 @@ * mobile info page +* Don't drop out of game if you don't ready (esp. tutorial) +* Preview combo if you select 3 items + ## SOON +* Graphical status effects instead of text +* Improve colour contrast / buttons + * supporter gold name in instance (anyone whos put any money into game) * change cooldowns to delay & recharge diff --git a/client/assets/styles/colours.less b/client/assets/styles/colours.less index d8ca2a5d..a1ae5dcb 100644 --- a/client/assets/styles/colours.less +++ b/client/assets/styles/colours.less @@ -122,6 +122,15 @@ svg { } } +@keyframes border-co { + 0% { + border-color: @gray-box; + } + 100% { + border-color: @gray-hint; + } +} + @keyframes co { from { background: @black; diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 65032870..97faca8f 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -2,7 +2,7 @@ overflow: hidden; display: grid; grid-template-columns: 1fr minmax(min-content, 1fr); - grid-template-rows: min-content 1fr; + grid-template-rows: minmax(min-content, 0.75fr) 1fr; grid-template-areas: "vbox info" @@ -33,16 +33,15 @@ } .instance .info { - /*font-size: 75%;*/ - margin: 0 0 0 1em; grid-area: info; - display: flex; - flex-flow: column; + display: grid; + font-size: 85%; + grid-template-rows: 0.8fr 1fr; + grid-template-areas: + "item" + "combos"; + // flex-flow: column; // white-space: pre-wrap; - - > *:first-child { - margin-bottom: 1em; - } } .instance .info h2 { @@ -63,6 +62,29 @@ } } +.instance .info-item { + grid-area: item; + margin: 0 0 0 1em; +} + +.instance .combos { + grid-area: combos; + margin: 0 0 0 1em; + + td.table-button { + padding:5px; + cursor: pointer; + animation: border-co 0.75s ease-in-out 0s infinite alternate; + &:hover { + color: whitesmoke; + background-color: @gray-hover; + } + svg { + height: 1em; + } + } +} + .instance .info figcaption { font-size: 1em; display: inline-block; diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 0666010a..26c790a1 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -9,12 +9,14 @@ const shapes = require('./shapes'); class InfoComponent extends preact.Component { - shouldComponentUpdate(newProps) { + shouldComponentUpdate(newProps, newState) { if (newProps.tutorial !== this.props.tutorial) return true; // We don't care about info during tutorial if (newProps.tutorial && this.props.instance.time_control === 'Practice' && this.props.instance.rounds.length === 1) return false; if (newProps.info !== this.props.info) return true; + if (newState.comboItem !== this.state.comboItem) return true; + return false; } @@ -33,7 +35,8 @@ class InfoComponent extends preact.Component { setInfo, setTutorialNull, } = args; - + const { comboItem } = this.state; + console.log(comboItem); function Info() { if (tutorial) { const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); @@ -42,7 +45,7 @@ class InfoComponent extends preact.Component { if (!info) return false; if (info.includes('constructName')) { return ( -
+

{info.replace('constructName ', '')}

This is the name of your construct.
Names are randomly generated and are purely cosmetic.
@@ -54,7 +57,7 @@ class InfoComponent extends preact.Component { if (info.includes('constructAvatar')) { return ( -

+

{info.replace('constructAvatar ', '')}

This is your construct avatar.
Avatars are randomly generated and are purely cosmetic.
@@ -63,7 +66,9 @@ class InfoComponent extends preact.Component {

); } - const fullInfo = itemInfo.items.find(i => i.item === info) || INFO[info]; + const fullInfo = comboItem + ? itemInfo.items.find(i => i.item === comboItem) || INFO[comboItem] + : itemInfo.items.find(i => i.item === info) || INFO[info]; if (!fullInfo) return false; const isSkill = fullInfo.skill; const isSpec = fullInfo.spec; @@ -75,16 +80,18 @@ class InfoComponent extends preact.Component { }; if (isSkill || isSpec) { - let infoName = info; + let infoName = fullInfo.item; while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); + console.log(fullInfo); - const header = isSkill ?

SKILL

:

SPEC

; - - const itemSource = itemInfo.combos.filter(c => c.item === removeTier(info)); - let itemSourceInfo = itemSource.length + const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); + + let itemSourceInfo = itemSource.length && !isSpec ? `${itemSource[0].components[0]} ${itemSource[0].components[1]} ${itemSource[0].components[2]}` : false; + let header = null; + if (!itemSource.length) header = isSkill ?

SKILL

:

SPEC

; if (itemSourceInfo) { while (itemSourceInfo.includes('Plus')) itemSourceInfo = itemSourceInfo.replace('Plus', '+'); const itemRegEx = /(Red|Blue|Green)/; @@ -100,7 +107,7 @@ class InfoComponent extends preact.Component { const thresholds = isSpec ? specThresholds(player, fullInfo, info) : null; return ( -
+

{infoName} {fullInfo.cost}b

{header} {itemSourceInfo} @@ -120,10 +127,10 @@ class InfoComponent extends preact.Component { ); } - function Combos() { + const Combos = () => { if (tutorial && instance.time_control === 'Practice' && instance.rounds.length === 1) return false; const generalNotes = ( -
+

General

You can preview combos by clicking the combined item when it appears in this section.
@@ -141,18 +148,25 @@ class InfoComponent extends preact.Component { {vboxCombos.map((c, i) => - - + + + {c.components.map((u, j) => )} )}
setInfo(c.item)} >{convertItem(c.item)}
{ + e.stopPropagation(); + this.setState({ comboItem: c.item }); + }} + onClick={() => setInfo(c.item)} + > {convertItem(c.item)} {convertItem(u)}
); - } + }; return ( -

+
this.setState({ comboItem: null })}>
diff --git a/client/src/tutorial.utils.jsx b/client/src/tutorial.utils.jsx index 53268161..2c6e5d5f 100644 --- a/client/src/tutorial.utils.jsx +++ b/client/src/tutorial.utils.jsx @@ -109,7 +109,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { const tutorialText = () => { if (tutorial === 1) { return ( -
+

Tutorial

Welcome to the vbox phase tutorial.

Colours are used to create powerful combinations.

@@ -121,7 +121,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { if (tutorial === 2) { return ( -
+

Tutorial

In a normal game you start with three base Attack skill items.

The Attack item can be combined with colours to create a new skill.

@@ -135,7 +135,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { if (tutorial === 3) { const constructOne = instance.players[0].constructs[0].name; return ( -
+

Tutorial

The first construct on your team is {constructOne}.

Skill items can be equipped to your constructs to be used in the combat phase.

@@ -147,7 +147,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { if (tutorial === 4) { return ( -
+

Tutorial

You can also buy specialisation items for your constructs.
Specialisation items increase stats including power, speed and life.

@@ -159,7 +159,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { if (tutorial === 5) { return ( -
+

Tutorial

Equipping specialisation items will increase the stats of your constructs.

These can also be combined with colours for further specialisation.

@@ -173,7 +173,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { const constructTwo = instance.players[0].constructs[1].name; const constructThree = instance.players[0].constructs[2].name; return ( -
+

Tutorial

You have now created a construct with an upgraded skill and base spec.

The goal is to create three powerful constructs for combat.

@@ -185,7 +185,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { if (tutorial === 7) { return ( -
+

Tutorial

Each round you start with a vbox full of different skills, specs and colours.

Bits are your currency for buying skills, specs and colours from the vbox.
@@ -204,7 +204,7 @@ function tutorialStage(tutorial, ws, clearTutorial, instance) { } return ( -

+

Tutorial

You've completed the tutorial! Try to create more skill and spec combinations.

You can unequip skills and specs back into the inventory by double clicking.
@@ -235,5 +235,5 @@ module.exports = { tutorialConstructDisplay, tutorialVbox, tutorialStage, - tutorialShouldDisableEquip + tutorialShouldDisableEquip, }; diff --git a/server/src/item.rs b/server/src/item.rs index 92848763..a754ecbc 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -900,11 +900,10 @@ impl Item { Item::Bash| Item::BashPlus | Item::BashPlusPlus => format!( - "Bash the target increasing the cooldowns of target skills by 1T. - Deals {:?}% RedPower as red damage and 45% more damage per cooldown increased. - Stuns for {:?}T.", - self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), - self.into_skill().unwrap().effect()[0].get_duration()), + "Bash the target increasing the cooldowns of target skills by 1T. Stuns target for {:?}T. + Deals {:?}% RedPower as red damage and 45% more damage per cooldown increased.", + self.into_skill().unwrap().effect()[0].get_duration(), + self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier()), Item::Strike| Item::StrikePlus | From c1d4dd3620bceed2a0bdf7c1e2be04b42401cb5f Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 12 Nov 2019 12:03:17 +1000 Subject: [PATCH 14/53] clear comboItem error handling --- client/src/components/info.component.jsx | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 26c790a1..3b8d6333 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -20,6 +20,11 @@ class InfoComponent extends preact.Component { return false; } + componentDidUpdate(prevProps) { + // Catch case where mouse events don't properly clear state and info changed + if (prevProps.info !== this.props.info) this.setState({ comboItem: null }); + } + render(args) { const { // Variables that will change @@ -36,7 +41,6 @@ class InfoComponent extends preact.Component { setTutorialNull, } = args; const { comboItem } = this.state; - console.log(comboItem); function Info() { if (tutorial) { const tutorialStageInfo = tutorialStage(tutorial, ws, setTutorialNull, instance); @@ -51,7 +55,7 @@ class InfoComponent extends preact.Component { Names are randomly generated and are purely cosmetic.
You can change change your construct name in the RESHAPE tab outside of games.

-
+
); } @@ -82,7 +86,6 @@ class InfoComponent extends preact.Component { if (isSkill || isSpec) { let infoName = fullInfo.item; while (infoName.includes('Plus')) infoName = infoName.replace('Plus', '+'); - console.log(fullInfo); const itemSource = itemInfo.combos.filter(c => c.item === removeTier(fullInfo.item)); From 4e627fa34b17228e9d86c2b6ee9cdce3dddf1fa2 Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 12 Nov 2019 12:32:06 +1000 Subject: [PATCH 15/53] client side disable shop purchase --- client/src/components/vbox.component.jsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index 1f70236c..a3e01b54 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -213,6 +213,7 @@ class Vbox extends preact.Component { const classes = `${v.toLowerCase()} ${selected ? 'highlight' : ''} ${comboHighlight}`; const vboxObject = shapes[v] ? shapes[v]() : v; + const disabled = vbox.bits <= group; return (
{range(0, 6).map(i => availableBtn(vbox.free[0][i], 0, i))} From 6c0457f8fdfd4a8eca4987d3ab489ef13c002c1c Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 12 Nov 2019 13:58:48 +1000 Subject: [PATCH 16/53] preview combo when you've selected 3 items --- client/src/components/info.component.jsx | 2 +- client/src/components/vbox.component.jsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index 3b8d6333..4529f513 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -22,7 +22,7 @@ class InfoComponent extends preact.Component { componentDidUpdate(prevProps) { // Catch case where mouse events don't properly clear state and info changed - if (prevProps.info !== this.props.info) this.setState({ comboItem: null }); + if (prevProps.info !== this.props.info && this.state.comboItem) this.setState({ comboItem: null }); } render(args) { diff --git a/client/src/components/vbox.component.jsx b/client/src/components/vbox.component.jsx index a3e01b54..d9589c2c 100644 --- a/client/src/components/vbox.component.jsx +++ b/client/src/components/vbox.component.jsx @@ -287,7 +287,7 @@ class Vbox extends preact.Component { const combinerItems = combiner.map(j => vbox.bound[j]); const combinerCount = countBy(combinerItems, co => co); - const comboHighlight = combinerItems.length > 0 && itemInfo.combos.some(combo => { + const comboItem = itemInfo.combos.find(combo => { if (combo.components.includes(v)) { return combinerItems.every(c => { if (!combo.components.includes(c)) return false; @@ -297,7 +297,8 @@ class Vbox extends preact.Component { return true; }); } return false; - }) ? 'combo-border' : ''; + }); + const comboHighlight = combinerItems.length > 0 && comboItem ? 'combo-border' : ''; function onClick(type) { if (vboxSelecting) clearVboxSelected(); @@ -323,6 +324,7 @@ class Vbox extends preact.Component { } combiner.push(i); + if (combiner.length === 3) setInfo(comboItem.item); return combinerChange(combiner); } From 87bc63e64842a2ac2dcf068421e4c8620430a3f1 Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 15:20:02 +1100 Subject: [PATCH 17/53] password changes, account name restrictions --- WORKLOG.md | 9 ++- client/assets/rotate.svg | 96 ++++++++++++++++-------- client/assets/styles/menu.less | 4 + client/src/components/stripe.buttons.jsx | 29 ++++--- server/src/account.rs | 17 +++-- server/src/http.rs | 5 +- 6 files changed, 106 insertions(+), 54 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 57b663fc..c6a5bf4f 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -6,10 +6,13 @@ * can't reset password without knowing password =\ * ws gzip encoding -* mobile info page +* Graphics + * Img + * Skill Icons + * Buttons / General UI Theming + * Front Page ## SOON - * supporter gold name in instance (anyone whos put any money into game) * change cooldowns to delay & recharge @@ -59,7 +62,7 @@ * Items * instead of red noise, red and black bar gradient * eth adapter - *sets* + *sets* * illusions * vaporwave * crop circles diff --git a/client/assets/rotate.svg b/client/assets/rotate.svg index b48ee399..38c05927 100644 --- a/client/assets/rotate.svg +++ b/client/assets/rotate.svg @@ -2457,9 +2457,9 @@ borderopacity="1.0" inkscape:pageopacity="1" inkscape:pageshadow="2" - inkscape:zoom="0.53357639" - inkscape:cx="411.32817" - inkscape:cy="1018.5983" + inkscape:zoom="0.53546627" + inkscape:cx="561.25984" + inkscape:cy="793.70079" inkscape:document-units="mm" inkscape:current-layer="layer1" showgrid="true" @@ -2538,17 +2538,10 @@ id="layer1" transform="translate(-472.60042,755.1467)" style="display:inline"> - + transform="translate(0,2.7646743)"> + id="g5142" + transform="translate(0,-47.235375)"> + + + + + - - + id="path5003" + d="m 697.60042,-460.14669 -25,25.00001 -25,-25.00001 25,25.00001 v -75.00001 h -25" + style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#f5f5f5;stroke-width:2.9685142;stroke-linecap:butt;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> + + + + + + + + - diff --git a/client/assets/styles/menu.less b/client/assets/styles/menu.less index c6349146..1ce06f73 100644 --- a/client/assets/styles/menu.less +++ b/client/assets/styles/menu.less @@ -122,6 +122,10 @@ section { // height: 3em; } + &.sub { + grid-template-columns: 1fr; + } + &.play { grid-template-columns: repeat(2, 1fr); align-items: flex-start; diff --git a/client/src/components/stripe.buttons.jsx b/client/src/components/stripe.buttons.jsx index 03d3e6b3..c23c2dfc 100644 --- a/client/src/components/stripe.buttons.jsx +++ b/client/src/components/stripe.buttons.jsx @@ -44,21 +44,26 @@ function BitsBtn(args) { } const subscription = account.subscribed - ? - : ; + ?
+
Thank you for your support
+ +
+ :
+
ยค150 / month + Chat Wheel + more
+ +
; return (
-
+
{subscription}
diff --git a/server/src/account.rs b/server/src/account.rs index 90d3f431..66af0821 100644 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -22,6 +22,7 @@ use failure::Error; use failure::{err_msg, format_err}; static PASSWORD_MIN_LEN: usize = 3; +static PASSWORD_ROUNDS: u32 = 10; #[derive(Debug,Clone,Serialize,Deserialize)] pub struct Account { @@ -70,11 +71,11 @@ pub fn chat_wheel(_db: &Db, _id: Uuid) -> Result, Error> { return Ok(vec![ "gg".to_string(), "glhf".to_string(), - "hmm".to_string(), - "ok".to_string(), + "ez".to_string(), "rekt".to_string(), - "thx".to_string(), "nice".to_string(), + "wp".to_string(), + "ok".to_string(), "...".to_string(), ]) } @@ -226,8 +227,7 @@ pub fn set_password(tx: &mut Transaction, id: Uuid, current: &String, password: return Err(MnmlHttpError::BadRequest); } - let rounds = 8; - let password = hash(&password, rounds)?; + let password = hash(&password, PASSWORD_ROUNDS)?; let query = " UPDATE accounts @@ -327,10 +327,13 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result< return Err(MnmlHttpError::AccountNameNotProvided); } + if name.len() > 20 { + return Err(MnmlHttpError::AccountNameUnacceptable); + } + let id = Uuid::new_v4(); let img = Uuid::new_v4(); - let rounds = 12; - let password = hash(&password, rounds)?; + let password = hash(&password, PASSWORD_ROUNDS)?; let mut rng = thread_rng(); let token: String = iter::repeat(()) diff --git a/server/src/http.rs b/server/src/http.rs index 068234f3..2bd7d988 100644 --- a/server/src/http.rs +++ b/server/src/http.rs @@ -44,7 +44,9 @@ pub enum MnmlHttpError { AccountNameNotProvided, #[fail(display="account name unavailable")] AccountNameUnavailable, - #[fail(display="account not found")] + #[fail(display="account name unavailable")] + AccountNameUnacceptable, + #[fail(display="account name is unacceptable. 20 char max")] AccountNotFound, #[fail(display="password does not match")] PasswordNotMatch, @@ -122,6 +124,7 @@ impl From for IronError { MnmlHttpError::AccountNameNotProvided | MnmlHttpError::AccountNameUnavailable | + MnmlHttpError::AccountNameUnacceptable | MnmlHttpError::AccountNotFound | MnmlHttpError::BadRequest | MnmlHttpError::PasswordUnacceptable => (m_err.compat(), status::BadRequest), From de82a21baafef0c7302551e92f6981a6303ec22b Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 15:21:37 +1100 Subject: [PATCH 18/53] fix account err text --- server/src/http.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/src/http.rs b/server/src/http.rs index 2bd7d988..b64568a9 100644 --- a/server/src/http.rs +++ b/server/src/http.rs @@ -44,9 +44,9 @@ pub enum MnmlHttpError { AccountNameNotProvided, #[fail(display="account name unavailable")] AccountNameUnavailable, - #[fail(display="account name unavailable")] - AccountNameUnacceptable, #[fail(display="account name is unacceptable. 20 char max")] + AccountNameUnacceptable, + #[fail(display="account not found")] AccountNotFound, #[fail(display="password does not match")] PasswordNotMatch, From db8e1988172be216ea3b56cccae701a3f20eabcd Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 15:34:44 +1100 Subject: [PATCH 19/53] fix info styles by removing grid --- client/assets/styles/instance.less | 14 +++++--------- client/src/components/anims/siphon.tick.jsx | 1 + 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 97faca8f..716ba6c1 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -34,14 +34,11 @@ .instance .info { grid-area: info; - display: grid; font-size: 85%; - grid-template-rows: 0.8fr 1fr; - grid-template-areas: - "item" - "combos"; - // flex-flow: column; - // white-space: pre-wrap; + + .info-item { + margin: 0 0 1em 1em; + } } .instance .info h2 { @@ -64,7 +61,6 @@ .instance .info-item { grid-area: item; - margin: 0 0 0 1em; } .instance .combos { @@ -72,7 +68,7 @@ margin: 0 0 0 1em; td.table-button { - padding:5px; + padding:5px; cursor: pointer; animation: border-co 0.75s ease-in-out 0s infinite alternate; &:hover { diff --git a/client/src/components/anims/siphon.tick.jsx b/client/src/components/anims/siphon.tick.jsx index 1f7f4d47..207b986f 100644 --- a/client/src/components/anims/siphon.tick.jsx +++ b/client/src/components/anims/siphon.tick.jsx @@ -20,6 +20,7 @@ function projectile(x, y, radius, colour) { cx={x} cy={y} r={radius} + stroke="none" fill={colour} /> ); From 1b5050a7bf746716177675e85f782ee4979c8d44 Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 15:51:33 +1100 Subject: [PATCH 20/53] fix auto ready and remove activeConstruct reducer --- client/src/actions.jsx | 1 - client/src/components/account.status.jsx | 1 - client/src/components/game.jsx | 10 +--------- client/src/components/header.jsx | 1 - client/src/components/instance.constructs.jsx | 15 ++------------- client/src/components/instance.ctrl.btns.jsx | 9 --------- client/src/components/nav.jsx | 1 - client/src/events.jsx | 17 ++++++++++++----- client/src/reducers.jsx | 1 - 9 files changed, 15 insertions(+), 41 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index e42d349c..ef463a40 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -1,5 +1,4 @@ export const setAccount = value => ({ type: 'SET_ACCOUNT', value }); -export const setActiveConstruct = value => ({ type: 'SET_ACTIVE_CONSTRUCT', value }); export const setAnimating = value => ({ type: 'SET_ANIMATING', value }); export const setAnimCb = value => ({ type: 'SET_ANIM_CB', value }); diff --git a/client/src/components/account.status.jsx b/client/src/components/account.status.jsx index 422d2233..c25b0855 100644 --- a/client/src/components/account.status.jsx +++ b/client/src/components/account.status.jsx @@ -36,7 +36,6 @@ const addState = connect( dispatch(actions.setCombiner([])); dispatch(actions.setReclaiming(false)); dispatch(actions.setActiveSkill(null)); - dispatch(actions.setActiveConstruct(null)); dispatch(actions.setInfo(null)); dispatch(actions.setItemEquip(null)); dispatch(actions.setItemUnequip([])); diff --git a/client/src/components/game.jsx b/client/src/components/game.jsx index 88cc3a1d..2767d290 100644 --- a/client/src/components/game.jsx +++ b/client/src/components/game.jsx @@ -14,7 +14,6 @@ const addState = connect( account, animating, activeSkill, - activeConstruct, } = state; function selectSkillTarget(targetConstructId) { @@ -34,7 +33,6 @@ const addState = connect( account, animating, activeSkill, - activeConstruct, selectSkillTarget, }; }, @@ -44,11 +42,7 @@ const addState = connect( dispatch(actions.setActiveSkill(constructId, skill)); } - function setActiveConstruct(construct) { - dispatch(actions.setActiveConstruct(construct)); - } - - return { setActiveSkill, setActiveConstruct }; + return { setActiveSkill }; } ); @@ -59,7 +53,6 @@ function Game(props) { account, animating, setActiveSkill, - setActiveConstruct, } = props; if (!game) return
...
; @@ -91,7 +84,6 @@ function Game(props) { function gameClick(e) { e.stopPropagation(); - setActiveConstruct(null); } return ( diff --git a/client/src/components/header.jsx b/client/src/components/header.jsx index 2ce0368f..76e96fe7 100644 --- a/client/src/components/header.jsx +++ b/client/src/components/header.jsx @@ -35,7 +35,6 @@ const addState = connect( dispatch(actions.setCombiner([])); dispatch(actions.setReclaiming(false)); dispatch(actions.setActiveSkill(null)); - dispatch(actions.setActiveConstruct(null)); dispatch(actions.setInfo(null)); dispatch(actions.setItemEquip(null)); dispatch(actions.setItemUnequip([])); diff --git a/client/src/components/instance.constructs.jsx b/client/src/components/instance.constructs.jsx index da843f8f..312ce513 100644 --- a/client/src/components/instance.constructs.jsx +++ b/client/src/components/instance.constructs.jsx @@ -66,10 +66,6 @@ const addState = connect( dispatch(actions.setInfo(item)); } - function setActiveConstruct(value) { - dispatch(actions.setActiveConstruct(value)); - } - function setItemEquip(v) { return dispatch(actions.setItemEquip(v)); } @@ -78,7 +74,7 @@ const addState = connect( return dispatch(actions.setItemUnequip(v)); } - return { quit, setInfo, setActiveConstruct, setItemUnequip, setItemEquip }; + return { quit, setInfo, setItemUnequip, setItemEquip }; } ); @@ -101,7 +97,6 @@ function Construct(props) { sendVboxAcceptEquip, sendVboxUnequipApply, sendUnequip, - setActiveConstruct, setItemUnequip, setItemEquip, setInfo, @@ -144,7 +139,6 @@ function Construct(props) { function skillClick(e) { if (!skill) return false; setItemUnequip([construct.id, skill.skill]); - setActiveConstruct(construct); e.stopPropagation(); return true; } @@ -152,7 +146,6 @@ function Construct(props) { function skillDblClick(e) { if (!skill) return false; sendUnequip(construct.id, skill.skill); - setActiveConstruct(null); setItemUnequip([]); e.stopPropagation(); e.preventDefault(); @@ -203,12 +196,10 @@ function Construct(props) { function specClick(e) { e.stopPropagation(); setItemUnequip([construct.id, s]); - setActiveConstruct(construct); } function specDblClick(e) { sendUnequip(construct.id, s); - setActiveConstruct(null); setItemUnequip([]); e.stopPropagation(); e.preventDefault(); @@ -291,7 +282,6 @@ class InstanceConstructs extends preact.Component { itemInfo, // Function calls setInfo, - setActiveConstruct, sendVboxApply, sendVboxAcceptEquip, sendVboxUnequipApply, @@ -321,7 +311,6 @@ class InstanceConstructs extends preact.Component { sendVboxAcceptEquip, sendVboxUnequipApply, setInfo, - setActiveConstruct, itemInfo, setVboxHighlight, sendUnequip, @@ -331,7 +320,7 @@ class InstanceConstructs extends preact.Component { }); return ( -
setActiveConstruct(null)}> +
{constructs}
); diff --git a/client/src/components/instance.ctrl.btns.jsx b/client/src/components/instance.ctrl.btns.jsx index ecfded9c..59752c1e 100644 --- a/client/src/components/instance.ctrl.btns.jsx +++ b/client/src/components/instance.ctrl.btns.jsx @@ -55,15 +55,6 @@ 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 (
diff --git a/client/src/components/nav.jsx b/client/src/components/nav.jsx index daf513f1..e254690a 100644 --- a/client/src/components/nav.jsx +++ b/client/src/components/nav.jsx @@ -36,7 +36,6 @@ const addState = connect( dispatch(actions.setCombiner([])); dispatch(actions.setReclaiming(false)); dispatch(actions.setActiveSkill(null)); - dispatch(actions.setActiveConstruct(null)); dispatch(actions.setInfo(null)); dispatch(actions.setItemEquip(null)); dispatch(actions.setItemUnequip([])); diff --git a/client/src/events.jsx b/client/src/events.jsx index 0c745017..29fea424 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -177,7 +177,6 @@ function registerEvents(store) { function clearInfo() { store.dispatch(actions.setInfo(null)); - store.dispatch(actions.setActiveConstruct(null)); console.log('event clear item'); } @@ -185,7 +184,6 @@ function registerEvents(store) { store.dispatch(actions.setCombiner([])); store.dispatch(actions.setReclaiming(false)); store.dispatch(actions.setActiveSkill(null)); - store.dispatch(actions.setActiveConstruct(null)); store.dispatch(actions.setInfo(null)); store.dispatch(actions.setItemEquip(null)); store.dispatch(actions.setItemUnequip([])); @@ -208,6 +206,7 @@ function registerEvents(store) { return store.dispatch(actions.setInvite(code)); } + let autoReady = null; function setInstance(v) { const { account, instance, ws, tutorial } = store.getState(); if (v) { @@ -216,15 +215,23 @@ function registerEvents(store) { store.dispatch(actions.setPlayer(player)); if (!instance || v.id !== instance.id) { - store.dispatch(actions.setNav('vbox')); - const first = player.constructs[0]; - store.dispatch(actions.setActiveConstruct(first)); + clearTimeout(autoReady); } if (v.phase === 'Finished') { ws.sendAccountInstances(); } + if (v.phase_end && v.phase === 'Lobby' && !autoReady) { + const autoReadyDelay = Date.parse(v.phase_end) - Date.now() - 1000; + autoReady = setTimeout(() => { + ws.sendInstanceReady(v.id); + autoReady = null; + }, autoReadyDelay); + } + + if (v.phase !== 'Lobby') clearTimeout(autoReady); + // instance.mobile.less hides info at @media 1000 if (localStorage.getItem('tutorial-complete') || window.innerWidth <= 1100) { store.dispatch(actions.setTutorial(null)); diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 96d8001c..e8bae9ef 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -10,7 +10,6 @@ function createReducer(defaultState, actionType) { /* eslint-disable key-spacing */ module.exports = { account: createReducer(null, 'SET_ACCOUNT'), - activeConstruct: createReducer(null, 'SET_ACTIVE_CONSTRUCT'), activeItem: createReducer(null, 'SET_ACTIVE_VAR'), activeSkill: createReducer(null, 'SET_ACTIVE_SKILL'), From 3a498616fbe75e2071d64ab5284c4823838d627c Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 15:52:45 +1100 Subject: [PATCH 21/53] additional setactive remove --- client/src/keyboard.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/client/src/keyboard.jsx b/client/src/keyboard.jsx index 1646a358..e037be18 100644 --- a/client/src/keyboard.jsx +++ b/client/src/keyboard.jsx @@ -9,7 +9,6 @@ function setupKeys(store) { key('esc', () => store.dispatch(actions.setCombiner([]))); key('esc', () => store.dispatch(actions.setReclaiming(false))); key('esc', () => store.dispatch(actions.setActiveSkill(null))); - key('esc', () => store.dispatch(actions.setActiveConstruct(null))); key('esc', () => store.dispatch(actions.setInfo(null))); key('esc', () => store.dispatch(actions.setItemEquip(null))); key('esc', () => store.dispatch(actions.setItemUnequip([]))); From 9c4215ebba9cf87bd6c669ae41bdaca8393ed148 Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 15:54:08 +1100 Subject: [PATCH 22/53] remove zombie skip code --- client/src/actions.jsx | 1 - client/src/animations.socket.jsx | 1 - client/src/events.jsx | 1 - client/src/reducers.jsx | 1 - 4 files changed, 4 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index ef463a40..59959393 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -39,7 +39,6 @@ export const setPing = value => ({ type: 'SET_PING', value }); export const setPlayer = value => ({ type: 'SET_PLAYER', value }); export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value }); export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value }); -export const setSkip = value => ({ type: 'SET_SKIP', value }); export const setShop = value => ({ type: 'SET_SHOP', value }); export const setSubscription = value => ({ type: 'SET_SUBSCRIPTION', value }); diff --git a/client/src/animations.socket.jsx b/client/src/animations.socket.jsx index ae99e1cc..d42ded1b 100644 --- a/client/src/animations.socket.jsx +++ b/client/src/animations.socket.jsx @@ -78,7 +78,6 @@ function createSocket(store) { store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimating(false)); store.dispatch(actions.setGameEffectInfo(null)); - store.dispatch(actions.setSkip(false)); // set the game state so resolutions don't fire twice store.dispatch(actions.setGame(game)); diff --git a/client/src/events.jsx b/client/src/events.jsx index 29fea424..898f1ef6 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -120,7 +120,6 @@ function registerEvents(store) { store.dispatch(actions.setAnimText(null)); store.dispatch(actions.setAnimating(false)); store.dispatch(actions.setGameEffectInfo(null)); - store.dispatch(actions.setSkip(false)); // set the game state so resolutions don't fire twice store.dispatch(actions.setGame(game)); diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index e8bae9ef..0ddb68b6 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -47,7 +47,6 @@ module.exports = { ping: createReducer(null, 'SET_PING'), player: createReducer(null, 'SET_PLAYER'), reclaiming: createReducer(false, 'SET_RECLAIMING'), - skip: createReducer(false, 'SET_SKIP'), shop: createReducer(false, 'SET_SHOP'), subscription: createReducer(null, 'SET_SUBSCRIPTION'), From af2f145d17f277c637732286b92f0ee5c0d3066d Mon Sep 17 00:00:00 2001 From: Mashy Date: Tue, 12 Nov 2019 15:15:29 +1000 Subject: [PATCH 23/53] ready through tutorial face off faster --- client/src/events.jsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/src/events.jsx b/client/src/events.jsx index 29fea424..a34363a5 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -223,7 +223,8 @@ function registerEvents(store) { } if (v.phase_end && v.phase === 'Lobby' && !autoReady) { - const autoReadyDelay = Date.parse(v.phase_end) - Date.now() - 1000; + const skip = v.time_control === 'Practice' ? 10000 : 2000; + const autoReadyDelay = Date.parse(v.phase_end) - Date.now() - skip; autoReady = setTimeout(() => { ws.sendInstanceReady(v.id); autoReady = null; From 3ee32b3ef211b8a4ef4d5465ffa9608f5a015117 Mon Sep 17 00:00:00 2001 From: ntr Date: Tue, 12 Nov 2019 16:32:19 +1100 Subject: [PATCH 24/53] pvp leave queue implemented --- client/src/actions.jsx | 1 + client/src/components/play.jsx | 43 +++++++++++++++++++++++++++------- client/src/events.jsx | 6 +++++ client/src/reducers.jsx | 1 + client/src/socket.jsx | 19 ++++++++++++--- server/src/events.rs | 14 +++++++++++ server/src/rpc.rs | 7 +++++- 7 files changed, 79 insertions(+), 12 deletions(-) diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 59959393..ebec075d 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -41,6 +41,7 @@ export const setReclaiming = value => ({ type: 'SET_RECLAIMING', value }); export const setShowLog = value => ({ type: 'SET_SHOW_LOG', value }); export const setShop = value => ({ type: 'SET_SHOP', value }); export const setSubscription = value => ({ type: 'SET_SUBSCRIPTION', value }); +export const setPvp = value => ({ type: 'SET_PVP', value }); export const setTeam = value => ({ type: 'SET_TEAM', value: Array.from(value) }); export const setTeamPage = value => ({ type: 'SET_TEAM_PAGE', value }); diff --git a/client/src/components/play.jsx b/client/src/components/play.jsx index 2059f774..2c97b77f 100644 --- a/client/src/components/play.jsx +++ b/client/src/components/play.jsx @@ -14,6 +14,7 @@ const addState = connect( account, instances, invite, + pvp, } = state; function sendInstanceState(id) { @@ -32,15 +33,21 @@ const addState = connect( ws.sendInstanceInvite(); } + function sendInstanceLeave() { + ws.sendInstanceLeave(); + } + return { account, instances, invite, + pvp, sendInstanceState, sendInstanceQueue, sendInstancePractice, sendInstanceInvite, + sendInstanceLeave, }; }, @@ -67,11 +74,13 @@ function Play(args) { account, instances, invite, + pvp, sendInstanceState, sendInstanceQueue, sendInstancePractice, sendInstanceInvite, + sendInstanceLeave, setNav, } = args; @@ -125,6 +134,31 @@ function Play(args) { ); }; + const pvpBtn = () => { + if (pvp) return ( +
+ +
Finding Opponent
+
+ ); + + return ( +
+ +
Matchmaking
+
+ ); + } + const subscription = account.subscribed ? -
Matchmaking
-
+ {pvpBtn()} {inviteBtn()}
diff --git a/client/src/events.jsx b/client/src/events.jsx index 0741ee51..073c2ffc 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -209,7 +209,6 @@ function registerEvents(store) { return store.dispatch(actions.setInvite(code)); } - let autoReady = null; function setInstance(v) { const { account, instance, ws, tutorial } = store.getState(); if (v) { @@ -218,25 +217,10 @@ function registerEvents(store) { const player = v.players.find(p => p.id === account.id); store.dispatch(actions.setPlayer(player)); - if (!instance || v.id !== instance.id) { - clearTimeout(autoReady); - } - if (v.phase === 'Finished') { ws.sendAccountInstances(); } - if (v.phase_end && v.phase === 'Lobby' && !autoReady) { - const skip = v.time_control === 'Practice' ? 10000 : 2000; - const autoReadyDelay = Date.parse(v.phase_end) - Date.now() - skip; - autoReady = setTimeout(() => { - ws.sendInstanceReady(v.id); - autoReady = null; - }, autoReadyDelay); - } - - if (v.phase !== 'Lobby') clearTimeout(autoReady); - // instance.mobile.less hides info at @media 1000 if (localStorage.getItem('tutorial-complete') || window.innerWidth <= 1100) { store.dispatch(actions.setTutorial(null)); diff --git a/server/src/game.rs b/server/src/game.rs index 02854483..86fed074 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -469,14 +469,14 @@ impl Game { let mut resolutions = resolution_steps(&cast, &mut self); r_animation_ms = resolutions.iter().fold(r_animation_ms, |acc, r| acc + r.clone().get_delay()); - + // the cast itself goes into this temp vec to handle cooldowns // if theres no resolution events, the skill didn't trigger (disable etc) if resolutions.len() > 0 { casts.push(cast); } - + self.resolved.append(&mut resolutions); // while let Some(resolution) = resolutions.pop() { @@ -635,15 +635,15 @@ impl Game { for player in self.players.iter_mut() { if !player.ready { player.set_ready(true); - player.add_warning(); - info!("upkeep: {:} warned", player.name); - if player.warnings >= 3 { - player.forfeit(); - info!("upkeep: {:} forfeited", player.name); - //todo - // self.resolved.push(forfeit) - // self.log.push(format!("{:} forfeited.", player.name)); - } + // player.add_warning(); + // info!("upkeep: {:} warned", player.name); + // if player.warnings >= 3 { + // player.forfeit(); + // info!("upkeep: {:} forfeited", player.name); + // //todo + // // self.resolved.push(forfeit) + // // self.log.push(format!("{:} forfeited.", player.name)); + // } } } @@ -1622,6 +1622,6 @@ mod tests { game.players[0].set_ready(true); game.phase_end = Some(Utc::now().checked_sub_signed(Duration::seconds(500)).unwrap()); game = game.upkeep(); - assert!(game.players[1].warnings == 1); + // assert!(game.players[1].warnings == 1); } } diff --git a/server/src/player.rs b/server/src/player.rs index 0e0baf56..ffa7c379 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -63,7 +63,6 @@ pub struct Player { pub constructs: Vec, pub bot: bool, pub ready: bool, - pub warnings: u8, pub draw_offered: bool, pub score: Score, } @@ -85,7 +84,6 @@ impl Player { constructs, bot: false, ready: false, - warnings: 0, draw_offered: false, score: Score::Zero, }) @@ -100,7 +98,6 @@ impl Player { constructs, bot: false, ready: false, - warnings: 0, draw_offered: false, score: Score::Zero, } @@ -134,11 +131,6 @@ impl Player { self } - pub fn add_warning(&mut self) -> &mut Player { - self.warnings += 1; - self - } - pub fn forfeit(&mut self) -> &mut Player { for construct in self.constructs.iter_mut() { construct.force_ko(); @@ -358,7 +350,7 @@ impl Player { } self.vbox.bound.push(target); - + if target_construct_id.is_some() { let equip_index = self.vbox.bound.len() - 1; self.vbox_apply(equip_index, target_construct_id.expect("no construct"))?; From 70f99a6ffd09d5646ca0cfdb417c26645c65cb92 Mon Sep 17 00:00:00 2001 From: ntr Date: Wed, 13 Nov 2019 21:35:52 +1100 Subject: [PATCH 52/53] game cancelled --- client/assets/styles/instance.less | 4 ++++ client/src/components/faceoff.jsx | 6 ++++++ server/src/account.rs | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/client/assets/styles/instance.less b/client/assets/styles/instance.less index 4bb23969..b94ad2d9 100644 --- a/client/assets/styles/instance.less +++ b/client/assets/styles/instance.less @@ -434,6 +434,10 @@ &.winner { animation: win 2s ease-in-out 0s 1; } + + .cancelled { + color: white; + } } .tutorial { diff --git a/client/src/components/faceoff.jsx b/client/src/components/faceoff.jsx index ea3858cd..579a9e6e 100644 --- a/client/src/components/faceoff.jsx +++ b/client/src/components/faceoff.jsx @@ -80,6 +80,12 @@ class Faceoff extends preact.Component { } function faceoffText() { if (!instance.winner) { + if (instance.phase === 'Finished') return ( +
+
game cancelled
+
+ ); + return (
{otherTeam.name}
diff --git a/server/src/account.rs b/server/src/account.rs index 66af0821..c404d7d6 100644 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -73,7 +73,7 @@ pub fn chat_wheel(_db: &Db, _id: Uuid) -> Result, Error> { "glhf".to_string(), "ez".to_string(), "rekt".to_string(), - "nice".to_string(), + "wow".to_string(), "wp".to_string(), "ok".to_string(), "...".to_string(), From 917b239647d6d74a8a37d3c4a02dd667c114e80c Mon Sep 17 00:00:00 2001 From: ntr Date: Wed, 13 Nov 2019 21:37:53 +1100 Subject: [PATCH 53/53] fix double ready --- client/src/components/instance.ctrl.btns.jsx | 5 ----- client/src/events.jsx | 7 ++++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/components/instance.ctrl.btns.jsx b/client/src/components/instance.ctrl.btns.jsx index c4130385..45c26e1f 100644 --- a/client/src/components/instance.ctrl.btns.jsx +++ b/client/src/components/instance.ctrl.btns.jsx @@ -49,11 +49,6 @@ function InstanceCtrlBtns(args) { const finished = instance && instance.phase === 'Finished'; - const skip = instance.time_control === 'Practice' && instance.phase === 'Lobby'; - if (skip) { - sendReady(); - } - return (
diff --git a/client/src/events.jsx b/client/src/events.jsx index 073c2ffc..ab634d98 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -210,13 +210,18 @@ function registerEvents(store) { } function setInstance(v) { - const { account, instance, ws, tutorial } = store.getState(); + const { account, ws, tutorial } = store.getState(); if (v) { setInvite(null); setPvp(false); const player = v.players.find(p => p.id === account.id); store.dispatch(actions.setPlayer(player)); + const skip = v.time_control === 'Practice' && v.phase === 'Lobby'; + if (skip) { + ws.sendInstanceReady(v.id); + } + if (v.phase === 'Finished') { ws.sendAccountInstances(); }