moving things around and inventory stuff
This commit is contained in:
@ -6,8 +6,9 @@ import com.pobnellion.aoe.civilisation.Civilisation
|
|||||||
import com.pobnellion.aoe.civilisation.CivilisationType
|
import com.pobnellion.aoe.civilisation.CivilisationType
|
||||||
import com.pobnellion.aoe.map.AoeMap
|
import com.pobnellion.aoe.map.AoeMap
|
||||||
import com.pobnellion.aoe.ui.PlaceHint
|
import com.pobnellion.aoe.ui.PlaceHint
|
||||||
import com.pobnellion.aoe.ui.PlaceItem
|
import com.pobnellion.aoe.ui.InventoryManager
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.GameMode
|
||||||
import org.bukkit.entity.Player
|
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
|
||||||
@ -19,6 +20,10 @@ class Aoe : JavaPlugin() {
|
|||||||
private var instance: Aoe? = null
|
private var instance: Aoe? = null
|
||||||
val civilisations: MutableMap<CivilisationType, Civilisation> = mutableMapOf()
|
val civilisations: MutableMap<CivilisationType, Civilisation> = mutableMapOf()
|
||||||
val map: AoeMap = AoeMap()
|
val map: AoeMap = AoeMap()
|
||||||
|
val players: MutableMap<Player, CivilisationType> = mutableMapOf()
|
||||||
|
val inventoryManager: InventoryManager = InventoryManager()
|
||||||
|
|
||||||
|
fun isPlaying(player: Player) = players.containsKey(player)
|
||||||
|
|
||||||
fun getTeam(player: Player): Civilisation? {
|
fun getTeam(player: Player): Civilisation? {
|
||||||
return civilisations.values.singleOrNull { team -> team.players.contains(player) }
|
return civilisations.values.singleOrNull { team -> team.players.contains(player) }
|
||||||
@ -28,8 +33,18 @@ class Aoe : JavaPlugin() {
|
|||||||
Paths.get(instance!!.dataFolder.path, "schematics", "$schematicName.schem").toFile()
|
Paths.get(instance!!.dataFolder.path, "schematics", "$schematicName.schem").toFile()
|
||||||
|
|
||||||
fun startGame() {
|
fun startGame() {
|
||||||
if (!gameInProgress)
|
if (gameInProgress)
|
||||||
civilisations.values.forEach { civ -> civ.initSetup() }
|
return
|
||||||
|
|
||||||
|
for (player in Bukkit.getOnlinePlayers()) {
|
||||||
|
if (isPlaying(player))
|
||||||
|
player.gameMode = GameMode.CREATIVE
|
||||||
|
else
|
||||||
|
player.gameMode = GameMode.SPECTATOR
|
||||||
|
}
|
||||||
|
|
||||||
|
civilisations.values.forEach { civ -> civ.initSetup() }
|
||||||
|
inventoryManager.initHotbars()
|
||||||
|
|
||||||
gameInProgress = true
|
gameInProgress = true
|
||||||
}
|
}
|
||||||
@ -39,7 +54,7 @@ class Aoe : JavaPlugin() {
|
|||||||
instance = this
|
instance = this
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
Bukkit.getPluginManager().registerEvents(PlaceItem(), this)
|
Bukkit.getPluginManager().registerEvents(InventoryManager(), this)
|
||||||
Bukkit.getPluginManager().registerEvents(PlaceHint, this)
|
Bukkit.getPluginManager().registerEvents(PlaceHint, this)
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
|
|||||||
8
src/main/kotlin/com/pobnellion/aoe/Extensions.kt
Normal file
8
src/main/kotlin/com/pobnellion/aoe/Extensions.kt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package com.pobnellion.aoe
|
||||||
|
|
||||||
|
import com.pobnellion.aoe.civilisation.Civilisation
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
fun Player.getCivilisation(): Civilisation? {
|
||||||
|
return Aoe.civilisations[Aoe.players[this]]
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ import com.sk89q.worldedit.function.operation.Operations
|
|||||||
import com.sk89q.worldedit.math.BlockVector3
|
import com.sk89q.worldedit.math.BlockVector3
|
||||||
import com.sk89q.worldedit.session.ClipboardHolder
|
import com.sk89q.worldedit.session.ClipboardHolder
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.util.Vector
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
|
|
||||||
@ -22,19 +23,26 @@ abstract class Building(val location: Location, val variant: Int): EntityWorkTar
|
|||||||
override fun removeProgress(amount: Float) {}
|
override fun removeProgress(amount: Float) {}
|
||||||
override fun onComplete() {}
|
override fun onComplete() {}
|
||||||
|
|
||||||
|
var sizeX: Int
|
||||||
|
var sizeZ: Int
|
||||||
|
fun center(): Location = location.clone().add(sizeX / 2.0, 0.0, sizeZ / 2.0)
|
||||||
|
private val clipboard: Clipboard
|
||||||
abstract var populationCapacity: Int
|
abstract var populationCapacity: Int
|
||||||
abstract fun getSchematicName(variant: Int): String
|
abstract fun getSchematicName(variant: Int): String
|
||||||
|
|
||||||
fun placeFull() {
|
init {
|
||||||
currentProgressPercent = 1f
|
val file: File = Aoe.getSchematicFile(this.getSchematicName(variant))
|
||||||
var clipboard: Clipboard
|
|
||||||
|
|
||||||
val file: File = Aoe.getSchematicFile(getSchematicName(variant))
|
|
||||||
val format = ClipboardFormats.findByFile(file)
|
val format = ClipboardFormats.findByFile(file)
|
||||||
format!!.getReader(FileInputStream(file)).use { reader ->
|
format!!.getReader(FileInputStream(file)).use { reader ->
|
||||||
clipboard = reader.read()
|
clipboard = reader.read()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sizeX = clipboard.maximumPoint.x() - clipboard.minimumPoint.x()
|
||||||
|
sizeZ = clipboard.maximumPoint.z() - clipboard.minimumPoint.z()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun placeFull() {
|
||||||
|
currentProgressPercent = 1f
|
||||||
val offset = clipboard.region.minimumPoint.subtract(clipboard.origin)
|
val offset = clipboard.region.minimumPoint.subtract(clipboard.origin)
|
||||||
|
|
||||||
WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(location.world)).use { editSession ->
|
WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(location.world)).use { editSession ->
|
||||||
@ -50,6 +58,7 @@ abstract class Building(val location: Location, val variant: Int): EntityWorkTar
|
|||||||
interface BuildingInfo {
|
interface BuildingInfo {
|
||||||
val buildingType: BuildingType
|
val buildingType: BuildingType
|
||||||
val schematicNames: List<String>
|
val schematicNames: List<String>
|
||||||
|
fun getSize(variant: Int): Vector
|
||||||
fun validate(location: Location): Boolean
|
fun validate(location: Location): Boolean
|
||||||
fun create(location: Location, variant: Int): Building
|
fun create(location: Location, variant: Int): Building
|
||||||
}
|
}
|
||||||
@ -1,13 +1,17 @@
|
|||||||
package com.pobnellion.aoe.civilisation
|
package com.pobnellion.aoe.civilisation
|
||||||
|
|
||||||
|
import com.pobnellion.aoe.Aoe
|
||||||
import com.pobnellion.aoe.Constants
|
import com.pobnellion.aoe.Constants
|
||||||
import com.pobnellion.aoe.building.Building
|
import com.pobnellion.aoe.building.Building
|
||||||
import com.pobnellion.aoe.building.BuildingInfo
|
import com.pobnellion.aoe.building.BuildingInfo
|
||||||
import com.pobnellion.aoe.building.BuildingType
|
import com.pobnellion.aoe.building.BuildingType
|
||||||
import com.pobnellion.aoe.building.TownCenter
|
import com.pobnellion.aoe.building.TownCenter
|
||||||
import com.pobnellion.aoe.entity.AoeVillager
|
import com.pobnellion.aoe.entity.AoeVillager
|
||||||
|
import com.pobnellion.aoe.ui.AoeInventory
|
||||||
import com.pobnellion.aoe.ui.BuildingPlaceHint
|
import com.pobnellion.aoe.ui.BuildingPlaceHint
|
||||||
|
import net.minecraft.world.phys.AABB
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.craftbukkit.CraftWorld
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -17,15 +21,17 @@ abstract class Civilisation(
|
|||||||
) {
|
) {
|
||||||
private val buildings: MutableList<Building> = mutableListOf()
|
private val buildings: MutableList<Building> = mutableListOf()
|
||||||
private val villagers: MutableList<AoeVillager> = mutableListOf()
|
private val villagers: MutableList<AoeVillager> = mutableListOf()
|
||||||
val players: MutableList<Player> = mutableListOf()
|
|
||||||
|
|
||||||
fun addPlayer(player: Player) {
|
val players get() = Aoe.players.filter { player -> player.value == this.type }.keys
|
||||||
players.add(player)
|
val buildingInventory = AoeInventory("Buildings", BuildingType.entries.size)
|
||||||
player.sendMessage("Joined team ${name()}")
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract fun getBuildingInfo(type: BuildingType): BuildingInfo
|
protected abstract fun getBuildingInfo(type: BuildingType): BuildingInfo
|
||||||
protected abstract fun name(): String
|
protected abstract val name: String
|
||||||
|
protected abstract val type: CivilisationType
|
||||||
|
|
||||||
|
init {
|
||||||
|
buildingInventory.addItem()
|
||||||
|
}
|
||||||
|
|
||||||
fun addBuilding(location: Location, buildingInfo: BuildingInfo, variant: Int): Building {
|
fun addBuilding(location: Location, buildingInfo: BuildingInfo, variant: Int): Building {
|
||||||
val building = buildingInfo.create(location, variant)
|
val building = buildingInfo.create(location, variant)
|
||||||
@ -47,9 +53,31 @@ abstract class Civilisation(
|
|||||||
townCenter.placeFull()
|
townCenter.placeFull()
|
||||||
|
|
||||||
// Spawn initial villagers
|
// Spawn initial villagers
|
||||||
for (i in 0..Constants.STARTING_VILLAGER_COUNT)
|
for (i in 0..< Constants.STARTING_VILLAGER_COUNT) {
|
||||||
villagers.add(AoeVillager(townCenter.villagerSpawnLocation))
|
val villager = AoeVillager(townCenter.villagerSpawnLocation, type)
|
||||||
|
villager.leaveBuilding(townCenter)
|
||||||
|
villagers.add(villager)
|
||||||
|
}
|
||||||
|
|
||||||
|
// tp players above town center
|
||||||
|
for (player in players) {
|
||||||
|
player.teleport(townCenter.location
|
||||||
|
.clone()
|
||||||
|
.add(townCenterInfo.getSize(variant).x / 2, 0.0, townCenterInfo.getSize(variant).z / 2)
|
||||||
|
.toHighestLocation()
|
||||||
|
.add(0.0, 10.0, 0.0))
|
||||||
|
|
||||||
|
player.isFlying = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun populationCap() = min(Constants.MAX_POP_CAP, buildings.sumOf { building -> building.populationCapacity })
|
fun populationCap() = min(Constants.MAX_POP_CAP, buildings.sumOf { building -> building.populationCapacity })
|
||||||
|
|
||||||
|
fun selectVillagers(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float) {
|
||||||
|
(location.world as CraftWorld).handle.getEntitiesOfClass(
|
||||||
|
AoeVillager::class.java,
|
||||||
|
AABB(location.x, location.y, location.z, location.x + sizeX, location.y + sizeY, location.z + sizeZ)
|
||||||
|
)
|
||||||
|
{ villager -> villager.civilisationType == type }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -7,7 +7,8 @@ import com.pobnellion.aoe.building.plains.PlainsTownCenter
|
|||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
|
|
||||||
class Plains(setupLocation: Location) : Civilisation(setupLocation) {
|
class Plains(setupLocation: Location) : Civilisation(setupLocation) {
|
||||||
override fun name(): String = "Plains"
|
override val name: String = "Plains"
|
||||||
|
override val type: CivilisationType = CivilisationType.PLAINS
|
||||||
|
|
||||||
override fun getBuildingInfo(type: BuildingType): BuildingInfo {
|
override fun getBuildingInfo(type: BuildingType): BuildingInfo {
|
||||||
return when (type) {
|
return when (type) {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ class TestCommand : CommandExecutor {
|
|||||||
CivilisationType.PLAINS -> Aoe.civilisations[CivilisationType.PLAINS] = Plains(Aoe.map.getStartingLocations()[0])
|
CivilisationType.PLAINS -> Aoe.civilisations[CivilisationType.PLAINS] = Plains(Aoe.map.getStartingLocations()[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
Aoe.civilisations[civilisationType]!!.addPlayer(player)
|
Aoe.players[player] = civilisationType
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,16 @@
|
|||||||
package com.pobnellion.aoe.entity
|
package com.pobnellion.aoe.entity
|
||||||
|
|
||||||
import com.pobnellion.aoe.building.Building
|
import com.pobnellion.aoe.building.Building
|
||||||
|
import com.pobnellion.aoe.civilisation.CivilisationType
|
||||||
import com.pobnellion.aoe.entity.goals.GoToBuildingGoal
|
import com.pobnellion.aoe.entity.goals.GoToBuildingGoal
|
||||||
|
import com.pobnellion.aoe.entity.goals.LeaveBuildingGoal
|
||||||
import net.minecraft.world.entity.EntityType
|
import net.minecraft.world.entity.EntityType
|
||||||
import net.minecraft.world.entity.npc.Villager
|
import net.minecraft.world.entity.npc.Villager
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.craftbukkit.CraftWorld
|
import org.bukkit.craftbukkit.CraftWorld
|
||||||
|
|
||||||
class AoeVillager(location: Location) : Villager(EntityType.VILLAGER, (location.world as CraftWorld).handle) {
|
class AoeVillager(location: Location, var civilisationType: CivilisationType)
|
||||||
|
: Villager(EntityType.VILLAGER, (location.world as CraftWorld).handle) {
|
||||||
init {
|
init {
|
||||||
setPos(location.x, location.y, location.z)
|
setPos(location.x, location.y, location.z)
|
||||||
level().addFreshEntity(this)
|
level().addFreshEntity(this)
|
||||||
@ -15,6 +18,10 @@ class AoeVillager(location: Location) : Villager(EntityType.VILLAGER, (location.
|
|||||||
targetSelector.removeAllGoals { true }
|
targetSelector.removeAllGoals { true }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun leaveBuilding(building: Building) {
|
||||||
|
targetSelector.addGoal(0, LeaveBuildingGoal(this, building, 1.0))
|
||||||
|
}
|
||||||
|
|
||||||
fun goToBuilding(building: Building) {
|
fun goToBuilding(building: Building) {
|
||||||
targetSelector.addGoal(0, GoToBuildingGoal(this, building, 1.0))
|
targetSelector.addGoal(0, GoToBuildingGoal(this, building, 1.0))
|
||||||
}
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
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 net.minecraft.world.entity.ai.util.DefaultRandomPos
|
||||||
|
import net.minecraft.world.level.pathfinder.Path
|
||||||
|
import net.minecraft.world.phys.Vec3
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
|
class LeaveBuildingGoal(
|
||||||
|
private val mob: PathfinderMob,
|
||||||
|
private val building: Building,
|
||||||
|
private var speedModifier: Double
|
||||||
|
): Goal() {
|
||||||
|
private var path: Path? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
this.setFlags(EnumSet.of(Flag.MOVE))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canUse(): Boolean {
|
||||||
|
val buildingCornerDistance = sqrt((building.sizeX.toFloat().pow(2) + building.sizeZ.toFloat().pow(2)))
|
||||||
|
val buildingCenter = building.center()
|
||||||
|
val fromPosition = Vec3(buildingCenter.x, buildingCenter.y, buildingCenter.z)
|
||||||
|
val posAway = DefaultRandomPos.getPosAway(mob, (buildingCornerDistance / 2).toInt(), 2, fromPosition)
|
||||||
|
|
||||||
|
if (posAway == null)
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (fromPosition.distanceToSqr(posAway.x, posAway.y, posAway.z) < fromPosition.distanceToSqr(mob.position()))
|
||||||
|
return false
|
||||||
|
|
||||||
|
path = mob.navigation.createPath(posAway.x, posAway.y, posAway.z, 0)
|
||||||
|
return path != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun start() {
|
||||||
|
mob.navigation.moveTo(path, speedModifier)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tick() {
|
||||||
|
if (!canContinueToUse())
|
||||||
|
mob.targetSelector.removeGoal(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun canContinueToUse(): Boolean {
|
||||||
|
return !mob.navigation.isDone
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/main/kotlin/com/pobnellion/aoe/ui/AoeInventory.kt
Normal file
13
src/main/kotlin/com/pobnellion/aoe/ui/AoeInventory.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.pobnellion.aoe.ui
|
||||||
|
|
||||||
|
import net.kyori.adventure.text.Component
|
||||||
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.inventory.Inventory
|
||||||
|
|
||||||
|
class AoeInventory(name: String, size: Int) {
|
||||||
|
val inventory: Inventory = Bukkit.createInventory(null, size + size % 9, Component.text(name))
|
||||||
|
|
||||||
|
fun addItem() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,13 +1,6 @@
|
|||||||
package com.pobnellion.aoe.ui
|
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.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.Location
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
@ -22,7 +15,7 @@ class AreaPlaceHint(
|
|||||||
private val sizeY: Float,
|
private val sizeY: Float,
|
||||||
private val sizeZ: Float,
|
private val sizeZ: Float,
|
||||||
private val onConfirm: (Location, Float, Float, Float) -> Unit,
|
private val onConfirm: (Location, Float, Float, Float) -> Unit,
|
||||||
private val validate: (Location, Float, Float, Float) -> Boolean
|
private val onTick: (Location, Float, Float, Float) -> Unit,
|
||||||
) : PlaceHint() {
|
) : PlaceHint() {
|
||||||
companion object {
|
companion object {
|
||||||
fun add(
|
fun add(
|
||||||
@ -31,12 +24,12 @@ class AreaPlaceHint(
|
|||||||
sizeY: Float,
|
sizeY: Float,
|
||||||
sizeZ: Float,
|
sizeZ: Float,
|
||||||
onConfirm: (Location, Float, Float, Float) -> Unit,
|
onConfirm: (Location, Float, Float, Float) -> Unit,
|
||||||
validate: (Location, Float, Float, Float) -> Boolean,
|
onTick: (Location, Float, Float, Float) -> Unit,
|
||||||
) {
|
) {
|
||||||
remove(player)
|
remove(player)
|
||||||
createOutlineTeam(player)
|
createOutlineTeam(player)
|
||||||
|
|
||||||
playerHints[player.uniqueId] = AreaPlaceHint(player, sizeX, sizeY, sizeZ, onConfirm, validate)
|
playerHints[player.uniqueId] = AreaPlaceHint(player, sizeX, sizeY, sizeZ, onConfirm, onTick)
|
||||||
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE)
|
val block = player.getTargetBlockExact(MAX_TARGET_DISTANCE)
|
||||||
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
playerHints[player.uniqueId]!!.moveTo(block?.location)
|
||||||
}
|
}
|
||||||
@ -48,9 +41,14 @@ class AreaPlaceHint(
|
|||||||
this.offset = Vector(sizeX / 2.0, 0.0, sizeZ / 2.0)
|
this.offset = Vector(sizeX / 2.0, 0.0, sizeZ / 2.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun validate(location: Location) = validate(location, sizeX, sizeY, sizeZ)
|
override fun tick() {
|
||||||
|
currentLocation?.let { onTick(it, sizeX, sizeY, sizeZ) }
|
||||||
|
}
|
||||||
|
|
||||||
override fun confirm() = onConfirm(currentLocation!!, sizeX, sizeY, sizeZ)
|
override fun confirm(): Boolean {
|
||||||
|
currentLocation?.let { onConfirm(it, sizeX, sizeY, sizeZ) }
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun addDisplays(initialLocation: Location) {
|
override fun addDisplays(initialLocation: Location) {
|
||||||
base = spawnBlockDisplay(initialLocation, Material.GRAY_STAINED_GLASS.createBlockData(),
|
base = spawnBlockDisplay(initialLocation, Material.GRAY_STAINED_GLASS.createBlockData(),
|
||||||
@ -58,23 +56,23 @@ class AreaPlaceHint(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun updateColour() {
|
// override fun updateGlowColour(colour: ChatFormatting) {
|
||||||
super.updateColour()
|
// super.updateGlowColour(colour)
|
||||||
|
//
|
||||||
// base
|
// // base
|
||||||
val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
// val dataPacket = PacketContainer(PacketType.Play.Server.ENTITY_METADATA)
|
||||||
dataPacket.integers.write(0, base.first)
|
// dataPacket.integers.write(0, base.first)
|
||||||
|
//
|
||||||
val material = if (isValid) Material.LIME_STAINED_GLASS else Material.RED_STAINED_GLASS
|
// val material = if (isValid) Material.LIME_STAINED_GLASS else Material.RED_STAINED_GLASS
|
||||||
val blockData = BukkitConverters
|
// val blockData = BukkitConverters
|
||||||
.getWrappedBlockDataConverter()
|
// .getWrappedBlockDataConverter()
|
||||||
.getGeneric(WrappedBlockData.createData(material))
|
// .getGeneric(WrappedBlockData.createData(material))
|
||||||
|
//
|
||||||
val metadata = listOf(
|
// val metadata = listOf(
|
||||||
WrappedDataValue(23, Registry.getBlockDataSerializer(false), blockData)
|
// WrappedDataValue(23, Registry.getBlockDataSerializer(false), blockData)
|
||||||
)
|
// )
|
||||||
|
//
|
||||||
dataPacket.dataValueCollectionModifier.write(0, metadata)
|
// dataPacket.dataValueCollectionModifier.write(0, metadata)
|
||||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
// ProtocolLibrary.getProtocolManager().sendServerPacket(player, dataPacket)
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.pobnellion.aoe.ui
|
package com.pobnellion.aoe.ui
|
||||||
|
|
||||||
|
import com.comphenix.protocol.wrappers.EnumWrappers
|
||||||
import com.pobnellion.aoe.Aoe
|
import com.pobnellion.aoe.Aoe
|
||||||
import com.pobnellion.aoe.building.BuildingInfo
|
import com.pobnellion.aoe.building.BuildingInfo
|
||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter
|
import com.sk89q.worldedit.bukkit.BukkitAdapter
|
||||||
@ -36,6 +37,7 @@ class BuildingPlaceHint(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val schematic: Clipboard
|
private val schematic: Clipboard
|
||||||
|
private var isValid = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val schematicName = buildingInfo.schematicNames[buildingVariant]
|
val schematicName = buildingInfo.schematicNames[buildingVariant]
|
||||||
@ -53,9 +55,23 @@ class BuildingPlaceHint(
|
|||||||
-floor(clipboard.dimensions.z() / 2.0))
|
-floor(clipboard.dimensions.z() / 2.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun validate(location: Location) = buildingInfo.validate(location)
|
override fun tick() {
|
||||||
|
// Update material
|
||||||
|
val valid = currentLocation?.let { buildingInfo.validate(it) } ?: false
|
||||||
|
|
||||||
override fun confirm() = onConfirm(currentLocation!!, buildingInfo, buildingVariant)
|
if (valid != isValid) {
|
||||||
|
isValid = valid
|
||||||
|
updateGlowColour(if (isValid) EnumWrappers.ChatFormatting.GREEN else EnumWrappers.ChatFormatting.RED)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun confirm(): Boolean {
|
||||||
|
if (!isValid || currentLocation == null)
|
||||||
|
return false
|
||||||
|
|
||||||
|
onConfirm(currentLocation!!, buildingInfo, buildingVariant)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun addDisplays(initialLocation: Location) {
|
override fun addDisplays(initialLocation: Location) {
|
||||||
schematic.iterator().forEach { blockPosition ->
|
schematic.iterator().forEach { blockPosition ->
|
||||||
|
|||||||
@ -2,8 +2,8 @@ package com.pobnellion.aoe.ui
|
|||||||
|
|
||||||
import com.pobnellion.aoe.Aoe
|
import com.pobnellion.aoe.Aoe
|
||||||
import com.pobnellion.aoe.building.BuildingType
|
import com.pobnellion.aoe.building.BuildingType
|
||||||
|
import com.pobnellion.aoe.getCivilisation
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import org.bukkit.Bukkit
|
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.event.EventHandler
|
import org.bukkit.event.EventHandler
|
||||||
@ -16,8 +16,8 @@ import org.bukkit.event.player.PlayerInteractEvent
|
|||||||
import org.bukkit.inventory.ItemStack
|
import org.bukkit.inventory.ItemStack
|
||||||
|
|
||||||
|
|
||||||
class PlaceItem : Listener {
|
class InventoryManager : Listener {
|
||||||
private val buildingInventory = Bukkit.createInventory(null, 9, Component.text("Buildings"))
|
private val buildingInventory =
|
||||||
|
|
||||||
init {
|
init {
|
||||||
buildingInventory.addItem(createGuiItem(Material.BELL, "Town center", "middle of the town :D"))
|
buildingInventory.addItem(createGuiItem(Material.BELL, "Town center", "middle of the town :D"))
|
||||||
@ -25,6 +25,25 @@ class PlaceItem : Listener {
|
|||||||
buildingInventory.addItem(createGuiItem(Material.EMERALD, "Villager", "willager"))
|
buildingInventory.addItem(createGuiItem(Material.EMERALD, "Villager", "willager"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun initHotbars() {
|
||||||
|
for (player in Aoe.players.keys) {
|
||||||
|
player.inventory.clear()
|
||||||
|
player.inventory.setItem(0, createGuiItem(Material.BRICKS, "Buildings"))
|
||||||
|
|
||||||
|
// TODO: double click select selects all of looking at type
|
||||||
|
player.inventory.setItem(6, createGuiItem(Material.WOODEN_HOE, "Select inactive villagers"))
|
||||||
|
player.inventory.setItem(7, createGuiItem(Material.IRON_HOE, "Select villagers"))
|
||||||
|
player.inventory.setItem(8, createGuiItem(Material.IRON_SWORD, "Select army"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showBuildingInventory(player: Player) {
|
||||||
|
if (Aoe.isPlaying(player))
|
||||||
|
player.openInventory(player.getCivilisation()!!.buildingInventory.inventory)
|
||||||
|
}
|
||||||
|
|
||||||
|
// region events
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onRightClickItem(event: PlayerInteractEvent) {
|
fun onRightClickItem(event: PlayerInteractEvent) {
|
||||||
if (event.action != Action.RIGHT_CLICK_AIR && event.action != Action.RIGHT_CLICK_BLOCK)
|
if (event.action != Action.RIGHT_CLICK_AIR && event.action != Action.RIGHT_CLICK_BLOCK)
|
||||||
@ -40,18 +59,20 @@ class PlaceItem : Listener {
|
|||||||
return
|
return
|
||||||
|
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
event.player.openInventory(buildingInventory)
|
showBuildingInventory(event.player)
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onInventoryClick(event: InventoryClickEvent) {
|
fun onInventoryClick(event: InventoryClickEvent) {
|
||||||
|
if (Aoe.players.containsKey(event.whoClicked as Player))
|
||||||
|
event.isCancelled = true
|
||||||
|
|
||||||
val player = event.whoClicked as Player
|
val player = event.whoClicked as Player
|
||||||
val team = Aoe.getTeam(player) ?: return
|
val team = Aoe.getTeam(player) ?: return
|
||||||
|
|
||||||
if (event.inventory != buildingInventory)
|
if (event.inventory != buildingInventory)
|
||||||
return
|
return
|
||||||
|
|
||||||
event.isCancelled = true
|
|
||||||
var validClick = true
|
var validClick = true
|
||||||
|
|
||||||
when (event.currentItem?.type) {
|
when (event.currentItem?.type) {
|
||||||
@ -67,14 +88,19 @@ class PlaceItem : Listener {
|
|||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onInventoryClick(event: InventoryDragEvent) {
|
fun onInventoryClick(event: InventoryDragEvent) {
|
||||||
if (event.inventory == buildingInventory)
|
if (Aoe.players.containsKey(event.whoClicked as Player))
|
||||||
event.isCancelled = true
|
event.isCancelled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createGuiItem(material: Material, name: String, lore: String): ItemStack {
|
// endregion
|
||||||
|
|
||||||
|
private fun createGuiItem(material: Material, name: String, lore: String? = null): ItemStack {
|
||||||
val item = ItemStack(material, 1)
|
val item = ItemStack(material, 1)
|
||||||
item.itemMeta.displayName(Component.text(name))
|
item.itemMeta.displayName(Component.text(name))
|
||||||
item.itemMeta.lore(mutableListOf(Component.text(lore)))
|
|
||||||
|
if (lore != null)
|
||||||
|
item.itemMeta.lore(mutableListOf(Component.text(lore)))
|
||||||
|
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4,6 +4,7 @@ import com.comphenix.protocol.PacketType
|
|||||||
import com.comphenix.protocol.ProtocolLibrary
|
import com.comphenix.protocol.ProtocolLibrary
|
||||||
import com.comphenix.protocol.events.PacketContainer
|
import com.comphenix.protocol.events.PacketContainer
|
||||||
import com.comphenix.protocol.wrappers.*
|
import com.comphenix.protocol.wrappers.*
|
||||||
|
import com.comphenix.protocol.wrappers.EnumWrappers.ChatFormatting
|
||||||
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 org.bukkit.Location
|
import org.bukkit.Location
|
||||||
@ -73,11 +74,8 @@ abstract class PlaceHint {
|
|||||||
|
|
||||||
// left click - confirm
|
// 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]!!.confirm())
|
||||||
return
|
remove(event.player)
|
||||||
|
|
||||||
playerHints[event.player.uniqueId]!!.confirm()
|
|
||||||
remove(event.player)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// right click - cancel
|
// right click - cancel
|
||||||
@ -91,7 +89,7 @@ abstract class PlaceHint {
|
|||||||
.collisionRule("never")
|
.collisionRule("never")
|
||||||
.nametagVisibility("never")
|
.nametagVisibility("never")
|
||||||
.options(0)
|
.options(0)
|
||||||
.color(EnumWrappers.ChatFormatting.RED)
|
.color(ChatFormatting.RED)
|
||||||
.prefix(WrappedChatComponent.fromText(""))
|
.prefix(WrappedChatComponent.fromText(""))
|
||||||
.suffix(WrappedChatComponent.fromText(""))
|
.suffix(WrappedChatComponent.fromText(""))
|
||||||
.build()
|
.build()
|
||||||
@ -102,11 +100,10 @@ abstract class PlaceHint {
|
|||||||
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())
|
||||||
protected val displayIds: MutableList<Pair<Int, UUID>> = mutableListOf()
|
protected val displayIds: MutableList<Pair<Int, UUID>> = mutableListOf()
|
||||||
var currentLocation: Location? = null
|
var currentLocation: Location? = null
|
||||||
var isValid = false
|
|
||||||
|
|
||||||
protected abstract fun addDisplays(initialLocation: Location)
|
protected abstract fun addDisplays(initialLocation: Location)
|
||||||
protected abstract fun confirm()
|
protected abstract fun confirm(): Boolean
|
||||||
protected abstract fun validate(location: Location): Boolean
|
protected abstract fun tick()
|
||||||
|
|
||||||
private fun show(initialLocation: Location) {
|
private fun show(initialLocation: Location) {
|
||||||
initialLocation.add(this.offset)
|
initialLocation.add(this.offset)
|
||||||
@ -138,8 +135,7 @@ abstract 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)
|
tick()
|
||||||
updateColour()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hide() {
|
private fun hide() {
|
||||||
@ -181,13 +177,7 @@ abstract class PlaceHint {
|
|||||||
|
|
||||||
currentLocation = newLocation
|
currentLocation = newLocation
|
||||||
|
|
||||||
// Update material
|
this.tick()
|
||||||
val valid = validate(newLocation)
|
|
||||||
|
|
||||||
if (valid != isValid) {
|
|
||||||
isValid = valid
|
|
||||||
updateColour()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// region helper functions
|
// region helper functions
|
||||||
@ -234,13 +224,13 @@ abstract class PlaceHint {
|
|||||||
return Pair<Int, UUID>(id, uuid)
|
return Pair<Int, UUID>(id, uuid)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open fun updateColour() {
|
protected open fun updateGlowColour(colour: ChatFormatting) {
|
||||||
// outline glow
|
// outline glow
|
||||||
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")
|
||||||
outlineTeamPacket.integers.write(0, 2)
|
outlineTeamPacket.integers.write(0, 2)
|
||||||
val params = WrappedTeamParameters.newBuilder(teamParamsTemplate)
|
val params = WrappedTeamParameters.newBuilder(teamParamsTemplate)
|
||||||
.color(if (isValid) EnumWrappers.ChatFormatting.GREEN else EnumWrappers.ChatFormatting.RED)
|
.color(colour)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
outlineTeamPacket.optionalTeamParameters.write(0, Optional.of(params))
|
outlineTeamPacket.optionalTeamParameters.write(0, Optional.of(params))
|
||||||
|
|||||||
Reference in New Issue
Block a user