1313import org .bukkit .event .EventHandler ;
1414import org .bukkit .event .Listener ;
1515import org .bukkit .event .player .PlayerMoveEvent ;
16- import org .bukkit .permissions .PermissionAttachment ;
17- import org .bukkit .scheduler .BukkitRunnable ;
1816
1917import java .util .HashMap ;
2018import java .util .Map ;
2119import java .util .UUID ;
2220
2321public class FloorTeleporterListener implements Listener {
2422
25- private Map <UUID , Double > lastY = new HashMap <>();
26-
27- public FloorTeleporterListener () {
28- Bukkit .getScheduler ().runTaskTimerAsynchronously (UtilsManager .getInstance (), bukkitTask -> {
29- for (Player player : Bukkit .getOnlinePlayers ()) {
30- if (player .hasPermission ("ported" )) {
31- return ;
32- }
33- if (player .isSneaking ()) {
34- down (player );
35- }
36- }
37- }, 1 , 1 );
38- }
23+ private final Map <UUID , Double > lastY = new HashMap <>();
24+ private final Map <UUID , Long > teleportCooldown = new HashMap <>();
25+ private static final long COOLDOWN_TICKS = 10L ; // 0.5 seconds
3926
4027 @ EventHandler
4128 public void onPlayerMove (PlayerMoveEvent event ) {
4229 Player player = event .getPlayer ();
4330 UUID playerId = player .getUniqueId ();
31+ Location to = event .getTo ();
4432
45- double currentY = player .getLocation ().getY ();
46- if (player .hasPermission ("ported" )) {
47- this .lastY .put (playerId , currentY );
33+ if (isOnCooldown (playerId )) {
4834 return ;
4935 }
50- double lastY = this .lastY .getOrDefault (playerId , currentY );
5136
52- if ( currentY > lastY ) {
53- up ( player );
54- } else if ( currentY < lastY ) {
37+ double currentY = to . getY ();
38+ double previousY = lastY . getOrDefault ( playerId , currentY );
39+ lastY . put ( playerId , currentY );
5540
41+ if (!isOnDaylightDetector (player )) {
42+ return ;
5643 }
5744
58- this .lastY .put (playerId , currentY );
45+ if (currentY > previousY ) {
46+ teleportUp (player );
47+ } else if (player .isSneaking ()) {
48+ teleportDown (player );
49+ }
5950 }
6051
61- public void up (Player player ) {
62- Block thisblock = player .getLocation ().getBlock ();
63- Location second = player .getLocation ();
64- second .setY (second .getY ()-1.0 );
65- Block thissecondblock = second .getBlock ();
66- if (thisblock .getType () == Material .DAYLIGHT_DETECTOR || thissecondblock .getType () == Material .DAYLIGHT_DETECTOR ) {
67- for (int y = player .getLocation ().getBlockY () + 1 ; y <= player .getWorld ().getMaxHeight (); y ++) {
68- Block block = player .getWorld ().getBlockAt (player .getLocation ().getBlockX (), y , player .getLocation ().getBlockZ ());
69- if (block .getType () == Material .DAYLIGHT_DETECTOR ) {
70- World world = player .getWorld ();
71- Block blockbackup = player .getWorld ().getBlockAt (player .getLocation ().getBlockX (), y + 1 , player .getLocation ().getBlockZ ());
72- if (blockbackup .getType () != Material .AIR ) {
73- player .teleport (new Location (world , player .getLocation ().getBlockX () + 0.5 , y + 1.50 , player .getLocation ().getBlockZ () + 0.5 ).setDirection (player .getLocation ().getDirection ()));
74- } else {
75- player .teleport (new Location (world , player .getLocation ().getBlockX () + 0.5 , y + 0.50 , player .getLocation ().getBlockZ () + 0.5 ).setDirection (player .getLocation ().getDirection ()));
76- }
77- PermissionAttachment attachment = player .addAttachment (UtilsManager .getInstance ());
78- attachment .setPermission ("ported" , true );
79- new BukkitRunnable () {
80- @ Override
81- public void run () {
82- attachment .setPermission ("ported" , false );
83- }
84- }.runTaskLater (UtilsManager .getInstance (), 10 );
85- return ;
86- }
87- }
88- if (LanguageAPI .getApi ().getLanguage (player ) == 2 ) {
89- player .sendActionBar (Component .text ("Es gibt keine Teleporter über dir!" , NamedTextColor .RED ));
90- } else {
91- player .sendActionBar (Component .text ("There are no teleporters over you" , NamedTextColor .RED ));
92- }
52+ private boolean isOnCooldown (UUID playerId ) {
53+ Long lastTeleport = teleportCooldown .get (playerId );
54+ if (lastTeleport == null ) {
55+ return false ;
56+ }
57+
58+ long currentTime = System .currentTimeMillis ();
59+ long cooldownMs = COOLDOWN_TICKS * 50 ;
60+
61+ if (currentTime - lastTeleport < cooldownMs ) {
62+ return true ;
9363 }
64+
65+ teleportCooldown .remove (playerId );
66+ return false ;
67+ }
68+
69+ private void setCooldown (UUID playerId ) {
70+ teleportCooldown .put (playerId , System .currentTimeMillis ());
71+ }
72+
73+ private boolean isOnDaylightDetector (Player player ) {
74+ Block blockAtFeet = player .getLocation ().getBlock ();
75+ Block blockBelow = player .getLocation ().subtract (0 , 1 , 0 ).getBlock ();
76+
77+ return blockAtFeet .getType () == Material .DAYLIGHT_DETECTOR ||
78+ blockBelow .getType () == Material .DAYLIGHT_DETECTOR ;
9479 }
9580
96- public void down (Player player ) {
97- Block thisblock = player .getLocation ().getBlock ();
98- Location second = player .getLocation ();
99- second .setY (second .getY ()-1.0 );
100- Block thissecondblock = second .getBlock ();
101- if (thisblock .getType () == Material .DAYLIGHT_DETECTOR || thissecondblock .getType () == Material .DAYLIGHT_DETECTOR ) {
102- for (int y = player .getLocation ().getBlockY () - 2 ; y >= player .getWorld ().getMinHeight (); y --) {
103- Block block = player .getWorld ().getBlockAt (player .getLocation ().getBlockX (), y , player .getLocation ().getBlockZ ());
104- if (block .getType () == Material .DAYLIGHT_DETECTOR ) {
105- World world = player .getWorld ();
106- Block blockbackup = player .getWorld ().getBlockAt (player .getLocation ().getBlockX (), y + 1 , player .getLocation ().getBlockZ ());
107- if (blockbackup .getType () != Material .AIR ) {
108- player .teleport (new Location (world , player .getLocation ().getBlockX () + 0.5 , y + 1.50 , player .getLocation ().getBlockZ () + 0.5 ).setDirection (player .getLocation ().getDirection ()));
109- } else {
110- player .teleport (new Location (world , player .getLocation ().getBlockX () + 0.5 , y + 0.50 , player .getLocation ().getBlockZ () + 0.5 ).setDirection (player .getLocation ().getDirection ()));
111- }
112- PermissionAttachment attachment = player .addAttachment (UtilsManager .getInstance ());
113- attachment .setPermission ("ported" , true );
114- new BukkitRunnable () {
115- @ Override
116- public void run () {
117- attachment .setPermission ("ported" , false );
118- }
119- }.runTaskLater (UtilsManager .getInstance (), 10 );
120- return ;
121- }
81+ private void teleportUp (Player player ) {
82+ int startY = player .getLocation ().getBlockY () + 1 ;
83+ int maxY = player .getWorld ().getMaxHeight ();
84+
85+ for (int y = startY ; y <= maxY ; y ++) {
86+ Block block = player .getWorld ().getBlockAt (
87+ player .getLocation ().getBlockX (),
88+ y ,
89+ player .getLocation ().getBlockZ ()
90+ );
91+
92+ if (block .getType () == Material .DAYLIGHT_DETECTOR ) {
93+ performTeleport (player , y );
94+ return ;
12295 }
123- if (LanguageAPI .getApi ().getLanguage (player ) == 2 ) {
124- player .sendActionBar (Component .text ("Es gibt keine Teleporter unter dir!" , NamedTextColor .RED ));
125- } else {
126- player .sendActionBar (Component .text ("There are no teleporters under you" , NamedTextColor .RED ));
96+ }
97+
98+ sendNoTeleporterMessage (player , true );
99+ }
100+
101+ private void teleportDown (Player player ) {
102+ int startY = player .getLocation ().getBlockY () - 2 ;
103+ int minY = player .getWorld ().getMinHeight ();
104+
105+ for (int y = startY ; y >= minY ; y --) {
106+ Block block = player .getWorld ().getBlockAt (
107+ player .getLocation ().getBlockX (),
108+ y ,
109+ player .getLocation ().getBlockZ ()
110+ );
111+
112+ if (block .getType () == Material .DAYLIGHT_DETECTOR ) {
113+ performTeleport (player , y );
114+ return ;
127115 }
128116 }
117+
118+ sendNoTeleporterMessage (player , false );
119+ }
120+
121+ private void performTeleport (Player player , int targetY ) {
122+ World world = player .getWorld ();
123+ int x = player .getLocation ().getBlockX ();
124+ int z = player .getLocation ().getBlockZ ();
125+
126+ Block blockAbove = world .getBlockAt (x , targetY + 1 , z );
127+ double yOffset = blockAbove .getType () != Material .AIR ? 1.50 : 0.50 ;
128+
129+ Location teleportLocation = new Location (
130+ world ,
131+ x + 0.5 ,
132+ targetY + yOffset ,
133+ z + 0.5
134+ );
135+ teleportLocation .setDirection (player .getLocation ().getDirection ());
136+
137+ player .teleport (teleportLocation );
138+ setCooldown (player .getUniqueId ());
139+ }
140+
141+ private void sendNoTeleporterMessage (Player player , boolean searchingUp ) {
142+ String messageKey = searchingUp ?
143+ "Es gibt keine Teleporter über dir!" :
144+ "Es gibt keine Teleporter unter dir!" ;
145+ String messageEn = searchingUp ?
146+ "There are no teleporters above you!" :
147+ "There are no teleporters below you!" ;
148+
149+ if (LanguageAPI .getApi ().getLanguage (player ) == 2 ) {
150+ player .sendActionBar (Component .text (messageKey , NamedTextColor .RED ));
151+ } else {
152+ player .sendActionBar (Component .text (messageEn , NamedTextColor .RED ));
153+ }
129154 }
130- }
155+ }
0 commit comments