Ir para conteúdo
  • 0

Stackar


Ygor

Pergunta

Olá,

Gostaria de saber como eu poderia estar blocos (igual estacar spawners e máquinas), por exemplo.

Um jogador põe um bloco de diamante, a partir daí, os blocos que ele colocar em uma área de 3x3 ao redor deste bloco seriam estacadas e salvas em um arquivo .yml

Ao quebrar, o bloco droparia a quantidade que foi estacada.

 

Espero que tenha ficado claro, estou fazendo o tópico com um pouquinho de pressa.

 

Obrigado pela atenção.

Link para o comentário
Compartilhar em outros sites

5 respostass a esta questão

Posts Recomendados

  • 0

Utilizaremos uma hashmap para armazenar os blocos estacados.

public HashMap<Location, Integer> blocosEstacados = new HashMap<>();

logo após, você precisará fazer um for para pegar o radius de onde o jogador está colocando o bloco

	@EventHandler
	public void _Gambiarra(BlockBreakEvent e) {
		Player p = (Player) e.getPlayer();
		Block currentBlock = null;
		Location location = null;
		for (int xOff = -1; xOff <= 1; ++xOff) {
			for (int yOff = -2; yOff <= 0; ++yOff) { // NOTE this goes from -2 to 0, not -1 to +1
				for (int zOff = -1; zOff <= 1; ++zOff) {
					currentBlock = e.getBlock().getRelative(xOff, yOff, zOff);
					if (currentBlock != null && blocosEstacados.containsKey(currentBlock.getLocation())) {
						location = currentBlock.getLocation();
						break;
					}
					continue;
				}
			}
		}
		
		if (location != null) {
			e.setCancelled(true);
			if (p.getItemInHand().getAmount() > 1) {
				p.getItemInHand().setAmount(p.getItemInHand().getAmount() - 1);
			} else {
				p.setItemInHand(null);
			}
			int atual = blocosEstacados.get(location);
			blocosEstacados.remove(location);
			blocosEstacados.put(location, (atual + 1));
		} else {
			blocosEstacados.put(e.getBlock().getLocation(), 1);
		}
	}

Não repare na gambiarra, é só um modelo.

 

E então, logo após fazer tudo isso, é só fazer um for na hashmap com os valores dos blocos estacados e salvar na config.

Fazer esse tanto de for nesse evento... é provavelmente a ram do servidor vai ir embora.

Link para o comentário
Compartilhar em outros sites

  • 0

Não sei se é o método mais eficiente, mas ele funciona.

Fiz com streams, daí ele filtra as localizações por perto, se não tiver nenhuma ele adiciona no mapa.

Mas se já tiver, ele cancela o evento e coloca no mapa.

private Map<Location, Integer> blocks = new HashMap<>();

@EventHandler
public void onPlace(BlockPlaceEvent e) {
	Block block = e.getBlock();
	if (block.getType() == Material.DIAMOND_BLOCK) { // Verifica se o bloco é de diamante
		Location loc1 = block.getLocation(); // Pega a localização do bloco
			
		Object[] array = blocks.keySet().stream() // Pega um stream das chaves do mapa
			.filter(l -> isNear(loc1, l, 3)) // Filtra as localizações por localizações próximas
			.toArray(); // Pega a localização que está dentro do filtro estabelecido
			
		if (array.length == 0) // Se a array estiver vazia, não há blocos por perto
			blocks.put(loc1, 1); // Adiciona a localização do bloco no mapa
		else {
			block.setType(Material.AIR); // Muda o material do bloco para AIR
			blocks.replace((Location) array[0], blocks.get(array[0]) + 1); // Atualiza o mapa, adicionando + 1
		}
	}
}
	
private boolean isNear(Location o1, Location o2, int range) {
	if (Math.abs(o1.getX() - o2.getX()) <= range
			&& Math.abs(o1.getY() - o2.getY()) <= range
			&& Math.abs(o1.getZ() - o2.getZ()) <= range)
		return true;
	return false;
}

Daí quando o jogador quebra um bloco de diamante, ele verifica se a localização daquele bloco está dentro do mapa

Se estiver, ele cancela o evento, quebra o bloco naturalmente e dropa os blocos na quantidade que estava no mapa.

@EventHandler
public void onBreak(BlockBreakEvent e) {
	Block block = e.getBlock();
	if (block.getType() == Material.DIAMOND_BLOCK) {
		Location loc = block.getLocation();
			
		if (blocks.containsKey(loc)) { // Verifica se a localização está no mapa
			e.setCancelled(true); // Cancela o evento
			block.breakNaturally(); // Quebra o bloco naturalmente
				
			loc.getWorld().dropItemNaturally(loc, new ItemStack(Material.DIAMOND_BLOCK, blocks.get(loc)-1)); // Dropa os blocos
				
			blocks.remove(loc); // Remove a localização do mapa
		}
	}
}
Editado por Out of Orbit
Link para o comentário
Compartilhar em outros sites

Visitante
Este tópico está impedido de receber novos posts.
×
×
  • Criar Novo...