added rapid fire bow mechanic

This commit is contained in:
kai ohara 2025-02-11 20:17:20 -05:00
parent 9fcb081c5c
commit f16f36224c
38 changed files with 167 additions and 12 deletions

Binary file not shown.

Binary file not shown.

View File

@ -2,7 +2,9 @@ package CoswayUtil;
import org.bukkit.*;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.data.type.LightningRod;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.ArmorStand;
@ -112,6 +114,10 @@ public final class CoswayUtil extends JavaPlugin implements Listener {
returnMsg(player,"&aYou threw "+Target.getName());
}
}
if (cmd.getName().equalsIgnoreCase("rapidbow") && sender instanceof Player player) {
player.getInventory().addItem(RapidFireBow.createRapidFireBow());
}
return true;
}
@ -354,6 +360,33 @@ public final class CoswayUtil extends JavaPlugin implements Listener {
}
}
}
@EventHandler
public void placedevent(BlockPlaceEvent event) {
Block placed = event.getBlockPlaced();
Player player = event.getPlayer();
if (placed.getType() == Material.RESPAWN_ANCHOR) {
Location above = placed.getLocation().clone().add(0, 1, 0);
Block blockAbove = placed.getWorld().getBlockAt(above);
// Check if the player has at least one Lightning Rod
if (player.getInventory().contains(Material.LIGHTNING_ROD, 1)) {
blockAbove.setType(Material.LIGHTNING_ROD);
// Ensure the Lightning Rod is placed upright
LightningRod rodData = (LightningRod) blockAbove.getBlockData();
rodData.setFacing(BlockFace.UP);
blockAbove.setBlockData(rodData);
// Remove one Lightning Rod from the player's inventory
ItemStack lightningRod = new ItemStack(Material.LIGHTNING_ROD, 1);
player.getInventory().removeItem(lightningRod);
} else {
player.sendMessage(ChatColor.RED + "You need a Lightning Rod in your inventory to place one!");
}
}
}
private void killHostileMobs(Location loc) {
loc.getWorld().getEntitiesByClass(Monster.class).forEach(mob -> {
if (mob.getLocation().distance(loc) <= RING_RADIUS) {

View File

@ -19,7 +19,7 @@ import java.util.Set;
public class LaunchStick implements Listener {
private final CoswayUtil plugin;
private final Set<Player> noFallPlayers = new HashSet<>();
private final double LAUNCH_POWER = 4.0; // Adjust this to change launch strength
private final double LAUNCH_POWER = 3.0; // Adjust this to change launch strength
public LaunchStick(CoswayUtil plugin) {
this.plugin = plugin;
@ -42,7 +42,9 @@ public class LaunchStick implements Listener {
player.setVelocity(direction);
// Add player to no-fall damage list
noFallPlayers.add(player);
if(player.getLocation().clone().subtract(0,1,0).getBlock().getType() == Material.AIR) {
noFallPlayers.add(player);
}
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_BREEZE_JUMP,10,0);
player.getWorld().playEffect(player.getLocation(), Effect.TRIAL_SPAWNER_DETECT_PLAYER_OMINOUS,1);
//player.sendMessage(ChatColor.GREEN + "You launched yourself forward!");

View File

@ -80,19 +80,19 @@ public class MobLevitationWand implements Listener {
return;
}
Vector direction = player.getLocation().getDirection().normalize().multiply(5);
Vector direction = player.getLocation().getDirection().normalize().multiply(8);
Location newLocation = player.getLocation().add(direction);
World world = player.getWorld();
// Ensure the mob is not placed inside a solid block
while (newLocation.getBlock().getType().isSolid()) {
newLocation.add(0, 1, 0); // Move up until a free space is found
}
// Ensure the mob is not underground
int highestY = world.getHighestBlockYAt(newLocation);
if (newLocation.getY() < highestY) {
newLocation.setY(highestY + 1); // Adjust to be above ground
if (newLocation.getBlock().getType().isSolid()) {
Location safeLocation = findSafeLocation(newLocation);
if (safeLocation != null) {
newLocation = safeLocation;
} else {
player.sendMessage(ChatColor.RED + "No safe location found for teleporting!");
return;
}
}
entity.teleport(newLocation);
@ -108,6 +108,24 @@ public class MobLevitationWand implements Listener {
}.runTaskTimer(plugin, 0L, 2L);
}
/**
* Finds the nearest safe location for teleportation by searching upwards but not going to max height.
*/
private Location findSafeLocation(Location loc) {
World world = loc.getWorld();
int maxHeight = world.getMaxHeight();
for (int y = loc.getBlockY(); y < maxHeight; y++) {
Location checkLoc = new Location(world, loc.getX(), y, loc.getZ());
if (!checkLoc.getBlock().getType().isSolid() && !checkLoc.clone().add(0, 1, 0).getBlock().getType().isSolid()) {
return checkLoc; // Found a safe spot
}
}
return null; // No valid space found
}
private void releaseMob(Player player) {
Entity entity = levitatedMobs.remove(player.getUniqueId());

View File

@ -0,0 +1,98 @@
package CoswayUtil;
import org.bukkit.*;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.persistence.PersistentDataType;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.util.Vector;
import java.util.Collections;
import java.util.HashMap;
import java.util.UUID;
public class RapidFireBow implements Listener {
private final NamespacedKey bowKey = new NamespacedKey("coswayutil", "rapid_fire_bow");
private final HashMap<UUID, BukkitRunnable> shootingTasks = new HashMap<>();
private final CoswayUtil plugin;
public RapidFireBow(CoswayUtil plugin) {
this.plugin = plugin;
}
@EventHandler
public void onRightClick(PlayerInteractEvent event) {
Player player = event.getPlayer();
ItemStack item = player.getInventory().getItemInMainHand();
// Check if the player is holding the custom bow
if (!isRapidFireBow(item)) return;
// If the player is already shooting, do nothing
if (shootingTasks.containsKey(player.getUniqueId())) return;
// Start firing arrows every tick
BukkitRunnable task = new BukkitRunnable() {
@Override
public void run() {
if (!player.isOnline() || !isHoldingBow(player)) {
stopShooting(player);
return;
}
// Fire arrow
Arrow arrow = player.launchProjectile(Arrow.class);
arrow.setVelocity(player.getLocation().getDirection().multiply(3)); // High speed
arrow.setCritical(true);
arrow.setPickupStatus(Arrow.PickupStatus.DISALLOWED); // Prevent pickup
arrow.setShooter(player);
// Play sound and particles
player.getWorld().playSound(player.getLocation(), Sound.ENTITY_ARROW_SHOOT, 1.0f, 1.5f);
player.getWorld().spawnParticle(Particle.CRIT, arrow.getLocation(), 5, 0.2, 0.2, 0.2, 0.1);
}
};
task.runTaskTimer(plugin, 0L, 1L); // Fire every tick
shootingTasks.put(player.getUniqueId(), task);
}
@EventHandler
public void onPlayerQuit(PlayerQuitEvent event) {
stopShooting(event.getPlayer());
}
private boolean isHoldingBow(Player player) {
ItemStack item = player.getInventory().getItemInMainHand();
return isRapidFireBow(item);
}
private boolean isRapidFireBow(ItemStack item) {
if (item == null || item.getType() != Material.BOW || !item.hasItemMeta()) return false;
ItemMeta meta = item.getItemMeta();
return meta.getPersistentDataContainer().has(bowKey, PersistentDataType.STRING);
}
private void stopShooting(Player player) {
UUID playerId = player.getUniqueId();
if (shootingTasks.containsKey(playerId)) {
shootingTasks.get(playerId).cancel();
shootingTasks.remove(playerId);
}
}
public static ItemStack createRapidFireBow() {
ItemStack bow = new ItemStack(Material.BOW);
ItemMeta meta = bow.getItemMeta();
meta.setDisplayName(ChatColor.GOLD + "Rapid-Fire Bow");
meta.setLore(Collections.singletonList(ChatColor.RED + "Hold Right-Click to unleash rapid arrows!"));
meta.getPersistentDataContainer().set(new NamespacedKey("coswayutil", "rapid_fire_bow"), PersistentDataType.STRING, "true");
bow.setItemMeta(meta);
return bow;
}
}

View File

@ -24,4 +24,8 @@ commands:
launchstick:
description: give player a stick to use for launching themselves
usage: /launchstick
permission: CoswayUtil.launchStick
permission: CoswayUtil.launchStick
rapidbow:
description: gives player a rapid fire bow
usage: /rapidbow
permission: CoswayUtil.rapidBow