Esempio n. 1
0
bool BlockSnow::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, direction);
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, direction);
  return false;
}
Esempio n. 2
0
bool BlockPumpkin::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  direction = user->relativeToBlock(x, y, z);

  switch (direction)
  {
  case BLOCK_EAST:
    direction = BLOCK_SOUTH;
    break;
  case BLOCK_BOTTOM:
    direction = BLOCK_EAST;
    break;
  case BLOCK_NORTH:
    direction = BLOCK_NORTH;
    break;
  case BLOCK_SOUTH:
    direction = BLOCK_BOTTOM;
    break;
  }

  Mineserver::get()->map(map)->setBlock(x, y, z, newblock, direction);
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, newblock, direction);

  return false;
}
Esempio n. 3
0
bool BlockNote::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
	uint8_t oldblock;
	uint8_t oldmeta;

	if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta)) {
		revertBlock(user, x, y, z, map);
		return true;
	}
	/* Check block below allows blocks placed on top */
	if (!this->isBlockStackable(oldblock)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	/* move the x,y,z coords dependent upon placement direction */
	if (!this->translateDirection(&x, &y, &z, map, direction)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (this->isUserOnBlock(x, y, z, map)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (!this->isBlockEmpty(x, y, z, map)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	ServerInstance->map(map)->setBlock(x, y, z, BLOCK_NOTE_BLOCK, 0);
	ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_NOTE_BLOCK, 0);
	return false;
}
Esempio n. 4
0
bool BlockLiquid::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
   uint8_t oldblock;
   uint8_t oldmeta;

   if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
    revertBlock(user,x,y,z,map);
      return true;

   /* move the x,y,z coords dependent upon placement direction */
   if (!this->translateDirection(&x,&y,&z,map,direction))
    revertBlock(user,x,y,z,map);
      return true;

   if (!this->isBlockEmpty(x,y,z,map))
    revertBlock(user,x,y,z,map);
      return true;

   direction = user->relativeToBlock(x, y, z);

   int block = newblock;

   if (block == ITEM_WATER_BUCKET)
      newblock = BLOCK_STATIONARY_WATER;

   if (block == ITEM_LAVA_BUCKET)
      newblock = BLOCK_STATIONARY_LAVA;

   Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, 0);
   Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, 0);

   physics(x,y,z,map);
   return false;
}
Esempio n. 5
0
bool BlockStair::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction, int8_t posx, int8_t posy, int8_t posz)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  int8_t relative_direction = user->relativeToBlock(x, y, z);

  switch(relative_direction)
  {
    case RELATIVE_SOUTH: relative_direction = 2;
      break;
    case RELATIVE_WEST: relative_direction = 1;
      break;
    case RELATIVE_NORTH: relative_direction = 3;
      break;
    case RELATIVE_EAST: relative_direction = 0;
  }

  //set upside down stair
  if( (direction != BLOCK_TOP && posy >= (int8_t)8) || direction == BLOCK_BOTTOM )
    relative_direction ^= 4;

  ServerInstance->map(map)->setBlock(x, y, z, char(newblock), char(relative_direction));
  ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), char(relative_direction));

  return false;
}
Esempio n. 6
0
bool BlockDefault::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (newblock > 255)
  {
    return true;
  }

  if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  //direction = user->relativeToBlock(x, y, z);

  if (newblock < 256)
  {
    ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, 0);
    ServerInstance->map(map)->sendBlockChange(x, y, z, newblock, 0);
  }
  return false;
}
Esempio n. 7
0
bool BlockDyed::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user,x,y,z,map);
    return true;
  }

  //Combine two steps
  if(newblock == BLOCK_STEP && oldblock == BLOCK_STEP && direction == BLOCK_TOP)
  {
    Item item = user->inv[user->curItem+36];

    if(item.getHealth() == oldmeta){
      Mineserver::get()->map(map)->setBlock(x, y, z, (char)BLOCK_DOUBLE_STEP, oldmeta);
      Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)BLOCK_DOUBLE_STEP, oldmeta);
      revertBlock(user,x,y,z,map);
      return true;
    }else{
      revertBlock(user,x,y,z,map);
      return true;
    }
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user,x,y,z,map);
    return true;
  }

  if (!this->translateDirection(&x,&y,&z,map,direction))
  {
    revertBlock(user,x,y,z,map);
    return true;
  }

  if (this->isUserOnBlock(x,y,z,map))
  {
    revertBlock(user,x,y,z,map);
    return true;
  }

  if (!this->isBlockEmpty(x,y,z,map))
  {
    revertBlock(user,x,y,z,map);
    return true; 
  }

  Item item = user->inv[user->curItem+36];

  Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, item.getHealth());
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, item.getHealth());
  return false;
}
Esempio n. 8
0
bool BlockWood::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  Item item = user->inv[user->curItem + 36];

  Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, item.getHealth());
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, item.getHealth());
  return false;
}
Esempio n. 9
0
bool BlockRedstone::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction, int8_t posx, int8_t posy, int8_t posz)
{
  uint8_t block;
  uint8_t meta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!isBlockStackable(block))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  newblock = 55;
  meta = 0;

  ServerInstance->map(map)->setBlock(x, y, z, char(newblock), meta);
  ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), meta);

  ServerInstance->redstone(map)->addSimulation(vec(x,y,z));

  return false;
}
Esempio n. 10
0
bool BlockFire::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction, int8_t posx, int8_t posy, int8_t posz)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* burning block regardless of direction */
  y++;

  /* FIXME: Need this or should be just let em burn? */
  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* if the block isn't empty then you can't burn it */
  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  direction = user->relativeToBlock(x, y, z);

  ServerInstance->map(map)->setBlock(x, y, z, (char)BLOCK_FIRE, 0);
  ServerInstance->map(map)->sendBlockChange(x, y, z, (char)BLOCK_FIRE, 0);
  return false;
}
Esempio n. 11
0
bool BlockSnow::onBroken(User* user, int8_t status, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t block;
  uint8_t meta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &block, &meta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  Mineserver::get()->map(map)->sendBlockChange(x, y, z, BLOCK_AIR, 0);
  Mineserver::get()->map(map)->setBlock(x, y, z, BLOCK_AIR, 0);
  this->spawnBlockItem(x, y, z, map, block, meta);
  return false;
}
Esempio n. 12
0
bool BlockLeaves::onBroken(User* user, int8_t status, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
  std::set<Decay>::iterator it = std::find_if(decaying.begin(), decaying.end(), DecayFinder(x,y,z,map));

  if (it != decaying.end()) decaying.erase(it);

  uint8_t block;
  uint8_t meta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_AIR, 0);
  ServerInstance->map(map)->setBlock(x, y, z, BLOCK_AIR, 0);
  this->spawnBlockItem(x, y, z, map, block, meta);

  return true;
}
Esempio n. 13
0
bool BlockDefault::onBroken(User* user, int8_t status, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
  uint8_t block;
  uint8_t meta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }
  if (block != BLOCK_WOOL && block != BLOCK_LOG && block != BLOCK_STEP)
  {
    // Only Cloth, Wood and Step have colour metadata
    meta = 0;
  }

  ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_AIR, 0);
  ServerInstance->map(map)->setBlock(x, y, z, BLOCK_AIR, 0);
  this->spawnBlockItem(x, y, z, map, block, meta);
  return false;
}
Esempio n. 14
0
bool BlockChest::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  // if there is a large chest around --> block
  {
    chestDataPtr _connectedChest;
    if(findConnectedChest(x, y, z, map, _connectedChest))
    {
      if(_connectedChest->large())
      {
        revertBlock(user, x, y, z, map);
        return true;
      }
    }
  }

  direction = user->relativeToBlock(x, y, z);

  //// Fix orientation  
  switch (direction)
  {
  case BLOCK_EAST:
    //direction = BLOCK_SOUTH;
    break;
  case BLOCK_BOTTOM:
    direction = BLOCK_WEST;
    break;
  case BLOCK_NORTH:
    direction = BLOCK_TOP;
    break;
  case BLOCK_SOUTH:
    //direction = BLOCK_NORTH;
    break;
  }
  

  int32_t connectedChestX, connectedChestZ;
  if(findConnectedChest(x, y, z, map, &connectedChestX, &connectedChestZ))
  {
    if(connectedChestX != x)
    {
      if(!(direction == 3 || direction == 2))
      {
        direction = 3;
      }
    }
    if(connectedChestZ != z)
    {
      if(!(direction == 4 || direction == 5))
      {
        direction = 4;
      }
    }

    ServerInstance->map(map)->setBlock(connectedChestX, y, connectedChestZ, (char)newblock, direction);
    ServerInstance->map(map)->sendBlockChange(connectedChestX, y, connectedChestZ, (char)newblock, direction);

    // create a new chest and connect it to another chest --> large chest
    chestDataPtr connectedChest;
    if(getChestByCoordinates(connectedChestX, y, connectedChestZ, map, connectedChest))
    {
      chestDataPtr newchest;
      if(!getChestByCoordinates(x, y, z, map, newchest))
      {
        sChunk* chunk = ServerInstance->map(map)->getChunk(blockToChunk(x), blockToChunk(z));
        if(chunk != NULL)
        {
          newchest = chestDataPtr(new chestData);
          newchest->items(connectedChest->items());
          newchest->x(x);
          newchest->y(y);
          newchest->z(z);
          chunk->chests.push_back(newchest);
        }
      } else {
        newchest->large(true);
      }
      connectedChest->large(true);
    }
  } else {
    // create a new (small) chest
    chestDataPtr newchest(new chestData);
    sChunk* chunk = ServerInstance->map(map)->getChunk(blockToChunk(x), blockToChunk(z));
    if(chunk != NULL)
    {
      newchest->x(x);
      newchest->y(y);
      newchest->z(z);
      chunk->chests.push_back(newchest);
    }
  }

  ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, direction);
  ServerInstance->map(map)->sendBlockChange(x, y, z, (char)newblock, direction);
  return false;
}
Esempio n. 15
0
bool BlockTorch::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }
  if (direction == 0)
  {
    if (ServerInstance->map(map)->getBlock(x+1, y, z, &oldblock, &oldmeta) && oldblock != BLOCK_AIR)
    {
      direction = 2;
    }
    else if (ServerInstance->map(map)->getBlock(x, y, z+1, &oldblock, &oldmeta) && oldblock != BLOCK_AIR)
    {
      direction = 4;
    }
    else if (ServerInstance->map(map)->getBlock(x-1, y, z, &oldblock, &oldmeta) && oldblock != BLOCK_AIR)
    {
      direction = 1;
    }
    else if (ServerInstance->map(map)->getBlock(x, y, z-1, &oldblock, &oldmeta) && oldblock != BLOCK_AIR)
    {
      direction = 3;
    }
    else
    {
      direction = 5;
    }
   }

  ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, direction);
  ServerInstance->map(map)->sendBlockChange(x, y, z, (char)newblock, direction);

  if(newblock == BLOCK_REDSTONE_TORCH_OFF || newblock == BLOCK_REDSTONE_TORCH_ON)
  {
    ServerInstance->redstone(map)->addSimulation(vec(x,y,z));
  }

  return false;
}
Esempio n. 16
0
bool BlockFurnace::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  direction = user->relativeToBlock(x, y, z);

  // Fix orientation

  //switch (direction)
  //{
  //case BLOCK_EAST:
  //  direction = BLOCK_SOUTH;
  //  break;
  //case BLOCK_BOTTOM:
  //  direction = BLOCK_EAST;
  //  break;
  //case BLOCK_NORTH:
  //  direction = BLOCK_NORTH;
  //  break;
  //case BLOCK_SOUTH:
  //  direction = BLOCK_BOTTOM;
  //  break;
  //}

  Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, direction);
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, direction);


  int chunk_x = blockToChunk(x);
  int chunk_z = blockToChunk(z);
  sChunk* chunk = Mineserver::get()->map(map)->loadMap(chunk_x, chunk_z);

  if (chunk == NULL)
  {
    revertBlock(user, x, y, z, map);
  }
  return true;

  for (uint32_t i = 0; i < chunk->furnaces.size(); i++)
  {
    if (chunk->furnaces[i]->x == x &&
        chunk->furnaces[i]->y == y &&
        chunk->furnaces[i]->z == z)
    {
      chunk->furnaces.erase(chunk->furnaces.begin() + i);
      break;
    }
  }

  return false;
}
Esempio n. 17
0
bool BlockPlant::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
	uint8_t oldblock;
	uint8_t oldmeta;

	/* move the x,y,z coords dependent upon placement direction */
	if (!this->translateDirection(&x, &y, &z, map, direction)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (!ServerInstance->map(map)->getBlock(x, y - 1, z, &oldblock, &oldmeta)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (newblock != BLOCK_DIRT && newblock != BLOCK_SOIL && newblock != BLOCK_GRASS) {
		if (this->isBlockEmpty(x, y - 1, z, map) || !this->isBlockEmpty(x, y, z, map)) {
			revertBlock(user, x, y, z, map);
			return true;
		}

		if (!this->isBlockStackable(oldblock)) {
			revertBlock(user, x, y, z, map);
			return true;
		}
	} else {
		if (this->isUserOnBlock(x, y, z, map)) {
			revertBlock(user, x, y, z, map);
			return true;
		}
	}

	if ((newblock == BLOCK_REED || newblock == ITEM_REED) && (oldblock == BLOCK_GRASS || oldblock == BLOCK_DIRT)) {
		// TODO : Check for water
		ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_REED, 0);
		ServerInstance->map(map)->setBlock(x, y, z, BLOCK_REED, 0);
		addBlock(x, y, z, map);
		return false;
	}

	if (newblock == BLOCK_CACTUS && oldblock != BLOCK_SAND) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if ((newblock == BLOCK_YELLOW_FLOWER  ||
	        newblock == BLOCK_RED_ROSE) && (oldblock != BLOCK_DIRT &&
	                                        oldblock != BLOCK_GRASS)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if ((newblock == ITEM_SEEDS || newblock == BLOCK_CROPS) && (oldblock == BLOCK_SOIL)) {
		ServerInstance->map(map)->sendBlockChange(x, y, z, BLOCK_CROPS, 0);
		ServerInstance->map(map)->setBlock(x, y, z, BLOCK_CROPS, 0);
		addBlock(x, y, z, map);
		return false;
	}

	if ((newblock == ITEM_SEEDS || newblock == BLOCK_CROPS)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (newblock > 255 && (oldblock == BLOCK_DIRT  || oldblock == BLOCK_GRASS)) {
		// Hoe on dirt = Soil
		ServerInstance->map(map)->sendBlockChange(x, y - 1, z, BLOCK_SOIL, 0);
		ServerInstance->map(map)->setBlock(x, y - 1, z, BLOCK_SOIL, 0);
		if (SEEDS_CHANCE >= rand() % 10000) {
			ServerInstance->map(map)->createPickupSpawn(x, y + 1, z, ITEM_SEEDS, 1, 0, nullptr);
		}
		return true;
	}

	if (newblock > 255) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if ((newblock == BLOCK_BROWN_MUSHROOM || newblock == BLOCK_RED_MUSHROOM)
	        && oldblock != BLOCK_DIRT) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (newblock == BLOCK_SAPLING) {
		ServerInstance->map(map)->addSapling(user, x, y, z);
	} else {
		ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), 0);
		ServerInstance->map(map)->setBlock(x, y, z, char(newblock), 0);
		addBlocks(x, y, z, map);
	}
	return false;
}
Esempio n. 18
0
bool BlockTracks::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
  uint8_t block;
  uint8_t meta;

  if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(block))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  uint8_t metadata = FLAT_NS;
  uint8_t elevoftrack = 2;

  // WEST of placed track
  if (searchTrack(x + 1, y, z, map, meta) != 2 && isStartPiece(x + 1, y, z, map))
  {
    LOG(INFO, "Tracks", "WEST");
    metadata = FLAT_EW;
    elevoftrack = searchTrack(x + 1, y, z, map, meta);

    if (meta == FLAT_NS && elevoftrack == 0)
    {
      ServerInstance->map(map)->setBlock(x + 1, y, z, (char)newblock, FLAT_EW);
      ServerInstance->map(map)->sendBlockChange(x + 1, y, z, (char)newblock, FLAT_EW);
    }

    // Rising & falling tracks
    if (isTrack(x + 1, y + 1, z, map, meta) && isStartPiece(x + 1, y + 1, z, map)) // Rising & falling tracks
    {
      metadata = ASCEND_W;
    }
    else if (isTrack(x + 1, y - 1, z, map, meta) && isStartPiece(x + 1, y - 1, z, map)) // Rising & falling tracks
    {
      ServerInstance->map(map)->setBlock(x + 1, y - 1, z, (char)newblock, ASCEND_E);
      ServerInstance->map(map)->sendBlockChange(x + 1, y - 1, z, (char)newblock, ASCEND_E);
    }

    // Change previous track, Turns
    if (searchTrack(x + 1, y, z - 1, map, meta) != 2 && isStartPiece(x + 1, y, z, map) && meta != FLAT_EW) // Left
    {
      ServerInstance->map(map)->setBlock(x + 1, y + elevoftrack, z, (char)newblock, CORNER_NW);
      ServerInstance->map(map)->sendBlockChange(x + 1, y + elevoftrack, z, (char)newblock, CORNER_NW);
    }
    if (searchTrack(x + 1, y, z + 1, map, meta) != 2 && isStartPiece(x + 1, y, z, map) && meta != FLAT_EW) // Right
    {
      ServerInstance->map(map)->setBlock(x + 1, y + elevoftrack, z, (char)newblock, CORNER_SW);
      ServerInstance->map(map)->sendBlockChange(x + 1, y + elevoftrack, z, (char)newblock, CORNER_SW);
    }

    // Make track you just placed a corner
    if (isTrack(x, y, z - 1, map, meta) && isStartPiece(x, y, z - 1, map))
    {
      metadata = CORNER_NE;
    }
    if (isTrack(x, y, z + 1, map, meta) && isStartPiece(x, y, z + 1, map))
    {
      metadata = CORNER_SE;
    }
  }

  // EAST of placed track
  else if (searchTrack(x - 1, y, z, map, meta) != 2 && isStartPiece(x - 1, y, z, map))
  {
    LOG(INFO, "Tracks", "EAST");
    metadata = FLAT_EW;
    elevoftrack = searchTrack(x - 1, y, z, map, meta);


    if (meta == FLAT_NS && elevoftrack == 0)
    {
      ServerInstance->map(map)->setBlock(x - 1, y, z, (char)newblock, FLAT_EW);
      ServerInstance->map(map)->sendBlockChange(x - 1, y, z, (char)newblock, FLAT_EW);
    }

    // Rising & falling tracks
    if (isTrack(x - 1, y + 1, z, map, meta) && isStartPiece(x - 1, y + 1, z, map))
    {
      metadata = ASCEND_E;
      if (meta != ASCEND_E || meta != CORNER_NW || meta != CORNER_SW)
      {
        ServerInstance->map(map)->setBlock(x - 1, y + 1, z, (char)newblock, FLAT_EW);
        ServerInstance->map(map)->sendBlockChange(x - 1, y + 1, z, (char)newblock, FLAT_EW);
      }
    }
    else if (isTrack(x - 1, y - 1, z, map, meta) && isStartPiece(x - 1, y - 1, z, map))
    {
      ServerInstance->map(map)->setBlock(x - 1, y - 1, z, (char)newblock, ASCEND_W);
      ServerInstance->map(map)->sendBlockChange(x - 1, y - 1, z, (char)newblock, ASCEND_W);
    }

    // Change previous track, Turns
    if (searchTrack(x - 1, y, z - 1, map, meta) != 2 && isStartPiece(x - 1, y, z, map) && meta != FLAT_EW) // Right
    {
      ServerInstance->map(map)->setBlock(x - 1, y + elevoftrack, z, (char)newblock, CORNER_NE);
      ServerInstance->map(map)->sendBlockChange(x - 1, y + elevoftrack, z, (char)newblock, CORNER_NE);
    }
    if (searchTrack(x - 1, y, z + 1, map, meta) != 2 && isStartPiece(x - 1, y, z, map) && meta != FLAT_EW) // Left
    {
      ServerInstance->map(map)->setBlock(x - 1, y + elevoftrack, z, (char)newblock, CORNER_SE);
      ServerInstance->map(map)->sendBlockChange(x - 1, y + elevoftrack, z, (char)newblock, CORNER_SE);
    }

    // Make track you just placed a corner
    if (isTrack(x, y, z - 1, map, meta) && isStartPiece(x, y, z - 1, map))
    {
      metadata = CORNER_NW;
    }
    if (isTrack(x, y, z + 1, map, meta) && isStartPiece(x, y, z + 1, map))
    {
      metadata = CORNER_SW;
    }

  }

  // SOUTH of placed track
  else if (searchTrack(x, y, z - 1, map, meta) != 2 && isStartPiece(x, y, z - 1, map))
  {
    LOG(INFO, "Tracks", "SOUTH");
    metadata = FLAT_NS;
    elevoftrack = searchTrack(x, y, z - 1, map, meta); // Elevation of found track

    if (meta == FLAT_EW && elevoftrack == 0)
    {
      ServerInstance->map(map)->setBlock(x, y, z - 1, (char)newblock, FLAT_NS);
      ServerInstance->map(map)->sendBlockChange(x, y, z - 1, (char)newblock, FLAT_NS);
    }

    // Rising & falling tracks
    if (isTrack(x, y + 1, z - 1, map, meta) && isStartPiece(x, y + 1, z - 1, map)) // Rising & falling tracks
    {
      metadata = ASCEND_S;
    }
    else if (isTrack(x, y - 1, z - 1, map, meta) && isStartPiece(x, y - 1, z - 1, map)) // Rising & falling tracks
    {
      ServerInstance->map(map)->setBlock(x, y - 1, z - 1, (char)newblock, ASCEND_N);
      ServerInstance->map(map)->sendBlockChange(x, y - 1, z - 1, (char)newblock, ASCEND_N);
    }

    // Change previous track, Turns
    if (searchTrack(x - 1, y, z - 1, map, meta) != 2 && isStartPiece(x, y, z - 1, map) && meta != FLAT_NS) // Left
    {
      ServerInstance->map(map)->setBlock(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SW);
      ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SW);
    }
    if (searchTrack(x + 1, y, z - 1, map, meta) != 2 && isStartPiece(x, y, z - 1, map) && meta != FLAT_NS) // Right
    {
      ServerInstance->map(map)->setBlock(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SE);
      ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z - 1, (char)newblock, CORNER_SE);
    }

    // Make track you just placed a corner
    if (isTrack(x + 1, y, z, map, meta) && isStartPiece(x + 1, y, z, map))
    {
      metadata = CORNER_NE;
    }
    if (isTrack(x - 1, y, z, map, meta) && isStartPiece(x - 1, y, z, map))
    {
      metadata = CORNER_NW;
    }
  }

  // NORTH of placed track
  else if (searchTrack(x, y, z + 1, map, meta) != 2 && isStartPiece(x, y, z + 1, map))
  {
    LOG(INFO, "Tracks", "NORTH");
    metadata = FLAT_NS;
    elevoftrack = searchTrack(x, y, z + 1, map, meta);


    if (meta == FLAT_EW && elevoftrack == 0)
    {
      ServerInstance->map(map)->setBlock(x, y, z + 1, (char)newblock, FLAT_NS);
      ServerInstance->map(map)->sendBlockChange(x, y, z + 1, (char)newblock, FLAT_NS);
    }

    // Rising & falling tracks
    if (isTrack(x, y - 1, z + 1, map, meta) && isStartPiece(x, y - 1, z + 1, map)) // Rising & falling tracks
    {
      ServerInstance->map(map)->setBlock(x, y - 1, z + 1, (char)newblock, ASCEND_S);
      ServerInstance->map(map)->sendBlockChange(x, y - 1, z + 1, (char)newblock, ASCEND_S);
    }
    else if (isTrack(x, y + 1, z + 1, map, meta) && isStartPiece(x, y + 1, z + 1, map)) // Rising & falling tracks
    {
      metadata = ASCEND_N;
    }

    // Change previous track, Turns
    if (searchTrack(x + 1, y, z + 1, map, meta) != 2 && isStartPiece(x, y, z + 1, map) && meta != FLAT_NS) // Left
    {
      ServerInstance->map(map)->setBlock(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NE);
      ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NE);
    }
    if (searchTrack(x - 1, y, z + 1, map, meta) != 2 && isStartPiece(x, y, z + 1, map)  && meta != FLAT_NS) // Right
    {
      ServerInstance->map(map)->setBlock(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NW);
      ServerInstance->map(map)->sendBlockChange(x, y + elevoftrack, z + 1, (char)newblock, CORNER_NW);
    }

    // Make track you just placed a corner
    if (isTrack(x + 1, y, z, map, meta) && isStartPiece(x + 1, y, z, map))
    {
      metadata = CORNER_SE;
    }
    if (isTrack(x - 1, y, z, map, meta) && isStartPiece(x - 1, y, z, map))
    {
      metadata = CORNER_SW;
    }

  }

  ServerInstance->map(map)->setBlock(x, y, z, (char)newblock, metadata);
  ServerInstance->map(map)->sendBlockChange(x, y, z, (char)newblock, metadata);
  return false;
}
Esempio n. 19
0
bool BlockSign::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  // 0x0 -> West  West  West  West
  // 0x1 -> West  West  West  North
  // 0x2 -> West  West  North North
  // 0x3 -> West  North North North
  // 0x4 -> North North North North
  // 0x5 -> North North North East
  // 0x6 -> North North East  East
  // 0x7 -> North East  East  East
  // 0x8 -> East  East  East  East
  // 0x9 -> East  East  East  South
  // 0xA -> East  East  South South
  // 0xB -> East  South South South
  // 0xC -> South South South South
  // 0xD -> South South South West
  // 0xE -> South South West  West
  // 0xF -> South West  West  West

  //           The values were the signs are facing
  //
  //                          North
  //
  //      -X |                  4
  //         |              3       5
  //         |           2             6
  //         |         1       [=]       7
  //  West   |        0         |         8           East
  //         |         F                 9
  //         |           E             A
  //         |              D       B
  //      +X |                  C
  //           ----------------------------------
  //           +Z                              -Z
  //
  //                          South


  // Were it should be placed depending on the user's position
  //
  //                          North
  //
  //      -X |                  C
  //         |              B       D
  //         |           A      o      E
  //         |         9       [ ]       F
  //  West   |        8        | |         0           East
  //         |         7                 1
  //         |           6             2
  //         |              5       3
  //      +X |                  4
  //           ----------------------------------
  //           +Z                              -Z
  //
  //                          South

  // We place according to the player's position
  double diffX = (x + 0.5) - user->pos.x; // + 0.5 to get the middle of the square
  double diffZ = (z + 0.5) - user->pos.z; // + 0.5 to get the middle of the square

  double angleDegree = ((atan2(diffZ, diffX) * 180 / M_PI + 90) / 22.5);

  uint8_t metadata;
  if (angleDegree < 0)
  {
    angleDegree += 16;
  }
  newblock = BLOCK_WALL_SIGN;
  metadata = 6 - direction;
  switch (direction)
  {
  case BLOCK_SOUTH:
    x--;
    break;
  case BLOCK_NORTH:
    x++;
    break;
  case BLOCK_EAST:
    z++;
    break;
  case BLOCK_WEST:
    z--;
    break;
  case BLOCK_TOP:
    y++;
    newblock = BLOCK_SIGN_POST;
    metadata = (uint8_t)(angleDegree + 0.5);
    break;
  case BLOCK_BOTTOM:
  default:
    revertBlock(user, x, y, z, map);
    return true;
    break;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, metadata);
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, metadata);
  return false;
}
Esempio n. 20
0
bool BlockRedstoneUtil::onPlace(User* user, int16_t newblock, int32_t x, int16_t y, int32_t z, int map, int8_t direction)
{
	uint8_t block;
	uint8_t meta = 0;
	if (!ServerInstance->map(map)->getBlock(x, y, z, &block, &meta)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	/* Check block below allows blocks placed on top */
	if (!isBlockStackable(block)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	/* move the x,y,z coords dependent upon placement direction */
	if (!translateDirection(&x, &y, &z, map, direction)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	if (!isBlockEmpty(x, y, z, map)) {
		revertBlock(user, x, y, z, map);
		return true;
	}


	// Check that switch is placed on legal direction
	if ((newblock == BLOCK_STONE_BUTTON && (direction == BLOCK_TOP || direction == BLOCK_BOTTOM))
	        || ((newblock == BLOCK_STONE_PRESSURE_PLATE || newblock == BLOCK_WOODEN_PRESSURE_PLATE) && direction != BLOCK_TOP)) {
		revertBlock(user, x, y, z, map);
		return true;
	}

	// Set metadata for the position
	if (newblock == BLOCK_STONE_BUTTON || newblock == BLOCK_LEVER) {
		// Wall switch
		if (direction != BLOCK_TOP && direction != BLOCK_BOTTOM) {
			meta = direction;
		}
		// Ceiling lever
		else if (direction == BLOCK_BOTTOM) {
			int yaw = abs(int(user->pos.yaw)) % 360;
			if ((yaw > 45 && yaw <= 135) || (yaw > 225 && yaw <= 315)) {
				meta = 0x00;
			} else {
				meta = 0x07;
			}
		}
		// Floor lever
		else {
			int yaw = abs(int(user->pos.yaw)) % 360;
			if ((yaw > 45 && yaw <= 135) || (yaw > 225 && yaw <= 315)) {
				meta = 0x06;
			} else {
				meta = 0x05;
			}
		}
	}

	ServerInstance->map(map)->setBlock(x, y, z, char(newblock), meta);
	ServerInstance->map(map)->sendBlockChange(x, y, z, char(newblock), meta);

	return false;
}
Esempio n. 21
0
bool BlockBed::onPlace(User* user, int16_t newblock, int32_t x, int8_t y, int32_t z, int map, int8_t direction)
{
  uint8_t oldblock;
  uint8_t oldmeta;
  int zMod = 0, xMod = 0;

  if (!Mineserver::get()->map(map)->getBlock(x, y, z, &oldblock, &oldmeta))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* Check block below allows blocks placed on top */
  if (!this->isBlockStackable(oldblock))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  /* move the x,y,z coords dependent upon placement direction */
  if (!this->translateDirection(&x, &y, &z, map, direction))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (this->isUserOnBlock(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  if (!this->isBlockEmpty(x, y, z, map))
  {
    revertBlock(user, x, y, z, map);
    return true;
  }

  // checking for an item rather then a block
  if (newblock == ITEM_BED)
  {
    newblock = BLOCK_BED;
  }

  direction = user->relativeToBlock(x, y, z);

  switch (direction)
  {
  case BLOCK_EAST:
    direction = BLOCK_SOUTH;
	zMod = -1;
	xMod = 0;
    break;
  case BLOCK_BOTTOM:
    direction = BLOCK_EAST;
	zMod = 0;
	xMod = +1;
    break;
  case BLOCK_NORTH:
    direction = BLOCK_NORTH;
	zMod = 0;
	xMod = -1;
    break;
  case BLOCK_SOUTH:
    direction = BLOCK_BOTTOM;
	zMod = +1;
	xMod = 0;
    break;
  }

  Mineserver::get()->map(map)->setBlock(x, y, z, (char)newblock, direction);
  Mineserver::get()->map(map)->sendBlockChange(x, y, z, (char)newblock, direction);

  // set head of the bed
  direction ^= 8;

  Mineserver::get()->map(map)->setBlock(x + xMod, y, z + zMod, (char)newblock, direction);
  Mineserver::get()->map(map)->sendBlockChange(x + xMod, y, z + zMod, (char)newblock, direction);
  return false;
}