boat variants (#1863)

This commit is contained in:
Corail31 2021-05-25 00:36:09 +02:00 committed by GitHub
parent 35b5b2f340
commit 503cda9ef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 412 additions and 17 deletions

View File

@ -0,0 +1,78 @@
package biomesoplenty.client.renderer;
import biomesoplenty.common.entity.item.BoatEntityBOP;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererManager;
import net.minecraft.client.renderer.entity.model.BoatModel;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.vector.Quaternion;
import net.minecraft.util.math.vector.Vector3f;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import static biomesoplenty.core.BiomesOPlenty.MOD_ID;
@OnlyIn(Dist.CLIENT)
public class BoatRendererBOP extends EntityRenderer<BoatEntityBOP> {
protected final BoatModel model = new BoatModel();
public BoatRendererBOP(EntityRendererManager renderer) {
super(renderer);
this.shadowRadius = 0.8f;
}
@Override
public void render(BoatEntityBOP entity, float entityYaw, float partialTicks, MatrixStack matrixStack, IRenderTypeBuffer renderTypeBuffer, int light) {
matrixStack.pushPose();
matrixStack.translate(0d, 0.375d, 0d);
matrixStack.mulPose(Vector3f.YP.rotationDegrees(180f - entityYaw));
float f = (float) entity.getHurtTime() - partialTicks;
float f1 = entity.getDamage() - partialTicks;
if (f1 < 0f) {
f1 = 0f;
}
if (f > 0f) {
matrixStack.mulPose(Vector3f.XP.rotationDegrees(MathHelper.sin(f) * f * f1 / 10f * (float) entity.getHurtDir()));
}
float f2 = entity.getBubbleAngle(partialTicks);
if (!MathHelper.equal(f2, 0f)) {
matrixStack.mulPose(new Quaternion(new Vector3f(1f, 0f, 1f), entity.getBubbleAngle(partialTicks), true));
}
matrixStack.scale(-1f, -1f, 1f);
matrixStack.mulPose(Vector3f.YP.rotationDegrees(90.0F));
this.model.setupAnim(entity, partialTicks, 0f, -0.1f, 0f, 0f);
IVertexBuilder ivertexbuilder = renderTypeBuffer.getBuffer(this.model.renderType(this.getTextureLocation(entity)));
this.model.renderToBuffer(matrixStack, ivertexbuilder, light, OverlayTexture.NO_OVERLAY, 1f, 1f, 1f, 1f);
if (!entity.isUnderWater()) {
IVertexBuilder ivertexbuilder1 = renderTypeBuffer.getBuffer(RenderType.waterMask());
this.model.waterPatch().render(matrixStack, ivertexbuilder1, light, OverlayTexture.NO_OVERLAY);
}
matrixStack.popPose();
super.render(entity, entityYaw, partialTicks, matrixStack, renderTypeBuffer, light);
}
@Override
public ResourceLocation getTextureLocation(BoatEntityBOP entity) {
return BOAT_TEXTURE_LOCATIONS[entity.getModel().ordinal()];
}
private static final ResourceLocation[] BOAT_TEXTURE_LOCATIONS = new ResourceLocation[] {
new ResourceLocation(MOD_ID, "textures/entity/boat/fir.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/redwood.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/cherry.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/mahogany.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/jacaranda.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/palm.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/willow.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/dead.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/magic.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/umbran.png"),
new ResourceLocation(MOD_ID, "textures/entity/boat/hellbark.png")
};
}

View File

@ -0,0 +1,183 @@
package biomesoplenty.common.entity.item;
import biomesoplenty.api.block.BOPBlocks;
import biomesoplenty.api.item.BOPItems;
import biomesoplenty.init.ModEntities;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.BoatEntity;
import net.minecraft.item.Item;
import net.minecraft.item.Items;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.network.IPacket;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.GameRules;
import net.minecraft.world.World;
import net.minecraftforge.common.util.Constants;
import net.minecraftforge.fml.network.FMLPlayMessages;
import net.minecraftforge.fml.network.NetworkHooks;
import java.util.Arrays;
import java.util.function.Supplier;
public class BoatEntityBOP extends BoatEntity {
public BoatEntityBOP(EntityType<? extends BoatEntityBOP> type, World world) {
super(type, world);
}
public BoatEntityBOP(World world, double x, double y, double z) {
super(ModEntities.boat, world);
setPos(x, y, z);
setDeltaMovement(Vector3d.ZERO);
this.xo = x;
this.yo = y;
this.zo = z;
}
public BoatEntityBOP(FMLPlayMessages.SpawnEntity spawnEntity, World world) {
this(world, spawnEntity.getPosX(), spawnEntity.getPosY(), spawnEntity.getPosZ());
}
@Override
public IPacket<?> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
protected void addAdditionalSaveData(CompoundNBT nbt) {
nbt.putString("model", getModel().getName());
}
@Override
protected void readAdditionalSaveData(CompoundNBT nbt) {
if (nbt.contains("model", Constants.NBT.TAG_STRING)) {
this.entityData.set(DATA_ID_TYPE, BoatModel.byName(nbt.getString("model")).ordinal());
}
}
@Override
protected void checkFallDamage(double y, boolean onGround, BlockState state, BlockPos pos) {
this.lastYd = getDeltaMovement().y;
if (!isPassenger()) {
if (onGround) {
if (this.fallDistance > 3f) {
if (this.status != Status.ON_LAND) {
this.fallDistance = 0f;
return;
}
causeFallDamage(this.fallDistance, 1f);
if (!this.level.isClientSide && !this.removed) {
this.remove();
if (this.level.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) {
for (int i = 0; i < 3; ++i) {
spawnAtLocation(getModel().getPlanks());
}
for (int j = 0; j < 2; ++j) {
spawnAtLocation(Items.STICK);
}
}
}
}
this.fallDistance = 0f;
} else if (!this.level.getFluidState(this.blockPosition().below()).is(FluidTags.WATER) && y < 0d) {
this.fallDistance = (float) ((double) this.fallDistance - y);
}
}
}
@Override
public Item getDropItem() {
switch (BoatModel.byId(this.entityData.get(DATA_ID_TYPE))) {
case FIR:
return BOPItems.fir_boat;
case REDWOOD:
return BOPItems.redwood_boat;
case CHERRY:
return BOPItems.cherry_boat;
case MAHOGANY:
return BOPItems.mahogany_boat;
case JACARANDA:
return BOPItems.jacaranda_boat;
case PALM:
return BOPItems.palm_boat;
case WILLOW:
return BOPItems.willow_boat;
case DEAD:
return BOPItems.dead_boat;
case MAGIC:
return BOPItems.magic_boat;
case UMBRAN:
return BOPItems.umbran_boat;
case HELLBARK:
return BOPItems.hellbark_boat;
}
return Items.OAK_BOAT;
}
public BoatEntityBOP withModel(BoatModel type) {
this.entityData.set(DATA_ID_TYPE, type.ordinal());
return this;
}
public BoatModel getModel() {
return BoatModel.byId(this.entityData.get(DATA_ID_TYPE));
}
@Deprecated
@Override
public void setType(Type vanillaType) {
}
@Deprecated
@Override
public Type getBoatType() {
return Type.OAK;
}
public enum BoatModel {
FIR("fir", () -> BOPBlocks.fir_planks),
REDWOOD("redwood", () -> BOPBlocks.redwood_planks),
CHERRY("cherry", () -> BOPBlocks.cherry_planks),
MAHOGANY("mahogany", () -> BOPBlocks.mahogany_planks),
JACARANDA("jacaranda", () -> BOPBlocks.jacaranda_planks),
PALM("palm", () -> BOPBlocks.palm_planks),
WILLOW("willow", () -> BOPBlocks.willow_planks),
DEAD("dead", () -> BOPBlocks.dead_planks),
MAGIC("magic", () -> BOPBlocks.magic_planks),
UMBRAN("umbran", () -> BOPBlocks.umbran_planks),
HELLBARK("hellbark", () -> BOPBlocks.hellbark_planks);
private final String name;
private final Supplier<Block> supplierPlanks;
BoatModel(String name, Supplier<Block> supplierPlanks) {
this.name = name;
this.supplierPlanks = supplierPlanks;
}
public String getName() {
return this.name;
}
public Block getPlanks() {
return this.supplierPlanks.get();
}
public String toString() {
return this.name;
}
public static BoatModel byId(int id) {
BoatModel[] type = values();
return type[id < 0 || id >= type.length ? 0 : id];
}
public static BoatModel byName(String aName) {
BoatModel[] type = values();
return Arrays.stream(type).filter(t -> t.getName().equals(aName)).findFirst().orElse(type[0]);
}
}
}

View File

@ -0,0 +1,72 @@
package biomesoplenty.common.item;
import biomesoplenty.common.entity.item.BoatEntityBOP;
import biomesoplenty.common.entity.item.BoatEntityBOP.BoatModel;
import biomesoplenty.common.util.inventory.ItemGroupBOP;
import net.minecraft.block.DispenserBlock;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.Stats;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EntityPredicates;
import net.minecraft.util.Hand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.RayTraceContext;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.world.World;
import java.util.List;
import java.util.function.Predicate;
public class BoatItemBOP extends Item {
private static final Predicate<Entity> ENTITY_PREDICATE = EntityPredicates.NO_SPECTATORS.and(Entity::isPickable);
private final BoatModel model;
public BoatItemBOP(BoatModel model) {
super(new Item.Properties().stacksTo(1).tab(ItemGroupBOP.instance));
this.model = model;
DispenserBlock.registerBehavior(this, new DispenserBoatBehaviorBOP(model));
}
@Override
public ActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
ItemStack heldItem = player.getItemInHand(hand);
RayTraceResult result = getPlayerPOVHitResult(world, player, RayTraceContext.FluidMode.ANY);
if (result.getType() == RayTraceResult.Type.MISS) {
return ActionResult.pass(heldItem);
} else {
Vector3d vector3d = player.getViewVector(1f);
List<Entity> entities = world.getEntities(player, player.getBoundingBox().expandTowards(vector3d.scale(5d)).inflate(1d), ENTITY_PREDICATE);
if (!entities.isEmpty()) {
Vector3d vector3d1 = player.getEyePosition(1f);
for (Entity entity : entities) {
AxisAlignedBB bounds = entity.getBoundingBox().inflate((double) entity.getPickRadius());
if (bounds.contains(vector3d1)) {
return ActionResult.pass(heldItem);
}
}
}
if (result.getType() == RayTraceResult.Type.BLOCK) {
BoatEntityBOP boat = new BoatEntityBOP(world, result.getLocation().x, result.getLocation().y, result.getLocation().z).withModel(this.model);
boat.yRot = player.yRot;
if (!world.noCollision(boat, boat.getBoundingBox().inflate(-0.1d))) {
return ActionResult.fail(heldItem);
} else {
if (!world.isClientSide()) {
world.addFreshEntity(boat);
if (!player.abilities.instabuild) {
heldItem.shrink(1);
}
}
player.awardStat(Stats.ITEM_USED.get(this));
return ActionResult.sidedSuccess(heldItem, world.isClientSide());
}
} else {
return ActionResult.pass(heldItem);
}
}
}
}

