1
0
Fork 0

Add colors for players

main
Mari 4 years ago
parent 5a664edb8e
commit 744e09483b
  1. 89
      src/main/kotlin/net/deliciousreya/minecraftportal/MinecraftPortalPlugin.kt
  2. 50
      src/main/kotlin/net/deliciousreya/minecraftportal/extensions/Material.kt
  3. 29
      src/main/kotlin/net/deliciousreya/minecraftportal/model/Portal.kt
  4. 57
      src/main/kotlin/net/deliciousreya/minecraftportal/model/PortalDataStore.kt
  5. 62
      src/main/kotlin/net/deliciousreya/minecraftportal/model/PortalFrame.kt
  6. 17
      src/main/kotlin/net/deliciousreya/minecraftportal/model/PortalType.kt
  7. 26
      src/main/proto/portal-save-data.proto
  8. 7
      src/main/resources/plugin.yml

@ -1,15 +1,19 @@
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
@ -21,6 +25,7 @@ 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
class MinecraftPortalPlugin() : JavaPlugin(), Listener
{
@ -31,6 +36,8 @@ class MinecraftPortalPlugin() : JavaPlugin(), Listener
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)
}
@ -39,8 +46,65 @@ class MinecraftPortalPlugin() : JavaPlugin(), Listener
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 = when {
argsList.size == 2 -> {
argsList[0]
}
sender is Player -> {
sender.name
}
else -> {
null
}
}
if (playerString == null) {
sender.sendMessage("Only players can set their own color with the one-arg form.")
return false
}
if (colorString == "show") {
if (sender is Player && playerString == sender.name) {
sender.sendMessage("Portals you create are marked with ${portals.getColorFor(playerString).name}.")
} else {
sender.sendMessage("Portals created by $playerString are marked with ${portals.getColorFor(playerString).name}.")
}
return true
}
if (playerString != sender.name && !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.name) {
sender.sendMessage("Your portals will now be marked with ${portals.getColorFor(playerString).name}.")
} else {
sender.sendMessage("Portals created by $playerString 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,
@ -50,6 +114,9 @@ class MinecraftPortalPlugin() : JavaPlugin(), Listener
val replacedPortal = portals.activateAndReplacePortal(newPortal)
val otherPortal = portals.getOtherPortal(newPortal)
newPortal.activate()
if (newPortal.color == Material.GLASS) {
newPortal.color = portals.getColorFor(e.player.name)
}
replacedPortal?.deactivate()
if (otherPortal != null) {
newPortal.open()
@ -123,19 +190,15 @@ class MinecraftPortalPlugin() : JavaPlugin(), Listener
}
}
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) {
cancelTeleportFor(player)
}
}
private fun cancelTeleportFor(entity: Entity) {
}
//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) {

