protected override void Update() { GameTime.Update(); Flags.Update(GameTime); Shots.Update(GameTime); Players.Update(GameTime); }
private Shots compareDamage(Shots shot1, Shots shot2, float time) { // This function determines whether waiting for {shot1} for {time} seconds produces more dps than using {shot2} right now if (shot1 == Shots.None) { return(Shots.None); } if (shot2 == Shots.None) { return(Shots.None); } if (time <= 0) { return(Shots.None); } float shot1damage = shotData.ContainsKey(shot1) ? shotData[shot1].damage : 0; float shot2damage = shotData.ContainsKey(shot2) ? shotData[shot2].damage : 0; float frac = (float)Math.Round(time / 1.5f, 3); if (shot1damage - shot2damage > shot2damage * frac) { return(shot1); } return(shot2); }
public Player GetNextPlayer() { var activePlayers = ActivePlayers; var playersDescending = GetCurrentActivePlayers(activePlayers, includeOvertime: false).ToList(); var duplicatePlayers = Shots.GroupBy(s => s.Player.Id).Where(p => p.Count() > 1); // Check to see if we've had any duplicate players yet (if so, that means we can determine the order) if (duplicatePlayers.Any()) { var currentPlayer = GetCurrentPlayer(); var currentPlayerIndex = playersDescending.IndexOf(currentPlayer); if (currentPlayerIndex == playersDescending.Count - 1) { return(playersDescending[currentPlayerIndex - 1]); } else { return(playersDescending[0]); } } else { // If we can't determine the order, just get the next player who has not gone already foreach (var player in _allPlayers) { if (!activePlayers.Any(p => p.Id == player.Id)) { return(player); } } } return(new Player()); }
private IEnumerable <Player> GetCurrentActivePlayers(IEnumerable <Player> gamePlayers, bool includeOvertime) { if (_currentActivePlayers == null) { var currentActivePlayers = new List <Player>(); Func <Shot, bool> query; if (includeOvertime) { query = s => s.Game.Id == Game.Id; } else { query = s => s.Game.Id == Game.Id && s.Hole.Id < 10; } // TODO: The part where we check for holes less than 10 will need to change when we implement the new hole logic foreach (var shot in Shots.Where(query).OrderByDescending(s => s.Id)) { if (!currentActivePlayers.Any(p => p.Id == shot.Player.Id)) { currentActivePlayers.Add(shot.Player); } else { break; } } _currentActivePlayers = currentActivePlayers; } return(_currentActivePlayers); }
/** * Adds a shot in the shots list using positions in parameters to create it * start : the position where the shot was performed * target : the position of the target on the map * userPosition : the current position of the user (the position where the ball was shot) * return the created Shot object */ public Shot addPositionForCurrentHole(MyPosition start, MyPosition target, MyPosition userPosition) { Shot s = new Shot(CurrentClub, start, target, userPosition, DateTime.Now); Shots.Add(s); return(s); }
/** * Manages the end of the current hole * saveForStatistics : true to save the stats of the current hole, false to not save them */ public void holeFinished(bool saveForStatistics) { ScoreHole sh = StatistiquesGolf.saveForStats(this, itHole.Current, saveForStatistics); ScoreOfThisPartie.add(sh); Shots.Clear(); }
private void ClearShots() { foreach (KeyValuePair <Team, List <Shot> > keyValue in Shots) { Shots.Remove(keyValue.Key); } }
private bool checkGCD(Shots shot) { if (shotData.ContainsKey(shot)) { return(shotData[shot].check_gcd); } return(true); }
public void CanDirtyState() { Shots shots = new Shots(); shots.Add(new Shot()); Assert.IsTrue(shots.IsDirty); }
public void CanCleanState() { Shots shots = new Shots(); shots.Add(new Shot()); shots.Clean(); Assert.IsFalse(shots.IsDirty); }
public ShotData(Shots aType, bool doesntdodamage, bool aCritProcs, bool aGcd //,Character character, Stats stats, CombatFactors cf, CalculationOptionsHunter opts ) { DoesntDoDamage = doesntdodamage; Type = aType; CanCrit = aCritProcs; TriggersGCD = aGcd; //AttackTable = new AttackTable(character, stats, cf, opts, false, false); }
static void CheckHideFlags(HideFlags hideFlags = HideFlags.HideInHierarchy) { Curves.ForEach(x => x.gameObject.hideFlags = hideFlags); Hazards.ForEach(x => x.gameObject.hideFlags = hideFlags); Tees.ForEach(x => x.gameObject.hideFlags = hideFlags); Shots.ForEach(x => x.gameObject.hideFlags = hideFlags); Pins.ForEach(x => x.gameObject.hideFlags = hideFlags); Measures.ForEach(x => x.gameObject.hideFlags = hideFlags); FlyBys.ForEach(x => x.gameObject.hideFlags = hideFlags); }
private bool containsShot(Shots shot) { for (int i = 0; i < shotTable.Length; i++) { if (shotTable[i] != null && shotTable[i].type == shot) { return(true); } } return(false); }
public void ReturnsCorrectDiff() { Shots shots = new Shots(); shots.Add(new Shot()); shots.Clean(); shots.Add(new Shot()); shots.Add(new Shot()); Assert.AreEqual(2, shots.GetDiff().Count); }
private void Prepare() { _score = 0; _currentNpcDirection = NpcDirection.Left; _moveEnemiesAfter = 0; // Get start position _spaceShip.PositionX = (Console.WindowWidth / 2) - 2; _spaceShip.PositionY = Console.WindowHeight - 1; _shots = new Shots(); }
public List <Shot> Play() { bool isHunting = true; Shot result; while (ShipsDestroyed != Ship.NUM_OF_SHIPS) { Display.Grid(Board); //DISPLAY PURPOSE if (isHunting) { result = Hunt(); if (result.ShotTypeId == (int)ShotType.Hit) { TargetCoords.Add(new Coordinates { X = result.X, Y = result.Y, Val = result.InitialVal.GetValueOrDefault() }); isHunting = false; } } else { result = Target(); if (result.ShotTypeId != (int)ShotType.Missed) { if (result.ShotTypeId == (int)ShotType.Hit) { TargetCoords.Add(new Coordinates { X = result.X, Y = result.Y, Val = result.InitialVal.GetValueOrDefault() }); } else if (result.ShotTypeId == (int)ShotType.Destroyed) { isHunting = true; ShipsDestroyed++; TargetDirection = DirectionTaken.Random; TargetOrientation = Orientation.Random; PossibleTargets.Clear(); TargetCoords.Clear(); } } } if (result.ShotTypeId != (int)ShotType.Duplicate) { Shots.Add(result); ShotNumber++; } } Console.WriteLine("----------------"); //Display Purpose return(Shots); }
public RotationShotInfo(ShotData shot) { this.type = shot.Type; this.cooldown = shot.Cd; this.castTime = shot.Cd; this.check_gcd = shot.TriggersGCD; this.no_gcd = !shot.TriggersGCD && shot.Type != Shots.Readiness; this.damage = shot.Damage; if (shot.Type == Shots.SerpentSting) { this.cooldown = shot.Duration; } }
public List <Shot> Play() { while (ShipsDestroyed != Ship.NUM_OF_SHIPS) { Display.Grid(Board); //DISPLAY PURPOSE ShotNumber++; Shots.Add(Shoot()); } Console.WriteLine("----------------"); //Display Purpose return(Shots); }
protected RotationShot createRotationShot(Shots type) { RotationShot shot = new RotationShot(); switch (type) { case Shots.SteadyShot: //shot.casttime = (calculatedStats.SteadySpeed < 1.5 ? 1.5 : calculatedStats.SteadySpeed) + options.Latency; shot.cooldown = 0.0; shot.type = Shots.SteadyShot; break; case Shots.SerpentSting: shot.casttime = 1.5 + options.Latency; shot.cooldown = 15.0; shot.type = Shots.SerpentSting; break; case Shots.MultiShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 10.0; shot.type = Shots.MultiShot; break; case Shots.ExplosiveShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 6.0; shot.type = Shots.ExplosiveShot; break; //case Shots.ChimeraShot_Serpent: // shot.casttime = 1.5 + options.Latency; // shot.cooldown = 10.0; // shot.type = Shots.ChimeraShot_Serpent; // break; case Shots.ArcaneShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 6.0; shot.type = Shots.ArcaneShot; break; case Shots.AimedShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 10.0; shot.type = Shots.AimedShot; break; } return(shot); }
public int ShotCount() { int shotCount = 0; Shots.ForEach(s => { shotCount += s.Count; }); if (Goal != null) { shotCount++; } return(shotCount); }
public ShotData getShotInRotation(Shots aType) { for (int i = 0; i < priorities.Length; i++) { if (priorities[i] != null) { if (priorities[i].Type == aType) { return(priorities[i]); } } } return(null); }
private float waitCount = 6.0f; // wait count before state transition. #endregion Fields #region Constructors public Ship(Device device, GameClass gameClass, HullColors hullColor) { this.device = device; this.game = gameClass; shots = new Shots(device); if (hullColor == HullColors.White) { shipMesh = new PositionedMesh(device, "WhiteShip.x"); startingPosition = new Vector3(10, 0, 10); } else { shipMesh = new PositionedMesh(device, "RedShip.x"); startingPosition = new Vector3(-50, 0, -150); } SetRandomPosition(true); }
private IEnumerator PlayShots() { yield return(new WaitForSeconds(0.2f)); foreach (GameObject shooter in Shots) { GameObject prefab = shooter.CompareTag("Player") ? ManagedPrefabs.Bank[PrefabID.Bullet02] : ManagedPrefabs.Bank[PrefabID.Bullet01]; StartCoroutine(Bullet.SpawnBullets(shooter.GetComponent <Shooter>().ShotsPerTurn, prefab, shooter)); } yield return(new WaitForSeconds(Bullet.BulletFlyTime / 2)); Shots.Clear(); CurrentPhase.Value = Phase.Resolution; }
public void Fire(Coordinate coordinates) { if (ShotMap().TryGetValue(coordinates, out _)) { throw new ShipBattlesException($"Shot already taken: {coordinates}"); } if (coordinates.X >= Height || coordinates.Y >= Height) { throw new ShipBattlesException($"Shot outside board: {coordinates}"); } var hit = ShipMap().TryGetValue(coordinates, out _); Shots.Add(new Shot(coordinates, hit)); }
public bool containsShot(Shots aType) { for (int i = 0; i < priorities.Length; i++) { if (priorities[i] != null) { if (priorities[i].Type == aType) { return(true); } } } return(false); }
public Ship(Device device, GameClass gameClass, HullColors hullColor) { this.device = device; this.game = gameClass; shots = new Shots(device); if (hullColor == HullColors.White) { shipMesh = new PositionedMesh(device, "WhiteShip.x"); startingPosition = new Vector3(10, 0, 10); } else { shipMesh = new PositionedMesh(device, "RedShip.x"); startingPosition = new Vector3(-50, 0, -150); } SetRandomPosition(true); }
internal void HandleKilled(ServerPlayer player, MsgKilled msgKilled) { if (msgKilled == null || player == null) { return; } KilledEventArgs args = new KilledEventArgs(); msgKilled.VictimID = player.PlayerID; args.Victim = player; args.Killer = GetPlayerByID(msgKilled.KillerID); args.Shot = Shots.FindKillableShot(msgKilled.KillerID, msgKilled.ShotID); args.KillInfo = msgKilled; KillPlayer(player, args); }
public int GetPointsAvailable(int currentHole) { if (currentHole == 1) { _pointsAvailable = _allHoles.Single(h => h.Id == 1).Par; return(_pointsAvailable.Value); } else { int totalPoints = _allHoles.Where(h => h.Id <= currentHole).Sum(h => h.Par); int totalPointsTaken = Shots.Where(s => s.Hole.Id < currentHole).Sum(s => s.Points); _pointsAvailable = totalPoints - totalPointsTaken; return(_pointsAvailable.Value); } }
public void Update() { counter = (counter + 1) % 60; if (asd.Engine.Keyboard.GetKeyState(asd.Keys.Z) == asd.KeyState.Hold && counter % 6 == 0) { var angle = Math.Cos(2 * Math.PI * counter / 60) * Math.PI / 3.0 + Math.PI / 2; var d = new asd.Vector2DF((float)Math.Cos(angle), (float)Math.Sin(angle)) * 64; d.Y *= -1; var shot1 = new Shot(player.Position + d); d.X *= -1; var shot2 = new Shot(player.Position + d); layer.AddObject(shot1); layer.AddObject(shot2); Add(shot1); Add(shot2); } Shots.RemoveAll(s => !s.IsAlive); }
private float waitCount = 6.0f; // wait count before state transition. #endregion Fields #region Constructors public Ship(Device device, GameClass gameClass, HullColors hullColor) { this.device = device; this.game = gameClass; shots = new Shots(device); if (hullColor == HullColors.White) { shipMesh = new PositionedMesh(device, "WhiteShip.x"); startingPosition = new Vector3(10, 0, 10); } else { shipMesh = new PositionedMesh(device, "RedShip.x"); startingPosition = new Vector3(-50, 0, -150); } vaporTrail = new ParticleEffects(device); vaporTrail.ParticleTexture = TextureLoader.FromFile(device, MediaUtilities.FindFile("particle-blue.bmp")); SetRandomPosition(true); }
public void Shot(Guid shotPlayerId, Guid reboundPlayerId = new Guid()) { DbAttackShot playerShot = Shots.FirstOrDefault(p => p.PlayerId.Equals(shotPlayerId)); if (playerShot == null) { Shots.Add(new DbAttackShot { Id = Guid.NewGuid(), AttackId = DbAttack.Id, PlayerId = shotPlayerId, Count = 1 }); } else { playerShot.Count++; } if (reboundPlayerId == Guid.Empty) { return; } IDbAttackRebound playerRebound = Rebounds.FirstOrDefault(p => p.PlayerId.Equals(reboundPlayerId)); if (playerRebound == null) { Rebounds.Add(new DbAttackRebound { Id = Guid.NewGuid(), AttackId = DbAttack.Id, PlayerId = reboundPlayerId, Count = 1 }); } else { playerRebound.Count++; } }
private IEnumerable <LeaderboardViewModel> GetPlayersWhoCanWin(int currentHole) { if (_playersWhoCanWin == null) { int currentPointsAvailable = GetPointsAvailable(currentHole); var leaderboard = Leaderboard.OrderByDescending(l => l.Points); var leader = leaderboard.First(); // This is the leader's points not counting any temporary points scored on the current hole var leaderPoints = Shots.Where(s => s.Player.Id == leader.Player.Id && s.Hole.Id < currentHole).Sum(s => s.Points); if (leaderboard.Count(l => l.Points > leaderPoints) > 1) { var leaderAtBeginningOfHole = leaderboard.Where(l => l.Player.Id != leader.Player.Id).OrderByDescending(l => l.Points); leaderPoints = leaderAtBeginningOfHole.First().Points; } var playersWhoCanWin = new List <LeaderboardViewModel>(); foreach (var player in leaderboard) { // If the player has already gone on this hole and made the shot then we need to // subtract those points for the next calculation var newPlayerCurrentHoleShot = Shots.Where(s => s.Player.Id == player.Player.Id && s.Hole.Id == currentHole && s.Points > 0); int playerCurrentHolePoints = newPlayerCurrentHoleShot.Any() ? newPlayerCurrentHoleShot.First().Points : 0; // If the player can at least tie the leader, then he gets to take all shots if (((player.Points - playerCurrentHolePoints) + currentPointsAvailable) >= leaderPoints) { playersWhoCanWin.Add(player); } } _playersWhoCanWin = playersWhoCanWin; } return(_playersWhoCanWin); }
private void CheckShipsForHit(Coordinate coordinate, ShotResponse response) { response.ShotStatus = Shots.Miss; foreach (var ship in Ships) { // no need to check sunk ships if (ship.IsSunk) { continue; } Shots status = ship.FireAtShip(coordinate); switch (status) { case Shots.HitAndSunk: response.ShotStatus = Shots.HitAndSunk; response.ShipImpacted = ship.ShipName; ShotHistory.Add(coordinate, ShotRecord.Hit); break; case Shots.Hit: response.ShotStatus = Shots.Hit; response.ShipImpacted = ship.ShipName; ShotHistory.Add(coordinate, ShotRecord.Hit); break; } // if they hit something, no need to continue looping if (status != Shots.Miss) { break; } } if (response.ShotStatus == Shots.Miss) { ShotHistory.Add(coordinate, ShotRecord.Miss); } }
public Ship(Device device, GameClass gameClass, HullColors hullColor) { this.device = device; this.game = gameClass; shots = new Shots(device); if (hullColor == HullColors.White) { shipMesh = new PositionedMesh(device, "WhiteShip.x"); startingPosition = new Vector3(10, 0, 10); } else { shipMesh = new PositionedMesh(device, "RedShip.x"); startingPosition = new Vector3(-50, 0, -150); } vaporTrail = new ParticleEffects(device); vaporTrail.ParticleTexture = TextureLoader.FromFile(device, MediaUtilities.FindFile("particle-blue.bmp")); shockWave = new Shockwave(device); SetRandomPosition(true); }
private bool containsShot(Shots shot) { for (int i = 0; i < shotTable.Length; i++) { if (shotTable[i] != null && shotTable[i].type == shot) return true; } return false; }
public void RunTest() { float FightDuration = BossOpts.BerserkTimer; float Latency = CalcOpts.Latency; float CDCutoff = CalcOpts.CDCutoff; float Longevity = character.HunterTalents.Longevity; float GCD = 1.5f; float BA = calculatedStats.blackArrow.Duration; float it = calculatedStats.immolationTrap.Duration; float et = calculatedStats.explosiveTrap.Duration; float ft = calculatedStats.freezingTrap.Duration; float frt = calculatedStats.frostTrap.Duration; //float vly = calculatedStats.volley.Duration; float LALChance = character.HunterTalents.BlackArrow == 1 ? character.HunterTalents.LockAndLoad * CalcOpts.LALProcChance : -1; bool RandomProcs = CalcOpts.RandomizeProcs; int ISSfix = 0; int IAotHfix = 0; int LALfix = 0; float AutoShotSpeed = 2; // Speed at which we shoot auto-shots //float IAotHEffect = 1 + calculatedStats.quickShotsEffect; // haste increase during IAoTH float IAotHChance = -1; float WaitForESCS = CalcOpts.waitForCooldown; bool InterleaveLAL = CalcOpts.interleaveLAL; bool ArcAimedPrio = CalcOpts.prioritiseArcAimedOverSteady; float ISSTalent = character.HunterTalents.ImprovedSteadyShot * 5; float ISSDuration = -1; int ISSprocsAimed = 0; int ISSProcsArcane = 0; int ISSProcsChimera = 0; float BossHPPercentage = CalcOpts.BossHPPerc * 100; float Sub20Time = (BossHPPercentage > 20) ? FightDuration - (float)BossOpts.Under20Perc * FightDuration : 0; // time *until* we hit sub-20 bool UseKillShot = calculatedStats.priorityRotation.containsShot(Shots.KillShot); bool BMSpec = character.HunterTalents.BestialWrath + character.HunterTalents.TheBeastWithin > 0; if (CalcOpts.PetFamily == PETFAMILY.None) { BMSpec = false; } int currentShot; float currentTime; //int selectedShot; float ElapsedTime; float BWTime; float RFTime; //float VolleyTime; float BWCD; float RFCD; //float VLYCD; float LALTimer; // timer till current serpent sting expires float LALShots; // amount of free shots left float LALDuration; // time since last Explosive Shot while having L&L up float LastLALCheck; // time since last check for proc float LastLALProc; // time since last proc int LALProcs; // Amount of procs Shots LALType; // Type of L&L proc, i.e. Immolation trap or Black Arrow float IAotHDuration; // Time until buff expires float LastAutoShotCheck; // Last time we checked for IAotH procs int IAotHProcs; bool SerpentUsed; // Have we used Serpent Sting yet? #region Initialize shotData & shotTable shotData = new Dictionary <Shots, RotationShotInfo>(); // the shot info (focus, cooldown, etc) shotTable = new RotationShotInfo[10]; // the rotation info for (int i = 0; i < calculatedStats.priorityRotation.priorities.Length; i++) { ShotData shot = calculatedStats.priorityRotation.priorities[i]; if (shot != null && shot.Type != Shots.None) { shotData[shot.Type] = new RotationShotInfo(shot); shotTable[i] = shotData[shot.Type]; } else { shotTable[i] = null; } } #endregion #region Shot Timing Adjustments // we need to adjust rapid fire cooldown, since we accounted for readiness initially if (shotData.ContainsKey(Shots.RapidFire)) { shotData[Shots.RapidFire].cooldown = (5 - character.HunterTalents.RapidKilling) * 60f; } // set Steady Shot cast time so it's only static haste if (shotData.ContainsKey(Shots.SteadyShot)) { //shotData[Shots.SteadyShot].castTime = 2f / (1f + calculatedStats.hasteStaticTotal); } // Set Auto Shot Speed to statically hasted value AutoShotSpeed = 0f;//calculatedStats.autoShotStaticSpeed; #endregion #region Variable setup // these are used by both the frequency rotation and here in the rotation test bool chimeraRefreshesSerpent = containsShot(Shots.ChimeraShot) && containsShot(Shots.SerpentSting); currentShot = 1; currentTime = 0; ElapsedTime = 0; //Lock And Load variables LALTimer = -1; LALShots = -1; LALDuration = -1; LastLALCheck = -1; LastLALProc = -50; LALType = Shots.None; //IAotH variables // 021109 Drizz: Updating init variables to align with v92b spreadsheet LastAutoShotCheck = 0; // -50; IAotHDuration = 0; // -1; IAotHProcs = 0; SerpentUsed = false; // some things not initialized in the spreadsheet BWTime = 0; //VolleyTime = 0; RFTime = 0; BWCD = 0; RFCD = 0; //VLYCD = 0; currentTime = 0; LALProcs = 0; float IAotHUptime = 0; #endregion #region The Main Loop do { bool haveShot = false; Shots thisShot = Shots.None; #region Find shot - Non-GCD // Check shots that are off the GCD for (int i = 0; i < shotTable.Length && !haveShot; i++) { RotationShotInfo s = shotTable[i]; if (s != null) { if (s.type == Shots.BestialWrath && BWTime > currentTime) { // do nothing if Rapid Fire is still active } else if (s.type == Shots.RapidFire && RFTime > currentTime) { // Check if TBW/BW CD is nearly up if we want to use Rapid Fire } else if (BMSpec && s.type == Shots.Readiness && BWCD < (currentTime + CDCutoff)) { // Wait for Rapid Fire if it's close too } else if (s.type == Shots.Readiness && RFCD < (currentTime + CDCutoff)) { // wait for Rapid Fire } else if (s.type == Shots.BestialWrath && !BMSpec) { // do nothing //} else if (s.type == Shots.Volley && VLYCD < (currentTime + CDCutoff)) { // do nothing, we're channelling } else { // check if the shot is off the GCD if (s.no_gcd && s.time_until_off_cd <= currentTime) { thisShot = s.type; haveShot = true; } } } } #endregion #region Find Shot - Any // Check all shots whether they are off CD for (int i = 0; i < shotTable.Length && !haveShot; i++) { RotationShotInfo s = shotTable[i]; // known as thisShot if (s != null) { // During L&L proc Explosive Shot gets priority over everything else // Do nothing if L&L just proc'ed and ES is still on CD if (s.time_until_off_cd > currentTime && LALShots == 3 && s.type == Shots.ExplosiveShot) { } // First L&L proc shot else if (s.time_until_off_cd < currentTime && LALShots == 3 && s.type == Shots.ExplosiveShot) { s.time_until_off_cd = 0; LALShots--; haveShot = true; thisShot = s.type; // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #1" } // If We're interleaving, make sure the last ES was at least 2 seconds before this else if (InterleaveLAL && LALShots < 3 && LALShots > 0 && LALDuration - currentTime > -2 && LALDuration - currentTime <= 0 && s.type == Shots.ExplosiveShot) { currentTime += 0.5f; s.time_until_off_cd = 0; haveShot = true; thisShot = s.type; if (LALShots == 2) { // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #2" } else if (LALShots == 1) { // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #3" } LALShots--; } // If we're not interleaving other shots with L&L procs reset ES cooldown and advance timer by 0.5 seconds (to miss the last tick) else if (!InterleaveLAL && LALShots < 3 && LALShots > 0 && s.type == Shots.ExplosiveShot) { // ****************************************************************************** // 29-10-2009 - Drizz: Commenting out this line to align with Spreadsheet (v92b) // currentTime += 0.5; // ****************************************************************************** s.time_until_off_cd = 0; haveShot = true; thisShot = s.type; if (LALShots == 2) { // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #2" } else if (LALShots == 1) { // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "L&L #3" } LALShots--; } float waitTime = (float)Math.Round(s.time_until_off_cd - currentTime, 2); // Check if shots with CDs come off CD soon enough to wait for them, excluding stings if (!haveShot && waitTime > 0 && s.time_until_off_cd > currentTime && s.time_until_off_cd <= currentTime + WaitForESCS && s.type != Shots.SerpentSting && s.type != Shots.BlackArrow) { if (!ArcAimedPrio && (thisShot == Shots.AimedShot || thisShot == Shots.ArcaneShot || thisShot == Shots.MultiShot)) { // do nothing if we don't want to prioritise Aimed/Arcane or Multi-Shot } // ************************************************************************ //29-10-2009 Drizz : Added one else if check to align with Spreadsheet v92b else if (s.type == Shots.Readiness && RFCD < (currentTime + CDCutoff + waitTime)) { // Do nothing if we Rapid Fire isn't soon enough of CD } // ************************************************************************ else if (s.check_gcd) { bool result = true; // Check if other shots that are about to come off CD do more damage than this one for (int j = i; j < shotTable.Length && result; j++) { RotationShotInfo thatShot = shotTable[j]; if (thatShot != null) { // 021109 Drizz: Removed the last && on this line (align with Worksheet 92b. if (thatShot.time_until_off_cd > currentTime && thatShot.time_until_off_cd <= currentTime + WaitForESCS) // && checkGCD(thisShot)) { if (compareDamage(thisShot, thatShot.type, waitTime) != thisShot) { result = false; // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "(Skipped " & thisShot & ") " //exit for loop } } } } if (result) { currentTime = s.time_until_off_cd; thisShot = s.type; haveShot = true; // Cells(row + 1, col + 5).value = Cells(row + 1, col + 5).value + "(Waited " & waitTime & "s) " } } } // this is a horrible round hack, i know. the issue probably comes // somewhere from a float->float cast. // the issue is that we have currentTime at (e.g.) 65.35 and steady shot CD is at 65.3500000001 // so we skip forward by 0.1 seconds when we didn;t really need to. if (!haveShot && s.time_until_off_cd <= currentTime + 0.00001) { if (s.type == Shots.SerpentSting && chimeraRefreshesSerpent && SerpentUsed) { // do nothing for refreshed Serpent Sting except the first time } else if (s.type == Shots.KillShot && (!UseKillShot || currentTime < Sub20Time)) { // Do not use Kill Shot if Boss HP is above 20% } else if (s.type == Shots.BestialWrath && BWTime > currentTime) { // do nothing if TBW or BW is still active } else if (s.type == Shots.RapidFire && RFTime > currentTime) { // do nothing if Rapid Fire is still active } else if (BMSpec && s.type == Shots.Readiness && BWCD < (currentTime + CDCutoff)) { // Check if TBW/BW CD is nearly up if we want to use Rapid Fire } else if (s.type == Shots.Readiness && RFCD < (currentTime + CDCutoff)) { // Wait for Rapid Fire if it's close too } else if (s.type == Shots.SerpentSting && FightDuration - currentTime < s.cooldown) { // do nothing if Rapid Fire is about to come off CD // do nothing if we don't get all the ticks of Serpent Sting anyway } else if (s.type == Shots.BlackArrow && FightDuration - currentTime < BA) { // ditto for Black Arrow } else if (s.type == Shots.BestialWrath && !BMSpec) { // do nothing } else { thisShot = s.type; haveShot = true; } } } } #endregion #region Execute shot if (!haveShot) { // If no shot, advance 100 ms // This case should almost never happen unless Steady Shot isn't in the rotation currentTime += 0.1f; //Debug.WriteLine("no shot found - advancing time to "+currentTime); } else { float currentAutoShotSpeed; currentAutoShotSpeed = AutoShotSpeed; RotationShotInfo thisShotInfo = shotData[thisShot]; if (thisShotInfo.type == Shots.SerpentSting && !SerpentUsed) { SerpentUsed = true; } // Adjust AutoShot Speed if Rapid Fire is active if (RFTime > currentTime) { currentAutoShotSpeed *= 0.6f; } // Adjust AutoShotSpeed if IAotH is active /*if (IAotHDuration - currentTime > 0) * { * currentAutoShotSpeed *= (1f / IAotHEffect); * }*/ // Check if we had an auto shot since the last check if (currentTime - LastAutoShotCheck > currentAutoShotSpeed) { // ******************************************************* // 021109 Drizz: Added if around LastAutoShotCheck, Updated from v92b (spreadsheet) if (currentTime == 0) { LastAutoShotCheck = currentTime; } else { LastAutoShotCheck += currentAutoShotSpeed; } // ******************************************************* // 021109 Drizz: Updating to use "LastAutoShotCheck" instead of currentTime (Align with v92b) if (RandomProcs) { // 10% proc chance if (randomProc(IAotHChance)) { if (IAotHDuration - LastAutoShotCheck < 0) { // No IAotH proc active IAotHUptime = IAotHUptime + 12; } else { IAotHUptime = IAotHUptime - (IAotHDuration - LastAutoShotCheck) + 12; } IAotHDuration = LastAutoShotCheck + 12; IAotHProcs = IAotHProcs + 1; } } else if (IAotHChance > 0) { IAotHfix = IAotHfix + 1; if (IAotHfix * IAotHChance > 100) { IAotHfix = 0; // reset counter if (IAotHDuration - LastAutoShotCheck < 0) { // No IAotH proc active IAotHUptime = IAotHUptime + 12; } else { IAotHUptime = IAotHUptime - (IAotHDuration - LastAutoShotCheck) + 12; } IAotHDuration = LastAutoShotCheck + 12; IAotHProcs = IAotHProcs + 1; } } } // count shots currentShot++; // advance row on the test page //row++ thisShotInfo.countUsed++; // Determine Steady Shot haste float SShaste = 1f; if (RFTime > currentTime) { SShaste *= 1.4f; } //if (IAotHDuration > currentTime) SShaste *= IAotHEffect; // Increment cooldown on the shot just fired if (thisShot == Shots.SteadyShot && thisShotInfo.castTime * (1f / SShaste) < GCD + Latency) { thisShotInfo.time_until_off_cd = currentTime + GCD + Latency; } else if (thisShot == Shots.SteadyShot) { thisShotInfo.time_until_off_cd = currentTime + thisShotInfo.castTime * (1f / SShaste) + Latency; } else if (checkGCD(thisShot)) { thisShotInfo.time_until_off_cd = currentTime + thisShotInfo.cooldown + Latency; } else { // Shots that are off the GCD do not incur latency thisShotInfo.time_until_off_cd = currentTime + thisShotInfo.cooldown; } // Note down shot current time and shot used // 091109 Drizz: If we now can get the debug info within Rawr, no need to go by debug option. /*if (calculatedStats.collectSequence) * { * float timeUsed = 0; * float castEnd = currentTime; * float onCDUntil = currentTime + thisShotInfo.cooldown; * * // Note down cast time used, cast end time and time till CD * if (!checkGCD(thisShot)) * { * // These do not cost time * // (we set these values just above) * } * else * { * // Steady Shot can fire faster than GCD so check * if (thisShot == Shots.SteadyShot) * { * timeUsed = thisShotInfo.castTime * (1 / SShaste) + Latency; * castEnd = currentTime + thisShotInfo.castTime * (1 / SShaste) + Latency; * } * //else if (thisShot == Shots.Volley) * //{ * // timeUsed = thisShotInfo.castTime + Latency; * // castEnd = currentTime + thisShotInfo.castTime + Latency; * //} * else * { * // Other shots fire at GCD + Latency * timeUsed = GCD + Latency; * castEnd = currentTime + GCD + Latency; * } * onCDUntil = thisShotInfo.time_until_off_cd; * } * // 091109 Drizz: Removing the Debug.Writeline * //Debug.WriteLine(" "+ currentTime + ": " + thisShot + " (" +timeUsed+"/"+castEnd+"/"+onCDUntil + ")"); * calculatedStats.sequence += String.Format("{0,6:0.00}:{1,-13}" + " : {2,7:0.000}:{3,7:0.000}:{4,7:0.000}", currentTime, thisShot, timeUsed, castEnd, onCDUntil) + Environment.NewLine; #if !RAWR3 && !RAWR4 && !SILVERLIGHT * Debug.Flush(); #endif * } */ // Set L&L Timer after Black Arrow/Immolation Trap was used if (thisShot == Shots.BlackArrow || thisShot == Shots.ImmolationTrap || thisShot == Shots.ExplosiveTrap || thisShot == Shots.FreezingTrap || thisShot == Shots.IceTrap) { switch (thisShot) { case Shots.BlackArrow: { LALTimer = currentTime + BA; break; } case Shots.ImmolationTrap: { LALTimer = currentTime + it; break; } case Shots.ExplosiveTrap: { LALTimer = currentTime + et; break; } case Shots.FreezingTrap: { LALTimer = currentTime + ft; break; } default: { LALTimer = currentTime + frt; break; } // Shots.IceTrap } LALType = thisShot; LastLALCheck = currentTime - 3; } if (currentTime + thisShotInfo.cooldown > ElapsedTime) { if (thisShotInfo.cooldown < GCD + Latency) { ElapsedTime = currentTime + GCD + Latency; } else { ElapsedTime = currentTime + thisShotInfo.cooldown; } } // If we have Improved Steady Shot and have just cast Steady Shot if (ISSTalent > 0 && thisShot == Shots.SteadyShot) { if (RandomProcs) { if (randomProc(ISSTalent)) { ISSDuration = currentTime + 12; } } else if (ISSTalent > 0) { ISSfix++; if (ISSfix * ISSTalent > 100) { ISSfix = 0; ISSDuration = currentTime + 12; } } } if (ISSDuration > currentTime) { if (thisShot == Shots.AimedShot) { ISSprocsAimed++; ISSDuration = -1; //Cells(row, col + 5).value = Cells(row, col + 5).value + "(ISS proc)" } else if (thisShot == Shots.ArcaneShot) { ISSProcsArcane++; ISSDuration = -1; //Cells(row, col + 5).value = Cells(row, col + 5).value + "(ISS proc)" } else if (thisShot == Shots.ChimeraShot) { ISSProcsChimera++; ISSDuration = -1; //Cells(row, col + 5).value = Cells(row, col + 5).value + "(ISS proc)" } } // If we used Explosive Shot, set the duration of the debuff if (thisShot == Shots.ExplosiveShot && LALShots > 0) { LALDuration = currentTime + 2; } // If we used Explosive Shot, set Arcane Shot on CD as well and likewise if (thisShot == Shots.ArcaneShot && shotData.ContainsKey(Shots.ExplosiveShot)) { shotData[Shots.ExplosiveShot].time_until_off_cd = currentTime + shotData[Shots.ExplosiveShot].cooldown + Latency; } if (thisShot == Shots.ExplosiveShot && shotData.ContainsKey(Shots.ArcaneShot)) { shotData[Shots.ArcaneShot].time_until_off_cd = currentTime + shotData[Shots.ArcaneShot].cooldown + Latency; } // If we used Multi-Shot set Aimed Shot cooldown as well and vice-versa if (thisShot == Shots.MultiShot && shotData.ContainsKey(Shots.AimedShot)) { shotData[Shots.AimedShot].time_until_off_cd = currentTime + shotData[Shots.AimedShot].cooldown + Latency; } if (thisShot == Shots.AimedShot && shotData.ContainsKey(Shots.MultiShot)) { shotData[Shots.MultiShot].time_until_off_cd = currentTime + shotData[Shots.MultiShot].cooldown + Latency; } // If Black Arrow is active (LALTimer) do check a proc every 3 seconds and if no LAL proc has occured within the last 22 seconds if (LALTimer > currentTime && currentTime - LastLALCheck > 3 && LALDuration < currentTime && currentTime - LastLALProc > 22) { if (RandomProcs) { // And currentTime - LastLALProc > 30 Then --- currently no ICD if (randomProc(LALChance)) { //L&L procs LALShots = 3; LastLALProc = currentTime; LALProcs++; //Cells(row, col + 5).value = Cells(row, col + 5).value + "(Proc L&L after this shot)" } } else if (LALChance > 0) { LALfix++; if (LALfix * LALChance > 100) { //L&L procs LALShots = 3; LastLALProc = currentTime; LALProcs++; //Cells(row, col + 5).value = /Cells(row, col + 5).value + "(Proc L&L after this shot)" LALfix = 0; } } LastLALCheck = currentTime; } // If we used Beast Within, set duration to 18 seconds if (thisShot == Shots.BestialWrath) { BWTime = currentTime + 10; // also record the time when it comes off CD BWCD = thisShotInfo.time_until_off_cd; } // If we used Volley, set duration to 6 seconds //if (thisShot == Shots.Volley) //{ // VolleyTime = currentTime + thisShotInfo.castTime; // // also record the time when it comes off CD // VLYCD = thisShotInfo.time_until_off_cd; //} if (thisShot == Shots.RapidFire) { RFTime = currentTime + 15; // also record the time when it comes off CD RFCD = thisShotInfo.time_until_off_cd; } // If Readiness is used, reset CD on other shots if (thisShot == Shots.Readiness) { // Reset everything but Readiness and Serpent Sting and TBW for (int i = 0; i < shotTable.Length; i++) { RotationShotInfo s = shotTable[i]; if (s != null) { if (s.type != Shots.Readiness && s.type != Shots.SerpentSting && s.type != Shots.BestialWrath) { s.time_until_off_cd = 0; } } } } if (LALTimer > currentTime) { //Cells(row, col + 5).value = "(" & LALType & ") " + Cells(row, col + 5).value } // Advance time by 0 if the shot is off the GCD, otherwise by GCD+Latency if (!checkGCD(thisShot)) { // do nothing } else if (thisShot == Shots.SteadyShot && thisShotInfo.castTime * (1f / SShaste) < GCD + Latency) { currentTime += GCD + Latency; } else if (thisShot == Shots.SteadyShot) { currentTime += thisShotInfo.castTime * (1f / SShaste) + Latency; //} else if (thisShot == Shots.Volley) { // currentTime += thisShotInfo.castTime + Latency; } else { currentTime += GCD + Latency; } // more here... } #endregion }while (currentTime < FightDuration - 1); #endregion #region Save Results foreach (var pair in shotData) { pair.Value.frequency = pair.Value.countUsed > 0 ? currentTime / pair.Value.countUsed : 0; } for (int i = 0; i < calculatedStats.priorityRotation.priorities.Length; i++) { ShotData s = calculatedStats.priorityRotation.priorities[i]; if (s != null) { s.setFrequency(calculatedStats.priorityRotation, shotData.ContainsKey(s.Type) ? shotData[s.Type].frequency : 0); } } this.TestTimeElapsed = currentTime; this.ISSProcsAimed = ISSprocsAimed; this.ISSProcsArcane = ISSProcsArcane; this.ISSProcsChimera = ISSProcsChimera; this.IAotHProcs = IAotHProcs; this.IAotHTime = IAotHUptime; this.LALProcCount = LALProcs; this.IAotHUptime = this.TestTimeElapsed > 0 ? 1.0f * this.IAotHTime / this.TestTimeElapsed : 0; this.ISSAimedUptime = this.ISSProcsAimed > 0 ? 1.0f * this.ISSProcsAimed / shotData[Shots.AimedShot].countUsed : 0; this.ISSArcaneUptime = this.ISSProcsArcane > 0 ? 1.0f * this.ISSProcsArcane / shotData[Shots.ArcaneShot].countUsed : 0; this.ISSChimeraUptime = this.ISSProcsChimera > 0 ? 1.0f * this.ISSProcsChimera / shotData[Shots.ChimeraShot].countUsed : 0; #endregion /* * ActiveWorkbook.Names.Add name:="RotationTestResultNames", RefersToR1C1:= _ * "='Rotation Test'!R5C7:R" & row & "C7" * ActiveWorkbook.Names.Add name:="RotationTestTable", RefersToR1C1:= _ * "='Rotation Test'!R5C6:R" & row & "C" & col + 5 */ }
private Shots compareDamage(Shots shot1, Shots shot2, float time) { // This function determines whether waiting for {shot1} for {time} seconds produces more dps than using {shot2} right now if (shot1 == Shots.None) return Shots.None; if (shot2 == Shots.None) return Shots.None; if (time <= 0) return Shots.None; float shot1damage = shotData.ContainsKey(shot1) ? shotData[shot1].damage : 0; float shot2damage = shotData.ContainsKey(shot2) ? shotData[shot2].damage : 0; float frac = (float)Math.Round(time / 1.5f, 3); if (shot1damage - shot2damage > shot2damage * frac) return shot1; return shot2; }
protected RotationShot createRotationShot(Shots type) { RotationShot shot = new RotationShot(); switch (type) { case Shots.SteadyShot: //shot.casttime = (calculatedStats.SteadySpeed < 1.5 ? 1.5 : calculatedStats.SteadySpeed) + options.Latency; shot.cooldown = 0.0; shot.type = Shots.SteadyShot; break; case Shots.SerpentSting: shot.casttime = 1.5 + options.Latency; shot.cooldown = 15.0; shot.type = Shots.SerpentSting; break; case Shots.MultiShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 10.0; shot.type = Shots.MultiShot; break; case Shots.ExplosiveShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 6.0; shot.type = Shots.ExplosiveShot; break; //case Shots.ChimeraShot_Serpent: // shot.casttime = 1.5 + options.Latency; // shot.cooldown = 10.0; // shot.type = Shots.ChimeraShot_Serpent; // break; case Shots.ArcaneShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 6.0; shot.type = Shots.ArcaneShot; break; case Shots.AimedShot: shot.casttime = 1.5 + options.Latency; shot.cooldown = 10.0; shot.type = Shots.AimedShot; break; } return shot; }
public RotationShotInfo(ShotData shot) { this.type = shot.Type; this.cooldown = shot.Cd; this.castTime = shot.Cd; this.check_gcd = shot.TriggersGCD; this.no_gcd = !shot.TriggersGCD && shot.Type != Shots.Readiness; this.damage = shot.Damage; if (shot.Type == Shots.SerpentSting) this.cooldown = shot.Duration; }
public bool containsShot(Shots aType) { for (int i=0; i<priorities.Length; i++) { if (priorities[i] != null) { if (priorities[i].Type == aType) return true; } } return false; }
public ShotData getShotInRotation(Shots aType) { for (int i = 0; i < priorities.Length; i++) { if (priorities[i] != null) { if (priorities[i].Type == aType) return priorities[i]; } } return null; }
private bool checkGCD(Shots shot) { if (shotData.ContainsKey(shot)) return shotData[shot].check_gcd; return true; }