View File

@ -0,0 +1,45 @@
package biomesoplenty.common.item;
import biomesoplenty.common.entity.item.BoatEntityBOP;
import biomesoplenty.common.entity.item.BoatEntityBOP.BoatModel;
import net.minecraft.block.DispenserBlock;
import net.minecraft.dispenser.DefaultDispenseItemBehavior;
import net.minecraft.dispenser.IBlockSource;
import net.minecraft.item.ItemStack;
import net.minecraft.tags.FluidTags;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
public class DispenserBoatBehaviorBOP extends DefaultDispenseItemBehavior {
private final DefaultDispenseItemBehavior defaultDispenseItemBehavior = new DefaultDispenseItemBehavior();
private final BoatModel model;
public DispenserBoatBehaviorBOP(BoatModel model) {
this.model = model;
}
@Override
public ItemStack execute(IBlockSource source, ItemStack stack) {
Direction direction = source.getBlockState().getValue(DispenserBlock.FACING);
World world = source.getLevel();
double d0 = source.x() + (double) ((float) direction.getStepX() * 1.125f);
double d1 = source.y() + (double) ((float) direction.getStepY() * 1.125f);
double d2 = source.z() + (double) ((float) direction.getStepZ() * 1.125f);
BlockPos blockpos = source.getPos().relative(direction);
double d3;
if (world.getFluidState(blockpos).is(FluidTags.WATER)) {
d3 = 1d;
} else {
if (!world.getBlockState(blockpos).isAir() || !world.getFluidState(blockpos.below()).is(FluidTags.WATER)) {
return this.defaultDispenseItemBehavior.dispense(source, stack);
}
d3 = 0d;
}
BoatEntityBOP boat = new BoatEntityBOP(world, d0, d1 + d3, d2).withModel(this.model);
boat.yRot = direction.toYRot();
world.addFreshEntity(boat);
stack.shrink(1);
return stack;
}
}

