public void LaunchingASubTriggersAnOnLaunchEvent() { MockSubLauncherEntity(10, initialOwner, 3); Assert.IsNotNull(_mockEntity.Object.GetComponent <SubLauncher>()); OnSubLaunchEventArgs subLaunchEventData = null; _mockEntity.Object.GetComponent <SubLauncher>().OnSubLaunch += (sender, args) => { subLaunchEventData = args; }; var mockGameState = new Mock <IGameState>(); var launchEventData = new LaunchEventData() { DestinationId = "1", DrillerCount = 5, SourceId = "2" }; var launchEvent = new LaunchEvent(new GameEventModel() { EventData = launchEventData.ToByteString(), EventType = EventType.LaunchEvent, Id = "asdf", IssuedBy = initialOwner.GetId(), OccursAtTick = 1, RoomId = "1", UnixTimeIssued = 1234123412341234, }); RftVector.Map = new Rft(100, 100); var destination = new Generator(launchEventData.DestinationId, new RftVector(0, 0)); var source = new Generator(launchEventData.SourceId, new RftVector(0, 0)); mockGameState.Setup(it => it.GetEntity(launchEventData.SourceId)).Returns(source); mockGameState.Setup(it => it.GetEntity(launchEventData.DestinationId)).Returns(destination); Sub capturedSub = null; mockGameState.Setup(it => it.AddSub(It.IsAny <Sub>())).Callback <Sub>(sub => { capturedSub = sub; }); _mockEntity.Object.GetComponent <SubLauncher>().LaunchSub(mockGameState.Object, launchEvent); // Verify the sub was added to the state mockGameState.Verify(it => it.AddSub(subLaunchEventData.LaunchedSub), Times.Once); Assert.IsNotNull(capturedSub); Assert.AreEqual(destination, capturedSub.GetComponent <PositionManager>().GetDestination()); Assert.AreEqual(launchEventData.DrillerCount, capturedSub.GetComponent <DrillerCarrier>().GetDrillerCount()); Assert.AreEqual(initialOwner, capturedSub.GetComponent <DrillerCarrier>().GetOwner()); Assert.AreEqual(0, capturedSub.GetComponent <SpecialistManager>().GetSpecialistCount()); // Verify event data Assert.IsNotNull(subLaunchEventData); Assert.AreEqual(destination, subLaunchEventData.Destination); Assert.AreEqual(source, subLaunchEventData.Source); Assert.IsNotNull(subLaunchEventData.LaunchedSub); Assert.AreEqual(launchEventData.DrillerCount, subLaunchEventData.LaunchedSub.GetComponent <DrillerCarrier>().GetDrillerCount()); Assert.AreEqual(initialOwner, subLaunchEventData.LaunchedSub.GetComponent <DrillerCarrier>().GetOwner()); Assert.AreEqual(0, subLaunchEventData.LaunchedSub.GetComponent <SpecialistManager>().GetSpecialistCount()); }
/// <summary> /// Undoes the sub's arrival /// </summary> /// <returns>If the event was undone</returns> public override bool BackwardAction(TimeMachine timeMachine, GameState.GameState state) { if (EventSuccess) { _outpost.GetComponent <DrillerCarrier>().RemoveDrillers(_arrivingSub.GetComponent <DrillerCarrier>().GetDrillerCount()); _outpost.GetComponent <SpecialistManager>() .RemoveSpecialists(_arrivingSub.GetComponent <SpecialistManager>().GetSpecialists()); state.AddSub(this._arrivingSub); return(true); } return(false); }
public Sub LaunchSub(IGameState state, LaunchEvent launchEvent) { // Determine any specialist effects if a specialist left the sub. LaunchEventData launchData = launchEvent.GetEventData(); Entity source = state.GetEntity(launchData.SourceId); Entity destination = state.GetEntity(launchData.DestinationId); if (destination != null && _drillerCarrier.HasDrillers(launchData.DrillerCount)) { _drillerCarrier.RemoveDrillers(launchData.DrillerCount); Sub launchedSub = new Sub(launchEvent.GetEventId(), source, destination, state.GetCurrentTick(), launchData.DrillerCount, this._drillerCarrier.GetOwner()); this._specialistManager.TransferSpecialistsById(launchedSub.GetComponent <SpecialistManager>(), launchData.SpecialistIds.ToList()); state.AddSub(launchedSub); launchEvent.SetLaunchedSub(launchedSub); OnSubLaunch?.Invoke(this, new OnSubLaunchEventArgs() { Destination = destination, LaunchedSub = launchedSub, LaunchEvent = launchEvent, Source = source }); return(launchedSub); } return(null); }
/// <summary> /// Validates a sub /// </summary> /// <param name="state">The game state</param> /// <param name="sub">The sub to validate</param> /// <returns>If the sub is valid</returns> public static bool ValidateSub(GameState.GameState state, Sub sub) { if (sub == null) { return(false); } if (!state.SubExists(sub)) { return(false); } if (sub.GetComponent <DrillerCarrier>().GetDrillerCount() < 0) { return(false); } if (sub.GetComponent <SpecialistManager>() == null) { return(false); } if (sub.GetComponent <SpecialistManager>().GetSpecialistCount() < 0) { return(false); } if (sub.GetComponent <SpecialistManager>().GetSpecialistCount() > sub.GetComponent <SpecialistManager>().GetCapacity()) { return(false); } if (sub.GetComponent <DrillerCarrier>().GetOwner() != null && !state.PlayerExists(sub.GetComponent <DrillerCarrier>().GetOwner())) { return(false); } return(true); }
/// <summary> /// Performs the forward event /// </summary> public override bool ForwardAction(TimeMachine timeMachine, GameState.GameState state) { this._launchedSub = state.GetEntity(GetEventData().SourceId).GetComponent <SubLauncher>().LaunchSub(state, this); if (_launchedSub != null && !_launchedSub.GetComponent <DrillerCarrier>().GetOwner().IsEliminated()) { _combatEvents.AddRange(CreateCombatEvents(_launchedSub, state)); foreach (GameEvent e in _combatEvents) { timeMachine.AddEvent(e); } this.EventSuccess = true; } else { this.EventSuccess = false; } return(this.EventSuccess); }
public void UndoLaunch(IGameState state, LaunchEvent launchEvent) { // Determine any specialist effects if a specialist left the sub. LaunchEventData launchData = launchEvent.GetEventData(); if (launchEvent.GetActiveSub() != null) { Sub launchedSub = launchEvent.GetActiveSub(); _drillerCarrier.AddDrillers(launchData.DrillerCount); launchedSub.GetComponent <SpecialistManager>().TransferSpecialistsTo(_specialistManager); state.RemoveSub(launchEvent.GetActiveSub()); OnUndoSubLaunch?.Invoke(this, new OnUndoSubLaunchEventArgs() { Destination = state.GetEntity(launchData.DestinationId), LaunchedSub = launchedSub, LaunchEvent = launchEvent, Source = state.GetEntity(launchData.SourceId) }); } }
/// <summary> /// Creates any combat events that will result in the launch. /// </summary> private List <GameEvent> CreateCombatEvents(Sub launchedSub, GameState.GameState state) { List <GameEvent> events = new List <GameEvent>(); // Create the combat event for arrival CombatEvent arriveCombat = new CombatEvent(launchedSub, state.GetEntity(GetEventData().DestinationId), launchedSub.GetComponent <PositionManager>().GetExpectedArrival()); events.Add(arriveCombat); // Determine any combat events that may exist along the way. // First determine if any subs are on the same path. // Subs will only be on the same path if it is outpost to outpost // TODO: /* * if (launchedSub.GetComponent<PositionManager>().GetExpectedDestination() is Outpost && launchedSub.GetComponent<PositionManager>().GetSource() is Outpost) * { * foreach (Sub sub in state.getSubsOnPath((Outpost)launchedSub.GetComponent<PositionManager>().GetSource(), (Outpost)launchedSub.GetComponent<PositionManager>().GetDestination())) * { * // Don't combat with yourself * if(sub == launchedSub) * continue; * * // Determine if we combat it * if (sub.GetComponent<PositionManager>().GetDirection() == launchedSub.GetComponent<PositionManager>().GetDirection()) * { * GameTick ourArrival = launchedSub.GetComponent<PositionManager>().GetExpectedArrival(); * GameTick theirArrival = sub.GetComponent<PositionManager>().GetExpectedArrival(); * if (ourArrival < theirArrival) * { * // We can catch it. Determine when and create a combat event. * float distanceBetween = (sub.GetComponent<PositionManager>().GetPositionAt(state.CurrentTick) - launchedSub.GetComponent<PositionManager>().GetPositionAt(state.GetCurrentTick())).ToVector2().Length(); * float velocityDifference = launchedSub.GetComponent<SpeedManager>().GetSpeed() - sub.GetComponent<SpeedManager>().GetSpeed(); * int catchInTicks = (int)Math.Ceiling(distanceBetween / velocityDifference); * * CombatEvent catchCombat = new CombatEvent(launchedSub, sub, state.GetCurrentTick().Advance(catchInTicks)); * _combatEvents.Add(arriveCombat); * } * } * else * { * // Sub is moving towards us. * if (sub.GetComponent<DrillerCarrier>().GetOwner() != launchedSub.GetComponent<DrillerCarrier>().GetOwner()) * { * // Combat will occur * // Determine when and create a combat event. * * // Determine the number of ticks between the incoming sub & the launched sub. * int ticksBetweenSubs = sub.GetComponent<PositionManager>().GetExpectedArrival() - launchedSub.GetComponent<PositionManager>().GetSpawnTick(); * * // Determine the speed ratio as a number between 0-0.5 * double speedRatio = (sub.GetComponent<SpeedManager>().GetSpeed() / launchedSub.GetComponent<SpeedManager>().GetSpeed()) - 0.5; * * int ticksUntilCombat = (int)Math.Floor(speedRatio * ticksBetweenSubs); * * // Determine collision position: * RftVector combatPosition = new RftVector(RftVector.Map, launchedSub.GetComponent<PositionManager>().GetDirection().ToVector2() * ticksUntilCombat); * * CombatEvent combatEvent = new CombatEvent(sub, launchedSub, state.CurrentTick.Advance(ticksUntilCombat)); * _combatEvents.Add(combatEvent); * } * } * } * } */ return(events); }
public void HasDrillerCarrier() { Assert.IsNotNull(_sub.GetComponent <DrillerCarrier>()); }