Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ object VeinMiningHUD {
for ((notice, alpha) in getActiveNotices()) {
val color = (alpha * 255).toInt() shl 24 or 0xFFFFFF
val text = when(VeinMiningNoticeType.fromId(notice.noticeType)) {
VeinMiningNoticeType.TASK_BLOCKED -> I18n.format("bandit.message.task-blocked")
VeinMiningNoticeType.TASK_STARTING -> I18n.format("bandit.message.task-starting")
VeinMiningNoticeType.TASK_HALT_HINT -> I18n.format("bandit.message.task-halt-hint")
VeinMiningNoticeType.TASK_STOP_KEY_RELEASE -> I18n.format("bandit.message.task-stop.key-release")
Expand Down
156 changes: 96 additions & 60 deletions src/main/kotlin/cn/elytra/mod/bandit/common/command/BanditCommand.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ object BanditCommand : CommandBase() {

override fun getRequiredPermissionLevel(): Int = 0

override fun canCommandSenderUseCommand(sender: ICommandSender?): Boolean {
return true
}

override fun processCommand(
sender: ICommandSender,
argsArray: Array<String>,
Expand All @@ -36,54 +40,67 @@ object BanditCommand : CommandBase() {
}
}

override fun addTabCompletionOptions(sender: ICommandSender, args: Array<String>): List<String>? {
if (args.isEmpty()) return super.addTabCompletionOptions(sender, args)

val argsList = args.toMutableList()

return when (argsList.removeFirstOrNull()) {
null, "" -> getListOfStringsMatchingLastWord(
args,
"stop",
"help",
"drop_pos",
"drop_timing",
"stop_on_release",
"block-filter",
"executor-generator"
)
class CommandNode(val name: String) {
private val _sub = mutableListOf<CommandNode>()
val sub: List<CommandNode> get() = _sub

"executor-generator", "executor", "block-filter", "filter" -> {
// TODO: add support to names and update this completion
emptyList()
fun sub(vararg nodesOrNames: Any): CommandNode {
nodesOrNames.forEach {
when (it) {
is CommandNode -> _sub.add(it)
is String -> _sub.add(CommandNode(it))
is Iterable<*> -> it.forEach { n -> if (n is String) _sub.add(CommandNode(n)) }
}
}
return this
}

"drop_pos" -> {
getListOfStringsMatchingLastWord(
args,
*getValidEnumValues<DropPosition>().toTypedArray()
)
}
fun complete(args: List<String>): List<String> {
if (args.isEmpty()) return listOf(name)

"drop_timing" -> {
getListOfStringsMatchingLastWord(
args,
*getValidEnumValues<DropTiming>().toTypedArray()
)
}
val head = args.first()
val tail = args.drop(1)

"stop_on_release" -> {
getListOfStringsMatchingLastWord(
args,
"true",
"false"
)
return when {
!name.startsWith(head) -> emptyList()
tail.isEmpty() -> listOf(name)
name == head -> sub.flatMap { it.complete(tail) }
else -> emptyList()
}
}
}

"stop", "help" -> emptyList()

else -> super.addTabCompletionOptions(sender, args)
}
override fun addTabCompletionOptions(sender: ICommandSender, args: Array<String>): List<String> {
val commandTree = listOf(
// Example:
// CommandNode("complex").sub(
// CommandNode("subLevel").sub(
// CommandNode("subLevel2a").sub("foo", "bar"),
// CommandNode("subLevel2b").sub(stringListFun()),
// CommandNode("subLevel2c")
// ),
// ),
CommandNode("stop"),
CommandNode("help"),

CommandNode("stop_on_release").sub("true", "false"),
CommandNode("drop_pos").sub(getValidEnumValues<DropPosition>()),
CommandNode("drop_timing").sub(getValidEnumValues<DropTiming>()),

CommandNode("executor-generator").sub(
ExecutorGeneratorRegistry.all().values.map {
it.getUnlocalizedName().substringAfterLast('.')
}
),
CommandNode("block-filter").sub(
BlockFilterRegistry.all().values.map {
it.getUnlocalizedName().substringAfterLast('.')
}
)
)

return commandTree.flatMap { it.complete(args.toList()) }
}

private fun ICommandSender.withEntityPlayer(block: (EntityPlayerMP) -> Unit) {
Expand All @@ -99,31 +116,40 @@ object BanditCommand : CommandBase() {
strings: MutableList<String>,
) {
sender.withEntityPlayer { p ->
val id = strings.removeFirstOrNull()
if(id == null) {
val raw = strings.removeFirstOrNull()
if(raw == null) {
val execId = p.veinMiningData.veinMiningExecutorId
sender.addChatMessage(
ChatComponentTranslation(
"command.bandit.executor.current",
ChatComponentTranslation("bandit.executor.$execId")
ExecutorGeneratorRegistry.get(execId)?.toChatComponent()
)
)
sender.addChatMessage(ChatComponentTranslation("command.bandit.executor.list"))
ExecutorGeneratorRegistry.all().forEach { id, _ ->
ExecutorGeneratorRegistry.all().forEach { (id, _) ->
sender.addChatMessage(
ChatComponentTranslation(
"command.bandit.executor.list.entry",
id,
ChatComponentTranslation("bandit.executor.$id")
ExecutorGeneratorRegistry.get(id)?.toChatComponent()
)
)
}
} else {
val id = parseInt(sender, id)
val flag = true // TODO: validation
p.veinMiningData.veinMiningExecutorId = id
if(flag) sender.addChatMessage(ChatComponentTranslation("command.bandit.executor.set.ok"))
else sender.addChatMessage(ChatComponentTranslation("command.bandit.executor.set.fail"))
val executorId = ExecutorGeneratorRegistry.resolveExecutorId(raw)

if (executorId == null) {
sender.addChatMessage(ChatComponentTranslation("command.bandit.executor.set.fail"))
return@withEntityPlayer
}

p.veinMiningData.veinMiningExecutorId = executorId
sender.addChatMessage(
ChatComponentTranslation(
"command.bandit.executor.set.ok",
ExecutorGeneratorRegistry.get(executorId)?.toChatComponent()
)
)
}
}
}
Expand All @@ -133,30 +159,40 @@ object BanditCommand : CommandBase() {
strings: MutableList<String>,
) {
sender.withEntityPlayer { p ->
val id = strings.removeFirstOrNull()
if(id == null) {
val raw = strings.removeFirstOrNull()
if(raw == null) {
val filterId = p.veinMiningData.veinMiningBlockFilterId
sender.addChatMessage(
ChatComponentTranslation(
"command.bandit.filter.current",
ChatComponentTranslation("bandit.filter.$filterId")
BlockFilterRegistry.get(filterId)?.toChatComponent()
)
)
sender.addChatMessage(ChatComponentTranslation("command.bandit.filter.list"))
BlockFilterRegistry.all().forEach { id, _ ->
BlockFilterRegistry.all().forEach { (id, _) ->
sender.addChatMessage(
ChatComponentTranslation(
"command.bandit.filter.list.entry",
ChatComponentTranslation("bandit.filter.$filterId")
id,
BlockFilterRegistry.get(id)?.toChatComponent()
)
)
}
} else {
val id = parseInt(sender, id)
val flag = true // TODO: validation
p.veinMiningData.veinMiningBlockFilterId = id
if(flag) sender.addChatMessage(ChatComponentTranslation("command.bandit.filter.set.ok"))
else sender.addChatMessage(ChatComponentTranslation("command.bandit.filter.set.fail"))
val filterId = BlockFilterRegistry.resolveFilterId(raw)

if (filterId == null) {
sender.addChatMessage(ChatComponentTranslation("command.bandit.filter.set.fail"))
return@withEntityPlayer
}

p.veinMiningData.veinMiningBlockFilterId = filterId
sender.addChatMessage(
ChatComponentTranslation(
"command.bandit.filter.set.ok",
BlockFilterRegistry.get(filterId)?.toChatComponent()
)
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ enum class VeinMiningNoticeType(val id: Int) {
* Task completed successfully.
* Mining chain finished naturally and requires statistical processing.
*/
TASK_DONE(6);
TASK_DONE(6),

/**
* Task not start cause there is another vein mining job.
*/
TASK_BLOCKED(7);

companion object {
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,15 @@ data class VeinMiningPlayerData(
// stop precalculate job and continue to start vein mining
TypedJob.JobType.VeinMiningPrecalculating -> currentJob = null
// stop if there is another vein mining job
TypedJob.JobType.VeinMining -> return
TypedJob.JobType.VeinMining -> {
val player = getPlayer()
BanditNetwork.pushSimpleNoticeToClient(player.asMP,
noticeType = VeinMiningNoticeType.TASK_BLOCKED,
fadeDelay = 10,
fadeTicks = 20
)
return
}
}
}

Expand Down Expand Up @@ -352,7 +360,7 @@ data class VeinMiningPlayerData(
"statBlocksMined" to context.statBlocksMined.get(),
"statItemDropped" to context.statItemDropped.values.sum()
),
fadeDelay = 40,
fadeDelay = 100,
fadeTicks = 20
)

Expand Down
20 changes: 20 additions & 0 deletions src/main/kotlin/cn/elytra/mod/bandit/mining/BlockFilterRegistry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,24 @@ object BlockFilterRegistry {
}

fun all(): Map<Int, VeinMiningBlockFilter> = blockFilterMap.toMap()

fun isRegistered(id: Int): Boolean {
return id in blockFilterMap
}

fun getUnlocalizedName(id: Int): String? {
return blockFilterMap[id]?.getUnlocalizedName()
}

fun resolveFilterId(raw: String): Int? {
val key = raw.trim().lowercase()

key.toIntOrNull()?.takeIf(::isRegistered)
?.let { return it }

return blockFilterMap.entries.firstOrNull { (_, filter) ->
val name = filter.getUnlocalizedName().lowercase()
name == key || name.substringAfterLast('.') == key
}?.key
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,24 @@ object ExecutorGeneratorRegistry {
}

fun all(): Map<Int, VeinMiningExecutorGenerator> = executorGeneratorMap.toMap()

fun isRegistered(id: Int): Boolean {
return id in executorGeneratorMap
}

fun getUnlocalizedName(id: Int): String? {
return executorGeneratorMap[id]?.getUnlocalizedName()
}

fun resolveExecutorId(raw: String): Int? {
val key = raw.trim().lowercase()

key.toIntOrNull()?.takeIf(::isRegistered)
?.let { return it }

return executorGeneratorMap.entries.firstOrNull { (_, executor) ->
val name = executor.getUnlocalizedName().lowercase()
name == key || name.substringAfterLast('.') == key
}?.key
}
}
5 changes: 3 additions & 2 deletions src/main/resources/assets/bandit/lang/en_US.lang
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ bandit.block-filter.none=None
bandit.block-filter.match-block=Matching Block
bandit.block-filter.match-block-and-meta=Matching Block and Metadata

bandit.message.task-blocked=§There is another vein mining job.
bandit.message.task-starting=§aStarting Vein Mining task
bandit.message.task-halt-hint=§aYou can type §6/bandit stop §ato halt a ongoing task
bandit.message.task-done=§aVein Mining done! §7Harvested %s §7blocks, and dropped %s §7items.
Expand All @@ -28,12 +29,12 @@ command.bandit.help.3=§6/bandit drop_timing [dropTiming] - §7list or set the t
command.bandit.executor.current=You are currently using %s
command.bandit.executor.list=Possible Executors:
command.bandit.executor.list.entry=%s %s
command.bandit.executor.set.ok=OK!
command.bandit.executor.set.ok=OK! Executor has now been changed to %s.
command.bandit.executor.set.fail=Failed! Possibly it is an invalid id.
command.bandit.filter.current=You are currently using %s
command.bandit.filter.list=Possible Filters:
command.bandit.filter.list.entry=%s %s
command.bandit.filter.set.ok=OK!
command.bandit.filter.set.ok=OK! Filter has now been changed to %s.
command.bandit.filter.set.fail=Failed! Possibly it is an invalid id.
command.bandit.drop_pos=Currently %s, valid values are %s
command.bandit.drop_pos.ok=OK, new value is %s!
Expand Down
5 changes: 3 additions & 2 deletions src/main/resources/assets/bandit/lang/zh_CN.lang
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ bandit.block-filter.none=无
bandit.block-filter.match-block=仅匹配方块
bandit.block-filter.match-block-and-meta=匹配方块和Meta

bandit.message.task-blocked=§a有另一挖掘任务进行中.
bandit.message.task-starting=§a开始连锁挖掘任务
bandit.message.task-halt-hint=§a你可以输入 §6/bandit stop §a来停止正在执行的任务
bandit.message.task-done=§a连锁挖掘完成! §7连锁了 %s §7个方块, 获得 %s §7个掉落物.
Expand All @@ -28,12 +29,12 @@ command.bandit.help.3=§6/bandit drop_timing [掉落物出现时机] - §7列出
command.bandit.executor.current=您当前正在使用 %s
command.bandit.executor.list=可能的执行器:
command.bandit.executor.list.entry=%s %s
command.bandit.executor.set.ok=OK!
command.bandit.executor.set.ok=OK! 执行器更改为 %s.
command.bandit.executor.set.fail=失败了! 可能这是个无效的ID.
command.bandit.filter.current=您当前正在使用 %s
command.bandit.filter.list=可能的过滤器:
command.bandit.filter.list.entry=%s %s
command.bandit.filter.set.ok=OK!
command.bandit.filter.set.ok=OK! 过滤器更改为: %s.
command.bandit.filter.set.fail=失败了! 可能这是个无效的ID.
command.bandit.drop_pos=当前 %s, 有效的值是 %s
command.bandit.drop_pos.ok=OK, 新的值是 %s!
Expand Down