WIP: Port some 1.21.5 things
This commit is contained in:
@@ -226,12 +226,12 @@ val citResewnSourceSet = createIsolatedSourceSet("citresewn", isEnabled = false)
|
||||
val yaclSourceSet = createIsolatedSourceSet("yacl")
|
||||
val explosiveEnhancementSourceSet =
|
||||
createIsolatedSourceSet("explosiveEnhancement", isEnabled = false) // TODO: wait for their port
|
||||
val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender")
|
||||
val wildfireGenderSourceSet = createIsolatedSourceSet("wildfireGender", isEnabled = false)
|
||||
val jadeSourceSet = createIsolatedSourceSet("jade")
|
||||
val modmenuSourceSet = createIsolatedSourceSet("modmenu")
|
||||
val reiSourceSet = createIsolatedSourceSet("rei")
|
||||
val reiSourceSet = createIsolatedSourceSet("rei", isEnabled = false)
|
||||
val moulconfigSourceSet = createIsolatedSourceSet("moulconfig")
|
||||
val customTexturesSourceSet = createIsolatedSourceSet("texturePacks", "texturePacks")
|
||||
val customTexturesSourceSet = createIsolatedSourceSet("texturePacks", "texturePacks", isEnabled = false)
|
||||
|
||||
dependencies {
|
||||
// Minecraft dependencies
|
||||
|
||||
@@ -15,7 +15,7 @@ fabric_loader = "0.16.10"
|
||||
fabric_api = "0.119.5+1.21.5"
|
||||
yarn = "1.21.5+build.1"
|
||||
modmenu = "14.0.0-rc.2"
|
||||
architectury = "16.0.2"
|
||||
architectury = "16.0.3"
|
||||
rei = "18.0.796"
|
||||
|
||||
# Update from https://maven.fabricmc.net/net/fabricmc/fabric-language-kotlin/
|
||||
|
||||
@@ -19,6 +19,7 @@ import me.shedaniel.rei.api.common.entry.EntryIngredient
|
||||
import me.shedaniel.rei.api.common.entry.EntryStack
|
||||
import net.minecraft.entity.EntityType
|
||||
import net.minecraft.entity.SpawnReason
|
||||
import net.minecraft.registry.entry.RegistryEntry
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.village.VillagerProfession
|
||||
@@ -33,6 +34,7 @@ import moe.nea.firmament.repo.RepoManager
|
||||
import moe.nea.firmament.repo.SBItemStack
|
||||
import moe.nea.firmament.util.AprilFoolsUtil
|
||||
import moe.nea.firmament.util.FirmFormatters
|
||||
import moe.nea.firmament.util.MC
|
||||
import moe.nea.firmament.util.SkyblockId
|
||||
import moe.nea.firmament.util.gold
|
||||
import moe.nea.firmament.util.grey
|
||||
@@ -92,7 +94,7 @@ class SBReforgeRecipe(
|
||||
list.add(Widgets.withTooltip(
|
||||
EntityWidget(
|
||||
EntityType.VILLAGER.create(EntityRenderer.fakeWorld, SpawnReason.COMMAND)
|
||||
?.also { it.villagerData = it.villagerData.withProfession(VillagerProfession.WEAPONSMITH) },
|
||||
?.also { it.villagerData = it.villagerData.withProfession(MC.currentOrDefaultRegistries.getEntryOrThrow(VillagerProfession.WEAPONSMITH)) },
|
||||
Point(bounds.minX + 10 + 24 + 8 - dimension.width / 2, bounds.centerY - dimension.height / 2),
|
||||
dimension
|
||||
),
|
||||
|
||||
@@ -3,10 +3,8 @@ package moe.nea.firmament.init;
|
||||
import me.shedaniel.mm.api.ClassTinkerers;
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.block.BlockModels;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.chunk.SectionBuilder;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
@@ -28,8 +26,8 @@ public class SectionBuilderRiser extends RiserUtils {
|
||||
String BlockRenderManager;
|
||||
@IntermediaryName(BlockState.class)
|
||||
String BlockState;
|
||||
@IntermediaryName(BakedModel.class)
|
||||
String BakedModel;
|
||||
// @IntermediaryName(BakedModel.class)
|
||||
// String BakedModel;
|
||||
String CustomBlockTextures = "moe.nea.firmament.features.texturepack.CustomBlockTextures";
|
||||
|
||||
Type getModelDesc = Type.getMethodType(
|
||||
@@ -41,7 +39,8 @@ public class SectionBuilderRiser extends RiserUtils {
|
||||
Intermediary.<BlockRenderManager>className(),
|
||||
Intermediary.methodName(net.minecraft.client.render.block.BlockRenderManager::getModel),
|
||||
Type.getMethodDescriptor(
|
||||
getTypeForClassName(Intermediary.<BakedModel>className()),
|
||||
// TODO: fix this riser
|
||||
// getTypeForClassName(Intermediary.<BakedModel>className()),
|
||||
getTypeForClassName(Intermediary.<BlockState>className())
|
||||
)
|
||||
);
|
||||
@@ -105,8 +104,9 @@ public class SectionBuilderRiser extends RiserUtils {
|
||||
Opcodes.INVOKESTATIC,
|
||||
getTypeForClassName(CustomBlockTextures).getInternalName(),
|
||||
"patchIndigo",
|
||||
Type.getMethodDescriptor(getTypeForClassName(BakedModel),
|
||||
getTypeForClassName(BakedModel),
|
||||
Type.getMethodDescriptor(
|
||||
// getTypeForClassName(BakedModel),
|
||||
// getTypeForClassName(BakedModel),
|
||||
getTypeForClassName(BlockPos),
|
||||
getTypeForClassName(BlockState)),
|
||||
false
|
||||
|
||||
@@ -20,7 +20,7 @@ public abstract class PlayerDropEventPatch extends PlayerEntity {
|
||||
|
||||
@Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true)
|
||||
public void onDropSelectedItem(boolean entireStack, CallbackInfoReturnable<Boolean> cir) {
|
||||
Slot fakeSlot = new Slot(getInventory(), getInventory().selectedSlot, 0, 0);
|
||||
Slot fakeSlot = new Slot(getInventory(), getInventory().getSelectedSlot(), 0, 0);
|
||||
if (IsSlotProtectedEvent.shouldBlockInteraction(fakeSlot, SlotActionType.THROW, IsSlotProtectedEvent.MoveOrigin.DROP_FROM_HOTBAR)) {
|
||||
cir.setReturnValue(false);
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ public abstract class SlotUpdateListener extends ClientCommonNetworkHandler {
|
||||
private void onMultiSlotUpdate(InventoryS2CPacket packet, CallbackInfo ci) {
|
||||
var player = this.client.player;
|
||||
assert player != null;
|
||||
if (packet.getSyncId() == 0) {
|
||||
PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.getContents()));
|
||||
} else if (packet.getSyncId() == player.currentScreenHandler.syncId) {
|
||||
if (packet.syncId() == 0) {
|
||||
PlayerInventoryUpdate.Companion.publish(new PlayerInventoryUpdate.Multi(packet.contents()));
|
||||
} else if (packet.syncId() == player.currentScreenHandler.syncId) {
|
||||
ChestInventoryUpdateEvent.Companion.publish(
|
||||
new ChestInventoryUpdateEvent.Multi(packet.getContents())
|
||||
new ChestInventoryUpdateEvent.Multi(packet.contents())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,30 +1,32 @@
|
||||
|
||||
package moe.nea.firmament.mixins;
|
||||
|
||||
import com.llamalad7.mixinextras.injector.v2.WrapWithCondition;
|
||||
import moe.nea.firmament.events.SoundReceiveEvent;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.registry.entry.RegistryEntry;
|
||||
import net.minecraft.sound.SoundCategory;
|
||||
import net.minecraft.sound.SoundEvent;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
public class SoundReceiveEventPatch {
|
||||
@Inject(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/player/PlayerEntity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"), cancellable = true)
|
||||
private void postEventWhenSoundIsPlayed(PlaySoundS2CPacket packet, CallbackInfo ci) {
|
||||
@WrapWithCondition(method = "onPlaySound", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;playSound(Lnet/minecraft/entity/Entity;DDDLnet/minecraft/registry/entry/RegistryEntry;Lnet/minecraft/sound/SoundCategory;FFJ)V"))
|
||||
private boolean postEventWhenSoundIsPlayed(ClientWorld instance, @Nullable Entity source, double x, double y, double z, RegistryEntry<SoundEvent> sound, SoundCategory category, float volume, float pitch, long seed) {
|
||||
var event = new SoundReceiveEvent(
|
||||
packet.getSound(),
|
||||
packet.getCategory(),
|
||||
new Vec3d(packet.getX(), packet.getY(), packet.getZ()),
|
||||
packet.getPitch(),
|
||||
packet.getVolume(),
|
||||
packet.getSeed()
|
||||
sound,
|
||||
category,
|
||||
new Vec3d(x,y,z),
|
||||
pitch,
|
||||
volume,
|
||||
seed
|
||||
);
|
||||
SoundReceiveEvent.Companion.publish(event);
|
||||
if (event.getCancelled()) {
|
||||
ci.cancel();
|
||||
}
|
||||
return !event.getCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package moe.nea.firmament.features.chat
|
||||
import io.ktor.client.request.get
|
||||
import io.ktor.client.statement.bodyAsChannel
|
||||
import io.ktor.utils.io.jvm.javaio.toInputStream
|
||||
import java.net.URI
|
||||
import java.net.URL
|
||||
import java.util.Collections
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
@@ -78,7 +79,7 @@ object ChatLinks : FirmamentFeature {
|
||||
val texId = Firmament.identifier("dynamic_image_preview${nextTexId.getAndIncrement()}")
|
||||
MC.textureManager.registerTexture(
|
||||
texId,
|
||||
NativeImageBackedTexture(image)
|
||||
NativeImageBackedTexture({ texId.path }, image)
|
||||
)
|
||||
Image(texId, image.width, image.height)
|
||||
} else
|
||||
@@ -102,8 +103,8 @@ object ChatLinks : FirmamentFeature {
|
||||
if (it.screen !is ChatScreen) return
|
||||
val hoveredComponent =
|
||||
MC.inGameHud.chatHud.getTextStyleAt(it.mouseX.toDouble(), it.mouseY.toDouble()) ?: return
|
||||
val hoverEvent = hoveredComponent.hoverEvent ?: return
|
||||
val value = hoverEvent.getValue(HoverEvent.Action.SHOW_TEXT) ?: return
|
||||
val hoverEvent = hoveredComponent.hoverEvent as? HoverEvent.ShowText ?: return
|
||||
val value = hoverEvent.value
|
||||
val url = urlRegex.matchEntire(value.unformattedString)?.groupValues?.get(0) ?: return
|
||||
if (!isImageUrl(url)) return
|
||||
val imageFuture = imageCache[url] ?: return
|
||||
@@ -149,8 +150,8 @@ object ChatLinks : FirmamentFeature {
|
||||
Text.literal(url).setStyle(
|
||||
Style.EMPTY.withUnderline(true).withColor(
|
||||
Formatting.AQUA
|
||||
).withHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.literal(url)))
|
||||
.withClickEvent(ClickEvent(ClickEvent.Action.OPEN_URL, url))
|
||||
).withHoverEvent(HoverEvent.ShowText(Text.literal(url)))
|
||||
.withClickEvent(ClickEvent.OpenUrl(URI(url)))
|
||||
)
|
||||
)
|
||||
if (isImageUrl(url))
|
||||
|
||||
@@ -43,6 +43,7 @@ import moe.nea.firmament.util.mc.IntrospectableItemModelManager
|
||||
import moe.nea.firmament.util.mc.SNbtFormatter
|
||||
import moe.nea.firmament.util.mc.SNbtFormatter.Companion.toPrettyString
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.mc.iterableArmorItems
|
||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||
import moe.nea.firmament.util.skyBlockId
|
||||
|
||||
@@ -108,7 +109,7 @@ object PowerUserTools : FirmamentFeature {
|
||||
MC.sendChat(Text.stringifiedTranslatable("firmament.poweruser.entity.position", target.pos))
|
||||
if (target is LivingEntity) {
|
||||
MC.sendChat(Text.translatable("firmament.poweruser.entity.armor"))
|
||||
for (armorItem in target.armorItems) {
|
||||
for ((slot, armorItem) in target.iterableArmorItems) {
|
||||
MC.sendChat(Text.translatable("firmament.poweruser.entity.armor.item", debugFormat(armorItem)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,7 +222,7 @@ object MinesweeperHelper {
|
||||
fun onChat(event: ProcessChatEvent) {
|
||||
if (CarnivalFeatures.TConfig.displayTutorials && event.unformattedString == startGameQuestion) {
|
||||
MC.sendChat(Text.translatable("firmament.carnival.tutorial.minesweeper").styled {
|
||||
it.withClickEvent(ClickEvent(ClickEvent.Action.RUN_COMMAND, "/firm minesweepertutorial"))
|
||||
it.withClickEvent(ClickEvent.RunCommand("/firm minesweepertutorial"))
|
||||
})
|
||||
}
|
||||
if (!CarnivalFeatures.TConfig.enableBombSolver) {
|
||||
@@ -259,7 +259,7 @@ object MinesweeperHelper {
|
||||
val boardPosition = BoardPosition.fromBlockPos(event.blockPos)
|
||||
log.log { "Breaking block at ${event.blockPos} ($boardPosition)" }
|
||||
gs.lastClickedPosition = boardPosition
|
||||
gs.lastDowsingMode = DowsingMode.fromItem(event.player.inventory.mainHandStack)
|
||||
gs.lastDowsingMode = DowsingMode.fromItem(event.player.mainHandStack)
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package moe.nea.firmament.features.inventory
|
||||
|
||||
import java.net.URI
|
||||
import net.fabricmc.loader.api.FabricLoader
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -38,7 +39,7 @@ object REIDependencyWarner {
|
||||
.white()
|
||||
.append(Text.literal("[").aqua())
|
||||
.append(Text.translatable("firmament.download", modName)
|
||||
.styled { it.withClickEvent(ClickEvent(ClickEvent.Action.OPEN_URL, modrinthLink(slug))) }
|
||||
.styled { it.withClickEvent(ClickEvent.OpenUrl(URI (modrinthLink(slug)))) }
|
||||
.yellow()
|
||||
.also {
|
||||
if (alreadyDownloaded)
|
||||
|
||||
@@ -4,6 +4,7 @@ package moe.nea.firmament.features.inventory
|
||||
|
||||
import java.util.UUID
|
||||
import org.lwjgl.glfw.GLFW
|
||||
import util.render.CustomRenderLayers
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@@ -17,6 +18,9 @@ import kotlinx.serialization.json.JsonPrimitive
|
||||
import kotlinx.serialization.json.int
|
||||
import kotlinx.serialization.serializer
|
||||
import net.minecraft.client.gui.screen.ingame.HandledScreen
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.RenderLayers
|
||||
import net.minecraft.client.render.TexturedRenderLayers
|
||||
import net.minecraft.entity.player.PlayerInventory
|
||||
import net.minecraft.screen.GenericContainerScreenHandler
|
||||
import net.minecraft.screen.slot.Slot
|
||||
@@ -45,7 +49,6 @@ import moe.nea.firmament.util.mc.ScreenUtil.getSlotByIndex
|
||||
import moe.nea.firmament.util.mc.SlotUtils.swapWithHotBar
|
||||
import moe.nea.firmament.util.mc.displayNameAccordingToNbt
|
||||
import moe.nea.firmament.util.mc.loreAccordingToNbt
|
||||
import moe.nea.firmament.util.render.GuiRenderLayers
|
||||
import moe.nea.firmament.util.render.drawLine
|
||||
import moe.nea.firmament.util.skyblock.DungeonUtil
|
||||
import moe.nea.firmament.util.skyblockUUID
|
||||
@@ -445,7 +448,7 @@ object SlotLocking : FirmamentFeature {
|
||||
val isUUIDLocked = (it.slot.stack?.skyblockUUID) in (lockedUUIDs ?: setOf())
|
||||
if (isSlotLocked || isUUIDLocked) {
|
||||
it.context.drawGuiTexture(
|
||||
GuiRenderLayers.GUI_TEXTURED_NO_DEPTH,
|
||||
RenderLayer::getGuiTexturedOverlay,
|
||||
when {
|
||||
isSlotLocked ->
|
||||
(Identifier.of("firmament:slot_locked"))
|
||||
|
||||
@@ -218,7 +218,7 @@ class StorageOverlayScreen : Screen(Text.literal("")) {
|
||||
}
|
||||
|
||||
fun drawPlayerInventory(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) {
|
||||
val items = MC.player?.inventory?.main ?: return
|
||||
val items = MC.player?.inventory?.mainStacks ?: return
|
||||
items.withIndex().forEach { (index, item) ->
|
||||
val (x, y) = getPlayerInventorySlotPosition(index)
|
||||
context.drawItem(item, x, y, 0)
|
||||
|
||||
@@ -11,6 +11,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
import net.minecraft.nbt.NbtIo
|
||||
@@ -42,15 +43,15 @@ data class VirtualInventory(
|
||||
override fun deserialize(decoder: Decoder): VirtualInventory {
|
||||
val s = decoder.decodeString()
|
||||
val n = NbtIo.readCompressed(ByteArrayInputStream(s.decodeBase64Bytes()), NbtSizeTracker.of(100_000_000))
|
||||
val items = n.getList(INVENTORY, NbtCompound.COMPOUND_TYPE.toInt())
|
||||
val items = n.getList(INVENTORY).getOrNull()
|
||||
val ops = getOps()
|
||||
return VirtualInventory(items.map {
|
||||
return VirtualInventory(items?.map {
|
||||
it as NbtCompound
|
||||
if (it.isEmpty) ItemStack.EMPTY
|
||||
else ErrorUtil.catch("Could not deserialize item") {
|
||||
ItemStack.CODEC.parse(ops, it).orThrow
|
||||
}.or { ItemStack.EMPTY }
|
||||
})
|
||||
} ?: listOf())
|
||||
}
|
||||
|
||||
fun getOps() = TolerantRegistriesOps(NbtOps.INSTANCE, MC.currentOrDefaultRegistries)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package moe.nea.firmament.features.mining
|
||||
|
||||
import java.util.regex.Pattern
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
import net.minecraft.client.MinecraftClient
|
||||
@@ -144,8 +145,7 @@ object PickaxeAbility : FirmamentFeature {
|
||||
}
|
||||
} ?: return
|
||||
val extra = it.item.extraAttributes
|
||||
if (!extra.contains("drill_fuel")) return
|
||||
val fuel = extra.getInt("drill_fuel")
|
||||
val fuel = extra.getInt("drill_fuel").getOrNull() ?: return
|
||||
val percentage = fuel / maxFuel.toFloat()
|
||||
it.barOverride = DurabilityBarEvent.DurabilityBar(
|
||||
lerp(
|
||||
|
||||
@@ -169,13 +169,13 @@ object EntityRenderer {
|
||||
val oldBodyYaw = entity.bodyYaw
|
||||
val oldYaw = entity.yaw
|
||||
val oldPitch = entity.pitch
|
||||
val oldPrevHeadYaw = entity.prevHeadYaw
|
||||
val oldPrevHeadYaw = entity.lastHeadYaw
|
||||
val oldHeadYaw = entity.headYaw
|
||||
entity.bodyYaw = 180.0f + targetYaw * 20.0f
|
||||
entity.yaw = 180.0f + targetYaw * 40.0f
|
||||
entity.pitch = -targetPitch * 20.0f
|
||||
entity.headYaw = entity.yaw
|
||||
entity.prevHeadYaw = entity.yaw
|
||||
entity.lastHeadYaw = entity.yaw
|
||||
val vector3f = Vector3f(0.0f, (entity.height / 2.0f + bottomOffset).toFloat(), 0.0f)
|
||||
InventoryScreen.drawEntity(
|
||||
context,
|
||||
@@ -190,7 +190,7 @@ object EntityRenderer {
|
||||
entity.bodyYaw = oldBodyYaw
|
||||
entity.yaw = oldYaw
|
||||
entity.pitch = oldPitch
|
||||
entity.prevHeadYaw = oldPrevHeadYaw
|
||||
entity.lastHeadYaw = oldPrevHeadYaw
|
||||
entity.headYaw = oldHeadYaw
|
||||
context.disableScissor()
|
||||
}
|
||||
|
||||
@@ -1,343 +0,0 @@
|
||||
package moe.nea.firmament.gui.entity
|
||||
|
||||
import java.util.UUID
|
||||
import java.util.function.BooleanSupplier
|
||||
import java.util.function.Consumer
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.gui.screen.world.SelectWorldScreen
|
||||
import net.minecraft.component.type.MapIdComponent
|
||||
import net.minecraft.entity.Entity
|
||||
import net.minecraft.entity.boss.dragon.EnderDragonPart
|
||||
import net.minecraft.entity.damage.DamageSource
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
import net.minecraft.fluid.Fluid
|
||||
import net.minecraft.item.FuelRegistry
|
||||
import net.minecraft.item.map.MapState
|
||||
import net.minecraft.particle.ParticleEffect
|
||||
import net.minecraft.recipe.BrewingRecipeRegistry
|
||||
import net.minecraft.recipe.RecipeManager
|
||||
import net.minecraft.recipe.RecipePropertySet
|
||||
import net.minecraft.recipe.StonecuttingRecipe
|
||||
import net.minecraft.recipe.display.CuttingRecipeDisplay
|
||||
import net.minecraft.registry.DynamicRegistryManager
|
||||
import net.minecraft.registry.Registries
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.registry.ServerDynamicRegistryType
|
||||
import net.minecraft.registry.entry.RegistryEntry
|
||||
import net.minecraft.resource.DataConfiguration
|
||||
import net.minecraft.resource.ResourcePackManager
|
||||
import net.minecraft.resource.featuretoggle.FeatureFlags
|
||||
import net.minecraft.resource.featuretoggle.FeatureSet
|
||||
import net.minecraft.scoreboard.Scoreboard
|
||||
import net.minecraft.server.SaveLoading
|
||||
import net.minecraft.server.command.CommandManager
|
||||
import net.minecraft.sound.SoundCategory
|
||||
import net.minecraft.sound.SoundEvent
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.TypeFilter
|
||||
import net.minecraft.util.function.LazyIterationConsumer
|
||||
import net.minecraft.util.math.BlockPos
|
||||
import net.minecraft.util.math.Box
|
||||
import net.minecraft.util.math.ChunkPos
|
||||
import net.minecraft.util.math.Direction
|
||||
import net.minecraft.util.math.Vec3d
|
||||
import net.minecraft.world.BlockView
|
||||
import net.minecraft.world.Difficulty
|
||||
import net.minecraft.world.MutableWorldProperties
|
||||
import net.minecraft.world.World
|
||||
import net.minecraft.world.biome.Biome
|
||||
import net.minecraft.world.biome.BiomeKeys
|
||||
import net.minecraft.world.chunk.Chunk
|
||||
import net.minecraft.world.chunk.ChunkManager
|
||||
import net.minecraft.world.chunk.ChunkStatus
|
||||
import net.minecraft.world.chunk.EmptyChunk
|
||||
import net.minecraft.world.chunk.light.LightingProvider
|
||||
import net.minecraft.world.entity.EntityLookup
|
||||
import net.minecraft.world.event.GameEvent
|
||||
import net.minecraft.world.explosion.ExplosionBehavior
|
||||
import net.minecraft.world.tick.OrderedTick
|
||||
import net.minecraft.world.tick.QueryableTickScheduler
|
||||
import net.minecraft.world.tick.TickManager
|
||||
import moe.nea.firmament.util.MC
|
||||
|
||||
fun createDynamicRegistry(): DynamicRegistryManager.Immutable {
|
||||
// TODO: use SaveLoading.load() to properly load a full registry
|
||||
return DynamicRegistryManager.of(Registries.REGISTRIES)
|
||||
}
|
||||
|
||||
class FakeWorld(
|
||||
registries: DynamicRegistryManager.Immutable = createDynamicRegistry(),
|
||||
) : World(
|
||||
Properties,
|
||||
RegistryKey.of(RegistryKeys.WORLD, Identifier.of("firmament", "fakeworld")),
|
||||
registries,
|
||||
MC.defaultRegistries.getOrThrow(RegistryKeys.DIMENSION_TYPE)
|
||||
.getOrThrow(RegistryKey.of(RegistryKeys.DIMENSION_TYPE, Identifier.of("minecraft", "overworld"))),
|
||||
true,
|
||||
false,
|
||||
0L,
|
||||
0
|
||||
) {
|
||||
object Properties : MutableWorldProperties {
|
||||
override fun getSpawnPos(): BlockPos {
|
||||
return BlockPos.ORIGIN
|
||||
}
|
||||
|
||||
override fun getSpawnAngle(): Float {
|
||||
return 0F
|
||||
}
|
||||
|
||||
override fun getTime(): Long {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getTimeOfDay(): Long {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun isThundering(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun isRaining(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun setRaining(raining: Boolean) {
|
||||
}
|
||||
|
||||
override fun isHardcore(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun getDifficulty(): Difficulty {
|
||||
return Difficulty.HARD
|
||||
}
|
||||
|
||||
override fun isDifficultyLocked(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun setSpawnPos(pos: BlockPos?, angle: Float) {}
|
||||
}
|
||||
|
||||
override fun getPlayers(): List<PlayerEntity> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun getBrightness(direction: Direction?, shaded: Boolean): Float {
|
||||
return 1f
|
||||
}
|
||||
|
||||
override fun getGeneratorStoredBiome(biomeX: Int, biomeY: Int, biomeZ: Int): RegistryEntry<Biome> {
|
||||
return registryManager.getOptionalEntry(BiomeKeys.PLAINS).get()
|
||||
}
|
||||
|
||||
override fun getSeaLevel(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getEnabledFeatures(): FeatureSet {
|
||||
return FeatureFlags.VANILLA_FEATURES
|
||||
}
|
||||
|
||||
class FakeTickScheduler<T> : QueryableTickScheduler<T> {
|
||||
override fun scheduleTick(orderedTick: OrderedTick<T>?) {
|
||||
}
|
||||
|
||||
override fun isQueued(pos: BlockPos?, type: T): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
override fun getTickCount(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun isTicking(pos: BlockPos?, type: T): Boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getBlockTickScheduler(): QueryableTickScheduler<Block> {
|
||||
return FakeTickScheduler()
|
||||
}
|
||||
|
||||
override fun getFluidTickScheduler(): QueryableTickScheduler<Fluid> {
|
||||
return FakeTickScheduler()
|
||||
}
|
||||
|
||||
|
||||
class FakeChunkManager(val world: FakeWorld) : ChunkManager() {
|
||||
override fun getChunk(x: Int, z: Int, leastStatus: ChunkStatus?, create: Boolean): Chunk {
|
||||
return EmptyChunk(
|
||||
world,
|
||||
ChunkPos(x, z),
|
||||
world.registryManager.getOptionalEntry(BiomeKeys.PLAINS).get()
|
||||
)
|
||||
}
|
||||
|
||||
override fun getWorld(): BlockView {
|
||||
return world
|
||||
}
|
||||
|
||||
override fun tick(shouldKeepTicking: BooleanSupplier?, tickChunks: Boolean) {
|
||||
}
|
||||
|
||||
override fun getDebugString(): String {
|
||||
return "FakeChunkManager"
|
||||
}
|
||||
|
||||
override fun getLoadedChunkCount(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun getLightingProvider(): LightingProvider {
|
||||
return FakeLightingProvider(this)
|
||||
}
|
||||
}
|
||||
|
||||
class FakeLightingProvider(chunkManager: FakeChunkManager) : LightingProvider(chunkManager, false, false)
|
||||
|
||||
override fun getChunkManager(): ChunkManager {
|
||||
return FakeChunkManager(this)
|
||||
}
|
||||
|
||||
override fun playSound(
|
||||
source: PlayerEntity?,
|
||||
x: Double,
|
||||
y: Double,
|
||||
z: Double,
|
||||
sound: RegistryEntry<SoundEvent>?,
|
||||
category: SoundCategory?,
|
||||
volume: Float,
|
||||
pitch: Float,
|
||||
seed: Long
|
||||
) {
|
||||
}
|
||||
|
||||
override fun syncWorldEvent(player: PlayerEntity?, eventId: Int, pos: BlockPos?, data: Int) {
|
||||
}
|
||||
|
||||
override fun emitGameEvent(event: RegistryEntry<GameEvent>?, emitterPos: Vec3d?, emitter: GameEvent.Emitter?) {
|
||||
}
|
||||
|
||||
override fun updateListeners(pos: BlockPos?, oldState: BlockState?, newState: BlockState?, flags: Int) {
|
||||
}
|
||||
|
||||
override fun playSoundFromEntity(
|
||||
source: PlayerEntity?,
|
||||
entity: Entity?,
|
||||
sound: RegistryEntry<SoundEvent>?,
|
||||
category: SoundCategory?,
|
||||
volume: Float,
|
||||
pitch: Float,
|
||||
seed: Long
|
||||
) {
|
||||
}
|
||||
|
||||
override fun createExplosion(
|
||||
entity: Entity?,
|
||||
damageSource: DamageSource?,
|
||||
behavior: ExplosionBehavior?,
|
||||
x: Double,
|
||||
y: Double,
|
||||
z: Double,
|
||||
power: Float,
|
||||
createFire: Boolean,
|
||||
explosionSourceType: ExplosionSourceType?,
|
||||
smallParticle: ParticleEffect?,
|
||||
largeParticle: ParticleEffect?,
|
||||
soundEvent: RegistryEntry<SoundEvent>?
|
||||
) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun asString(): String {
|
||||
return "FakeWorld"
|
||||
}
|
||||
|
||||
override fun getEntityById(id: Int): Entity? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun getEnderDragonParts(): MutableCollection<EnderDragonPart> {
|
||||
return mutableListOf()
|
||||
}
|
||||
|
||||
override fun getTickManager(): TickManager {
|
||||
return TickManager()
|
||||
}
|
||||
|
||||
override fun getMapState(id: MapIdComponent?): MapState? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun putMapState(id: MapIdComponent?, state: MapState?) {
|
||||
}
|
||||
|
||||
override fun increaseAndGetMapId(): MapIdComponent {
|
||||
return MapIdComponent(0)
|
||||
}
|
||||
|
||||
override fun setBlockBreakingInfo(entityId: Int, pos: BlockPos?, progress: Int) {
|
||||
}
|
||||
|
||||
override fun getScoreboard(): Scoreboard {
|
||||
return Scoreboard()
|
||||
}
|
||||
|
||||
override fun getRecipeManager(): RecipeManager {
|
||||
return object : RecipeManager {
|
||||
override fun getPropertySet(key: RegistryKey<RecipePropertySet>?): RecipePropertySet {
|
||||
return RecipePropertySet.EMPTY
|
||||
}
|
||||
|
||||
override fun getStonecutterRecipes(): CuttingRecipeDisplay.Grouping<StonecuttingRecipe> {
|
||||
return CuttingRecipeDisplay.Grouping.empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object FakeEntityLookup : EntityLookup<Entity> {
|
||||
override fun get(id: Int): Entity? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun get(uuid: UUID?): Entity? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun iterate(): MutableIterable<Entity> {
|
||||
return mutableListOf()
|
||||
}
|
||||
|
||||
override fun <U : Entity?> forEachIntersects(
|
||||
filter: TypeFilter<Entity, U>?,
|
||||
box: Box?,
|
||||
consumer: LazyIterationConsumer<U>?
|
||||
) {
|
||||
}
|
||||
|
||||
override fun forEachIntersects(box: Box?, action: Consumer<Entity>?) {
|
||||
}
|
||||
|
||||
override fun <U : Entity?> forEach(filter: TypeFilter<Entity, U>?, consumer: LazyIterationConsumer<U>?) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getEntityLookup(): EntityLookup<Entity> {
|
||||
return FakeEntityLookup
|
||||
}
|
||||
|
||||
override fun getBrewingRecipeRegistry(): BrewingRecipeRegistry {
|
||||
return BrewingRecipeRegistry.EMPTY
|
||||
}
|
||||
|
||||
override fun getFuelRegistry(): FuelRegistry {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ object ModifyEquipment : EntityModifier {
|
||||
|
||||
private fun coloredLeatherArmor(leatherArmor: Item, data: String): ItemStack {
|
||||
val stack = ItemStack(leatherArmor)
|
||||
stack.set(DataComponentTypes.DYED_COLOR, DyedColorComponent(data.toInt(16), false))
|
||||
stack.set(DataComponentTypes.DYED_COLOR, DyedColorComponent(data.toInt(16)))
|
||||
return stack
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
package moe.nea.firmament.gui.entity
|
||||
|
||||
import com.google.gson.JsonNull
|
||||
@@ -7,6 +6,7 @@ import kotlin.experimental.and
|
||||
import kotlin.experimental.inv
|
||||
import kotlin.experimental.or
|
||||
import net.minecraft.entity.EntityType
|
||||
import net.minecraft.entity.EquipmentSlot
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.entity.SpawnReason
|
||||
import net.minecraft.entity.passive.AbstractHorseEntity
|
||||
@@ -49,14 +49,11 @@ object ModifyHorse : EntityModifier {
|
||||
}
|
||||
|
||||
fun AbstractHorseEntity.setIsSaddled(shouldBeSaddled: Boolean) {
|
||||
val oldFlag = dataTracker.get(AbstractHorseEntity.HORSE_FLAGS)
|
||||
dataTracker.set(
|
||||
AbstractHorseEntity.HORSE_FLAGS,
|
||||
if (shouldBeSaddled) oldFlag or AbstractHorseEntity.SADDLED_FLAG.toByte()
|
||||
else oldFlag and AbstractHorseEntity.SADDLED_FLAG.toByte().inv()
|
||||
)
|
||||
this.equipStack(EquipmentSlot.SADDLE,
|
||||
if (shouldBeSaddled) ItemStack(Items.SADDLE)
|
||||
else ItemStack.EMPTY)
|
||||
}
|
||||
|
||||
fun AbstractHorseEntity.setHorseArmor(itemStack: ItemStack) {
|
||||
items.setStack(1, itemStack)
|
||||
this.equipBodyArmor(itemStack)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.mojang.serialization.Dynamic
|
||||
import io.github.moulberry.repo.IReloadable
|
||||
import io.github.moulberry.repo.NEURepository
|
||||
import io.github.moulberry.repo.data.NEUItem
|
||||
import io.github.notenoughupdates.moulconfig.xml.Bind
|
||||
import java.text.NumberFormat
|
||||
import java.util.UUID
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
@@ -13,7 +12,6 @@ import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import net.minecraft.SharedConstants
|
||||
import net.minecraft.client.resource.language.I18n
|
||||
import net.minecraft.component.DataComponentTypes
|
||||
import net.minecraft.component.type.NbtComponent
|
||||
import net.minecraft.datafixer.Schemas
|
||||
@@ -28,9 +26,6 @@ import net.minecraft.text.MutableText
|
||||
import net.minecraft.text.Style
|
||||
import net.minecraft.text.Text
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.gui.config.HudMeta
|
||||
import moe.nea.firmament.gui.config.HudPosition
|
||||
import moe.nea.firmament.gui.hud.MoulConfigHud
|
||||
import moe.nea.firmament.repo.RepoManager.initialize
|
||||
import moe.nea.firmament.util.LegacyFormattingCode
|
||||
import moe.nea.firmament.util.LegacyTagParser
|
||||
@@ -140,7 +135,8 @@ object ItemCache : IReloadable {
|
||||
ItemStack.fromNbt(MC.defaultRegistries, modernItemTag).getOrNull() ?: return brokenItemStack(this)
|
||||
itemInstance.loreAccordingToNbt = lore.map { un189Lore(it) }
|
||||
itemInstance.displayNameAccordingToNbt = un189Lore(displayName)
|
||||
val extraAttributes = oldItemTag.getCompound("tag").getCompound("ExtraAttributes")
|
||||
val extraAttributes = oldItemTag.getCompound("tag").flatMap { it.getCompound("ExtraAttributes") }
|
||||
.getOrNull()
|
||||
if (extraAttributes != null)
|
||||
itemInstance.set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(extraAttributes))
|
||||
return itemInstance
|
||||
|
||||
@@ -24,7 +24,7 @@ import net.minecraft.resource.metadata.ResourceMetadata
|
||||
import net.minecraft.resource.metadata.ResourceMetadataSerializer
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.PathUtil
|
||||
import net.minecraft.util.path.PathUtil
|
||||
import moe.nea.firmament.Firmament
|
||||
|
||||
class RepoModResourcePack(val basePath: Path) : ModResourcePack {
|
||||
|
||||
@@ -99,7 +99,7 @@ object MC {
|
||||
inline val soundManager get() = instance.soundManager
|
||||
inline val player: ClientPlayerEntity? get() = TestUtil.unlessTesting { instance.player }
|
||||
inline val camera: Entity? get() = instance.cameraEntity
|
||||
inline val stackInHand: ItemStack get() = player?.inventory?.mainHandStack ?: ItemStack.EMPTY
|
||||
inline val stackInHand: ItemStack get() = player?.mainHandStack ?: ItemStack.EMPTY
|
||||
inline val guiAtlasManager get() = instance.guiAtlasManager
|
||||
inline val world: ClientWorld? get() = TestUtil.unlessTesting { instance.world }
|
||||
inline val playerName: String? get() = player?.name?.unformattedString
|
||||
|
||||
@@ -130,13 +130,14 @@ fun ItemStack.modifyExtraAttributes(block: (NbtCompound) -> Unit) {
|
||||
}
|
||||
|
||||
val ItemStack.skyblockUUIDString: String?
|
||||
get() = extraAttributes.getString("uuid")?.takeIf { it.isNotBlank() }
|
||||
get() = extraAttributes.getString("uuid").getOrNull()?.takeIf { it.isNotBlank() }
|
||||
|
||||
val ItemStack.skyblockUUID: UUID?
|
||||
get() = skyblockUUIDString?.let { UUID.fromString(it) }
|
||||
|
||||
private val petDataCache = WeakCache.memoize<ItemStack, Optional<HypixelPetInfo>>("PetInfo") {
|
||||
val jsonString = it.extraAttributes.getString("petInfo")
|
||||
.getOrNull()
|
||||
if (jsonString.isNullOrBlank()) return@memoize Optional.empty()
|
||||
ErrorUtil.catch<HypixelPetInfo?>("Could not decode hypixel pet info") {
|
||||
jsonparser.decodeFromString<HypixelPetInfo>(jsonString)
|
||||
@@ -145,8 +146,8 @@ private val petDataCache = WeakCache.memoize<ItemStack, Optional<HypixelPetInfo>
|
||||
}
|
||||
|
||||
fun ItemStack.getUpgradeStars(): Int {
|
||||
return extraAttributes.getInt("upgrade_level").takeIf { it > 0 }
|
||||
?: extraAttributes.getInt("dungeon_item_level").takeIf { it > 0 }
|
||||
return extraAttributes.getInt("upgrade_level").getOrNull()?.takeIf { it > 0 }
|
||||
?: extraAttributes.getInt("dungeon_item_level").getOrNull()?.takeIf { it > 0 }
|
||||
?: 0
|
||||
}
|
||||
|
||||
@@ -155,7 +156,7 @@ fun ItemStack.getUpgradeStars(): Int {
|
||||
value class ReforgeId(val id: String)
|
||||
|
||||
fun ItemStack.getReforgeId(): ReforgeId? {
|
||||
return extraAttributes.getString("modifier").takeIf { it.isNotBlank() }?.let(::ReforgeId)
|
||||
return extraAttributes.getString("modifier").getOrNull()?.takeIf { it.isNotBlank() }?.let(::ReforgeId)
|
||||
}
|
||||
|
||||
val ItemStack.petData: HypixelPetInfo?
|
||||
@@ -169,8 +170,8 @@ fun ItemStack.setSkyBlockId(skyblockId: SkyblockId): ItemStack {
|
||||
|
||||
val ItemStack.skyBlockId: SkyblockId?
|
||||
get() {
|
||||
return when (val id = extraAttributes.getString("id")) {
|
||||
"" -> {
|
||||
return when (val id = extraAttributes.getString("id").getOrNull()) {
|
||||
"", null -> {
|
||||
null
|
||||
}
|
||||
|
||||
@@ -180,20 +181,22 @@ val ItemStack.skyBlockId: SkyblockId?
|
||||
|
||||
"RUNE", "UNIQUE_RUNE" -> {
|
||||
val runeData = extraAttributes.getCompound("runes")
|
||||
val runeKind = runeData.keys.singleOrNull()
|
||||
.getOrNull()
|
||||
val runeKind = runeData?.keys?.singleOrNull()
|
||||
if (runeKind == null) SkyblockId("RUNE")
|
||||
else SkyblockId("${runeKind.uppercase()}_RUNE;${runeData.getInt(runeKind)}")
|
||||
else SkyblockId("${runeKind.uppercase()}_RUNE;${runeData.getInt(runeKind).getOrNull()}")
|
||||
}
|
||||
|
||||
"ABICASE" -> {
|
||||
SkyblockId("ABICASE_${extraAttributes.getString("model").uppercase()}")
|
||||
SkyblockId("ABICASE_${extraAttributes.getString("model").getOrNull()?.uppercase()}")
|
||||
}
|
||||
|
||||
"ENCHANTED_BOOK" -> {
|
||||
val enchantmentData = extraAttributes.getCompound("enchantments")
|
||||
val enchantName = enchantmentData.keys.singleOrNull()
|
||||
.getOrNull()
|
||||
val enchantName = enchantmentData?.keys?.singleOrNull()
|
||||
if (enchantName == null) SkyblockId("ENCHANTED_BOOK")
|
||||
else SkyblockId("${enchantName.uppercase()};${enchantmentData.getInt(enchantName)}")
|
||||
else SkyblockId("${enchantName.uppercase()};${enchantmentData.getInt(enchantName).getOrNull()}")
|
||||
}
|
||||
|
||||
// TODO: PARTY_HAT_CRAB{,_ANIMATED,_SLOTH},POTION
|
||||
|
||||
8
src/main/kotlin/util/mc/ArmorUtil.kt
Normal file
8
src/main/kotlin/util/mc/ArmorUtil.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
package moe.nea.firmament.util.mc
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot
|
||||
import net.minecraft.entity.LivingEntity
|
||||
|
||||
val LivingEntity.iterableArmorItems
|
||||
get() = EquipmentSlot.entries.asSequence()
|
||||
.map { it to getEquippedStack(it) }
|
||||
7
src/main/kotlin/util/mc/PlayerUtil.kt
Normal file
7
src/main/kotlin/util/mc/PlayerUtil.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package moe.nea.firmament.util.mc
|
||||
|
||||
import net.minecraft.entity.EquipmentSlot
|
||||
import net.minecraft.entity.player.PlayerEntity
|
||||
|
||||
|
||||
val PlayerEntity.mainHandStack get() = this.getEquippedStack(EquipmentSlot.MAINHAND)
|
||||
@@ -1,5 +1,6 @@
|
||||
package moe.nea.firmament.util.mc
|
||||
|
||||
import net.minecraft.nbt.AbstractNbtList
|
||||
import net.minecraft.nbt.NbtByte
|
||||
import net.minecraft.nbt.NbtByteArray
|
||||
import net.minecraft.nbt.NbtCompound
|
||||
@@ -38,7 +39,7 @@ class SNbtFormatter private constructor() : NbtElementVisitor {
|
||||
|
||||
|
||||
override fun visitString(element: NbtString) {
|
||||
result.append(NbtString.escape(element.asString()))
|
||||
result.append(NbtString.escape(element.value))
|
||||
}
|
||||
|
||||
override fun visitByte(element: NbtByte) {
|
||||
@@ -65,18 +66,18 @@ class SNbtFormatter private constructor() : NbtElementVisitor {
|
||||
result.append(element.doubleValue()).append("d")
|
||||
}
|
||||
|
||||
private fun visitArrayContents(array: List<NbtElement>) {
|
||||
private fun visitArrayContents(array: AbstractNbtList) {
|
||||
array.forEachIndexed { index, element ->
|
||||
writeIndent()
|
||||
element.accept(this)
|
||||
if (array.size != index + 1) {
|
||||
if (array.size() != index + 1) {
|
||||
result.append(",")
|
||||
}
|
||||
result.append("\n")
|
||||
}
|
||||
}
|
||||
|
||||
private fun writeArray(arrayTypeTag: String, array: List<NbtElement>) {
|
||||
private fun writeArray(arrayTypeTag: String, array: AbstractNbtList) {
|
||||
result.append("[").append(arrayTypeTag).append("\n")
|
||||
pushIndent()
|
||||
visitArrayContents(array)
|
||||
|
||||
62
src/main/kotlin/util/render/CustomRenderLayers.kt
Normal file
62
src/main/kotlin/util/render/CustomRenderLayers.kt
Normal file
@@ -0,0 +1,62 @@
|
||||
package util.render
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline
|
||||
import com.mojang.blaze3d.platform.DepthTestFunction
|
||||
import com.mojang.blaze3d.vertex.VertexFormat.DrawMode
|
||||
import java.util.function.Function
|
||||
import net.minecraft.client.gl.RenderPipelines
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.RenderPhase
|
||||
import net.minecraft.client.render.VertexFormats
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.TriState
|
||||
import net.minecraft.util.Util
|
||||
import moe.nea.firmament.Firmament
|
||||
|
||||
object CustomRenderPipelines {
|
||||
val GUI_TEXTURED_NO_DEPTH_TRIS =
|
||||
RenderPipeline.builder(RenderPipelines.POSITION_TEX_COLOR_SNIPPET)
|
||||
.withVertexFormat(VertexFormats.POSITION_TEXTURE_COLOR, DrawMode.TRIANGLES)
|
||||
.withLocation(Firmament.identifier("gui_textured_overlay_tris"))
|
||||
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
|
||||
.withCull(false)
|
||||
.withDepthWrite(false)
|
||||
.build()
|
||||
val COLORED_OMNIPRESENT_QUADS = RenderPipeline.builder(RenderPipelines.ENTITY_SNIPPET)// TODO: split this up to support better transparent ordering.
|
||||
.withLocation(Firmament.identifier("colored_omnipresent_quads"))
|
||||
.withDepthTestFunction(DepthTestFunction.NO_DEPTH_TEST)
|
||||
.withDepthWrite(false)
|
||||
.build()
|
||||
}
|
||||
|
||||
object CustomRenderLayers {
|
||||
|
||||
|
||||
inline fun memoizeTextured(crossinline func: (Identifier) -> RenderLayer) = memoize(func)
|
||||
inline fun <T, R> memoize(crossinline func: (T) -> R): Function<T, R> {
|
||||
return Util.memoize { it: T -> func(it) }
|
||||
}
|
||||
|
||||
val GUI_TEXTURED_NO_DEPTH_TRIS = memoizeTextured { texture ->
|
||||
RenderLayer.of("firmament_gui_textured_overlay_tris",
|
||||
RenderLayer.DEFAULT_BUFFER_SIZE,
|
||||
CustomRenderPipelines.GUI_TEXTURED_NO_DEPTH_TRIS,
|
||||
RenderLayer.MultiPhaseParameters.builder().texture(
|
||||
RenderPhase.Texture(texture, TriState.DEFAULT, false))
|
||||
.build(false))
|
||||
}
|
||||
val LINES = RenderLayer.of(
|
||||
"firmament_lines",
|
||||
RenderLayer.DEFAULT_BUFFER_SIZE,
|
||||
RenderPipelines.LINES,
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.build(false)
|
||||
)
|
||||
val COLORED_QUADS = RenderLayer.of(
|
||||
"firmament_quads",
|
||||
RenderLayer.DEFAULT_BUFFER_SIZE,
|
||||
CustomRenderPipelines.COLORED_OMNIPRESENT_QUADS,
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.build(false)
|
||||
)
|
||||
}
|
||||
@@ -1,52 +1,24 @@
|
||||
package moe.nea.firmament.util.render
|
||||
|
||||
import com.mojang.blaze3d.pipeline.RenderPipeline
|
||||
import com.mojang.blaze3d.platform.DepthTestFunction
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import com.mojang.blaze3d.vertex.VertexFormat.DrawMode
|
||||
import me.shedaniel.math.Color
|
||||
import org.joml.Matrix4f
|
||||
import util.render.CustomRenderLayers
|
||||
import net.minecraft.client.gl.RenderPipelines
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.RenderLayer.MultiPhaseParameters
|
||||
import net.minecraft.client.render.RenderPhase
|
||||
import net.minecraft.client.render.VertexFormat
|
||||
import net.minecraft.client.render.VertexFormat.DrawMode
|
||||
import net.minecraft.client.render.VertexFormats
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.TriState
|
||||
import net.minecraft.util.Util
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.util.MC
|
||||
|
||||
fun DrawContext.isUntranslatedGuiDrawContext(): Boolean {
|
||||
return (matrices.peek().positionMatrix.properties() and Matrix4f.PROPERTY_IDENTITY.toInt()) != 0
|
||||
}
|
||||
|
||||
object GuiRenderLayers {
|
||||
val GUI_TEXTURED_NO_DEPTH = Util.memoize<Identifier, RenderLayer> { texture: Identifier ->
|
||||
RenderLayer.of("firmament_gui_textured_no_depth",
|
||||
VertexFormats.POSITION_TEXTURE_COLOR,
|
||||
DrawMode.QUADS,
|
||||
DEFAULT_BUFFER_SIZE,
|
||||
MultiPhaseParameters.builder()
|
||||
.texture(RenderPhase.Texture(texture, TriState.FALSE, false))
|
||||
.program(RenderPhase.POSITION_TEXTURE_COLOR_PROGRAM)
|
||||
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||
.build(false))
|
||||
}
|
||||
val GUI_TEXTURED_TRIS = Util.memoize { texture: Identifier ->
|
||||
RenderLayer.of("firmament_gui_textured_overlay_tris",
|
||||
VertexFormats.POSITION_TEXTURE_COLOR,
|
||||
DrawMode.TRIANGLES,
|
||||
DEFAULT_BUFFER_SIZE,
|
||||
MultiPhaseParameters.builder()
|
||||
.texture(RenderPhase.Texture(texture, TriState.DEFAULT, false))
|
||||
.program(RenderPhase.POSITION_TEXTURE_COLOR_PROGRAM)
|
||||
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||
.writeMaskState(RenderPhase.COLOR_MASK)
|
||||
.build(false))
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated("Use the other drawGuiTexture")
|
||||
fun DrawContext.drawGuiTexture(
|
||||
x: Int, y: Int, z: Int, width: Int, height: Int, sprite: Identifier
|
||||
@@ -91,7 +63,7 @@ fun DrawContext.drawLine(fromX: Int, fromY: Int, toX: Int, toY: Int, color: Colo
|
||||
}
|
||||
RenderSystem.lineWidth(MC.window.scaleFactor.toFloat())
|
||||
draw { vertexConsumers ->
|
||||
val buf = vertexConsumers.getBuffer(RenderInWorldContext.RenderLayers.LINES)
|
||||
val buf = vertexConsumers.getBuffer(CustomRenderLayers.LINES)
|
||||
buf.vertex(fromX.toFloat(), fromY.toFloat(), 0F).color(color.color)
|
||||
.normal(toX - fromX.toFloat(), toY - fromY.toFloat(), 0F)
|
||||
buf.vertex(toX.toFloat(), toY.toFloat(), 0F).color(color.color)
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
|
||||
package moe.nea.firmament.util.render
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import io.github.notenoughupdates.moulconfig.platform.next
|
||||
import org.joml.Matrix4f
|
||||
import net.minecraft.client.font.TextRenderer
|
||||
import net.minecraft.client.render.BufferRenderer
|
||||
import net.minecraft.client.render.GameRenderer
|
||||
import net.minecraft.client.render.LightmapTextureManager
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.Tessellator
|
||||
import net.minecraft.client.render.VertexConsumer
|
||||
import net.minecraft.client.render.VertexFormat
|
||||
import net.minecraft.client.render.VertexFormats
|
||||
import net.minecraft.text.Text
|
||||
import net.minecraft.util.Identifier
|
||||
import net.minecraft.util.math.BlockPos
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package moe.nea.firmament.util.render
|
||||
|
||||
import com.mojang.blaze3d.vertex.VertexFormat
|
||||
import net.minecraft.client.gl.CompiledShader
|
||||
import net.minecraft.client.gl.Defines
|
||||
import net.minecraft.client.gl.ShaderProgramKey
|
||||
import net.minecraft.client.gl.ShaderProgram
|
||||
import net.minecraft.client.render.RenderPhase
|
||||
import net.minecraft.client.render.VertexFormat
|
||||
import net.minecraft.client.render.VertexFormats
|
||||
import moe.nea.firmament.Firmament
|
||||
import moe.nea.firmament.annotations.Subscribe
|
||||
@@ -11,20 +12,9 @@ import moe.nea.firmament.events.DebugInstantiateEvent
|
||||
import moe.nea.firmament.util.MC
|
||||
|
||||
object FirmamentShaders {
|
||||
val shaders = mutableListOf<ShaderProgramKey>()
|
||||
|
||||
private fun shader(name: String, format: VertexFormat, defines: Defines): ShaderProgramKey {
|
||||
val key = ShaderProgramKey(Firmament.identifier(name), format, defines)
|
||||
shaders.add(key)
|
||||
return key
|
||||
}
|
||||
|
||||
val LINES = RenderPhase.ShaderProgram(shader("core/rendertype_lines", VertexFormats.LINES, Defines.EMPTY))
|
||||
|
||||
@Subscribe
|
||||
fun debugLoad(event: DebugInstantiateEvent) {
|
||||
shaders.forEach {
|
||||
MC.instance.shaderLoader.getOrCreateProgram(it)
|
||||
}
|
||||
// TODO: do i still need to work with shaders like this?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,12 @@
|
||||
package moe.nea.firmament.util.render
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import io.github.notenoughupdates.moulconfig.platform.next
|
||||
import org.joml.Matrix4f
|
||||
import org.joml.Vector2f
|
||||
import util.render.CustomRenderLayers
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.tan
|
||||
import net.minecraft.client.gui.DrawContext
|
||||
import net.minecraft.client.render.BufferRenderer
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.RenderPhase
|
||||
import net.minecraft.client.render.Tessellator
|
||||
import net.minecraft.client.render.VertexFormat.DrawMode
|
||||
import net.minecraft.client.render.VertexFormats
|
||||
import net.minecraft.util.Identifier
|
||||
|
||||
object RenderCircleProgress {
|
||||
@@ -26,9 +20,8 @@ object RenderCircleProgress {
|
||||
v1: Float,
|
||||
v2: Float,
|
||||
) {
|
||||
RenderSystem.enableBlend()
|
||||
drawContext.draw {
|
||||
val bufferBuilder = it.getBuffer(GuiRenderLayers.GUI_TEXTURED_TRIS.apply(texture))
|
||||
val bufferBuilder = it.getBuffer(CustomRenderLayers.GUI_TEXTURED_NO_DEPTH_TRIS.apply(texture))
|
||||
val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix
|
||||
|
||||
val corners = listOf(
|
||||
@@ -86,7 +79,6 @@ object RenderCircleProgress {
|
||||
.next()
|
||||
}
|
||||
}
|
||||
RenderSystem.disableBlend()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,15 +5,12 @@ import io.github.notenoughupdates.moulconfig.platform.next
|
||||
import java.lang.Math.pow
|
||||
import org.joml.Matrix4f
|
||||
import org.joml.Vector3f
|
||||
import net.minecraft.client.gl.VertexBuffer
|
||||
import util.render.CustomRenderLayers
|
||||
import net.minecraft.client.render.Camera
|
||||
import net.minecraft.client.render.RenderLayer
|
||||
import net.minecraft.client.render.RenderPhase
|
||||
import net.minecraft.client.render.RenderTickCounter
|
||||
import net.minecraft.client.render.Tessellator
|
||||
import net.minecraft.client.render.VertexConsumer
|
||||
import net.minecraft.client.render.VertexConsumerProvider
|
||||
import net.minecraft.client.render.VertexFormat
|
||||
import net.minecraft.client.render.VertexFormats
|
||||
import net.minecraft.client.texture.Sprite
|
||||
import net.minecraft.client.util.math.MatrixStack
|
||||
@@ -27,47 +24,12 @@ import moe.nea.firmament.util.MC
|
||||
|
||||
@RenderContextDSL
|
||||
class RenderInWorldContext private constructor(
|
||||
private val tesselator: Tessellator,
|
||||
val matrixStack: MatrixStack,
|
||||
private val camera: Camera,
|
||||
private val tickCounter: RenderTickCounter,
|
||||
val vertexConsumers: VertexConsumerProvider.Immediate,
|
||||
) {
|
||||
|
||||
object RenderLayers {
|
||||
val TRANSLUCENT_TRIS = RenderLayer.of("firmament_translucent_tris",
|
||||
VertexFormats.POSITION_COLOR,
|
||||
VertexFormat.DrawMode.TRIANGLES,
|
||||
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||
false, true,
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||
.program(RenderPhase.POSITION_COLOR_PROGRAM)
|
||||
.build(false))
|
||||
val LINES = RenderLayer.of("firmament_rendertype_lines",
|
||||
VertexFormats.LINES,
|
||||
VertexFormat.DrawMode.LINES,
|
||||
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||
false, false, // do we need translucent? i dont think so
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||
.program(FirmamentShaders.LINES)
|
||||
.build(false)
|
||||
)
|
||||
val COLORED_QUADS = RenderLayer.of(
|
||||
"firmament_quads",
|
||||
VertexFormats.POSITION_COLOR,
|
||||
VertexFormat.DrawMode.QUADS,
|
||||
RenderLayer.CUTOUT_BUFFER_SIZE,
|
||||
false, true,
|
||||
RenderLayer.MultiPhaseParameters.builder()
|
||||
.depthTest(RenderPhase.ALWAYS_DEPTH_TEST)
|
||||
.program(RenderPhase.POSITION_COLOR_PROGRAM)
|
||||
.transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY)
|
||||
.build(false)
|
||||
)
|
||||
}
|
||||
|
||||
@Deprecated("stateful color management is no longer a thing")
|
||||
fun color(color: me.shedaniel.math.Color) {
|
||||
@@ -82,7 +44,7 @@ class RenderInWorldContext private constructor(
|
||||
fun block(blockPos: BlockPos, color: Int) {
|
||||
matrixStack.push()
|
||||
matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat())
|
||||
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(RenderLayers.COLORED_QUADS), color)
|
||||
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(CustomRenderLayers.COLORED_QUADS), color)
|
||||
matrixStack.pop()
|
||||
}
|
||||
|
||||
@@ -155,7 +117,7 @@ class RenderInWorldContext private constructor(
|
||||
matrixStack.translate(vec3d.x, vec3d.y, vec3d.z)
|
||||
matrixStack.scale(size, size, size)
|
||||
matrixStack.translate(-.5, -.5, -.5)
|
||||
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(RenderLayers.COLORED_QUADS), color)
|
||||
buildCube(matrixStack.peek().positionMatrix, vertexConsumers.getBuffer(CustomRenderLayers.COLORED_QUADS), color)
|
||||
matrixStack.pop()
|
||||
vertexConsumers.draw()
|
||||
}
|
||||
@@ -182,8 +144,7 @@ class RenderInWorldContext private constructor(
|
||||
|
||||
fun line(points: List<Vec3d>, lineWidth: Float = 10F) {
|
||||
RenderSystem.lineWidth(lineWidth)
|
||||
// TODO: replace with renderlayers
|
||||
val buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES)
|
||||
val buffer = vertexConsumers.getBuffer(CustomRenderLayers.LINES)
|
||||
|
||||
val matrix = matrixStack.peek()
|
||||
var lastNormal: Vector3f? = null
|
||||
@@ -203,7 +164,6 @@ class RenderInWorldContext private constructor(
|
||||
.next()
|
||||
}
|
||||
|
||||
RenderLayers.LINES.draw(buffer.end())
|
||||
}
|
||||
// TODO: put the favourite icons in front of items again
|
||||
|
||||
@@ -281,16 +241,15 @@ class RenderInWorldContext private constructor(
|
||||
fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) {
|
||||
// TODO: there should be *no more global state*. the only thing we should be doing is render layers. that includes settings like culling, blending, shader color, and depth testing
|
||||
// For now i will let these functions remain, but this needs to go before i do a full (non-beta) release
|
||||
RenderSystem.disableDepthTest()
|
||||
RenderSystem.enableBlend()
|
||||
RenderSystem.defaultBlendFunc()
|
||||
RenderSystem.disableCull()
|
||||
// RenderSystem.disableDepthTest()
|
||||
// RenderSystem.enableBlend()
|
||||
// RenderSystem.defaultBlendFunc()
|
||||
// RenderSystem.disableCull()
|
||||
|
||||
event.matrices.push()
|
||||
event.matrices.translate(-event.camera.pos.x, -event.camera.pos.y, -event.camera.pos.z)
|
||||
|
||||
val ctx = RenderInWorldContext(
|
||||
RenderSystem.renderThreadTesselator(),
|
||||
event.matrices,
|
||||
event.camera,
|
||||
event.tickCounter,
|
||||
@@ -302,10 +261,6 @@ class RenderInWorldContext private constructor(
|
||||
event.matrices.pop()
|
||||
event.vertexConsumers.draw()
|
||||
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
|
||||
VertexBuffer.unbind()
|
||||
RenderSystem.enableDepthTest()
|
||||
RenderSystem.enableCull()
|
||||
RenderSystem.disableBlend()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package moe.nea.firmament.util.render
|
||||
|
||||
import com.mojang.blaze3d.platform.GlConst
|
||||
import com.mojang.blaze3d.systems.RenderSystem
|
||||
import me.shedaniel.math.Color
|
||||
import net.minecraft.client.render.OverlayTexture
|
||||
import net.minecraft.util.math.ColorHelper
|
||||
@@ -29,16 +27,9 @@ class TintedOverlayTexture : OverlayTexture() {
|
||||
}
|
||||
}
|
||||
|
||||
RenderSystem.activeTexture(GlConst.GL_TEXTURE1)
|
||||
texture.bindTexture()
|
||||
texture.setFilter(false, false)
|
||||
texture.setClamp(true)
|
||||
image.upload(0,
|
||||
0, 0,
|
||||
0, 0,
|
||||
image.width, image.height,
|
||||
false)
|
||||
RenderSystem.activeTexture(GlConst.GL_TEXTURE0)
|
||||
texture.upload()
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ object SackUtil {
|
||||
|
||||
fun updateFromHoverText(text: Text) {
|
||||
text.siblings.forEach(::updateFromHoverText)
|
||||
val hoverText = text.style.hoverEvent?.getValue(HoverEvent.Action.SHOW_TEXT) ?: return
|
||||
val hoverText = (text.style.hoverEvent as? HoverEvent.ShowText)?.value ?: return
|
||||
val cleanedText = hoverText.unformattedString
|
||||
if (cleanedText.startsWith("Added items:\n")) {
|
||||
if (!foundAdded) {
|
||||
|
||||
@@ -127,13 +127,13 @@ fun MutableText.darkGrey() = withColor(Formatting.DARK_GRAY)
|
||||
fun MutableText.red() = withColor(Formatting.RED)
|
||||
fun MutableText.white() = withColor(Formatting.WHITE)
|
||||
fun MutableText.bold(): MutableText = styled { it.withBold(true) }
|
||||
fun MutableText.hover(text: Text): MutableText = styled {it.withHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT, text))}
|
||||
fun MutableText.hover(text: Text): MutableText = styled {it.withHoverEvent(HoverEvent.ShowText(text))}
|
||||
|
||||
|
||||
fun MutableText.clickCommand(command: String): MutableText {
|
||||
require(command.startsWith("/"))
|
||||
return this.styled {
|
||||
it.withClickEvent(ClickEvent(ClickEvent.Action.RUN_COMMAND, command))
|
||||
it.withClickEvent(ClickEvent.RunCommand(command))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,9 +9,6 @@ accessible class net/minecraft/registry/RegistryOps$CachedRegistryInfoGetter
|
||||
|
||||
accessible field net/minecraft/entity/mob/CreeperEntity CHARGED Lnet/minecraft/entity/data/TrackedData;
|
||||
accessible method net/minecraft/entity/decoration/ArmorStandEntity setSmall (Z)V
|
||||
accessible field net/minecraft/entity/passive/AbstractHorseEntity items Lnet/minecraft/inventory/SimpleInventory;
|
||||
accessible field net/minecraft/entity/passive/AbstractHorseEntity SADDLED_FLAG I
|
||||
accessible field net/minecraft/entity/passive/AbstractHorseEntity HORSE_FLAGS Lnet/minecraft/entity/data/TrackedData;
|
||||
accessible method net/minecraft/resource/NamespaceResourceManager loadMetadata (Lnet/minecraft/resource/InputSupplier;)Lnet/minecraft/resource/metadata/ResourceMetadata;
|
||||
accessible method net/minecraft/client/gui/DrawContext drawTexturedQuad (Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIIIFFFFI)V
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ import kotlinx.serialization.serializer
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import net.minecraft.block.Block
|
||||
import net.minecraft.block.BlockState
|
||||
import net.minecraft.client.render.model.BakedModel
|
||||
import net.minecraft.client.util.ModelIdentifier
|
||||
import net.minecraft.client.render.item.model.ItemModel
|
||||
import net.minecraft.client.render.model.BlockStateModel
|
||||
import net.minecraft.registry.RegistryKey
|
||||
import net.minecraft.registry.RegistryKeys
|
||||
import net.minecraft.resource.ResourceManager
|
||||
@@ -57,11 +57,11 @@ object CustomBlockTextures {
|
||||
) {
|
||||
|
||||
@Transient
|
||||
val blockModelIdentifier get() = ModelIdentifier(block.withPrefixedPath("block/"), "firmament")
|
||||
val blockModelIdentifier get() = block.withPrefixedPath("block/")
|
||||
|
||||
@Transient
|
||||
val bakedModel: BakedModel by lazy(LazyThreadSafetyMode.NONE) {
|
||||
MC.instance.bakedModelManager.getModel(blockModelIdentifier)
|
||||
val bakedModel: ItemModel by lazy(LazyThreadSafetyMode.NONE) {
|
||||
MC.instance.bakedModelManager.blockModels.(blockModelIdentifier)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@@ -189,7 +189,7 @@ object CustomBlockTextures {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getReplacementModel(block: BlockState, blockPos: BlockPos?): BakedModel? {
|
||||
fun getReplacementModel(block: BlockState, blockPos: BlockPos?): BlockStateModel? {
|
||||
return getReplacement(block, blockPos)?.bakedModel
|
||||
}
|
||||
|
||||
@@ -269,11 +269,6 @@ object CustomBlockTextures {
|
||||
return BakedReplacements(map.mapValues { LocationReplacements(it.value) })
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun patchIndigo(orig: BakedModel, pos: BlockPos, state: BlockState): BakedModel {
|
||||
return getReplacementModel(state, pos) ?: orig
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
fun onStart(event: FinalizeResourceManagerEvent) {
|
||||
event.resourceManager.registerReloader(object :
|
||||
|
||||
@@ -81,7 +81,11 @@ object CustomGlobalArmorOverrides {
|
||||
null,
|
||||
Optional.of(RegistryKey.of(EquipmentAssetKeys.REGISTRY_KEY, model)),
|
||||
Optional.empty(),
|
||||
Optional.empty(), false, false, false
|
||||
Optional.empty(),
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.slf4j.LoggerFactory
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import net.minecraft.client.util.ModelIdentifier
|
||||
import net.minecraft.resource.ResourceManager
|
||||
import net.minecraft.resource.SinglePreparationResourceReloader
|
||||
import net.minecraft.text.Text
|
||||
|
||||
@@ -9,12 +9,11 @@ import net.minecraft.client.render.item.ItemRenderState
|
||||
import net.minecraft.client.render.item.model.BasicItemModel
|
||||
import net.minecraft.client.render.item.model.ItemModel
|
||||
import net.minecraft.client.render.item.model.ItemModelTypes
|
||||
import net.minecraft.client.render.item.tint.TintSource
|
||||
import net.minecraft.client.render.model.ResolvableModel
|
||||
import net.minecraft.client.world.ClientWorld
|
||||
import net.minecraft.entity.LivingEntity
|
||||
import net.minecraft.item.ItemDisplayContext
|
||||
import net.minecraft.item.ItemStack
|
||||
import net.minecraft.item.ModelTransformationMode
|
||||
import net.minecraft.util.Identifier
|
||||
import moe.nea.firmament.features.texturepack.predicates.AndPredicate
|
||||
|
||||
@@ -29,10 +28,10 @@ class PredicateModel {
|
||||
)
|
||||
|
||||
override fun update(
|
||||
state: ItemRenderState,
|
||||
state: ItemRenderState?,
|
||||
stack: ItemStack,
|
||||
resolver: ItemModelManager,
|
||||
transformationMode: ModelTransformationMode,
|
||||
resolver: ItemModelManager?,
|
||||
displayContext: ItemDisplayContext?,
|
||||
world: ClientWorld?,
|
||||
user: LivingEntity?,
|
||||
seed: Int
|
||||
@@ -42,7 +41,7 @@ class PredicateModel {
|
||||
.findLast { it.predicate.test(stack, user) }
|
||||
?.model
|
||||
?: fallback
|
||||
model.update(state, stack, resolver, transformationMode, world, user, seed)
|
||||
model.update(state, stack, resolver, displayContext, world, user, seed)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import net.minecraft.nbt.NbtString
|
||||
import net.minecraft.text.Text
|
||||
import moe.nea.firmament.util.MC
|
||||
@@ -26,7 +27,7 @@ interface StringMatcher {
|
||||
}
|
||||
|
||||
fun matches(nbt: NbtString): Boolean {
|
||||
val string = nbt.asString()
|
||||
val string = nbt.value
|
||||
val jsonStart = string.indexOf('{')
|
||||
val stringStart = string.indexOf('"')
|
||||
val isString = stringStart >= 0 && string.subSequence(0, stringStart).isBlank()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
package moe.nea.firmament.features.texturepack.predicates
|
||||
|
||||
import com.google.gson.Gson
|
||||
@@ -5,8 +6,9 @@ import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.JsonPrimitive
|
||||
import com.mojang.serialization.JsonOps
|
||||
import kotlin.jvm.optionals.getOrDefault
|
||||
import kotlin.jvm.optionals.getOrNull
|
||||
import com.mojang.serialization.JsonOps
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicate
|
||||
import moe.nea.firmament.features.texturepack.FirmamentModelPredicateParser
|
||||
import moe.nea.firmament.features.texturepack.StringMatcher
|
||||
|
||||
@@ -7,16 +7,17 @@ import moe.nea.firmament.features.texturepack.CustomBlockTextures;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.block.BlockModels;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.chunk.SectionBuilder;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.render.model.BlockStateModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
||||
@Mixin(BlockRenderManager.class)
|
||||
@Mixin(SectionBuilder.class)
|
||||
public class ReplaceBlockRenderManagerBlockModel {
|
||||
@WrapOperation(method = "renderBlock", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;"))
|
||||
private BakedModel replaceModelInRenderBlock(
|
||||
BlockRenderManager instance, BlockState state, Operation<BakedModel> original, @Local(argsOnly = true) BlockPos pos) {
|
||||
@WrapOperation(method = "build", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BlockStateModel;"))
|
||||
private BlockStateModel replaceModelInRenderBlock(BlockRenderManager instance, BlockState state, Operation<BlockStateModel> original, @Local(argsOnly = true) BlockPos pos) {
|
||||
var replacement = CustomBlockTextures.getReplacementModel(state, pos);
|
||||
if (replacement != null) return replacement;
|
||||
CustomBlockTextures.enterFallbackCall();
|
||||
|
||||
Reference in New Issue
Block a user