nms custom villager and restructuring for teams
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "2.1.20-Beta1"
|
kotlin("jvm") version "2.1.20-Beta1"
|
||||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||||
|
id("io.papermc.paperweight.userdev") version "2.0.0-beta.11"
|
||||||
// id("de.nilsdruyen.gradle-ftp-upload-plugin") version "0.5.0"
|
// id("de.nilsdruyen.gradle-ftp-upload-plugin") version "0.5.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24,13 +25,13 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT")
|
// compileOnly("io.papermc.paper:paper-api:1.21.3-R0.1-SNAPSHOT")
|
||||||
// compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0")
|
// compileOnly("com.comphenix.protocol:ProtocolLib:5.3.0")
|
||||||
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit")
|
compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit")
|
||||||
compileOnly(files("libs/ProtocolLib.jar"))
|
compileOnly(files("libs/ProtocolLib.jar"))
|
||||||
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
|
||||||
implementation(platform("com.intellectualsites.bom:bom-newest:1.51")) // Ref: https://github.com/IntellectualSites/bom
|
implementation(platform("com.intellectualsites.bom:bom-newest:1.51")) // Ref: https://github.com/IntellectualSites/bom
|
||||||
// implementation("de.nilsdruyen.gradle-ftp-upload-plugin:de.nilsdruyen.gradle-ftp-upload-plugin.gradle.plugin:0.5.0")
|
paperweight.paperDevBundle("1.21.4-R0.1-SNAPSHOT")
|
||||||
}
|
}
|
||||||
|
|
||||||
val targetJavaVersion = 21
|
val targetJavaVersion = 21
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
|
||||||
networkTimeout=10000
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@ -1,15 +1,22 @@
|
|||||||
package com.pobnellion.aoe
|
package com.pobnellion.aoe
|
||||||
|
|
||||||
import com.pobnellion.aoe.command.TestCommand
|
import com.pobnellion.aoe.command.TestCommand
|
||||||
|
import com.pobnellion.aoe.team.Team
|
||||||
import com.pobnellion.aoe.ui.PlaceHint
|
import com.pobnellion.aoe.ui.PlaceHint
|
||||||
import com.pobnellion.aoe.ui.PlaceItem
|
import com.pobnellion.aoe.ui.PlaceItem
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.plugin.java.JavaPlugin
|
import org.bukkit.plugin.java.JavaPlugin
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class Aoe : JavaPlugin() {
|
class Aoe : JavaPlugin() {
|
||||||
companion object {
|
companion object {
|
||||||
private var instance: Aoe? = null
|
private var instance: Aoe? = null
|
||||||
|
val teams: MutableList<Team> = mutableListOf()
|
||||||
|
|
||||||
|
fun getTeam(player: Player): Team? {
|
||||||
|
return teams.singleOrNull() { team -> team.players.contains(player) }
|
||||||
|
}
|
||||||
|
|
||||||
fun getSchematicsFolder(): File = File(instance!!.dataFolder, "schematics")
|
fun getSchematicsFolder(): File = File(instance!!.dataFolder, "schematics")
|
||||||
}
|
}
|
||||||
@ -18,8 +25,8 @@ class Aoe : JavaPlugin() {
|
|||||||
instance = this
|
instance = this
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
Bukkit.getPluginManager().registerEvents(PlaceHint, this)
|
|
||||||
Bukkit.getPluginManager().registerEvents(PlaceItem(), this)
|
Bukkit.getPluginManager().registerEvents(PlaceItem(), this)
|
||||||
|
Bukkit.getPluginManager().registerEvents(PlaceHint, this)
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
this.getCommand("debug")!!.setExecutor(TestCommand())
|
this.getCommand("debug")!!.setExecutor(TestCommand())
|
||||||
|
|||||||
@ -6,12 +6,8 @@ import org.bukkit.Location
|
|||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class Blacksmith: Building {
|
class Blacksmith(location: Location, variant: Int): Building(location, variant) {
|
||||||
override fun showPlaceHint(player: Player) {
|
fun place(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, offsetY: Int) {
|
||||||
PlaceHint.add(player, "house2", ::place, PlaceHintValidators::allReplaceable)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun place(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float) {
|
|
||||||
for (x in 0..<sizeX.toInt())
|
for (x in 0..<sizeX.toInt())
|
||||||
for (y in 0..<sizeY.toInt())
|
for (y in 0..<sizeY.toInt())
|
||||||
for (z in 0..<sizeZ.toInt())
|
for (z in 0..<sizeZ.toInt())
|
||||||
|
|||||||
@ -3,6 +3,12 @@ package com.pobnellion.aoe.building
|
|||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
interface Building {
|
abstract class Building(val location: Location, val variant: Int) {
|
||||||
fun showPlaceHint(player: Player)
|
}
|
||||||
|
|
||||||
|
interface BuildingInfo {
|
||||||
|
val buildingType: BuildingType
|
||||||
|
val schematicNames: List<String>
|
||||||
|
fun validate(location: Location): Boolean
|
||||||
|
fun create(location: Location, variant: Int): Building
|
||||||
}
|
}
|
||||||
12
src/main/kotlin/com/pobnellion/aoe/building/BuildingType.kt
Normal file
12
src/main/kotlin/com/pobnellion/aoe/building/BuildingType.kt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package com.pobnellion.aoe.building
|
||||||
|
|
||||||
|
enum class BuildingType {
|
||||||
|
BARRACKS,
|
||||||
|
FARM,
|
||||||
|
HOUSE,
|
||||||
|
MILL,
|
||||||
|
TOWN_CENTER,
|
||||||
|
UNIQUE,
|
||||||
|
WALL,
|
||||||
|
WATCH_TOWER,
|
||||||
|
}
|
||||||
@ -1,17 +1,22 @@
|
|||||||
package com.pobnellion.aoe.building
|
package com.pobnellion.aoe.building
|
||||||
|
|
||||||
import com.pobnellion.aoe.ui.PlaceHint
|
|
||||||
import com.pobnellion.aoe.ui.PlaceHintValidators
|
import com.pobnellion.aoe.ui.PlaceHintValidators
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
|
||||||
|
|
||||||
class House: Building {
|
class House(location: Location, variant: Int): Building(location, variant) {
|
||||||
override fun showPlaceHint(player: Player) {
|
companion object Info: BuildingInfo {
|
||||||
PlaceHint.add(player, "house1", ::place, PlaceHintValidators::allReplaceable)
|
override val buildingType: BuildingType = BuildingType.HOUSE
|
||||||
|
override val schematicNames: List<String> = listOf("house1")
|
||||||
|
|
||||||
|
override fun validate(location: Location): Boolean {
|
||||||
|
return PlaceHintValidators.allReplaceable(location, 5f, 5f, 5f, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun create(location: Location, variant: Int): Building = House(location, variant)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun place(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float) {
|
fun place(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, int: Int) {
|
||||||
for (x in 0..<sizeX.toInt())
|
for (x in 0..<sizeX.toInt())
|
||||||
for (y in 0..<sizeY.toInt())
|
for (y in 0..<sizeY.toInt())
|
||||||
for (z in 0..<sizeZ.toInt())
|
for (z in 0..<sizeZ.toInt())
|
||||||
|
|||||||
@ -1,14 +1,13 @@
|
|||||||
package com.pobnellion.aoe.command
|
package com.pobnellion.aoe.command
|
||||||
|
|
||||||
import com.pobnellion.aoe.ui.PlaceHint
|
import com.pobnellion.aoe.entity.AoeVillager
|
||||||
import org.bukkit.Material
|
|
||||||
import org.bukkit.command.Command
|
import org.bukkit.command.Command
|
||||||
import org.bukkit.command.CommandExecutor
|
import org.bukkit.command.CommandExecutor
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class TestCommand : CommandExecutor {
|
class TestCommand : CommandExecutor {
|
||||||
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>?): Boolean {
|
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
|
||||||
if (sender !is Player) {
|
if (sender !is Player) {
|
||||||
sender.sendMessage("Command can only be executed by players")
|
sender.sendMessage("Command can only be executed by players")
|
||||||
return true
|
return true
|
||||||
|
|||||||
21
src/main/kotlin/com/pobnellion/aoe/entity/Villager.kt
Normal file
21
src/main/kotlin/com/pobnellion/aoe/entity/Villager.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package com.pobnellion.aoe.entity
|
||||||
|
|
||||||
|
import com.pobnellion.aoe.building.Building
|
||||||
|
import com.pobnellion.aoe.entity.goals.GoToBuildingGoal
|
||||||
|
import net.minecraft.world.entity.EntityType
|
||||||
|
import net.minecraft.world.entity.npc.Villager
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld
|
||||||
|
|
||||||
|
class AoeVillager(location: Location) : Villager(EntityType.VILLAGER, (location.world as CraftWorld).handle) {
|
||||||
|
init {
|
||||||
|
setPos(location.x, location.y, location.z)
|
||||||
|
level().addFreshEntity(this)
|
||||||
|
|
||||||
|
targetSelector.removeAllGoals { true }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun goToBuilding(building: Building) {
|
||||||
|
targetSelector.addGoal(0, GoToBuildingGoal(this, building, 1.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package com.pobnellion.aoe.entity.goals
|
||||||
|
|
||||||
|
import com.pobnellion.aoe.building.Building
|
||||||
|
import net.minecraft.world.entity.PathfinderMob
|
||||||
|
import net.minecraft.world.entity.ai.goal.Goal
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class GoToBuildingGoal(
|
||||||
|
private val mob: PathfinderMob,
|
||||||
|
private val building: Building,
|
||||||
|
private var speedModifier: Double
|
||||||
|
): Goal() {
|
||||||
|
private var recalculateTicks = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.setFlags(EnumSet.of(Flag.MOVE, Flag.JUMP))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canUse(): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
|
mob.navigation.moveTo(building.location.x, building.location.y, building.location.z, speedModifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
recalculateTicks++
|
||||||
|
|
||||||
|
if (recalculateTicks % 40 == 0)
|
||||||
|
mob.navigation.moveTo(building.location.x, building.location.y, building.location.z, speedModifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun requiresUpdateEveryTick(): Boolean = true
|
||||||
|
}
|
||||||
23
src/main/kotlin/com/pobnellion/aoe/team/Plains.kt
Normal file
23
src/main/kotlin/com/pobnellion/aoe/team/Plains.kt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package com.pobnellion.aoe.team
|
||||||
|
|
||||||
|
import com.pobnellion.aoe.building.BuildingInfo
|
||||||
|
import com.pobnellion.aoe.building.BuildingType
|
||||||
|
import com.pobnellion.aoe.building.House
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class Plains(players: List<Player>) : Team(players) {
|
||||||
|
|
||||||
|
override fun getBuildingInfo(type: BuildingType): BuildingInfo {
|
||||||
|
return when (type) {
|
||||||
|
BuildingType.BARRACKS -> TODO()
|
||||||
|
BuildingType.FARM -> TODO()
|
||||||
|
BuildingType.HOUSE -> House.Info
|
||||||
|
BuildingType.MILL -> TODO()
|
||||||
|
BuildingType.TOWN_CENTER -> TODO()
|
||||||
|
BuildingType.UNIQUE -> TODO()
|
||||||
|
BuildingType.WALL -> TODO()
|
||||||
|
BuildingType.WATCH_TOWER -> TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,7 +1,25 @@
|
|||||||
package com.pobnellion.aoe.team
|
package com.pobnellion.aoe.team
|
||||||
|
|
||||||
import com.pobnellion.aoe.building.Building
|
import com.pobnellion.aoe.building.Building
|
||||||
|
import com.pobnellion.aoe.building.BuildingInfo
|
||||||
|
import com.pobnellion.aoe.building.BuildingType
|
||||||
|
import com.pobnellion.aoe.ui.BuildingPlaceHint
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
class Team {
|
abstract class Team(val players: List<Player>) {
|
||||||
public val Buildings: List<Building> = listOf()
|
val buildings: MutableList<Building> = mutableListOf()
|
||||||
|
|
||||||
|
protected abstract fun getBuildingInfo(type: BuildingType): BuildingInfo
|
||||||
|
|
||||||
|
fun addBuilding(location: Location, building: BuildingInfo, variant: Int) {
|
||||||
|
buildings.add(building.create(location, variant))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showBuildingPlaceHint(type: BuildingType, player: Player) {
|
||||||
|
val info = getBuildingInfo(type)
|
||||||
|
val variant = Random.nextInt(info.schematicNames.size)
|
||||||
|
BuildingPlaceHint.add(player, info, ::addBuilding, variant)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
80
src/main/kotlin/com/pobnellion/aoe/ui/AreaPlaceHint.kt
Normal file
80
src/main/kotlin/com/pobnellion/aoe/ui/AreaPlaceHint.kt
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package com.pobnellion.aoe.ui
|
||||||
|
|
||||||
|
import com.comphenix.protocol.PacketType
|
||||||
|
import com.comphenix.protocol.ProtocolLibrary
|
||||||
|
import com.comphenix.protocol.events.PacketContainer
|
||||||
|
import com.comphenix.protocol.wrappers.BukkitConverters
|
||||||
|
import com.comphenix.protocol.wrappers.Pair
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedBlockData
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedDataValue
|
||||||
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.Material
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.util.Vector
|
||||||
|
import org.joml.Math
|
||||||
|
import org.joml.Vector3f
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
class AreaPlaceHint(
|
||||||
|
override val player: Player,
|
||||||
|
private val sizeX: Float,
|
||||||
|
private val sizeY: Float,
|
||||||
|
private val sizeZ: Float,
|
||||||
|
private val onConfirm: (Location, Float, Float, Float) -> Unit,
|
||||||
|
private val validate: (Location, Float, Float, Float) -> Boolean
|
||||||
|
) : PlaceHint() {
|
||||||
|
companion object {
|
||||||
|
fun add(
|
||||||
|
player: Player,
|
||||||
|
sizeX: Float,
|
||||||
|
sizeY: Float,
|
||||||
|
sizeZ: Float,
|
||||||
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
||||||
|
validate: (Location, Float, Float, Float) -> Boolean,
|
||||||
|
) {
|
||||||
|
remove(player)
|
||||||
|
createOutlineTeam(player)
|
||||||
|
|
||||||
|
playerHints[player.uniqueId] = AreaPlaceHint(player, sizeX, sizeY, sizeZ, onConfirm, validate)
|
||||||
|
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE)
|
||||||
|
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var base: Pair<Int, UUID> = Pair((Math.random() * Int.MAX_VALUE).toInt(), UUID.randomUUID())
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.offset = Vector(sizeX / 2.0, 0.0, sizeZ / 2.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun validate(location: Location) = validate(location, sizeX, sizeY, sizeZ)
|
||||||
|
|
||||||
|
override fun confirm() = onConfirm(currentLocation!!, sizeX, sizeY, sizeZ)
|
||||||
|
|
||||||
|
override fun addDisplays(initialLocation: Location) {
|
||||||
|
base = spawnBlockDisplay(initialLocation, Material.GRAY_STAINED_GLASS.createBlockData(),
|
||||||
|
scale = Vector3f(sizeX + 0.1f, 0.2f, sizeZ + 0.1f), offset = Vector3f(-0.05f, -0.05f, -0.05f))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun updateColour() {
|
||||||
|
super.updateColour()
|
||||||
|
|
||||||
|
// base
|
||||||
|
val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
||||||
|
dataPacket.integers.write(0, base.first)
|
||||||
|
|
||||||
|
val material = if (isValid) Material.LIME_STAINED_GLASS else Material.RED_STAINED_GLASS
|
||||||
|
val blockData = BukkitConverters
|
||||||
|
.getWrappedBlockDataConverter()
|
||||||
|
.getGeneric(WrappedBlockData.createData(material))
|
||||||
|
|
||||||
|
val metadata = listOf(
|
||||||
|
WrappedDataValue(23, Registry.getBlockDataSerializer(false), blockData)
|
||||||
|
)
|
||||||
|
|
||||||
|
dataPacket.dataValueCollectionModifier.write(0, metadata)
|
||||||
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
||||||
|
}
|
||||||
|
}
|
||||||
75
src/main/kotlin/com/pobnellion/aoe/ui/BuildingPlaceHint.kt
Normal file
75
src/main/kotlin/com/pobnellion/aoe/ui/BuildingPlaceHint.kt
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
package com.pobnellion.aoe.ui
|
||||||
|
|
||||||
|
import com.pobnellion.aoe.Aoe
|
||||||
|
import com.pobnellion.aoe.building.BuildingInfo
|
||||||
|
import com.sk89q.worldedit.bukkit.BukkitAdapter
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.Clipboard
|
||||||
|
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats
|
||||||
|
import com.sk89q.worldedit.math.BlockVector3
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.util.Vector
|
||||||
|
import org.joml.Vector3f
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileInputStream
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
|
class BuildingPlaceHint(
|
||||||
|
override val player: Player,
|
||||||
|
private val buildingInfo: BuildingInfo,
|
||||||
|
private val onConfirm: (Location, BuildingInfo, Int) -> Unit,
|
||||||
|
private val buildingVariant: Int = 0
|
||||||
|
) : PlaceHint() {
|
||||||
|
companion object {
|
||||||
|
fun add(
|
||||||
|
player: Player,
|
||||||
|
buildingInfo: BuildingInfo,
|
||||||
|
onConfirm: (Location, BuildingInfo, Int) -> Unit,
|
||||||
|
buildingVariant: Int = 0
|
||||||
|
) {
|
||||||
|
remove(player)
|
||||||
|
createOutlineTeam(player)
|
||||||
|
|
||||||
|
playerHints[player.uniqueId] = BuildingPlaceHint(player, buildingInfo, onConfirm, buildingVariant)
|
||||||
|
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE)
|
||||||
|
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val schematic: Clipboard
|
||||||
|
|
||||||
|
init {
|
||||||
|
val schematicName = buildingInfo.schematicNames[buildingVariant]
|
||||||
|
val file = File(Aoe.getSchematicsFolder(),
|
||||||
|
if (schematicName.endsWith(".schem")) schematicName else "$schematicName.schem")
|
||||||
|
|
||||||
|
val format = ClipboardFormats.findByFile(file)
|
||||||
|
val reader = format?.getReader(FileInputStream(file))
|
||||||
|
val clipboard = reader?.read() ?: throw NullPointerException("Could not load schematic ${file.path}. Is it present?")
|
||||||
|
clipboard.origin = BlockVector3.ZERO
|
||||||
|
this.schematic = clipboard
|
||||||
|
|
||||||
|
this.offset = Vector(
|
||||||
|
-floor(clipboard.dimensions.x() / 2.0),
|
||||||
|
clipboard.minY.toDouble(),
|
||||||
|
-floor(clipboard.dimensions.z() / 2.0))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun validate(location: Location) = buildingInfo.validate(location)
|
||||||
|
|
||||||
|
override fun confirm() = onConfirm(currentLocation!!, buildingInfo, buildingVariant)
|
||||||
|
|
||||||
|
override fun addDisplays(initialLocation: Location) {
|
||||||
|
schematic.iterator().forEach { blockPosition ->
|
||||||
|
val block = BukkitAdapter.adapt(schematic.getBlock(blockPosition))
|
||||||
|
|
||||||
|
if (!block.material.isAir && !block.material.isEmpty) {
|
||||||
|
val x = (blockPosition.x() - schematic.minimumPoint.x()).toFloat()
|
||||||
|
val y = blockPosition.y().toFloat()
|
||||||
|
val z = (blockPosition.z() - schematic.minimumPoint.z()).toFloat()
|
||||||
|
|
||||||
|
displayIds.add(spawnBlockDisplay(initialLocation, block, offset = Vector3f(x, y, z), options = 0b01000000))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,12 +6,7 @@ import com.comphenix.protocol.events.PacketContainer
|
|||||||
import com.comphenix.protocol.wrappers.*
|
import com.comphenix.protocol.wrappers.*
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry
|
||||||
import com.destroystokyo.paper.MaterialSetTag
|
import com.destroystokyo.paper.MaterialSetTag
|
||||||
import com.pobnellion.aoe.Aoe
|
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.Clipboard
|
|
||||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats
|
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.Material
|
|
||||||
import org.bukkit.block.data.BlockData
|
import org.bukkit.block.data.BlockData
|
||||||
import org.bukkit.entity.EntityType
|
import org.bukkit.entity.EntityType
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
@ -20,47 +15,16 @@ import org.bukkit.event.Listener
|
|||||||
import org.bukkit.event.block.Action
|
import org.bukkit.event.block.Action
|
||||||
import org.bukkit.event.player.PlayerInteractEvent
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
import org.bukkit.event.player.PlayerMoveEvent
|
import org.bukkit.event.player.PlayerMoveEvent
|
||||||
|
import org.bukkit.util.Vector
|
||||||
import org.joml.Math
|
import org.joml.Math
|
||||||
import org.joml.Vector3f
|
import org.joml.Vector3f
|
||||||
import java.io.File
|
|
||||||
import java.io.FileInputStream
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.math.floor
|
|
||||||
|
|
||||||
class PlaceHint {
|
abstract class PlaceHint {
|
||||||
companion object : Listener {
|
companion object : Listener {
|
||||||
private const val MAX_TARGET_DISTANCE = 64
|
const val MAX_TARGET_DISTANCE = 64
|
||||||
private val playerHints = HashMap<UUID, PlaceHint>()
|
@JvmStatic
|
||||||
|
protected val playerHints = HashMap<UUID, PlaceHint>()
|
||||||
fun add(
|
|
||||||
player: Player,
|
|
||||||
sizeX: Float,
|
|
||||||
sizeY: Float,
|
|
||||||
sizeZ: Float,
|
|
||||||
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
||||||
validate: (Location, Float, Float, Float) -> Boolean,
|
|
||||||
) {
|
|
||||||
remove(player)
|
|
||||||
createOutlineTeam(player)
|
|
||||||
|
|
||||||
playerHints[player.uniqueId] = PlaceHint(player, sizeX, sizeY, sizeZ, onConfirm, validate)
|
|
||||||
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE)
|
|
||||||
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun add(
|
|
||||||
player: Player,
|
|
||||||
schematicName: String,
|
|
||||||
onConfirm: (Location, Float, Float, Float) -> Unit,
|
|
||||||
validate: (Location, Float, Float, Float) -> Boolean,
|
|
||||||
) {
|
|
||||||
remove(player)
|
|
||||||
createOutlineTeam(player)
|
|
||||||
|
|
||||||
playerHints[player.uniqueId] = PlaceHint(player, schematicName, onConfirm, validate)
|
|
||||||
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE)
|
|
||||||
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun remove(player: Player) {
|
fun remove(player: Player) {
|
||||||
if (!playerHints.containsKey(player.uniqueId))
|
if (!playerHints.containsKey(player.uniqueId))
|
||||||
@ -79,7 +43,8 @@ class PlaceHint {
|
|||||||
return playerHints.containsKey(player.uniqueId)
|
return playerHints.containsKey(player.uniqueId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createOutlineTeam(player: Player) {
|
@JvmStatic
|
||||||
|
protected fun createOutlineTeam(player: Player) {
|
||||||
val packet = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
val packet = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
||||||
packet.strings.write(0, "placeValid")
|
packet.strings.write(0, "placeValid")
|
||||||
packet.integers.write(0, 0)
|
packet.integers.write(0, 0)
|
||||||
@ -105,13 +70,12 @@ class PlaceHint {
|
|||||||
|
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
|
|
||||||
// left click - place
|
// left click - confirm
|
||||||
if (event.action == Action.LEFT_CLICK_BLOCK || event.action == Action.LEFT_CLICK_AIR) {
|
if (event.action == Action.LEFT_CLICK_BLOCK || event.action == Action.LEFT_CLICK_AIR) {
|
||||||
if (!playerHints[event.player.uniqueId]!!.isValid)
|
if (!playerHints[event.player.uniqueId]!!.isValid)
|
||||||
return
|
return
|
||||||
|
|
||||||
val marker = playerHints[event.player.uniqueId]!!
|
playerHints[event.player.uniqueId]!!.confirm()
|
||||||
marker.onConfirm(marker.currentLocation!!, marker.sizeX, marker.sizeY, marker.sizeZ)
|
|
||||||
remove(event.player)
|
remove(event.player)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,53 +96,19 @@ class PlaceHint {
|
|||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val player: Player
|
protected abstract val player: Player
|
||||||
private val sizeX: Float
|
protected lateinit var offset: Vector
|
||||||
private val sizeY: Float
|
|
||||||
private val sizeZ: Float
|
|
||||||
val onConfirm: (Location, Float, Float, Float) -> Unit
|
|
||||||
val validate: (Location, Float, Float, Float) -> Boolean
|
|
||||||
private val schematic: Clipboard?
|
|
||||||
private var marker: Pair<Int, UUID> = Pair((Math.random() * Int.MAX_VALUE).toInt(), UUID.randomUUID())
|
private var marker: Pair<Int, UUID> = Pair((Math.random() * Int.MAX_VALUE).toInt(), UUID.randomUUID())
|
||||||
private var base: Pair<Int, UUID> = Pair((Math.random() * Int.MAX_VALUE).toInt(), UUID.randomUUID())
|
protected val displayIds: MutableList<Pair<Int, UUID>> = mutableListOf()
|
||||||
private val displayIds: MutableList<Pair<Int, UUID>> = mutableListOf()
|
|
||||||
var currentLocation: Location? = null
|
var currentLocation: Location? = null
|
||||||
var isValid = false
|
var isValid = false
|
||||||
|
|
||||||
constructor(player: Player, sizeX: Float, sizeY: Float, sizeZ: Float,
|
protected abstract fun addDisplays(initialLocation: Location)
|
||||||
onConfirm: (Location, Float, Float, Float) -> Unit,
|
protected abstract fun confirm()
|
||||||
validate: (Location, Float, Float, Float) -> Boolean) {
|
protected abstract fun validate(location: Location): Boolean
|
||||||
this.player = player
|
|
||||||
this.sizeX = sizeX
|
|
||||||
this.sizeY = sizeY
|
|
||||||
this.sizeZ = sizeZ
|
|
||||||
this.onConfirm = onConfirm
|
|
||||||
this.validate = validate
|
|
||||||
this.schematic = null
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(player: Player, schematicName: String,
|
protected fun show(initialLocation: Location) {
|
||||||
onConfirm: (Location, Float, Float, Float) -> Unit,
|
initialLocation.add(this.offset)
|
||||||
validate: (Location, Float, Float, Float) -> Boolean) {
|
|
||||||
this.player = player
|
|
||||||
this.onConfirm = onConfirm
|
|
||||||
this.validate = validate
|
|
||||||
|
|
||||||
val file = File(Aoe.getSchematicsFolder(),
|
|
||||||
if (schematicName.endsWith(".schem")) schematicName else "$schematicName.schem")
|
|
||||||
|
|
||||||
val format = ClipboardFormats.findByFile(file)
|
|
||||||
val reader = format?.getReader(FileInputStream(file))
|
|
||||||
val clipboard = reader?.read() ?: throw NullPointerException("Could not load schematic ${file.path}. Is it present?")
|
|
||||||
|
|
||||||
this.schematic = clipboard
|
|
||||||
this.sizeX = clipboard.dimensions.x().toFloat()
|
|
||||||
this.sizeY = clipboard.dimensions.y().toFloat()
|
|
||||||
this.sizeZ = clipboard.dimensions.z().toFloat()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun show(initialLocation: Location) {
|
|
||||||
initialLocation.add(-floor(sizeX / 2.0), 1.0, -floor(sizeZ / 2.0))
|
|
||||||
currentLocation = initialLocation
|
currentLocation = initialLocation
|
||||||
|
|
||||||
val spawnMarkerPacket = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY)
|
val spawnMarkerPacket = PacketContainer(PacketType.Play.Server.SPAWN_ENTITY)
|
||||||
@ -190,20 +120,7 @@ class PlaceHint {
|
|||||||
.write(1, initialLocation.y)
|
.write(1, initialLocation.y)
|
||||||
.write(2, initialLocation.z)
|
.write(2, initialLocation.z)
|
||||||
|
|
||||||
base = spawnBlockDisplay(initialLocation, Material.GRAY_STAINED_GLASS.createBlockData(),
|
addDisplays(initialLocation)
|
||||||
scale = Vector3f(sizeX + 0.1f, 0.2f, sizeZ + 0.1f), offset = Vector3f(-0.05f, -0.05f, -0.05f))
|
|
||||||
|
|
||||||
schematic?.iterator()?.forEach { blockPosition ->
|
|
||||||
val block = BukkitAdapter.adapt(schematic.getBlock(blockPosition))
|
|
||||||
|
|
||||||
if (!block.material.isAir && !block.material.isEmpty) {
|
|
||||||
val x = (blockPosition.x() - schematic.minimumPoint.x()).toFloat()
|
|
||||||
val y = (blockPosition.y() - schematic.minimumPoint.y()).toFloat()
|
|
||||||
val z = (blockPosition.z() - schematic.minimumPoint.z()).toFloat()
|
|
||||||
|
|
||||||
displayIds.add(spawnBlockDisplay(initialLocation, block, offset = Vector3f(x, y, z), options = 0b01000000))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
||||||
outlineTeamPacket.strings.write(0, "placeValid")
|
outlineTeamPacket.strings.write(0, "placeValid")
|
||||||
@ -211,7 +128,6 @@ class PlaceHint {
|
|||||||
outlineTeamPacket.getSpecificModifier(Collection::class.java).write(0, displayIds.map { it.second.toString() })
|
outlineTeamPacket.getSpecificModifier(Collection::class.java).write(0, displayIds.map { it.second.toString() })
|
||||||
|
|
||||||
val ids = displayIds.map { it.first }.toMutableList()
|
val ids = displayIds.map { it.first }.toMutableList()
|
||||||
ids.add(base.first)
|
|
||||||
|
|
||||||
val passengerPacket = PacketContainer(PacketType.Play.Server.MOUNT)
|
val passengerPacket = PacketContainer(PacketType.Play.Server.MOUNT)
|
||||||
passengerPacket.integers.write(0, marker.first)
|
passengerPacket.integers.write(0, marker.first)
|
||||||
@ -221,7 +137,7 @@ class PlaceHint {
|
|||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, outlineTeamPacket)
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, outlineTeamPacket)
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, passengerPacket)
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, passengerPacket)
|
||||||
|
|
||||||
isValid = validate(initialLocation, sizeX, sizeY, sizeZ)
|
isValid = validate(initialLocation)
|
||||||
updateColour()
|
updateColour()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +145,6 @@ class PlaceHint {
|
|||||||
val packet = PacketContainer(PacketType.Play.Server.ENTITY_DESTROY)
|
val packet = PacketContainer(PacketType.Play.Server.ENTITY_DESTROY)
|
||||||
val ids = displayIds.map { it.first }.toMutableList()
|
val ids = displayIds.map { it.first }.toMutableList()
|
||||||
ids.add(marker.first)
|
ids.add(marker.first)
|
||||||
ids.add(base.first)
|
|
||||||
packet.intLists.write(0, ids)
|
packet.intLists.write(0, ids)
|
||||||
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet)
|
||||||
@ -245,11 +160,11 @@ class PlaceHint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (currentLocation == null) {
|
if (currentLocation == null) {
|
||||||
show(newLocation)
|
addDisplays(newLocation)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newLocation.add(-floor(sizeX / 2.0), 1.0, -floor(sizeZ / 2.0))
|
newLocation.add(this.offset)
|
||||||
|
|
||||||
val basePacket = PacketContainer(PacketType.Play.Server.ENTITY_POSITION_SYNC)
|
val basePacket = PacketContainer(PacketType.Play.Server.ENTITY_POSITION_SYNC)
|
||||||
basePacket.integers.write(0, marker.first)
|
basePacket.integers.write(0, marker.first)
|
||||||
@ -266,7 +181,7 @@ class PlaceHint {
|
|||||||
currentLocation = newLocation
|
currentLocation = newLocation
|
||||||
|
|
||||||
// Update material
|
// Update material
|
||||||
val valid = validate(newLocation, sizeX, sizeY, sizeZ)
|
val valid = validate(newLocation)
|
||||||
|
|
||||||
if (valid != isValid) {
|
if (valid != isValid) {
|
||||||
isValid = valid
|
isValid = valid
|
||||||
@ -276,7 +191,7 @@ class PlaceHint {
|
|||||||
|
|
||||||
// region helper functions
|
// region helper functions
|
||||||
|
|
||||||
private fun spawnBlockDisplay(
|
protected fun spawnBlockDisplay(
|
||||||
location: Location,
|
location: Location,
|
||||||
block: BlockData,
|
block: BlockData,
|
||||||
scale: Vector3f = Vector3f(1f, 1f, 1f),
|
scale: Vector3f = Vector3f(1f, 1f, 1f),
|
||||||
@ -318,23 +233,7 @@ class PlaceHint {
|
|||||||
return Pair<Int, UUID>(id, uuid)
|
return Pair<Int, UUID>(id, uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateColour() {
|
protected open fun updateColour() {
|
||||||
// base
|
|
||||||
val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
|
||||||
dataPacket.integers.write(0, base.first)
|
|
||||||
|
|
||||||
val material = if (isValid) Material.LIME_STAINED_GLASS else Material.RED_STAINED_GLASS
|
|
||||||
val blockData = BukkitConverters
|
|
||||||
.getWrappedBlockDataConverter()
|
|
||||||
.getGeneric(WrappedBlockData.createData(material))
|
|
||||||
|
|
||||||
val metadata = listOf(
|
|
||||||
WrappedDataValue(23, Registry.getBlockDataSerializer(false), blockData)
|
|
||||||
)
|
|
||||||
|
|
||||||
dataPacket.dataValueCollectionModifier.write(0, metadata)
|
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
|
||||||
|
|
||||||
// outline
|
// outline
|
||||||
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
val outlineTeamPacket = PacketContainer(PacketType.Play.Server.SCOREBOARD_TEAM)
|
||||||
outlineTeamPacket.strings.write(0, "placeValid")
|
outlineTeamPacket.strings.write(0, "placeValid")
|
||||||
|
|||||||
@ -5,13 +5,13 @@ import org.bukkit.Location
|
|||||||
class PlaceHintValidators {
|
class PlaceHintValidators {
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun alwaysTrue(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float): Boolean {
|
fun alwaysTrue(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, offsetY: Int): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allAir(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float): Boolean {
|
fun allAir(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, offsetY: Int): Boolean {
|
||||||
for (x in 0..<sizeX.toInt())
|
for (x in 0..<sizeX.toInt())
|
||||||
for (y in 0..<sizeY.toInt())
|
for (y in -offsetY..<sizeY.toInt())
|
||||||
for (z in 0..<sizeZ.toInt())
|
for (z in 0..<sizeZ.toInt())
|
||||||
if (!location.world.getBlockAt(
|
if (!location.world.getBlockAt(
|
||||||
location.blockX + x,
|
location.blockX + x,
|
||||||
@ -22,9 +22,9 @@ class PlaceHintValidators {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun allReplaceable(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float): Boolean {
|
fun allReplaceable(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, offsetY: Int): Boolean {
|
||||||
for (x in 0..<sizeX.toInt())
|
for (x in 0..<sizeX.toInt())
|
||||||
for (y in 0..<sizeY.toInt())
|
for (y in -offsetY..<sizeY.toInt())
|
||||||
for (z in 0..<sizeZ.toInt())
|
for (z in 0..<sizeZ.toInt())
|
||||||
if (!location.world.getBlockAt(
|
if (!location.world.getBlockAt(
|
||||||
location.blockX + x,
|
location.blockX + x,
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package com.pobnellion.aoe.ui
|
package com.pobnellion.aoe.ui
|
||||||
|
|
||||||
import com.pobnellion.aoe.building.Blacksmith
|
import com.pobnellion.aoe.Aoe
|
||||||
import com.pobnellion.aoe.building.House
|
import com.pobnellion.aoe.building.BuildingType
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
@ -14,22 +14,26 @@ import org.bukkit.event.inventory.InventoryCloseEvent
|
|||||||
import org.bukkit.event.inventory.InventoryDragEvent
|
import org.bukkit.event.inventory.InventoryDragEvent
|
||||||
import org.bukkit.event.player.PlayerInteractEvent
|
import org.bukkit.event.player.PlayerInteractEvent
|
||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
class PlaceItem : Listener {
|
class PlaceItem : Listener {
|
||||||
private val buildingInventory = Bukkit.createInventory(null, 9, Component.text("Buildings"))
|
private val buildingInventory = Bukkit.createInventory(null, 9, Component.text("Buildings"))
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
buildingInventory.addItem(createGuiItem(Material.BELL, "Town center", "middle of the town :D"))
|
||||||
buildingInventory.addItem(createGuiItem(Material.OAK_LOG, "House", "Just a house bro"))
|
buildingInventory.addItem(createGuiItem(Material.OAK_LOG, "House", "Just a house bro"))
|
||||||
buildingInventory.addItem(createGuiItem(Material.ANVIL, "Blacksmith", "smith ."))
|
buildingInventory.addItem(createGuiItem(Material.EMERALD, "Villager", "willager"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onRightClickItem(event: PlayerInteractEvent) {
|
fun onRightClickItem(event: PlayerInteractEvent) {
|
||||||
if (event.material != Material.BRICKS
|
if (event.action != Action.RIGHT_CLICK_AIR && event.action != Action.RIGHT_CLICK_BLOCK)
|
||||||
|| (event.action != Action.RIGHT_CLICK_AIR && event.action != Action.RIGHT_CLICK_BLOCK)
|
return
|
||||||
|| PlaceHint.contains(event.player))
|
|
||||||
|
if (PlaceHint.contains(event.player))
|
||||||
|
return
|
||||||
|
|
||||||
|
if (event.material != Material.BRICKS)
|
||||||
return
|
return
|
||||||
|
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
@ -38,6 +42,9 @@ class PlaceItem : Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onInventoryClick(event: InventoryClickEvent) {
|
fun onInventoryClick(event: InventoryClickEvent) {
|
||||||
|
val player = event.whoClicked as Player
|
||||||
|
val team = Aoe.getTeam(player) ?: return
|
||||||
|
|
||||||
if (event.inventory != buildingInventory)
|
if (event.inventory != buildingInventory)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -45,8 +52,9 @@ class PlaceItem : Listener {
|
|||||||
var validClick = true
|
var validClick = true
|
||||||
|
|
||||||
when (event.currentItem?.type) {
|
when (event.currentItem?.type) {
|
||||||
Material.OAK_LOG -> House().showPlaceHint(event.whoClicked as Player)
|
Material.OAK_LOG -> team.showBuildingPlaceHint(BuildingType.HOUSE, player)
|
||||||
Material.ANVIL -> Blacksmith().showPlaceHint(event.whoClicked as Player)
|
Material.BELL -> team.showBuildingPlaceHint(BuildingType.TOWN_CENTER, player)
|
||||||
|
Material.EMERALD -> {}
|
||||||
else -> validClick = false
|
else -> validClick = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user