package net.glowstone.net.handler.play.player;
import com.flowpowered.networking.MessageHandler;
import net.glowstone.EventFactory;
import net.glowstone.GlowServer;
import net.glowstone.constants.AttackDamage;
import net.glowstone.entity.GlowEntity;
import net.glowstone.entity.GlowLivingEntity;
import net.glowstone.entity.GlowPlayer;
import net.glowstone.net.GlowSession;
import net.glowstone.net.message.play.player.InteractEntityMessage;
import org.bukkit.GameMode;
import org.bukkit.Material;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.inventory.ItemStack;
public final class InteractEntityHandler implements MessageHandler<GlowSession, InteractEntityMessage> {
@Override
public void handle(GlowSession session, InteractEntityMessage message) {
GlowPlayer player = session.getPlayer();
// You can't do anything when you're dead
if (player.isDead()) {
GlowServer.logger.info("Player " + player.getName() + " tried to interact with an entity while dead");
return;
}
GlowEntity possibleTarget = player.getWorld().getEntityManager().getEntity(message.getId());
GlowLivingEntity target = possibleTarget instanceof GlowLivingEntity ? (GlowLivingEntity) possibleTarget : null;
if (message.getAction() == InteractEntityMessage.Action.ATTACK.ordinal()) {
if (target == null) {
if (possibleTarget != null) {
possibleTarget.entityInteract(player, message);
} else {
GlowServer.logger.info("Player " + player.getName() + " tried to attack an entity that does not exist");
}
} else if (!target.isDead() && target.canTakeDamage(EntityDamageEvent.DamageCause.ENTITY_ATTACK)) {
// Calculate damage amount
ItemStack hand = player.getItemInHand();
Material type = hand == null ? Material.AIR : hand.getType();
// todo: Actual critical hit check
float damage = AttackDamage.getMeleeDamage(type, false);
// Apply damage. Calls the EntityDamageByEntityEvent
target.damage(damage, player, EntityDamageEvent.DamageCause.ENTITY_ATTACK);
// Apply durability loss (if applicable)
short durabilityLoss = AttackDamage.getMeleeDurabilityLoss(type);
if (durabilityLoss > 0 && hand != null && player.getGameMode() != GameMode.CREATIVE) {
// Yes, this actually subtracts
hand.setDurability((short) (hand.getDurability() + durabilityLoss));
}
}
} else if (message.getAction() == InteractEntityMessage.Action.INTERACT_AT.ordinal()) {
// todo: Interaction with entity at a specified location (X, Y, and Z are present in the message)
// used for adjusting specific portions of armor stands
} else if (message.getAction() == InteractEntityMessage.Action.INTERACT.ordinal()) {
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, possibleTarget);
EventFactory.callEvent(event);
if (!event.isCancelled()) {
possibleTarget.entityInteract(player, message);
}
} else {
GlowServer.logger.info("Player " + player.getName() + " sent unknown interact action: " + message.getAction());
}
}
}