|
| 1 | +package generations.gg.generations.core.generationscore.common.client.render.entity |
| 2 | + |
| 3 | +import com.google.common.collect.ImmutableMap |
| 4 | +import com.mojang.blaze3d.vertex.PoseStack |
| 5 | +import com.mojang.datafixers.util.Pair |
| 6 | +import com.mojang.math.Axis |
| 7 | +import generations.gg.generations.core.generationscore.common.GenerationsCore |
| 8 | +import generations.gg.generations.core.generationscore.common.GenerationsCore.id |
| 9 | +import generations.gg.generations.core.generationscore.common.world.entity.GenerationsBoatEntity |
| 10 | +import net.minecraft.client.model.BoatModel |
| 11 | +import net.minecraft.client.model.ChestBoatModel |
| 12 | +import net.minecraft.client.model.ListModel |
| 13 | +import net.minecraft.client.model.WaterPatchModel |
| 14 | +import net.minecraft.client.model.geom.ModelLayerLocation |
| 15 | +import net.minecraft.client.renderer.MultiBufferSource |
| 16 | +import net.minecraft.client.renderer.RenderType |
| 17 | +import net.minecraft.client.renderer.entity.EntityRenderer |
| 18 | +import net.minecraft.client.renderer.entity.EntityRendererProvider |
| 19 | +import net.minecraft.client.renderer.texture.OverlayTexture |
| 20 | +import net.minecraft.resources.ResourceLocation |
| 21 | +import net.minecraft.util.Mth |
| 22 | +import net.minecraft.world.entity.vehicle.Boat |
| 23 | +import org.joml.Quaternionf |
| 24 | +import java.util.function.Function |
| 25 | +import java.util.stream.Stream |
| 26 | + |
| 27 | +class GenerationsBoatRenderer<T : GenerationsBoatEntity>(context: EntityRendererProvider.Context, bl: Boolean) : |
| 28 | + EntityRenderer<T>(context) { |
| 29 | + private val boatResources: Map<GenerationsBoatEntity.Type, Pair<ResourceLocation, ListModel<Boat>>> |
| 30 | + |
| 31 | + init { |
| 32 | + this.shadowRadius = 0.8f |
| 33 | + this.boatResources = GenerationsBoatEntity.Type.entries.associateWith { type: GenerationsBoatEntity.Type -> |
| 34 | + Pair(id(getTextureLocation(type, bl)), |
| 35 | + createBoatModel(context, type, bl) |
| 36 | + ) |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + private fun createBoatModel( |
| 41 | + context: EntityRendererProvider.Context, |
| 42 | + type: GenerationsBoatEntity.Type, |
| 43 | + bl: Boolean |
| 44 | + ): ListModel<Boat> { |
| 45 | + val modelLayerLocation = if (bl) createChestBoatModelName(type) else createBoatModelName(type) |
| 46 | + val modelPart = context.bakeLayer(modelLayerLocation) |
| 47 | + return if (bl) ChestBoatModel(modelPart) else BoatModel(modelPart) |
| 48 | + } |
| 49 | + |
| 50 | + override fun render( |
| 51 | + boat: T, |
| 52 | + f: Float, |
| 53 | + g: Float, |
| 54 | + poseStack: PoseStack, |
| 55 | + multiBufferSource: MultiBufferSource, |
| 56 | + i: Int |
| 57 | + ) { |
| 58 | + poseStack.pushPose() |
| 59 | + poseStack.translate(0.0f, 0.375f, 0.0f) |
| 60 | + poseStack.mulPose(Axis.YP.rotationDegrees(180.0f - f)) |
| 61 | + val h = boat!!.hurtTime.toFloat() - g |
| 62 | + var j = boat.damage - g |
| 63 | + if (j < 0.0f) { |
| 64 | + j = 0.0f |
| 65 | + } |
| 66 | + |
| 67 | + if (h > 0.0f) { |
| 68 | + poseStack.mulPose(Axis.XP.rotationDegrees(Mth.sin(h) * h * j / 10.0f * boat.hurtDir.toFloat())) |
| 69 | + } |
| 70 | + |
| 71 | + val k = boat.getBubbleAngle(g) |
| 72 | + if (!Mth.equal(k, 0.0f)) { |
| 73 | + poseStack.mulPose((Quaternionf()).setAngleAxis(boat.getBubbleAngle(g) * 0.017453292f, 1.0f, 0.0f, 1.0f)) |
| 74 | + } |
| 75 | + |
| 76 | + val pair = |
| 77 | + boatResources[boat.modBoatType]!! |
| 78 | + val resourceLocation = pair.first |
| 79 | + val listModel = pair.second |
| 80 | + poseStack.scale(-1.0f, -1.0f, 1.0f) |
| 81 | + poseStack.mulPose(Axis.YP.rotationDegrees(90.0f)) |
| 82 | + listModel.setupAnim(boat, g, 0.0f, -0.1f, 0.0f, 0.0f) |
| 83 | + val vertexConsumer = multiBufferSource.getBuffer(listModel.renderType(resourceLocation)) |
| 84 | + listModel.renderToBuffer(poseStack, vertexConsumer, i, OverlayTexture.NO_OVERLAY, -0x1) |
| 85 | + if (!boat.isUnderWater) { |
| 86 | + val vertexConsumer2 = multiBufferSource.getBuffer(RenderType.waterMask()) |
| 87 | + if (listModel is WaterPatchModel) { |
| 88 | + listModel.waterPatch().render(poseStack, vertexConsumer2, i, OverlayTexture.NO_OVERLAY) |
| 89 | + } |
| 90 | + } |
| 91 | + |
| 92 | + poseStack.popPose() |
| 93 | + super.render(boat, f, g, poseStack, multiBufferSource, i) |
| 94 | + } |
| 95 | + |
| 96 | + override fun getTextureLocation(boat: T): ResourceLocation { |
| 97 | + return boatResources[boat.modBoatType]!!.first |
| 98 | + } |
| 99 | + |
| 100 | + companion object { |
| 101 | + fun createBoatModelName(type: GenerationsBoatEntity.Type): ModelLayerLocation { |
| 102 | + return createLocation("boat/" + type.id) |
| 103 | + } |
| 104 | + |
| 105 | + fun createChestBoatModelName(type: GenerationsBoatEntity.Type): ModelLayerLocation { |
| 106 | + return createLocation("chest_boat/" + type.id) |
| 107 | + } |
| 108 | + |
| 109 | + private fun createLocation(string: String): ModelLayerLocation { |
| 110 | + return ModelLayerLocation(id(string), "main") |
| 111 | + } |
| 112 | + |
| 113 | + private fun getTextureLocation(type: GenerationsBoatEntity.Type, bl: Boolean): String { |
| 114 | + return if (bl) "textures/entity/chest_boat/" + type.id + ".png" else "textures/entity/boat/" + type.id + ".png" |
| 115 | + } |
| 116 | + } |
| 117 | +} |
0 commit comments