/** * Mixes this brew with another (yummy!) *@param other the one to combine with *@return false if other was already in this brew, otherwise true */ public bool mix(Brew other) { // first must make sure to unmix the uncolor if (extract(other)) { for (int i = 1; i <= other.color; i <<= 1) { if ((i & other.color) != 0 && (i & color) == 0) { color |= other.color; return true; } } return false; } return false; }
/** * Extracts a brew from this one *@param other the one to extract *@return false if other was not in this */ public bool extract(Brew other) { for (int i = 1; i <= other.uncolor; i <<= 1) { if ((i & other.uncolor) != 0 && (i & color) == 0) { return false; } } color &= ~other.uncolor; return true; }
/** * Determines if we have the color *@param *@return */ public bool hasColor(Brew brew) { for (int i = 1; i <= color; i <<= 1) { if ((i & color) != 0 && (i & brew.getColor()) == 0) { return false; } } return true; }
/** * Determines whether or not this bouncer is passable *@param brew the brew we have *@return true or false */ public bool canPass(Brew brew, int x, int y, int w, int h, int px, int py, int pw, int ph) { // ensure color is correct Console.WriteLine(color + " // " + brew.getColor()); if (hasColor(brew)) { // ensure path not blocked Area area = GameplayManager.ActiveArea; int dir = atPathStart ? 1 : -1; // check obj at x,y switch (getPath(0)) { case PATH_DOWN: if (py > y && px - pw / 2 < x + w / 2 && px + pw / 2 > x - w / 2) { return false; } break; case PATH_LEFT: if (px > x && py - ph / 2 < y + h / 2 && py + ph / 2 > y - h / 2) { return false; } break; case PATH_RIGHT: if (px < x && py - ph / 2 < y + h / 2 && py + ph / 2 > y - h / 2) { return false; } break; case PATH_UP: if (py < y && px - pw / 2 < x + w / 2 && px + pw / 2 > x - w / 2) { return false; } break; } for (int i = atPathStart ? 0 : path.Count - 1; atPathStart ? (i < path.Count) : (i >= 0); i += dir) { if (path[i] == PATH_UP * dir) { y -= Area.TILE_HEIGHT; } else if (path[i] == PATH_DOWN * dir) { y += Area.TILE_HEIGHT; } else if (path[i] == PATH_LEFT * dir) { x -= Area.TILE_WIDTH; } else if (path[i] == PATH_RIGHT * dir) { x += Area.TILE_WIDTH; } // check obj at x,y if (area.objectAt(x, y, w, Area.TILE_HEIGHT-2, false)) { return false; } } } else { return false; } return true; }
/** * Returns objects new x,y that you can interact with * @param x * @param y * @param w * @param h * @param brwe * @return */ public List<PuzzleObject> getPuzzleObjects(int x, int y, int w, int h, Brew brew) { List<PuzzleObject> objs = new List<PuzzleObject>(); List<int> locs = new List<int>(); locs.Add(x+y*WIDTH_IN_TILES); List<int> toCheck = new List<int>(); List<int> toCheck2 = new List<int>(); // bfs for (int i = 0; i < locs.Count; i++) { int curX = locs[i] % WIDTH_IN_TILES; int curY = locs[i] / WIDTH_IN_TILES; // check to make sure can pass through tile if (TileSet.tileInfos[Tiles[curX, curY]].passable) { // check if doodad at location bool doodadAt = false; for (int j = 0; j < GameObjects.Count; j++) { if (((ICollidable)GameObjects[j]).getCollider().Bounds.IntersectsWith(new DoubleRect(curX*TILE_WIDTH + (TILE_WIDTH-w) / 2, curY*TILE_HEIGHT + (TILE_HEIGHT-h) / 2, w, h))) { // if puzzle object, then add to list if (((ICollidable)GameObjects[j]).getCollider().m_type == ColliderType.NPC) { CharacterController npc = (CharacterController)GameObjects[j]; if (npc.bouncer != null && npc.bouncer.hasColor(brew)) { toCheck.Add(j); toCheck2.Add(i); } if (npc.brew != null && ((Brew)brew.copy()).mix(npc.brew)) { objs.Add(npc.brew); } } doodadAt = true; break; } } if (!doodadAt) { // add adjacent locs if (curX > 0 && !locs.Contains(locs[i] - 1)) { locs.Add(locs[i] - 1); } if (curX < WIDTH_IN_TILES - 1 && !locs.Contains(locs[i] + 1)) { locs.Add(locs[i] + 1); } if (curY > 0 && !locs.Contains(locs[i]-WIDTH_IN_TILES)) { locs.Add(locs[i]-WIDTH_IN_TILES); } if (curY < HEIGHT_IN_TILES - 1 && !locs.Contains(locs[i] + WIDTH_IN_TILES)) { locs.Add(locs[i] + WIDTH_IN_TILES); } } } } for (int j = 0; j < toCheck.Count; j++) { CharacterController npc = (CharacterController)GameObjects[toCheck[j]]; int i = toCheck2[j]; // make sure can reach spot that isn't part of path List<int> spots = new List<int>(); if (locs[i] % Area.WIDTH_IN_TILES > 0 && !objectAt(1 + Area.TILE_WIDTH * ((locs[i] - 1) % Area.WIDTH_IN_TILES) + (w) / 2, 1 + Area.TILE_HEIGHT * ((locs[i] - 1) / Area.WIDTH_IN_TILES) + (h) / 2, w / 2, h / 2, true)) { spots.Add(locs[i] - 1); } if (locs[i] % Area.WIDTH_IN_TILES < Area.WIDTH_IN_TILES - 1 && !objectAt(1 + Area.TILE_WIDTH * ((locs[i] + 1) % Area.WIDTH_IN_TILES) + (w) / 2, 1 + Area.TILE_HEIGHT * ((locs[i] + 1) / Area.WIDTH_IN_TILES) + (h) / 2, w / 2, h / 2, true)) { spots.Add(locs[i] + 1); } if (locs[i] / Area.WIDTH_IN_TILES > 0 && !objectAt(1 + Area.TILE_WIDTH * ((locs[i] - Area.WIDTH_IN_TILES) % Area.WIDTH_IN_TILES) + (w) / 2, 1 + Area.TILE_HEIGHT * ((locs[i] - Area.WIDTH_IN_TILES) / Area.WIDTH_IN_TILES) + (h) / 2, w / 2, h / 2, true)) { spots.Add(locs[i] - Area.WIDTH_IN_TILES); } if (locs[i] / Area.WIDTH_IN_TILES < Area.HEIGHT_IN_TILES - 1 && !objectAt(1 + Area.TILE_WIDTH * ((locs[i] + Area.WIDTH_IN_TILES) % Area.WIDTH_IN_TILES) + (w) / 2, 1 + Area.TILE_HEIGHT * ((locs[i] + Area.WIDTH_IN_TILES) / Area.WIDTH_IN_TILES) + (h) / 2, w / 2, h / 2, true)) { spots.Add(locs[i] + Area.WIDTH_IN_TILES); } switch (npc.bouncer.getPath(0)) { case Bouncer.PATH_DOWN: spots.Remove(locs[i] + Area.WIDTH_IN_TILES); break; case Bouncer.PATH_LEFT: spots.Remove(locs[i] - 1); break; case Bouncer.PATH_RIGHT: spots.Remove(locs[i] + 1); break; case Bouncer.PATH_UP: spots.Remove(locs[i] - Area.WIDTH_IN_TILES); break; } for (int k = 0; k < spots.Count; k++) { if (locs.Contains(spots[k])) { objs.Add(npc.bouncer); break; } } } return objs; }