I realized I may get more people to use this plugin if I add more helpful example scripts. All those scripts are ready to use, but I encourage you to edit them to get the best results for your desired server experience.
I plan on adding more scripts somewhat regularly. This is the first one.
val staffMembers = listOf(
"KitCrafty",
"Notch"
)
onPlayerJoin {
if (player.name in staffMembers) {
setMessage("&2The legendary ${player.name} has joined the server!".t)
}
}
You can change the message as you like, with all the normal Minecraft color codes. Adding new players in the list should be self-explanatory.
That’s it for today, I appreciate suggestions from you guys.
This is a pretty cool use for Kotlin! Have you done any testing to see how well a KtScript performs when compared to the same thing implemented in a compiled plugin, or does this work in a similar way to Kotlin itself under normal conditions?
I haven’t done any benchmarking yet. I guess the only performance hit is the compiling itself, it is done at startup, at reload and when scripts are modified/deleted/created. The Kotlin compiler is under steady improvement.
Once compiled, it is just another loaded JVM class. Ofc the kotlin runtime and stdlib is another added layer, but this “issue” is present in any other real compiled Kotlin plugin/program/app. The Kotlin compiler itself and the JVM runtime inline many things.
I think I could simplify more things with Kotlin’s DSL, like scheduling tasks. But I don’t want to cover the SpongeAPI completly lol.
Btw: One thing I am not very happy with is NMS code. I haven’t been able to find the correct classloader and import them properly at runtime. So NMS stuff isn’t possible yet. Maybe that will change once I migrate from FastClasspathLoader to ClassGraph.
val SHOUTING_PREFIX = "!"
registerListener<MessageChannelEvent.Chat> {
val isShouting = rawMessage.toPlain().startsWith(SHOUTING_PREFIX)
val range = if (isShouting) 100 else 50
val playerLoc = causingPlayer.location
val targetedPlayers = playerLoc.extent
.getNearbyEntities(playerLoc.position, range.toDouble())
.mapNotNull { it as? Player }
setChannel(MessageChannel.fixed(targetedPlayers))
formatter.setBody(rawMessage.toPlain().removePrefix(SHOUTING_PREFIX).toText())
val prefix = if (isShouting) "&7[&aShout&7] ".t else "&7[&aLocal&7] ".t
formatter.setHeader(prefix + formatter.header.toText())
}
This is a roleplay chat system which limits the range players can “understand” each other. This was suggested by @Louie_Beltranhere.
By default players can chat with each other as in vanilla Minecraft within 50 blocks. To extend that range to 100 a ! has to be appending before the message.
Modify the script as you like, change the shouting prefix, the range or anything else. Let me know if you have any questions.
FoxGuard doesn’t seem to have a public API, but other plugins (or a script) can still interact with FoxGuard nevertheless. Though you would have to dig through the code and find the respective methods for getting a region and then checking if it is inside that. There’s no built-in shortcut for that in KtSkript.
So I advise you to get familiar with FoxGuard’s code and how to get a region/all regions and then checking if some position is inside a region. Maybe you will get help from the developer.
It may be easier for you to just check if some position is inside a hard coded area, if that would work for you.
It would look like this:
val pos = v3(3, 1, 3)
val area = v3(0, 0, 0)..v3(10, 10, 10)
if (pos in area) {
println("pos really is in area!")
}
val replacements = mapOf(
"minecraft:log" to "minecraft:diamond",
"minecraft:stone" to "minecraft:gold_ingot"
).mapValues { (_, itemTypeId) ->
ItemStack.of(Sponge.getRegistry().getType(ItemType::class.java, itemTypeId).get(), 1).createSnapshot()
}
registerListener<SpawnEntityEvent> {
entities
.filter { it is Item }
.forEach { item ->
if (context.get(EventContextKeys.SPAWN_TYPE).orNull() == SpawnTypes.DROPPED_ITEM) {
val brokenBlockSnapshot = context.get(EventContextKeys.BLOCK_HIT).orNull() ?: return@forEach
val replacement = replacements[brokenBlockSnapshot.state.type.id] ?: return@forEach
item.tryOffer(Keys.REPRESENTED_ITEM, replacement)
}
}
}
This script can replace block drops with other items. The replacements can be defined at the top.
The script can definitely be worked on to support custom data, other variants of item drops or even add more requirements (like having to have a special item in the inventory to produce a different drop).
Hey can someone help me out? I need a sckript that disables all of my mod messages that my mods bring in, when they join all that junk pops up in chat, PLEASE HELP