public addStackEvts ( List |
||
stackPaths | List |
|
nSeeUnits | int | |
return | void |
public override void apply(Sim g) { Dictionary<Path, List<Unit>> exPaths = existingPaths (g); List<Path> movedPaths = new List<Path> { g.paths[stackPath] }; // move paths to final location of stackPath // related to ISSUE #20: if stackPathVal < 0 (pressing stack button will do that) then move all paths to their average location foreach (KeyValuePair<Path, List<Unit>> path in exPaths) { if (path.Key.speed == g.paths[stackPath].speed && path.Key.canMove (timeCmd, path.Value) && !movedPaths.Contains (path.Key)) { movedPaths.Add (path.Key.moveTo (timeCmd, new List<Unit>(path.Value), g.paths[stackPath].moves.Last ().vecEnd, autoTimeTravel)); } } // if able to move any of the paths, add events to stack them as they arrive g.addStackEvts (movedPaths, nSeeUnits); }
public override void apply(Sim g) { Dictionary<Path, List<Unit>> exPaths = existingPaths (g); List<List<Path>> formationOrder = new List<List<Path>>(); List<int> nSeeUnits = new List<int>(); FP.Vector goal, rows = new FP.Vector(), offset = new FP.Vector(); long spacing = 0; // order paths in formation foreach (KeyValuePair<Path, List<Unit>> path in exPaths) { if (path.Key.canMove(timeCmd, path.Value)) { int i; for (i = 0; i < formationOrder.Count; i++) { if (path.Key.moves.Last ().vecEnd.x == formationOrder[i][0].moves.Last ().vecEnd.x && path.Key.moves.Last ().vecEnd.y == formationOrder[i][0].moves.Last ().vecEnd.y) { SimEvt evt = g.events.FindLast (e => e is StackEvt && (e as StackEvt).paths.Contains (path.Key) && formationOrder[i].Find (p => (e as StackEvt).paths.Contains (p)) != null); if (evt != null) { // path is trying to stack onto another commanded path formationOrder[i].Add (path.Key); nSeeUnits[i] = (evt as StackEvt).nSeeUnits; break; } } } if (i == formationOrder.Count) { // path isn't trying to stack onto another commanded path formationOrder.Add (new List<Path> { path.Key }); nSeeUnits.Add (int.MaxValue); } if (formation == Formation.Tight) { // calculate spacing for tight formation foreach (Unit unit in path.Value) { if (unit.type.tightFormationSpacing > spacing) spacing = unit.type.tightFormationSpacing; } } } } if (formationOrder.Count == 0) return; // calculate spacing // (if tight formation, then spacing was already calculated above) // ISSUE #28: loose formation should be triangular if (formation == Formation.Loose) { spacing = FP.mul(g.visRadius, FP.sqrt2) >> FP.precision << FP.precision; } else if (formation == Formation.Ring) { spacing = (g.visRadius * 2 >> FP.precision) - 1 << FP.precision; } if (formation == Formation.Tight || formation == Formation.Loose) { rows.x = FP.sqrt(formationOrder.Count); rows.y = (formationOrder.Count - 1) / rows.x + 1; offset = (rows - new FP.Vector(1, 1)) * spacing / 2; } else if (formation == Formation.Ring) { offset.x = (formationOrder.Count == 1) ? 0 : FP.div(spacing / 2, FP.sin(FP.pi / formationOrder.Count)); offset.y = offset.x; } else { throw new NotImplementedException("requested formation is not implemented"); } if (pos.x < Math.Min(offset.x, g.mapSize / 2)) pos.x = Math.Min(offset.x, g.mapSize / 2); if (pos.x > g.mapSize - Math.Min(offset.x, g.mapSize / 2)) pos.x = g.mapSize - Math.Min(offset.x, g.mapSize / 2); if (pos.y < Math.Min(offset.y, g.mapSize / 2)) pos.y = Math.Min(offset.y, g.mapSize / 2); if (pos.y > g.mapSize - Math.Min(offset.y, g.mapSize / 2)) pos.y = g.mapSize - Math.Min(offset.y, g.mapSize / 2); // move units for (int i = 0; i < formationOrder.Count; i++) { List<Path> movedPaths = new List<Path>(); foreach (Path path in formationOrder[i]) { if (formation == Formation.Tight || formation == Formation.Loose) { goal = pos + new FP.Vector((i % rows.x) * spacing - offset.x, i / rows.x * spacing - offset.y); } else if (formation == Formation.Ring) { goal = pos + offset.x * new FP.Vector(FP.cos(2 * FP.pi * i / formationOrder.Count), FP.sin(2 * FP.pi * i / formationOrder.Count)); } else { throw new NotImplementedException("requested formation is not implemented"); } movedPaths.Add (path.moveTo(timeCmd, new List<Unit>(exPaths[path]), goal, autoTimeTravel)); } g.addStackEvts (movedPaths, nSeeUnits[i]); } }