void setLineUpsForPlayers(Replay rp, rect top, rect mid, rect bot, rect sentinelBase, rect scourgeBase) { // approximate creep spawn time int creepSpawnTime = GetFirstCreepAttackTime(rp, top, mid, bot); foreach (Team team in rp.Teams) switch (team.Type) { case TeamType.Sentinel: case TeamType.Scourge: List<int> alliedHeroes = GetListOfAlliedHeroes(team); foreach (Player p in team.Players) { location l = GetAverageLocation(p, (team.Type == TeamType.Sentinel ? sentinelBase : scourgeBase), alliedHeroes, creepSpawnTime); p.LineUpLocation = l; if (top.ContainsXY(l.x, l.y)) p.LineUp = LineUp.Top; else if (mid.ContainsXY(l.x, l.y)) p.LineUp = LineUp.Middle; else if (bot.ContainsXY(l.x, l.y)) p.LineUp = LineUp.Bottom; else p.LineUp = LineUp.JungleOrRoaming; } break; } }
location GetAverageLocation(Player player, rect baseArea, List<int> alliedHeroes, int creepSpawnTime) { double x = 0; double y = 0; int count = 0; foreach (PlayerAction pa in player.Actions) { // if creeps were not spawned yet, then skip this action if (pa.Time < creepSpawnTime) continue; // if it's > than 3 minutes since creep spawn then stop if (pa.Time > creepSpawnTime + 180000) break; if (pa.IsValidObjects && !alliedHeroes.Contains(pa.Object1)) { // skip this action if it was performed on the base area if (baseArea.ContainsXY(pa.X, pa.Y, 800)) continue; if (x == 0 && y == 0) { x = pa.X; y = pa.Y; } else { x += pa.X; y += pa.Y; } count++; if (count > 50) break; } } x /= count; y /= count; return new location(x, y); }
int GetFirstCreepAttackTime(Replay rp, rect top, rect mid, rect bot) { List<string> dcCreeps = new List<string>(); // Sentinel creeps: // // esen - Treant // edry - Druid of the Talon dcCreeps.Add("esen"); dcCreeps.Add("edry"); // Scourge creeps: // // unec - Necromancer // ugho - Ghoul dcCreeps.Add("unec"); dcCreeps.Add("ugho"); int minCreepAttackTime = int.MaxValue; foreach (Player p in rp.Players) foreach (PlayerAction pa in p.Actions) if (pa.IsValidObjects) { string codeID1; rp.dcObjectsCodeIDs.TryGetValue(pa.Object1, out codeID1); if (codeID1 == null || dcCreeps.Contains(codeID1)) { if (top.ContainsXY(pa.X, pa.Y) || mid.ContainsXY(pa.X, pa.Y) || bot.ContainsXY(pa.X, pa.Y)) { minCreepAttackTime = Math.Min(minCreepAttackTime, pa.Time); break; // go to next player } } } return (minCreepAttackTime != int.MaxValue) ? minCreepAttackTime : 180000; // 180000 = 3 minutes (will be used in case of errors) }