mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-11-23 11:15:24 +01:00
Fixed and improved Breeding protection
It wasn't catching breeding with some newer animals (Pandas, Foxes...), was a bit overprotective (it could prevent feeding some animals), or wasn't catching some breeding items (Golden Carrots, ...). I rewrote it so that every animal is now protected with the foods that actually make them breed (based off the MC wiki page about Breeding). Once we will move to 1.15 API, we will have to add BEES in that.
This commit is contained in:
parent
cc0d981e62
commit
120be13b36
@ -1,10 +1,14 @@
|
||||
package world.bentobox.bentobox.listeners.flags.protection;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
|
||||
@ -25,23 +29,42 @@ public class BreedingListener extends FlagListener {
|
||||
/**
|
||||
* A list of items that cause breeding if a player has them in their hand and they click an animal
|
||||
* This list may need to be extended with future versions of Minecraft.
|
||||
* See this Minecraft Wiki page for reference: https://minecraft.gamepedia.com/Breeding#Breeding_foods.
|
||||
*/
|
||||
private static final List<Material> BREEDING_ITEMS = Arrays.asList(
|
||||
Material.EGG,
|
||||
Material.WHEAT,
|
||||
Material.CARROT,
|
||||
Material.WHEAT_SEEDS,
|
||||
Material.SEAGRASS);
|
||||
private static final ImmutableMap<EntityType, List<Material>> BREEDING_ITEMS = new ImmutableMap.Builder<EntityType, List<Material>>()
|
||||
.put(EntityType.HORSE, Arrays.asList(Material.GOLDEN_APPLE, Material.GOLDEN_CARROT))
|
||||
.put(EntityType.DONKEY, Arrays.asList(Material.GOLDEN_APPLE, Material.GOLDEN_CARROT))
|
||||
.put(EntityType.COW, Collections.singletonList(Material.WHEAT))
|
||||
.put(EntityType.MUSHROOM_COW, Collections.singletonList(Material.WHEAT))
|
||||
.put(EntityType.SHEEP, Collections.singletonList(Material.WHEAT))
|
||||
.put(EntityType.PIG, Arrays.asList(Material.CARROT, Material.POTATO, Material.BEETROOT))
|
||||
.put(EntityType.CHICKEN, Arrays.asList(Material.WHEAT_SEEDS, Material.PUMPKIN_SEEDS, Material.MELON_SEEDS, Material.BEETROOT_SEEDS))
|
||||
.put(EntityType.WOLF, Arrays.asList(Material.PORKCHOP, Material.COOKED_PORKCHOP, Material.BEEF, Material.COOKED_BEEF,
|
||||
Material.CHICKEN, Material.COOKED_CHICKEN, Material.RABBIT, Material.COOKED_RABBIT,
|
||||
Material.MUTTON, Material.COOKED_MUTTON, Material.ROTTEN_FLESH))
|
||||
.put(EntityType.CAT, Arrays.asList(Material.COD, Material.SALMON))
|
||||
.put(EntityType.OCELOT, Arrays.asList(Material.COD, Material.SALMON))
|
||||
.put(EntityType.RABBIT, Arrays.asList(Material.DANDELION, Material.CARROT, Material.GOLDEN_CARROT))
|
||||
.put(EntityType.LLAMA, Collections.singletonList(Material.HAY_BLOCK))
|
||||
.put(EntityType.TRADER_LLAMA, Collections.singletonList(Material.HAY_BLOCK))
|
||||
.put(EntityType.TURTLE, Collections.singletonList(Material.SEAGRASS))
|
||||
.put(EntityType.PANDA, Collections.singletonList(Material.BAMBOO))
|
||||
.put(EntityType.FOX, Collections.singletonList(Material.SWEET_BERRIES))
|
||||
.build();
|
||||
|
||||
//TODO: add bees when switching to 1.15.x only
|
||||
|
||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
||||
public void onPlayerInteract(final PlayerInteractAtEntityEvent e) {
|
||||
if (e.getRightClicked() instanceof Animals) {
|
||||
ItemStack inHand = e.getPlayer().getInventory().getItemInMainHand();
|
||||
Player p = e.getPlayer();
|
||||
if (e.getRightClicked() instanceof Animals && BREEDING_ITEMS.containsKey(e.getRightClicked().getType())) {
|
||||
Animals animal = (Animals) e.getRightClicked();
|
||||
ItemStack inHand = p.getInventory().getItemInMainHand();
|
||||
if (e.getHand().equals(EquipmentSlot.OFF_HAND)) {
|
||||
inHand = e.getPlayer().getInventory().getItemInOffHand();
|
||||
inHand = p.getInventory().getItemInOffHand();
|
||||
}
|
||||
if (BREEDING_ITEMS.contains(inHand.getType()) && !checkIsland(e, e.getPlayer(), e.getRightClicked().getLocation(), Flags.BREEDING)) {
|
||||
((Animals)e.getRightClicked()).setBreed(false);
|
||||
if (BREEDING_ITEMS.get(animal.getType()).contains(inHand.getType()) && !checkIsland(e, p, animal.getLocation(), Flags.BREEDING)) {
|
||||
animal.setBreed(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,3 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package world.bentobox.bentobox.listeners.flags.protection;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@ -8,12 +5,12 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.logging.Logger;
|
||||
@ -26,6 +23,7 @@ import org.bukkit.World;
|
||||
import org.bukkit.entity.Animals;
|
||||
import org.bukkit.entity.Cow;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Slime;
|
||||
import org.bukkit.entity.Zombie;
|
||||
@ -80,12 +78,9 @@ public class BreedingListenerTest {
|
||||
private ItemStack itemInOffHand;
|
||||
private IslandWorldManager iwm;
|
||||
|
||||
private static final List<Material> BREEDING_ITEMS = Arrays.asList(
|
||||
Material.EGG,
|
||||
Material.WHEAT,
|
||||
Material.CARROT,
|
||||
Material.WHEAT_SEEDS,
|
||||
Material.SEAGRASS);
|
||||
private static final EntityType ENTITY_TYPE = EntityType.COW;
|
||||
private static final Material BREEDABLE_WITH = Material.WHEAT;
|
||||
private static final Material NOT_BREEDABLE_WITH = Material.SEAGRASS;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
@ -211,7 +206,7 @@ public class BreedingListenerTest {
|
||||
public void testOnPlayerInteractNotAnimal() {
|
||||
Entity clickedEntity = mock(Entity.class);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position);
|
||||
new BreedingListener().onPlayerInteract(e);
|
||||
assertFalse("Not animal failed", e.isCancelled());
|
||||
}
|
||||
@ -221,10 +216,9 @@ public class BreedingListenerTest {
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerInteractAnimalNothingInMainHand() {
|
||||
|
||||
Animals clickedEntity = mock(Animals.class);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position);
|
||||
new BreedingListener().onPlayerInteract(e);
|
||||
assertFalse("Animal, nothing in main hand failed", e.isCancelled());
|
||||
}
|
||||
@ -236,7 +230,7 @@ public class BreedingListenerTest {
|
||||
public void testOnPlayerInteractAnimalNothingInOffHand() {
|
||||
Animals clickedEntity = mock(Animals.class);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position, EquipmentSlot.OFF_HAND);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position, EquipmentSlot.OFF_HAND);
|
||||
new BreedingListener().onPlayerInteract(e);
|
||||
assertFalse("Animal, nothing in off hand failed", e.isCancelled());
|
||||
}
|
||||
@ -249,16 +243,19 @@ public class BreedingListenerTest {
|
||||
public void testOnPlayerInteractAnimalBreedingFoodInMainHandNotRightWorld() {
|
||||
Animals clickedEntity = mock(Animals.class);
|
||||
when(clickedEntity.getLocation()).thenReturn(location);
|
||||
when(clickedEntity.getType()).thenReturn(ENTITY_TYPE);
|
||||
when(iwm.inWorld(any(World.class))).thenReturn(false);
|
||||
when(iwm.inWorld(any(Location.class))).thenReturn(false);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position);
|
||||
BreedingListener bl = new BreedingListener();
|
||||
for (Material breedingMat : BREEDING_ITEMS) {
|
||||
when(itemInMainHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertFalse("Animal, breeding item in main hand, wrong world failed " + breedingMat, e.isCancelled());
|
||||
}
|
||||
|
||||
Material breedingMat = BREEDABLE_WITH;
|
||||
|
||||
when(itemInMainHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertFalse("Animal, breeding item in main hand, wrong world failed " + breedingMat, e.isCancelled());
|
||||
|
||||
// verify breeding was prevented
|
||||
Mockito.verify(clickedEntity, Mockito.never()).setBreed(false);
|
||||
}
|
||||
@ -270,16 +267,19 @@ public class BreedingListenerTest {
|
||||
public void testOnPlayerInteractAnimalBreedingFoodInMainHand() {
|
||||
Animals clickedEntity = mock(Animals.class);
|
||||
when(clickedEntity.getLocation()).thenReturn(location);
|
||||
when(clickedEntity.getType()).thenReturn(EntityType.COW);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position);
|
||||
BreedingListener bl = new BreedingListener();
|
||||
for (Material breedingMat : BREEDING_ITEMS) {
|
||||
when(itemInMainHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertTrue("Animal, breeding item in main hand failed " + breedingMat, e.isCancelled());
|
||||
}
|
||||
|
||||
Material breedingMat = BREEDABLE_WITH;
|
||||
|
||||
when(itemInMainHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertTrue("Animal, breeding item in main hand failed " + breedingMat, e.isCancelled());
|
||||
|
||||
// verify breeding was prevented
|
||||
Mockito.verify(clickedEntity, Mockito.times(5)).setBreed(false);
|
||||
Mockito.verify(clickedEntity).setBreed(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -292,34 +292,56 @@ public class BreedingListenerTest {
|
||||
when(iwm.inWorld(any(World.class))).thenReturn(false);
|
||||
when(iwm.inWorld(any(Location.class))).thenReturn(false);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position, EquipmentSlot.OFF_HAND);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position, EquipmentSlot.OFF_HAND);
|
||||
BreedingListener bl = new BreedingListener();
|
||||
for (Material breedingMat : BREEDING_ITEMS) {
|
||||
when(itemInOffHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertFalse("Animal, breeding item in off hand, wrong world failed " + breedingMat, e.isCancelled());
|
||||
}
|
||||
|
||||
Material breedingMat = BREEDABLE_WITH;
|
||||
|
||||
when(itemInOffHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertFalse("Animal, breeding item in off hand, wrong world failed " + breedingMat, e.isCancelled());
|
||||
|
||||
// verify breeding was not prevented
|
||||
Mockito.verify(clickedEntity, Mockito.never()).setBreed(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* I am not sure if breeding with off hand is possible!
|
||||
* Test method for {@link BreedingListener#onPlayerInteract(org.bukkit.event.player.PlayerInteractAtEntityEvent)}.
|
||||
*/
|
||||
@Test
|
||||
public void testOnPlayerInteractAnimalBreedingFoodInOffHand() {
|
||||
Animals clickedEntity = mock(Animals.class);
|
||||
when(clickedEntity.getLocation()).thenReturn(location);
|
||||
when(clickedEntity.getType()).thenReturn(ENTITY_TYPE);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity , position, EquipmentSlot.OFF_HAND);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position, EquipmentSlot.OFF_HAND);
|
||||
BreedingListener bl = new BreedingListener();
|
||||
for (Material breedingMat : BREEDING_ITEMS) {
|
||||
when(itemInOffHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertTrue("Animal, breeding item in off hand failed " + breedingMat, e.isCancelled());
|
||||
}
|
||||
|
||||
Material breedingMat = BREEDABLE_WITH;
|
||||
when(itemInOffHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertTrue("Animal, breeding item in off hand failed " + breedingMat, e.isCancelled());
|
||||
|
||||
// verify breeding was prevented
|
||||
Mockito.verify(clickedEntity, Mockito.times(5)).setBreed(false);
|
||||
Mockito.verify(clickedEntity).setBreed(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnPlayerIntereactAnimalBreedingWrongFood() {
|
||||
Animals clickedEntity = mock(Animals.class);
|
||||
when(clickedEntity.getLocation()).thenReturn(location);
|
||||
when(clickedEntity.getType()).thenReturn(EntityType.COW);
|
||||
Vector position = new Vector(0,0,0);
|
||||
PlayerInteractAtEntityEvent e = new PlayerInteractAtEntityEvent(player, clickedEntity, position);
|
||||
BreedingListener bl = new BreedingListener();
|
||||
|
||||
Material breedingMat = NOT_BREEDABLE_WITH;
|
||||
|
||||
when(itemInMainHand.getType()).thenReturn(breedingMat);
|
||||
bl.onPlayerInteract(e);
|
||||
assertFalse("Animal, breeding item in main hand was prevented " + breedingMat, e.isCancelled());
|
||||
|
||||
// verify breeding was prevented
|
||||
Mockito.verify(clickedEntity, never()).setBreed(false);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user