/// <summary> /// Creates any combat events that will result in the launch. /// </summary> private List <GameEvent> CreateCombatEvents(Sub launchedSub, GameState state) { List <GameEvent> _combatEvents = new List <GameEvent>(); // Create the combat event for arrival CombatEvent arriveCombat = new CombatEvent(launchedSub, launchedSub.GetDestination(), launchedSub.GetExpectedArrival()); _combatEvents.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 if (launchedSub.GetDestination() is Outpost && launchedSub.GetSource() is Outpost) { foreach (Sub sub in state.getSubsOnPath((Outpost)launchedSub.GetSource(), (Outpost)launchedSub.GetDestination())) { // Don't combat with yourself if (sub == launchedSub) { continue; } // Determine if we combat it if (sub.GetDirection() == launchedSub.GetDirection()) { GameTick ourArrival = launchedSub.GetExpectedArrival(); GameTick theirArrival = sub.GetExpectedArrival(); if (ourArrival < theirArrival) { // We can catch it. Determine when and create a combat event. float distanceBetween = (sub.GetCurrentPosition(state.CurrentTick) - launchedSub.GetCurrentPosition(state.GetCurrentTick())).ToVector2().Length(); float velocityDifference = launchedSub.GetSpeed() - sub.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.GetOwner() != launchedSub.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.GetExpectedArrival() - launchedSub.GetLaunchTick(); // Determine the speed ratio as a number between 0-0.5 double speedRatio = (sub.GetSpeed() / launchedSub.GetSpeed()) - 0.5; int ticksUntilCombat = (int)Math.Floor(speedRatio * ticksBetweenSubs); // Determine collision position: RftVector combatPosition = new RftVector(RftVector.Map, launchedSub.GetDirection().ToVector2() * ticksUntilCombat); CombatEvent combatEvent = new CombatEvent(sub, launchedSub, state.CurrentTick.Advance(ticksUntilCombat)); _combatEvents.Add(combatEvent); } } } } return(_combatEvents); }