1.21.3 WIP

This commit is contained in:
Linnea Gräf
2024-11-03 01:24:24 +01:00
parent 646843ba3b
commit 22f0cc59a2
105 changed files with 2854 additions and 2646 deletions

View File

@@ -1,4 +1,3 @@
package moe.nea.firmament.gui
import com.mojang.blaze3d.systems.RenderSystem
@@ -10,116 +9,115 @@ import io.github.notenoughupdates.moulconfig.observer.GetSetter
import io.github.notenoughupdates.moulconfig.platform.ModernRenderContext
import me.shedaniel.math.Color
import net.minecraft.client.gui.DrawContext
import net.minecraft.client.render.RenderLayer
import net.minecraft.util.Identifier
import moe.nea.firmament.Firmament
class BarComponent(
val progress: GetSetter<Double>, val total: GetSetter<Double>,
val fillColor: Color,
val emptyColor: Color,
val progress: GetSetter<Double>, val total: GetSetter<Double>,
val fillColor: Color,
val emptyColor: Color,
) : GuiComponent() {
override fun getWidth(): Int {
return 80
}
override fun getWidth(): Int {
return 80
}
override fun getHeight(): Int {
return 8
}
override fun getHeight(): Int {
return 8
}
data class Texture(
val identifier: Identifier,
val u1: Float, val v1: Float,
val u2: Float, val v2: Float,
) {
fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) {
context.drawTexturedQuad(
identifier,
x, y, x + width, x + height, 0,
u1, u2, v1, v2,
color.red / 255F,
color.green / 255F,
color.blue / 255F,
color.alpha / 255F,
)
}
}
data class Texture(
val identifier: Identifier,
val u1: Float, val v1: Float,
val u2: Float, val v2: Float,
) {
fun draw(context: DrawContext, x: Int, y: Int, width: Int, height: Int, color: Color) {
context.drawTexturedQuad(
RenderLayer::getGuiTextured,
identifier,
x, y, x + width, x + height,
u1, u2, v1, v2,
color.color
)
}
}
companion object {
val resource = Firmament.identifier("textures/gui/bar.png")
val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F)
val middle = Texture(resource, 4 / 64F, 0 / 64F, 8 / 64F, 8 / 64F)
val right = Texture(resource, 8 / 64F, 0 / 64F, 12 / 64F, 8 / 64F)
val segmentOverlay = Texture(resource, 12 / 64F, 0 / 64F, 15 / 64F, 8 / 64F)
}
companion object {
val resource = Firmament.identifier("textures/gui/bar.png")
val left = Texture(resource, 0 / 64F, 0 / 64F, 4 / 64F, 8 / 64F)
val middle = Texture(resource, 4 / 64F, 0 / 64F, 8 / 64F, 8 / 64F)
val right = Texture(resource, 8 / 64F, 0 / 64F, 12 / 64F, 8 / 64F)
val segmentOverlay = Texture(resource, 12 / 64F, 0 / 64F, 15 / 64F, 8 / 64F)
}
private fun drawSection(
context: DrawContext,
texture: Texture,
x: Int,
y: Int,
width: Int,
sectionStart: Double,
sectionEnd: Double
) {
if (sectionEnd < progress.get() && width == 4) {
texture.draw(context, x, y, 4, 8, fillColor)
return
}
if (sectionStart > progress.get() && width == 4) {
texture.draw(context, x, y, 4, 8, emptyColor)
return
}
val increasePerPixel = (sectionEnd - sectionStart) / width
var valueAtPixel = sectionStart
for (i in (0 until width)) {
val newTex =
Texture(texture.identifier, texture.u1 + i / 64F, texture.v1, texture.u1 + (i + 1) / 64F, texture.v2)
newTex.draw(
context, x + i, y, 1, 8,
if (valueAtPixel < progress.get()) fillColor else emptyColor
)
valueAtPixel += increasePerPixel
}
}
private fun drawSection(
context: DrawContext,
texture: Texture,
x: Int,
y: Int,
width: Int,
sectionStart: Double,
sectionEnd: Double
) {
if (sectionEnd < progress.get() && width == 4) {
texture.draw(context, x, y, 4, 8, fillColor)
return
}
if (sectionStart > progress.get() && width == 4) {
texture.draw(context, x, y, 4, 8, emptyColor)
return
}
val increasePerPixel = (sectionEnd - sectionStart) / width
var valueAtPixel = sectionStart
for (i in (0 until width)) {
val newTex =
Texture(texture.identifier, texture.u1 + i / 64F, texture.v1, texture.u1 + (i + 1) / 64F, texture.v2)
newTex.draw(
context, x + i, y, 1, 8,
if (valueAtPixel < progress.get()) fillColor else emptyColor
)
valueAtPixel += increasePerPixel
}
}
override fun render(context: GuiImmediateContext) {
val renderContext = (context.renderContext as ModernRenderContext).drawContext
var i = 0
val x = 0
val y = 0
while (i < context.width - 4) {
drawSection(
renderContext,
if (i == 0) left else middle,
x + i, y,
(context.width - (i + 4)).coerceAtMost(4),
i * total.get() / context.width, (i + 4) * total.get() / context.width
)
i += 4
}
drawSection(
renderContext,
right,
x + context.width - 4,
y,
4,
(context.width - 4) * total.get() / context.width,
total.get()
)
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
override fun render(context: GuiImmediateContext) {
val renderContext = (context.renderContext as ModernRenderContext).drawContext
var i = 0
val x = 0
val y = 0
while (i < context.width - 4) {
drawSection(
renderContext,
if (i == 0) left else middle,
x + i, y,
(context.width - (i + 4)).coerceAtMost(4),
i * total.get() / context.width, (i + 4) * total.get() / context.width
)
i += 4
}
drawSection(
renderContext,
right,
x + context.width - 4,
y,
4,
(context.width - 4) * total.get() / context.width,
total.get()
)
RenderSystem.setShaderColor(1F, 1F, 1F, 1F)
}
}
}
fun Identifier.toMoulConfig(): MyResourceLocation {
return MyResourceLocation(this.namespace, this.path)
return MyResourceLocation(this.namespace, this.path)
}
fun RenderContext.color(color: Color) {
color(color.red, color.green, color.blue, color.alpha)
color(color.red, color.green, color.blue, color.alpha)
}
fun RenderContext.color(red: Int, green: Int, blue: Int, alpha: Int) {
color(red / 255f, green / 255f, blue / 255f, alpha / 255f)
color(red / 255f, green / 255f, blue / 255f, alpha / 255f)
}

View File

@@ -1,4 +1,3 @@
package moe.nea.firmament.gui.entity
import com.google.gson.Gson
@@ -13,7 +12,9 @@ import net.minecraft.client.gui.screen.ingame.InventoryScreen
import net.minecraft.entity.Entity
import net.minecraft.entity.EntityType
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.SpawnReason
import net.minecraft.util.Identifier
import net.minecraft.world.World
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.assertNotNullOr
import moe.nea.firmament.util.iterate
@@ -21,177 +22,177 @@ import moe.nea.firmament.util.openFirmamentResource
import moe.nea.firmament.util.render.enableScissorWithTranslation
object EntityRenderer {
val fakeWorld = FakeWorld()
private fun <T : Entity> t(entityType: EntityType<T>): () -> T {
return { entityType.create(fakeWorld)!! }
}
val fakeWorld: World get() = MC.lastWorld!!
private fun <T : Entity> t(entityType: EntityType<T>): () -> T {
return { entityType.create(fakeWorld, SpawnReason.LOAD)!! }
}
val entityIds: Map<String, () -> LivingEntity> = mapOf(
"Zombie" to t(EntityType.ZOMBIE),
"Chicken" to t(EntityType.CHICKEN),
"Slime" to t(EntityType.SLIME),
"Wolf" to t(EntityType.WOLF),
"Skeleton" to t(EntityType.SKELETON),
"Creeper" to t(EntityType.CREEPER),
"Ocelot" to t(EntityType.OCELOT),
"Blaze" to t(EntityType.BLAZE),
"Rabbit" to t(EntityType.RABBIT),
"Sheep" to t(EntityType.SHEEP),
"Horse" to t(EntityType.HORSE),
"Eisengolem" to t(EntityType.IRON_GOLEM),
"Silverfish" to t(EntityType.SILVERFISH),
"Witch" to t(EntityType.WITCH),
"Endermite" to t(EntityType.ENDERMITE),
"Snowman" to t(EntityType.SNOW_GOLEM),
"Villager" to t(EntityType.VILLAGER),
"Guardian" to t(EntityType.GUARDIAN),
"ArmorStand" to t(EntityType.ARMOR_STAND),
"Squid" to t(EntityType.SQUID),
"Bat" to t(EntityType.BAT),
"Spider" to t(EntityType.SPIDER),
"CaveSpider" to t(EntityType.CAVE_SPIDER),
"Pigman" to t(EntityType.ZOMBIFIED_PIGLIN),
"Ghast" to t(EntityType.GHAST),
"MagmaCube" to t(EntityType.MAGMA_CUBE),
"Wither" to t(EntityType.WITHER),
"Enderman" to t(EntityType.ENDERMAN),
"Mooshroom" to t(EntityType.MOOSHROOM),
"WitherSkeleton" to t(EntityType.WITHER_SKELETON),
"Cow" to t(EntityType.COW),
"Dragon" to t(EntityType.ENDER_DRAGON),
"Player" to { makeGuiPlayer(fakeWorld) },
"Pig" to t(EntityType.PIG),
"Giant" to t(EntityType.GIANT),
)
val entityModifiers: Map<String, EntityModifier> = mapOf(
"playerdata" to ModifyPlayerSkin,
"equipment" to ModifyEquipment,
"riding" to ModifyRiding,
"charged" to ModifyCharged,
"witherdata" to ModifyWither,
"invisible" to ModifyInvisible,
"age" to ModifyAge,
"horse" to ModifyHorse,
"name" to ModifyName,
)
val entityIds: Map<String, () -> LivingEntity> = mapOf(
"Zombie" to t(EntityType.ZOMBIE),
"Chicken" to t(EntityType.CHICKEN),
"Slime" to t(EntityType.SLIME),
"Wolf" to t(EntityType.WOLF),
"Skeleton" to t(EntityType.SKELETON),
"Creeper" to t(EntityType.CREEPER),
"Ocelot" to t(EntityType.OCELOT),
"Blaze" to t(EntityType.BLAZE),
"Rabbit" to t(EntityType.RABBIT),
"Sheep" to t(EntityType.SHEEP),
"Horse" to t(EntityType.HORSE),
"Eisengolem" to t(EntityType.IRON_GOLEM),
"Silverfish" to t(EntityType.SILVERFISH),
"Witch" to t(EntityType.WITCH),
"Endermite" to t(EntityType.ENDERMITE),
"Snowman" to t(EntityType.SNOW_GOLEM),
"Villager" to t(EntityType.VILLAGER),
"Guardian" to t(EntityType.GUARDIAN),
"ArmorStand" to t(EntityType.ARMOR_STAND),
"Squid" to t(EntityType.SQUID),
"Bat" to t(EntityType.BAT),
"Spider" to t(EntityType.SPIDER),
"CaveSpider" to t(EntityType.CAVE_SPIDER),
"Pigman" to t(EntityType.ZOMBIFIED_PIGLIN),
"Ghast" to t(EntityType.GHAST),
"MagmaCube" to t(EntityType.MAGMA_CUBE),
"Wither" to t(EntityType.WITHER),
"Enderman" to t(EntityType.ENDERMAN),
"Mooshroom" to t(EntityType.MOOSHROOM),
"WitherSkeleton" to t(EntityType.WITHER_SKELETON),
"Cow" to t(EntityType.COW),
"Dragon" to t(EntityType.ENDER_DRAGON),
"Player" to { makeGuiPlayer(fakeWorld) },
"Pig" to t(EntityType.PIG),
"Giant" to t(EntityType.GIANT),
)
val entityModifiers: Map<String, EntityModifier> = mapOf(
"playerdata" to ModifyPlayerSkin,
"equipment" to ModifyEquipment,
"riding" to ModifyRiding,
"charged" to ModifyCharged,
"witherdata" to ModifyWither,
"invisible" to ModifyInvisible,
"age" to ModifyAge,
"horse" to ModifyHorse,
"name" to ModifyName,
)
val logger = LogManager.getLogger("Firmament.Entity")
fun applyModifiers(entityId: String, modifiers: List<JsonObject>): LivingEntity? {
val entityType = assertNotNullOr(entityIds[entityId]) {
logger.error("Could not create entity with id $entityId")
return null
}
var entity = entityType()
for (modifierJson in modifiers) {
val modifier = assertNotNullOr(modifierJson["type"]?.asString?.let(entityModifiers::get)) {
logger.error("Unknown modifier $modifierJson")
return null
}
entity = modifier.apply(entity, modifierJson)
}
return entity
}
val logger = LogManager.getLogger("Firmament.Entity")
fun applyModifiers(entityId: String, modifiers: List<JsonObject>): LivingEntity? {
val entityType = assertNotNullOr(entityIds[entityId]) {
logger.error("Could not create entity with id $entityId")
return null
}
var entity = entityType()
for (modifierJson in modifiers) {
val modifier = assertNotNullOr(modifierJson["type"]?.asString?.let(entityModifiers::get)) {
logger.error("Unknown modifier $modifierJson")
return null
}
entity = modifier.apply(entity, modifierJson)
}
return entity
}
fun constructEntity(info: JsonObject): LivingEntity? {
val modifiers = (info["modifiers"] as JsonArray?)?.map { it.asJsonObject } ?: emptyList()
val entityType = assertNotNullOr(info["entity"]?.asString) {
logger.error("Missing entity type on entity object")
return null
}
return applyModifiers(entityType, modifiers)
}
fun constructEntity(info: JsonObject): LivingEntity? {
val modifiers = (info["modifiers"] as JsonArray?)?.map { it.asJsonObject } ?: emptyList()
val entityType = assertNotNullOr(info["entity"]?.asString) {
logger.error("Missing entity type on entity object")
return null
}
return applyModifiers(entityType, modifiers)
}
private val gson = Gson()
fun constructEntity(location: Identifier): LivingEntity? {
return constructEntity(
gson.fromJson(
location.openFirmamentResource().bufferedReader(), JsonObject::class.java
)
)
}
private val gson = Gson()
fun constructEntity(location: Identifier): LivingEntity? {
return constructEntity(
gson.fromJson(
location.openFirmamentResource().bufferedReader(), JsonObject::class.java
)
)
}
fun renderEntity(
entity: LivingEntity,
renderContext: DrawContext,
posX: Int,
posY: Int,
mouseX: Float,
mouseY: Float
) {
var bottomOffset = 0.0F
var currentEntity = entity
val maxSize = entity.iterate { it.firstPassenger as? LivingEntity }
.map { it.height }
.sum()
while (true) {
currentEntity.age = MC.player?.age ?: 0
drawEntity(
renderContext,
posX,
posY,
posX + 50,
posY + 80,
minOf(2F / maxSize, 1F) * 30,
-bottomOffset,
mouseX,
mouseY,
currentEntity
)
val next = currentEntity.firstPassenger as? LivingEntity ?: break
bottomOffset += currentEntity.getPassengerRidingPos(next).y.toFloat() * 0.75F
currentEntity = next
}
}
fun renderEntity(
entity: LivingEntity,
renderContext: DrawContext,
posX: Int,
posY: Int,
mouseX: Float,
mouseY: Float
) {
var bottomOffset = 0.0F
var currentEntity = entity
val maxSize = entity.iterate { it.firstPassenger as? LivingEntity }
.map { it.height }
.sum()
while (true) {
currentEntity.age = MC.player?.age ?: 0
drawEntity(
renderContext,
posX,
posY,
posX + 50,
posY + 80,
minOf(2F / maxSize, 1F) * 30,
-bottomOffset,
mouseX,
mouseY,
currentEntity
)
val next = currentEntity.firstPassenger as? LivingEntity ?: break
bottomOffset += currentEntity.getPassengerRidingPos(next).y.toFloat() * 0.75F
currentEntity = next
}
}
fun drawEntity(
context: DrawContext,
x1: Int,
y1: Int,
x2: Int,
y2: Int,
size: Float,
bottomOffset: Float,
mouseX: Float,
mouseY: Float,
entity: LivingEntity
) {
context.enableScissorWithTranslation(x1.toFloat(), y1.toFloat(), x2.toFloat(), y2.toFloat())
val centerX = (x1 + x2) / 2f
val centerY = (y1 + y2) / 2f
val targetYaw = atan(((centerX - mouseX) / 40.0f).toDouble()).toFloat()
val targetPitch = atan(((centerY - mouseY) / 40.0f).toDouble()).toFloat()
val rotateToFaceTheFront = Quaternionf().rotateZ(Math.PI.toFloat())
val rotateToFaceTheCamera = Quaternionf().rotateX(targetPitch * 20.0f * (Math.PI.toFloat() / 180))
rotateToFaceTheFront.mul(rotateToFaceTheCamera)
val oldBodyYaw = entity.bodyYaw
val oldYaw = entity.yaw
val oldPitch = entity.pitch
val oldPrevHeadYaw = entity.prevHeadYaw
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
val vector3f = Vector3f(0.0f, entity.height / 2.0f + bottomOffset, 0.0f)
InventoryScreen.drawEntity(
context,
centerX,
centerY,
size,
vector3f,
rotateToFaceTheFront,
rotateToFaceTheCamera,
entity
)
entity.bodyYaw = oldBodyYaw
entity.yaw = oldYaw
entity.pitch = oldPitch
entity.prevHeadYaw = oldPrevHeadYaw
entity.headYaw = oldHeadYaw
context.disableScissor()
}
fun drawEntity(
context: DrawContext,
x1: Int,
y1: Int,
x2: Int,
y2: Int,
size: Float,
bottomOffset: Float,
mouseX: Float,
mouseY: Float,
entity: LivingEntity
) {
context.enableScissorWithTranslation(x1.toFloat(), y1.toFloat(), x2.toFloat(), y2.toFloat())
val centerX = (x1 + x2) / 2f
val centerY = (y1 + y2) / 2f
val targetYaw = atan(((centerX - mouseX) / 40.0f).toDouble()).toFloat()
val targetPitch = atan(((centerY - mouseY) / 40.0f).toDouble()).toFloat()
val rotateToFaceTheFront = Quaternionf().rotateZ(Math.PI.toFloat())
val rotateToFaceTheCamera = Quaternionf().rotateX(targetPitch * 20.0f * (Math.PI.toFloat() / 180))
rotateToFaceTheFront.mul(rotateToFaceTheCamera)
val oldBodyYaw = entity.bodyYaw
val oldYaw = entity.yaw
val oldPitch = entity.pitch
val oldPrevHeadYaw = entity.prevHeadYaw
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
val vector3f = Vector3f(0.0f, entity.height / 2.0f + bottomOffset, 0.0f)
InventoryScreen.drawEntity(
context,
centerX,
centerY,
size,
vector3f,
rotateToFaceTheFront,
rotateToFaceTheCamera,
entity
)
entity.bodyYaw = oldBodyYaw
entity.yaw = oldYaw
entity.pitch = oldPitch
entity.prevHeadYaw = oldPrevHeadYaw
entity.headYaw = oldHeadYaw
context.disableScissor()
}
}

View File

@@ -1,38 +1,37 @@
package moe.nea.firmament.gui.entity
import com.mojang.datafixers.util.Pair
import com.mojang.serialization.Lifecycle
import java.util.*
import java.util.UUID
import java.util.function.BooleanSupplier
import java.util.function.Consumer
import java.util.stream.Stream
import kotlin.jvm.optionals.getOrNull
import kotlin.streams.asSequence
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.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.Ingredient
import net.minecraft.recipe.RecipeManager
import net.minecraft.registry.BuiltinRegistries
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.Registry
import net.minecraft.registry.Registries
import net.minecraft.registry.RegistryKey
import net.minecraft.registry.RegistryKeys
import net.minecraft.registry.RegistryWrapper
import net.minecraft.registry.ServerDynamicRegistryType
import net.minecraft.registry.entry.RegistryEntry
import net.minecraft.registry.entry.RegistryEntryInfo
import net.minecraft.registry.entry.RegistryEntryList
import net.minecraft.registry.entry.RegistryEntryOwner
import net.minecraft.registry.tag.TagKey
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
@@ -43,11 +42,8 @@ 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.util.math.random.Random
import net.minecraft.util.profiler.DummyProfiler
import net.minecraft.world.BlockView
import net.minecraft.world.Difficulty
import net.minecraft.world.GameRules
import net.minecraft.world.MutableWorldProperties
import net.minecraft.world.World
import net.minecraft.world.biome.Biome
@@ -59,430 +55,284 @@ 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
fun <T> makeRegistry(registryWrapper: RegistryWrapper.Impl<T>, key: RegistryKey<out Registry<T>>): Registry<T> {
val inverseLookup = registryWrapper.streamEntries()
.asSequence().map { it.value() to it.registryKey() }
.toMap()
val idLookup = registryWrapper.streamEntries()
.asSequence()
.map { it.registryKey() }
.withIndex()
.associate { it.value to it.index }
val map = registryWrapper.streamEntries().asSequence().map { it.registryKey() to it.value() }.toMap(mutableMapOf())
val inverseIdLookup = idLookup.asIterable().associate { (k, v) -> v to k }
return object : Registry<T> {
override fun get(key: RegistryKey<T>?): T? {
return registryWrapper.getOptional(key).getOrNull()?.value()
}
override fun iterator(): MutableIterator<T> {
return object : MutableIterator<T> {
val iterator = registryWrapper.streamEntries().iterator()
override fun hasNext(): Boolean {
return iterator.hasNext()
}
override fun next(): T {
return iterator.next().value()
}
override fun remove() {
TODO("Not yet implemented")
}
}
}
override fun getRawId(value: T?): Int {
return idLookup[inverseLookup[value ?: return -1] ?: return -1] ?: return -1
}
override fun get(id: Identifier?): T? {
return get(RegistryKey.of(key, id))
}
override fun get(index: Int): T? {
return get(inverseIdLookup[index] ?: return null)
}
override fun size(): Int {
return idLookup.size
}
override fun getKey(): RegistryKey<out Registry<T>> {
return key
}
override fun getEntryInfo(key: RegistryKey<T>?): Optional<RegistryEntryInfo> {
TODO("Not yet implemented")
}
override fun getLifecycle(): Lifecycle {
return Lifecycle.stable()
}
override fun getDefaultEntry(): Optional<RegistryEntry.Reference<T>> {
return Optional.empty()
}
override fun getIds(): MutableSet<Identifier> {
return idLookup.keys.mapTo(mutableSetOf()) { it.value }
}
override fun getEntrySet(): MutableSet<MutableMap.MutableEntry<RegistryKey<T>, T>> {
return map.entries
}
override fun getKeys(): MutableSet<RegistryKey<T>> {
return map.keys
}
override fun getRandom(random: Random?): Optional<RegistryEntry.Reference<T>> {
return registryWrapper.streamEntries().findFirst()
}
override fun containsId(id: Identifier?): Boolean {
return idLookup.containsKey(RegistryKey.of(key, id ?: return false))
}
override fun freeze(): Registry<T> {
return this
}
override fun getEntry(rawId: Int): Optional<RegistryEntry.Reference<T>> {
val x = inverseIdLookup[rawId] ?: return Optional.empty()
return Optional.of(RegistryEntry.Reference.standAlone(registryWrapper, x))
}
override fun streamEntries(): Stream<RegistryEntry.Reference<T>> {
return registryWrapper.streamEntries()
}
override fun streamTagsAndEntries(): Stream<Pair<TagKey<T>, RegistryEntryList.Named<T>>> {
return streamTags().map { Pair(it, getOrCreateEntryList(it)) }
}
override fun streamTags(): Stream<TagKey<T>> {
return registryWrapper.streamTagKeys()
}
override fun clearTags() {
}
override fun getEntryOwner(): RegistryEntryOwner<T> {
return registryWrapper
}
override fun getReadOnlyWrapper(): RegistryWrapper.Impl<T> {
return registryWrapper
}
override fun populateTags(tagEntries: MutableMap<TagKey<T>, MutableList<RegistryEntry<T>>>?) {
}
override fun getOrCreateEntryList(tag: TagKey<T>?): RegistryEntryList.Named<T> {
return getEntryList(tag).orElseGet { RegistryEntryList.of(registryWrapper, tag) }
}
override fun getEntryList(tag: TagKey<T>?): Optional<RegistryEntryList.Named<T>> {
return registryWrapper.getOptional(tag ?: return Optional.empty())
}
override fun getEntry(value: T): RegistryEntry<T> {
return registryWrapper.getOptional(inverseLookup[value]!!).get()
}
override fun getEntry(key: RegistryKey<T>?): Optional<RegistryEntry.Reference<T>> {
return registryWrapper.getOptional(key ?: return Optional.empty())
}
override fun getEntry(id: Identifier?): Optional<RegistryEntry.Reference<T>> {
TODO("Not yet implemented")
}
override fun createEntry(value: T): RegistryEntry.Reference<T> {
TODO("Not yet implemented")
}
override fun contains(key: RegistryKey<T>?): Boolean {
return getEntry(key).isPresent
}
override fun getId(value: T): Identifier? {
return (inverseLookup[value] ?: return null).value
}
override fun getKey(entry: T): Optional<RegistryKey<T>> {
return Optional.ofNullable(inverseLookup[entry ?: return Optional.empty()])
}
}
}
import moe.nea.firmament.util.MC
fun createDynamicRegistry(): DynamicRegistryManager.Immutable {
val wrapperLookup = BuiltinRegistries.createWrapperLookup()
return object : DynamicRegistryManager.Immutable {
override fun <E : Any?> getOptional(key: RegistryKey<out Registry<out E>>): Optional<Registry<E>> {
val lookup = wrapperLookup.getOptionalWrapper(key).getOrNull() ?: return Optional.empty()
val registry = makeRegistry(lookup, key as RegistryKey<out Registry<E>>)
return Optional.of(registry)
}
fun <T> entry(reg: RegistryKey<out Registry<T>>): DynamicRegistryManager.Entry<T> {
return DynamicRegistryManager.Entry(reg, getOptional(reg).get())
}
override fun streamAllRegistries(): Stream<DynamicRegistryManager.Entry<*>> {
return wrapperLookup.streamAllRegistryKeys()
.map { entry(it as RegistryKey<out Registry<Any>>) }
}
}
// TODO: use SaveLoading.load() to properly load a full registry
return DynamicRegistryManager.of(Registries.REGISTRIES)
}
class FakeWorld(
registries: DynamicRegistryManager.Immutable = createDynamicRegistry(),
registries: DynamicRegistryManager.Immutable = createDynamicRegistry(),
) : World(
Properties,
RegistryKey.of(RegistryKeys.WORLD, Identifier.of("firmament", "fakeworld")),
registries,
registries[RegistryKeys.DIMENSION_TYPE].entryOf(
RegistryKey.of(
RegistryKeys.DIMENSION_TYPE,
Identifier.of("minecraft", "overworld")
)
),
{ DummyProfiler.INSTANCE },
true,
false,
0, 0
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
}
object Properties : MutableWorldProperties {
override fun getSpawnPos(): BlockPos {
return BlockPos.ORIGIN
}
override fun getSpawnAngle(): Float {
return 0F
}
override fun getSpawnAngle(): Float {
return 0F
}
override fun getTime(): Long {
return 0
}
override fun getTime(): Long {
return 0
}
override fun getTimeOfDay(): Long {
return 0
}
override fun getTimeOfDay(): Long {
return 0
}
override fun isThundering(): Boolean {
return false
}
override fun isThundering(): Boolean {
return false
}
override fun isRaining(): Boolean {
return false
}
override fun isRaining(): Boolean {
return false
}
override fun setRaining(raining: Boolean) {
}
override fun setRaining(raining: Boolean) {
}
override fun isHardcore(): Boolean {
return false
}
override fun isHardcore(): Boolean {
return false
}
override fun getGameRules(): GameRules {
return GameRules()
}
override fun getDifficulty(): Difficulty {
return Difficulty.HARD
}
override fun getDifficulty(): Difficulty {
return Difficulty.HARD
}
override fun isDifficultyLocked(): Boolean {
return false
}
override fun isDifficultyLocked(): Boolean {
return false
}
override fun setSpawnPos(pos: BlockPos?, angle: Float) {}
}
override fun setSpawnPos(pos: BlockPos?, angle: Float) {}
}
override fun getPlayers(): List<PlayerEntity> {
return emptyList()
}
override fun getPlayers(): List<PlayerEntity> {
return emptyList()
}
override fun getBrightness(direction: Direction?, shaded: Boolean): Float {
return 1f
}
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 getGeneratorStoredBiome(biomeX: Int, biomeY: Int, biomeZ: Int): RegistryEntry<Biome> {
return registryManager.get(RegistryKeys.BIOME).entryOf(BiomeKeys.PLAINS)
}
override fun getSeaLevel(): Int {
return 0
}
override fun getEnabledFeatures(): FeatureSet {
return FeatureFlags.VANILLA_FEATURES
}
override fun getEnabledFeatures(): FeatureSet {
return FeatureFlags.VANILLA_FEATURES
}
class FakeTickScheduler<T> : QueryableTickScheduler<T> {
override fun scheduleTick(orderedTick: OrderedTick<T>?) {
}
class FakeTickScheduler<T> : QueryableTickScheduler<T> {
override fun scheduleTick(orderedTick: OrderedTick<T>?) {
}
override fun isQueued(pos: BlockPos?, type: T): Boolean {
return true
}
override fun isQueued(pos: BlockPos?, type: T): Boolean {
return true
}
override fun getTickCount(): Int {
return 0
}
override fun getTickCount(): Int {
return 0
}
override fun isTicking(pos: BlockPos?, type: T): Boolean {
return true
}
override fun isTicking(pos: BlockPos?, type: T): Boolean {
return true
}
}
}
override fun getBlockTickScheduler(): QueryableTickScheduler<Block> {
return FakeTickScheduler()
}
override fun getBlockTickScheduler(): QueryableTickScheduler<Block> {
return FakeTickScheduler()
}
override fun getFluidTickScheduler(): QueryableTickScheduler<Fluid> {
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.get(RegistryKeys.BIOME).entryOf(BiomeKeys.PLAINS)
)
}
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 getWorld(): BlockView {
return world
}
override fun tick(shouldKeepTicking: BooleanSupplier?, tickChunks: Boolean) {
}
override fun tick(shouldKeepTicking: BooleanSupplier?, tickChunks: Boolean) {
}
override fun getDebugString(): String {
return "FakeChunkManager"
}
override fun getDebugString(): String {
return "FakeChunkManager"
}
override fun getLoadedChunkCount(): Int {
return 0
}
override fun getLoadedChunkCount(): Int {
return 0
}
override fun getLightingProvider(): LightingProvider {
return FakeLightingProvider(this)
}
}
override fun getLightingProvider(): LightingProvider {
return FakeLightingProvider(this)
}
}
class FakeLightingProvider(chunkManager: FakeChunkManager) : LightingProvider(chunkManager, false, false)
class FakeLightingProvider(chunkManager: FakeChunkManager) : LightingProvider(chunkManager, false, false)
override fun getChunkManager(): ChunkManager {
return FakeChunkManager(this)
}
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 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 syncWorldEvent(player: PlayerEntity?, eventId: Int, pos: BlockPos?, data: Int) {
}
override fun emitGameEvent(event: RegistryEntry<GameEvent>?, emitterPos: Vec3d?, emitter: GameEvent.Emitter?) {
}
override fun emitGameEvent(event: RegistryEntry<GameEvent>?, emitterPos: Vec3d?, emitter: GameEvent.Emitter?) {
}
override fun updateListeners(pos: BlockPos?, oldState: BlockState?, newState: BlockState?, flags: Int) {
}
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 playSoundFromEntity(
source: PlayerEntity?,
entity: Entity?,
sound: RegistryEntry<SoundEvent>?,
category: SoundCategory?,
volume: Float,
pitch: Float,
seed: Long
) {
}
override fun asString(): String {
return "FakeWorld"
}
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 getEntityById(id: Int): Entity? {
return null
}
override fun asString(): String {
return "FakeWorld"
}
override fun getTickManager(): TickManager {
return TickManager()
}
override fun getEntityById(id: Int): Entity? {
return null
}
override fun getMapState(id: MapIdComponent?): MapState? {
return null
}
override fun getTickManager(): TickManager {
return TickManager()
}
override fun putMapState(id: MapIdComponent?, state: MapState?) {
}
override fun getMapState(id: MapIdComponent?): MapState? {
return null
}
override fun increaseAndGetMapId(): MapIdComponent {
return MapIdComponent(0)
}
override fun putMapState(id: MapIdComponent?, state: MapState?) {
}
override fun setBlockBreakingInfo(entityId: Int, pos: BlockPos?, progress: Int) {
}
override fun increaseAndGetMapId(): MapIdComponent {
return MapIdComponent(0)
}
override fun getScoreboard(): Scoreboard {
return Scoreboard()
}
override fun setBlockBreakingInfo(entityId: Int, pos: BlockPos?, progress: Int) {
}
override fun getRecipeManager(): RecipeManager {
return RecipeManager(registryManager)
}
override fun getScoreboard(): Scoreboard {
return Scoreboard()
}
object FakeEntityLookup : EntityLookup<Entity> {
override fun get(id: Int): Entity? {
return null
}
override fun getRecipeManager(): RecipeManager {
return object : RecipeManager {
override fun getPropertySet(key: RegistryKey<RecipePropertySet>?): RecipePropertySet {
return RecipePropertySet.EMPTY
}
override fun get(uuid: UUID?): Entity? {
return null
}
override fun getStonecutterRecipes(): CuttingRecipeDisplay.Grouping<StonecuttingRecipe> {
return CuttingRecipeDisplay.Grouping.empty()
}
}
}
override fun iterate(): MutableIterable<Entity> {
return mutableListOf()
}
object FakeEntityLookup : EntityLookup<Entity> {
override fun get(id: Int): Entity? {
return null
}
override fun <U : Entity?> forEachIntersects(
filter: TypeFilter<Entity, U>?,
box: Box?,
consumer: LazyIterationConsumer<U>?
) {
}
override fun get(uuid: UUID?): Entity? {
return null
}
override fun forEachIntersects(box: Box?, action: Consumer<Entity>?) {
}
override fun iterate(): MutableIterable<Entity> {
return mutableListOf()
}
override fun <U : Entity?> forEach(filter: TypeFilter<Entity, U>?, consumer: LazyIterationConsumer<U>?) {
}
override fun <U : Entity?> forEachIntersects(
filter: TypeFilter<Entity, U>?,
box: Box?,
consumer: LazyIterationConsumer<U>?
) {
}
}
override fun forEachIntersects(box: Box?, action: Consumer<Entity>?) {
}
override fun getEntityLookup(): EntityLookup<Entity> {
return FakeEntityLookup
}
override fun <U : Entity?> forEach(filter: TypeFilter<Entity, U>?, consumer: LazyIterationConsumer<U>?) {
}
override fun getBrewingRecipeRegistry(): BrewingRecipeRegistry {
return BrewingRecipeRegistry.EMPTY
}
}
override fun getEntityLookup(): EntityLookup<Entity> {
return FakeEntityLookup
}
override fun getBrewingRecipeRegistry(): BrewingRecipeRegistry {
return BrewingRecipeRegistry.EMPTY
}
override fun getFuelRegistry(): FuelRegistry {
TODO("Not yet implemented")
}
}

View File

@@ -1,8 +1,7 @@
package moe.nea.firmament.gui.entity
import com.mojang.authlib.GameProfile
import java.util.*
import java.util.UUID
import net.minecraft.client.network.AbstractClientPlayerEntity
import net.minecraft.client.util.DefaultSkinHelper
import net.minecraft.client.util.SkinTextures
@@ -15,40 +14,40 @@ import net.minecraft.world.World
/**
* @see moe.nea.firmament.init.EarlyRiser
*/
fun makeGuiPlayer(world: FakeWorld): GuiPlayer {
val constructor = GuiPlayer::class.java.getDeclaredConstructor(
World::class.java,
BlockPos::class.java,
Float::class.javaPrimitiveType,
GameProfile::class.java
)
return constructor.newInstance(world, BlockPos.ORIGIN, 0F, GameProfile(UUID.randomUUID(), "Linnea"))
fun makeGuiPlayer(world: World): GuiPlayer {
val constructor = GuiPlayer::class.java.getDeclaredConstructor(
World::class.java,
BlockPos::class.java,
Float::class.javaPrimitiveType,
GameProfile::class.java
)
return constructor.newInstance(world, BlockPos.ORIGIN, 0F, GameProfile(UUID.randomUUID(), "Linnea"))
}
class GuiPlayer(world: ClientWorld?, profile: GameProfile?) : AbstractClientPlayerEntity(world, profile) {
override fun isSpectator(): Boolean {
return false
}
override fun isSpectator(): Boolean {
return false
}
override fun isCreative(): Boolean {
return false
}
override fun isCreative(): Boolean {
return false
}
override fun shouldRenderName(): Boolean {
return false
}
override fun shouldRenderName(): Boolean {
return false
}
var skinTexture: Identifier = DefaultSkinHelper.getSkinTextures(this.getUuid()).texture
var capeTexture: Identifier? = null
var model: Model = Model.WIDE
override fun getSkinTextures(): SkinTextures {
return SkinTextures(
skinTexture,
null,
capeTexture,
null,
model,
true
)
}
var skinTexture: Identifier = DefaultSkinHelper.getSkinTextures(this.getUuid()).texture
var capeTexture: Identifier? = null
var model: Model = Model.WIDE
override fun getSkinTextures(): SkinTextures {
return SkinTextures(
skinTexture,
null,
capeTexture,
null,
model,
true
)
}
}

View File

@@ -8,6 +8,7 @@ import kotlin.experimental.inv
import kotlin.experimental.or
import net.minecraft.entity.EntityType
import net.minecraft.entity.LivingEntity
import net.minecraft.entity.SpawnReason
import net.minecraft.entity.passive.AbstractHorseEntity
import net.minecraft.item.ItemStack
import net.minecraft.item.Items
@@ -19,11 +20,11 @@ object ModifyHorse : EntityModifier {
var entity: AbstractHorseEntity = entity
info["kind"]?.let {
entity = when (it.asString) {
"skeleton" -> EntityType.SKELETON_HORSE.create(fakeWorld)!!
"zombie" -> EntityType.ZOMBIE_HORSE.create(fakeWorld)!!
"mule" -> EntityType.MULE.create(fakeWorld)!!
"donkey" -> EntityType.DONKEY.create(fakeWorld)!!
"horse" -> EntityType.HORSE.create(fakeWorld)!!
"skeleton" -> EntityType.SKELETON_HORSE.create(fakeWorld, SpawnReason.LOAD)!!
"zombie" -> EntityType.ZOMBIE_HORSE.create(fakeWorld, SpawnReason.LOAD)!!
"mule" -> EntityType.MULE.create(fakeWorld, SpawnReason.LOAD)!!
"donkey" -> EntityType.DONKEY.create(fakeWorld, SpawnReason.LOAD)!!
"horse" -> EntityType.HORSE.create(fakeWorld, SpawnReason.LOAD)!!
else -> error("Unknown horse kind $it")
}
}