/// <summary> /// Manages split requests /// </summary> public void Split(int CubeUid, double x, double y) { // Check if a split team exists if (!SplitCubeUids.ContainsKey(CubeUid)) { // Check if the cube is big enough to split if (Cubes[CubeUid].Mass < MIN_SPLIT_MASS) { return; } // Set up a split team Cubes[CubeUid].Team_ID = CubeUid; SplitCubeUids[CubeUid] = new Dictionary <int, SplitCubeData>(); SplitCubeUids[CubeUid][CubeUid] = new SplitCubeData(Cubes[CubeUid].loc_y, Cubes[CubeUid].loc_y, 0); } List <int> temp = new List <int>(SplitCubeUids[CubeUid].Keys); foreach (int uid in temp) { if (SplitCubeUids[CubeUid].Count >= MAX_SPLIT_COUNT) { continue; } double mass = Cubes[uid].Mass; if (mass < MIN_SPLIT_MASS) { continue; } // Halve the mass of the original cube, create a new cube Cubes[uid].Mass = mass / 2; // Get the directional vector double xx = x - Cubes[uid].loc_x; double yy = y - Cubes[uid].loc_y; UnitVector(ref xx, ref yy); // For use in putting into SplitCubeUids at the very bottom of this method. This is the direction vector the cube needs to keep going double xxx = xx; double yyy = yy; // Get a starting position for the cube that isn't right in the center of the original cube and is in the direction that it needs to go. xx = Cubes[uid].loc_x + (xx * Cubes[uid].width / 2); yy = Cubes[uid].loc_y + (yy * Cubes[uid].width / 2); Cube newCube = new Cube(xx, yy, GetUid(), false, Cubes[CubeUid].Name, mass / 2, Cubes[CubeUid].argb_color, CubeUid); // Add the new cube to the world Cubes.Add(newCube.uid, newCube); SplitCubeUids[CubeUid][newCube.uid] = new SplitCubeData(xxx, yyy, (int)(MAX_SPLIT_DISTANCE * Math.Pow(10 * mass, .05))); } }
/// <summary> /// Manages splitting when hit a virus /// </summary> public void VirusSplit(int CubeUid, double x, double y) //BUG! SOMETIMES LOSES TRACK OF A CUBE { Cube cube = Cubes[CubeUid]; // If the cube's team id is not yet set and tracked in SplitCubeUids, set it up (because the cube is about to split) if (!SplitCubeUids.ContainsKey(cube.Team_ID)) { Cubes[CubeUid].Team_ID = CubeUid; SplitCubeUids[CubeUid] = new Dictionary <int, SplitCubeData>(); SplitCubeUids[CubeUid][CubeUid] = new SplitCubeData(cube.loc_x, cube.loc_y, 0); } // Store the team id, and number of split cubes int teamID = cube.Team_ID; int numSplitCubes = SplitCubeUids[teamID].Count; // If at max split count, just add on virus mass and return if (numSplitCubes >= this.MAX_SPLIT_COUNT) { cube.Mass += VIRUS_MASS; return; } // Store the original cube mass double mass = cube.Mass; // Find the number of split cubes to make int maxSplits = (int)(mass / PLAYER_START_MASS); int numSplits = (maxSplits > MAX_SPLIT_COUNT - numSplitCubes) ? MAX_SPLIT_COUNT - numSplitCubes + 1 : maxSplits + 1; // +1 to account for reassigning original cube // Find the leftover mass (if all split cubes get the player starting mass) double leftoverMass = mass - (numSplits * PLAYER_START_MASS); // Generate all but the last split cube (the last will 'replace' the original later) while (numSplits > 1) { Cube newCube = GenerateSplitCube(ref numSplits, ref leftoverMass, teamID, CubeUid, x, y); double xx = newCube.loc_x - cube.loc_x; double yy = newCube.loc_y - cube.loc_y; UnitVector(ref xx, ref yy); // Add the new cube in to the world and the split set, and adjust its position Cubes.Add(newCube.uid, newCube); SplitCubeUids[teamID][newCube.uid] = new SplitCubeData(xx, yy, MAX_SPLIT_DISTANCE); AdjustPosition(newCube.uid); } // Alter the original cube to be a split cube now Cube replacement = GenerateSplitCube(ref numSplits, ref leftoverMass, teamID, CubeUid, x, y); cube.Mass = replacement.Mass; cube.loc_x = replacement.loc_x; cube.loc_y = replacement.loc_y; AdjustPosition(cube.uid); }