public BombList(Player player, int capacity)
 {
     array = new Bomb[capacity];
     for (int i = 0; i < capacity; ++i)
     {
         array[i] = new Bomb(player);
     }
 }
 public void SetFrom(Bomb b)
 {
     active = b.isActive;
     if (active)
     {
         direction = b.direction;
         px = b.px;
         py = b.py;
         speed = b.GetSpeed();
         flags = 0;
         flags |= b.IsJelly() ? FLAG_JELLY : 0;
         flags |= b.IsTrigger() ? FLAG_TRIGGER : 0;
     }
 }
        private void DrawBomb(Context context, Bomb bomb)
        {
            float drawX = bomb.GetPx();
            float drawY = bomb.GetPy();

            AnimationInstance anim = bomb.currentAnimation;
            anim.Draw(context, drawX, drawY + 0.5f * cellHeight, bomb.IsBlocked ? Color.Red : Color.White);

            if (CVars.g_drawBombDir.boolValue)
            {
                TextureImage dirImage = dirLookup[bomb.direction];
                context.DrawImage(dirImage, drawX - 0.5f * dirImage.GetWidth(), drawY - 0.5f * dirImage.GetHeight());
            }

            context.DrawRect(bomb.cx * cellWidth, bomb.cy * cellHeight, cellWidth, cellHeight, Color.White);
            context.DrawRect(bomb.px - 0.5f * cellWidth, bomb.py - 0.5f * cellHeight, cellWidth, cellHeight, Color.Red);
        }
 private void WriteBombState(NetBuffer msg, Bomb b)
 {
     msg.Write(b.isActive);
     if (b.isActive)
     {
         msg.WriteTime(NetTime.Now + b.timeRemains, false);
         msg.Write(b.px);
         msg.Write(b.py);
         msg.Write((byte)b.direction);
         msg.Write(b.GetSpeed());
         msg.Write(b.IsJelly());
         msg.Write(b.IsTrigger());
     }
 }
        /* Player is moving, bomb is still */
        private bool HandlePlayerMovingBombStillCollision(Bomb bomb)
        {
            Debug.Assert(IsMoving());
            Debug.Assert(!bomb.IsMoving());

            if (CheckCell2CellCollision(bomb)) // player and bomb share the cell
            {
                return false;
            }

            if (CheckBounds2CellCollision(bomb)) // player bounds collide bomb`s cell
            {
                if (IsMovingTowards(bomb)) // check if player is moving towards the bomb
                {
                    if (HasKick())
                    {
                        TryKick(bomb);
                    }
                    else
                    {
                        MoveOutOfCell(bomb);
                    }

                    return true;
                }
            }

            return false;
        }
 private void AddThrownBomb(Bomb bomb)
 {
     Debug.AssertNotContains(m_thrownBombs, bomb);
     m_thrownBombs.Add(bomb);
 }
        private void ReadBombState(NetIncomingMessage msg, Player p, Bomb b)
        {
            bool active = msg.ReadBoolean();
            if (active)
            {
                float remains = (float)(msg.ReadTime(false) - NetTime.Now);
                float px = msg.ReadFloat();
                float py = msg.ReadFloat();
                Direction dir = (Direction)msg.ReadByte();
                float speed = msg.ReadFloat();
                bool jelly = msg.ReadBoolean();
                bool trigger = msg.ReadBoolean();

                if (!b.isActive)
                {
                    b.player = p;
                    b.Activate();
                    game.Field.SetBomb(b);
                }

                b.timeRemains = remains;
                b.SetPos(px, py);
                b.SetSpeed(speed);
                b.SetJelly(jelly);
                b.SetTrigger(trigger);
                // TODO: jelly & trigger
            }
            else if (b.isActive)
            {
                b.Deactivate();
                b.RemoveFromField();
            }
        }
        /* Player is moving, bomb is moving */
        private bool HandlePlayerMovingBombMovingCollision(Bomb bomb)
        {
            Debug.Assert(IsMoving());
            Debug.Assert(bomb.IsMoving());

            bool hasKick = HasKick();

            if (direction == Util.Opposite(bomb.direction)) // moving in opposite directions
            {
                if (IsMovingTowards(bomb))
                {
                    if (CheckCell2BoundsCollision(bomb) || CheckBounds2CellCollision(bomb))
                    {
                        if (hasKick)
                        {
                            // move bomb out of player`s cell
                            bomb.MoveOutOfCell(this);

                            // kick in the moving direction
                            TryKick(bomb);

                            return true;
                        }

                        // treat player as an obstacle
                        bomb.HandleObstacleCollistion(this);

                        // make sure player is out of bomb`s cell
                        MoveOutOfCell(bomb);

                        return true;
                    }
                }
            }
            else if (direction == bomb.direction) // moving in the same direction
            {
                if (bomb.IsMovingTowards(this)) // bomb`s following player?
                {
                    if (bomb.CheckBounds2CellCollision(this)) // bomb bounds should collide player`s cell
                    {
                        // treat player as an obstacle
                        bomb.HandleObstacleCollistion(this);

                        return true;
                    }
                }
                else if (IsMovingTowards(bomb)) // player`s following bomb
                {
                    if (CheckCell2BoundsCollision(bomb) || CheckBounds2CellCollision(bomb))
                    {
                        if (hasKick)
                        {
                            // kick in the moving direction
                            TryKick(bomb);

                            return true;
                        }

                        // make sure player is out of bomb`s cell
                        MoveOutOfCell(bomb);

                        return true;
                    }
                }
            }
            else // player and bomb move in perpendicular directions
            {
                if (CheckCell2CellCollision(bomb))
                {
                    return false;
                }

                if (CheckBounds2CellCollision(bomb) && CheckBounds2BoundsCollision(bomb))
                {
                    if (IsMovingTowards(bomb))
                    {
                        if (hasKick)
                        {
                            TryKick(bomb);
                        }

                        MoveOutOfCell(bomb);

                        return true;
                    }
                }

                if (bomb.CheckBounds2BoundsCollision(this))
                {
                    if (bomb.IsMovingTowards(this))
                    {
                        bomb.HandleObstacleCollistion(this);
                        return true;
                    }
                }
            }

            return false;
        }
        // should be only called from PlayeList
        internal void Kill()
        {
            Debug.Assert(m_alive);
            m_alive = false;

            StopMoving();
            if (m_bombInHands != null)
            {
                m_bombInHands.isActive = false;
                m_bombInHands = null;
            }

            m_diseases.CureAll();

            UpdateAnimation();
        }
