Skip to content

Commit 3077233

Browse files
committed
autosmelt ability
1 parent dffca62 commit 3077233

File tree

7 files changed

+164
-0
lines changed

7 files changed

+164
-0
lines changed

Diff for: gradle.properties

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ port_lib_modules = \
4242
entity,\
4343
extensions,\
4444
items,\
45+
loot,\
4546
lazy_registration,\
4647
level_events,\
4748
mixin_extensions,\

Diff for: src/main/kotlin/dev/sterner/VoidBound.kt

+7
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package dev.sterner
22

3+
import com.mojang.serialization.Codec
34
import com.sammy.malum.MalumMod
45
import com.sammy.malum.MalumModClient
56
import dev.emi.trinkets.api.client.TrinketRendererRegistry
67
import dev.sterner.client.VoidBoundModelLoaderPlugin
78
import dev.sterner.client.renderer.HallowedMonocleRenderer
89
import dev.sterner.client.renderer.WandItemRenderer
910
import dev.sterner.client.screen.OsmoticEnchanterScreen
11+
import dev.sterner.common.VoidBoundLootModifier
1012
import dev.sterner.listener.EnchantSpiritDataReloadListenerFabricImpl
1113
import dev.sterner.registry.*
14+
import io.github.fabricators_of_create.porting_lib.loot.IGlobalLootModifier
15+
import io.github.fabricators_of_create.porting_lib.loot.PortingLibLoot
16+
import io.github.fabricators_of_create.porting_lib.util.RegistryObject
1217
import net.fabricmc.api.ClientModInitializer
1318
import net.fabricmc.api.ModInitializer
1419
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap
@@ -29,6 +34,7 @@ object VoidBound : ModInitializer, ClientModInitializer {
2934
const val modid: String = "voidbound"
3035
private val logger = LoggerFactory.getLogger(modid)
3136

37+
3238
override fun onInitialize() {
3339
LodestoneLib()
3440
MalumMod()
@@ -48,6 +54,7 @@ object VoidBound : ModInitializer, ClientModInitializer {
4854
VoidBoundMenuTypeRegistry.MENU_TYPES.register()
4955
VoidBoundStructureRegistry.STRUCTURES.register()
5056
VoidBoundSoundEvents.SOUNDS.register()
57+
VoidBoundLootModifier.MODIFIERS.register()
5158

5259
VoidBoundCreativeTabRegistry.init()
5360
VoidBoundEvents.init()

Diff for: src/main/kotlin/dev/sterner/api/VoidBoundApi.kt

+4
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,8 @@ object VoidBoundApi {
193193
}
194194
}
195195
}
196+
197+
fun hasItemAbility(stack: ItemStack, ability: ItemAbility): Boolean {
198+
return !getItemAbility(stack).none { it.itemAbility == ability }
199+
}
196200
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package dev.sterner.common
2+
3+
import com.google.common.base.Supplier
4+
import com.google.common.cache.Cache
5+
import com.google.common.cache.CacheBuilder
6+
import com.mojang.serialization.Codec
7+
import com.mojang.serialization.codecs.RecordCodecBuilder
8+
import dev.sterner.VoidBound
9+
import dev.sterner.api.VoidBoundApi
10+
import dev.sterner.api.item.ItemAbility
11+
import io.github.fabricators_of_create.porting_lib.loot.IGlobalLootModifier
12+
import io.github.fabricators_of_create.porting_lib.loot.LootModifier
13+
import io.github.fabricators_of_create.porting_lib.loot.LootTableIdCondition
14+
import io.github.fabricators_of_create.porting_lib.loot.PortingLibLoot
15+
import io.github.fabricators_of_create.porting_lib.util.LazyRegistrar
16+
import io.github.fabricators_of_create.porting_lib.util.RegistryObject
17+
import it.unimi.dsi.fastutil.objects.ObjectArrayList
18+
import net.minecraft.world.SimpleContainer
19+
import net.minecraft.world.item.Item
20+
import net.minecraft.world.item.ItemStack
21+
import net.minecraft.world.item.crafting.RecipeType
22+
import net.minecraft.world.item.crafting.SmeltingRecipe
23+
import net.minecraft.world.level.storage.loot.LootContext
24+
import net.minecraft.world.level.storage.loot.parameters.LootContextParams
25+
import net.minecraft.world.level.storage.loot.predicates.LootItemCondition
26+
import net.minecraft.world.level.storage.loot.predicates.LootItemConditions
27+
import java.util.*
28+
29+
30+
class VoidBoundLootModifier(conditionsIn: Array<out LootItemCondition>?) : LootModifier(conditionsIn) {
31+
32+
33+
34+
override fun codec(): Codec<out IGlobalLootModifier> {
35+
return CODEC.get()
36+
}
37+
38+
override fun doApply(
39+
generatedLoot: ObjectArrayList<ItemStack>?,
40+
context: LootContext?
41+
): ObjectArrayList<ItemStack> {
42+
43+
val stack = context?.getParamOrNull(LootContextParams.TOOL)
44+
if (stack != null && VoidBoundApi.hasItemAbility(stack, ItemAbility.AUTOSMELT)) {
45+
46+
val level = context!!.level
47+
val smeltedItems = generatedLoot?.asSequence()?.map { originalStack ->
48+
val inventory = SimpleContainer(originalStack)
49+
val smeltingRecipe = level.recipeManager.getRecipeFor(RecipeType.SMELTING, inventory, level)
50+
51+
if (smeltingRecipe.isPresent) {
52+
val result = smeltingRecipe.get().assemble(inventory, level.registryAccess())
53+
if (result.count > 0) {
54+
result.count *= originalStack.count
55+
}
56+
result
57+
} else {
58+
originalStack
59+
}
60+
}?.filter { !it.isEmpty }?.toList() ?: emptyList()
61+
62+
return ObjectArrayList(smeltedItems)
63+
}
64+
65+
return generatedLoot ?: ObjectArrayList()
66+
}
67+
68+
companion object {
69+
70+
val MODIFIERS = LazyRegistrar.create(PortingLibLoot.GLOBAL_LOOT_MODIFIER_SERIALIZERS_KEY, VoidBound.modid)
71+
72+
val CODEC: Supplier<Codec<VoidBoundLootModifier>> = Supplier {
73+
RecordCodecBuilder.create { inst ->
74+
codecStart(inst).apply(inst, ::VoidBoundLootModifier)
75+
}
76+
}
77+
78+
79+
val AUTOSMELT = MODIFIERS.register("autosmelt", CODEC)
80+
}
81+
}

Diff for: src/main/kotlin/dev/sterner/registry/VoidBoundEvents.kt

+59
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package dev.sterner.registry
33
import com.google.common.collect.Multimap
44
import com.sammy.malum.common.events.MalumCodexEvents
55
import dev.sterner.api.ClientTickHandler
6+
import dev.sterner.api.VoidBoundApi
7+
import dev.sterner.api.item.ItemAbility
68
import dev.sterner.client.event.*
79
import dev.sterner.common.components.VoidBoundPlayerComponent
810
import dev.sterner.common.components.VoidBoundWorldComponent
911
import dev.sterner.common.item.tool.TidecutterItem
1012
import dev.sterner.common.item.tool.UpgradableTool
1113
import io.github.fabricators_of_create.porting_lib.event.common.BlockEvents
14+
import io.github.fabricators_of_create.porting_lib.event.common.BlockEvents.BlockBreak
1215
import net.fabricmc.api.EnvType
1316
import net.fabricmc.api.Environment
1417
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
@@ -17,12 +20,19 @@ import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents
1720
import net.fabricmc.fabric.api.event.player.UseBlockCallback
1821
import net.fabricmc.fabric.api.event.player.UseEntityCallback
1922
import net.fabricmc.fabric.api.item.v1.ModifyItemAttributeModifiersCallback
23+
import net.fabricmc.fabric.api.loot.v2.LootTableEvents
24+
import net.minecraft.server.level.ServerLevel
2025
import net.minecraft.world.entity.EquipmentSlot
2126
import net.minecraft.world.entity.ai.attributes.Attribute
2227
import net.minecraft.world.entity.ai.attributes.AttributeModifier
2328
import net.minecraft.world.entity.ai.attributes.Attributes
2429
import net.minecraft.world.item.ItemStack
30+
import net.minecraft.world.item.crafting.RecipeType
31+
import net.minecraft.world.item.crafting.SmeltingRecipe
32+
import net.minecraft.world.level.block.Block
33+
import net.minecraft.world.level.block.entity.FurnaceBlockEntity
2534
import java.util.*
35+
import io.github.fabricators_of_create.porting_lib.loot.LootModifier;
2636

2737

2838
object VoidBoundEvents {
@@ -33,6 +43,55 @@ object VoidBoundEvents {
3343
BlockEvents.BLOCK_BREAK.register(VoidBoundWorldComponent.Companion::removeWard)
3444
BlockEvents.BLOCK_BREAK.register(TidecutterItem.Companion::breakBlock)
3545

46+
BlockEvents.BLOCK_BREAK.register { event ->
47+
val player = event?.player
48+
49+
if (player?.level() is ServerLevel) {
50+
val level = player.level() as? ServerLevel
51+
val pos = event.pos
52+
if (VoidBoundApi.hasItemAbility(player.mainHandItem, ItemAbility.AUTOSMELT) && false) {
53+
val blockState = level!!.getBlockState(pos)
54+
val blockEntity = level.getBlockEntity(pos)
55+
56+
// Get the list of dropped items from the block
57+
val drops: MutableList<ItemStack> = Block.getDrops(blockState, level, pos, blockEntity)
58+
59+
// Retrieve all smelting recipes
60+
val allSmeltingRecipes = level.recipeManager.getAllRecipesFor(RecipeType.SMELTING)
61+
62+
// Create a map of ItemStack to its smelted result
63+
val smeltedResults = mutableMapOf<ItemStack, ItemStack>()
64+
65+
// Populate the smeltedResults map
66+
for (recipe in allSmeltingRecipes) {
67+
if (recipe is SmeltingRecipe) {
68+
for (ingredient in recipe.ingredients) {
69+
val smeltedResult = recipe.getResultItem(level.registryAccess())
70+
for (item in drops) {
71+
if (ingredient.test(item)) {
72+
smeltedResults[item] = smeltedResult
73+
}
74+
}
75+
}
76+
}
77+
}
78+
79+
// Drop smelted items instead of original items
80+
for ((item, smeltedResult) in smeltedResults) {
81+
// Remove the original item from the list
82+
drops.remove(item)
83+
// Drop the smelted result
84+
Block.popResource(level, pos, smeltedResult)
85+
}
86+
87+
// Drop the original items that didn't have a smelting recipe
88+
for (item in drops) {
89+
Block.popResource(level, pos, item)
90+
}
91+
}
92+
}
93+
}
94+
3695
/**
3796
* Add extra damage to UpgradableTools when it has extra damage
3897
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"entries": [
3+
"voidbound:autosmelt"
4+
],
5+
"replace": false
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"type": "voidbound:autosmelt",
3+
"conditions": [
4+
5+
]
6+
}

0 commit comments

Comments
 (0)