finish rule match part

This commit is contained in:
tony_all 2023-06-21 16:22:42 +08:00
parent 45629b0d1b
commit 9f5f657ea1
No known key found for this signature in database
GPG Key ID: 508C1C0A78B379C5
3 changed files with 1374 additions and 33 deletions

File diff suppressed because it is too large Load Diff

View File

@ -54,8 +54,8 @@ class Game(
timer.startTimer()
timer.submitEvent("wall_fall", Duration.ofMinutes(1)) {
broadcast { it.sendLang("game_wall_fall") }
placeBreakRule.addRule("allow_center_wall") { _, _, loc, _ ->
map.wall.contains(loc)
placeBreakRule.addRuleLast("allow_center_wall") { (_, _, loc, _) ->
if (map.wall.contains(loc)) GamePlaceBreakRule.MatchResult.ALLOW else GamePlaceBreakRule.MatchResult.DEFAULT
}
submit {
map.wall.forBlocksInArea().forEach {

View File

@ -2,29 +2,40 @@ package cc.maxmc.blastingcrisis.game
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.BREAK
import cc.maxmc.blastingcrisis.game.GamePlaceBreakRule.ActionType.PLACE
import cc.maxmc.blastingcrisis.misc.EnhancedLinkedList
import cc.maxmc.blastingcrisis.misc.debug
import org.bukkit.Location
import org.bukkit.entity.Player
import taboolib.library.xseries.XMaterial
typealias PlaceBreakRule = (GamePlaceBreakRule.GamePlaceBreakEvent) -> GamePlaceBreakRule.MatchResult
@Suppress("unused") // API
class GamePlaceBreakRule(val game: Game) {
enum class ActionType {
PLACE,
BREAK
}
enum class PlacePosition {
FIRST,
LAST
enum class MatchResult {
DEFAULT,
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 {
// match rules
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")
return true
return result == MatchResult.ALLOW
}
}
@ -32,10 +43,7 @@ class GamePlaceBreakRule(val game: Game) {
return false
}
fun addRule(
name: String,
rule: (player: Player, actionType: ActionType, loc: Location, type: XMaterial) -> Boolean
) {
private fun recordRule(name: String, rule: PlaceBreakRule) {
if (rules.containsKey(name)) {
throw IllegalArgumentException("Rule $name already exists.")
}
@ -43,43 +51,80 @@ class GamePlaceBreakRule(val game: Game) {
rules[name] = rule
}
fun loadDefaultRule() {
// allow tnt in enemy's home
addRule("allow_tnt_conditional") { player, actionType, loc, type ->
if (type != XMaterial.TNT) return@addRule false
val team = player.team ?: return@addRule false
val isHome = game.teams
.map {
it.teamInfo.home.containsBlock(loc)
.also { result -> debug("area ${it.teamInfo.home} contains $loc is $result") }
fun addRuleLast(
name: String,
rule: PlaceBreakRule
) {
recordRule(name, rule)
rulesPriority.addLast(name)
}
.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
addRule("allow_mine") { _, _, loc, _ ->
game.map.teams.flatMap {
addRuleLast("allow_mine") { (_, _, loc, _) ->
val result = game.map.teams.flatMap {
it.sides + it.mine
}.map {
it.containsBlock(loc)
}.reduce { a, b -> a || b }
if (result) MatchResult.ALLOW else MatchResult.DEFAULT
}
// allow enemy wall
addRule("allow_wall_conditional") { player, actionType, loc, _ ->
val team = player.team ?: return@addRule false
addRuleLast("allow_wall_conditional") { (player, actionType, loc, _) ->
val team = player.team ?: return@addRuleLast MatchResult.DENY
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
if (!isWall) return@addRuleLast MatchResult.DEFAULT
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
}
}
}