@ -6,6 +6,44 @@ import net.deliciousreya.minecraftportal.proto.PortalSaveDataProtos
import org.bukkit.Material
import java.lang.IllegalStateException
val COLOR_NAME_MAPPING: ImmutableBiMap<String, Material> = ImmutableBiMap.builder<String, Material>()
.put("white", Material.WHITE_STAINED_GLASS)
.put("red", Material.RED_STAINED_GLASS)
.put("orange", Material.ORANGE_STAINED_GLASS)
.put("pink", Material.PINK_STAINED_GLASS)
.put("yellow", Material.YELLOW_STAINED_GLASS)
.put("lime", Material.LIME_STAINED_GLASS)
.put("green", Material.GREEN_STAINED_GLASS)
.put("lightblue", Material.LIGHT_BLUE_STAINED_GLASS)
.put("cyan", Material.CYAN_STAINED_GLASS)
.put("blue", Material.BLUE_STAINED_GLASS)
.put("magenta", Material.MAGENTA_STAINED_GLASS)
.put("purple", Material.PURPLE_STAINED_GLASS)
.put("brown", Material.BROWN_STAINED_GLASS)
.put("gray", Material.GRAY_STAINED_GLASS)
.put("lightgray", Material.LIGHT_GRAY_STAINED_GLASS)
.put("black", Material.BLACK_STAINED_GLASS)
.build()
val COLOR_MAPPING: ImmutableBiMap<Material, PortalSaveDataProtos.Portal.Color> = ImmutableBiMap.builder<Material, PortalSaveDataProtos.Portal.Color>()
.put(Material.WHITE_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.WHITE)
.put(Material.RED_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.RED)
.put(Material.ORANGE_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.ORANGE)
.put(Material.PINK_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.PINK)
.put(Material.YELLOW_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.YELLOW)
.put(Material.LIME_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.LIME)
.put(Material.GREEN_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.GREEN)
.put(Material.LIGHT_BLUE_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.LIGHT_BLUE)
.put(Material.CYAN_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.CYAN)
.put(Material.BLUE_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.BLUE)
.put(Material.MAGENTA_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.MAGENTA)
.put(Material.PURPLE_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.PURPLE)
.put(Material.BROWN_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.BROWN)
.put(Material.GRAY_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.GRAY)
.put(Material.LIGHT_GRAY_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.LIGHT_GRAY)
.put(Material.BLACK_STAINED_GLASS, PortalSaveDataProtos.Portal.Color.BLACK)
.build()
val MINERAL_MAPPING: ImmutableBiMap<Material, PortalSaveDataProtos.Portal.Mineral> = ImmutableBiMap.builder<Material, PortalSaveDataProtos.Portal.Mineral>()
.put(Material.COAL_BLOCK, PortalSaveDataProtos.Portal.Mineral.COAL)
.put(Material.REDSTONE_BLOCK, PortalSaveDataProtos.Portal.Mineral.REDSTONE)
@ -18,9 +56,17 @@ val MINERAL_MAPPING: ImmutableBiMap<Material, PortalSaveDataProtos.Portal.Minera
.build()
fun Material.toMineralProto(): PortalSaveDataProtos.Portal.Mineral {
return MINERAL_MAPPING[this] ?: throw DeserializationException("Not a mineral: ${this}")
return MINERAL_MAPPING[this] ?: throw DeserializationException("Not a mineral: $this")
}
fun Material.toColorProto(): PortalSaveDataProtos.Portal.Color {
return COLOR_MAPPING[this] ?: throw DeserializationException("Not a color: $this")
}
fun PortalSaveDataProtos.Portal.Mineral.toMaterial(): Material {
return MINERAL_MAPPING.inverse()[this] ?: throw DeserializationException("Not a material: ${this}")
return MINERAL_MAPPING.inverse()[this] ?: throw DeserializationException("Not a material: $this")
}
fun PortalSaveDataProtos.Portal.Color.toMaterial(): Material {
return COLOR_MAPPING.inverse()[this] ?: throw DeserializationException("Not a material: $this")
}

@ -1,20 +1,30 @@
package net.deliciousreya.minecraftportal.model
import net.deliciousreya.minecraftportal.extensions.toLocation
import net.deliciousreya.minecraftportal.extensions.toMaterial
import net.deliciousreya.minecraftportal.extensions.toMineralProto
import net.deliciousreya.minecraftportal.extensions.toProto
import net.deliciousreya.minecraftportal.extensions.*
import net.deliciousreya.minecraftportal.proto.PortalSaveDataProtos
import org.bukkit.Material
import org.bukkit.Server
import org.bukkit.plugin.Plugin
import org.bukkit.scheduler.BukkitRunnable
import java.lang.IllegalArgumentException
fun PortalSaveDataProtos.Portal.toPortal(server: Server, portalTypes: Map<Material, PortalType>): Portal {
val portalType = portalTypes[mineral.toMaterial()] ?: throw IllegalArgumentException("No portal type for $mineral")
val result = Portal(PortalFrame(lowerLeftFrontCorner.toLocation(server), exitDirection.toDirection()), portalType)
return result
fun PortalSaveDataProtos.Portal.Mineral.asColor(): PortalSaveDataProtos.Portal.Color {
if (this == PortalSaveDataProtos.Portal.Mineral.UNKNOWN_MINERAL) {
throw IllegalArgumentException("No portal color for $this")
}
val material = toMaterial()
val matchingGlass = MINERAL_TYPES[material] ?: throw IllegalArgumentException("No portal color for $this: no glass matches")
return COLOR_MAPPING[matchingGlass] ?: throw IllegalArgumentException("No portal color for $this: no color matches")
}
fun PortalSaveDataProtos.Portal.toPortal(server: Server, portalTypes: Map<Material, Map<Material, PortalType>>): Portal {
val mineralMap = portalTypes[mineral.toMaterial()] ?: throw IllegalArgumentException("No portal type for $mineral")
val effectiveColor = if (color == PortalSaveDataProtos.Portal.Color.UNKNOWN_COLOR) {
mineral.asColor()
} else {
color
}
val portalType = mineralMap[effectiveColor.toMaterial()] ?: throw IllegalArgumentException("No portal type for $color")
return Portal(PortalFrame(lowerLeftFrontCorner.toLocation(server), exitDirection.toDirection()), portalType)
}
class Portal(val frame: PortalFrame, val type: PortalType) {
@ -41,6 +51,7 @@ class Portal(val frame: PortalFrame, val type: PortalType) {
.setLowerLeftFrontCorner(frame.lowerLeftFrontCorner.toProto())
.setExitDirection(frame.direction.toProto())
.setMineral(frame.mineral.toMineralProto())
.setColor(frame.color.toColorProto())
.build()
}
}

@ -1,8 +1,12 @@
package net.deliciousreya.minecraftportal.model
import com.google.common.collect.ImmutableList
import com.google.common.collect.ImmutableMap
import com.google.protobuf.InvalidProtocolBufferException
import net.deliciousreya.minecraftportal.extensions.COLOR_MAPPING
import net.deliciousreya.minecraftportal.extensions.MINERAL_MAPPING
import net.deliciousreya.minecraftportal.extensions.toColorProto
import net.deliciousreya.minecraftportal.extensions.toMaterial
import net.deliciousreya.minecraftportal.proto.PortalSaveDataProtos
import org.bukkit.Location
import org.bukkit.Material
@ -16,17 +20,27 @@ import java.util.logging.Logger
class PortalDataStore (){
var saveDataTo: File? = null
var useBackup: File? = null
val portalTypes: ImmutableMap<Material, PortalType>
private val userColors: MutableMap<String, Material> = mutableMapOf()
private val portalTypes: ImmutableMap<Material, ImmutableMap<Material, PortalType>>
private val allPortals: ImmutableList<PortalType>
init {
val portalTypesBuilder = ImmutableMap.builder<Material, PortalType>()
val allPortalsBuilder = ImmutableList.builder<PortalType>()
val portalTypesBuilder = ImmutableMap.builder<Material, ImmutableMap<Material, PortalType>>()
for (mineralType in MINERAL_MAPPING.keys) {
portalTypesBuilder.put(mineralType, PortalType(mineralType))
val colors = ImmutableMap.Builder<Material, PortalType>()
for (color in COLOR_MAPPING.keys) {
val portalType = PortalType(mineralType, color)
colors.put(color, portalType)
allPortalsBuilder.add(portalType)
}
portalTypesBuilder.put(mineralType, colors.build())
}
portalTypes = portalTypesBuilder.build()
allPortals = allPortalsBuilder.build()
}
fun isLocationInPortalOrChamber(location: Location): PortalFrame? {
for (type in this.portalTypes.values) {
for (type in this.allPortals) {
if (type.isEmpty) {
continue
}
@ -39,7 +53,7 @@ class PortalDataStore (){
}
fun isLocationInPortalChamber(location: Location): PortalFrame? {
for (type in this.portalTypes.values) {
for (type in this.allPortals) {
if (type.isEmpty) {
continue
}
@ -90,7 +104,7 @@ class PortalDataStore (){
}
fun validateWorldOnStartup(logger: Logger) {
for (portalType in this.portalTypes.values) {
for (portalType in this.allPortals) {
val oldPortal = portalType.oldestActivePortal
val newPortal = portalType.newestActivePortal
if (newPortal != null && !validatePortal(newPortal)) {
@ -106,11 +120,11 @@ class PortalDataStore (){
}
fun validatePortal(portal: Portal): Boolean {
return portal.frame.mineral == portal.type.mineral && portal.frame.isActivePortal()
return portal.frame.mineral == portal.type.mineral && portal.frame.color == portal.type.color && portal.frame.isActivePortal()
}
fun launchEffectsOnStartup(plugin: Plugin) {
for (portalType in this.portalTypes.values) {
for (portalType in this.allPortals) {
startEffectsFor(portalType, plugin)
}
}
@ -174,7 +188,7 @@ class PortalDataStore (){
}
fun getPortalType(frame: PortalFrame): PortalType {
return portalTypes[frame.mineral] ?: throw IllegalArgumentException("There are no portals of type ${frame.mineral}")
return portalTypes[frame.mineral]?.get(frame.color) ?: throw IllegalArgumentException("There are no portals of type ${frame.mineral}/${frame.color}")
}
/** Gets the other portal, if the given frame is one of the portals in a pair. */
@ -185,7 +199,7 @@ class PortalDataStore (){
/** Forgets all the data without actually affecting the world. */
fun clear() {
for (portalType in this.portalTypes.values) {
for (portalType in this.allPortals) {
portalType.oldestActivePortal?.stopEffects()
portalType.newestActivePortal?.stopEffects()
portalType.clear()
@ -206,11 +220,14 @@ class PortalDataStore (){
}
olderPortal.type.loadPairedPortals(olderPortal, newerPortal)
}
for (userData in proto.userDataList) {
userColors[userData.name] = userData.color.toMaterial()
}
}
fun toProto(): PortalSaveDataProtos.PortalSaveData {
val builder = PortalSaveDataProtos.PortalSaveData.newBuilder()
for (portalType in this.portalTypes.values) {
for (portalType in this.allPortals) {
when {
portalType.isEmpty -> {
// Nothing here to save. Just skip it.
@ -223,6 +240,9 @@ class PortalDataStore (){
}
}
}
for (user in this.userColors.keys) {
builder.addUserData(PortalSaveDataProtos.UserData.newBuilder().setName(user).setColor(this.userColors[user]?.toColorProto()))
}
return builder.build()
}
@ -233,4 +253,19 @@ class PortalDataStore (){
fun stopTeleporting(portal: PortalFrame) {
getPortalType(portal).cancelTeleportation()
}
private val defaultColor = Material.GRAY_STAINED_GLASS
fun getColorFor(name: String): Material {
return userColors.getOrDefault(name, defaultColor)
}
fun setColorFor(name: String, color: Material) {
if (color == defaultColor) {
userColors.remove(name)
} else {
userColors[name] = color
}
onAfterChanged()
}
}

@ -33,11 +33,11 @@ val MINERAL_TYPES: ImmutableMap<Material, Material> = ImmutableMap.Builder<Mater
val DOOR_TYPES: ImmutableSet<Material> = ImmutableSet.of(ACACIA_DOOR, BIRCH_DOOR, DARK_OAK_DOOR, IRON_DOOR, JUNGLE_DOOR, OAK_DOOR, SPRUCE_DOOR)
fun findPortalFrameConnectedTo(block:Block, state: PortalFrame.State): PortalFrame? {
when {
block.type in state.glassBlocks -> for (direction in PortalFrame.ExitDirection.values()) {
for (vector in direction.glassOffsets) {
for (blockSet in state.blockSets) {
for (direction in PortalFrame.ExitDirection.values()) {
for (offset in blockSet.offsets(direction)) {
val scanResult = checkPortalFrameAt(
block.location.subtract(vector),
block.location.subtract(offset),
direction,
state
)
@ -46,28 +46,6 @@ fun findPortalFrameConnectedTo(block:Block, state: PortalFrame.State): PortalFra
}
}
}
block.type in state.doorBlocks -> for (direction in PortalFrame.ExitDirection.values()) {
for (vector in direction.doorOffsets) {
val scanResult = checkPortalFrameAt(
block.location.subtract(vector),
direction,
state
)
if (scanResult != null) {
return scanResult
}
}
}
block.type in state.mineralBlocks -> for (direction in PortalFrame.ExitDirection.values()) {
val scanResult = checkPortalFrameAt(
block.location.subtract(direction.mineralOffset),
direction,
state
)
if (scanResult != null) {
return scanResult
}
}
}
return null
}
@ -78,6 +56,10 @@ fun checkPortalFrameAt(location:Location, direction: PortalFrame.ExitDirection,
if (mineral.type !in state.mineralBlocks) {
return null
}
val color = (location + direction.colorOffset).block
if (color.type !in state.colorBlocks) {
return null
}
for (vector in direction.glassOffsets) {
val block = (location + vector).block
if (block.type !in state.glassBlocks) {
@ -105,13 +87,20 @@ fun PortalSaveDataProtos.Portal.Direction.toDirection(): PortalFrame.ExitDirecti
/** Information about a portal frame. */
data class PortalFrame(val lowerLeftFrontCorner: Location, val direction: ExitDirection) {
enum class State(val glassBlocks: ImmutableSet<Material>, val doorBlocks: ImmutableSet<Material>, val mineralBlocks: ImmutableSet<Material>) {
ACTIVE(ImmutableSet.copyOf(MINERAL_TYPES.values),
enum class State(val glassBlocks: ImmutableSet<Material>, val colorBlocks: ImmutableSet<Material>, val doorBlocks: ImmutableSet<Material>, val mineralBlocks: ImmutableSet<Material>) {
ACTIVE(ImmutableSet.copyOf(MINERAL_TYPES.values), ImmutableSet.copyOf(COLOR_MAPPING.keys),
DOOR_TYPES, ImmutableSet.copyOf(MINERAL_TYPES.keys)),
INACTIVE(ImmutableSet.of(GLASS),
INACTIVE(ImmutableSet.of(GLASS), ImmutableSet.builder<Material>().addAll(COLOR_MAPPING.keys).add(GLASS).build(),
DOOR_TYPES, ImmutableSet.copyOf(MINERAL_TYPES.keys));
val allValidBlocks:ImmutableSet<Material> = ImmutableSet.Builder<Material>().addAll(glassBlocks).addAll(doorBlocks).addAll(mineralBlocks).build()
val allValidBlocks:ImmutableSet<Material> = ImmutableSet.Builder<Material>().addAll(glassBlocks).addAll(doorBlocks).addAll(mineralBlocks).addAll(colorBlocks).build()
data class BlockSet(val blockTypes: Set<Material>, val offsets: (direction: ExitDirection) -> List<Vector>)
val blockSets = listOf(
BlockSet(glassBlocks, offsets = { it.glassOffsets }),
BlockSet(doorBlocks, offsets = { it.doorOffsets }),
BlockSet(colorBlocks, offsets = { listOf(it.colorOffset) }),
BlockSet(mineralBlocks, offsets = { listOf(it.mineralOffset) })
)
}
/** The direction a player faces when exiting the portal. */
enum class ExitDirection(val toRight: Vector, val toBack: Vector, val doorDirection: BlockFace, val protoEnum: PortalSaveDataProtos.Portal.Direction) {
@ -143,8 +132,6 @@ data class PortalFrame(val lowerLeftFrontCorner: Location, val direction: ExitDi
// left front wall
UP,
UP * 2,
// top front wall
UP * 3 + toRight,
// right front wall
UP + toRight * 2,
UP * 2 + toRight * 2,
@ -164,10 +151,11 @@ data class PortalFrame(val lowerLeftFrontCorner: Location, val direction: ExitDi
)
val mineralOffset: Vector = toRight
val colorOffset: Vector = UP * 3 + toRight
val doorOffsets: ImmutableList<Vector> = ImmutableList.of(
Vector(0, 1, 0) + toRight,
Vector(0, 2, 0) + toRight
UP + toRight,
UP * 2 + toRight
)
fun toProto():PortalSaveDataProtos.Portal.Direction {
@ -175,6 +163,7 @@ data class PortalFrame(val lowerLeftFrontCorner: Location, val direction: ExitDi
}
}
val portalCenter = lowerLeftFrontCorner + direction.doorOffsets[0]
val midCenter = portalCenter + MID_BLOCK
val fullPortalBoundingBox = BoundingBox.of(lowerLeftFrontCorner.block, (lowerLeftFrontCorner + UP * 3 + direction.toRight * 2 + direction.toBack).block)
@ -209,6 +198,11 @@ data class PortalFrame(val lowerLeftFrontCorner: Location, val direction: ExitDi
}
val mineral = (lowerLeftFrontCorner + direction.mineralOffset).block.type
var color: Material
get() = (lowerLeftFrontCorner + direction.colorOffset).block.type
set(newColor) {
(lowerLeftFrontCorner + direction.colorOffset).block.type = newColor
}
fun open() {
val block = portalCenter.block

@ -4,10 +4,9 @@ import net.deliciousreya.minecraftportal.proto.PortalSaveDataProtos
import org.bukkit.Location
import org.bukkit.Material
import org.bukkit.plugin.Plugin
import java.lang.IllegalArgumentException
import java.lang.IllegalStateException
class PortalType(val mineral: Material) {
class PortalType(val mineral: Material, val color: Material) {
var oldestActivePortal: Portal? = null
var newestActivePortal: Portal? = null
@ -31,7 +30,7 @@ class PortalType(val mineral: Material) {
fun addOrReplacePortal(portal: Portal): Portal? {
if (portal.type != this) {
throw DeserializationException("Tried to add $portal which didn't belong to ${this}")
throw DeserializationException("Tried to add $portal which didn't belong to $this")
}
return when {
this.isEmpty -> {
@ -54,23 +53,23 @@ class PortalType(val mineral: Material) {
fun loadUnpairedPortal(portal: Portal) {
if (!this.isEmpty) {
throw DeserializationException("Already have a value for ${this} when adding $portal")
throw DeserializationException("Already have a value for $this when adding $portal")
}
if (portal.type != this) {
throw DeserializationException("Tried to add $portal which didn't belong to ${this}")
throw DeserializationException("Tried to add $portal which didn't belong to $this")
}
this.oldestActivePortal = portal
}
fun loadPairedPortals(olderPortal: Portal, newerPortal: Portal) {
if (!this.isEmpty) {
throw DeserializationException("Already have a value for ${this} when adding $olderPortal and $newerPortal")
throw DeserializationException("Already have a value for $this when adding $olderPortal and $newerPortal")
}
if (olderPortal.type != this) {
throw DeserializationException("Tried to add $olderPortal which didn't belong to ${this}")
throw DeserializationException("Tried to add $olderPortal which didn't belong to $this")
}
if (newerPortal.type != this) {
throw DeserializationException("Tried to add $newerPortal which didn't belong to ${this}")
throw DeserializationException("Tried to add $newerPortal which didn't belong to $this")
}
this.oldestActivePortal = olderPortal
this.newestActivePortal = newerPortal
@ -95,7 +94,7 @@ class PortalType(val mineral: Material) {
}
override fun toString():String {
return "PortalType{mineral=$mineral, oldestActivePortal=$oldestActivePortal, newestActivePortal=$newestActivePortal}"
return "PortalType{mineral=$mineral, color=$color, oldestActivePortal=$oldestActivePortal, newestActivePortal=$newestActivePortal}"
}
/**

@ -31,9 +31,29 @@ message Portal {
IRON = 7;
QUARTZ = 8;
}
enum Color {
UNKNOWN_COLOR = 0;
WHITE = 1;
RED = 2;
ORANGE = 3;
PINK = 4;
YELLOW = 5;
LIME = 6;
GREEN = 7;
LIGHT_BLUE = 8;
CYAN = 9;
BLUE = 10;
MAGENTA = 11;
PURPLE = 12;
BROWN = 13;
GRAY = 14;
LIGHT_GRAY = 15;
BLACK = 16;
}
Location lower_left_front_corner = 1;
Direction exit_direction = 2;
Mineral mineral = 3;
Color color = 4;
}
message PortalPair {
@ -41,7 +61,13 @@ message PortalPair {
Portal newer = 2;
}
message UserData {
string name = 1;
Portal.Color color = 2;
}
message PortalSaveData {
repeated PortalPair paired_portals = 1;
repeated Portal unpaired_portals = 2;
repeated UserData user_data = 3;
}

@ -1 +1,6 @@
api-version: '1.13'
api-version: '1.16'
commands:
portalcolor:
description: Sets or gets the color of portals created by you or another player.
usage: "Usage: /portalcolor ([playername]) [show/white/red/orange/pink/yellow/lime/green/lightblue/cyan/blue/magenta/purple/brown/gray/lightgray/black]"

Loading…
Cancel
Save