Skip to content

Commit

Permalink
Add protection for Wind Charge explosions #2422
Browse files Browse the repository at this point in the history
  • Loading branch information
tastybento committed Jul 14, 2024
1 parent 2d9bbb9 commit b2d5e0b
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.player.PlayerInteractEvent;

Expand Down Expand Up @@ -55,24 +58,37 @@ public void onPlayerInteract(PlayerInteractEvent e)
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onProjectileHit(EntityInteractEvent e)
{
if (!(e.getEntity() instanceof Projectile p))
if (e.getEntity() instanceof Projectile p && p.getShooter() instanceof Player player)
{
checkBlocks(e, player, e.getBlock());
}
}

private void checkBlocks(Event e, Player player, Block block) {
if (Tag.WOODEN_BUTTONS.isTagged(block.getType())) {
this.checkIsland(e, player, block.getLocation(), Flags.BUTTON);
return;
}

if (p.getShooter() instanceof Player player)
{
if (Tag.WOODEN_BUTTONS.isTagged(e.getBlock().getType()))
{
this.checkIsland(e, player, e.getBlock().getLocation(), Flags.BUTTON);
return;
}
if (Tag.PRESSURE_PLATES.isTagged(block.getType())) {
// Pressure plates
this.checkIsland(e, player, block.getLocation(), Flags.PRESSURE_PLATE);
}

if (Tag.PRESSURE_PLATES.isTagged(e.getBlock().getType()))
{
// Pressure plates
this.checkIsland(e, player, e.getBlock().getLocation(), Flags.PRESSURE_PLATE);
}

/**
* Protects buttons and plates from being activated by projectiles that explode
* @param e - event
*/
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onProjectileExplode(EntityExplodeEvent e) {
if (e.getEntity() instanceof Projectile p && p.getShooter() instanceof Player player) {
for (Block b : e.blockList()) {
this.checkBlocks(e, player, b);
}
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.bukkit.Bukkit;
import org.bukkit.Material;
Expand All @@ -25,6 +28,7 @@
import org.bukkit.entity.Zombie;
import org.bukkit.event.Event.Result;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.inventory.ItemStack;
Expand Down Expand Up @@ -228,4 +232,63 @@ public void testOnProjectileHitProjectilePlayer() {
assertTrue(p.name() +" failed", e.isCancelled());
});
}

/**
* Test method for {@link PhysicalInteractionListener#onProjectileExplode(org.bukkit.event.entity.EntityExplodeEvent)}.
*/
@Test
public void testOnProjectileExplodeNotProjectile() {
Entity entity = mock(Entity.class);
List<Block> blocks = new ArrayList<>();
EntityExplodeEvent e = new EntityExplodeEvent(entity, location, blocks, 0);
PhysicalInteractionListener i = new PhysicalInteractionListener();
i.onProjectileExplode(e);
assertFalse(e.isCancelled());
}

/**
* Test method for {@link PhysicalInteractionListener#onProjectileExplode(org.bukkit.event.entity.EntityExplodeEvent)}.
*/
@Test
public void testOnProjectileExplodeProjectileNoPlayer() {
Projectile entity = mock(Projectile.class);
ProjectileSource source = mock(Creeper.class);
when(entity.getShooter()).thenReturn(source);
List<Block> blocks = new ArrayList<>();
EntityExplodeEvent e = new EntityExplodeEvent(entity, location, blocks, 0);
PhysicalInteractionListener i = new PhysicalInteractionListener();
i.onProjectileExplode(e);
assertFalse(e.isCancelled());
}

/**
* Test method for {@link PhysicalInteractionListener#onProjectileExplode(org.bukkit.event.entity.EntityExplodeEvent)}.
*/
@Test
public void testOnProjectileExplodeProjectilePlayer() {
Projectile entity = mock(Projectile.class);
when(entity.getShooter()).thenReturn(mockPlayer);
List<Block> blocks = new ArrayList<>();
Block block1 = mock(Block.class);
Block block2 = mock(Block.class);
when(block1.getLocation()).thenReturn(location);
when(block2.getLocation()).thenReturn(location);
blocks.add(block1);
blocks.add(block2);

EntityExplodeEvent e = new EntityExplodeEvent(entity, location, blocks, 0);
PhysicalInteractionListener i = new PhysicalInteractionListener();

// Test with wooden button
when(block1.getType()).thenReturn(Material.OAK_BUTTON);
when(Tag.WOODEN_BUTTONS.isTagged(Material.OAK_BUTTON)).thenReturn(true);
i.onProjectileExplode(e);
verify(notifier).notify(any(), eq("protection.protected"));

// Test with pressure plate
when(block2.getType()).thenReturn(Material.STONE_PRESSURE_PLATE);
when(Tag.PRESSURE_PLATES.isTagged(Material.STONE_PRESSURE_PLATE)).thenReturn(true);
i.onProjectileExplode(e);
verify(notifier, times(3)).notify(any(), eq("protection.protected"));
}
}

0 comments on commit b2d5e0b

Please sign in to comment.