Add April Fools' prank functionality with scheduled explosions and test command
This commit is contained in:
parent
57b5b8fe84
commit
592f58a89b
|
|
@ -1,6 +1,7 @@
|
|||
package com.alttd.playerutils;
|
||||
|
||||
import com.alttd.playerutils.commands.PlayerUtilsCommand;
|
||||
import com.alttd.playerutils.commands.playerutils_subcommands.AprilFools;
|
||||
import com.alttd.playerutils.commands.playerutils_subcommands.GhastSpeed;
|
||||
import com.alttd.playerutils.commands.playerutils_subcommands.RotateBlock;
|
||||
import com.alttd.playerutils.config.Config;
|
||||
|
|
@ -13,12 +14,17 @@ import org.bukkit.plugin.java.JavaPlugin;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.alttd.playerutils.util.AprilFoolsPrank;
|
||||
|
||||
public final class PlayerUtils extends JavaPlugin {
|
||||
|
||||
private PlayerUtilsCommand playerUtilsCommand;
|
||||
private AprilFoolsPrank aprilFoolsPrank;
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// initialize prank utility
|
||||
aprilFoolsPrank = new AprilFoolsPrank(this);
|
||||
registerCommands();
|
||||
registerEvents();
|
||||
reloadConfigs();
|
||||
|
|
@ -32,6 +38,8 @@ public final class PlayerUtils extends JavaPlugin {
|
|||
|
||||
private void registerCommands() {
|
||||
playerUtilsCommand = new PlayerUtilsCommand(this);
|
||||
// add april fools test command
|
||||
playerUtilsCommand.addSubCommand(new AprilFools(aprilFoolsPrank));
|
||||
}
|
||||
|
||||
private void registerEvents() {
|
||||
|
|
@ -61,7 +69,11 @@ public final class PlayerUtils extends JavaPlugin {
|
|||
}
|
||||
|
||||
private void registerSchedulers() {
|
||||
// periodic key storage save (async)
|
||||
Bukkit.getScheduler().runTaskTimerAsynchronously(this, KeyStorage.STORAGE::save,
|
||||
TimeUnit.MINUTES.toSeconds(5) * 20, TimeUnit.MINUTES.toSeconds(5) * 20);
|
||||
|
||||
// April 1st prank scheduler
|
||||
aprilFoolsPrank.schedule();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
package com.alttd.playerutils.commands.playerutils_subcommands;
|
||||
|
||||
import com.alttd.playerutils.commands.SubCommand;
|
||||
import com.alttd.playerutils.config.Messages;
|
||||
import com.alttd.playerutils.util.AprilFoolsPrank;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AprilFools extends SubCommand {
|
||||
|
||||
private final AprilFoolsPrank prank;
|
||||
|
||||
public AprilFools(AprilFoolsPrank prank) {
|
||||
this.prank = prank;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCommand(CommandSender commandSender, String[] args) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendRichMessage(Messages.GENERIC.PLAYER_ONLY);
|
||||
return true;
|
||||
}
|
||||
boolean ok = prank.playExplosionAround(player);
|
||||
if (ok) {
|
||||
commandSender.sendRichMessage("<green>April Fools test triggered. Listen closely...");
|
||||
} else {
|
||||
commandSender.sendRichMessage("<red>Failed to trigger. You must be in the overworld named 'world'.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "aprilfools";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpMessage() {
|
||||
return "<gray>/playerutils aprilfools</gray> <dark_gray>-</dark_gray> <gray>Play a fake explosion near you (testing).";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package com.alttd.playerutils.util;
|
||||
|
||||
import com.alttd.playerutils.PlayerUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.Month;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* Encapsulates the April Fools' prank logic.
|
||||
* - schedule(): registers the timed prank that only runs on April 1st and only during overworld night.
|
||||
* - playExplosionAround(Player): immediately plays the explosion sound around the target for testing (no date/time checks),
|
||||
* but still requires the target to be in the overworld named "world" to match intended environment.
|
||||
*/
|
||||
public class AprilFoolsPrank {
|
||||
|
||||
private final PlayerUtils plugin;
|
||||
|
||||
public AprilFoolsPrank(PlayerUtils plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the timed prank task. Safe to call on the main thread during plugin enable.
|
||||
*/
|
||||
public void schedule() {
|
||||
// April 1st prank: during overworld night, every 2 minutes pick one player and play an explosion somewhere in a 30-block radius
|
||||
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
|
||||
LocalDate now = LocalDate.now(ZoneId.systemDefault());
|
||||
if (now.getMonth() != Month.APRIL || now.getDayOfMonth() != 1) {
|
||||
return; // only active on April 1st
|
||||
}
|
||||
|
||||
// World world = Bukkit.getWorld("world");
|
||||
World world = Bukkit.getWorld("lobby");
|
||||
if (world == null) return; // overworld not present
|
||||
|
||||
long time = world.getTime() % 24000L;
|
||||
if (time < 13000L || time > 23000L) {
|
||||
return; // only at night
|
||||
}
|
||||
|
||||
List<Player> players = world.getPlayers();
|
||||
if (players.isEmpty()) return;
|
||||
|
||||
Player target = players.get(ThreadLocalRandom.current().nextInt(players.size()));
|
||||
playOnce(world, target);
|
||||
}, 20L, 20L * 60L * 2L); // start after 1s, repeat every 2 minutes
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger the prank once around the given player for testing. Returns true if executed.
|
||||
* This method ignores the date and time checks so it can be tested easily, but it still
|
||||
* requires the player to be in the overworld named "world".
|
||||
*/
|
||||
public boolean playExplosionAround(Player target) {
|
||||
if (target == null) return false;
|
||||
World world = target.getWorld();
|
||||
// if (!"world".equalsIgnoreCase(world.getName())) {
|
||||
if (!"lobby".equalsIgnoreCase(world.getName())) {
|
||||
return false; // only intended for overworld
|
||||
}
|
||||
playOnce(world, target);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void playOnce(World world, Player target) {
|
||||
Location base = target.getLocation();
|
||||
double radius = 30.0;
|
||||
double r = ThreadLocalRandom.current().nextDouble(radius);
|
||||
double theta = ThreadLocalRandom.current().nextDouble(Math.PI * 2);
|
||||
double dx = r * Math.cos(theta);
|
||||
double dz = r * Math.sin(theta);
|
||||
Location soundLoc = new Location(world, base.getX() + dx, base.getY(), base.getZ() + dz);
|
||||
world.playSound(soundLoc, Sound.ENTITY_GENERIC_EXPLODE, 0.8f, 1.0f);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user