コード例 #1
0
ファイル: physics.cpp プロジェクト: chtisgit/mine152
// Add world simulation
bool Physics::addSimulation(vec pos)
{
	if (!enabled) {
		return true;
	}

	uint8_t block;
	uint8_t meta;
	map->getBlock(pos, &block, &meta);
	SimBlock simulationBlock(block, pos, meta);

	// Dont add duplicates
	for (std::vector<Sim>::iterator simIt = simList.begin(); simIt != simList.end(); simIt++) {
		vec itpos = simIt->blocks[0].pos;
		if (itpos.x() == pos.x() && itpos.y() == pos.y() && itpos.z() == pos.z()) {
			return true;
		}
	}


	// Simulating water
	if (isWaterBlock(block)) {
		simList.push_back(Sim(TYPE_WATER, simulationBlock));
		return true;
	}
	// Simulating lava
	else if (isLavaBlock(block)) {
		simList.push_back(Sim(TYPE_LAVA, simulationBlock));
		return true;
	}

	return false;
}
コード例 #2
0
ファイル: physics.cpp プロジェクト: ReDucTor/mineserver
// Add world simulation
bool Physics::addSimulation(vec pos)
{
  if(!enabled)
    return true;

  uint8 block; uint8 meta;
  Map::get()->getBlock(pos, &block, &meta);
  SimBlock simulationBlock(block, pos, meta);

  // Simulating water
  if(isWaterBlock(block))
  {
    simList.push_back(Sim(TYPE_WATER, simulationBlock));
    return true;
  }
  // Simulating lava
  else if(isLavaBlock(block))
  {
    simList.push_back(Sim(TYPE_LAVA, simulationBlock));
    return true;
  }

  return false;
}
コード例 #3
0
ファイル: physics.cpp プロジェクト: poizan42/mineserver
// 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;
}
コード例 #4
0
ファイル: physics.cpp プロジェクト: bytesnake/mineserver
// 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;
}