Compare commits
9 Commits
accec4fe8f
...
ef8e2391d6
| Author | SHA1 | Date |
|---|---|---|
|
|
ef8e2391d6 | |
|
|
20b1004e62 | |
|
|
3d35de3fe3 | |
|
|
764ead46c2 | |
|
|
84baa309e3 | |
|
|
ed6f40b462 | |
|
|
45882c8cb6 | |
|
|
97c5c1c9fb | |
|
|
362941fe58 |
|
|
@ -22,7 +22,6 @@ object BlastingCrisis : Plugin() {
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
info("§a| §7Loading BlastingCrisis")
|
info("§a| §7Loading BlastingCrisis")
|
||||||
DebugCommand.debug("debugcmd")
|
DebugCommand.debug("debugcmd")
|
||||||
info("§a| §7Loading BlastingCrisis")
|
|
||||||
createDefaultGame()
|
createDefaultGame()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -40,12 +39,13 @@ object BlastingCrisis : Plugin() {
|
||||||
location(0, 72, -44),
|
location(0, 72, -44),
|
||||||
location(0, 72, -44),
|
location(0, 72, -44),
|
||||||
location(-8, 73, -47),
|
location(-8, 73, -47),
|
||||||
Area(location(14, 72, -48), location(-13, 78, -34)),
|
Area(location(14, 72, -48), location(-14, 78, -34)),
|
||||||
Area(location(-13, 78, -33), location(13, 72, -33)),
|
Area(location(-13, 78, -33), location(13, 72, -33)),
|
||||||
Area(location(-13, 78, -32), location(13, 71, -1)),
|
Area(location(-13, 78, -32), location(13, 72, -1)),
|
||||||
Area(location(7, 72, -45), location(9, 74, -48)),
|
Area(location(7, 72, -45), location(9, 74, -48)),
|
||||||
listOf(
|
listOf(
|
||||||
Area(location(15, 72, -1), location(19, 78, -48)), Area(location(19, 78, -48), location(-15, 72, -1))
|
Area(location(15, 72, -1), location(19, 78, -48)),
|
||||||
|
Area(location(-19, 78, -48), location(-15, 72, -1))
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val teamGreen = MapTeam(
|
val teamGreen = MapTeam(
|
||||||
|
|
@ -54,12 +54,13 @@ object BlastingCrisis : Plugin() {
|
||||||
location(0, 72, 44),
|
location(0, 72, 44),
|
||||||
location(0, 72, 44),
|
location(0, 72, 44),
|
||||||
location(8, 73, 47),
|
location(8, 73, 47),
|
||||||
Area(location(-14, 72, 48), location(13, 78, 34)),
|
Area(location(-14, 72, 48), location(14, 78, 34)),
|
||||||
Area(location(13, 78, 33), location(-13, 72, 33)),
|
Area(location(13, 78, 33), location(-13, 72, 33)),
|
||||||
Area(location(13, 78, 32), location(-13, 71, 1)),
|
Area(location(13, 78, 32), location(-13, 72, 1)),
|
||||||
Area(location(-7, 72, 45), location(-9, 74, 48)),
|
Area(location(-7, 72, 45), location(-9, 74, 48)),
|
||||||
listOf(
|
listOf(
|
||||||
Area(location(-15, 72, 1), location(-19, 78, 48)), Area(location(-19, 78, 48), location(15, 72, 1))
|
Area(location(-15, 72, 1), location(-19, 78, 48)),
|
||||||
|
Area(location(19, 78, 48), location(15, 72, 1))
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
val map = GameMap(
|
val map = GameMap(
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class Game(
|
||||||
val scoreboard: GameScoreboard = GameScoreboard(this)
|
val scoreboard: GameScoreboard = GameScoreboard(this)
|
||||||
val timer: GameTimer = GameTimer(this)
|
val timer: GameTimer = GameTimer(this)
|
||||||
val players = ArrayList<Player>()
|
val players = ArrayList<Player>()
|
||||||
|
val placeBreakRule = GamePlaceBreakRule(this)
|
||||||
var state: GameState = GameState.WAITING
|
var state: GameState = GameState.WAITING
|
||||||
|
|
||||||
private fun autoJoinTeam() {
|
private fun autoJoinTeam() {
|
||||||
|
|
@ -47,6 +48,8 @@ class Game(
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
debug("game ${map.name} started.")
|
debug("game ${map.name} started.")
|
||||||
|
placeBreakRule.defaultRule()
|
||||||
|
|
||||||
state = GameState.START
|
state = GameState.START
|
||||||
timer.startTimer()
|
timer.startTimer()
|
||||||
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
||||||
|
|
@ -55,6 +58,9 @@ class Game(
|
||||||
map.wall.forBlocksInArea().forEach {
|
map.wall.forBlocksInArea().forEach {
|
||||||
it.block.type = Material.AIR
|
it.block.type = Material.AIR
|
||||||
}
|
}
|
||||||
|
placeBreakRule.addRule("allow_center_wall") { _, _, loc ->
|
||||||
|
map.wall.contains(loc)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
autoJoinTeam()
|
autoJoinTeam()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.BREAK
|
||||||
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class GamePlaceBreakRule(val game: Game) {
|
||||||
|
enum class ActionType {
|
||||||
|
PLACE,
|
||||||
|
BREAK
|
||||||
|
}
|
||||||
|
|
||||||
|
private val rules = HashMap<String, (Player, ActionType, Location) -> Boolean>()
|
||||||
|
fun matchRule(player: Player, actionType: ActionType, location: Location): Boolean {
|
||||||
|
// match rules
|
||||||
|
rules.forEach { (name, func) ->
|
||||||
|
if (func(player, actionType, location)) {
|
||||||
|
debug("Hit rule $name")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback strategy
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addRule(name: String, rule: (player: Player, type: ActionType, loc: Location) -> Boolean) {
|
||||||
|
if (rules.containsKey(name)) {
|
||||||
|
throw IllegalArgumentException("Rule $name already exists.")
|
||||||
|
}
|
||||||
|
debug("rule $name added")
|
||||||
|
rules[name] = rule
|
||||||
|
}
|
||||||
|
|
||||||
|
fun defaultRule() {
|
||||||
|
// allow mine
|
||||||
|
addRule("allow_mine") { _, _, loc ->
|
||||||
|
game.map.teams.flatMap {
|
||||||
|
it.sides + it.mine
|
||||||
|
}.map {
|
||||||
|
it.containsBlock(loc)
|
||||||
|
}.reduce { a, b -> a || b }
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow enemy wall
|
||||||
|
addRule("allow_wall_conditional") { player, type, loc ->
|
||||||
|
val team = player.team ?: return@addRule false
|
||||||
|
val isWall = game.teams
|
||||||
|
.map {
|
||||||
|
it.teamInfo.wall.containsBlock(loc).also { result -> debug("area ${it.teamInfo.wall} contains $loc is $result") }
|
||||||
|
}
|
||||||
|
.reduce { a, b -> a || b }
|
||||||
|
if (!isWall) return@addRule false
|
||||||
|
val isHome = team.teamInfo.wall.containsBlock(loc)
|
||||||
|
(type == BREAK) xor isHome
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,12 @@ class GameTeam(val game: Game, val teamInfo: MapTeam) {
|
||||||
GameListener.interactSubscribed[teamInfo.upgrade] = {
|
GameListener.interactSubscribed[teamInfo.upgrade] = {
|
||||||
debug("interact team ${teamInfo.name} upgrade.")
|
debug("interact team ${teamInfo.name} upgrade.")
|
||||||
}
|
}
|
||||||
|
GameListener.moveSubscribed.add(teamInfo.teleport to {
|
||||||
|
val player = it.player ?: throw IllegalStateException("Bukkit API LOL")
|
||||||
|
debug("teleporting $player to battle field")
|
||||||
|
val team = player.team ?: throw IllegalStateException("Player ${player.name} should have a team")
|
||||||
|
player.teleport(team.teamInfo.mine.randomLocation().toPlayerLocation())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fun join(player: Player) {
|
fun join(player: Player) {
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,28 @@
|
||||||
package cc.maxmc.blastingcrisis.listener
|
package cc.maxmc.blastingcrisis.listener
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.game.team
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule
|
||||||
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
import cc.maxmc.blastingcrisis.misc.GameManager
|
import cc.maxmc.blastingcrisis.misc.GameManager
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
import cc.maxmc.blastingcrisis.misc.toPlayerLocation
|
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
|
import org.bukkit.event.block.BlockBreakEvent
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent
|
||||||
import org.bukkit.event.entity.EntityExplodeEvent
|
import org.bukkit.event.entity.EntityExplodeEvent
|
||||||
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 taboolib.common.platform.event.SubscribeEvent
|
import taboolib.common.platform.event.SubscribeEvent
|
||||||
|
import taboolib.platform.util.sendLang
|
||||||
|
|
||||||
object GameListener {
|
object GameListener {
|
||||||
val interactSubscribed = HashMap<Location, (PlayerInteractEvent) -> Unit>()
|
val interactSubscribed = HashMap<Location, (PlayerInteractEvent) -> Unit>()
|
||||||
|
val moveSubscribed = ArrayList<Pair<Area, (PlayerMoveEvent) -> Unit>>()
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
fun onMoveInTeleport(event: PlayerMoveEvent) {
|
fun portalTeleport(event: PlayerMoveEvent) {
|
||||||
if (!GameManager.currentGame.players.contains(event.player)) return
|
if (!GameManager.currentGame.players.contains(event.player)) return
|
||||||
val player = event.player
|
moveSubscribed.forEach { (area, func) ->
|
||||||
val team = player.team ?: return
|
if (area.contains(event.to)) func(event)
|
||||||
if (!team.teamInfo.teleport.isInArea(event.to)) return
|
}
|
||||||
debug("teleporting ${event.player} to battle field")
|
|
||||||
player.teleport(team.teamInfo.mine.randomLocation().toPlayerLocation())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
|
|
@ -35,10 +37,28 @@ object GameListener {
|
||||||
tntExplode.blockList().clear()
|
tntExplode.blockList().clear()
|
||||||
if (!GameManager.currentGame.state.isStarted()) return
|
if (!GameManager.currentGame.state.isStarted()) return
|
||||||
GameManager.currentGame.teams.findLast {
|
GameManager.currentGame.teams.findLast {
|
||||||
it.teamSurvive && it.teamInfo.home.isInArea(tntExplode.location)
|
it.teamSurvive && it.teamInfo.home.contains(tntExplode.location)
|
||||||
}?.apply {
|
}?.apply {
|
||||||
villager.damage()
|
villager.damage()
|
||||||
debug("team ${teamInfo.name}'s villager damaged")
|
debug("team ${teamInfo.name}'s villager damaged")
|
||||||
} ?: throw IllegalStateException("TNT Exploded at no team, which shouldn't happen")
|
} ?: throw IllegalStateException("TNT Exploded at no team, which shouldn't happen")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onBreak(breakEvent: BlockBreakEvent) {
|
||||||
|
val loc = breakEvent.block.location ?: return
|
||||||
|
val player = breakEvent.player ?: return
|
||||||
|
if (GameManager.currentGame.placeBreakRule.matchRule(player, GamePlaceBreakRule.ActionType.BREAK, loc)) return
|
||||||
|
breakEvent.isCancelled = true
|
||||||
|
player.sendLang("game_cant_break_block")
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
fun onPlace(placeEvent: BlockPlaceEvent) {
|
||||||
|
val loc = placeEvent.block.location ?: return
|
||||||
|
val player = placeEvent.player ?: return
|
||||||
|
if (GameManager.currentGame.placeBreakRule.matchRule(player, GamePlaceBreakRule.ActionType.PLACE, loc)) return
|
||||||
|
placeEvent.isCancelled = true
|
||||||
|
player.sendLang("game_cant_place_block")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,7 +2,13 @@ package cc.maxmc.blastingcrisis.map
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.misc.Area
|
import cc.maxmc.blastingcrisis.misc.Area
|
||||||
|
|
||||||
class GameMap(val name: String, val area: Area, val wall: Area, val teams: List<MapTeam>, val maxPlayersPerTeam: Int) {
|
class GameMap(
|
||||||
|
val name: String,
|
||||||
|
val area: Area,
|
||||||
|
val wall: Area,
|
||||||
|
val teams: List<MapTeam>,
|
||||||
|
val maxPlayersPerTeam: Int
|
||||||
|
) {
|
||||||
val maxPlayer: Int
|
val maxPlayer: Int
|
||||||
get() = maxPlayersPerTeam * teams.size
|
get() = maxPlayersPerTeam * teams.size
|
||||||
}
|
}
|
||||||
|
|
@ -9,5 +9,4 @@ class MapInfo(
|
||||||
var waitArea: Area,
|
var waitArea: Area,
|
||||||
val teams: List<MapTeam>,
|
val teams: List<MapTeam>,
|
||||||
val maxPlayersPerTeam: Int,
|
val maxPlayersPerTeam: Int,
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
@ -2,7 +2,6 @@ package cc.maxmc.blastingcrisis.misc
|
||||||
|
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.Material
|
import org.bukkit.Material
|
||||||
import org.bukkit.block.Block
|
|
||||||
import org.bukkit.configuration.serialization.ConfigurationSerializable
|
import org.bukkit.configuration.serialization.ConfigurationSerializable
|
||||||
import org.bukkit.configuration.serialization.SerializableAs
|
import org.bukkit.configuration.serialization.SerializableAs
|
||||||
import org.bukkit.util.Vector
|
import org.bukkit.util.Vector
|
||||||
|
|
@ -15,6 +14,7 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
val locTop: Location
|
val locTop: Location
|
||||||
val locMin: Location
|
val locMin: Location
|
||||||
|
|
||||||
|
@Suppress("unused") // Bukkit Specification
|
||||||
constructor(map: Map<String, Any>) : this(map["locTop"] as Location, map["locMin"] as Location)
|
constructor(map: Map<String, Any>) : this(map["locTop"] as Location, map["locMin"] as Location)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
@ -30,21 +30,18 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
*
|
*
|
||||||
* @return true if the location is in this area
|
* @return true if the location is in this area
|
||||||
*/
|
*/
|
||||||
fun isInArea(location: Location): Boolean {
|
fun contains(location: Location): Boolean {
|
||||||
if (location.world != locTop.world) return false
|
if (location.world != locTop.world) return false
|
||||||
if (location.x !in (locMin.x - 1)..(locTop.x + 1)) return false
|
if (location.x !in (locMin.x - 1)..(locTop.x + 1)) return false
|
||||||
if (location.y !in locMin.y..locTop.y + 1) return false
|
if (location.y !in locMin.y..locTop.y + 1) return false
|
||||||
if (location.z !in (locMin.z - 1)..(locTop.z + 1)) return false
|
return location.z in (locMin.z - 1)..(locTop.z + 1)
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isBlockInArea(block: Block): Boolean {
|
fun containsBlock(location: Location): Boolean {
|
||||||
val location = block.location
|
|
||||||
if (location.world != locTop.world) return false
|
if (location.world != locTop.world) return false
|
||||||
if (location.x !in locMin.x..locTop.x) return false
|
if (location.x !in locMin.x..locTop.x) return false
|
||||||
if (location.y !in locMin.y..locTop.y) return false
|
if (location.y !in locMin.y..locTop.y) return false
|
||||||
if (location.z !in locMin.z..locTop.z) return false
|
return location.z in locMin.z..locTop.z
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -101,11 +98,10 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
other as Area
|
other as Area
|
||||||
|
|
||||||
if (locTop != other.locTop) return false
|
if (locTop != other.locTop) return false
|
||||||
if (locMin != other.locMin) return false
|
return locMin == other.locMin
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = locTop.hashCode()
|
var result = locTop.hashCode()
|
||||||
result = 31 * result + locMin.hashCode()
|
result = 31 * result + locMin.hashCode()
|
||||||
|
|
@ -114,4 +110,8 @@ class Area(loc1: Location, loc2: Location) : ConfigurationSerializable {
|
||||||
|
|
||||||
override fun serialize() = mutableMapOf<String, Any>("locTop" to locTop, "locMin" to locMin)
|
override fun serialize() = mutableMapOf<String, Any>("locTop" to locTop, "locMin" to locMin)
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "Area(locTop=$locTop, locMin=$locMin)"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue