@Overridepublic void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) { if (!entity.isPlayer()){ return; } var player = (PlayerEntity)entity; var items = player.getHandItems().iterator(); var isItemInHand = Lists.newArrayList(items).contains(stack); if (!isItemInHand){ return; } super.inventoryTick(stack, world, entity, slot, selected); }
Vyhledání entit v okolí hráče
Nejprve musíme získat všechny creepery v určitém okolí hráče. To se dělá tak, že určíme oblast (kvádr), kde chceme entity hledat a poté určíme typ entit, který nás zajímá.
Kvádr bude umístěný okolo hráče, takže si nejprve získáme souřadnice, kde hráč stojí.
var playerPos = player.getPos();
Dále si určíme vzdálenost, do které chceme creepery hledat. Tu musíme určit ve všech 3 směrech.
var distance = new Vec3d(10, 10, 10);
v tomto případě budeme hledat creepery do vzdálenost 10 bloků ve všech směrech
Nyní si ze souřadnic hráče a vzdálenosti vytvoříme kvádr (box). U třídy Box určujeme 2 protější rohy oblasti. Tu získáme tak, že nejprve od souřadnic hráče vzdálenost odečteme (subtract) a pro druhý roh vzdálenost naopak přičteme (add).
var box = new Box(playerPos.subtract(distance), playerPos.add(distance));
Nakonec vše spojíme a pomocí metody getEntitiesByClass ze třídy World získáme všechny entity v dané oblasti, které mají třídu CreeperEntity. Výsledkem bude seznam creeperů.
var creepers = world.getEntitiesByClass(CreeperEntity.class, box, creeperEntity -> creeperEntity.distanceTo(player) < 10);
argument je třída entit, které chceme vybrat
argument je oblast, ve které chceme entity hledat
argument je funkce, pomocí které můžeme entity filtrovat
Filtrování entit
U každého creepera (creeperEntity) můžeme provést ještě dodatečnou kontrolu.
Kdybychom pro výběr použili jen box, tak se vyberou i entity, které jsou dál, než 10 bloků, protože se vybírá ve čtvercové oblasti. Pokud ale chceme vybrat opravdu jen creepery do vzdálenosti 10 bloků, tak můžeme ještě dodatečně zkontrolovat vzdálenost každého creepera k hráči. Poté bude oblast výběru kruhová.
@Overridepublic void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) { if (!entity.isPlayer()) { return; } var player = (PlayerEntity) entity; var items = player.getHandItems().iterator(); var isItemInHand = Lists.newArrayList(items).contains(stack); if (!isItemInHand) { return; } var playerPos = player.getPos(); var distance = new Vec3d(10, 10, 10); var box = new Box(playerPos.subtract(distance), playerPos.add(distance)); var creepers = world.getEntitiesByClass(CreeperEntity.class, box, creeperEntity -> creeperEntity.distanceTo(player) < 10); super.inventoryTick(stack, world, entity, slot, selected);
Zabránění výbuchu creepera
Když se creeper přiblíží k hráči, tak se aktivuje odpočet do výbuchu (fuse). Tento odpočet nemůžeme měnit, ale můžeme změnit rychlost odpočtu. V základu je tato rychlost nastavená na 1. Pokud ale rychlost změníme na -1, tak se creeper vrátí do neaktivovaného stavu. To uděláme pomocí metody setFuseSpeed() ze třídy CreeperEntity.
Abychom takhle deaktivovali všechny creepery, tak musíme postupně projít seznam creeperů v proměnné creepers a u každého creepera odpočet resetovat zvlášť.
Seznam se prochází pomocí smyčky for. Používá se následujícím způsobem:
for (var creeper : creepers) { }
Za dvojtečkou máme seznam, který chceme procházet. Před dvojtečkou pak máme proměnnou, kam se nám vždy uloží aktuální creeper z daného seznamu.
Dále nám jen stačí každého creepera deaktivovat:
for (var creeper : creepers) { creeper.setFuseSpeed(-1); }
Poznámka
Poslední řádek v metodě inventoryTick můžeme smazat, protože nic nedělá.
@Overridepublic void inventoryTick(ItemStack stack, World world, Entity entity, int slot, boolean selected) { if (!entity.isPlayer()) { return; } var player = (PlayerEntity) entity; var items = player.getHandItems().iterator(); var isItemInHand = Lists.newArrayList(items).contains(stack); if (!isItemInHand) { return; } var playerPos = player.getPos(); var distance = new Vec3d(10, 10, 10); var box = new Box(playerPos.subtract(distance), playerPos.add(distance)); var creepers = world.getEntitiesByClass(CreeperEntity.class, box, creeperEntity -> creeperEntity.distanceTo(player) < 10); for (var creeper : creepers) { creeper.setFuseSpeed(-1); }
Nyní by nám item měl fungovat a pokud jej máme v jedné nebo druhé ruce, tak by u nás neměl vybouchnout žádný creeper. Pro testování musíte být v survival nebo adventure módu.