예제 #10
0
        /** Should only be called from Bomb.Blow() */
        public void BlowBomb(Bomb bomb)
        {
            int cx = bomb.GetCx();
            int cy = bomb.GetCy();

            bomb.RemoveFromField();
            SetFlame(bomb, cx, cy);

            bomb.player.OnBombBlown(bomb);

            bool up = true, down = true, left = true, right = true;
            int radius = bomb.GetRadius();

            for (int i = 1; i <= radius && (up || down || left || right); ++i)
            {
                left = left && SetFlame(bomb, cx - i, cy);
                up = up && SetFlame(bomb, cx, cy - i);
                down = down && SetFlame(bomb, cx, cy + i);
                right = right && SetFlame(bomb, cx + i, cy);
            }
        }
예제 #11
0
        /* Player is still, bomb is still */
        private bool HandlePlayerStillBombStillCollision(Bomb bomb)
        {
            Debug.Assert(!IsMoving());
            Debug.Assert(!bomb.IsMoving());

            return false;
        }
예제 #12
0
        private bool TryKick(Bomb bomb)
        {
            Debug.Assert(HasKick());
            Debug.Assert(IsMoving());

            MoveOutOfCell(bomb);

            if (!bomb.HasNearObstacle(direction))
            {
                KickBomb(bomb);
                return true;
            }

            return false;
        }
예제 #13
0
        private bool TryThrowBomb()
        {
            if (IsHoldingBomb())
            {
                AddThrownBomb(m_bombInHands);
                m_bombInHands.Throw();
                m_bombInHands = null;

                IsPickingUpBomb = false;
                return true;
            }
            return false;
        }
예제 #14
0
        private bool TryGrab()
        {
            Bomb underlyingBomb = GetField().GetBomb(cx, cy);
            if (underlyingBomb != null)
            {
                underlyingBomb.Grab();
                m_bombInHands = underlyingBomb;

                IsPickingUpBomb = true;
                return true;
            }
            return false;
        }
예제 #15
0
 private void RemoveThrownBomb(Bomb bomb)
 {
     bool removed = m_thrownBombs.Remove(bomb);
     Debug.Assert(removed);
 }
예제 #16
0
        private void KickBomb(Bomb bomb)
        {
            Debug.Assert(IsMoving());
            Debug.Assert(HasKick());

            // kick in the moving direction
            bomb.Kick(direction);

            // make sure player is out of the bomb`s cell
            MoveOutOfCell(bomb);
        }
