Пример #1
0
void Board::roll(GroupSphere spheres) {
  int col = 0;
  GroupSphere spheres_end_board;

  _match_lock();
  spheres_end_board.clear();
  for(auto &sphere: spheres) {

    _grid.push_front(col, sphere);

    auto pos = PointGrid(col, 0);
    sphere->setPosition(pos);
    auto sphere_view = sphere->getView();
    _node->addChild(sphere_view);
    auto poss = pos.toPoint();
    poss.x += GRID_SIZE/2;
    poss.y *= -1; //invierte, para mostrar hacia abajo
    poss.y += _node->getContentSize().height;
    sphere_view->setPosition(poss);
    
    //std::cout << "Rolling sphere first" << std::endl;
    for(int row = _grid.getRows(); row > 0; row--){
      Sphere* data = static_cast<Sphere*>(_grid.get(PointGrid(col, row)));

      if(!_grid.Empty(data)){
	auto pos = PointGrid(col, row);
	auto sphere_view = data->getView();
	data->setPosition(pos);
	auto poss = pos.toPoint();
	poss.x += GRID_SIZE/2;
	poss.y *= -1; //invierte, para mostrar hacia abajo
	poss.y += _node->getContentSize().height;
	sphere_view->setPosition(poss);
	sphere_view->retain();
	//std::cout << "Rolling sphere down" << std::endl;
	if(data->getPosition().y == _grid.getRows() - 1 //@patch para permitir colision ultima esfera
	   ){
	  data->retain();
	  spheres_end_board.push_back(data);
	}
      }
    }
    col += 1;
  }
  _match_unlock();

  for(auto &func: onAttachRoll) {
    func(spheres);
  }


  
  if(spheres_end_board.size()>0){
    for(auto &func: onAttachEndBoard) {
      func(spheres_end_board);
    }
  }


}
Пример #2
0
//--------------------------------------------------------------------------------------------
Uint8 FindTileInPassage( const int x0, const int y0, const int tiletype, const int passageID, int *px1, int *py1 )
{
    /// @author ZZ
    /// @details This function finds the next tile in the passage, x0 and y0
    ///    must be set first, and are set on a find.  Returns true or false
    ///    depending on if it finds one or not

    int x, y;
    
    ego_tile_info_t * ptile = NULL;

    const std::shared_ptr<Passage> &passage = _currentModule->getPassageByID(passageID);
    if ( !passage ) return false;

    // Do the first row
    x = x0 / GRID_ISIZE;
    y = y0 / GRID_ISIZE;

    if ( x < passage->getLeft() )  x = passage->getLeft();
    if ( y < passage->getTop() )  y = passage->getTop();

    if ( y < passage->getBottom() )
    {
        for ( /*nothing*/; x <= passage->getRight(); x++ )
        {
            TileIndex fan = _currentModule->getMeshPointer()->get_tile_int(PointGrid(x, y));

            ptile = _currentModule->getMeshPointer()->get_ptile(fan);
            if ( NULL != ptile && tiletype == ( ptile->img & TILE_LOWER_MASK ) )
            {
                *px1 = ( x * GRID_ISIZE ) + 64;
                *py1 = ( y * GRID_ISIZE ) + 64;
                return true;
            }
        }
        y++;
    }

    // Do all remaining rows
    for ( /* nothing */; y <= passage->getBottom(); y++ )
    {
        for ( x = passage->getLeft(); x <= passage->getRight(); x++ )
        {
            TileIndex fan = _currentModule->getMeshPointer()->get_tile_int(PointGrid(x, y));

            ptile = _currentModule->getMeshPointer()->get_ptile(fan);
            if ( NULL != ptile && tiletype == ( ptile->img & TILE_LOWER_MASK ) )
            {
                *px1 = x * GRID_ISIZE + 64;
                *py1 = y * GRID_ISIZE + 64;
                return true;
            }
        }
    }

    return false;
}
Пример #3
0
void Board::fallSpheres(std::function<void(Sphere*,PointGrid)> logic){
  GroupSphere spheres_fall;
  std::vector<PointGrid> spheres_fall_old_pos;
  std::vector<PointGrid> spheres_fall_new_pos;

  _match_lock();

  //esto correge error de mal cambio de columna 0 a 11
  //imprevistamente
  spheres_fall.clear();

  std::cout << "GridCols:" << _grid.getCols() << " GridRows:" << _grid.getRows() << std::endl;
  for(int col=_grid.getCols()-1; col >= 0; col--){
    for(int row=0; row < _grid.getRows(); row++){

      PointGrid sphere_pos(col, row);
      Sphere* sphere = _grid.get(sphere_pos);
      //std::cout << "TryingFallingSphere:" << sphere_pos.x << "," << sphere_pos.y << std::endl;
      if(_grid.Empty(sphere)) continue;
      std::cout << "FallingSphere:" << sphere->getPosition().x << "," << sphere->getPosition().y << " Col: " << col << std::endl;
      sphere->retain();
      PointGrid sphere_new_pos = PointGrid::BAD;
      for(int row_row=row-1; row_row>=0; row_row--){
	if(_grid.Empty(PointGrid(col, row_row))){
	  std::cout << "FallingSphere::newpos:" << sphere_pos.x << "," << row_row << std::endl;
	  sphere_new_pos = PointGrid(col, row_row);
	}else{
	  break;
	}
      }
      if(sphere_new_pos != PointGrid::BAD){
	sphere->retain();
	spheres_fall.push_back(sphere);
	spheres_fall_new_pos.push_back(sphere_new_pos);
	spheres_fall_old_pos.push_back(sphere->getPosition());

	std::cout << "FallingSphere::newpos sended:" << sphere_new_pos.x << "," << sphere_new_pos.y << std::endl;
	
	if(logic)
	  logic(sphere, sphere_new_pos);
	_grid.move(sphere->getPosition(), sphere_new_pos);
	sphere->setPosition(sphere_new_pos);
      }

    }
  }
  _match_unlock();

  for(auto ifunc = onAttachFall.begin(); ifunc != onAttachFall.end(); ifunc++){
    (*ifunc)(spheres_fall, spheres_fall_old_pos, spheres_fall_new_pos);
  }
  std::cout << "FallingSphere::End" << std::endl;

}
Пример #4
0
void Board::updateView() {
  for(int col = _grid.getCols(); col > 0; col--){
    for(int row = _grid.getRows(); row > 0; row--){
      Sphere* data = static_cast<Sphere*>(_grid.get(PointGrid(col, row)));

      if(!_grid.Empty(data)){
	data->updateView(GRID_SIZE/2, _node->getContentSize().height);
      }

    }
  }
}
Пример #5
0
void Passage::open()
{
    //no need to do this if it already is open
    if ( isOpen() ) {
       return; 
    } 

    if ( _area._top <= _area._bottom )
    {
        _open = true;
        for ( int y = _area._top; y <= _area._bottom; y++ )
        {
            for ( int x = _area._left; x <= _area._right; x++ )
            {
                //clear impassable and wall bits
                TileIndex fan = _currentModule->getMeshPointer()->get_tile_int(PointGrid(x, y));
                ego_mesh_clear_fx( _currentModule->getMeshPointer(), fan, MAPFX_WALL | MAPFX_IMPASS );
            }
        }
    }

}
Пример #6
0
void Passage::flashColor(uint8_t color)
{
    for (int y = _area._top; y <= _area._bottom; y++ )
    {
        for (int x = _area._left; x <= _area._right; x++ )
        {
            TileIndex fan = _currentModule->getMeshPointer()->get_tile_int(PointGrid(x, y));

            ego_tile_info_t *ptile = _currentModule->getMeshPointer()->get_ptile(fan);
            if ( NULL == ptile ) continue;

            for (int cnt = 0; cnt < 4; cnt++ )
            {
                // set the color
                ptile->lcache[cnt]       = color;

                // force the lighting code to update
                ptile->request_clst_update = true;
                ptile->clst_frame          = -1;
            }
        }
    }
}
Пример #7
0
Sphere::Sphere() : _pos(PointGrid(0,0)), _node(NULL) {
}
Пример #8
0
GroupSphere Board::_match(PointGrid start) {
  GroupSphere spheres;


  spheres.clear();
  if(start.x < 0) { return spheres; }
  if(start.y < 0) { return spheres; }

  Sphere* start_sphere = _grid.getPop(start.x);
  unsigned int start_count_match = 0;
  if(_grid.Empty(start_sphere)) { return spheres; }
  if(_grid.getLastRow(start.x) == 0) { return spheres; }
  std::cout << "Match::PoinTStart:" << start.x << " LastRow:" << _grid.getLastRow(start.x) << std::endl;
  std::cout << "Match::StartSphereType:" << start_sphere->getType() << std::endl;

  //start_sphere->retain();
  if(!_grid.Empty(start_sphere)){
    start_count_match += 1;
    spheres.push_back(start_sphere);
    //vertical
    int last_row = _grid.getLastRow(start.x);
    if(last_row <= 0) { return spheres; }
    for(int row=last_row; row >= 0; row--){
      PointGrid pos_match(start.x, row);

      Sphere* sphere_to_match = _grid.get(pos_match);
      //sphere_to_match->retain();
      if(!_grid.Empty(sphere_to_match) && 
	 sphere_to_match->getType() == start_sphere->getType()
	 ){
	spheres.push_back(sphere_to_match);
	start_count_match += 1;
      }else{
	break;
      }
      std::cout << "Match::PosMatch: " << start.x << "," << row  << "Type:" << sphere_to_match->getType() << std::endl;
      //por derecha

      GroupSphere spheres_right = _match_right(PointGrid(start.x, row));
      for(auto it = spheres_right.begin(); it != spheres_right.end(); it++){
	if((*it))
	  spheres.push_back((*it));
      }
      //por izquierda
      GroupSphere spheres_left = _match_left(PointGrid(start.x, row));
      for(auto it = spheres_left.begin(); it != spheres_left.end(); it++){
	if((*it))
	  spheres.push_back((*it));
      }
    }
  }

  std::unique(spheres.begin(), spheres.end(),[](Sphere* a, Sphere *b) -> bool{
      return a == b;
    });

  for(auto it = onAttachMatch.begin(); it != onAttachMatch.end(); it++){
    (*it)(spheres, start_count_match);
  }

  return spheres;
}
Пример #9
0
void Board::takeSphere(int col, GroupSphere& spheres) {
  populateCol(col, spheres);
  _match_lock();
  _match(PointGrid(col,_grid.getRows()));
  _match_unlock();
}
Пример #10
0
bool Passage::close()
{
    //is it already closed?
    if(!isOpen()) {
        return true;
    }

    // don't compute all of this for nothing
    if ( EMPTY_BIT_FIELD == _mask ) {
        return true;
    }

    // check to see if a wall can close
    if ( 0 != HAS_SOME_BITS( _mask, MAPFX_IMPASS | MAPFX_WALL ) )
    {
        std::vector<std::shared_ptr<Object>> crushedCharacters;

        // Make sure it isn't blocked
        for(const std::shared_ptr<Object> &object : _currentModule->getObjectHandler().iterator())
        {
            if(object->isTerminated()) {
                continue;
            }

            //Don't do held items
            if (object->isBeingHeld()) continue;

            if ( 0.0f != object->bump_stt.size )
            {
                if ( objectIsInPassage( object->getPosX(), object->getPosY(), object->bump_1.size ) )
                {
                    if ( !object->canbecrushed || ( object->isAlive() && object->getProfile()->canOpenStuff() ) )
                    {
                        // Someone is blocking who can open stuff, stop here
                        return false;
                    }
                    else
                    {
                        crushedCharacters.push_back(object);
                    }
                }
            }
        }

        // Crush any unfortunate characters
        for(const std::shared_ptr<Object> &character : crushedCharacters) {
            SET_BIT( character->ai.alert, ALERTIF_CRUSHED );
        }
    }

    // Close it off
    _open = false;
    for ( int y = _area._top; y <= _area._bottom; y++ )
    {
        for ( int x = _area._left; x <= _area._right; x++ )
        {
            TileIndex fan = _currentModule->getMeshPointer()->get_tile_int(PointGrid(x, y));
            ego_mesh_add_fx( _currentModule->getMeshPointer(), fan, _mask );
        }
    }

    return true;    
}
Пример #11
0
//--------------------------------------------------------------------------------------------
bool line_of_sight_with_mesh( line_of_sight_info_t * plos )
{
    int Dx, Dy;
    int ix, ix_stt, ix_end;
    int iy, iy_stt, iy_end;

    int Dbig, Dsmall;
    int ibig, ibig_stt, ibig_end;
    int ismall, ismall_stt, ismall_end;
    int dbig, dsmall;
    int TwoDsmall, TwoDsmallMinusTwoDbig, TwoDsmallMinusDbig;

    bool steep;

    if ( NULL == plos ) return false;

    //is there any point of these calculations?
    if ( EMPTY_BIT_FIELD == plos->stopped_by ) return false;

    ix_stt = std::floor( plos->x0 / GRID_FSIZE ); /// @todo We have a projection function for that.
    ix_end = std::floor( plos->x1 / GRID_FSIZE );

    iy_stt = std::floor( plos->y0 / GRID_FSIZE ); /// @todo We have a projection function for that.
    iy_end = std::floor( plos->y1 / GRID_FSIZE );

    Dx = plos->x1 - plos->x0;
    Dy = plos->y1 - plos->y0;

    steep = (std::abs(Dy) >= std::abs(Dx));

    // determine which are the big and small values
    if ( steep )
    {
        ibig_stt = iy_stt;
        ibig_end = iy_end;

        ismall_stt = ix_stt;
        ismall_end = ix_end;
    }
    else
    {
        ibig_stt = ix_stt;
        ibig_end = ix_end;

        ismall_stt = iy_stt;
        ismall_end = iy_end;
    }

    // set up the big loop variables
    dbig = 1;
    Dbig = ibig_end - ibig_stt;
    if ( Dbig < 0 )
    {
        dbig = -1;
        Dbig = -Dbig;
        ibig_end--;
    }
    else
    {
        ibig_end++;
    }

    // set up the small loop variables
    dsmall = 1;
    Dsmall = ismall_end - ismall_stt;
    if ( Dsmall < 0 )
    {
        dsmall = -1;
        Dsmall = -Dsmall;
    }

    // pre-compute some common values
    TwoDsmall             = 2 * Dsmall;
    TwoDsmallMinusTwoDbig = TwoDsmall - 2 * Dbig;
    TwoDsmallMinusDbig    = TwoDsmall - Dbig;

    TileIndex fan_last = TileIndex::Invalid;
    for ( ibig = ibig_stt, ismall = ismall_stt;  ibig != ibig_end;  ibig += dbig )
    {
        if ( steep )
        {
            ix = ismall;
            iy = ibig;
        }
        else
        {
            ix = ibig;
            iy = ismall;
        }

        // check to see if the "ray" collides with the mesh
        TileIndex fan = _currentModule->getMeshPointer()->get_tile_int(PointGrid(ix, iy));
        if (TileIndex::Invalid != fan && fan != fan_last )
        {
            Uint32 collide_fx = ego_mesh_t::test_fx( _currentModule->getMeshPointer(), fan, plos->stopped_by );
            // collide the ray with the mesh

            if ( EMPTY_BIT_FIELD != collide_fx )
            {
                plos->collide_x  = ix;
                plos->collide_y  = iy;
                plos->collide_fx = collide_fx;

                return true;
            }

            fan_last = fan;
        }

        // go to the next step
        if ( TwoDsmallMinusDbig > 0 )
        {
            TwoDsmallMinusDbig += TwoDsmallMinusTwoDbig;
            ismall             += dsmall;
        }
        else
        {
            TwoDsmallMinusDbig += TwoDsmall;
        }
    }

    return false;
}