/* Builds walls for individual exterior cell */ public void BuildWalls(HoloCell c) { if (c.cell == null) { return; } int x = c.cell.x; int y = c.cell.y; List <int[]> sides = new List <int[]>(); // neighboring coordinates sides.Add(new int[] { x + 1, y }); sides.Add(new int[] { x - 1, y }); sides.Add(new int[] { x, y + 1 }); sides.Add(new int[] { x, y - 1 }); Session s = Session.session; for (int i = 0; i < sides.Count; i++) { bool needWall = !Loaded(sides[i][0], sides[i][1]); if (needWall) { c.BuildWall(i); } } }
/* Instantiates a cell to the correct position, adds it to cells, * and returns it. */ HoloCell AddExteriorCell(int x, int y) { HoloCell hc = new HoloCell(GridPosition(x, y), this); cells.Add(hc); return(hc); }
/* Shifts the position of cells such that the cells closest to the destination * are moved first, averting cells merging contents.*/ void PositionShift(Vector3 dir) { List <HoloCell> cs = new List <HoloCell>(cells); List <HoloCell> sorted = new List <HoloCell>(); Vector3 dest = focalCell.position + 10 * dir; // Points in direction of movement. while (cs.Count > 0) { HoloCell min = cs[0]; for (int i = 1; i < cs.Count; i++) { float mdist = Vector3.Distance(dest, min.position); float cdist = Vector3.Distance(dest, cs[i].position); if (cdist < mdist) { min = cs[i]; } } cs.Remove(min); sorted.Add(min); } for (int i = 0; i < sorted.Count; i++) { sorted[i].Move(dir); } }
/* Clears the contents of all HoloCells and deletes them. */ public void ClearContents() { for (int i = 0; i < cells.Count; i++) { cells[i].Clear(); } cells = new List <HoloCell>(); focalCell = null; }
/* Compares two Cells using GridAdjacency. */ bool CellAdjacency(HoloCell a, HoloCell b) { int DISTANCE = 150; // Distance between two cells, allowing corners. float dist = Vector3.Distance(a.position, b.position); if (dist < DISTANCE) { return(true); } return(false); }
/* Returns the deck this position is in, or null */ public HoloCell GetCell(Vector3 pos) { for (int i = 0; i < decks.Count; i++) { HoloCell hc = decks[i].ContainingCell(pos); if (hc != null) { return(hc); } } return(null); }
/* Returns the relative 3x3 grid position of a cell to a center cell.*/ int[] GridRelation(HoloCell center, HoloCell other) { int[] ret = new int[2]; if (center.cell == null || other.cell == null) { return(null); } ret[0] = other.cell.x - center.cell.x; ret[1] = other.cell.y - center.cell.y; ret[0] += 1; // This pushes the grid from [-1,1] to [0,2] ret[1] += 1; return(ret); }
/* Re-centers the holodeck around the player's location, pruning * HoloCells that are not adjacent whilst loading any additional adjacent * HoloCells. */ public void ShiftExterior() { HoloCell fc = focalCell; focalCell = ContainingCell(players[0].transform.position); ClearWalls(); Prune(); Expand(); Vector3 dir = transform.position - focalCell.position; PositionShift(dir); BuildWalls(); }
/* Returns the cell that contains this pos, or null. */ public HoloCell ContainingCell(Vector3 pos) { float DISTANCE = 50; for (int i = 0; i < cells.Count; i++) { HoloCell hc = cells[i]; if (hc.Contains(pos)) { return(hc); } } return(null); }
/* Loads any unloaded adjacent cells. */ void Expand() { List <int[]> neighbors = Adjacencies(focalCell.cell.x, focalCell.cell.y); for (int i = 0; i < neighbors.Count; i++) { int[] ne = neighbors[i]; if (!Loaded(ne[0], ne[1])) { int[] fr = FocalRelation(ne[0], ne[1]); HoloCell hc = AddExteriorCell(fr[0], fr[1]); Cell c = Session.session.world.GetExterior(ne[0], ne[1]); hc.LoadData(c); } } }
/* Loads a given interior cell. */ public void LoadInterior(Cell c, int door, bool saveFirst) { SavePlayers(); if (saveFirst && interior) { SaveInterior(); } else if (saveFirst) { SaveExterior(); } ClearContents(); cells.Add(new HoloCell(transform.position, this)); focalCell = cells[0]; focalCell.LoadData(c, door); LoadPlayers(); interior = true; }
/* Removes all non-adjacent Cells. */ void Prune() { List <HoloCell> orphans = new List <HoloCell>(); for (int i = 0; i < cells.Count; i++) { HoloCell hc = cells[i]; if (!CellAdjacency(focalCell, hc)) { Session.session.world.SetExterior(hc.GetData()); hc.Clear(); orphans.Add(hc); } } for (int i = 0; i < orphans.Count; i++) { cells.Remove(orphans[i]); } }
/* Recenters the HoloDeck on specified exterior and loads relevant cells. * This is called as the result of a warp door being used. */ public void LoadExterior( int x, int y, int door, bool saveFirst ) { SavePlayers(); if (saveFirst && interior) { SaveInterior(); } else if (saveFirst) { SaveExterior(); } ClearContents(); interior = false; for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { int cx = x - 1 + i; int cy = y - 1 + j; Cell c = Session.session.world.GetExterior(cx, cy); HoloCell hc = AddExteriorCell(i, j); if (i == 1 && j == 1) { hc.LoadData(c, door); focalCell = hc; } else { hc.LoadData(c); } } } LoadPlayers(); interior = false; BuildWalls(); }