Untitled
public void handleFireball(Fireball explosive) { debug("fireball detected"); BlockManager blockManager = arena.getBlockManager(); Set<Block> explodingBlocks = getExplodingBlocks( FIREBALL_INVULNERABLE, explosive.getLocation().getBlock(), 3 ); explodingBlocks.forEach(blockManager::breakBlock); handleExplosionBehavior( explosive, explodingBlocks, new Vector(0.55, 0.485, 0.55), 6, 5.5 ); } public void handleTnt(TNTPrimed explosive) { debug("tnt detected"); BlockManager blockManager = arena.getBlockManager(); Set<Block> explodingBlocks = getExplodingBlocks( TNT_INVULNERABLE, explosive.getLocation().getBlock(), 4 ); explodingBlocks.forEach(blockManager::breakBlock); handleExplosionBehavior( explosive, explodingBlocks, new Vector(0.55, 0.485, 0.55), 8, 6.5 ); } private Vector scaledBisector(Vector v1, Vector v2) { Vector normBisector = v1.clone().add(v2).normalize(); return normBisector.multiply(v1.length() / normBisector.length()); } @SuppressWarnings("deprecation") public void handleExplosionBehavior(Entity explosive, Set<Block> explodingBlocks, Vector modifier, double radius, double maxDamage) { Location sourceLocation = explosive.getLocation(); World world = sourceLocation.getWorld(); Arena arena = Arena.byWorld(world).get(); WorldServer worldServer = ((CraftWorld) world).getHandle(); boolean isTNT = explosive.getType() == EntityType.PRIMED_TNT; world.playSound(sourceLocation, Sound.EXPLODE, isTNT ? worldServer.paperSpigotConfig.tntExplosionVolume : 8.0F, (1.0F + (worldServer.random.nextFloat() - worldServer.random.nextFloat()) * 0.2F) * 0.7F ); world.getPlayers().forEach(worldPlayer -> { if (isTNT) { PacketUtils.sendEffectData(worldPlayer, EnumParticle.EXPLOSION_HUGE, sourceLocation, true, 0.1f, 0.1f, 0.1f, 1f, 1); } else { PacketUtils.sendEffectData(worldPlayer, EnumParticle.EXPLOSION_LARGE, sourceLocation, true, 1f, 1f, 1f, 1f, 2); } explodingBlocks.forEach(block -> PacketUtils.sendEffectData(worldPlayer, EnumParticle.SMOKE_NORMAL, block.getLocation(), true, 0.1f, 0.1f, 0.1f, 0.05f, 7)); }); WorldUtils.getNearbyEntities(sourceLocation, radius).forEach(entity -> { EntityType type = entity.getType(); if (type == EntityType.PLAYER) { Player player = (Player) entity; if (arena.isRespawning(player) || arena.isSpectator(player)) { return; } } Location entityLocation = entity.getLocation(); Location headLocation = type == EntityType.PLAYER ? ((Player) entity).getEyeLocation() : entityLocation.clone().add(0, 1, 0); Vector flyDir = headLocation.toVector().subtract(sourceLocation.toVector()); double distance = entityLocation.distance(sourceLocation); if (type == EntityType.PLAYER) { Bukkit.broadcastMessage(entity.getVelocity().toString()); Bukkit.broadcastMessage(String.valueOf(distance)); } double deltaX = entityLocation.getX() - sourceLocation.getX(); double deltaZ = entityLocation.getZ() - sourceLocation.getZ(); double horizontalDistance = Math.sqrt(deltaX * deltaX + deltaZ * deltaZ); flyDir.normalize(); flyDir.multiply(Math.max(0, 4 * (1 - distance / radius))); flyDir.multiply(modifier); Vector jumpVector = new Vector(0, (distance <= closeDistance ? closeMul : 2.5f) * (horizontalDistance / radius), 0); flyDir = scaledBisector(scaledBisector(flyDir, jumpVector), entity.getVelocity()); // Velocity minecraft yejoori kar mikone ke nemitone bishtar as 4 too packet bede, pas momkene player false bokhore ya har etefaghi biofte // Behtar ine ke velocity ro be 4 limit kard, ya baze baze apply kard // ya age bekhai mishe too config disable esh kard // See: // - https://github.com/PaperMC/Paper/issues/536 // - CraftEntity#setVelocity() double damage = maxDamage * (1 - distance / radius); if (type == EntityType.PLAYER) { Player player = (Player) entity; damage = player.isBlocking() ? damage / 1.25 : damage; entity.setVelocity(entity.getVelocity().add(player.isBlocking() ? flyDir.multiply(6 / 7) : flyDir)); } else if (type == EntityType.PRIMED_TNT) { entity.setVelocity(flyDir.multiply(0.5f)); } else { entity.setVelocity(flyDir); } if (entity instanceof LivingEntity) { LivingEntity livingEntity = (LivingEntity) entity; EntityDamageByEntityEvent damageEvent = new EntityDamageByEntityEvent( explosive, livingEntity, DamageCause.ENTITY_EXPLOSION, damage ); BukkitUtils.callEvent(damageEvent); if (!damageEvent.isCancelled()) { double finalDamage = damageEvent.getFinalDamage(); livingEntity.setLastDamageCause(new EntityDamageEvent(livingEntity, DamageCause.ENTITY_EXPLOSION, finalDamage)); livingEntity.damage(finalDamage); } } }); }
Leave a Comment