/// <summary> /// Sub constructor /// </summary> /// <param name="source">The initial location of the sub</param> /// <param name="destination">The destination of the sub</param> /// <param name="launchTime">The time of launch</param> /// <param name="drillerCount">The amount of drillers to launch</param> /// <param name="owner">The owner</param> public Sub(ILaunchable source, ITargetable destination, GameTick launchTime, int drillerCount, Player owner) : base() { this._id = IdGenerator.GetNextId(); this._source = source; this._destination = destination; this._launchTime = launchTime; this._drillerCount = drillerCount; this.Position = source.GetCurrentPosition(); this._owner = owner; this._specialistManager = new SpecialistManager(3); }
/// <summary> /// Creates any combat events that will result in the launch. /// </summary> private void CreateCombatEvents() { // Create the combat event for arrival RftVector targetPosition = this._destination.GetTargetPosition(_source.GetCurrentPosition(), this._launchedSub.GetSpeed()); GameTick arrival = this._launchTime.Advance((int)Math.Floor((targetPosition - _source.GetCurrentPosition()).Magnitude() / this._launchedSub.GetSpeed())); CombatEvent arriveCombat = new CombatEvent(this._launchedSub, this._destination, arrival, targetPosition); _combatEvents.Add(arriveCombat); Game.TimeMachine.AddEvent(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 (this._destination.GetType().Equals(typeof(Outpost)) && this._source.GetType().Equals(typeof(Outpost))) { // Interpolate to launch time to determine combats! GameTick currentTick = Game.TimeMachine.GetCurrentTick(); Game.TimeMachine.GoTo(this.GetTick()); GameState interpolatedState = Game.TimeMachine.GetState(); foreach (Sub sub in interpolatedState.getSubsOnPath((Outpost)this._source, (Outpost)this._destination)) { // Don't combat with yourself if (sub == this.GetActiveSub()) { continue; } // Determine if we combat it if (sub.GetDirection() == this.GetActiveSub().GetDirection()) { if (this.GetActiveSub().GetExpectedArrival() < sub.GetExpectedArrival()) { // We can catch it. Determine when and create a combat event. } } else { // Sub is moving towards us. if (sub.GetOwner() != this.GetActiveSub().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() - this._launchTime; // Determine the speed ratio as a number between 0-0.5 double speedRatio = (sub.GetSpeed() / this.GetActiveSub().GetSpeed()) - 0.5; int ticksUntilCombat = (int)Math.Floor(speedRatio * ticksBetweenSubs); // Determine collision position: RftVector combatPosition = new RftVector(RftVector.Map, this.GetActiveSub().GetDirection() * ticksUntilCombat); CombatEvent combatEvent = new CombatEvent(sub, this.GetActiveSub(), this._launchTime.Advance(ticksUntilCombat), combatPosition); _combatEvents.Add(combatEvent); Game.TimeMachine.AddEvent(combatEvent); } } } // Go back to the original point in time. Game.TimeMachine.GoTo(currentTick); } }