-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit d937c3a
Showing
13 changed files
with
1,642 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# OBAmazeingTimer | ||
No, it's not an amazing timer. It's a rudimentary timer for a maze. In particular, for the awesome maze | ||
on our build server called "A-Maze-Ing". | ||
|
||
This plugin will automatically time a players attempt to solve A-Maze-Ing, and update a sign based | ||
leaderboard with the player name, the time and their rank. | ||
|
||
Triggers for the start/entry and stop/exit are customizable, along with the maze dimensions for | ||
detecting when a player leaves the maze. The leaderboard is also configurable for placement | ||
and materials, as well as the text color and direction the leaderboard faces. | ||
|
||
The elapsed time during a run is displayed in the action bar, as well as the final time as a title | ||
message when you exit the maze by triggering the exit/stop trigger. | ||
|
||
Main configuration file contains the start and stop triggers and borders of the maze. The Maze borders | ||
are defined as two corners (so a square maze) and a low and high Y coordinate value. A listener will | ||
detect if you go out of the maze boundary and will cancel the timer, as will leaving the game, getting | ||
killed or warping out etc. | ||
|
||
The leaderboard config file contains players and their times. The file contains the times as a hash with | ||
player uuid as the key and their time. This is so we can have one time for a player - uniquness of key. | ||
However, the in-game hash used for the leaderboard is a TreeMap using the time as the key and player as | ||
the value. This is because a TreeMap will automatically add new entries in numeric ascending order, which | ||
is great the for leaderboard as no sorting required and the signs can be rendered directly from the hash. | ||
|
||
The signs configuration file contains the sign direction, location, sign and backing materials, as well | ||
as the color of the text on the signs. Title and leaderboard are set separately with a flag for whether | ||
you want to draw the title or not. There is also a setting for the number of sign lines the leaderboard | ||
contains. Each sign line on the leaderboard is a set of 3 horizontally oriented signs which show rank, | ||
player name, and the time. Since a sign has 4 lines, a 3 row leaderboard will have 12 ranks, which is | ||
also the default. | ||
|
||
The timer of course can be used for things other than a maze. | ||
Here is my gaudy looking leaderboard showing the title row and 3 leaderboard rows: | ||
|
||
![OBAmazeingTimer-leaderboard](https://ob-mc.net/repo/OBAmazeingTimer-leaderboard.png) | ||
![OBAmazeing](https://ob-mc.net/repo/OBAmazeing.png) | ||
|
||
You can find A-Maze-Ing in our origial amusement park area at X=634, Z=-85. Join ob-mc.net! | ||
|
||
Compiled for 1.19 with Java 17. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>net.obmc</groupId> | ||
<artifactId>OBAmazeingTimer</artifactId> | ||
<version>1.0</version> | ||
<packaging>jar</packaging> | ||
<name>OBAmazeingTimer</name> | ||
<description>Timer for the build server maze called A-Maze-Ing</description> | ||
|
||
<properties> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<build> | ||
|
||
<finalName>OBAmazeingTimer</finalName> | ||
|
||
<resources> | ||
<resource> | ||
<targetPath>.</targetPath> | ||
<filtering>true</filtering> | ||
<directory>${basedir}/src/main/resources/</directory> | ||
<includes> | ||
<include>*.yml</include> | ||
</includes> | ||
</resource> | ||
</resources> | ||
|
||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.11.0</version> | ||
<configuration> | ||
<source>17</source> | ||
<target>17</target> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
<repositories> | ||
<repository> | ||
<id>spigot repo</id> | ||
<url>https://hub.spigotmc.org/nexus/content/repositories/public</url> | ||
</repository> | ||
<repository> | ||
<id>jetbrains repo</id> | ||
<url>https://mvnrepository.com/artifact/org.jetbrains/annotations</url> | ||
</repository> | ||
<repository> | ||
<id>apache lang</id> | ||
<url>https://mvnrepository.com/artifact/org.apache.commons/commons-lang3</url> | ||
</repository> | ||
</repositories> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.spigotmc</groupId> | ||
<artifactId>spigot-api</artifactId> | ||
<version>1.19.4-R0.1-SNAPSHOT</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.jetbrains</groupId> | ||
<artifactId>annotations</artifactId> | ||
<version>24.0.1</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-lang3</artifactId> | ||
<version>3.12.0</version> | ||
</dependency> | ||
</dependencies> | ||
|
||
</project> |
214 changes: 214 additions & 0 deletions
214
src/main/java/net/obmc/OBAmazeingTimer/EventListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
package net.obmc.OBAmazeingTimer; | ||
|
||
import java.util.logging.Level; | ||
import java.util.logging.Logger; | ||
|
||
import org.bukkit.Location; | ||
import org.bukkit.entity.Player; | ||
import org.bukkit.event.EventHandler; | ||
import org.bukkit.event.player.PlayerMoveEvent; | ||
import org.bukkit.event.player.PlayerQuitEvent; | ||
import org.bukkit.event.player.PlayerRespawnEvent; | ||
import org.bukkit.event.player.PlayerChangedWorldEvent; | ||
import org.bukkit.event.player.PlayerInteractEvent; | ||
import org.bukkit.event.player.PlayerJoinEvent; | ||
import org.bukkit.event.player.PlayerKickEvent; | ||
import org.bukkit.Material; | ||
|
||
import org.bukkit.event.Listener; | ||
import org.bukkit.event.block.Action; | ||
import org.bukkit.event.entity.PlayerDeathEvent; | ||
|
||
public class EventListener implements Listener | ||
{ | ||
static Logger log = Logger.getLogger("Minecraft"); | ||
private String logmsgprefix = null; | ||
|
||
public EventListener() { | ||
|
||
logmsgprefix = OBAmazeingTimer.getLogMsgPrefix(); | ||
|
||
} | ||
/* | ||
* Detect a players movement and see if they have triggered a maze timer stop/start event | ||
* Look at the location of the player and see if that matches the triggers from the config | ||
* | ||
* @param {@link PlayerMoveEvent} | ||
*/ | ||
@EventHandler | ||
public void onPlayerMove( PlayerMoveEvent event ) { | ||
|
||
Player player = event.getPlayer(); | ||
Location playerloc = player.getLocation(); | ||
MazeTrigger entryloc = OBAmazeingTimer.getInstance().getStartTimerTrigger(); | ||
MazeTrigger exitloc = OBAmazeingTimer.getInstance().getStopTimerTrigger(); | ||
|
||
// Entering maze - only process event if there's no timer running for a player | ||
if ( !OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) ) { | ||
|
||
// check if we've moved to the entry trigger block | ||
if ((int)playerloc.getX() == entryloc.getPadLocationX() && | ||
(int)playerloc.getY() == entryloc.getPadLocationY() && | ||
(int)playerloc.getZ() == entryloc.getPadLocationZ() && | ||
playerloc.getBlock().getType().equals( entryloc.getPadMaterial() ) ) { | ||
|
||
log.log(Level.INFO, logmsgprefix + "Maze entry detected for " + player.getName() + "!" ); | ||
|
||
// yes, so start a timer and task for the player | ||
OBAmazeingTimer.getInstance().getMazeTimer().StartTimer( player.getUniqueId() ); | ||
|
||
//TODO: do something? | ||
//player.playSound(player.getLocation(), OBAmazeingTimer.getInstance().getSound(), 1.0f, 1.0f); | ||
//displayEffect(OBAmazeingTimer.getInstance().getEffect(), player.getLocation(), 1.0f, 1.0f, 1.0f, 1.0f, OBAmazeingTimer.getInstance().getParticleCount()); | ||
} | ||
} | ||
|
||
// Exit maze - checks when a timer is running for a player | ||
if ( OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) ) { | ||
|
||
// check if we've exited the maze - ignore if not activated | ||
if ((int)playerloc.getX() == exitloc.getPadLocationX() && | ||
(int)playerloc.getY() == exitloc.getPadLocationY() && | ||
(int)playerloc.getZ() == exitloc.getPadLocationZ() && | ||
playerloc.getBlock().getType().equals( exitloc.getPadMaterial() ) ) { | ||
|
||
log.log(Level.INFO, logmsgprefix + "Maze exit detected for " + player.getName() + "!" ); | ||
|
||
OBAmazeingTimer.getInstance().getMazeTimer().StopTimerOnExit( player.getUniqueId() ); | ||
|
||
//TODO: do sometthing? | ||
//player.playSound(player.getLocation(), OBAmazeingTimer.getInstance().getSound(), 1.0f, 1.0f); | ||
//displayEffect(OBAmazeingTimer.getInstance().getEffect(), player.getLocation(), 1.0f, 1.0f, 1.0f, 1.0f, OBAmazeingTimer.getInstance().getParticleCount()); | ||
} | ||
|
||
// check if player has somehow moved outside of maze boundaries whilst being timed and cancel timer if they have | ||
// we check the X and Z coordinates of our corners and high and low Y coordinates to form essentially a box | ||
if ((int)playerloc.getX() > (int)OBAmazeingTimer.getInstance().getMazeSideHigh().getX() || (int)playerloc.getX() < (int)OBAmazeingTimer.getInstance().getMazeSideLow().getX() || | ||
(int)playerloc.getZ() > (int)OBAmazeingTimer.getInstance().getMazeSideHigh().getZ() || (int)playerloc.getZ() < (int)OBAmazeingTimer.getInstance().getMazeSideLow().getZ() || | ||
(int)playerloc.getY() >= (int)OBAmazeingTimer.getInstance().getMazeHigh() || (int)playerloc.getY() < (int)OBAmazeingTimer.getInstance().getMazeLow()) { | ||
|
||
log.log(Level.INFO, logmsgprefix + "Out of boundary detected for " + player.getName() + "!" ); | ||
|
||
OBAmazeingTimer.getInstance().getMazeTimer().StopTimerOutBounds( player.getUniqueId() ); | ||
} | ||
} | ||
|
||
} | ||
|
||
/** | ||
* See if the player has interacted in some way with our entry or exit place and cancel the event | ||
* | ||
* @param {@link PlayerInteractEvent} | ||
*/ | ||
@EventHandler | ||
public void onPlayerInteract(PlayerInteractEvent event) { | ||
Player player = event.getPlayer(); | ||
Location playerloc = player.getLocation(); | ||
|
||
MazeTrigger entryloc = OBAmazeingTimer.getInstance().getStartTimerTrigger(); | ||
MazeTrigger exitloc = OBAmazeingTimer.getInstance().getStopTimerTrigger(); | ||
|
||
if ( event.getAction() == Action.PHYSICAL ) { | ||
|
||
Material eventplate = event.getClickedBlock().getLocation().getBlock().getType(); | ||
|
||
// check for entry plate event and cancel event | ||
if (!OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) && | ||
(int)playerloc.getX() == entryloc.getPadLocationX() && | ||
(int)playerloc.getY() == entryloc.getPadLocationY() && | ||
(int)playerloc.getZ() == entryloc.getPadLocationZ() && | ||
eventplate.equals( OBAmazeingTimer.getInstance().getStartTimerTrigger().getPadMaterial() ) ) { | ||
event.setCancelled(true); | ||
} | ||
|
||
// check for exit plate event and cancel | ||
if (OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) && | ||
(int)playerloc.getX() == exitloc.getPadLocationX() && | ||
(int)playerloc.getY() == exitloc.getPadLocationY() && | ||
(int)playerloc.getZ() == exitloc.getPadLocationZ() && | ||
eventplate.equals( OBAmazeingTimer.getInstance().getStopTimerTrigger().getPadMaterial() ) ) { | ||
event.setCancelled(true); | ||
} | ||
} | ||
} | ||
|
||
@EventHandler | ||
/* | ||
* Detect if a player has quit whilst being timed and cancel their timer and task | ||
* | ||
* @param {@link PlayerQuitEvent} | ||
*/ | ||
public void onPlayerQuit( PlayerQuitEvent event ) { | ||
|
||
clearTaskTimer( event.getPlayer() ); | ||
} | ||
|
||
/* | ||
* Detect if a player has been kicked whilst being timed and cancel their timer and task | ||
* | ||
* @param {@link PlayerKickEvent} | ||
*/ | ||
@EventHandler | ||
public void onPlayerKick( PlayerKickEvent event ) { | ||
|
||
clearTaskTimer( event.getPlayer() ); | ||
} | ||
|
||
/* | ||
* Detect if a player joins and cancel any tasks that might be left over | ||
* | ||
* @param {@link PlayerJoinEvent} | ||
*/ | ||
@EventHandler | ||
public void onPlayerJoin( PlayerJoinEvent event ) { | ||
|
||
clearTaskTimer( event.getPlayer() ); | ||
} | ||
|
||
/* | ||
* Detect if a player respawns and cancel any timers and tasks | ||
* | ||
* @param {@link PlayerRespawnEvent} | ||
*/ | ||
@EventHandler | ||
public void onReSpawn( PlayerRespawnEvent event ) { | ||
|
||
clearTaskTimer( event.getPlayer() ); | ||
} | ||
|
||
/* | ||
* Detect if a player leaves the world and cancel any timers and tasks | ||
* | ||
* @param {@link PlayerChangedWorldEvent} | ||
*/ | ||
@EventHandler | ||
public void onWorldChange( PlayerChangedWorldEvent event ) { | ||
|
||
clearTaskTimer( event.getPlayer() ); | ||
} | ||
|
||
/* | ||
* Detect if a player dies and cancel any timers and tasks | ||
* | ||
* @param {@link PlayerDeathEvent} | ||
*/ | ||
@EventHandler | ||
public void onPlayerDeath( PlayerDeathEvent event ) { | ||
|
||
clearTaskTimer( event.getEntity() ); | ||
} | ||
|
||
/* | ||
* Remove a player timer and cancel any timer tasks | ||
* | ||
* @param {@link Player} | ||
*/ | ||
private void clearTaskTimer( Player player ) { | ||
|
||
if ( OBAmazeingTimer.getInstance().getMazeTimer().timerRunning( player.getUniqueId() ) ) { | ||
|
||
OBAmazeingTimer.getInstance().getMazeTimer().removePlayerTimer( player.getUniqueId() ); | ||
OBAmazeingTimer.getInstance().getMazeTimer().removePlayerTask( player.getUniqueId() ); | ||
} | ||
} | ||
} |
Oops, something went wrong.