From 4c2ea8317e54067cba0e7dfc9a3d649073078059 Mon Sep 17 00:00:00 2001 From: grish Date: Wed, 25 Sep 2024 14:21:54 +0545 Subject: [PATCH 1/4] Calling the function. for NPC. on init. --- .../java/me/godspunky/skyblock/Skyblock.java | 24 ++++++------- .../godspunky/skyblock/npc/SkyblockNPC.java | 36 ++++++++++++++----- 2 files changed, 39 insertions(+), 21 deletions(-) diff --git a/src/main/java/me/godspunky/skyblock/Skyblock.java b/src/main/java/me/godspunky/skyblock/Skyblock.java index 35aa7af..5fc6117 100644 --- a/src/main/java/me/godspunky/skyblock/Skyblock.java +++ b/src/main/java/me/godspunky/skyblock/Skyblock.java @@ -124,6 +124,7 @@ public void onEnable() { new WardrobeListener(this); new CheckPlayerGUIListener(this); loadymldata(); + registerNPCS(); loadIslandWorld(); loadDungeonWorld(); loadCommandMap(); @@ -288,20 +289,19 @@ public void loadListeners() { this.sendMessage(SUtil.getRandomVisibleColor() + "Successfully loaded listeners [" + SUtil.getTimeDifferenceAndColor(start, System.currentTimeMillis()) + ChatColor.WHITE + "]"); } -private void registerNPCS() - { - Reflections reflections = new Reflections("import me.godspunky.skyblock.npc"); - for (Class npcClazz : reflections.getSubTypesOf(SkyblockNPC.class)){ - try { - npcClazz.getDeclaredConstructor().newInstance(); - }catch (Exception ex){ - ex.printStackTrace(); - - } +private void registerNPCS() { + Reflections reflections = new Reflections("me.godspunky.skyblock.npc"); + for (Class npcClazz : reflections.getSubTypesOf(SkyblockNPC.class)) { + try { + SkyblockNPC npcInstance = npcClazz.getDeclaredConstructor().newInstance(); + SkyblockNPCManager.addNPC(npcInstance); + } catch (Exception ex) { + SLog.error("Failed to register NPC: " + npcClazz.getName(), ex); } - SLog.info("Loaded " + SkyblockNPCManager.getNPCS().size() + " npcs"); - } + SLog.info("Loaded " + SkyblockNPCManager.getNPCS().size() + " NPCs"); +} + public void loadDatabase() { this.sendMessage(SUtil.getRandomVisibleColor() + "Loading SQL Database..."); diff --git a/src/main/java/me/godspunky/skyblock/npc/SkyblockNPC.java b/src/main/java/me/godspunky/skyblock/npc/SkyblockNPC.java index 7af9618..3645700 100644 --- a/src/main/java/me/godspunky/skyblock/npc/SkyblockNPC.java +++ b/src/main/java/me/godspunky/skyblock/npc/SkyblockNPC.java @@ -89,6 +89,10 @@ public void showTo(Player player) { sendPacket(player, packetPlayOutPlayerInfo); sendPacket(player, packetPlayOutNamedEntitySpawn); + // Send entity metadata packet to ensure visibility + PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(entityPlayer.getId(), entityPlayer.getDataWatcher(), true); + sendPacket(player, metadataPacket); + CraftScoreboardManager scoreboardManager = ((CraftServer) Bukkit.getServer()).getScoreboardManager(); CraftScoreboard craftScoreboard = scoreboardManager.getMainScoreboard(); Scoreboard scoreboard = craftScoreboard.getHandle(); @@ -117,6 +121,15 @@ public void run() { } } }.runTaskTimer(Skyblock.getPlugin(), 0, 2); + + // Add a delay before removing the player info to ensure the NPC appears + Bukkit.getScheduler().runTaskLater(Skyblock.getPlugin(), () -> { + PacketPlayOutPlayerInfo removeInfo = new PacketPlayOutPlayerInfo( + PacketPlayOutPlayerInfo.EnumPlayerInfoAction.REMOVE_PLAYER, + entityPlayer + ); + sendPacket(player, removeInfo); + }, 20L); // 1 second delay } public void hideFrom(Player player) { @@ -144,7 +157,7 @@ public void sendHeadRotationPacket(Player player) { getId(), yaw, pitch, - false + true ); sendPacket(player, lookPacket); } @@ -165,7 +178,7 @@ public boolean isPlayerNearby(Player player) { if (!playerLocation.getWorld().equals(npcLocation.getWorld())) { return false; } - double hideDistance = 25; + double hideDistance = 48; // Increased view distance double bukkitRange = Bukkit.getViewDistance() << 4; double distanceSquared = npcLocation.distanceSquared(playerLocation); @@ -181,30 +194,35 @@ public static void sendPacket(Player player, Packet packet) { } public void sendHologram(Player player, String[] lines) { - double yOffset = 0.0; - double DELTA = 0.3; + double yOffset = 0.3; // Start slightly above the NPC's head + double DELTA = 0.25; for (String text : lines) { - EntityArmorStand armorStand = new EntityArmorStand(((CraftPlayer) player).getHandle().getWorld()); + EntityArmorStand armorStand = new EntityArmorStand(((CraftWorld) world).getHandle()); Location hologramLocation = getLocation().clone().add(0, yOffset, 0); armorStand.setLocation(hologramLocation.getX(), hologramLocation.getY(), hologramLocation.getZ(), 0, 0); armorStand.setCustomName(ChatColor.translateAlternateColorCodes('&', text)); armorStand.setCustomNameVisible(true); armorStand.setInvisible(true); - armorStand.setGravity(false); // Fix for NPC not appearing in the specified place + armorStand.setGravity(false); + armorStand.setSmall(true); PacketPlayOutSpawnEntityLiving packet = new PacketPlayOutSpawnEntityLiving(armorStand); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + sendPacket(player, packet); + + // Send metadata packet to ensure visibility + PacketPlayOutEntityMetadata metadataPacket = new PacketPlayOutEntityMetadata(armorStand.getId(), armorStand.getDataWatcher(), true); + sendPacket(player, metadataPacket); holograms.add(armorStand); - yOffset -= DELTA; + yOffset += DELTA; } } public void removeHolograms(Player player) { for (EntityArmorStand armorStand : holograms) { PacketPlayOutEntityDestroy packet = new PacketPlayOutEntityDestroy(armorStand.getId()); - ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet); + sendPacket(player, packet); } holograms.clear(); } From 5a79833d3433cd9417ecaadee904da1d5f37f024 Mon Sep 17 00:00:00 2001 From: grish Date: Wed, 25 Sep 2024 16:08:23 +0545 Subject: [PATCH 2/4] better slayer --- .../java/me/godspunky/skyblock/Skyblock.java | 7 +- .../features/slayer/SlayerBossType.java | 120 ++++--------- .../skyblock/features/slayer/SlayerQuest.java | 71 ++++++-- .../features/slayer/SlayerSystem.java | 167 ++++++++---------- .../skyblock/npc/SkyblockNPCManager.java | 4 + 5 files changed, 165 insertions(+), 204 deletions(-) diff --git a/src/main/java/me/godspunky/skyblock/Skyblock.java b/src/main/java/me/godspunky/skyblock/Skyblock.java index 5fc6117..6d1a4f7 100644 --- a/src/main/java/me/godspunky/skyblock/Skyblock.java +++ b/src/main/java/me/godspunky/skyblock/Skyblock.java @@ -290,16 +290,19 @@ public void loadListeners() { } private void registerNPCS() { + this.sendMessage(SUtil.getRandomVisibleColor() + "Registering NPCs..."); + long start = System.currentTimeMillis(); + Reflections reflections = new Reflections("me.godspunky.skyblock.npc"); for (Class npcClazz : reflections.getSubTypesOf(SkyblockNPC.class)) { try { SkyblockNPC npcInstance = npcClazz.getDeclaredConstructor().newInstance(); SkyblockNPCManager.addNPC(npcInstance); } catch (Exception ex) { - SLog.error("Failed to register NPC: " + npcClazz.getName(), ex); } } - SLog.info("Loaded " + SkyblockNPCManager.getNPCS().size() + " NPCs"); + + this.sendMessage(SUtil.getRandomVisibleColor() + "Successfully registered " + SkyblockNPCManager.getNPCS().size() + " NPCs [" + SUtil.getTimeDifferenceAndColor(start, System.currentTimeMillis()) + ChatColor.WHITE + "]"); } diff --git a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerBossType.java b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerBossType.java index 4c645a1..fc88283 100644 --- a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerBossType.java +++ b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerBossType.java @@ -35,42 +35,42 @@ public class SlayerBossType { "At 50% health, calls its deadly pack", "of pups."); public static final SlayerBossType REVENANT_HORROR_I = new SlayerBossType("revenant_horror_i", "Revenant Horror", SEntityType.REVENANT_HORROR, 1, - "Beginner", SlayerMobType.ZOMBIE, 500, 15, 5, 150, 100, LIFE_DRAIN); + "Beginner", SlayerMobType.ZOMBIE, 500, 15, 5, 5, 100, LIFE_DRAIN); public static final SlayerBossType REVENANT_HORROR_II = new SlayerBossType("revenant_horror_ii", "Revenant Horror", SEntityType.REVENANT_HORROR, 2, "Strong", SlayerMobType.ZOMBIE, - 20000, 50, 25, 1440, 2000, LIFE_DRAIN, PESTILENCE); + 20000, 50, 25, 25, 2000, LIFE_DRAIN, PESTILENCE); public static final SlayerBossType REVENANT_HORROR_III = new SlayerBossType("revenant_horror_iii", "Revenant Horror", SEntityType.REVENANT_HORROR, 3, "Challenging", SlayerMobType.ZOMBIE, 400000, 300, - 100, 2400, 10000, LIFE_DRAIN, PESTILENCE, ENRAGE); + 100, 100, 10000, LIFE_DRAIN, PESTILENCE, ENRAGE); public static final SlayerBossType REVENANT_HORROR_IV = new SlayerBossType("revenant_horror_iv", "Revenant Horror", SEntityType.REVENANT_HORROR, 4, "Deadly", SlayerMobType.ZOMBIE, 1500000, - 1000, 500, 4800, 50000, LIFE_DRAIN, PESTILENCE, ENRAGE); + 1000, 500, 500, 50000, LIFE_DRAIN, PESTILENCE, ENRAGE); public static final SlayerBossType TARANTULA_BROODFATHER_I = new SlayerBossType("tarantula_broodfather_i", "Tarantula Broodfather", SEntityType.TARANTULA_BROODFATHER, 1, "Beginner", SlayerMobType.SPIDER, 750, - 35, 5, 250, 100, COMBAT_JUMP); + 35, 5, 5, 100, COMBAT_JUMP); public static final SlayerBossType TARANTULA_BROODFATHER_II = new SlayerBossType("tarantula_broodfather_ii", "Tarantula Broodfather", SEntityType.TARANTULA_BROODFATHER, 2, "Strong", SlayerMobType.SPIDER, 30000, - 110, 25, 600, 2000, COMBAT_JUMP, NOXIOUS); + 110, 25, 25, 2000, COMBAT_JUMP, NOXIOUS); public static final SlayerBossType TARANTULA_BROODFATHER_III = new SlayerBossType("tarantula_broodfather_iii", "Tarantula Broodfather", SEntityType.TARANTULA_BROODFATHER, 3, "Challenging", SlayerMobType.SPIDER, 900000, - 525, 100, 1000, 10000, COMBAT_JUMP, NOXIOUS); + 525, 100, 100, 10000, COMBAT_JUMP, NOXIOUS); public static final SlayerBossType TARANTULA_BROODFATHER_IV = new SlayerBossType("tarantula_broodfather_iv", "Tarantula Broodfather", SEntityType.TARANTULA_BROODFATHER, 4, "Debilitating", SlayerMobType.SPIDER, 2400000, - 1325, 500, 2000, 50000, COMBAT_JUMP, NOXIOUS); + 1325, 500, 500, 50000, COMBAT_JUMP, NOXIOUS); public static final SlayerBossType SVEN_PACKMASTER_I = new SlayerBossType("sven_packmaster_i", - "Sven Packmaster", SEntityType.SVEN_PACKMASTER, 1, "Beginner", SlayerMobType.WOLF, 2000, 60, 5, 250, + "Sven Packmaster", SEntityType.SVEN_PACKMASTER, 1, "Beginner", SlayerMobType.WOLF, 2000, 60, 5, 5, 100, AGILE); public static final SlayerBossType SVEN_PACKMASTER_II = new SlayerBossType("sven_packmaster_ii", "Sven Packmaster", SEntityType.SVEN_PACKMASTER, 2, "Strong", SlayerMobType.WOLF, 40000, - 200, 10, 25, 600, 2000, AGILE, TRUE_DAMAGE); + 200, 10, 25, 25, 2000, AGILE, TRUE_DAMAGE); public static final SlayerBossType SVEN_PACKMASTER_III = new SlayerBossType("sven_packmaster_iii", "Sven Packmaster", SEntityType.SVEN_PACKMASTER, 3, "Challenging", SlayerMobType.WOLF, 750000, - 450, 50, 100, 1500, 10000, AGILE, TRUE_DAMAGE, CALL_THE_PUPS); + 450, 50, 100, 100, 10000, AGILE, TRUE_DAMAGE, CALL_THE_PUPS); public static final SlayerBossType SVEN_PACKMASTER_IV = new SlayerBossType("sven_packmaster_iv", "Sven Packmaster", SEntityType.SVEN_PACKMASTER, 4, "Truly Painful", SlayerMobType.WOLF, 2000000, - 1100, 200, 500, 3000, 50000, AGILE, TRUE_DAMAGE, CALL_THE_PUPS); + 1100, 200, 500, 500, 50000, AGILE, TRUE_DAMAGE, CALL_THE_PUPS); private final String namespace; private final String name; @@ -125,36 +125,27 @@ public static ChatColor getColorForTier(int tier) { public static int staticGetXPReqForLevel(int level, EntityType type) { switch (type) { case ZOMBIE: - return (Integer) SUtil.getOrDefault(Arrays.asList(new Integer[]{5, 15, 200, Integer.valueOf(1000), Integer.valueOf(5000), Integer.valueOf(20000), Integer.valueOf(100000), Integer.valueOf(400000), Integer.valueOf(1000000)}), level, Integer.valueOf(1000000)); + return SUtil.getOrDefault(Arrays.asList(5, 15, 200, 1000, 5000, 20000, 100000, 400000, 1000000), level - 1, 1000000); case SPIDER: - return (Integer) SUtil.getOrDefault(Arrays.asList(new Integer[]{5, 25, 200, Integer.valueOf(1000), Integer.valueOf(5000), Integer.valueOf(20000), Integer.valueOf(100000), Integer.valueOf(400000), Integer.valueOf(1000000)} ), level, Integer.valueOf(1000000)); + return SUtil.getOrDefault(Arrays.asList(5, 25, 200, 1000, 5000, 20000, 100000, 400000, 1000000), level - 1, 1000000); case WOLF: - return (Integer) SUtil.getOrDefault(Arrays.asList(new Integer[]{10, 30, 250, 1500, 5000, 20000, Integer.valueOf(100000), Integer.valueOf(400000), Integer.valueOf(1000000)} ), level, Integer.valueOf(1000000)); + return SUtil.getOrDefault(Arrays.asList(10, 30, 250, 1500, 5000, 20000, 100000, 400000, 1000000), level - 1, 1000000); case ENDERMAN: - return (Integer) SUtil.getOrDefault(Arrays.asList(10, 30, 250, Integer.valueOf(1500), Integer.valueOf(5000), Integer.valueOf(20000), Integer.valueOf(100000), Integer.valueOf(400000), 1000000), level, 1000000); + return SUtil.getOrDefault(Arrays.asList(10, 30, 250, 1500, 5000, 20000, 100000, 400000, 1000000), level - 1, 1000000); + default: + return 1000000; } - return 1000000; } public int getXPReqForLevel(int level) { - switch (type) { - case ZOMBIE: - return SUtil.getOrDefault(Arrays.asList(5, 15, 200, 1000, 5000, 20000, 100000, 400000, 1000000), level, 1000000); - case SPIDER: - return SUtil.getOrDefault(Arrays.asList(5, 25, 200, 1000, 5000, 20000, 100000, 400000, 1000000), level, 1000000); - case WOLF: - return SUtil.getOrDefault(Arrays.asList(10, 30, 250, 1500, 5000, 20000, 100000, 400000, 1000000), level, 1000000); - default: - return 1000000; - } + return staticGetXPReqForLevel(level, type.getEntityType()); } public static SlayerBossType getByNamespace(String namespace) { - for (SlayerBossType type : TYPES) { - if (namespace.toLowerCase().equals(type.namespace.toLowerCase())) - return type; - } - return null; + return TYPES.stream() + .filter(type -> type.namespace.equalsIgnoreCase(namespace)) + .findFirst() + .orElse(null); } public String getDisplayName() { @@ -209,39 +200,15 @@ public enum SlayerMobType { WOLF; public String getName() { - switch (this) { - case ZOMBIE: - return "Zombie"; - case SPIDER: - return "Spider"; - case WOLF: - return "Wolf"; - } - return "Unknown"; + return name().charAt(0) + name().substring(1).toLowerCase(); } public String getPluralName() { - switch (this) { - case ZOMBIE: - return "Zombies"; - case SPIDER: - return "Spiders"; - case WOLF: - return "Wolves"; - } - return "Unknown"; + return getName() + (this == WOLF ? "ves" : "s"); } public EntityType getEntityType() { - switch (this) { - case ZOMBIE: - return EntityType.ZOMBIE; - case SPIDER: - return EntityType.SPIDER; - case WOLF: - return EntityType.WOLF; - } - return null; + return EntityType.valueOf(name()); } public Material getIcon() { @@ -252,40 +219,19 @@ public Material getIcon() { return Material.WEB; case WOLF: return Material.MUTTON; + default: + return Material.AIR; } - return Material.AIR; } public int getLevelForXP(int xp) { - if (xp >= 1000000) return 9; - if (xp >= 400000) return 8; - if (xp >= 100000) return 7; - if (xp >= 20000) return 6; - if (xp >= 5000) return 5; - switch (this) { - case ZOMBIE: { - if (xp >= 1000) return 4; - if (xp >= 200) return 3; - if (xp >= 15) return 2; - if (xp >= 5) return 1; - break; - } - case SPIDER: { - if (xp >= 1000) return 4; - if (xp >= 200) return 3; - if (xp >= 25) return 2; - if (xp >= 5) return 1; - break; - } - case WOLF: { - if (xp >= 1500) return 4; - if (xp >= 250) return 3; - if (xp >= 30) return 2; - if (xp >= 10) return 1; - break; + int[] thresholds = {5, 15, 200, 1000, 5000, 20000, 100000, 400000, 1000000}; + for (int i = 0; i < thresholds.length; i++) { + if (xp < thresholds[i]) { + return i; } } - return 0; + return 9; } } diff --git a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java index 6fc5141..e2d4ca9 100644 --- a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java +++ b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java @@ -8,11 +8,10 @@ import me.godspunky.skyblock.features.entity.SEntityType; import me.godspunky.skyblock.sequence.SoundSequenceType; import me.godspunky.skyblock.util.SUtil; -import org.bukkit.Effect; -import org.bukkit.Location; -import org.bukkit.World; +import org.bukkit.*; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; import java.util.HashMap; @@ -35,15 +34,19 @@ public class SlayerQuest implements ConfigurationSerializable { @Setter private SEntity entity; private boolean bossSpawned; + @Setter + private Player owner; - public SlayerQuest(SlayerBossType type, long started) { + public SlayerQuest(SlayerBossType type, long started, Player owner) { this.type = type; this.started = started; this.entity = null; this.bossSpawned = false; + this.owner = owner; } + - private SlayerQuest(SlayerBossType type, long started, double xp, long spawned, long killed, long died, SEntityType lastKilled) { + private SlayerQuest(SlayerBossType type, long started, double xp, long spawned, long killed, long died, SEntityType lastKilled, Player owner) { this.type = type; this.started = started; this.xp = xp; @@ -53,6 +56,7 @@ private SlayerQuest(SlayerBossType type, long started, double xp, long spawned, this.lastKilled = lastKilled; this.entity = null; this.bossSpawned = false; + this.owner = owner; } @Override @@ -65,20 +69,51 @@ public Map serialize() { map.put("killed", killed); map.put("died", died); map.put("lastKilled", lastKilled.name()); + map.put("owner", owner.getUniqueId().toString()); return map; } public static SlayerQuest deserialize(Map map) { - return new SlayerQuest(SlayerBossType.getByNamespace(String.valueOf(map.get("type"))), - ((Number) map.get("started")).longValue(), - ((Number) map.get("xp")).doubleValue(), - ((Number) map.get("spawned")).longValue(), - ((Number) map.get("killed")).longValue(), - ((Number) map.get("died")).longValue(), - SEntityType.valueOf(String.valueOf(map.get("lastKilled")))); + return new SlayerQuest( + SlayerBossType.getByNamespace(String.valueOf(map.get("type"))), + ((Number) map.get("started")).longValue(), + ((Number) map.get("xp")).doubleValue(), + ((Number) map.get("spawned")).longValue(), + ((Number) map.get("killed")).longValue(), + ((Number) map.get("died")).longValue(), + SEntityType.valueOf(String.valueOf(map.get("lastKilled"))), + Bukkit.getPlayer(UUID.fromString((String) map.get("owner"))) + ); + } + + public void addXP(double amount) { + this.xp += amount; + double progress = (this.xp / this.type.getSpawnXP()) * 100; + owner.sendMessage(ChatColor.YELLOW + "Slayer XP: " + ChatColor.WHITE + SUtil.roundTo(this.xp, 1) + "/" + this.type.getSpawnXP() + " (" + SUtil.roundTo(progress, 1) + "%)"); + + if (this.xp >= this.type.getSpawnXP() && !bossSpawned) { + spawnBoss(); + } } - // Plays the spawn effect for minibosses, similar to Hypixel's flashy visuals + private void spawnBoss() { + bossSpawned = true; + spawned = System.currentTimeMillis(); + Location spawnLoc = owner.getLocation(); + + // TODO: Implement custom entity spawning logic here + // This would involve creating a custom entity with the boss's attributes + // entity = SEntityType.spawn(type.getSpecType(), spawnLoc); + + playBossSpawn(spawnLoc, owner); + owner.sendMessage(ChatColor.RED + "The " + type.getDisplayName() + " has spawned!"); + } + + public void complete() { + killed = System.currentTimeMillis(); + + + spawn effect for minibosses, similar to Hypixel's flashy visuals public static void playMinibossSpawn(Location location, Entity sound) { Location clone = location.clone(); World world = location.getWorld(); @@ -105,17 +140,17 @@ public static void playBossSpawn(Location location, Entity sound) { SUtil.runIntervalForTicks(() -> { for (int i = 0; i < 50; i++) { - world.playEffect(clone, Effect.SPELL, 0); - world.playEffect(clone, Effect.FLYING_GLYPH, 0); - world.playEffect(clone, Effect.WITCH_MAGIC, 0); + world.spawnParticle(Particle.SPELL_WITCH, clone, 1, 0.5, 0.5, 0.5, 0); + world.spawnParticle(Particle.ENCHANTMENT_TABLE, clone, 1, 0.5, 0.5, 0.5, 0); + world.spawnParticle(Particle.DRAGON_BREATH, clone, 1, 0.5, 0.5, 0.5, 0); } }, 5, 28); new BukkitRunnable() { public void run() { - world.playEffect(clone, Effect.EXPLOSION_HUGE, 0); + world.spawnParticle(Particle.EXPLOSION_HUGE, clone, 1, 0, 0, 0, 0); + world.playSound(clone, Sound.ENTITY_GENERIC_EXPLODE, 1.0f, 1.0f); } }.runTaskLater(Skyblock.getPlugin(), 28); } - } diff --git a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java index a624389..a33996a 100644 --- a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java +++ b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java @@ -1,129 +1,102 @@ package me.godspunky.skyblock.features.slayer; +import me.godspunky.skyblock.Skyblock; +import me.godspunky.skyblock.user.User; +import me.godspunky.skyblock.util.SUtil; +import org.bukkit.ChatColor; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitRunnable; + import java.util.HashMap; import java.util.Map; -import java.util.Random; public class SlayerSystem { - public enum SlayerType { - ZOMBIE, SPIDER, WOLF, ENDERMAN, VAMPIRE, BLAZE - } + private static final Map activeQuests = new HashMap<>(); - public static class SlayerBoss { - private String name; - private int health; - private int damage; - private int tier; - private int xpReward; - private Map drops; - - public SlayerBoss(String name, int health, int damage, int tier, int xpReward) { - this.name = name; - this.health = health; - this.damage = damage; - this.tier = tier; - this.xpReward = xpReward; - this.drops = new HashMap<>(); + public static void startQuest(Player player, SlayerBossType bossType) { + User user = User.getUser(player.getUniqueId()); + if (user == null) return; + + if (activeQuests.containsKey(player)) { + player.sendMessage(ChatColor.RED + "You already have an active Slayer quest!"); + return; } - public void addDrop(String itemName, double chance) { - drops.put(itemName, chance); + if (user.getCoins() < bossType.getCost()) { + player.sendMessage(ChatColor.RED + "You don't have enough coins to start this quest!"); + return; } - public Map rollDrops() { - Map loot = new HashMap<>(); - Random rand = new Random(); + user.subCoins(bossType.getCost()); + SlayerQuest quest = new SlayerQuest(bossType, System.currentTimeMillis()); + activeQuests.put(player, quest); + user.setSlayerQuest(quest); + + player.sendMessage(ChatColor.GREEN + "Slayer quest started! Kill " + bossType.getType().getName() + "s to spawn the boss."); - for (Map.Entry entry : drops.entrySet()) { - if (rand.nextDouble() < entry.getValue()) { - loot.put(entry.getKey(), 1); + new BukkitRunnable() { + @Override + public void run() { + if (!activeQuests.containsKey(player)) { + this.cancel(); + return; } - } - return loot; - } + SlayerQuest currentQuest = activeQuests.get(player); + if (currentQuest.getXp() >= bossType.getSpawnXP()) { + spawnBoss(player, currentQuest); + this.cancel(); + } + } + }.runTaskTimer(Skyblock.getPlugin(), 20L, 20L); } - public static class SlayerQuest { - private SlayerType type; - private int tier; - private int combatXpRequired; - private int cost; - private SlayerBoss boss; - - public SlayerQuest(SlayerType type, int tier, int combatXpRequired, int cost, SlayerBoss boss) { - this.type = type; - this.tier = tier; - this.combatXpRequired = combatXpRequired; - this.cost = cost; - this.boss = boss; - } + public static void addSlayerXP(Player player, double xp) { + if (!activeQuests.containsKey(player)) return; - public boolean canStart(Player player) { - return player.getCoins() >= cost; - } + SlayerQuest quest = activeQuests.get(player); + quest.setXp(quest.getXp() + xp); - public void start(Player player) { - if (canStart(player)) { - player.removeCoins(cost); - player.setActiveQuest(this); - } - } + double progress = (quest.getXp() / quest.getType().getSpawnXP()) * 100; + player.sendMessage(ChatColor.YELLOW + "Slayer XP: " + ChatColor.WHITE + SUtil.roundTo(quest.getXp(), 1) + "/" + quest.getType().getSpawnXP() + " (" + SUtil.roundTo(progress, 1) + "%)"); + } - public boolean isComplete(Player player) { - return player.getCombatXpGained() >= combatXpRequired; - } + private static void spawnBoss(Player player, SlayerQuest quest) { + SlayerBossType bossType = quest.getType(); + // Logic to spawn the boss entity + // This would involve creating a custom entity with the boss's attributes - public void complete(Player player) { - if (isComplete(player)) { - player.addSlayerXp(type, boss.xpReward); - Map loot = boss.rollDrops(); - player.addItems(loot); - } - } + player.sendMessage(ChatColor.RED + "The " + bossType.getDisplayName() + " has spawned!"); + SlayerQuest.playBossSpawn(player.getLocation(), player); } - public static class Player { - private int coins; - private Map slayerXp; - private SlayerQuest activeQuest; - private int combatXpGained; - private Map inventory; - - public Player(int coins) { - this.coins = coins; - this.slayerXp = new HashMap<>(); - for (SlayerType type : SlayerType.values()) { - slayerXp.put(type, 0); - } - this.inventory = new HashMap<>(); - } + public static void killBoss(Player player, SlayerBossType bossType) { + if (!activeQuests.containsKey(player)) return; - public void removeCoins(int amount) { - coins -= amount; - } + SlayerQuest quest = activeQuests.get(player); + if (quest.getType() != bossType) return; - public void setActiveQuest(SlayerQuest quest) { - activeQuest = quest; - combatXpGained = 0; - } + User user = User.getUser(player.getUniqueId()); + if (user == null) return; - public void addSlayerXp(SlayerType type, int amount) { - slayerXp.put(type, slayerXp.get(type) + amount); - } + quest.setKilled(System.currentTimeMillis()); + user.setSlayerXP(bossType.getType(), user.getSlayerXP(bossType.getType()) + bossType.getRewardXP()); - public void addItems(Map items) { - for (Map.Entry entry : items.entrySet()) { - inventory.put(entry.getKey(), inventory.getOrDefault(entry.getKey(), 0) + entry.getValue()); - } - } + player.sendMessage(ChatColor.GREEN + "You killed the " + bossType.getDisplayName() + " and gained " + bossType.getRewardXP() + " Slayer XP!"); + + // Logic for boss drops would go here - public int getCoins() { return coins; } + activeQuests.remove(player); + user.setSlayerQuest(null); + } - public int getCombatXpGained() { return combatXpGained; } + public static boolean hasActiveQuest(Player player) { + return activeQuests.containsKey(player); + } - public void addCombatXp(int amount) { combatXpGained += amount; } + public static SlayerQuest getActiveQuest(Player player) { + return activeQuests.get(player); } } - diff --git a/src/main/java/me/godspunky/skyblock/npc/SkyblockNPCManager.java b/src/main/java/me/godspunky/skyblock/npc/SkyblockNPCManager.java index 3b89266..ee17689 100644 --- a/src/main/java/me/godspunky/skyblock/npc/SkyblockNPCManager.java +++ b/src/main/java/me/godspunky/skyblock/npc/SkyblockNPCManager.java @@ -13,6 +13,10 @@ public static void registerNPC(SkyblockNPC skyblockNPC){ } } + public static void addNPC(SkyblockNPC skyblockNPC) { + registerNPC(skyblockNPC); + } + public static Set getNPCS(){ return Collections.unmodifiableSet(SKYBLOCK_NPCS); } From 1b17fec6773aaa88944bdfd63b6d2883962c56a2 Mon Sep 17 00:00:00 2001 From: grish Date: Wed, 25 Sep 2024 16:14:18 +0545 Subject: [PATCH 3/4] fix typeo --- .../skyblock/features/slayer/SlayerQuest.java | 79 +++++++------------ 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java index e2d4ca9..64e2c95 100644 --- a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java +++ b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java @@ -8,11 +8,14 @@ import me.godspunky.skyblock.features.entity.SEntityType; import me.godspunky.skyblock.sequence.SoundSequenceType; import me.godspunky.skyblock.util.SUtil; -import org.bukkit.*; +import org.bukkit.Effect; +import org.bukkit.Location; +import org.bukkit.World; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.ChatColor; import java.util.HashMap; import java.util.Map; @@ -34,19 +37,16 @@ public class SlayerQuest implements ConfigurationSerializable { @Setter private SEntity entity; private boolean bossSpawned; - @Setter - private Player owner; + private Player owner; // Add this field if it doesn't exist - public SlayerQuest(SlayerBossType type, long started, Player owner) { + public SlayerQuest(SlayerBossType type, long started) { this.type = type; this.started = started; this.entity = null; this.bossSpawned = false; - this.owner = owner; } - - private SlayerQuest(SlayerBossType type, long started, double xp, long spawned, long killed, long died, SEntityType lastKilled, Player owner) { + private SlayerQuest(SlayerBossType type, long started, double xp, long spawned, long killed, long died, SEntityType lastKilled) { this.type = type; this.started = started; this.xp = xp; @@ -56,7 +56,6 @@ private SlayerQuest(SlayerBossType type, long started, double xp, long spawned, this.lastKilled = lastKilled; this.entity = null; this.bossSpawned = false; - this.owner = owner; } @Override @@ -69,51 +68,20 @@ public Map serialize() { map.put("killed", killed); map.put("died", died); map.put("lastKilled", lastKilled.name()); - map.put("owner", owner.getUniqueId().toString()); return map; } public static SlayerQuest deserialize(Map map) { - return new SlayerQuest( - SlayerBossType.getByNamespace(String.valueOf(map.get("type"))), - ((Number) map.get("started")).longValue(), - ((Number) map.get("xp")).doubleValue(), - ((Number) map.get("spawned")).longValue(), - ((Number) map.get("killed")).longValue(), - ((Number) map.get("died")).longValue(), - SEntityType.valueOf(String.valueOf(map.get("lastKilled"))), - Bukkit.getPlayer(UUID.fromString((String) map.get("owner"))) - ); - } - - public void addXP(double amount) { - this.xp += amount; - double progress = (this.xp / this.type.getSpawnXP()) * 100; - owner.sendMessage(ChatColor.YELLOW + "Slayer XP: " + ChatColor.WHITE + SUtil.roundTo(this.xp, 1) + "/" + this.type.getSpawnXP() + " (" + SUtil.roundTo(progress, 1) + "%)"); - - if (this.xp >= this.type.getSpawnXP() && !bossSpawned) { - spawnBoss(); - } - } - - private void spawnBoss() { - bossSpawned = true; - spawned = System.currentTimeMillis(); - Location spawnLoc = owner.getLocation(); - - // TODO: Implement custom entity spawning logic here - // This would involve creating a custom entity with the boss's attributes - // entity = SEntityType.spawn(type.getSpecType(), spawnLoc); - - playBossSpawn(spawnLoc, owner); - owner.sendMessage(ChatColor.RED + "The " + type.getDisplayName() + " has spawned!"); + return new SlayerQuest(SlayerBossType.getByNamespace(String.valueOf(map.get("type"))), + ((Number) map.get("started")).longValue(), + ((Number) map.get("xp")).doubleValue(), + ((Number) map.get("spawned")).longValue(), + ((Number) map.get("killed")).longValue(), + ((Number) map.get("died")).longValue(), + SEntityType.valueOf(String.valueOf(map.get("lastKilled")))); } - public void complete() { - killed = System.currentTimeMillis(); - - - spawn effect for minibosses, similar to Hypixel's flashy visuals + // Plays the spawn effect for minibosses, similar to Hypixel's flashy visuals public static void playMinibossSpawn(Location location, Entity sound) { Location clone = location.clone(); World world = location.getWorld(); @@ -140,17 +108,24 @@ public static void playBossSpawn(Location location, Entity sound) { SUtil.runIntervalForTicks(() -> { for (int i = 0; i < 50; i++) { - world.spawnParticle(Particle.SPELL_WITCH, clone, 1, 0.5, 0.5, 0.5, 0); - world.spawnParticle(Particle.ENCHANTMENT_TABLE, clone, 1, 0.5, 0.5, 0.5, 0); - world.spawnParticle(Particle.DRAGON_BREATH, clone, 1, 0.5, 0.5, 0.5, 0); + world.playEffect(clone, Effect.SPELL, 0); + world.playEffect(clone, Effect.FLYING_GLYPH, 0); + world.playEffect(clone, Effect.WITCH_MAGIC, 0); } }, 5, 28); new BukkitRunnable() { public void run() { - world.spawnParticle(Particle.EXPLOSION_HUGE, clone, 1, 0, 0, 0, 0); - world.playSound(clone, Sound.ENTITY_GENERIC_EXPLODE, 1.0f, 1.0f); + world.playEffect(clone, Effect.EXPLOSION_HUGE, 0); } }.runTaskLater(Skyblock.getPlugin(), 28); } + + public void complete(Player player) { // Add Player parameter + killed = System.currentTimeMillis(); + + // Use the player parameter instead of owner + player.sendMessage(ChatColor.GREEN + "You completed the " + type.getDisplayName() + " Slayer quest!"); + // Add any other completion logic here + } } From 2fa994b8574a804844d12bbff42407d5e28c3139 Mon Sep 17 00:00:00 2001 From: grish Date: Wed, 25 Sep 2024 16:16:22 +0545 Subject: [PATCH 4/4] Fix this bug from? New Slayer logic --- .../me/godspunky/skyblock/features/slayer/SlayerQuest.java | 7 ++----- .../godspunky/skyblock/features/slayer/SlayerSystem.java | 4 ++-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java index 64e2c95..7b040eb 100644 --- a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java +++ b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerQuest.java @@ -37,7 +37,7 @@ public class SlayerQuest implements ConfigurationSerializable { @Setter private SEntity entity; private boolean bossSpawned; - private Player owner; // Add this field if it doesn't exist + private Player owner; public SlayerQuest(SlayerBossType type, long started) { this.type = type; @@ -81,7 +81,6 @@ public static SlayerQuest deserialize(Map map) { SEntityType.valueOf(String.valueOf(map.get("lastKilled")))); } - // Plays the spawn effect for minibosses, similar to Hypixel's flashy visuals public static void playMinibossSpawn(Location location, Entity sound) { Location clone = location.clone(); World world = location.getWorld(); @@ -97,7 +96,6 @@ public static void playMinibossSpawn(Location location, Entity sound) { ); } - // Plays the boss spawn effect with magical particles and explosions public static void playBossSpawn(Location location, Entity sound) { Location clone = location.clone(); World world = location.getWorld(); @@ -121,11 +119,10 @@ public void run() { }.runTaskLater(Skyblock.getPlugin(), 28); } - public void complete(Player player) { // Add Player parameter + public void complete(Player player) { killed = System.currentTimeMillis(); // Use the player parameter instead of owner player.sendMessage(ChatColor.GREEN + "You completed the " + type.getDisplayName() + " Slayer quest!"); - // Add any other completion logic here } } diff --git a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java index a33996a..0214ffa 100644 --- a/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java +++ b/src/main/java/me/godspunky/skyblock/features/slayer/SlayerSystem.java @@ -65,8 +65,8 @@ public static void addSlayerXP(Player player, double xp) { private static void spawnBoss(Player player, SlayerQuest quest) { SlayerBossType bossType = quest.getType(); - // Logic to spawn the boss entity - // This would involve creating a custom entity with the boss's attributes + // Logic to spawn the boss entity This would involve creating a custom entity + // with the boss's attributes player.sendMessage(ChatColor.RED + "The " + bossType.getDisplayName() + " has spawned!"); SlayerQuest.playBossSpawn(player.getLocation(), player);