public void Update(MouseButtonState buttonState, Vector2 mousePos, PlatformCharacter shooter, List <PlatformObject> allObjects, List <Projectile> projectiles) { if (buttonState == null) { return; } if (buttonState.justPressed) { foreach (PlatformObject p in allObjects) { if (p is ChemBlock && p.bounds.Contains(mousePos)) { clicked = (ChemBlock)(p as ChemBlock).GetPrimaryBlock(); clickedOffset = mousePos - clicked.pos; break; } } } else if (buttonState.justReleased) { clicked = null; } if (clicked != null) { Vector2 offset = mousePos - (clicked.pos + clickedOffset); clicked.velocity = offset; } }
public Vector2 GetCorrection(ChemBlock block) { Point gridPos = blocks[block]; Vector2 origin = GetOrigin(); return(new Vector2(origin.X + gridPos.X * Game1.BLOCKSIZE - block.pos.X, origin.Y + gridPos.Y * Game1.BLOCKSIZE - block.pos.Y)); }
public override void Update(InputState input, List <PlatformObject> allObjects, List <Projectile> projectiles) { Vectangle myBounds = bounds; foreach (PlatformObject obj in allObjects) { if (obj is ChemBlock && !obj.destroyed && myBounds.Intersects(obj.bounds)) { ChemBlock block = obj as ChemBlock; /*if (!block.chemGrid.IsInside(myBounds)) * continue; */ if (signature != block.chemGrid.GetSignature()) { continue; } Game1.instance.platformLevel.Record(sellAction, sellPrice); block.chemGrid.DestroyAll(); Game1.instance.platformLevel.UpdateAnyBlocksLeft(); } } }
public ChemGrid(ChemBlock solo) { blocks = new Dictionary <ChemBlock, Point> { { solo, Point.Zero } }; horizontalBonds = new HashSet <Point>(); verticalBonds = new HashSet <Point>(); }
public void Destroy(ChemBlock block) { Point p = blocks[block]; horizontalBonds.Remove(p); verticalBonds.Remove(p); horizontalBonds.Remove(new Point(p.X + 1, p.Y)); verticalBonds.Remove(new Point(p.X, p.Y + 1)); blocks.Remove(block); UpdateConnectivity(); }
public void Update(List <PlatformObject> allObjects) { pos += velocity; Point windowSize = Game1.instance.Window.ClientBounds.Size; if (pos.X < 0 || pos.Y < 0 || windowSize.X < pos.X || windowSize.Y < pos.Y) { destroyed = true; } PlatformObject collisionObj = null; foreach (PlatformObject obj in allObjects) { if (CanCollide(obj) && obj.bounds.Contains(pos)) { collisionObj = obj; } } if (collisionObj == null) { return; } destroyed = true; const float VELOCITY_TRANSFER = 0.2f; // hit this thing switch (action) { case ProjectileAction.RIVET: if (collisionObj is ChemBlock) { ChemBlock body = (ChemBlock)collisionObj; //Vector2 nailDirection = velocity; //nailDirection.Normalize(); body.Nailed(Vector2.Zero - GetCollisionNormal(collisionObj.bounds, pos - velocity, pos)); body.velocity += velocity * VELOCITY_TRANSFER; body.UpdatedVelocity(); } break; case ProjectileAction.BUBBLE: SpawnBubble(collisionObj, pos, GetCollisionNormal(collisionObj.bounds, pos - velocity, pos), allObjects); break; } }
public void Cut(Vectangle area, List <PlatformObject> objects) { HashSet <ChemGrid> gridsChecked = new HashSet <ChemGrid>(); foreach (PlatformObject obj in objects) { ChemBlock block = obj as ChemBlock; if (block != null && !gridsChecked.Contains(block.chemGrid) && block.bounds.Intersects(area)) { gridsChecked.Add(block.chemGrid); block.chemGrid.Split(area); } } }
public override void HandleColliding(PlatformObject obj, Vector2 move) { if (obj is ChemBlock) { ChemBlock block = (ChemBlock)obj; if (!IsBondedWith(block) && nailDuration > 0) { Vector2 moveDir = move; moveDir.Normalize(); if (nailDirection.DotProduct(moveDir) > 0.5f) { NailOnto(block); nailDuration = 0; } } } }
public void AddNail(ChemBlock a, Vector2 direction) { Point aPos = blocks[a]; Point offset = new Point((int)Math.Round(direction.X), (int)Math.Round(direction.Y)); if (!IsValidNailOffset(offset)) { return; } Point bPos = aPos + offset; bool found = false; foreach (KeyValuePair <ChemBlock, Point> kv in blocks) { if (kv.Value == bPos) { found = true; break; } } // no block to connect to if (!found) { return; } if (offset.X == 1) { horizontalBonds.Add(aPos); } else if (offset.X == -1) { horizontalBonds.Add(aPos + offset); } else if (offset.Y == 1) { verticalBonds.Add(aPos); } else if (offset.Y == -1) { verticalBonds.Add(aPos + offset); } }
public override void Update(InputState input, List <PlatformObject> allObjects, List <Projectile> projectiles) { Vectangle myBounds = bounds; foreach (PlatformObject obj in allObjects) { if (obj is ChemBlock && obj.bounds.Intersects(myBounds) && !obj.destroyed) { ChemBlock block = (ChemBlock)obj; block.chemGrid.DoOutput(); if (signature != null && block.chemGrid.GetSignature() != signature && (signature2 == null || block.chemGrid.GetSignature() != signature2)) { Game1.instance.splashes.Add(new Splash("WRONG OUTPUT!", TextAlignment.CENTER, Game1.font, Color.Orange, new Vector2(300, 350), new Vector2(0, -5), 0.96f, 0, 3)); } } } }
void SpawnBubble(PlatformObject objectHit, Vector2 pos, Vector2 direction, List <PlatformObject> allObjects) { Vectangle objectBounds = objectHit.bounds; if (objectHit is ChemBlock) { pos = objectBounds.Center + direction * 16; } while (objectBounds.Contains(pos)) { pos += direction; } pos += direction * 17; Vectangle bubbleBounds = new Vectangle(pos - new Vector2(16, 16), new Vector2(32, 32)); bool failed = false; foreach (PlatformObject obj in allObjects) { if (obj.bounds.Intersects(bubbleBounds)) { failed = true; break; } } if (!failed) { Game1.instance.platformLevel.Record(FactoryCommandType.SPENDCRYSTAL); ChemicalElement c = ChemicalElement.WHITE; ChemBlock newBlock = new ChemBlock(c, c.ToTexture(false), bubbleBounds.TopLeft, bubbleBounds.Size, c.ToColor()); if (objectHit is ChemBlock) { newBlock.NailOnto((ChemBlock)objectHit); } allObjects.Add(newBlock); } }
public void NailOnto(ChemBlock other) { chemGrid.AddNail(this, other); }
public void UpdateConnectivity() { Dictionary <Point, ChemBlock> blockMapping = new Dictionary <Point, ChemBlock>(); HashSet <Point> inactiveBlocks = new HashSet <Point>(); foreach (KeyValuePair <ChemBlock, Point> kv in blocks) { blockMapping.Add(kv.Value, kv.Key); inactiveBlocks.Add(kv.Value); } //now flood fill regions until everything is filled while (inactiveBlocks.Count > 0) { Point originPoint = inactiveBlocks.First(); inactiveBlocks.Remove(originPoint); ChemBlock originBlock = blockMapping[originPoint]; ChemGrid newGrid = new ChemGrid(originBlock); originBlock.chemGrid = newGrid; originBlock.UnbondFromGroup(); List <Point> activeBlocks = new List <Point>() { originPoint }; List <Point> nextActiveBlocks = new List <Point>(); List <Point> finalPositions = new List <Point>(); while (activeBlocks.Count > 0) { foreach (Point p in activeBlocks) { Func <Point, bool> addBlock = pos => { inactiveBlocks.Remove(pos); nextActiveBlocks.Add(pos); ChemBlock block = blockMapping[pos]; block.UnbondFromGroup(); block.chemGrid = null; newGrid.AddNail(blockMapping[p], block); return(false); }; Point up = new Point(p.X, p.Y - 1); Point down = new Point(p.X, p.Y + 1); Point left = new Point(p.X - 1, p.Y); Point right = new Point(p.X + 1, p.Y); if (verticalBonds.Contains(up) && inactiveBlocks.Contains(up)) { addBlock(up); } if (verticalBonds.Contains(p) && inactiveBlocks.Contains(down)) { addBlock(down); } if (horizontalBonds.Contains(left) && inactiveBlocks.Contains(left)) { addBlock(left); } if (horizontalBonds.Contains(p) && inactiveBlocks.Contains(right)) { addBlock(right); } } List <Point> temp = activeBlocks; temp.Clear(); activeBlocks = nextActiveBlocks; nextActiveBlocks = temp; } } }
public void AddNail(ChemBlock a, ChemBlock b) { System.Diagnostics.Debug.Assert(a.chemGrid == this); Vector2 blockOffsetPixels = b.pos - a.pos; Point blockOffset = new Point((int)Math.Round(blockOffsetPixels.X / Game1.BLOCKSIZE), (int)Math.Round(blockOffsetPixels.Y / Game1.BLOCKSIZE)); if (!IsValidNailOffset(blockOffset)) { return; } Point a_in_aPos = blocks[a]; Point b_in_bPos = b.chemGrid != null? b.chemGrid.blocks[b]: new Point(0, 0); bool sameGrids = blocks.ContainsKey(b); if (!sameGrids) { Point b_in_aPos = a_in_aPos + blockOffset; if (b.chemGrid == null) { blocks[b] = b_in_aPos; b.chemGrid = this; a.BondWith(b); } else { // merge the grids Point gridOffset = b_in_aPos - b_in_bPos; foreach (Point p in b.chemGrid.horizontalBonds) { horizontalBonds.Add(p + gridOffset); } foreach (Point p in b.chemGrid.verticalBonds) { verticalBonds.Add(p + gridOffset); } foreach (KeyValuePair <ChemBlock, Point> kv in b.chemGrid.blocks) { blocks[kv.Key] = kv.Value + gridOffset; kv.Key.chemGrid = this; a.BondWith(kv.Key); } } } // they're already connected, just add the bond if (blockOffset.X == 0) { if (blockOffset.Y == 1) { verticalBonds.Add(a_in_aPos); } else { verticalBonds.Add(a_in_aPos + blockOffset); } } else if (blockOffset.X == 1) { horizontalBonds.Add(a_in_aPos); } else { horizontalBonds.Add(a_in_aPos + blockOffset); } }
public void Update(List <PlatformObject> objects) { if (!triggered) { return; } foreach (PlatformObject obj in objects) { if (obj.bounds.Intersects(bounds)) { return; } } ChemicalSignature signature = Game1.instance.platformLevel.SpawnInputChemical(inputIndex); if (signature == null) { return; } triggered = false; int height = signature.height; int width = signature.width; float startX = bounds.CenterX - width * 32 / 2; float startY = bounds.CenterY - height * 32 / 2; float curX = startX; float curY = startY; ChemBlock[,] blocksSpawned = new ChemBlock[width, height]; for (int col = 0; col < width; ++col) { for (int row = 0; row < height; ++row) { ChemicalElement c = signature[col, row]; if (c != ChemicalElement.NONE) { ChemBlock newBlock = new ChemBlock(c, c.ToTexture(false), new Vector2(curX, curY), new Vector2(32, 32), c.ToColor()); objects.Add(newBlock); blocksSpawned[col, row] = newBlock; if (col > 0 && blocksSpawned[col - 1, row] != null) { blocksSpawned[col - 1, row].NailOnto(newBlock); } if (row > 0 && blocksSpawned[col, row - 1] != null) { blocksSpawned[col, row - 1].NailOnto(newBlock); } } curY += 32.5f; } curX += 32.5f; curY = startY; Game1.instance.platformLevel.UpdateAnyBlocksLeft(); } }