use of net.glowstone.EventFactory in project Glowstone by GlowstoneMC.
the class DiggingHandler method handle.
@Override
public void handle(GlowSession session, DiggingMessage message) {
GlowPlayer player = session.getPlayer();
GlowWorld world = player.getWorld();
EventFactory eventFactory = EventFactory.getInstance();
GlowBlock block = world.getBlockAt(message.getX(), message.getY(), message.getZ());
BlockFace face = BlockPlacementHandler.convertFace(message.getFace());
ItemStack holding = player.getItemInHand();
if (block.getRelative(face).getType() == Material.FIRE) {
block.getRelative(face).breakNaturally();
// returns to avoid breaking block in creative
return;
}
boolean blockBroken = false;
boolean revert = false;
Material material = block.getType();
switch(message.getState()) {
case START_DIGGING:
if (block.equals(player.getDigging()) || block.isLiquid()) {
return;
}
// call interact event
Action action = Action.LEFT_CLICK_BLOCK;
Block eventBlock = block;
if (player.getLocation().distanceSquared(block.getLocation()) > 36 || ExtraMaterialTags.AIR_VARIANTS.isTagged(material)) {
action = Action.LEFT_CLICK_AIR;
eventBlock = null;
}
PlayerInteractEvent interactEvent = eventFactory.onPlayerInteract(player, action, EquipmentSlot.HAND, eventBlock, face);
// attempt to use item in hand, that is, dig up the block
if (!BlockPlacementHandler.selectResult(interactEvent.useItemInHand(), true)) {
// the event was cancelled, get out of here
revert = true;
} else if (player.getGameMode() != GameMode.SPECTATOR) {
player.setDigging(null);
// emit damage event - cancel by default if holding a sword
boolean instaBreak = player.getGameMode() == GameMode.CREATIVE || block.getMaterialValues().getHardness() == 0;
BlockDamageEvent damageEvent = new BlockDamageEvent(player, block, player.getItemInHand(), instaBreak);
if (player.getGameMode() == GameMode.CREATIVE && holding != null && EnchantmentTarget.WEAPON.includes(holding.getType())) {
damageEvent.setCancelled(true);
}
eventFactory.callEvent(damageEvent);
// follow orders
if (damageEvent.isCancelled()) {
revert = true;
} else {
// in creative, break even if denied in the event, or the block
// can never be broken (client does not send DONE_DIGGING).
blockBroken = damageEvent.getInstaBreak();
if (!blockBroken) {
// TODO: add a delay here based on hardness
player.setDigging(block);
}
}
}
break;
case DiggingMessage.CANCEL_DIGGING:
player.setDigging(null);
break;
case DiggingMessage.FINISH_DIGGING:
// untrusted)
break;
case DiggingMessage.STATE_DROP_ITEM:
player.dropItemInHand(false);
return;
case DiggingMessage.STATE_DROP_ITEMSTACK:
player.dropItemInHand(true);
return;
case DiggingMessage.STATE_SHOT_ARROW_FINISH_EATING:
final ItemStack usageItem = player.getUsageItem();
if (usageItem != null) {
if (Objects.equals(usageItem, holding)) {
ItemType type = ItemTable.instance().getItem(usageItem.getType());
if (type != null && type instanceof ItemTimedUsage) {
((ItemTimedUsage) type).endUse(player, usageItem);
} else {
// todo: inform the player that this item cannot be consumed/used
}
} else {
// todo: verification against malicious clients
// todo: inform player their item is wrong
}
}
return;
case DiggingMessage.SWAP_ITEM_IN_HAND:
ItemStack main = player.getInventory().getItemInMainHand();
ItemStack off = player.getInventory().getItemInOffHand();
PlayerSwapHandItemsEvent event = EventFactory.getInstance().callEvent(new PlayerSwapHandItemsEvent(player, off, main));
if (!event.isCancelled()) {
player.getInventory().setItemInOffHand(main);
player.getInventory().setItemInMainHand(off);
player.updateInventory();
}
return;
default:
return;
}
if (blockBroken && !revert) {
// fire the block break event
BlockBreakEvent breakEvent = eventFactory.callEvent(new BlockBreakEvent(block, player));
if (breakEvent.isCancelled()) {
BlockPlacementHandler.revert(player, block);
return;
}
MaterialData data = block.getState().getData();
if (ExtraMaterialTags.BISECTED_BLOCKS.isTagged(material)) {
if (block.getRelative(BlockFace.DOWN).getType() == material) {
block = block.getRelative(BlockFace.DOWN);
}
}
BlockType blockType = ItemTable.instance().getBlock(material);
if (blockType != null) {
blockType.blockDestroy(player, block, face);
}
// destroy the block
if (!block.isEmpty() && !block.isLiquid() && (player.getGameMode() != GameMode.CREATIVE || blockType instanceof BlockContainer) && world.getGameRuleMap().getBoolean(GameRules.DO_TILE_DROPS)) {
Collection<ItemStack> drops = blockType.getDrops(block, holding);
if (blockType instanceof BlockContainer && player.getGameMode() == GameMode.CREATIVE) {
drops = ((BlockContainer) blockType).getContentDrops(block);
}
for (ItemStack drop : drops) {
GlowItem item = world.dropItemNaturally(block.getLocation(), drop);
item.setPickupDelay(30);
item.setBias(player);
}
}
player.addExhaustion(0.005f);
// STEP_SOUND actually is the block break particles
world.playEffectExceptTo(block.getLocation(), Effect.STEP_SOUND, block.getType().getId(), 64, player);
GlowBlockState state = block.getState();
block.setType(Material.AIR);
if (blockType != null) {
blockType.afterDestroy(player, block, face, state);
}
} else if (revert) {
// replace the block that wasn't really dug
BlockPlacementHandler.revert(player, block);
} else if (!ExtraMaterialTags.AIR_VARIANTS.isTagged(material)) {
BlockType blockType = ItemTable.instance().getBlock(material);
blockType.leftClickBlock(player, block, holding);
}
}
use of net.glowstone.EventFactory in project Glowstone by GlowstoneMC.
the class InteractEntityHandler method handle.
@Override
public void handle(GlowSession session, InteractEntityMessage message) {
GlowPlayer player = session.getPlayer();
EventFactory eventFactory = EventFactory.getInstance();
// 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;
EquipmentSlot hand = message.getHandSlot();
if (message.getAction() == 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(DamageCause.ENTITY_ATTACK)) {
// Calculate damage amount
ItemStack itemInHand = InventoryUtil.itemOrEmpty(player.getInventory().getItem(hand));
Material type = itemInHand.getType();
boolean critical = player.getFallDistance() > 0.0F && !player.isOnGround() && !player.isInWater() && !player.isInsideVehicle() && !player.isSprinting();
float damage = AttackDamage.getMeleeDamage(type, critical);
if (critical) {
// Critical-hit effect
target.playAnimation(EntityAnimation.CRITICAL_HIT);
}
// Set entity on fire if the item has Fire Aspect
if (itemInHand.containsEnchantment(Enchantment.FIRE_ASPECT)) {
target.setFireTicks(target.getFireTicks() + itemInHand.getEnchantmentLevel(Enchantment.FIRE_ASPECT) * 80);
}
boolean showMagicCrit = false;
// Apply other enchantments that amplify damage
if (itemInHand.containsEnchantment(Enchantment.DAMAGE_ALL)) {
// Sharpness
int level = itemInHand.getEnchantmentLevel(Enchantment.DAMAGE_ALL);
if (level > 0) {
damage += 1.0F + 0.5F * (level - 1);
}
if (!showMagicCrit) {
showMagicCrit = ToolType.SWORD.matches(type) || ToolType.AXE.matches(type);
}
}
if (itemInHand.containsEnchantment(Enchantment.DAMAGE_ARTHROPODS)) {
// Endermites)
if (target.isArthropod()) {
int level = itemInHand.getEnchantmentLevel(Enchantment.DAMAGE_ARTHROPODS);
if (level > 0) {
damage += level * 2.5F;
// TODO: add Slowness potion effect (after damaging and checking for
// event-cancellation)
}
}
if (!showMagicCrit) {
showMagicCrit = ToolType.SWORD.matches(type) || ToolType.AXE.matches(type);
}
}
if (itemInHand.containsEnchantment(Enchantment.DAMAGE_UNDEAD)) {
// Smite (applies to "undead" mobs)
if (target.isUndead()) {
int level = itemInHand.getEnchantmentLevel(Enchantment.DAMAGE_UNDEAD);
damage += level * 2.5F;
}
if (!showMagicCrit) {
showMagicCrit = ToolType.SWORD.matches(type) || ToolType.AXE.matches(type);
}
}
if (showMagicCrit) {
target.playAnimation(EntityAnimation.MAGIC_CRITICAL_HIT);
}
// Apply damage. Calls the EntityDamageByEntityEvent
target.damage(damage, player, DamageCause.ENTITY_ATTACK);
player.incrementStatistic(Statistic.DAMAGE_DEALT, Math.round(damage));
player.addExhaustion(0.1f);
if (target.isDead()) {
player.incrementStatistic(target.getType() == EntityType.PLAYER ? Statistic.PLAYER_KILLS : Statistic.MOB_KILLS);
}
// Apply durability loss (if applicable)
short durabilityLoss = AttackDamage.getMeleeDurabilityLoss(type);
if (durabilityLoss > 0 && !InventoryUtil.isEmpty(itemInHand) && player.getGameMode() != GameMode.CREATIVE) {
// Yes, this actually subtracts
itemInHand.setDurability((short) (itemInHand.getDurability() + durabilityLoss));
}
}
} else if (message.getAction() == Action.INTERACT_AT.ordinal()) {
// used for adjusting specific portions of armor stands
PlayerInteractAtEntityEvent event = new PlayerInteractAtEntityEvent(player, possibleTarget, new Vector(message.getTargetX(), message.getTargetY(), message.getTargetZ()), hand);
eventFactory.callEvent(event);
if (!event.isCancelled()) {
possibleTarget.entityInteract(player, message);
}
} else if (message.getAction() == Action.INTERACT.ordinal()) {
// Todo: Handle hand variable
PlayerInteractEntityEvent event = new PlayerInteractEntityEvent(player, possibleTarget, hand);
eventFactory.callEvent(event);
if (!event.isCancelled()) {
possibleTarget.entityInteract(player, message);
}
} else {
GlowServer.logger.info("Player " + player.getName() + " sent unknown interact action: " + message.getAction());
}
}
use of net.glowstone.EventFactory in project Glowstone by GlowstoneMC.
the class PlayerSwingArmHandler method handle.
@Override
public void handle(GlowSession session, PlayerSwingArmMessage message) {
GlowPlayer player = session.getPlayer();
EventFactory eventFactory = EventFactory.getInstance();
Block block = player.getTargetBlock((Set<Material>) null, 6);
if (block == null || block.isEmpty()) {
if (eventFactory.onPlayerInteract(player, Action.LEFT_CLICK_AIR, message.getHandSlot()).useItemInHand() == Result.DENY) {
return;
}
// todo: item interactions with air
}
if (!eventFactory.callEvent(new PlayerAnimationEvent(player)).isCancelled()) {
// play the animation to others
player.playAnimation(message.getHand() == 1 ? EntityAnimation.SWING_OFF_HAND : EntityAnimation.SWING_MAIN_HAND);
}
}
use of net.glowstone.EventFactory in project Glowstone by GlowstoneMC.
the class CreativeItemHandler method handle.
@Override
public void handle(GlowSession session, CreativeItemMessage message) {
GlowPlayer player = session.getPlayer();
// CraftBukkit does use a inventory view with both inventories set to the player's inventory
// for the creative inventory as there is no second inventory (no crafting) visible for the
// client
InventoryView view = player.getOpenInventory();
// only if creative mode; only if default (player) inventory
if (player.getGameMode() != GameMode.CREATIVE || !GlowInventoryView.isDefault(player.getOpenInventory())) {
player.kickPlayer(GlowstoneMessages.Kick.CREATIVE_ITEM.get());
return;
}
ItemStack stack = ItemIds.sanitize(message.getItem());
// clicking outside drops the item
EventFactory eventFactory = EventFactory.getInstance();
if (message.getSlot() < 0) {
InventoryCreativeEvent event = eventFactory.callEvent(new InventoryCreativeEvent(view, SlotType.OUTSIDE, -999, stack));
if (event.isCancelled()) {
session.send(new SetWindowSlotMessage(-1, -1, stack));
} else {
player.drop(event.getCursor());
}
return;
}
int viewSlot = message.getSlot();
// this happens quiet often as the client tends to update the whole inventory at once
if (Objects.equals(stack, view.getItem(viewSlot))) {
return;
}
GlowInventory inv = player.getInventory();
int slot = view.convertSlot(viewSlot);
SlotType type = inv.getSlotType(slot);
InventoryCreativeEvent event = eventFactory.callEvent(new InventoryCreativeEvent(view, type, viewSlot, stack));
if (event.isCancelled()) {
// send original slot to player to prevent async inventories
player.sendItemChange(viewSlot, view.getItem(viewSlot));
// don't keep track of player's current item, just give them back what they tried to
// place
session.send(new SetWindowSlotMessage(-1, -1, stack));
return;
}
view.setItem(viewSlot, stack);
}
use of net.glowstone.EventFactory in project Glowstone by GlowstoneMC.
the class GlowPlayerTest method testGiveExp.
@Test
public void testGiveExp() {
entity.giveExp(20);
verify(eventFactory, times(2)).callEvent(argThat(input -> {
if (input instanceof PlayerExpChangeEvent) {
PlayerExpChangeEvent event = (PlayerExpChangeEvent) input;
assertEquals(20, event.getAmount());
return true;
} else if (input instanceof PlayerLevelChangeEvent) {
PlayerLevelChangeEvent event = (PlayerLevelChangeEvent) input;
assertSame(entity, event.getPlayer());
assertEquals(2, event.getNewLevel());
assertEquals(1, event.getOldLevel());
return true;
}
return false;
}));
assertEquals(2, entity.getLevel());
assertEquals(0.17, entity.getExp(), 0.1);
assertEquals(20, entity.getTotalExperience());
}
Aggregations