private string EnumerateSolutionIssues(int waveIndex, WaveSolution solution) { bool issuesFound = false; string issuesString = ""; WaveStats stats = WaveStatList[waveIndex]; // // Is it possible to afford this solution? // if (stats.CoinAvail < stats.CoinNeeded) { issuesFound = true; issuesString += "Can't afford at start of wave "; } // // Are all the enemies killed in simulation? // if (LevelDesc.Waves[waveIndex].Count > stats.FullSimulation.EnemiesKilled) { issuesFound = true; issuesString += "Enemies survived simulation "; } if (!issuesFound) { return("<span foreground='green'>None</span>"); } return("<span foreground='red'>" + issuesString + "</span>"); }
public bool Same(WaveSolution s) { if (s.Turrets.Count != Turrets.Count) { return(false); } for (int i = 0; i < Turrets.Count; i++) { if (Turrets[i].Name != s.Turrets[i].Name) { return(false); } if (Turrets[i].pos.x != s.Turrets[i].pos.x) { return(false); } if (Turrets[i].pos.z != s.Turrets[i].pos.z) { return(false); } } return(true); }
private WaveSolution GenerateWaveSolution() { WaveSolution sol = new WaveSolution(); for (int i = 0; i < LevelDesc.Map.Count; i++) { if (LevelDesc.Map[i] == 'T') { int turretIndex = 0; if (TurretSelections.TryGetValue(i, out turretIndex)) { WaveSolutionTurret t = new WaveSolutionTurret(); t.pos.x = (i % LevelDesc.FieldWidth); t.pos.z = (i / LevelDesc.FieldDepth); t.Name = LevelDesc.AllowedTurrets[turretIndex]; sol.Turrets.Add(t); } } } return(sol); }
private void SaveSolutionClicked(TreeIter iter) { int row = (int)WavesModel.GetValue(iter, 0); string action = (string)WavesModel.GetValue(iter, 9); if (action != "Save") { return; } WaveSolution sol = GenerateWaveSolution(); sol.WaveIndex = row; for (int i = 0; i < Solution.WaveSolutions.Count; i++) { if (Solution.WaveSolutions[i].WaveIndex == row) { Solution.WaveSolutions.RemoveAt(i); break; } } Solution.WaveSolutions.Add(sol); WriteSolution(); RecalculateAllStats(); PopulateTreeWithWaves(LevelDesc); }
public WaveSimulatorDamageStats SimulateDamageToEnemies( EnemyDescription enemy, WaveSolution solution, float HandMissileFreqency, float HandMissileDamantPctAverage, int enemyCount, bool invincible) { DamageStats = new WaveSimulatorDamageStats(); InvincibleEnemies = invincible; float waveTime = 0.0F; float timeDelta = 1.0F / 72.0F; float previousHandMissileTime = 0.0f; EnemyWave waveDesc = new EnemyWave(); waveDesc.Count = enemyCount; waveDesc.Enemy = enemy.Name; waveDesc.DifficultyMultiplier = 1.0F; ResetLevelDescState(LevelDesc); TurretManager turrets = new TurretManager(LevelDesc); ProjectileManager projectiles = new ProjectileManager(LevelDesc, LevelManager.LookupProjectile); WaveInstance wave = new WaveInstance(LevelDesc, waveDesc, enemy, 0.0F, SimulatorDamageCallback); for (int i = 0; i < solution.Turrets.Count; i++) { turrets.AddTurret(LevelManager.LookupTurret(solution.Turrets[i].Name), solution.Turrets[i].pos, projectiles); } Debug.Log("----------------------------------------"); Debug.Log(" Wave of " + enemyCount + " " + enemy.Name + "s"); Debug.Log("----------------------------------------"); do { wave.Advance(waveTime); projectiles.AdvanceAll(waveTime); turrets.Fire(waveTime); float timeSinceLastHandMissile = waveTime - previousHandMissileTime; if (timeSinceLastHandMissile >= HandMissileFreqency) { // Real projectiles have to incur flight time but we'll simulate // the damage as instanntaneous to keep it simple. Also real projectiles // have blast radius that should hit multiple enemies. We'll just hit one. } waveTime += timeDelta; } while (!wave.IsCompleted); DamageStats.DamagePerEnemy = DamageStats.DamageDealt / enemyCount; return(DamageStats); }
private void SetSolution(WaveSolution sol) { TurretSelections.Clear(); int turretCount = 0; for (int i = 0; i < LevelDesc.Map.Count; i++) { if (LevelDesc.Map[i] == 'T') { int x = i % LevelDesc.FieldWidth; int z = i / LevelDesc.FieldDepth; Button b = MapButtons[i]; bool turretMatch = false; for (int j = 0; j < sol.Turrets.Count; j++) { if ((sol.Turrets[j].pos.x == x) && (sol.Turrets[j].pos.z == z)) { TurretSelections.Add(i, AllowedTurretIndexFromName(sol.Turrets[j].Name)); // Update location on map UpdateFieldTurretButton(b, sol.Turrets[j].Name); turretCount++; turretMatch = true; } } if (!turretMatch) { UpdateFieldTurretButton(b, "None"); } } } if (turretCount != sol.Turrets.Count) { MessageDialog md = new MessageDialog(null, DialogFlags.Modal, MessageType.Warning, ButtonsType.OkCancel, "Some turret positions do not match turret slots - did the map change? Dropped the turrets that don't match."); int result = md.Run(); md.Destroy(); } RecalculateAllStats(); PopulateTreeWithWaves(LevelDesc); }
private void CalculateStatsForWaves(List <TurretStats> Turrets) { WaveStatList = new List <WaveStats>(); float maxDPSOverall = 0.0F; int coinNeeded = 0; for (int j = 0; j < Turrets.Count; j++) { maxDPSOverall += Turrets[j].MaxDPSOverall; coinNeeded += Turrets[j].t.Cost; } int maxCoinEarned = LevelDesc.StartingCoins; for (int i = 0; i < LevelDesc.Waves.Count; i++) { EnemyWave wave = LevelDesc.Waves[i]; EnemyDescription enemyDesc = LevelManager.LookupEnemy(wave.Enemy); WaveSolution solution = GenerateWaveSolution(); WaveStats stats = new WaveStats(); WaveSimulatorDamageStats singleEnemyStats = SimulateWave(enemyDesc, solution, 1, true); WaveSimulatorDamageStats fullWaveStats = SimulateWave(enemyDesc, solution, wave.Count, false); EnemyDescription enemy = LevelManager.LookupEnemy(wave.Enemy); stats.MaxDmgDealtSingleEnemy = singleEnemyStats.DamageDealt; stats.MaxDPSOverall = maxDPSOverall; stats.MaxHPPSProducted = EnemyEditLayout.CalculateDPSforWave(enemy); stats.FullSimulation = fullWaveStats; stats.CoinNeeded = coinNeeded; stats.CoinAvail = maxCoinEarned; maxCoinEarned += (enemy.Coins * wave.Count); WaveStatList.Add(stats); } }
private void PopulateTreeWithWaves(LevelDescription desc) { WavesModel.Clear(); WaveSolution currentSolution = GenerateWaveSolution(); Dictionary <int, WaveSolution> waveSolves = new Dictionary <int, WaveSolution>(); for (int i = 0; i < Solution.WaveSolutions.Count; i++) { waveSolves.Add(Solution.WaveSolutions[i].WaveIndex, Solution.WaveSolutions[i]); } for (int i = 0; i < desc.Waves.Count; i++) { string saveString = "Save"; string loadString = "n/a"; WaveSolution solution = null; if (waveSolves.TryGetValue(i, out solution)) { if (solution.Same(currentSolution)) { saveString = "n/a"; loadString = "n/a"; } else { saveString = "Save"; loadString = "Load"; } } string simDamageKills = WaveStatList[i].FullSimulation.DamagePerEnemy.ToString() + "/" + WaveStatList[i].FullSimulation.EnemiesKilled; string coinString = WaveStatList[i].CoinNeeded.ToString() + "/" + WaveStatList[i].CoinAvail.ToString(); string issues = EnumerateSolutionIssues(i, currentSolution); object[] values = { i, desc.Waves[i].Enemy, desc.Waves[i].Count, desc.Waves[i].DifficultyMultiplier, WaveStatList[i].MaxDmgDealtSingleEnemy, WaveStatList[i].MaxHPPSProducted, WaveStatList[i].MaxDPSOverall, simDamageKills, coinString, saveString, loadString, issues }; WavesModel.AppendValues(values); } }
private WaveSimulatorDamageStats SimulateWave(EnemyDescription enemy, WaveSolution solution, int enemyCount, bool invincible) { WaveSimulator sim = new WaveSimulator(LevelDesc); return(sim.SimulateDamageToEnemies(enemy, solution, HandMissileFreqency, HandMissileDamantPctAverage, enemyCount, invincible)); }