예제 #17
0
        private bool HandleCollision(Bomb other)
        {
            bool moving1 = IsMoving();
            bool moving2 = other.IsMoving();

            Debug.Assert(moving1 || moving2);

            if (moving1 && moving2)
            {
                if (direction == Util.Opposite(other.direction)) // moving in opposite directions
                {
                    bool backBlocked1 = HasJellyBlockingObstacle(Util.Opposite(direction));
                    bool backBlocked2 = other.HasJellyBlockingObstacle(Util.Opposite(other.direction));

                    bool cell2cell     = CheckCell2CellCollision(other);
                    bool bounds2cell   = CheckBounds2CellCollision(other);
                    bool cell2bounds   = CheckCell2BoundsCollision(other);
                    bool bounds2bounds = CheckBounds2BoundsCollision(other);

                    if (backBlocked1 && backBlocked2)
                    {
                        if (cell2cell)
                        {
                            switch (direction)
                            {
                            case Direction.LEFT:
                            case Direction.RIGHT:
                            {
                                float shift = 0.5f * OverlapX(other);
                                MoveBackX(shift);
                                other.MoveBackX(shift);
                                break;
                            }

                            case Direction.UP:
                            case Direction.DOWN:
                            {
                                float shift = 0.5f * OverlapY(other);
                                MoveBackY(shift);
                                other.MoveBackY(shift);
                                break;
                            }
                            }
                        }
                    }
                    else if (backBlocked1)
                    {
                        if (bounds2cell)
                        {
                            HandleObstacleCollistion(other);
                            if (bounds2bounds)
                            {
                                other.HandleObstacleCollistion(this);
                            }

                            return(true);
                        }
                    }
                    else if (backBlocked2)
                    {
                        if (cell2bounds)
                        {
                            other.HandleObstacleCollistion(this);
                            if (bounds2bounds)
                            {
                                HandleObstacleCollistion(other);
                            }

                            return(true);
                        }
                    }
                    else
                    {
                        if (!bounds2bounds)
                        {
                            return(false);
                        }
                    }

                    HandleObstacleCollistion(other);
                    other.HandleObstacleCollistion(this);

                    return(true);
                }
                else if (direction == other.direction)
                {
                    if (IsMovingTowards(other))
                    {
                        HandleObstacleCollistion(other);
                        return(true);
                    }

                    other.HandleObstacleCollistion(this);
                    return(true);
                }
                else // perpendicular directions
                {
                    if (CheckBounds2CellCollision(other))
                    {
                        if (IsMovingTowards(other))
                        {
                            HandleObstacleCollistion(other);
                            return(true);
                        }
                    }
                    else if (other.CheckBounds2CellCollision(this))
                    {
                        if (other.IsMovingTowards(this))
                        {
                            other.HandleObstacleCollistion(this);
                            return(true);
                        }
                    }

                    if (CheckBounds2BoundsCollision(this))
                    {
                        if (IsMovingTowards(other))
                        {
                            HandleObstacleCollistion(other);
                            return(true);
                        }

                        if (other.IsMovingTowards(this))
                        {
                            other.HandleObstacleCollistion(this);
                            return(true);
                        }
                    }
                }

                return(false);
            }

            if (moving1)
            {
                if (IsMovingTowards(other))
                {
                    return(HandleObstacleCollistion(other));
                }

                return(false);
            }

            if (moving2)
            {
                if (other.IsMovingTowards(this))
                {
                    return(other.HandleObstacleCollistion(this));
                }
                return(false);
            }

            return(false);
        }
예제 #18
0
        /* Returns true if can be spread more */
        private bool SetFlame(Bomb bomb, int cx, int cy)
        {
            if (!IsInsideField(cx, cy))
            {
                return false;
            }

            FieldCellSlot slot = GetSlot(cx, cy);

            FieldCell staticCell = slot.staticCell;
            if (staticCell != null)
            {
                if (staticCell.IsSolid())
                {
                    return false;
                }

                if (staticCell.IsBrick())
                {
                    BrickCell brick = staticCell.AsBrick();
                    if (!brick.destroyed)
                    {
                        brick.Destroy();
                    }

                    return false;
                }

                if (staticCell.IsPowerup())
                {
                    staticCell.AsPowerup().RemoveFromField();
                    return false;
                }
            }

            if (slot.MovableCount() > 0)
            {
                LinkedList<FieldCell> tempList = new LinkedList<FieldCell>();
                slot.GetCells(tempList);

                foreach (FieldCell cell in tempList)
                {
                    if (cell.IsBomb())
                    {
                        cell.AsBomb().Blow();
                    }
                    else if (cell.IsPlayer())
                    {
                        KillPlayer(cell.AsPlayer());
                    }
                }
            }

            SetFlame(bomb.player, cx, cy);
            return true;
        }
예제 #19
0
 public void OnBombBlown(Bomb bomb)
 {
     TrySchedulePoops();
 }
예제 #20
0
        /* Player is still, bomb is moving */
        private bool HandlePlayerStillBombMovingCollision(Bomb bomb)
        {
            Debug.Assert(!IsMoving());
            Debug.Assert(bomb.IsMoving());

            if (CheckCell2BoundsCollision(bomb)) // player`s cell should collide bomb`s bounds
            {
                if (bomb.IsMovingTowards(this)) // bomb is moving towards the player
                {
                    bomb.HandleObstacleCollistion(this);
                    return true;
                }
            }

            return false;
        }
