public override ICommandResponse Handle(StopJamCommand command) { var bout = _boutDataService.Load(command.BoutId); var state = _boutRunnerService.GetBoutState(command.BoutId); //State must be in jam if (state.Phase != BoutPhase.Jam) { throw new InvalidBoutPhaseException(state.Phase); } //Check to see if bout is over if (state.GameClock.Elapsed.Seconds < bout.RuleSet.PeriodDurationSeconds) { //Still good state.LineupStart = DateTime.Now; state.Phase = BoutPhase.Lineup; state.CreateNextJam(); //keep the jam clock going in case of undo } else { //Intermission if (state.Period < bout.RuleSet.NumberOfPeriods) { state.JamNumber = 1; state.Period++; state.GameClock.Clear(); state.Phase = BoutPhase.Halftime; } else //Game Over { state.Phase = BoutPhase.UnofficialFinal; } } state.JamStart = DateTime.Now; state.GameClock.Start(); var response = new UpdateBoutStateResponse(state); state.PenaltyBox.ForEach(x => { x.StopWatch.Stop(); response.AddEvent(new ChairUpdatedEvent(state.BoutId, x), Audiences.Bout(state.BoutId)); }); return(response); }
public override ICommandResponse Handle(ButtHitSeatCommand command) { var response = new CommandResponse(); var state = _boutRunner.GetBoutState(command.BoutId); if (state.PenaltyBox.Any(x => x.Id == command.Chair.Id)) { throw new ButtAlreadyInChairException(command.Chair.Id); } if (state.Phase == Entities.BoutPhase.Jam) { command.Chair.StopWatch.Start(); } if (command.Chair.IsJammer) { var jammer = state.GetCurrentJammer(command.Chair.Team); if (jammer.HasValue) { command.Chair.Number = jammer.Value; command.Chair.SecondsOwed = state.Penalties.Any(x => x.Number == command.Chair.Number) ? state.Penalties.Where(x => x.Number == command.Chair.Number).Sum(x => x.SecondsOwed) : command.Chair.SecondsOwed; } var otherTeam = command.Chair.Team == "left" ? "right" : "left"; var otherJammerInBox = state.PenaltyBox.SingleOrDefault(x => x.Team == otherTeam && x.IsJammer); if (otherJammerInBox != null) { var timeRemaining = Math.Max(otherJammerInBox.SecondsOwed - (int)Math.Round(otherJammerInBox.StopWatch.Elapsed.TotalSeconds), 0); if (timeRemaining < command.Chair.SecondsOwed) { otherJammerInBox.SecondsOwed -= timeRemaining; command.Chair.SecondsOwed -= timeRemaining; } else { otherJammerInBox.SecondsOwed -= command.Chair.SecondsOwed; command.Chair.SecondsOwed = 0; } response.AddEvent(new ChairUpdatedEvent(command.BoutId, otherJammerInBox), Audiences.Bout(command.BoutId)); } } state.PenaltyBox.Add(command.Chair); response.AddEvent(new ChairUpdatedEvent(command.BoutId, command.Chair), Audiences.Bout(command.BoutId)); return(response); }
public override ICommandResponse Handle(CreatePenaltyCommand command) { var state = _boutRunner.GetBoutState(command.BoutId); var data = _boutData.Load(command.BoutId); var penalty = new Penalty(command.Team, command.Period, command.Jam, state.GameClock.Elapsed, data.RuleSet.PenaltyDurationSeconds); state.Penalties.Add(penalty); var response = new CommandResponse(); response.AddEvent(new PenaltyUpdatedEvent(command.BoutId, penalty), Audiences.Bout(command.BoutId)); return(response); }
public override ICommandResponse Handle(UpdatePenaltyCommand command) { var state = _boutRunner.GetBoutState(command.BoutId); var target = state.Penalties.SingleOrDefault(x => x.Id == command.Penalty.Id); if (target == null) { throw new NoSuchPenaltyException(command.Penalty.Id); } var source = command.Penalty; target.Team = source.Team; if (target.Number != source.Number) { // If the penalty is moving off of a skater in the box, remove time // If it's moving to a skater in the box, add time var skaterInBox = state.PenaltyBox.SingleOrDefault(x => x.Number == target.Number); if (skaterInBox != null) { skaterInBox.SecondsOwed -= 30; } target.Number = source.Number; skaterInBox = state.PenaltyBox.SingleOrDefault(x => x.Number == target.Number); if (skaterInBox != null) { skaterInBox.SecondsOwed += 30; } } target.SecondsOwed = source.SecondsOwed; target.PenaltyCode = source.PenaltyCode; target.Period = source.Period; target.JamNumber = source.JamNumber; target.GameClock = source.GameClock; var response = new CommandResponse(); response.AddEvent(new PenaltyUpdatedEvent(command.BoutId, target), Audiences.Bout(command.BoutId)); return(response); }
public override ICommandResponse Handle(ReleaseSkaterCommand command) { var response = new CommandResponse(); var state = _boutRunner.GetBoutState(command.BoutId); var sit = state.PenaltyBox.SingleOrDefault(x => x.Id == command.ChairId); if (sit == null) { return(response); } var timeServed = sit.SecondsOwed; var penalties = state.Penalties.Where(x => x.Team == sit.Team && x.Number == sit.Number).ToList(); while (timeServed > 0 && penalties.Any()) { var penalty = penalties.First(); if (timeServed > penalty.SecondsOwed) { timeServed -= penalty.SecondsOwed; penalty.SecondsOwed = 0; penalties.Remove(penalty); } else { penalty.SecondsOwed -= timeServed; timeServed = 0; } response.AddEvent(new PenaltyUpdatedEvent(command.BoutId, penalty), Audiences.Bout(command.BoutId)); } state.PenaltyBox.Remove(sit); response.AddEvent(new ChairRemovedEvent(command.BoutId, command.ChairId), Audiences.Bout(command.BoutId)); return(response); }
public override ICommandResponse Handle(StartJamCommand command) { var response = new CommandResponse(); var bout = _boutDataService.Load(command.BoutId); var state = _boutRunnerService.GetBoutState(command.BoutId); //State must be in lineup if (state.Phase != BoutPhase.Lineup) { throw new InvalidBoutPhaseException(state.Phase); } //There must be time left on the game clock var elapsed = state.GameClock.Elapsed.TotalSeconds; if (elapsed > bout.RuleSet.PeriodDurationSeconds) { response.AddEvent( MessageBaseEvent.Error($"Call to start jam came too late. Elapsed: {state.GameClock.Elapsed.TotalSeconds}"), command.Originator); return(response); } state.Phase = BoutPhase.Jam; state.JamStart = DateTime.Now; state.GameClock.Start(); state.PenaltyBox.ForEach(x => { x.StopWatch.Start(); response.AddEvent(new ChairUpdatedEvent(state.BoutId, x), Audiences.Bout(state.BoutId)); }); response.AddEvent(new BoutStateUpdatedEvent(state), Audiences.Bout(state.BoutId)); return(response); }
public override ICommandResponse Handle(CancelSitCommand command) { var state = _boutRunner.GetBoutState(command.BoutId); var sit = state.PenaltyBox.SingleOrDefault(x => x.Id == command.ChairId); var response = new CommandResponse(); if (sit != null) { state.PenaltyBox.Remove(sit); response.AddEvent(new ChairRemovedEvent(command.BoutId, command.ChairId), Audiences.Bout(command.BoutId)); } return(response); }