Skip to content

Commit

Permalink
build
Browse files Browse the repository at this point in the history
  • Loading branch information
mrsterner committed Mar 6, 2025
1 parent 13d49f9 commit 132d434
Show file tree
Hide file tree
Showing 35 changed files with 1,577 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/main/kotlin/dev/sterner/VoidBound.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ object VoidBound : ModInitializer {
VoidBoundParticleTypeRegistry.PARTICLES.register()
VoidBoundMemoryTypeRegistry.MEMORY_TYPES.register()
VoidBoundSensorTypeRegistry.SENSOR_TYPES.register()
VoidBoundWandFocusRegistry.WAND_FOCI.register()
VoidBoundRiftTypeRegistry.RIFT_TYPES.register()
VoidBoundMenuTypeRegistry.MENU_TYPES.register()
VoidBoundStructureRegistry.STRUCTURES.register()
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/dev/sterner/VoidBoundClient.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.sterner.VoidBound.id
import dev.sterner.client.VoidBoundModelLoaderPlugin
import dev.sterner.client.renderer.HallowedMonocleRenderer
import dev.sterner.client.renderer.IchoriumCircletRenderer
import dev.sterner.client.renderer.WandItemRenderer
import dev.sterner.client.screen.OsmoticEnchanterScreen
import dev.sterner.common.ItemAbilityHandler
import dev.sterner.registry.*
Expand Down Expand Up @@ -46,6 +47,15 @@ object VoidBoundClient : ClientModInitializer {
return@register v
}

BuiltinItemRendererRegistry.INSTANCE.register(
VoidBoundItemRegistry.HALLOWED_GOLD_CAPPED_RUNEWOOD_WAND.get(),
WandItemRenderer("hallowed_gold_capped_runewood_wand")
)
BuiltinItemRendererRegistry.INSTANCE.register(
VoidBoundItemRegistry.SOUL_STAINED_STEEL_CAPPED_SOULWOOD_WAND.get(),
WandItemRenderer("soul_stained_steel_capped_soulwood_wand")
)

BlockRenderLayerMap.INSTANCE.putBlocks(
RenderType.cutout(),
VoidBoundBlockRegistry.TEAR_OF_ENDER.get(),
Expand Down
166 changes: 166 additions & 0 deletions src/main/kotlin/dev/sterner/api/VoidBoundApi.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
package dev.sterner.api

import com.sammy.malum.client.VoidRevelationHandler
import com.sammy.malum.common.container.WeaversWorkbenchContainer.component
import com.sammy.malum.core.systems.recipe.SpiritWithCount
import dev.sterner.api.item.ItemAbility
import dev.sterner.api.item.ItemAbilityWithLevel
import dev.sterner.listener.EnchantSpiritDataReloadListener
import dev.sterner.registry.VoidBoundComponentRegistry
import dev.sterner.registry.VoidBoundItemRegistry
import net.minecraft.client.Minecraft
import net.minecraft.core.BlockPos
import net.minecraft.core.GlobalPos
import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.network.chat.Component
import net.minecraft.world.entity.EquipmentSlot
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.enchantment.Enchantment
import net.minecraft.world.level.Level
import team.lodestar.lodestone.helpers.TrinketsHelper

object VoidBoundApi {

/**
* Returns true if a client player has the hallowed goggles or monocle equipped
*/
fun hasGoggles(): Boolean {
val player = Minecraft.getInstance().player
if (player != null) {
val bl = TrinketsHelper.hasTrinketEquipped(player, VoidBoundItemRegistry.HALLOWED_MONOCLE.get())
val bl2 = Minecraft.getInstance().player!!.getItemBySlot(EquipmentSlot.HEAD)
.`is`(
VoidBoundItemRegistry.HALLOWED_GOGGLES.get()
)
return bl || bl2
}
return false
}

/**
* Returns true if a player has the hallowed goggles or monocle equipped
*/
fun hasGoggles(player: Player): Boolean {
val bl = TrinketsHelper.hasTrinketEquipped(player, VoidBoundItemRegistry.HALLOWED_MONOCLE.get())
val bl2 = Minecraft.getInstance().player!!.getItemBySlot(EquipmentSlot.HEAD)
.`is`(
VoidBoundItemRegistry.HALLOWED_GOGGLES.get()
)
return bl || bl2
}

/**
* Returns how many spirits of each kind a enchantment is worth for the osmotic enchanter
*/
fun getSpiritFromEnchant(enchantment: Enchantment, level: Int): List<SpiritWithCount> {

val reg = BuiltInRegistries.ENCHANTMENT.getKey(enchantment)
val list = EnchantSpiritDataReloadListener.ENCHANTING_DATA[reg]
val out = mutableListOf<SpiritWithCount>()
if (list != null) {
for (spiritIn in list.spirits) {
out.add(SpiritWithCount(spiritIn.type, spiritIn.count * level))
}
}

return out
}

/**
* Returns false if the block being broken is warded by another player
*/
fun canPlayerBreakBlock(level: Level, player: Player, blockPos: BlockPos): Boolean {
val comp = VoidBoundComponentRegistry.VOID_BOUND_WORLD_COMPONENT.get(level)
if (comp.isEmpty()) {
return true
}

return !comp.isPosBoundToAnotherPlayer(player, GlobalPos.of(player.level().dimension(), blockPos))
}

/**
* Returns false if the block being broken is warded by any player
*/
fun canBlockBreak(level: Level, blockPos: BlockPos): Boolean {
val comp = VoidBoundComponentRegistry.VOID_BOUND_WORLD_COMPONENT.get(level)
if (comp.isEmpty()) {
return true
}

if (comp.hasBlockPos(GlobalPos.of(level.dimension(), blockPos))) {
return false
}
return true
}

fun hasTearKnowledgeClient(): Boolean {
val player = Minecraft.getInstance().player
if (player != null) {
val comp = VoidBoundComponentRegistry.VOID_BOUND_REVELATION_COMPONENT.get(player)
return comp.isTearKnowledgeComplete()
}
return false
}

fun addThought(player: Player, text: Component, duration: Int = 20 * 5){
VoidBoundComponentRegistry.VOID_BOUND_REVELATION_COMPONENT.maybeGet(player).ifPresent {
it.addThought(text, duration, 20 * 5)
}
}

fun getItemAbility(stack: ItemStack): List<ItemAbilityWithLevel> {
val abilities = mutableListOf<ItemAbilityWithLevel>()
val tag = stack.tag ?: return abilities // Return empty if no NBT

val abilitiesTag = tag.getList("Abilities", 10) // 10 is the NBT type for CompoundTag
for (i in 0 until abilitiesTag.size) {
val abilityTag = abilitiesTag.getCompound(i)
val ability = ItemAbilityWithLevel.readNbt(abilityTag)
abilities.add(ability)
}
return abilities
}

// Function to add an ItemAbilityWithLevel to an ItemStack's NBT
fun addItemAbility(stack: ItemStack, abilityWithLevel: ItemAbilityWithLevel) {
val tag = stack.orCreateTag // Ensures the stack has NBT
val abilitiesTag = tag.getList("Abilities", 10) // Fetch or create list

// Check if ability already exists, if so, skip adding a duplicate
for (i in 0 until abilitiesTag.size) {
val abilityTag = abilitiesTag.getCompound(i)
val existingAbility = ItemAbilityWithLevel.readNbt(abilityTag)
if (existingAbility.itemAbility == abilityWithLevel.itemAbility) {
return // Ability already exists, exit without adding
}
}

// Add new ability
abilitiesTag.add(abilityWithLevel.writeNbt())
tag.put("Abilities", abilitiesTag)
}

// Function to modify the level of an existing ItemAbility in NBT
fun modifyItemAbilityLevel(stack: ItemStack, itemAbility: ItemAbility, newLevel: Int) {
val tag = stack.tag ?: return // No NBT, nothing to modify
val abilitiesTag = tag.getList("Abilities", 10)

// Find the ability and modify its level
for (i in 0 until abilitiesTag.size) {
val abilityTag = abilitiesTag.getCompound(i)
val ability = ItemAbilityWithLevel.readNbt(abilityTag)
if (ability.itemAbility == itemAbility) {
// Modify the level and update the NBT
abilityTag.putInt("Level", newLevel)
abilitiesTag[i] = abilityTag // Replace the modified ability in the list
tag.put("Abilities", abilitiesTag)
return
}
}
}

fun hasItemAbility(stack: ItemStack, ability: ItemAbility): Boolean {
return !getItemAbility(stack).none { it.itemAbility == ability }
}
}
24 changes: 24 additions & 0 deletions src/main/kotlin/dev/sterner/api/item/ItemAbilityWithLevel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package dev.sterner.api.item

import net.minecraft.nbt.CompoundTag

data class ItemAbilityWithLevel(val itemAbility: ItemAbility, val level: Int) {

fun writeNbt(): CompoundTag {
val compoundTag = CompoundTag()
compoundTag.putString("ItemAbility", itemAbility.name)
compoundTag.putInt("Level", level)
return compoundTag
}

companion object {
fun readNbt(nbt: CompoundTag): ItemAbilityWithLevel {
val ability = ItemAbility.valueOf(nbt.getString("ItemAbility"))
val level = nbt.getInt("Level")

return ItemAbilityWithLevel(ability, level)
}
}


}
21 changes: 21 additions & 0 deletions src/main/kotlin/dev/sterner/api/wand/IWandFocus.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package dev.sterner.api.wand

import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.phys.HitResult

interface IWandFocus {

fun onFocusRightClick(stack: ItemStack, level: Level, player: Player, hitResult: HitResult) {

}

fun onUsingFocusTick(stack: ItemStack, level: Level, player: Player) {

}

fun onPlayerStopUsingFocus(stack: ItemStack, level: Level, player: Player) {

}
}
86 changes: 86 additions & 0 deletions src/main/kotlin/dev/sterner/client/renderer/WandItemRenderer.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package dev.sterner.client.renderer

import com.mojang.blaze3d.vertex.PoseStack
import dev.sterner.VoidBound
import dev.sterner.client.model.FocusModel
import dev.sterner.client.model.WandItemModel
import dev.sterner.registry.VoidBoundWandFocusRegistry
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry.DynamicItemRenderer
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderType
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemDisplayContext
import net.minecraft.world.item.ItemStack


class WandItemRenderer(val texture: String) : DynamicItemRenderer {

var model: WandItemModel? = null

var focusModel: FocusModel? = null


override fun render(
stack: ItemStack,
mode: ItemDisplayContext,
poseStack: PoseStack,
vertexConsumers: MultiBufferSource,
light: Int,
overlay: Int
) {

if (model == null) {
model = WandItemModel(Minecraft.getInstance().entityModels.bakeLayer(WandItemModel.LAYER_LOCATION))
}
if (focusModel == null) {
focusModel = FocusModel(Minecraft.getInstance().entityModels.bakeLayer(FocusModel.LAYER_LOCATION))
}

poseStack.pushPose()

poseStack.translate(0f, 0.75f, 0f)

poseStack.translate(0.5, 0.65, 0.5)

poseStack.scale(1f, -1f, -1f)
model?.renderToBuffer(
poseStack,
vertexConsumers.getBuffer(RenderType.entityTranslucent(VoidBound.id("textures/item/$texture.png"))),
light,
overlay,
1f,
1f,
1f,
1f
)

val focusName = stack.tag?.getString("FocusName")
val focus = VoidBoundWandFocusRegistry.WAND_FOCUS.getOptional(focusName?.let { ResourceLocation.tryParse(it) })
if (focus.isPresent) {

focusModel?.renderToBuffer(
poseStack,
vertexConsumers.getBuffer(
RenderType.entityTranslucent(
VoidBound.id(
"textures/models/${
ResourceLocation.tryParse(
focusName!!
)!!.path
}.png"
)
)
),
light,
overlay,
1f,
1f,
1f,
1f
)
}

poseStack.popPose()
}
}
Loading

0 comments on commit 132d434

Please sign in to comment.