View File

@ -8,8 +8,10 @@
package biomesoplenty.core;
import biomesoplenty.client.renderer.BoatRendererBOP;
import biomesoplenty.init.*;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.client.registry.RenderingRegistry;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
@ -50,6 +52,7 @@ public class BiomesOPlenty
private void clientSetup(final FMLClientSetupEvent event)
{
RenderingRegistry.registerEntityRenderingHandler(ModEntities.boat, BoatRendererBOP::new);
}
private void loadComplete(final FMLLoadCompleteEvent event) // PostRegistrationEven

View File

@ -7,5 +7,20 @@
******************************************************************************/
package biomesoplenty.init;
import biomesoplenty.common.entity.item.BoatEntityBOP;
import biomesoplenty.core.BiomesOPlenty;
import net.minecraft.entity.EntityClassification;
import net.minecraft.entity.EntityType;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD)
public class ModEntities {
public static final EntityType<BoatEntityBOP> boat = EntityType.Builder.<BoatEntityBOP>of(BoatEntityBOP::new, EntityClassification.MISC).sized(1.375f, 0.5625f).setCustomClientFactory(BoatEntityBOP::new).clientTrackingRange(10).build(BiomesOPlenty.MOD_ID + ":boat");
@SubscribeEvent
public static void registerEntities(final RegistryEvent.Register<EntityType<?>> event) {
event.getRegistry().register(boat.setRegistryName("boat"));
}
}

