Skip to content

Commit a5aa804

Browse files
committed
feat: implement SurfBukkitNmsLootTableBridge and its implementation for custom loot table handling
1 parent c330e8a commit a5aa804

5 files changed

Lines changed: 116 additions & 2 deletions

File tree

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
77
javaVersion=21
88
mcVersion=1.21.4
99
group=dev.slne.surf
10-
version=1.21.4-2.18.0-SNAPSHOT
10+
version=1.21.4-2.19.0-SNAPSHOT
1111
relocationPrefix=dev.slne.surf.surfapi.libs

surf-api-bukkit/surf-api-bukkit-api/api/surf-api-bukkit-api.api

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,6 +1257,19 @@ public final class dev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsIte
12571257
public static final fun getItemBridge ()Ldev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsItemBridge;
12581258
}
12591259

1260+
public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsLootTableBridge {
1261+
public static final field Companion Ldev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsLootTableBridge$Companion;
1262+
public abstract fun getDifferentLootTable (Lorg/bukkit/entity/LivingEntity;Lorg/bukkit/damage/DamageSource;Lorg/bukkit/entity/EntityType;Z)Ljava/util/Collection;
1263+
}
1264+
1265+
public final class dev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsLootTableBridge$Companion {
1266+
public final fun getInstance ()Ldev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsLootTableBridge;
1267+
}
1268+
1269+
public final class dev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsLootTableBridgeKt {
1270+
public static final fun getNmsLootTableBridge ()Ldev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsLootTableBridge;
1271+
}
1272+
12601273
public abstract interface class dev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsNbtBridge {
12611274
public static final field Companion Ldev/slne/surf/surfapi/bukkit/api/nms/bridges/SurfBukkitNmsNbtBridge$Companion;
12621275
public abstract fun getNbtString (Lorg/bukkit/inventory/ItemStack;Ljava/lang/String;)Ljava/lang/String;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package dev.slne.surf.surfapi.bukkit.api.nms.bridges
2+
3+
import dev.slne.surf.surfapi.bukkit.api.nms.NmsUseWithCaution
4+
import dev.slne.surf.surfapi.core.api.util.requiredService
5+
import org.bukkit.damage.DamageSource
6+
import org.bukkit.entity.EntityType
7+
import org.bukkit.entity.LivingEntity
8+
import org.bukkit.inventory.ItemStack
9+
10+
@NmsUseWithCaution
11+
interface SurfBukkitNmsLootTableBridge {
12+
13+
fun getDifferentLootTable(
14+
entity: LivingEntity,
15+
damageSource: DamageSource,
16+
replacement: EntityType,
17+
causedByPlayer: Boolean,
18+
): Collection<ItemStack>
19+
20+
companion object {
21+
val instance = requiredService<SurfBukkitNmsLootTableBridge>()
22+
}
23+
}
24+
25+
@NmsUseWithCaution
26+
val nmsLootTableBridge get() = SurfBukkitNmsLootTableBridge.instance
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package dev.slne.surf.surfapi.bukkit.server.impl.nms.bridges
2+
3+
import com.google.auto.service.AutoService
4+
import dev.slne.surf.surfapi.bukkit.api.nms.NmsUseWithCaution
5+
import dev.slne.surf.surfapi.bukkit.api.nms.bridges.SurfBukkitNmsLootTableBridge
6+
import dev.slne.surf.surfapi.bukkit.server.nms.toBukkit
7+
import dev.slne.surf.surfapi.bukkit.server.nms.toNms
8+
import dev.slne.surf.surfapi.core.api.util.emptyObjectList
9+
import dev.slne.surf.surfapi.core.api.util.mutableObjectListOf
10+
import net.minecraft.server.MinecraftServer
11+
import net.minecraft.server.level.ServerLevel
12+
import net.minecraft.world.level.storage.loot.LootParams
13+
import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets
14+
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
15+
import org.bukkit.damage.DamageSource
16+
import org.bukkit.entity.EntityType
17+
import org.bukkit.entity.LivingEntity
18+
import org.bukkit.inventory.ItemStack
19+
import java.util.*
20+
import kotlin.jvm.optionals.getOrNull
21+
22+
@AutoService(SurfBukkitNmsLootTableBridge::class)
23+
@NmsUseWithCaution
24+
class SurfBukkitNmsLootTableBridgeImpl : SurfBukkitNmsLootTableBridge {
25+
override fun getDifferentLootTable(
26+
entity: LivingEntity,
27+
damageSource: DamageSource,
28+
replacement: EntityType,
29+
causedByPlayer: Boolean,
30+
): Collection<ItemStack> {
31+
val lootTableKey =
32+
replacement.toNms().defaultLootTable.getOrNull() ?: return emptyObjectList()
33+
val lootTable =
34+
MinecraftServer.getServer().reloadableRegistries().getLootTable(lootTableKey)
35+
val nmsEntity = entity.toNms()
36+
val nmsDamageSource = damageSource.toNms()
37+
38+
val lootParamsBuilder = LootParams.Builder(nmsEntity.level() as ServerLevel)
39+
.withParameter(LootContextParams.THIS_ENTITY, nmsEntity)
40+
.withParameter(LootContextParams.ORIGIN, nmsEntity.position())
41+
.withParameter(LootContextParams.DAMAGE_SOURCE, nmsDamageSource)
42+
.withOptionalParameter(LootContextParams.ATTACKING_ENTITY, nmsDamageSource.entity)
43+
.withOptionalParameter(
44+
LootContextParams.DIRECT_ATTACKING_ENTITY,
45+
nmsDamageSource.directEntity
46+
)
47+
48+
val lastHurtByPlayer = nmsEntity.lastHurtByPlayer
49+
if (causedByPlayer && lastHurtByPlayer != null) {
50+
lootParamsBuilder.withParameter(LootContextParams.LAST_DAMAGE_PLAYER, lastHurtByPlayer)
51+
.withLuck(lastHurtByPlayer.luck)
52+
}
53+
54+
val lootParams = lootParamsBuilder.create(LootContextParamSets.ENTITY)
55+
return lootTable.getRandomItems(lootParams, nmsEntity.lootTableSeed)
56+
.mapTo(mutableObjectListOf()) { it.toBukkit() }
57+
}
58+
}

surf-api-bukkit/surf-api-bukkit-server/src/main/kotlin/dev/slne/surf/surfapi/bukkit/server/nms/nms-extensions.kt

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import io.papermc.paper.math.FinePosition
1010
import io.papermc.paper.math.Position
1111
import net.minecraft.core.BlockPos
1212
import net.minecraft.network.chat.Component
13+
import net.minecraft.server.level.ServerLevel
1314
import net.minecraft.server.level.ServerPlayer
1415
import net.minecraft.world.entity.Display
1516
import net.minecraft.world.inventory.MenuType
@@ -21,18 +22,28 @@ import net.minecraft.world.level.block.entity.SignText
2122
import net.minecraft.world.phys.Vec3
2223
import org.bukkit.Material
2324
import org.bukkit.Server
25+
import org.bukkit.World
2426
import org.bukkit.block.BlockState
2527
import org.bukkit.block.data.BlockData
2628
import org.bukkit.craftbukkit.CraftServer
29+
import org.bukkit.craftbukkit.CraftWorld
2730
import org.bukkit.craftbukkit.block.CraftBlockState
2831
import org.bukkit.craftbukkit.block.data.CraftBlockData
32+
import org.bukkit.craftbukkit.damage.CraftDamageSource
33+
import org.bukkit.craftbukkit.entity.CraftEntity
34+
import org.bukkit.craftbukkit.entity.CraftEntityType
35+
import org.bukkit.craftbukkit.entity.CraftLivingEntity
2936
import org.bukkit.craftbukkit.entity.CraftPlayer
3037
import org.bukkit.craftbukkit.inventory.CraftItemStack
3138
import org.bukkit.craftbukkit.inventory.CraftItemType
3239
import org.bukkit.craftbukkit.util.Commodore
3340
import org.bukkit.craftbukkit.util.CraftMagicNumbers
41+
import org.bukkit.damage.DamageSource
3442
import org.bukkit.entity.Display.Billboard
43+
import org.bukkit.entity.Entity
44+
import org.bukkit.entity.EntityType
3545
import org.bukkit.entity.ItemDisplay.ItemDisplayTransform
46+
import org.bukkit.entity.LivingEntity
3647
import org.bukkit.entity.Player
3748
import org.bukkit.event.inventory.InventoryType
3849
import org.bukkit.inventory.ItemStack
@@ -110,4 +121,10 @@ fun Component.toBukkit(): AdventureComponent = PaperAdventure.asAdventure(this)
110121

111122
fun Server.toCraft() = this as CraftServer
112123
val craftServer: CraftServer get() = server.toCraft()
113-
val commodore: Commodore get() = CraftMagicNumbers.INSTANCE.commodore
124+
val commodore: Commodore get() = CraftMagicNumbers.INSTANCE.commodore
125+
126+
fun EntityType.toNms(): net.minecraft.world.entity.EntityType<*> = CraftEntityType.bukkitToMinecraft(this)
127+
fun World.toNms(): ServerLevel = (this as CraftWorld).handle
128+
fun Entity.toNms(): net.minecraft.world.entity.Entity = (this as CraftEntity).handle
129+
fun LivingEntity.toNms(): net.minecraft.world.entity.LivingEntity = (this as CraftLivingEntity).handle
130+
fun DamageSource.toNms(): net.minecraft.world.damagesource.DamageSource = (this as CraftDamageSource).handle

0 commit comments

Comments
 (0)