1+ package xyz.theprogramsrc.uismodule
2+
3+ import com.cryptomorin.xseries.messages.ActionBar
4+ import com.cryptomorin.xseries.messages.Titles
5+ import org.bukkit.Bukkit
6+ import org.bukkit.entity.Player
7+ import org.bukkit.event.EventHandler
8+ import org.bukkit.event.EventPriority
9+ import org.bukkit.event.HandlerList
10+ import org.bukkit.event.Listener
11+ import org.bukkit.event.block.Action
12+ import org.bukkit.event.player.AsyncPlayerChatEvent
13+ import org.bukkit.event.player.PlayerInteractEvent
14+ import org.bukkit.event.player.PlayerMoveEvent
15+ import xyz.theprogramsrc.simplecoreapi.spigot.SpigotLoader
16+ import xyz.theprogramsrc.tasksmodule.objects.RecurringTask
17+ import xyz.theprogramsrc.tasksmodule.spigot.SpigotTasks
18+ import xyz.theprogramsrc.uismodule.objects.bukkitColor
19+ import xyz.theprogramsrc.uismodule.objects.bukkitStripColor
20+
21+ /* *
22+ * Representation of a dialog
23+ * @param player The player that will see the dialog
24+ * @param title The title of the dialog. If null it will be empty. (Defaults to null)
25+ * @param subtitle The subtitle of the dialog. If null it will be empty. (Defaults to null)
26+ * @param actionbar The actionbar of the dialog. If null it will be empty. (Defaults to null)
27+ * @param onClose The function that will be called when the player closes the dialog. (Defaults to empty function)
28+ */
29+ class Dialog (
30+ val player : Player ,
31+ val title : String? = null ,
32+ val subtitle : String? = null ,
33+ val actionbar : String? = null ,
34+ val onClose : (Player ) -> Unit = {},
35+ val onChat : (Player , String ) -> Boolean = { _: Player , _: String -> true },
36+ ): Listener{
37+
38+ private var task: RecurringTask ? = null
39+ private var lastMovementAt = 0L
40+
41+ /* *
42+ * Should the player be able to close this dialog?
43+ */
44+ var canBeClosed = true
45+
46+ /* *
47+ * Was this dialog closed manually or programmatically?
48+ */
49+ var manuallyClosed = false
50+ private set
51+
52+ private fun send () {
53+ if (this .player.isOnline) { // Check if the player is online
54+ if (this .title != null || this .subtitle != null ) {
55+ Titles .sendTitle(
56+ this .player,
57+ 0 , // Fade in
58+ 20 , // Stay
59+ 0 , // Fade out
60+ (this .title ? : " &7" ).bukkitColor(),
61+ (this .subtitle ? : " &7" ).bukkitColor()
62+ )
63+ } else {
64+ Titles .clearTitle(this .player)
65+ }
66+
67+ val now = System .currentTimeMillis() // Get the current time
68+ val calc = now - lastMovementAt // Calculate the difference between the last movement and now. (If the player hasn't moved the calc will be equals to now)
69+ // Show the close actionbar translation if the player has moved in the last 5 seconds, otherwise show the actionbar
70+ val actionbar = if (calc < 5000L && calc != now && this .canBeClosed) {
71+ Main .HOW_TO_CLOSE_DIALOG_TRANSLATION .translate()
72+ } else {
73+ this .actionbar
74+ }
75+
76+ if (actionbar != null ){
77+ ActionBar .sendActionBar(this .player, actionbar.bukkitColor())
78+ }else {
79+ ActionBar .clearActionBar(this .player)
80+ }
81+ } else {
82+ this .task?.stop()
83+ }
84+ }
85+
86+ fun open (): Dialog = this .apply {
87+ if (this .task == null ){
88+ this .task = SpigotTasks .instance.runTaskTimerAsynchronously(delay = 1L , period = 5L , task = this ::send)
89+ }
90+ this .task?.stop() // Stop the previous task if there is any
91+ HandlerList .unregisterAll(this ) // Unregister all the listeners
92+ SpigotTasks .instance.runTask(this .player::closeInventory) // Close the inventory of the player
93+ Bukkit .getPluginManager().registerEvents(this , SpigotLoader .instance) // Register the listeners
94+ this .task?.start() // Start the task
95+ this .manuallyClosed = false // Reset the manually closed flag
96+ }
97+
98+ fun close (sendMessage : Boolean = true): Dialog = this .apply {
99+ this .task?.stop() // Stop the task
100+ HandlerList .unregisterAll(this ) // Unregister all the listeners
101+ this .manuallyClosed = true // Set the manually closed flag
102+ Titles .clearTitle(this .player) // Clear the title
103+ ActionBar .clearActionBar(this .player) // Clear the actionbar
104+ if (sendMessage) { // Send the message if the flag is true
105+ this .player.sendMessage(Main .DIALOG_CLOSED_TRANSLATION .translate().bukkitColor())
106+ }
107+ }
108+
109+ @EventHandler(priority = EventPriority .LOWEST )
110+ fun onInteract (e : PlayerInteractEvent ) {
111+ if (this .player == e.player && this .canBeClosed) {
112+ if (e.action == Action .LEFT_CLICK_AIR || e.action == Action .LEFT_CLICK_BLOCK ) {
113+ this .close()
114+ }
115+ }
116+ }
117+
118+ @EventHandler(priority = EventPriority .LOWEST )
119+ fun onMessageReceived (event : AsyncPlayerChatEvent ) {
120+ if (this .player == event.player) {
121+ event.isCancelled = true
122+ val msg = event.message.bukkitStripColor()
123+ SpigotTasks .instance.runTask {
124+ if (this .onChat(this .player, msg)) {
125+ this .manuallyClosed = false
126+ this .close()
127+ }
128+ }
129+ }
130+ }
131+
132+ @EventHandler(ignoreCancelled = true , priority = EventPriority .LOWEST )
133+ fun onMove (e : PlayerMoveEvent ) {
134+ if (this .player == e.player){ // Check if the player is the same
135+ this .lastMovementAt = System .currentTimeMillis() // Update the last movement time
136+ }
137+ }
138+
139+
140+ }
0 commit comments