View File

@ -7,14 +7,11 @@
******************************************************************************/
package biomesoplenty.init;
import biomesoplenty.common.entity.item.BoatEntityBOP;
import biomesoplenty.common.item.BoatItemBOP;
import biomesoplenty.common.item.MusicDiscItemBOP;
import biomesoplenty.common.util.inventory.ItemGroupBOP;
import net.minecraft.entity.item.BoatEntity;
import net.minecraft.item.BoatItem;
import net.minecraft.item.Food;
import net.minecraft.item.Item;
import net.minecraft.potion.EffectInstance;
import net.minecraft.potion.Effects;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;
@ -34,17 +31,17 @@ public class ModItems
music_disc_wanderer = registerItem(new MusicDiscItemBOP("music_disc.wanderer"), "music_disc_wanderer");
fir_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "fir_boat");
redwood_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "redwood_boat");
cherry_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "cherry_boat");
mahogany_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "mahogany_boat");
jacaranda_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "jacaranda_boat");
palm_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "palm_boat");
willow_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "willow_boat");
dead_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "dead_boat");
magic_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "magic_boat");
umbran_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "umbran_boat");
hellbark_boat = registerItem(new BoatItem(BoatEntity.Type.OAK, (new Item.Properties()).stacksTo(1).tab(ItemGroupBOP.instance)), "hellbark_boat");
fir_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.FIR), "fir_boat");
redwood_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.REDWOOD), "redwood_boat");
cherry_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.CHERRY), "cherry_boat");
mahogany_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.MAHOGANY), "mahogany_boat");
jacaranda_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.JACARANDA), "jacaranda_boat");
palm_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.PALM), "palm_boat");
willow_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.WILLOW), "willow_boat");
dead_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.DEAD), "dead_boat");
magic_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.MAGIC), "magic_boat");
umbran_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.UMBRAN), "umbran_boat");
hellbark_boat = registerItem(new BoatItemBOP(BoatEntityBOP.BoatModel.HELLBARK), "hellbark_boat");
bop_icon = registerItem(new Item(new Item.Properties()), "bop_icon");
}

View File

@ -36,7 +36,9 @@ public-f net.minecraft.item.AxeItem field_203176_a # BLOCK_STRIPPING_MAP
public-f net.minecraft.item.HoeItem field_195973_b # TILLABLES
public-f net.minecraft.item.ShovelItem field_195955_e # FLATTENABLES
protected net.minecraft.entity.item.BoatEntity func_184447_s()V #tickLerp
public net.minecraft.entity.item.BoatEntity field_184466_d #DATA_ID_TYPE
public net.minecraft.entity.item.BoatEntity field_184469_aF #status
public net.minecraft.entity.item.BoatEntity field_184473_aH #lastYd
public net.minecraft.world.gen.feature.WorldDecoratingHelper *