Esempio n. 1
0
bool Physics::updateFluid(uint32_t simIt) 
{
	//Get Pos    
	vec pos = simList[simIt].blocks[0].pos;
	//Render the block?
	bool render = simList[simIt].blocks[0].render;
	//Meta -> High of water    
	uint8_t block, meta;
   Mineserver::get()->map(map)->getBlock(pos, &block, &meta);
	
	if(render)
	{
		uint8_t around[6][2];
		vec vectors[6];
		getBlocksAround(pos, vectors, around);
		//If there nothing water higher than self, delete
		if(meta > 0 && !((around[1][0] == block && around[1][1] < meta ) || (around[2][0] == block && around[2][1] < meta) || (around[3][0] == block && around[3][1] < meta) || (around[4][0] == block && around[4][1] < meta) || (around[5][0] == block && around[5][1] < 8 ))) 
			{
			removeSimulation(pos);
			Mineserver::get()->map(map)->setBlock(pos, BLOCK_AIR, 0);

			for(int i = 0; i < 5; i ++) 
			{
				addSimulation(vectors[i]);
			}
		}
		//else if(meta == 1 && (((around[1][0] == block && around[1][1] == 0 ) && (around[3][0] == block && around[3][1] == 0)) || 										 ((around[2][0] == block && around[2][1] == 0 ) && (around[4][0] == block && around[4][1] == 0)) ||
										 //((around[1][0] == block && around[1][1] == 0 ) && (around[2][0] == block && around[2][1] == 0)) ||
										 //((around[3][0] == block && around[3][1] == 0 ) && (around[4][0] == block && around[4][1] == 0)) ||
										 //((around[1][0] == block && around[1][1] == 0 ) && (around[4][0] == block && around[4][1] == 0)) ||
										 //((around[2][0] == block && around[2][1] == 0 ) && (around[3][0] == block && around[3][1] == 0)) ||
										//around[5][0] == block && around[5][1] == 1 ))) 
		//{
			//Mineserver::get()->map(map)->setBlock(pos, block , 0);
		//}
		//Try to flow down
		else if(around[0][0] == BLOCK_AIR) 
		{
			Mineserver::get()->map(map)->setBlock(vectors[0], block, 1);
			addSimulation(vectors[0]);		
		}
		//Try to flow site
		else if(meta < 7 && around[0][0] != block && around[0][0] != block && (around[1][0] == BLOCK_AIR || around[2][0] == BLOCK_AIR || around[3][0] == BLOCK_AIR || around[4][0] == BLOCK_AIR)) 
		{					
			for (int i = 1; i < 5; i++)
			{
				if(around[i][0] == BLOCK_AIR) 
				{
					Mineserver::get()->map(map)->setBlock(vectors[i], block , meta + 1);
					addSimulation(vectors[i]);
				}	
			}
		}	
		//Nothing to do, dont rendering
		else 
		{
			simList[simIt].blocks[0].render = false;
		}
	}
}
Esempio n. 2
0
// Physics loop
bool Physics::update()
{
  updateFall();
  updateMinecart();
  if (!enabled)
  {
    return true;
  }

  // Check if needs to be updated
  if (simList.empty())
  {
    return true;
  }

  std::vector<vec> toAdd;
  std::vector<vec> toRem;
  std::set<vec> changed;

  clock_t starttime = clock();

  LOG(INFO, "Physics", "Simulating " + dtos(simList.size()) + " items!");

  uint32_t listSize = simList.size();

  for (uint32_t simIt = 0; simIt < listSize; simIt++)
  {
    vec pos = simList[simIt].blocks[0].pos;
    // Blocks
    uint8_t block, meta;
    ServerInstance->map(map)->getBlock(pos, &block, &meta);
    simList[simIt].blocks[0].id   = block;
    simList[simIt].blocks[0].meta = meta;

    bool used = false;
    for (int i = 0; i < 5; i++)
    {
      vec local(pos);
      bool falling = false;
      switch (i)
      {
      case 0:
        local += vec(0, -1, 0); // First tries to go down
        falling = true;
        break;
      case 1:
        local += vec(1, 0, 0); // Might be bad to have the 4 cardinal dir'
        // so predictable
        break;
      case 2:
        local += vec(-1, 0, 0);
        break;
      case 3:
        local += vec(0, 0, 1);
        break;
      case 4:
        local += vec(0, 0, -1);
        break;
      case 5:
        //        local += vec(0,1,0); // Going UP
        break;
      }
      uint8_t newblock, newmeta;
      ServerInstance->map(map)->getBlock(pos, &block, &meta);
      ServerInstance->map(map)->getBlock(local, &newblock, &newmeta);
      if (!isLiquidBlock(block))
      {
        toRem.push_back(pos);
        break;
      }
      if ((isWaterBlock(newblock) && isWaterBlock(block)) || (isLavaBlock(newblock) && isLavaBlock(block)) || (isLiquidBlock(block) && mayFallThrough(newblock)))
      {
        if (falling && !isLiquidBlock(newblock))
        {
          ServerInstance->map(map)->setBlock(local, block, meta);
          changed.insert(local);
          ServerInstance->map(map)->setBlock(pos, BLOCK_AIR, 0);
          changed.insert(pos);
          toRem.push_back(pos);
          toAdd.push_back(local);
          used = true;
          continue;
        }
        if (falling && isLiquidBlock(newblock))
        {
          int top = 8 - meta;
          int bot = 8 - newmeta;
          int volume = top + bot;
          if (volume > 8)
          {
            top = volume - 8;
            bot = 8;
          }
          else
          {
            top = 0;
            bot = volume;
          }
          int a_meta = 8 - top;
          int a_newmeta = 8 - bot;
          toAdd.push_back(local);
          if (a_meta == meta && a_newmeta == newmeta)
          {
            toRem.push_back(pos);
            toRem.push_back(local);
            continue;
          }
          if ((isWaterBlock(block) && a_meta < 8) || (isLavaBlock(block) && a_meta < 4))
          {
            ServerInstance->map(map)->setBlock(pos, block, a_meta);

            changed.insert(pos);
          }
          else
          {
            ServerInstance->map(map)->setBlock(pos, BLOCK_AIR, 0);
            changed.insert(pos);
          }
          ServerInstance->map(map)->setBlock(local, block, a_newmeta);
          used = true;
          toAdd.push_back(local);
          toAdd.push_back(pos);
          changed.insert(pos);
          continue;
        }

        if (!isLiquidBlock(newblock))
        {
          if (!falling)
          {
            if ((isWaterBlock(block) && meta == 7) || (isLavaBlock(block) && meta >= 3))
            {
              toRem.push_back(pos);
              break;
            }
          }
          // We are spreading onto dry area.
          newmeta = 7;
          ServerInstance->map(map)->setBlock(local, block, newmeta);
          changed.insert(local);
          meta++;
          if (meta < 8)
          {
            ServerInstance->map(map)->setBlock(pos, block, meta);
            changed.insert(pos);
          }
          else
          {
            ServerInstance->map(map)->setBlock(pos, BLOCK_AIR, 0);
            changed.insert(pos);
            toRem.push_back(pos);
          }
          toAdd.push_back(local);
          used = true;
          continue;
        }
        if (meta < newmeta - 1 || (meta == newmeta && falling))
        {
          newmeta --;
          ServerInstance->map(map)->setBlock(local, block, newmeta);
          changed.insert(local);
          meta ++;
          if (meta < 8)
          {
            ServerInstance->map(map)->setBlock(pos, block, meta);
            changed.insert(pos);
          }
          else
          {
            ServerInstance->map(map)->setBlock(pos, BLOCK_AIR, 0);
            changed.insert(pos);
            toRem.push_back(pos);
          }
          toAdd.push_back(local);
          used = true;
          continue;
        }
      }
    }
    if (!used)
    {
      toRem.push_back(pos);
    }
  }
  for (int i = int(toRem.size()) - 1; i >= 0; i--)
  {
    removeSimulation(toRem[i]);
  }
  for (size_t i = 0; i < toAdd.size(); i++)
  {
    addSimulation(toAdd[i]);
  }
  ServerInstance->map(map)->sendMultiBlocks(changed);

  clock_t endtime = clock() - starttime;
  //  LOG(INFO, "Physics", "Exit simulation, took " + dtos(endtime * 1000 / CLOCKS_PER_SEC) + " ms, " + dtos(simList.size()) + " items left");
  return true;
}
Esempio n. 3
0
// Physics loop
bool Physics::update()
{
	
  if (!enabled)
  {
    return true;
  }

  // Check if needs to be updated
  if (simList.empty())
  {
    return true;
  }

  std::set<vec> changed;

	//if(this->lasttime == NULL) this->lasttime = 0;
  clock_t diffTime = clock() - lasttime;

  LOG(INFO, "Physics", "Simulating " + dtos(simList.size()) + " items!");

  uint32_t listSize = simList.size();

  for (uint32_t simIt = 0; simIt < listSize; simIt++)
  {
		//Get Pos    
		vec pos = simList[simIt].blocks[0].pos;
		//Render the block?
		bool render = simList[simIt].blocks[0].render;
		//Meta -> High of water(0-7), State of redstone (15-0)     
		uint8_t block, meta;
    Mineserver::get()->map(map)->getBlock(pos, &block, &meta);

    if(isWaterBlock(block) || (isLavaBlock(block) && diffTime > 4000))
    {
      updateFluid(simIt);
      changed.insert(pos);
    }
    else if(isRedstone(block))
    {
      updateRedstone(simIt);
      changed.insert(pos);
    }
    else
   {
      removeSimulation(pos);

      uint8_t around[6][2];
      vec vectors[6];
      getBlocksAround(pos, vectors, around);
      for(int i = 0; i < 5; i ++)
      {
        addSimulation(vectors[i]);
      }
      break;
   }
  }

  Mineserver::get()->map(map)->sendMultiBlocks(changed);
  lasttime = clock();
  
  //clock_t endtime = clock() - starttime;
  //  LOG(INFO, "Physics", "Exit simulation, took " + dtos(endtime * 1000 / CLOCKS_PER_SEC) + " ms, " + dtos(simList.size()) + " items left");
	
  return true;
}