CoreNetwork / Mantle

The main plugin powering majority of features on Flatcore
1 stars 1 forks source link

When Enderman takes damage, sometimes teleport the player #28

Closed riddle closed 11 years ago

riddle commented 11 years ago

Implements #22

  1. Half of the time when hitting an Enderman, teleport the player (so players cannot take cover under 2 block high overhangs)
  2. Ignore rain damage
  3. From the code below, ignore the “cave” check. Also, change teleport event to damage event (some players bypass Endermen teleport by hitting them in their feet.

Extra Hard Mode code

@EventHandler
public void onEntityTeleport(EntityTeleportEvent event)
{
    Entity entity = event.getEntity();
    World world = entity.getWorld();
    if(!ExtraHardMode.instance.config_enabled_worlds.contains(world)) return;
    if(world.getEnvironment() != Environment.NORMAL) return;

    if(entity instanceof Enderman && ExtraHardMode.instance.config_improvedEndermanTeleportation)
    {
        Enderman enderman = (Enderman)entity;

        //ignore endermen which aren't fighting players
        if(enderman.getTarget() == null || !(enderman.getTarget() instanceof Player)) return;

        //ignore endermen which are taking damage from the environment (to avoid rapid teleportation due to rain or suffocation)
        if(enderman.getLastDamageCause() != null && enderman.getLastDamageCause().getCause() != DamageCause.ENTITY_ATTACK) return;

        //ignore endermen which are in caves (standing on stone)
        if(enderman.getLocation().getBlock().getRelative(BlockFace.DOWN).getType() == Material.STONE) return;

        Player player = (Player)enderman.getTarget();

        //ignore when player is in a different world from the enderman
        if(!player.getWorld().equals(enderman.getWorld())) return;

        //half the time, teleport the player instead
        if(ExtraHardMode.random(50))
        {       
            event.setCancelled(true);
            int distanceSquared = (int)player.getLocation().distanceSquared(enderman.getLocation());

            //play sound at old location
            world.playSound(player.getLocation(), Sound.ENDERMAN_TELEPORT, 1, 1);
            Block destinationBlock;

            //if the player is far away
            if(distanceSquared > 75)
            {
                //have the enderman swap places with the player
                destinationBlock = enderman.getLocation().getBlock();
                enderman.teleport(player.getLocation());
            }

            //otherwise if the player is close
            else
            {
                //teleport the player to the enderman's destination
                destinationBlock = event.getTo().getBlock();                
            }

            while(destinationBlock.getType() != Material.AIR || destinationBlock.getRelative(BlockFace.UP).getType() != Material.AIR)
            {
                destinationBlock = destinationBlock.getRelative(BlockFace.UP);
            }

            player.teleport(destinationBlock.getLocation(), TeleportCause.ENDER_PEARL);

            //play sound at new location
            world.playSound(player.getLocation(), Sound.ENDERMAN_TELEPORT, 1, 1);
        }
    }
}
matejdro commented 11 years ago

Teleport player how?

To them or to some random location?

riddle commented 11 years ago

The plugin has this:

//teleport the player to the enderman's destination

So it might be a bit overpowered (basically instant damage for at least 1 tick, possibly more which could mean instant death) so let’s return to this issue later. Not important right now.

riddle commented 11 years ago

Closing the issue now as we need a robust random teleporting system to allow this interaction to be interesting and challenging rather than frustrating.