예제 #21
0
        public void SetBomb(Bomb bomb)
        {
            AddCell(bomb);

            FieldCellSlot slot = GetSlot(bomb);
            PowerupCell powerup = slot.GetPowerup();
            if (powerup != null)
            {
                powerup.RemoveFromField();
            }
            else
            {
                FlameCell flame = slot.GetFlame();
                if (flame != null)
                {
                    bomb.Blow();
                }
            }
        }
예제 #22
0
 public void OnBombLanded(Bomb bomb)
 {
     RemoveThrownBomb(bomb);
     bomb.SetCell();
     GetField().SetBomb(bomb);
 }
예제 #23
0
        private bool HandleCollision(Bomb other)
        {
            bool moving1 = IsMoving();
            bool moving2 = other.IsMoving();

            Debug.Assert(moving1 || moving2);

            if (moving1 && moving2)
            {
                if (direction == Util.Opposite(other.direction)) // moving in opposite directions
                {
                    bool backBlocked1 = HasJellyBlockingObstacle(Util.Opposite(direction));
                    bool backBlocked2 = other.HasJellyBlockingObstacle(Util.Opposite(other.direction));

                    bool cell2cell = CheckCell2CellCollision(other);
                    bool bounds2cell = CheckBounds2CellCollision(other);
                    bool cell2bounds = CheckCell2BoundsCollision(other);
                    bool bounds2bounds = CheckBounds2BoundsCollision(other);

                    if (backBlocked1 && backBlocked2)
                    {
                        if (cell2cell)
                        {
                            switch (direction)
                            {
                                case Direction.LEFT:
                                case Direction.RIGHT:
                                {
                                    float shift = 0.5f * OverlapX(other);
                                    MoveBackX(shift);
                                    other.MoveBackX(shift);
                                    break;
                                }

                                case Direction.UP:
                                case Direction.DOWN:
                                {
                                    float shift = 0.5f * OverlapY(other);
                                    MoveBackY(shift);
                                    other.MoveBackY(shift);
                                    break;
                                }
                            }
                        }
                    }
                    else if (backBlocked1)
                    {
                        if (bounds2cell)
                        {
                            HandleObstacleCollistion(other);
                            if (bounds2bounds)
                            {
                                other.HandleObstacleCollistion(this);
                            }

                            return true;
                        }
                    }
                    else if (backBlocked2)
                    {
                        if (cell2bounds)
                        {
                            other.HandleObstacleCollistion(this);
                            if (bounds2bounds)
                            {
                                HandleObstacleCollistion(other);
                            }

                            return true;
                        }
                    }
                    else
                    {
                        if (!bounds2bounds)
                        {
                            return false;
                        }
                    }

                    HandleObstacleCollistion(other);
                    other.HandleObstacleCollistion(this);

                    return true;
                }
                else if (direction == other.direction)
                {
                    if (IsMovingTowards(other))
                    {
                        HandleObstacleCollistion(other);
                        return true;
                    }

                    other.HandleObstacleCollistion(this);
                    return true;
                }
                else // perpendicular directions
                {
                    if (CheckBounds2CellCollision(other))
                    {
                        if (IsMovingTowards(other))
                        {
                            HandleObstacleCollistion(other);
                            return true;
                        }
                    }
                    else if (other.CheckBounds2CellCollision(this))
                    {
                        if (other.IsMovingTowards(this))
                        {
                            other.HandleObstacleCollistion(this);
                            return true;
                        }
                    }

                    if (CheckBounds2BoundsCollision(this))
                    {
                        if (IsMovingTowards(other))
                        {
                            HandleObstacleCollistion(other);
                            return true;
                        }

                        if (other.IsMovingTowards(this))
                        {
                            other.HandleObstacleCollistion(this);
                            return true;
                        }
                    }
                }

                return false;
            }

            if (moving1)
            {
                if (IsMovingTowards(other))
                {
                    return HandleObstacleCollistion(other);
                }

                return false;
            }

            if (moving2)
            {
                if (other.IsMovingTowards(this))
                {
                    return other.HandleObstacleCollistion(this);
                }
                return false;
            }

            return false;
        }
예제 #24
0
        internal bool HandleCollision(Bomb bomb)
        {
            if (IsMoving())
            {
                if (bomb.IsMoving())
                {
                    return HandlePlayerMovingBombMovingCollision(bomb);
                }
                return HandlePlayerMovingBombStillCollision(bomb);
            }

            if (bomb.IsMoving())
            {
                return HandlePlayerStillBombMovingCollision(bomb);
            }

            return HandlePlayerStillBombStillCollision(bomb);
        }