finish rule match part
This commit is contained in:
parent
45629b0d1b
commit
9f5f657ea1
File diff suppressed because it is too large
Load Diff
|
|
@ -54,8 +54,8 @@ class Game(
|
||||||
timer.startTimer()
|
timer.startTimer()
|
||||||
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
|
||||||
broadcast { it.sendLang("game_wall_fall") }
|
broadcast { it.sendLang("game_wall_fall") }
|
||||||
placeBreakRule.addRule("allow_center_wall") { _, _, loc, _ ->
|
placeBreakRule.addRuleLast("allow_center_wall") { (_, _, loc, _) ->
|
||||||
map.wall.contains(loc)
|
if (map.wall.contains(loc)) GamePlaceBreakRule.MatchResult.ALLOW else GamePlaceBreakRule.MatchResult.DEFAULT
|
||||||
}
|
}
|
||||||
submit {
|
submit {
|
||||||
map.wall.forBlocksInArea().forEach {
|
map.wall.forBlocksInArea().forEach {
|
||||||
|
|
|
||||||
|
|
@ -2,29 +2,40 @@ package cc.maxmc.blastingcrisis.game
|
||||||
|
|
||||||
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.BREAK
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.BREAK
|
||||||
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.PLACE
|
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.PLACE
|
||||||
|
import cc.maxmc.blastingcrisis.misc.EnhancedLinkedList
|
||||||
import cc.maxmc.blastingcrisis.misc.debug
|
import cc.maxmc.blastingcrisis.misc.debug
|
||||||
import org.bukkit.Location
|
import org.bukkit.Location
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import taboolib.library.xseries.XMaterial
|
import taboolib.library.xseries.XMaterial
|
||||||
|
|
||||||
|
typealias PlaceBreakRule = (GamePlaceBreakRule.GamePlaceBreakEvent) -> GamePlaceBreakRule.MatchResult
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("unused") // API
|
||||||
class GamePlaceBreakRule(val game: Game) {
|
class GamePlaceBreakRule(val game: Game) {
|
||||||
|
|
||||||
enum class ActionType {
|
enum class ActionType {
|
||||||
PLACE,
|
PLACE,
|
||||||
BREAK
|
BREAK
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class PlacePosition {
|
enum class MatchResult {
|
||||||
FIRST,
|
DEFAULT,
|
||||||
LAST
|
ALLOW,
|
||||||
|
DENY
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rules = HashMap<String, (Player, ActionType, Location, XMaterial) -> Boolean>()
|
data class GamePlaceBreakEvent(val player: Player, val actionType: ActionType, val loc: Location, val type: XMaterial)
|
||||||
|
|
||||||
|
private val rules = HashMap<String, PlaceBreakRule>()
|
||||||
|
private val rulesPriority = EnhancedLinkedList<String>()
|
||||||
fun matchRule(player: Player, actionType: ActionType, location: Location, type: XMaterial): Boolean {
|
fun matchRule(player: Player, actionType: ActionType, location: Location, type: XMaterial): Boolean {
|
||||||
// match rules
|
// match rules
|
||||||
rules.forEach { (name, func) ->
|
rules.forEach { (name, func) ->
|
||||||
if (func(player, actionType, location, type)) {
|
val result = func(GamePlaceBreakEvent(player, actionType, location, type))
|
||||||
|
if (result != MatchResult.DEFAULT) {
|
||||||
debug("Hit rule $name")
|
debug("Hit rule $name")
|
||||||
return true
|
return result == MatchResult.ALLOW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,10 +43,7 @@ class GamePlaceBreakRule(val game: Game) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addRule(
|
private fun recordRule(name: String, rule: PlaceBreakRule) {
|
||||||
name: String,
|
|
||||||
rule: (player: Player, actionType: ActionType, loc: Location, type: XMaterial) -> Boolean
|
|
||||||
) {
|
|
||||||
if (rules.containsKey(name)) {
|
if (rules.containsKey(name)) {
|
||||||
throw IllegalArgumentException("Rule $name already exists.")
|
throw IllegalArgumentException("Rule $name already exists.")
|
||||||
}
|
}
|
||||||
|
|
@ -43,43 +51,80 @@ class GamePlaceBreakRule(val game: Game) {
|
||||||
rules[name] = rule
|
rules[name] = rule
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadDefaultRule() {
|
fun addRuleLast(
|
||||||
// allow tnt in enemy's home
|
name: String,
|
||||||
addRule("allow_tnt_conditional") { player, actionType, loc, type ->
|
rule: PlaceBreakRule
|
||||||
if (type != XMaterial.TNT) return@addRule false
|
) {
|
||||||
val team = player.team ?: return@addRule false
|
recordRule(name, rule)
|
||||||
val isHome = game.teams
|
rulesPriority.addLast(name)
|
||||||
.map {
|
}
|
||||||
it.teamInfo.home.containsBlock(loc)
|
|
||||||
.also { result -> debug("area ${it.teamInfo.home} contains $loc is $result") }
|
|
||||||
}
|
|
||||||
.reduce { a, b -> a || b }
|
|
||||||
if (!isHome) return@addRule false
|
|
||||||
val isSelf = team.teamInfo.home.containsBlock(loc)
|
|
||||||
(actionType == PLACE) xor isSelf
|
|
||||||
|
|
||||||
}
|
fun addRuleFirst(
|
||||||
|
name: String,
|
||||||
|
rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addFirst(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addRuleBefore(
|
||||||
|
base: String,
|
||||||
|
name: String,
|
||||||
|
rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addBefore(base, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun addRuleAfter(
|
||||||
|
base: String,
|
||||||
|
name: String,
|
||||||
|
rule: PlaceBreakRule
|
||||||
|
) {
|
||||||
|
recordRule(name, rule)
|
||||||
|
rulesPriority.addAfter(base, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadDefaultRule() {
|
||||||
// allow mine
|
// allow mine
|
||||||
addRule("allow_mine") { _, _, loc, _ ->
|
addRuleLast("allow_mine") { (_, _, loc, _) ->
|
||||||
game.map.teams.flatMap {
|
val result = game.map.teams.flatMap {
|
||||||
it.sides + it.mine
|
it.sides + it.mine
|
||||||
}.map {
|
}.map {
|
||||||
it.containsBlock(loc)
|
it.containsBlock(loc)
|
||||||
}.reduce { a, b -> a || b }
|
}.reduce { a, b -> a || b }
|
||||||
|
if (result) MatchResult.ALLOW else MatchResult.DEFAULT
|
||||||
}
|
}
|
||||||
|
|
||||||
// allow enemy wall
|
// allow enemy wall
|
||||||
addRule("allow_wall_conditional") { player, actionType, loc, _ ->
|
addRuleLast("allow_wall_conditional") { (player, actionType, loc, _) ->
|
||||||
val team = player.team ?: return@addRule false
|
val team = player.team ?: return@addRuleLast MatchResult.DENY
|
||||||
val isWall = game.teams
|
val isWall = game.teams
|
||||||
.map {
|
.map {
|
||||||
it.teamInfo.wall.containsBlock(loc)
|
it.teamInfo.wall.containsBlock(loc)
|
||||||
.also { result -> debug("area ${it.teamInfo.wall} contains $loc is $result") }
|
.also { result -> debug("area ${it.teamInfo.wall} contains $loc is $result") }
|
||||||
}
|
}
|
||||||
.reduce { a, b -> a || b }
|
.reduce { a, b -> a || b }
|
||||||
if (!isWall) return@addRule false
|
if (!isWall) return@addRuleLast MatchResult.DEFAULT
|
||||||
val isHome = team.teamInfo.wall.containsBlock(loc)
|
val isHome = team.teamInfo.wall.containsBlock(loc)
|
||||||
(actionType == BREAK) xor isHome
|
if ((actionType == BREAK) xor isHome) MatchResult.ALLOW else MatchResult.DENY
|
||||||
|
}
|
||||||
|
|
||||||
|
// allow tnt in enemy's home
|
||||||
|
addRuleFirst("allow_tnt_conditional") { (player, actionType, loc, type) ->
|
||||||
|
if (type != XMaterial.TNT) return@addRuleFirst MatchResult.DEFAULT
|
||||||
|
val team = player.team ?: return@addRuleFirst MatchResult.DENY
|
||||||
|
val isHome = game.teams
|
||||||
|
.map {
|
||||||
|
it.teamInfo.home.containsBlock(loc)
|
||||||
|
.also { result -> debug("area ${it.teamInfo.home} contains $loc is $result") }
|
||||||
|
}
|
||||||
|
.reduce { a, b -> a || b }
|
||||||
|
if (!isHome) return@addRuleFirst MatchResult.DENY
|
||||||
|
val isSelf = team.teamInfo.home.containsBlock(loc)
|
||||||
|
if ((actionType == PLACE) xor isSelf) MatchResult.ALLOW else MatchResult.DENY
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue