aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/gui/entity
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/gui/entity')
-rw-r--r--src/main/kotlin/gui/entity/EntityModifier.kt2
-rw-r--r--src/main/kotlin/gui/entity/EntityRenderer.kt168
-rw-r--r--src/main/kotlin/gui/entity/FakeWorld.kt343
-rw-r--r--src/main/kotlin/gui/entity/GuiPlayer.kt60
-rw-r--r--src/main/kotlin/gui/entity/ModifyAge.kt16
-rw-r--r--src/main/kotlin/gui/entity/ModifyCharged.kt8
-rw-r--r--src/main/kotlin/gui/entity/ModifyEquipment.kt24
-rw-r--r--src/main/kotlin/gui/entity/ModifyHorse.kt94
-rw-r--r--src/main/kotlin/gui/entity/ModifyInvisible.kt2
-rw-r--r--src/main/kotlin/gui/entity/ModifyName.kt6
-rw-r--r--src/main/kotlin/gui/entity/ModifyPlayerSkin.kt84
-rw-r--r--src/main/kotlin/gui/entity/ModifyRiding.kt4
-rw-r--r--src/main/kotlin/gui/entity/ModifyWither.kt8
13 files changed, 246 insertions, 573 deletions
diff --git a/src/main/kotlin/gui/entity/EntityModifier.kt b/src/main/kotlin/gui/entity/EntityModifier.kt
index 9623070..4915ebb 100644
--- a/src/main/kotlin/gui/entity/EntityModifier.kt
+++ b/src/main/kotlin/gui/entity/EntityModifier.kt
@@ -2,7 +2,7 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
+import net.minecraft.world.entity.LivingEntity
fun interface EntityModifier {
fun apply(entity: LivingEntity, info: JsonObject): LivingEntity
diff --git a/src/main/kotlin/gui/entity/EntityRenderer.kt b/src/main/kotlin/gui/entity/EntityRenderer.kt
index fd7a0c4..4972709 100644
--- a/src/main/kotlin/gui/entity/EntityRenderer.kt
+++ b/src/main/kotlin/gui/entity/EntityRenderer.kt
@@ -3,17 +3,18 @@ package moe.nea.firmament.gui.entity
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonObject
+import me.shedaniel.math.Dimension
import org.joml.Quaternionf
import org.joml.Vector3f
import kotlin.math.atan
-import net.minecraft.client.gui.DrawContext
-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 net.minecraft.client.gui.GuiGraphics
+import net.minecraft.client.gui.screens.inventory.InventoryScreen
+import net.minecraft.world.entity.Entity
+import net.minecraft.world.entity.EntityType
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.EntitySpawnReason
+import net.minecraft.resources.ResourceLocation
+import net.minecraft.world.level.Level
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.iterate
@@ -21,47 +22,87 @@ import moe.nea.firmament.util.openFirmamentResource
import moe.nea.firmament.util.render.enableScissorWithTranslation
object EntityRenderer {
- val fakeWorld: World get() = MC.lastWorld!!
+ val fakeWorld: Level get() = MC.lastWorld!!
private fun <T : Entity> t(entityType: EntityType<T>): () -> T {
- return { entityType.create(fakeWorld, SpawnReason.LOAD)!! }
+ return { entityType.create(fakeWorld, EntitySpawnReason.LOAD)!! }
}
val entityIds: Map<String, () -> LivingEntity> = mapOf(
- "Zombie" to t(EntityType.ZOMBIE),
+ "Armadillo" to t(EntityType.ARMADILLO),
+ "ArmorStand" to t(EntityType.ARMOR_STAND),
+ "Axolotl" to t(EntityType.AXOLOTL),
+ "Bat" to t(EntityType.BAT),
+ "Bee" to t(EntityType.BEE),
+ "Blaze" to t(EntityType.BLAZE),
+ "Bogged" to t(EntityType.BOGGED),
+ "Breeze" to t(EntityType.BREEZE),
+ "CaveSpider" to t(EntityType.CAVE_SPIDER),
"Chicken" to t(EntityType.CHICKEN),
- "Slime" to t(EntityType.SLIME),
- "Wolf" to t(EntityType.WOLF),
- "Skeleton" to t(EntityType.SKELETON),
+ "Cod" to t(EntityType.COD),
+ "Cow" to t(EntityType.COW),
+ "Creaking" to t(EntityType.CREAKING),
"Creeper" to t(EntityType.CREEPER),
+ "Dolphin" to t(EntityType.DOLPHIN),
+ "Donkey" to t(EntityType.DONKEY),
+ "Dragon" to t(EntityType.ENDER_DRAGON),
+ "Drowned" to t(EntityType.DROWNED),
+ "Eisengolem" to t(EntityType.IRON_GOLEM),
+ "Enderman" to t(EntityType.ENDERMAN),
+ "Endermite" to t(EntityType.ENDERMITE),
+ "Evoker" to t(EntityType.EVOKER),
+ "Fox" to t(EntityType.FOX),
+ "Frog" to t(EntityType.FROG),
+ "Ghast" to t(EntityType.GHAST),
+ "Giant" to t(EntityType.GIANT),
+ "GlowSquid" to t(EntityType.GLOW_SQUID),
+ "Goat" to t(EntityType.GOAT),
+ "Guardian" to t(EntityType.GUARDIAN),
+ "Horse" to t(EntityType.HORSE),
+ "Husk" to t(EntityType.HUSK),
+ "Illusioner" to t(EntityType.ILLUSIONER),
+ "LLama" to t(EntityType.LLAMA),
+ "MagmaCube" to t(EntityType.MAGMA_CUBE),
+ "Mooshroom" to t(EntityType.MOOSHROOM),
+ "Mule" to t(EntityType.MULE),
"Ocelot" to t(EntityType.OCELOT),
- "Blaze" to t(EntityType.BLAZE),
+ "Panda" to t(EntityType.PANDA),
+ "Phantom" to t(EntityType.PHANTOM),
+ "Pig" to t(EntityType.PIG),
+ "Piglin" to t(EntityType.PIGLIN),
+ "PiglinBrute" to t(EntityType.PIGLIN_BRUTE),
+ "Pigman" to t(EntityType.ZOMBIFIED_PIGLIN),
+ "Pillager" to t(EntityType.PILLAGER),
+ "Player" to { makeGuiPlayer(fakeWorld) },
+ "PolarBear" to t(EntityType.POLAR_BEAR),
+ "Pufferfish" to t(EntityType.PUFFERFISH),
"Rabbit" to t(EntityType.RABBIT),
+ "Salmom" to t(EntityType.SALMON),
+ "Salmon" to t(EntityType.SALMON),
"Sheep" to t(EntityType.SHEEP),
- "Horse" to t(EntityType.HORSE),
- "Eisengolem" to t(EntityType.IRON_GOLEM),
+ "Shulker" to t(EntityType.SHULKER),
"Silverfish" to t(EntityType.SILVERFISH),
- "Witch" to t(EntityType.WITCH),
- "Endermite" to t(EntityType.ENDERMITE),
+ "Skeleton" to t(EntityType.SKELETON),
+ "Slime" to t(EntityType.SLIME),
+ "Sniffer" to t(EntityType.SNIFFER),
"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),
+ "Squid" to t(EntityType.SQUID),
+ "Stray" to t(EntityType.STRAY),
+ "Strider" to t(EntityType.STRIDER),
+ "Tadpole" to t(EntityType.TADPOLE),
+ "TropicalFish" to t(EntityType.TROPICAL_FISH),
+ "Turtle" to t(EntityType.TURTLE),
+ "Vex" to t(EntityType.VEX),
+ "Villager" to t(EntityType.VILLAGER),
+ "Vindicator" to t(EntityType.VINDICATOR),
+ "Warden" to t(EntityType.WARDEN),
+ "Witch" to t(EntityType.WITCH),
"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),
+ "Wolf" to t(EntityType.WOLF),
+ "Zoglin" to t(EntityType.ZOGLIN),
+ "Zombie" to t(EntityType.ZOMBIE),
+ "ZombieVillager" to t(EntityType.ZOMBIE_VILLAGER)
)
val entityModifiers: Map<String, EntityModifier> = mapOf(
"playerdata" to ModifyPlayerSkin,
@@ -83,7 +124,8 @@ object EntityRenderer {
for (modifierJson in modifiers) {
val modifier = ErrorUtil.notNullOr(
modifierJson["type"]?.asString?.let(entityModifiers::get),
- "Could not create entity with id $entityId. Failed to apply modifier $modifierJson") { return null }
+ "Could not create entity with id $entityId. Failed to apply modifier $modifierJson"
+ ) { return null }
entity = modifier.apply(entity, modifierJson)
}
return entity
@@ -98,7 +140,7 @@ object EntityRenderer {
}
private val gson = Gson()
- fun constructEntity(location: Identifier): LivingEntity? {
+ fun constructEntity(location: ResourceLocation): LivingEntity? {
return constructEntity(
gson.fromJson(
location.openFirmamentResource().bufferedReader(), JsonObject::class.java
@@ -108,7 +150,7 @@ object EntityRenderer {
fun renderEntity(
entity: LivingEntity,
- renderContext: DrawContext,
+ renderContext: GuiGraphics,
posX: Int,
posY: Int,
// TODO: Add width, height properties here
@@ -121,10 +163,10 @@ object EntityRenderer {
var bottomOffset = 0.0
var currentEntity = entity
val maxSize = entity.iterate { it.firstPassenger as? LivingEntity }
- .map { it.height }
+ .map { it.bbHeight }
.sum()
while (true) {
- currentEntity.age = MC.player?.age ?: 0
+ currentEntity.tickCount = MC.player?.tickCount ?: 0
drawEntity(
renderContext,
posX,
@@ -138,14 +180,14 @@ object EntityRenderer {
currentEntity
)
val next = currentEntity.firstPassenger as? LivingEntity ?: break
- bottomOffset += currentEntity.getPassengerRidingPos(next).y.toFloat() * 0.75F
+ bottomOffset += currentEntity.getPassengerRidingPosition(next).y.toFloat() * 0.75F
currentEntity = next
}
}
fun drawEntity(
- context: DrawContext,
+ context: GuiGraphics,
x1: Int,
y1: Int,
x2: Int,
@@ -162,38 +204,38 @@ object EntityRenderer {
val hw = (x2 - x1) / 2
val hh = (y2 - y1) / 2
val targetYaw = atan(((centerX - mouseX) / hw)).toFloat()
- val targetPitch = atan(((centerY - mouseY) / hh)).toFloat()
+ val targetPitch = atan(((centerY - mouseY) / hh - entity.eyeHeight * hh / 40)).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).toFloat(), 0.0f)
- InventoryScreen.drawEntity(
+ val oldBodyYaw = entity.yBodyRot
+ val oldYaw = entity.yRot
+ val oldPitch = entity.xRot
+ val oldPrevHeadYaw = entity.yHeadRotO
+ val oldHeadYaw = entity.yHeadRot
+ entity.yBodyRot = 180.0f + targetYaw * 20.0f
+ entity.yRot = 180.0f + targetYaw * 40.0f
+ entity.xRot = -targetPitch * 20.0f
+ entity.yHeadRot = entity.yRot
+ entity.yHeadRotO = entity.yRot
+ val vector3f = Vector3f(0.0f, (entity.bbHeight / 2.0f + bottomOffset).toFloat(), 0.0f)
+ InventoryScreen.renderEntityInInventory( // TODO: fix multiple entities rendering the same entity
context,
- centerX,
- centerY,
+ x1, y1,
+ x2, y2,
size.toFloat(),
vector3f,
rotateToFaceTheFront,
rotateToFaceTheCamera,
entity
)
- entity.bodyYaw = oldBodyYaw
- entity.yaw = oldYaw
- entity.pitch = oldPitch
- entity.prevHeadYaw = oldPrevHeadYaw
- entity.headYaw = oldHeadYaw
+ entity.yBodyRot = oldBodyYaw
+ entity.yRot = oldYaw
+ entity.xRot = oldPitch
+ entity.yHeadRotO = oldPrevHeadYaw
+ entity.yHeadRot = oldHeadYaw
context.disableScissor()
}
-
+ val defaultSize = Dimension(50, 80)
}
diff --git a/src/main/kotlin/gui/entity/FakeWorld.kt b/src/main/kotlin/gui/entity/FakeWorld.kt
deleted file mode 100644
index ccf6b60..0000000
--- a/src/main/kotlin/gui/entity/FakeWorld.kt
+++ /dev/null
@@ -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")
- }
-}
diff --git a/src/main/kotlin/gui/entity/GuiPlayer.kt b/src/main/kotlin/gui/entity/GuiPlayer.kt
index f728dbf..b53f68c 100644
--- a/src/main/kotlin/gui/entity/GuiPlayer.kt
+++ b/src/main/kotlin/gui/entity/GuiPlayer.kt
@@ -1,62 +1,28 @@
package moe.nea.firmament.gui.entity
-import com.mojang.authlib.GameProfile
-import java.util.UUID
-import net.minecraft.client.network.AbstractClientPlayerEntity
-import net.minecraft.client.util.DefaultSkinHelper
-import net.minecraft.client.util.SkinTextures
-import net.minecraft.client.util.SkinTextures.Model
-import net.minecraft.client.world.ClientWorld
-import net.minecraft.util.Identifier
-import net.minecraft.util.math.BlockPos
-import net.minecraft.util.math.Vec3d
-import net.minecraft.world.World
+import net.minecraft.client.entity.ClientMannequin
+import net.minecraft.client.resources.DefaultPlayerSkin
+import net.minecraft.client.multiplayer.ClientLevel
+import net.minecraft.world.entity.player.PlayerSkin
+import net.minecraft.world.level.Level
+import moe.nea.firmament.util.MC
-/**
- * @see moe.nea.firmament.init.EarlyRiser
- */
-fun makeGuiPlayer(world: World): GuiPlayer {
- val constructor = GuiPlayer::class.java.getDeclaredConstructor(
- World::class.java,
- BlockPos::class.java,
- Float::class.javaPrimitiveType,
- GameProfile::class.java
- )
- val player = constructor.newInstance(world, BlockPos.ORIGIN, 0F, GameProfile(UUID.randomUUID(), "Linnea"))
- player.postInit()
+fun makeGuiPlayer(world: Level): GuiPlayer {
+ val player = GuiPlayer(MC.instance.level!!)
return player
}
-class GuiPlayer(world: ClientWorld?, profile: GameProfile?) : AbstractClientPlayerEntity(world, profile) {
+class GuiPlayer(world: ClientLevel?) : ClientMannequin(world, MC.instance.playerSkinRenderCache()) {
override fun isSpectator(): Boolean {
return false
}
- fun postInit() {
- skinTexture = DefaultSkinHelper.getSkinTextures(this.getUuid()).texture
- lastVelocity = Vec3d.ZERO
- model = Model.WIDE
- }
-
- override fun isCreative(): Boolean {
- return false
- }
-
- override fun shouldRenderName(): Boolean {
+ override fun shouldShowName(): Boolean {
return false
}
- lateinit var skinTexture: Identifier
- var capeTexture: Identifier? = null
- var model: Model = Model.WIDE
- override fun getSkinTextures(): SkinTextures {
- return SkinTextures(
- skinTexture,
- null,
- capeTexture,
- null,
- model,
- true
- )
+ var skinTextures: PlayerSkin = DefaultPlayerSkin.get(this.uuid) // TODO: 1.21.10
+ override fun getSkin(): PlayerSkin {
+ return skinTextures
}
}
diff --git a/src/main/kotlin/gui/entity/ModifyAge.kt b/src/main/kotlin/gui/entity/ModifyAge.kt
index a65c368..99154ef 100644
--- a/src/main/kotlin/gui/entity/ModifyAge.kt
+++ b/src/main/kotlin/gui/entity/ModifyAge.kt
@@ -2,19 +2,19 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
-import net.minecraft.entity.decoration.ArmorStandEntity
-import net.minecraft.entity.mob.ZombieEntity
-import net.minecraft.entity.passive.PassiveEntity
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.decoration.ArmorStand
+import net.minecraft.world.entity.monster.Zombie
+import net.minecraft.world.entity.AgeableMob
object ModifyAge : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
val isBaby = info["baby"]?.asBoolean ?: false
- if (entity is PassiveEntity) {
- entity.breedingAge = if (isBaby) -1 else 1
- } else if (entity is ZombieEntity) {
+ if (entity is AgeableMob) {
+ entity.age = if (isBaby) -1 else 1
+ } else if (entity is Zombie) {
entity.isBaby = isBaby
- } else if (entity is ArmorStandEntity) {
+ } else if (entity is ArmorStand) {
entity.isSmall = isBaby
} else {
error("Cannot set age for $entity")
diff --git a/src/main/kotlin/gui/entity/ModifyCharged.kt b/src/main/kotlin/gui/entity/ModifyCharged.kt
index d22f6e3..23fd495 100644
--- a/src/main/kotlin/gui/entity/ModifyCharged.kt
+++ b/src/main/kotlin/gui/entity/ModifyCharged.kt
@@ -2,13 +2,13 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
-import net.minecraft.entity.mob.CreeperEntity
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.monster.Creeper
object ModifyCharged : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
- require(entity is CreeperEntity)
- entity.dataTracker.set(CreeperEntity.CHARGED, true)
+ require(entity is Creeper)
+ entity.entityData.set(Creeper.DATA_IS_POWERED, true)
return entity
}
}
diff --git a/src/main/kotlin/gui/entity/ModifyEquipment.kt b/src/main/kotlin/gui/entity/ModifyEquipment.kt
index a558936..9c43e73 100644
--- a/src/main/kotlin/gui/entity/ModifyEquipment.kt
+++ b/src/main/kotlin/gui/entity/ModifyEquipment.kt
@@ -1,17 +1,18 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.component.DataComponentTypes
-import net.minecraft.component.type.DyedColorComponent
-import net.minecraft.entity.EquipmentSlot
-import net.minecraft.entity.LivingEntity
-import net.minecraft.item.Item
-import net.minecraft.item.ItemStack
-import net.minecraft.item.Items
+import net.minecraft.core.component.DataComponents
+import net.minecraft.world.item.component.DyedItemColor
+import net.minecraft.world.entity.EquipmentSlot
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.item.Item
+import net.minecraft.world.item.ItemStack
+import net.minecraft.world.item.Items
+import moe.nea.firmament.repo.ExpensiveItemCacheApi
import moe.nea.firmament.repo.SBItemStack
import moe.nea.firmament.util.SkyblockId
+import moe.nea.firmament.util.mc.arbitraryUUID
import moe.nea.firmament.util.mc.setEncodedSkullOwner
-import moe.nea.firmament.util.mc.zeroUUID
object ModifyEquipment : EntityModifier {
val names = mapOf(
@@ -25,18 +26,19 @@ object ModifyEquipment : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
names.forEach { (key, slot) ->
info[key]?.let {
- entity.equipStack(slot, createItem(it.asString))
+ entity.setItemSlot(slot, createItem(it.asString))
}
}
return entity
}
+ @OptIn(ExpensiveItemCacheApi::class)
private fun createItem(item: String): ItemStack {
val split = item.split("#")
if (split.size != 2) return SBItemStack(SkyblockId(item)).asImmutableItemStack()
val (type, data) = split
return when (type) {
- "SKULL" -> ItemStack(Items.PLAYER_HEAD).also { it.setEncodedSkullOwner(zeroUUID, data) }
+ "SKULL" -> ItemStack(Items.PLAYER_HEAD).also { it.setEncodedSkullOwner(arbitraryUUID, data) }
"LEATHER_LEGGINGS" -> coloredLeatherArmor(Items.LEATHER_LEGGINGS, data)
"LEATHER_BOOTS" -> coloredLeatherArmor(Items.LEATHER_BOOTS, data)
"LEATHER_HELMET" -> coloredLeatherArmor(Items.LEATHER_HELMET, data)
@@ -47,7 +49,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(DataComponents.DYED_COLOR, DyedItemColor(data.toInt(16)))
return stack
}
}
diff --git a/src/main/kotlin/gui/entity/ModifyHorse.kt b/src/main/kotlin/gui/entity/ModifyHorse.kt
index f094ca4..a870bf1 100644
--- a/src/main/kotlin/gui/entity/ModifyHorse.kt
+++ b/src/main/kotlin/gui/entity/ModifyHorse.kt
@@ -1,62 +1,58 @@
-
package moe.nea.firmament.gui.entity
import com.google.gson.JsonNull
import com.google.gson.JsonObject
-import kotlin.experimental.and
-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
+import net.minecraft.world.entity.EntityType
+import net.minecraft.world.entity.EquipmentSlot
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.EntitySpawnReason
+import net.minecraft.world.entity.animal.horse.AbstractHorse
+import net.minecraft.world.item.ItemStack
+import net.minecraft.world.item.Items
import moe.nea.firmament.gui.entity.EntityRenderer.fakeWorld
object ModifyHorse : EntityModifier {
- override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
- require(entity is AbstractHorseEntity)
- var entity: AbstractHorseEntity = entity
- info["kind"]?.let {
- entity = when (it.asString) {
- "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")
- }
- }
- info["armor"]?.let {
- if (it is JsonNull) {
- entity.setHorseArmor(ItemStack.EMPTY)
- } else {
- when (it.asString) {
- "iron" -> entity.setHorseArmor(ItemStack(Items.IRON_HORSE_ARMOR))
- "golden" -> entity.setHorseArmor(ItemStack(Items.GOLDEN_HORSE_ARMOR))
- "diamond" -> entity.setHorseArmor(ItemStack(Items.DIAMOND_HORSE_ARMOR))
- else -> error("Unknown horse armor $it")
- }
- }
- }
- info["saddled"]?.let {
- entity.setIsSaddled(it.asBoolean)
- }
- return entity
- }
+ override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
+ require(entity is AbstractHorse)
+ var entity: AbstractHorse = entity
+ info["kind"]?.let {
+ entity = when (it.asString) {
+ "skeleton" -> EntityType.SKELETON_HORSE.create(fakeWorld, EntitySpawnReason.LOAD)!!
+ "zombie" -> EntityType.ZOMBIE_HORSE.create(fakeWorld, EntitySpawnReason.LOAD)!!
+ "mule" -> EntityType.MULE.create(fakeWorld, EntitySpawnReason.LOAD)!!
+ "donkey" -> EntityType.DONKEY.create(fakeWorld, EntitySpawnReason.LOAD)!!
+ "horse" -> EntityType.HORSE.create(fakeWorld, EntitySpawnReason.LOAD)!!
+ else -> error("Unknown horse kind $it")
+ }
+ }
+ info["armor"]?.let {
+ if (it is JsonNull) {
+ entity.setHorseArmor(ItemStack.EMPTY)
+ } else {
+ when (it.asString) {
+ "iron" -> entity.setHorseArmor(ItemStack(Items.IRON_HORSE_ARMOR))
+ "golden" -> entity.setHorseArmor(ItemStack(Items.GOLDEN_HORSE_ARMOR))
+ "diamond" -> entity.setHorseArmor(ItemStack(Items.DIAMOND_HORSE_ARMOR))
+ else -> error("Unknown horse armor $it")
+ }
+ }
+ }
+ info["saddled"]?.let {
+ entity.setIsSaddled(it.asBoolean)
+ }
+ return entity
+ }
}
-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()
- )
+fun AbstractHorse.setIsSaddled(shouldBeSaddled: Boolean) {
+ this.setItemSlot(
+ EquipmentSlot.SADDLE,
+ if (shouldBeSaddled) ItemStack(Items.SADDLE)
+ else ItemStack.EMPTY
+ )
}
-fun AbstractHorseEntity.setHorseArmor(itemStack: ItemStack) {
- items.setStack(1, itemStack)
+fun AbstractHorse.setHorseArmor(itemStack: ItemStack) {
+ bodyArmorItem = itemStack
}
diff --git a/src/main/kotlin/gui/entity/ModifyInvisible.kt b/src/main/kotlin/gui/entity/ModifyInvisible.kt
index 8d36991..7a54ab1 100644
--- a/src/main/kotlin/gui/entity/ModifyInvisible.kt
+++ b/src/main/kotlin/gui/entity/ModifyInvisible.kt
@@ -2,7 +2,7 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
+import net.minecraft.world.entity.LivingEntity
object ModifyInvisible : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
diff --git a/src/main/kotlin/gui/entity/ModifyName.kt b/src/main/kotlin/gui/entity/ModifyName.kt
index a03da96..6def0b4 100644
--- a/src/main/kotlin/gui/entity/ModifyName.kt
+++ b/src/main/kotlin/gui/entity/ModifyName.kt
@@ -2,12 +2,12 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
-import net.minecraft.text.Text
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.network.chat.Component
object ModifyName : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
- entity.customName = Text.literal(info.get("name").asString)
+ entity.customName = Component.literal(info.get("name").asString)
return entity
}
diff --git a/src/main/kotlin/gui/entity/ModifyPlayerSkin.kt b/src/main/kotlin/gui/entity/ModifyPlayerSkin.kt
index 28f0070..0b393bb 100644
--- a/src/main/kotlin/gui/entity/ModifyPlayerSkin.kt
+++ b/src/main/kotlin/gui/entity/ModifyPlayerSkin.kt
@@ -1,47 +1,57 @@
-
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
import com.google.gson.JsonPrimitive
import kotlin.experimental.and
import kotlin.experimental.or
-import net.minecraft.client.util.SkinTextures
-import net.minecraft.entity.LivingEntity
-import net.minecraft.entity.player.PlayerEntity
-import net.minecraft.entity.player.PlayerModelPart
-import net.minecraft.util.Identifier
+import net.minecraft.client.entity.ClientAvatarEntity
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.Avatar
+import net.minecraft.world.entity.player.Player
+import net.minecraft.world.entity.player.PlayerModelPart
+import net.minecraft.world.entity.player.PlayerModelType
+import net.minecraft.world.entity.player.PlayerSkin
+import net.minecraft.core.ClientAsset
+import net.minecraft.resources.ResourceLocation
object ModifyPlayerSkin : EntityModifier {
- val playerModelPartIndex = PlayerModelPart.entries.associateBy { it.getName() }
- override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
- require(entity is GuiPlayer)
- info["cape"]?.let {
- entity.capeTexture = Identifier.of(it.asString)
- }
- info["skin"]?.let {
- entity.skinTexture = Identifier.of(it.asString)
- }
- info["slim"]?.let {
- entity.model = if (it.asBoolean) SkinTextures.Model.SLIM else SkinTextures.Model.WIDE
- }
- info["parts"]?.let {
- var trackedData = entity.dataTracker.get(PlayerEntity.PLAYER_MODEL_PARTS)
- if (it is JsonPrimitive && it.isBoolean) {
- trackedData = (if (it.asBoolean) -1 else 0).toByte()
- } else {
- val obj = it.asJsonObject
- for ((k, v) in obj.entrySet()) {
- val part = playerModelPartIndex[k]!!
- trackedData = if (v.asBoolean) {
- trackedData and (part.bitFlag.inv().toByte())
- } else {
- trackedData or (part.bitFlag.toByte())
- }
- }
- }
- entity.dataTracker.set(PlayerEntity.PLAYER_MODEL_PARTS, trackedData)
- }
- return entity
- }
+ val playerModelPartIndex = PlayerModelPart.entries.associateBy { it.id }
+ override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
+ require(entity is GuiPlayer)
+ var capeTexture = entity.skinTextures.cape
+ var model = entity.skinTextures.model
+ var bodyTexture = entity.skinTextures.body
+ fun mkTexAsset(id: ResourceLocation) = ClientAsset.ResourceTexture(id, id)
+ info["cape"]?.let {
+ capeTexture = mkTexAsset(ResourceLocation.parse(it.asString))
+ }
+ info["skin"]?.let {
+ bodyTexture = mkTexAsset(ResourceLocation.parse(it.asString))
+ }
+ info["slim"]?.let {
+ model = if (it.asBoolean) PlayerModelType.SLIM else PlayerModelType.WIDE
+ }
+ info["parts"]?.let {
+ var trackedData = entity.entityData.get(Avatar.DATA_PLAYER_MODE_CUSTOMISATION)
+ if (it is JsonPrimitive && it.isBoolean) {
+ trackedData = (if (it.asBoolean) -1 else 0).toByte()
+ } else {
+ val obj = it.asJsonObject
+ for ((k, v) in obj.entrySet()) {
+ val part = playerModelPartIndex[k]!!
+ trackedData = if (v.asBoolean) {
+ trackedData and (part.mask.inv().toByte())
+ } else {
+ trackedData or (part.mask.toByte())
+ }
+ }
+ }
+ entity.entityData.set(Player.DATA_PLAYER_MODE_CUSTOMISATION, trackedData)
+ }
+ entity.skinTextures = PlayerSkin(
+ bodyTexture, capeTexture, null, model, true
+ )
+ return entity
+ }
}
diff --git a/src/main/kotlin/gui/entity/ModifyRiding.kt b/src/main/kotlin/gui/entity/ModifyRiding.kt
index 5c4c78d..51fcfae 100644
--- a/src/main/kotlin/gui/entity/ModifyRiding.kt
+++ b/src/main/kotlin/gui/entity/ModifyRiding.kt
@@ -2,13 +2,13 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
+import net.minecraft.world.entity.LivingEntity
object ModifyRiding : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
val newEntity = EntityRenderer.constructEntity(info)
require(newEntity != null)
- newEntity.startRiding(entity, true)
+ newEntity.startRiding(entity, true, false)
return entity
}
diff --git a/src/main/kotlin/gui/entity/ModifyWither.kt b/src/main/kotlin/gui/entity/ModifyWither.kt
index 6083d88..67252b8 100644
--- a/src/main/kotlin/gui/entity/ModifyWither.kt
+++ b/src/main/kotlin/gui/entity/ModifyWither.kt
@@ -2,14 +2,14 @@
package moe.nea.firmament.gui.entity
import com.google.gson.JsonObject
-import net.minecraft.entity.LivingEntity
-import net.minecraft.entity.boss.WitherEntity
+import net.minecraft.world.entity.LivingEntity
+import net.minecraft.world.entity.boss.wither.WitherBoss
object ModifyWither : EntityModifier {
override fun apply(entity: LivingEntity, info: JsonObject): LivingEntity {
- require(entity is WitherEntity)
+ require(entity is WitherBoss)
info["tiny"]?.let {
- entity.setInvulTimer(if (it.asBoolean) 800 else 0)
+ entity.invulnerableTicks = if (it.asBoolean) 800 else 0
}
info["armored"]?.let {
entity.health = if (it.asBoolean) 1F else entity.maxHealth