diff --git a/WORKLOG.md b/WORKLOG.md index 782d0f24..601e950b 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -46,9 +46,8 @@ * eth adapter * pay for rerolls -* remove test variants of skills - -* itemise all skills and warn on some +* warden + * set upkeep_at timestamp for games and instances ## SOON @@ -63,6 +62,11 @@ * skills * private fields for opponents +* matchmaking + * elo + * password on MM game to prevent direct joins + + * flavour text * chat wheel trash talk * KO animations and trash talk diff --git a/client/index.html b/client/index.html index f2a78170..f0da3e9e 100644 --- a/client/index.html +++ b/client/index.html @@ -18,14 +18,5 @@ - + \ No newline at end of file diff --git a/client/src/components/game.component.jsx b/client/src/components/game.component.jsx index d199661d..fe110229 100644 --- a/client/src/components/game.component.jsx +++ b/client/src/components/game.component.jsx @@ -83,7 +83,7 @@ function GamePanel(props) { return null; } - const zero = Date.parse(game.phase_end) - (1000 * 60); + const zero = Date.parse(game.phase_start); const now = Date.now(); const end = Date.parse(game.phase_end); const timerPct = ((now - zero) / (end - zero) * 100); diff --git a/client/src/components/info.component.jsx b/client/src/components/info.component.jsx index cbbc714a..c70133e9 100644 --- a/client/src/components/info.component.jsx +++ b/client/src/components/info.component.jsx @@ -117,7 +117,9 @@ function InfoComponent(args) { function Combos() { if (!player) return false; - if (!(combiner.every(u => u === null))) { + + // show recipe for what's in combiner + if (combiner.some(u => u !== null)) { const filteredCombos = itemInfo.combos .filter(combo => combiner.every(u => u === null || combo.components.includes(player.vbox.bound[u]))); @@ -136,6 +138,7 @@ function InfoComponent(args) { ); } + if (!info) return false; const vboxCombos = itemInfo.combos.filter(c => c.components.includes(info)); if (vboxCombos.length > 6) return false; return ( diff --git a/client/src/components/instance.component.jsx b/client/src/components/instance.component.jsx index dff4d03c..2bc1b09c 100644 --- a/client/src/components/instance.component.jsx +++ b/client/src/components/instance.component.jsx @@ -64,7 +64,7 @@ function Instance(args) { : null; // TIMER - const zero = Date.parse(instance.phase_end) - (1000 * 120); + const zero = Date.parse(instance.phase_start); const now = Date.now(); const end = Date.parse(instance.phase_end); const timerPct = ((now - zero) / (end - zero) * 100); diff --git a/client/src/components/instance.equip.jsx b/client/src/components/instance.equip.jsx index 3a18908a..a5f8f813 100644 --- a/client/src/components/instance.equip.jsx +++ b/client/src/components/instance.equip.jsx @@ -64,8 +64,6 @@ function Equipment(props) { const isSkill = fullInfo && fullInfo.skill; const isSpec = fullInfo && fullInfo.spec; - console.log('isSkill', isSkill, fullInfo); - function skillClick(e, i) { if (itemUnequip && activeConstruct) return false; // const value = vbox.bound[i]; diff --git a/client/src/constants.jsx b/client/src/constants.jsx index e950b8ad..6bf4de39 100644 --- a/client/src/constants.jsx +++ b/client/src/constants.jsx @@ -1,6 +1,5 @@ module.exports = { TIMES: { - RESOLUTION_TIME_MS: 1000, START_SKILL: 700, END_SKILL: 700, POST_SKILL: 1000, diff --git a/server/src/game.rs b/server/src/game.rs index 51a544ef..5cbf6120 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -162,13 +162,14 @@ impl Game { return self.finish(); } - self.skill_phase_start() + self.skill_phase_start(0) } - fn skill_phase_start(mut self) -> Game { + fn skill_phase_start(mut self, num_resolutions: usize) -> Game { + let phase_add_time_ms = 60000 + num_resolutions * 2500; self.phase_start = Utc::now(); self.phase_end = Utc::now() - .checked_add_signed(Duration::seconds(60)) + .checked_add_signed(Duration::milliseconds(phase_add_time_ms as i64)) .expect("could not set phase end"); for player in self.players.iter_mut() { @@ -426,12 +427,14 @@ impl Game { // temp vec of this round's resolving skills // because need to check cooldown use before pushing them into the complete list let mut casts = vec![]; + let mut turn_events = 0; while let Some(cast) = self.stack.pop() { // info!("{:} casts ", cast); let mut resolutions = resolution_steps(&cast, &mut self); resolutions.reverse(); + turn_events += resolutions.len(); while let Some(resolution) = resolutions.pop() { self.log_resolution(cast.speed, &resolution); // the results go into the resolutions @@ -455,7 +458,7 @@ impl Game { return self.finish() } - self.skill_phase_start() + self.skill_phase_start(turn_events) } fn progress_durations(&mut self, resolved: &Vec) -> &mut Game { diff --git a/server/src/instance.rs b/server/src/instance.rs index d2de34ea..d564d49b 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -30,6 +30,11 @@ enum InstancePhase { Finished, } +#[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] +enum Format { + Standard, +} + #[derive(Debug,Clone,Serialize,Deserialize)] struct Round { player_ids: Vec, @@ -48,7 +53,10 @@ pub struct Instance { max_rounds: usize, password: Option, pub name: String, + + format: Format, phase_end: DateTime, + phase_start: DateTime, } impl Instance { @@ -64,6 +72,9 @@ impl Instance { name: String::new(), password: None, phase_end: Utc::now(), + phase_start: Utc::now(), + + format: Format::Standard, } } @@ -78,7 +89,10 @@ impl Instance { max_rounds: 1, name: "Global Matchmaking".to_string(), password: None, + phase_start: Utc::now(), phase_end: Utc::now(), + + format: Format::Standard, } } @@ -273,16 +287,17 @@ impl Instance { } fn next_round(&mut self) -> &mut Instance { - self.phase = InstancePhase::InProgress; - self.phase_end = Utc::now() - .checked_add_signed(Duration::seconds(15000)) - .expect("could not set phase end"); - - - if self.rounds.len() >= self.max_rounds { + if self.win_condition() { return self.finish(); } + self.phase = InstancePhase::InProgress; + self.phase_start = Utc::now(); + self.phase_end = Utc::now() + .checked_add_signed(Duration::seconds(120)) + .expect("could not set phase end"); + + self.players.iter_mut().for_each(|p| { p.set_ready(false); p.vbox.fill(); @@ -294,6 +309,12 @@ impl Instance { self } + fn win_condition(&self) -> bool { + match self.format { + Format::Standard => self.players.iter().any(|p| p.score.wins > 2) + } + } + fn finish(&mut self) -> &mut Instance { self.phase = InstancePhase::Finished; self