You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
8.8 KiB
243 lines
8.8 KiB
package net.deliciousreya.minecraftportal
|
|
|
|
import com.destroystokyo.paper.event.block.BlockDestroyEvent
|
|
import net.deliciousreya.minecraftportal.extensions.COLOR_NAME_MAPPING
|
|
import net.deliciousreya.minecraftportal.extensions.MID_BLOCK
|
|
import net.deliciousreya.minecraftportal.extensions.plus
|
|
import net.deliciousreya.minecraftportal.model.DOOR_TYPES
|
|
import net.deliciousreya.minecraftportal.model.PortalDataStore
|
|
import net.deliciousreya.minecraftportal.model.PortalFrame
|
|
import net.deliciousreya.minecraftportal.model.findPortalFrameConnectedTo
|
|
import org.bukkit.Material
|
|
import org.bukkit.Sound
|
|
import org.bukkit.block.Block
|
|
import org.bukkit.block.data.type.Door
|
|
import org.bukkit.command.Command
|
|
import org.bukkit.command.CommandSender
|
|
import org.bukkit.entity.Entity
|
|
import org.bukkit.entity.Player
|
|
import org.bukkit.event.EventHandler
|
|
import org.bukkit.event.Listener
|
|
import org.bukkit.event.block.*
|
|
import org.bukkit.event.entity.EntityChangeBlockEvent
|
|
import org.bukkit.event.entity.EntityExplodeEvent
|
|
import org.bukkit.event.player.PlayerInteractEvent
|
|
import org.bukkit.event.player.PlayerMoveEvent
|
|
import org.bukkit.plugin.java.JavaPlugin
|
|
import org.bukkit.potion.PotionEffectType
|
|
import java.lang.IllegalStateException
|
|
import java.util.*
|
|
|
|
class MinecraftPortalPlugin() : JavaPlugin(), Listener
|
|
{
|
|
val portals: PortalDataStore = PortalDataStore(logger)
|
|
|
|
override fun onEnable() {
|
|
super.onEnable()
|
|
if (!dataFolder.isDirectory) {
|
|
if (dataFolder.exists()) {
|
|
throw IllegalStateException("Data folder already exists but not as a directory")
|
|
} else {
|
|
logger.info("Setting up in newly created data directory $dataFolder")
|
|
dataFolder.mkdirs()
|
|
}
|
|
} else {
|
|
logger.info("Setting up in data directory $dataFolder")
|
|
}
|
|
portals.loadFromAndAutoSaveTo(server, dataFolder.resolve("portal_data.binproto"), dataFolder.resolve("portal_data.binproto.bak"))
|
|
portals.validateWorldOnStartup(logger)
|
|
portals.launchEffectsOnStartup(this)
|
|
val setColorCommand = getCommand("portalcolor") ?: throw IllegalStateException("portalcolor command was missing")
|
|
setColorCommand.setExecutor { sender, _, _, args -> onPortalColor(sender, args) }
|
|
server.pluginManager.registerEvents(this, this)
|
|
}
|
|
|
|
override fun onDisable() {
|
|
super.onDisable()
|
|
portals.unload()
|
|
}
|
|
|
|
fun onPortalColor(sender: CommandSender, args: Array<String>): Boolean {
|
|
val argsList = if (args.isEmpty() && sender is Player) {
|
|
listOf("show")
|
|
} else {
|
|
args.asList()
|
|
}
|
|
if (argsList.isEmpty() || args.size > 2) {
|
|
sender.sendMessage("You must specify one or two arguments.")
|
|
return false
|
|
}
|
|
val colorString = if (argsList.size == 1) {
|
|
argsList[0]
|
|
} else {
|
|
argsList[1]
|
|
}
|
|
val playerString: String = when {
|
|
argsList.size == 2 -> {
|
|
val player = server.getPlayer(args[0])
|
|
player?.uniqueId?.toString()
|
|
?: try {
|
|
UUID.fromString(args[0]).toString()
|
|
} catch (ex: IllegalArgumentException) {
|
|
"bad UUID"
|
|
}
|
|
}
|
|
sender is Player -> {
|
|
sender.uniqueId.toString()
|
|
}
|
|
else -> {
|
|
"console"
|
|
}
|
|
}
|
|
if (playerString == "console") {
|
|
sender.sendMessage("Only players can set their own color with the one-arg form.")
|
|
return false
|
|
} else if (playerString == "bad UUID") {
|
|
sender.sendMessage("You must pass a UUID or the name of an online player.")
|
|
return false
|
|
}
|
|
if (colorString == "show") {
|
|
if (sender is Player && playerString == sender.uniqueId.toString()) {
|
|
sender.sendMessage("Portals you create are marked with ${portals.getColorFor(playerString).name}.")
|
|
} else {
|
|
val name = server.getOfflinePlayer(UUID.fromString(playerString)).name
|
|
sender.sendMessage("Portals created by $name are marked with ${portals.getColorFor(playerString).name}.")
|
|
}
|
|
return true
|
|
}
|
|
if ((sender !is Player || playerString != sender.uniqueId.toString()) && !sender.isOp) {
|
|
sender.sendMessage("Only ops can set other players' colors with the two-arg form.")
|
|
return false
|
|
}
|
|
val color = COLOR_NAME_MAPPING[colorString]
|
|
if (color == null) {
|
|
sender.sendMessage("I don't know that color. Are you sure it's one of the dye colors?")
|
|
return false
|
|
}
|
|
portals.setColorFor(playerString, color)
|
|
if (sender is Player && playerString == sender.uniqueId.toString()) {
|
|
sender.sendMessage("Your portals will now be marked with ${portals.getColorFor(playerString).name}.")
|
|
} else {
|
|
val name = server.getOfflinePlayer(UUID.fromString(playerString)).name
|
|
sender.sendMessage("Portals created by $name will now be marked with ${portals.getColorFor(playerString).name}")
|
|
}
|
|
return true
|
|
}
|
|
|
|
@EventHandler
|
|
fun onBlockPlaced(e: BlockPlaceEvent) {
|
|
e.player.name
|
|
if (e.block.type in PortalFrame.State.INACTIVE.allValidBlocks) {
|
|
val newPortal = findPortalFrameConnectedTo(
|
|
e.block,
|
|
PortalFrame.State.INACTIVE
|
|
)
|
|
if (newPortal != null) {
|
|
if (newPortal.color == Material.GLASS) {
|
|
newPortal.color = portals.getColorFor(e.player.uniqueId.toString())
|
|
}
|
|
val replacedPortal = portals.activateAndReplacePortal(newPortal)
|
|
val otherPortal = portals.getOtherPortal(newPortal)
|
|
newPortal.activate()
|
|
replacedPortal?.deactivate()
|
|
if (otherPortal != null) {
|
|
newPortal.open()
|
|
otherPortal.open()
|
|
portals.startEffectsFor(newPortal, this)
|
|
} else {
|
|
newPortal.ejectEntities()
|
|
newPortal.close()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
fun onBlockDestroy(e:BlockDestroyEvent) {
|
|
onDestroyedBlock(e.block)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onEntityExplosion(e:EntityExplodeEvent) {
|
|
e.blockList().forEach(::onDestroyedBlock)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onBlockExplosion(e:BlockExplodeEvent) {
|
|
onDestroyedBlock(e.block)
|
|
e.blockList().forEach(::onDestroyedBlock)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onBlockBurn(e: BlockBurnEvent) {
|
|
onDestroyedBlock(e.block)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onBlockFade(e: BlockFadeEvent) {
|
|
onDestroyedBlock(e.block)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onBlockBreak(e:BlockBreakEvent) {
|
|
onDestroyedBlock(e.block)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onEntityChangeBlock(e: EntityChangeBlockEvent) {
|
|
onDestroyedBlock(e.block)
|
|
}
|
|
|
|
@EventHandler
|
|
fun onPlayerInteract(e: PlayerInteractEvent) {
|
|
if (e.clickedBlock == null || e.action != Action.RIGHT_CLICK_BLOCK) {
|
|
return
|
|
}
|
|
val block = e.clickedBlock!!
|
|
if(block.type !in DOOR_TYPES) {
|
|
return
|
|
}
|
|
val door = block.blockData as Door
|
|
val location = e.player.location
|
|
// i.e., is the door part of a portal and are we standing in that portal?
|
|
val portal = portals.isLocationInPortalChamber(block.location + MID_BLOCK) ?: return
|
|
if (location.toVector() !in portal.portalInsideBoundingBox) {
|
|
e.isCancelled = true
|
|
return
|
|
}
|
|
if (!door.isOpen) {
|
|
portals.stopTeleporting(portal)
|
|
} else {
|
|
portals.startTeleporting(portal, this)
|
|
}
|
|
}
|
|
|
|
//fun onPlayerMove(e: PlayerMoveEvent) {
|
|
//val player = e.player
|
|
//val oldLocation = e.from
|
|
//val portal = portals.isLocationInPortalChamber(oldLocation) ?: return
|
|
//val newLocation = e.to ?: return
|
|
//if (oldLocation.world != newLocation.world || oldLocation.toVector() !in portal.portalInsideBoundingBox) {
|
|
// TODO: cancelTeleportFor(player)
|
|
//}
|
|
//}
|
|
|
|
fun onDestroyedBlock(block: Block) {
|
|
if (block.type !in PortalFrame.State.ACTIVE.allValidBlocks) {
|
|
return
|
|
}
|
|
val oldPortal = findPortalFrameConnectedTo(
|
|
block,
|
|
PortalFrame.State.ACTIVE
|
|
)
|
|
if (oldPortal != null) {
|
|
val otherPortal = portals.getOtherPortal(oldPortal)
|
|
portals.deactivatePortal(oldPortal)
|
|
oldPortal.deactivate()
|
|
if (otherPortal != null) {
|
|
otherPortal.ejectEntities()
|
|
otherPortal.close()
|
|
}
|
|
}
|
|
}
|
|
} |