From 57626e4f95411798c23f32d10d9429ff7e4d1934 Mon Sep 17 00:00:00 2001 From: ruby Date: Sun, 5 Jan 2025 21:23:32 +1300 Subject: [PATCH] restructure things a bit for use in actual gameplay --- .gitignore | 5 +- src/main/kotlin/com/pobnellion/aoe/Aoe.kt | 19 +++++-- .../kotlin/com/pobnellion/aoe/Constants.kt | 6 ++ .../com/pobnellion/aoe/building/Blacksmith.kt | 12 +--- .../com/pobnellion/aoe/building/Building.kt | 44 ++++++++++++++- .../com/pobnellion/aoe/building/House.kt | 14 +---- .../com/pobnellion/aoe/building/TownCenter.kt | 48 +--------------- .../aoe/building/plains/PlainsHouse.kt | 23 ++++++++ .../aoe/building/plains/PlainsTownCenter.kt | 27 +++++++++ .../aoe/civilisation/Civilisation.kt | 55 +++++++++++++++++++ .../aoe/civilisation/CivilisationType.kt | 5 ++ .../aoe/{team => civilisation}/Plains.kt | 14 ++--- .../com/pobnellion/aoe/command/TestCommand.kt | 22 ++++++-- .../aoe/entity/goals/EntityWorkTarget.kt | 10 ++++ .../kotlin/com/pobnellion/aoe/map/AoeMap.kt | 10 ++++ .../kotlin/com/pobnellion/aoe/team/Team.kt | 30 ---------- .../kotlin/com/pobnellion/aoe/ui/PlaceItem.kt | 1 - 17 files changed, 229 insertions(+), 116 deletions(-) create mode 100644 src/main/kotlin/com/pobnellion/aoe/Constants.kt create mode 100644 src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsHouse.kt create mode 100644 src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsTownCenter.kt create mode 100644 src/main/kotlin/com/pobnellion/aoe/civilisation/Civilisation.kt create mode 100644 src/main/kotlin/com/pobnellion/aoe/civilisation/CivilisationType.kt rename src/main/kotlin/com/pobnellion/aoe/{team => civilisation}/Plains.kt (66%) create mode 100644 src/main/kotlin/com/pobnellion/aoe/entity/goals/EntityWorkTarget.kt create mode 100644 src/main/kotlin/com/pobnellion/aoe/map/AoeMap.kt delete mode 100644 src/main/kotlin/com/pobnellion/aoe/team/Team.kt diff --git a/.gitignore b/.gitignore index 8a983ee..674043d 100644 --- a/.gitignore +++ b/.gitignore @@ -115,8 +115,9 @@ gradle-app.setting run/ runs/ +# Ignore gradle.properties cos its got sensitive info +gradle.properties + # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.jar -# Ignore gradle.properties cos its got sensitive info -gradle.properties \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/Aoe.kt b/src/main/kotlin/com/pobnellion/aoe/Aoe.kt index 5376922..f0f7972 100644 --- a/src/main/kotlin/com/pobnellion/aoe/Aoe.kt +++ b/src/main/kotlin/com/pobnellion/aoe/Aoe.kt @@ -2,7 +2,9 @@ package com.pobnellion.aoe import com.pobnellion.aoe.command.TestCommand import com.pobnellion.aoe.command.TestTabCompleter -import com.pobnellion.aoe.team.Team +import com.pobnellion.aoe.civilisation.Civilisation +import com.pobnellion.aoe.civilisation.CivilisationType +import com.pobnellion.aoe.map.AoeMap import com.pobnellion.aoe.ui.PlaceHint import com.pobnellion.aoe.ui.PlaceItem import org.bukkit.Bukkit @@ -13,15 +15,24 @@ import java.nio.file.Paths class Aoe : JavaPlugin() { companion object { + private var gameInProgress: Boolean = false private var instance: Aoe? = null - val teams: MutableList = mutableListOf() + val civilisations: MutableMap = mutableMapOf() + val map: AoeMap = AoeMap() - fun getTeam(player: Player): Team? { - return teams.singleOrNull() { team -> team.players.contains(player) } + fun getTeam(player: Player): Civilisation? { + return civilisations.values.singleOrNull { team -> team.players.contains(player) } } fun getSchematicFile(schematicName: String): File = Paths.get(instance!!.dataFolder.path, "schematics", "$schematicName.schem").toFile() + + fun startGame() { + if (!gameInProgress) + civilisations.values.forEach { civ -> civ.initSetup() } + + gameInProgress = true + } } override fun onEnable() { diff --git a/src/main/kotlin/com/pobnellion/aoe/Constants.kt b/src/main/kotlin/com/pobnellion/aoe/Constants.kt new file mode 100644 index 0000000..f5f101d --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/Constants.kt @@ -0,0 +1,6 @@ +package com.pobnellion.aoe + +object Constants { + const val MAX_POP_CAP = 200 + const val STARTING_VILLAGER_COUNT = 5 +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/building/Blacksmith.kt b/src/main/kotlin/com/pobnellion/aoe/building/Blacksmith.kt index 777ad45..35edf5a 100644 --- a/src/main/kotlin/com/pobnellion/aoe/building/Blacksmith.kt +++ b/src/main/kotlin/com/pobnellion/aoe/building/Blacksmith.kt @@ -1,16 +1,8 @@ package com.pobnellion.aoe.building import org.bukkit.Location -import org.bukkit.Material class Blacksmith(location: Location, variant: Int): Building(location, variant) { - fun place(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, offsetY: Int) { - for (x in 0..= 1.0f + override fun addProgress(amount: Float) {} + override fun setProgress(amount: Float) {} + override fun removeProgress(amount: Float) {} + override fun onComplete() {} + + abstract var populationCapacity: Int + abstract fun getSchematicName(variant: Int): String + + fun placeFull() { + currentProgressPercent = 1f + var clipboard: Clipboard + + val file: File = Aoe.getSchematicFile(getSchematicName(variant)) + val format = ClipboardFormats.findByFile(file) + format!!.getReader(FileInputStream(file)).use { reader -> + clipboard = reader.read() + } + + val offset = clipboard.region.minimumPoint.subtract(clipboard.origin) + + WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(location.world)).use { editSession -> + val operation: Operation = ClipboardHolder(clipboard) + .createPaste(editSession) + .to(BlockVector3.at(location.x, location.y, location.z).subtract(offset)) + .build() + Operations.complete(operation) + } + } } interface BuildingInfo { diff --git a/src/main/kotlin/com/pobnellion/aoe/building/House.kt b/src/main/kotlin/com/pobnellion/aoe/building/House.kt index 363bc62..3b17560 100644 --- a/src/main/kotlin/com/pobnellion/aoe/building/House.kt +++ b/src/main/kotlin/com/pobnellion/aoe/building/House.kt @@ -1,20 +1,10 @@ package com.pobnellion.aoe.building -import com.pobnellion.aoe.ui.PlaceHintValidators import org.bukkit.Location import org.bukkit.Material -class House(location: Location, variant: Int): Building(location, variant) { - companion object Info: BuildingInfo { - override val buildingType: BuildingType = BuildingType.HOUSE - override val schematicNames: List = 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) - } +abstract class House(location: Location, variant: Int): Building(location, variant) { + override var populationCapacity: Int = 5 fun place(location: Location, sizeX: Float, sizeY: Float, sizeZ: Float, int: Int) { for (x in 0.. - clipboard = reader.read() - } - - val offset = clipboard.region.minimumPoint.subtract(clipboard.origin) - - WorldEdit.getInstance().newEditSession(BukkitAdapter.adapt(location.world)).use { editSession -> - val operation: Operation = ClipboardHolder(clipboard) - .createPaste(editSession) - .to(BlockVector3.at(location.x, location.y, location.z).subtract(offset)) // configure here - .build() - Operations.complete(operation) - } - } } \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsHouse.kt b/src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsHouse.kt new file mode 100644 index 0000000..f065060 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsHouse.kt @@ -0,0 +1,23 @@ +package com.pobnellion.aoe.building.plains + +import com.pobnellion.aoe.building.Building +import com.pobnellion.aoe.building.BuildingInfo +import com.pobnellion.aoe.building.BuildingType +import com.pobnellion.aoe.building.House +import com.pobnellion.aoe.ui.PlaceHintValidators +import org.bukkit.Location + +class PlainsHouse(location: Location, variant: Int): House(location, variant) { + companion object Info: BuildingInfo { + override val buildingType: BuildingType = BuildingType.HOUSE + override val schematicNames: List = listOf("house1") + + override fun validate(location: Location): Boolean { + return PlaceHintValidators.allReplaceable(location, 5f, 5f, 5f, -1) + } + + override fun create(location: Location, variant: Int): Building = PlainsHouse(location, variant) + } + + override fun getSchematicName(variant: Int) = schematicNames[variant] +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsTownCenter.kt b/src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsTownCenter.kt new file mode 100644 index 0000000..d47b6f3 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/building/plains/PlainsTownCenter.kt @@ -0,0 +1,27 @@ +package com.pobnellion.aoe.building.plains + +import com.pobnellion.aoe.building.Building +import com.pobnellion.aoe.building.BuildingInfo +import com.pobnellion.aoe.building.BuildingType +import com.pobnellion.aoe.building.TownCenter +import com.pobnellion.aoe.ui.PlaceHintValidators +import org.bukkit.Location + +class PlainsTownCenter(location: Location, variant: Int): TownCenter(location, variant) { + companion object Info: BuildingInfo { + override val buildingType = BuildingType.TOWN_CENTER + override val schematicNames = listOf("plains_towncenter") + + override fun validate(location: Location): Boolean { + return PlaceHintValidators.allReplaceable(location, 10f, 10f, 10f, -2) + } + + override fun create(location: Location, variant: Int): Building { + return PlainsTownCenter(location, variant) + } + } + + override val villagerSpawnLocation: Location = location.clone().add(7.0,2.0, 7.0) + override fun getSchematicName(variant: Int) = schematicNames[variant] + +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/civilisation/Civilisation.kt b/src/main/kotlin/com/pobnellion/aoe/civilisation/Civilisation.kt new file mode 100644 index 0000000..2e9e343 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/civilisation/Civilisation.kt @@ -0,0 +1,55 @@ +package com.pobnellion.aoe.civilisation + +import com.pobnellion.aoe.Constants +import com.pobnellion.aoe.building.Building +import com.pobnellion.aoe.building.BuildingInfo +import com.pobnellion.aoe.building.BuildingType +import com.pobnellion.aoe.building.TownCenter +import com.pobnellion.aoe.entity.AoeVillager +import com.pobnellion.aoe.ui.BuildingPlaceHint +import org.bukkit.Location +import org.bukkit.entity.Player +import kotlin.math.min +import kotlin.random.Random + +abstract class Civilisation( + private val setupLocation: Location +) { + private val buildings: MutableList = mutableListOf() + private val villagers: MutableList = mutableListOf() + val players: MutableList = mutableListOf() + + fun addPlayer(player: Player) { + players.add(player) + player.sendMessage("Joined team ${name()}") + } + + protected abstract fun getBuildingInfo(type: BuildingType): BuildingInfo + protected abstract fun name(): String + + fun addBuilding(location: Location, buildingInfo: BuildingInfo, variant: Int): Building { + val building = buildingInfo.create(location, variant) + buildings.add(building) + return building + } + + fun showBuildingPlaceHint(type: BuildingType, player: Player) { + val info = getBuildingInfo(type) + val variant = Random.nextInt(info.schematicNames.size) + BuildingPlaceHint.add(player, info, ::addBuilding, variant) + } + + fun initSetup() { + // Create town center + val townCenterInfo = getBuildingInfo(BuildingType.TOWN_CENTER) + val variant = Random.nextInt(townCenterInfo.schematicNames.size) + val townCenter = addBuilding(setupLocation, townCenterInfo, variant) as TownCenter + townCenter.placeFull() + + // Spawn initial villagers + for (i in 0..Constants.STARTING_VILLAGER_COUNT) + villagers.add(AoeVillager(townCenter.villagerSpawnLocation)) + } + + fun populationCap() = min(Constants.MAX_POP_CAP, buildings.sumOf { building -> building.populationCapacity }) +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/civilisation/CivilisationType.kt b/src/main/kotlin/com/pobnellion/aoe/civilisation/CivilisationType.kt new file mode 100644 index 0000000..cbcf454 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/civilisation/CivilisationType.kt @@ -0,0 +1,5 @@ +package com.pobnellion.aoe.civilisation + +enum class CivilisationType { + PLAINS +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/team/Plains.kt b/src/main/kotlin/com/pobnellion/aoe/civilisation/Plains.kt similarity index 66% rename from src/main/kotlin/com/pobnellion/aoe/team/Plains.kt rename to src/main/kotlin/com/pobnellion/aoe/civilisation/Plains.kt index 4944e9a..9db774a 100644 --- a/src/main/kotlin/com/pobnellion/aoe/team/Plains.kt +++ b/src/main/kotlin/com/pobnellion/aoe/civilisation/Plains.kt @@ -1,12 +1,12 @@ -package com.pobnellion.aoe.team +package com.pobnellion.aoe.civilisation import com.pobnellion.aoe.building.BuildingInfo import com.pobnellion.aoe.building.BuildingType -import com.pobnellion.aoe.building.House -import com.pobnellion.aoe.building.TownCenter -import org.bukkit.entity.Player +import com.pobnellion.aoe.building.plains.PlainsHouse +import com.pobnellion.aoe.building.plains.PlainsTownCenter +import org.bukkit.Location -class Plains(players: List) : Team(players) { +class Plains(setupLocation: Location) : Civilisation(setupLocation) { override fun name(): String = "Plains" override fun getBuildingInfo(type: BuildingType): BuildingInfo { @@ -15,12 +15,12 @@ class Plains(players: List) : Team(players) { BuildingType.BARRACKS -> TODO() BuildingType.DOCK -> TODO() BuildingType.FARM -> TODO() - BuildingType.HOUSE -> House.Info + BuildingType.HOUSE -> PlainsHouse.Info BuildingType.LUMBER_CAMP -> TODO() BuildingType.MILL -> TODO() BuildingType.MINING_CAMP -> TODO() BuildingType.STABLE -> TODO() - BuildingType.TOWN_CENTER -> TownCenter.Info + BuildingType.TOWN_CENTER -> PlainsTownCenter.Info BuildingType.UNIQUE -> TODO() BuildingType.WALL -> TODO() BuildingType.WATCH_TOWER -> TODO() diff --git a/src/main/kotlin/com/pobnellion/aoe/command/TestCommand.kt b/src/main/kotlin/com/pobnellion/aoe/command/TestCommand.kt index 5fbb956..f81b067 100644 --- a/src/main/kotlin/com/pobnellion/aoe/command/TestCommand.kt +++ b/src/main/kotlin/com/pobnellion/aoe/command/TestCommand.kt @@ -1,7 +1,8 @@ package com.pobnellion.aoe.command import com.pobnellion.aoe.Aoe -import com.pobnellion.aoe.team.Plains +import com.pobnellion.aoe.civilisation.CivilisationType +import com.pobnellion.aoe.civilisation.Plains import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender @@ -22,6 +23,7 @@ class TestCommand : CommandExecutor { when (args[0]) { "team" -> team(sender, args) + "start" -> Aoe.startGame() else -> sender.sendMessage("Invalid argument: ${args[0]}") } @@ -35,21 +37,33 @@ class TestCommand : CommandExecutor { } when (args[1]) { - "plains" -> Aoe.teams.add(Plains(listOf(sender as Player))) + "plains" -> joinCiv(sender as Player, CivilisationType.PLAINS) else -> sender.sendMessage("Invalid team: ${args[1]}") } } + + private fun joinCiv(player: Player, civilisationType: CivilisationType) { + if (!Aoe.civilisations.containsKey(civilisationType)) + when (civilisationType) { + CivilisationType.PLAINS -> Aoe.civilisations[CivilisationType.PLAINS] = Plains(Aoe.map.getStartingLocations()[0]) + } + + Aoe.civilisations[civilisationType]!!.addPlayer(player) + } } class TestTabCompleter: TabCompleter { override fun onTabComplete(sender: CommandSender, command: Command, label: String, args: Array): MutableList? { val options: MutableList = mutableListOf() - if (args.size == 1) + if (args.size == 1) { options.add("team") + options.add("start") + } if (args.size == 2) - options.add("plains") + if (args[0] == "team") + options.add("plains") return options } diff --git a/src/main/kotlin/com/pobnellion/aoe/entity/goals/EntityWorkTarget.kt b/src/main/kotlin/com/pobnellion/aoe/entity/goals/EntityWorkTarget.kt new file mode 100644 index 0000000..d934ff6 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/entity/goals/EntityWorkTarget.kt @@ -0,0 +1,10 @@ +package com.pobnellion.aoe.entity.goals + +interface EntityWorkTarget { + var currentProgressPercent: Float + fun isComplete(): Boolean + fun addProgress(amount: Float) + fun setProgress(amount: Float) + fun removeProgress(amount: Float) + fun onComplete() +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/map/AoeMap.kt b/src/main/kotlin/com/pobnellion/aoe/map/AoeMap.kt new file mode 100644 index 0000000..d69c135 --- /dev/null +++ b/src/main/kotlin/com/pobnellion/aoe/map/AoeMap.kt @@ -0,0 +1,10 @@ +package com.pobnellion.aoe.map + +import org.bukkit.Bukkit +import org.bukkit.Location + +class AoeMap { + fun getStartingLocations(): List { + return listOf(Location(Bukkit.getWorld("world"), -165.0, 63.0, 32.0)) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/team/Team.kt b/src/main/kotlin/com/pobnellion/aoe/team/Team.kt deleted file mode 100644 index c0555b5..0000000 --- a/src/main/kotlin/com/pobnellion/aoe/team/Team.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.pobnellion.aoe.team - -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 - -abstract class Team(val players: List) { - private val buildings: MutableList = mutableListOf() - - init { - players.forEach { player -> player.sendMessage("Joined team ${name()}") } - } - - protected abstract fun getBuildingInfo(type: BuildingType): BuildingInfo - protected abstract fun name(): String - - 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) - } -} \ No newline at end of file diff --git a/src/main/kotlin/com/pobnellion/aoe/ui/PlaceItem.kt b/src/main/kotlin/com/pobnellion/aoe/ui/PlaceItem.kt index 2429749..7806fdf 100644 --- a/src/main/kotlin/com/pobnellion/aoe/ui/PlaceItem.kt +++ b/src/main/kotlin/com/pobnellion/aoe/ui/PlaceItem.kt @@ -77,5 +77,4 @@ class PlaceItem : Listener { item.itemMeta.lore(mutableListOf(Component.text(lore))) return item } - } \ No newline at end of file