Started working on re-adding boats (Still broken, boat items spawn oak boats for the time being)
This commit is contained in:
parent
7a560a8fd9
commit
3a4458a666
48 changed files with 1965 additions and 27 deletions
|
@ -73,6 +73,8 @@ public class BOPBiomes
|
|||
public static Optional<Biome> white_beach = Optional.empty();
|
||||
public static Optional<Biome> woodland = Optional.empty();
|
||||
public static Optional<Biome> xeric_shrubland = Optional.empty();
|
||||
|
||||
|
||||
public static Optional<Biome> undergarden = Optional.empty();
|
||||
|
||||
public static Optional<Biome> end_plains = Optional.empty();
|
||||
}
|
||||
|
|
27
src/main/java/biomesoplenty/common/biome/NetherBiomeBOP.java
Normal file
27
src/main/java/biomesoplenty/common/biome/NetherBiomeBOP.java
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright 2014-2019, the Biomes O' Plenty Team
|
||||
*
|
||||
* This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International Public License.
|
||||
*
|
||||
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/4.0/.
|
||||
******************************************************************************/
|
||||
package biomesoplenty.common.biome;
|
||||
|
||||
import biomesoplenty.api.enums.BOPClimates;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class NetherBiomeBOP extends BiomeBOP
|
||||
{
|
||||
protected Map<BOPClimates, Integer> weightMap = new HashMap<BOPClimates, Integer>();
|
||||
public boolean canSpawnInBiome;
|
||||
public int beachBiomeId = -1;
|
||||
public int riverBiomeId = -1;
|
||||
|
||||
public NetherBiomeBOP(Builder builder)
|
||||
{
|
||||
super(builder);
|
||||
this.canSpawnInBiome = false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package biomesoplenty.common.biome.nether;
|
||||
|
||||
import biomesoplenty.api.block.BOPBlocks;
|
||||
import biomesoplenty.common.biome.NetherBiomeBOP;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.fluid.Fluids;
|
||||
import net.minecraft.world.biome.Biome;
|
||||
import net.minecraft.world.biome.DefaultBiomeFeatures;
|
||||
import net.minecraft.world.gen.GenerationStage;
|
||||
import net.minecraft.world.gen.carver.WorldCarver;
|
||||
import net.minecraft.world.gen.feature.*;
|
||||
import net.minecraft.world.gen.placement.*;
|
||||
import net.minecraft.world.gen.surfacebuilders.SurfaceBuilder;
|
||||
|
||||
public class UndergardenBiome extends NetherBiomeBOP
|
||||
{
|
||||
public UndergardenBiome()
|
||||
{
|
||||
super((new Biome.Builder()).surfaceBuilder(SurfaceBuilder.NETHER, SurfaceBuilder.NETHERRACK_CONFIG).precipitation(Biome.RainType.NONE).category(Biome.Category.NETHER).depth(0.1F).scale(0.2F).temperature(2.0F).downfall(0.0F).waterColor(4159204).waterFogColor(329011).parent((String)null));
|
||||
|
||||
//Terrain
|
||||
this.addStructure(Feature.NETHER_BRIDGE, IFeatureConfig.NO_FEATURE_CONFIG);
|
||||
this.addCarver(GenerationStage.Carving.AIR, createCarver(WorldCarver.HELL_CAVE, new ProbabilityConfig(0.2F)));
|
||||
this.addFeature(GenerationStage.Decoration.VEGETAL_DECORATION, createDecoratedFeature(Feature.SPRING_FEATURE, new LiquidsConfig(Fluids.LAVA.getDefaultState()), Placement.COUNT_VERY_BIASED_RANGE, new CountRangeConfig(20, 8, 16, 256)));
|
||||
|
||||
DefaultBiomeFeatures.addMushrooms(this);
|
||||
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.NETHER_BRIDGE, IFeatureConfig.NO_FEATURE_CONFIG, Placement.NOPE, IPlacementConfig.NO_PLACEMENT_CONFIG));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.NETHER_SPRING, new HellLavaConfig(false), Placement.COUNT_RANGE, new CountRangeConfig(8, 4, 8, 128)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.HELL_FIRE, IFeatureConfig.NO_FEATURE_CONFIG, Placement.HELL_FIRE, new FrequencyConfig(10)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.GLOWSTONE_BLOB, IFeatureConfig.NO_FEATURE_CONFIG, Placement.LIGHT_GEM_CHANCE, new FrequencyConfig(10)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.GLOWSTONE_BLOB, IFeatureConfig.NO_FEATURE_CONFIG, Placement.COUNT_RANGE, new CountRangeConfig(10, 0, 0, 128)));
|
||||
|
||||
//Custom Features
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.BUSH, new BushConfig(BOPBlocks.burning_blossom.getDefaultState()), Placement.COUNT_HEIGHTMAP_DOUBLE, new FrequencyConfig(10)));
|
||||
|
||||
//Other Decorations
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.BUSH, new BushConfig(Blocks.BROWN_MUSHROOM.getDefaultState()), Placement.CHANCE_RANGE, new ChanceRangeConfig(0.5F, 0, 0, 128)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.BUSH, new BushConfig(Blocks.RED_MUSHROOM.getDefaultState()), Placement.CHANCE_RANGE, new ChanceRangeConfig(0.5F, 0, 0, 128)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NETHERRACK, Blocks.NETHER_QUARTZ_ORE.getDefaultState(), 14), Placement.COUNT_RANGE, new CountRangeConfig(16, 10, 20, 128)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.ORE, new OreFeatureConfig(OreFeatureConfig.FillerBlockType.NETHERRACK, Blocks.MAGMA_BLOCK.getDefaultState(), 33), Placement.MAGMA, new FrequencyConfig(4)));
|
||||
this.addFeature(GenerationStage.Decoration.UNDERGROUND_DECORATION, createDecoratedFeature(Feature.NETHER_SPRING, new HellLavaConfig(true), Placement.COUNT_RANGE, new CountRangeConfig(16, 10, 20, 128)));
|
||||
|
||||
//Entities
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.GHAST, 50, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ZOMBIE_PIGMAN, 100, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.MAGMA_CUBE, 2, 4, 4));
|
||||
this.addSpawn(EntityClassification.MONSTER, new Biome.SpawnListEntry(EntityType.ENDERMAN, 1, 4, 4));
|
||||
}
|
||||
}
|
|
@ -69,6 +69,10 @@ public class FlowerBlockBOP extends FlowerBlock
|
|||
{
|
||||
return ground == Blocks.SAND || ground == Blocks.RED_SAND || ground == BOPBlocks.white_sand || super.isValidPosition(state, worldIn, pos);
|
||||
}
|
||||
if (this == BOPBlocks.burning_blossom)
|
||||
{
|
||||
return ground == Blocks.NETHERRACK || ground == Blocks.SOUL_SAND || super.isValidPosition(state, worldIn, pos);
|
||||
}
|
||||
|
||||
return super.isValidPosition(state, worldIn, pos);
|
||||
}
|
||||
|
@ -96,11 +100,11 @@ public class FlowerBlockBOP extends FlowerBlock
|
|||
|
||||
if (block == BOPBlocks.burning_blossom)
|
||||
{
|
||||
if (rand.nextInt(4) == 0)
|
||||
if (rand.nextInt(8) == 0)
|
||||
{
|
||||
worldIn.addParticle(ParticleTypes.FLAME, (double)((float)pos.getX() + rand.nextFloat()), (double)((float)pos.getY() + rand.nextFloat()), (double)((float)pos.getZ() + rand.nextFloat()), 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
if (rand.nextInt(2) == 0)
|
||||
if (rand.nextInt(4) == 0)
|
||||
{
|
||||
worldIn.addParticle(ParticleTypes.SMOKE, (double)((float)pos.getX() + rand.nextFloat()), (double)((float)pos.getY() + rand.nextFloat()), (double)((float)pos.getZ() + rand.nextFloat()), 0.0D, 0.0D, 0.0D);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,953 @@
|
|||
package biomesoplenty.common.entity.item;
|
||||
|
||||
import biomesoplenty.api.block.BOPBlocks;
|
||||
import biomesoplenty.api.item.BOPItems;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.LilyPadBlock;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.MoverType;
|
||||
import net.minecraft.entity.item.BoatEntity;
|
||||
import net.minecraft.entity.passive.AnimalEntity;
|
||||
import net.minecraft.entity.passive.WaterMobEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.fluid.IFluidState;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.datasync.DataParameter;
|
||||
import net.minecraft.network.datasync.DataSerializers;
|
||||
import net.minecraft.network.datasync.EntityDataManager;
|
||||
import net.minecraft.network.play.client.CSteerBoatPacket;
|
||||
import net.minecraft.network.play.server.SSpawnObjectPacket;
|
||||
import net.minecraft.particles.ParticleTypes;
|
||||
import net.minecraft.tags.FluidTags;
|
||||
import net.minecraft.util.*;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.shapes.IBooleanFunction;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.math.shapes.VoxelShapes;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.List;
|
||||
|
||||
public class BoatEntityBOP extends Entity {
|
||||
private static final DataParameter<Integer> TIME_SINCE_HIT = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.VARINT);
|
||||
private static final DataParameter<Integer> FORWARD_DIRECTION = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.VARINT);
|
||||
private static final DataParameter<Float> DAMAGE_TAKEN = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.FLOAT);
|
||||
private static final DataParameter<Integer> BOAT_TYPE = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.VARINT);
|
||||
private static final DataParameter<Boolean> field_199704_e = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.BOOLEAN);
|
||||
private static final DataParameter<Boolean> field_199705_f = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.BOOLEAN);
|
||||
private static final DataParameter<Integer> ROCKING_TICKS = EntityDataManager.createKey(BoatEntityBOP.class, DataSerializers.VARINT);
|
||||
private final float[] paddlePositions = new float[2];
|
||||
private float momentum;
|
||||
private float outOfControlTicks;
|
||||
private float deltaRotation;
|
||||
private int lerpSteps;
|
||||
private double lerpX;
|
||||
private double lerpY;
|
||||
private double lerpZ;
|
||||
private double lerpYaw;
|
||||
private double lerpPitch;
|
||||
private boolean leftInputDown;
|
||||
private boolean rightInputDown;
|
||||
private boolean forwardInputDown;
|
||||
private boolean backInputDown;
|
||||
private double waterLevel;
|
||||
private float boatGlide;
|
||||
private BoatEntityBOP.Status status;
|
||||
private BoatEntityBOP.Status previousStatus;
|
||||
private double lastYd;
|
||||
private boolean rocking;
|
||||
private boolean field_203060_aN;
|
||||
private float rockingIntensity;
|
||||
private float rockingAngle;
|
||||
private float prevRockingAngle;
|
||||
|
||||
public BoatEntityBOP(EntityType p_i50129_1_, World p_i50129_2_) {
|
||||
super(p_i50129_1_, p_i50129_2_);
|
||||
this.preventEntitySpawning = true;
|
||||
}
|
||||
|
||||
public BoatEntityBOP(World worldIn, double x, double y, double z) {
|
||||
this(EntityType.BOAT, worldIn);
|
||||
this.setPosition(x, y, z);
|
||||
this.setMotion(Vec3d.ZERO);
|
||||
this.prevPosX = x;
|
||||
this.prevPosY = y;
|
||||
this.prevPosZ = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns if this entity triggers Block.onEntityWalking on the blocks they walk on. used for spiders and wolves to
|
||||
* prevent them from trampling crops
|
||||
*/
|
||||
protected boolean canTriggerWalking() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void registerData() {
|
||||
this.dataManager.register(TIME_SINCE_HIT, 0);
|
||||
this.dataManager.register(FORWARD_DIRECTION, 1);
|
||||
this.dataManager.register(DAMAGE_TAKEN, 0.0F);
|
||||
this.dataManager.register(BOAT_TYPE, Type.FIR.ordinal());
|
||||
this.dataManager.register(field_199704_e, false);
|
||||
this.dataManager.register(field_199705_f, false);
|
||||
this.dataManager.register(ROCKING_TICKS, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boundingBox used to collide the entity with other entities and blocks. This enables the entity to be
|
||||
* pushable on contact, like boats or minecarts.
|
||||
*/
|
||||
@Nullable
|
||||
public AxisAlignedBB getCollisionBox(Entity entityIn) {
|
||||
return entityIn.canBePushed() ? entityIn.getBoundingBox() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public AxisAlignedBB getCollisionBoundingBox() {
|
||||
return this.getBoundingBox();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this entity should push and be pushed by other entities when colliding.
|
||||
*/
|
||||
public boolean canBePushed() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Y offset from the entity's position for any entity riding this one.
|
||||
*/
|
||||
public double getMountedYOffset() {
|
||||
return -0.1D;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity is attacked.
|
||||
*/
|
||||
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||
if (this.isInvulnerableTo(source)) {
|
||||
return false;
|
||||
} else if (!this.world.isRemote && !this.removed) {
|
||||
if (source instanceof IndirectEntityDamageSource && source.getTrueSource() != null && this.isPassenger(source.getTrueSource())) {
|
||||
return false;
|
||||
} else {
|
||||
this.setForwardDirection(-this.getForwardDirection());
|
||||
this.setTimeSinceHit(10);
|
||||
this.setDamageTaken(this.getDamageTaken() + amount * 10.0F);
|
||||
this.markVelocityChanged();
|
||||
boolean flag = source.getTrueSource() instanceof PlayerEntity && ((PlayerEntity)source.getTrueSource()).abilities.isCreativeMode;
|
||||
if (flag || this.getDamageTaken() > 40.0F) {
|
||||
if (!flag && this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) {
|
||||
this.entityDropItem(this.getItemBoat());
|
||||
}
|
||||
|
||||
this.remove();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void onEnterBubbleColumnWithAirAbove(boolean downwards) {
|
||||
if (!this.world.isRemote) {
|
||||
this.rocking = true;
|
||||
this.field_203060_aN = downwards;
|
||||
if (this.getRockingTicks() == 0) {
|
||||
this.setRockingTicks(60);
|
||||
}
|
||||
}
|
||||
|
||||
this.world.addParticle(ParticleTypes.SPLASH, this.posX + (double)this.rand.nextFloat(), this.posY + 0.7D, this.posZ + (double)this.rand.nextFloat(), 0.0D, 0.0D, 0.0D);
|
||||
if (this.rand.nextInt(20) == 0) {
|
||||
this.world.playSound(this.posX, this.posY, this.posZ, this.getSplashSound(), this.getSoundCategory(), 1.0F, 0.8F + 0.4F * this.rand.nextFloat(), false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a velocity to the entities, to push them away from eachother.
|
||||
*/
|
||||
public void applyEntityCollision(Entity entityIn) {
|
||||
if (entityIn instanceof BoatEntity) {
|
||||
if (entityIn.getBoundingBox().minY < this.getBoundingBox().maxY) {
|
||||
super.applyEntityCollision(entityIn);
|
||||
}
|
||||
} else if (entityIn.getBoundingBox().minY <= this.getBoundingBox().minY) {
|
||||
super.applyEntityCollision(entityIn);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Item getItemBoat() {
|
||||
switch(this.getBoatType()) {
|
||||
case FIR:
|
||||
default:
|
||||
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;
|
||||
case ETHEREAL:
|
||||
return BOPItems.ethereal_boat;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setups the entity to do the hurt animation. Only used by packets in multiplayer.
|
||||
*/
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void performHurtAnimation() {
|
||||
this.setForwardDirection(-this.getForwardDirection());
|
||||
this.setTimeSinceHit(10);
|
||||
this.setDamageTaken(this.getDamageTaken() * 11.0F);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if other Entities should be prevented from moving through this Entity.
|
||||
*/
|
||||
public boolean canBeCollidedWith() {
|
||||
return !this.removed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a target for the client to interpolate towards over the next few ticks
|
||||
*/
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void setPositionAndRotationDirect(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport) {
|
||||
this.lerpX = x;
|
||||
this.lerpY = y;
|
||||
this.lerpZ = z;
|
||||
this.lerpYaw = (double)yaw;
|
||||
this.lerpPitch = (double)pitch;
|
||||
this.lerpSteps = 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the horizontal facing direction of this Entity, adjusted to take specially-treated entity types into account.
|
||||
*/
|
||||
public Direction getAdjustedHorizontalFacing() {
|
||||
return this.getHorizontalFacing().rotateY();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to update the entity's position/logic.
|
||||
*/
|
||||
@Override
|
||||
public void tick() {
|
||||
this.previousStatus = this.status;
|
||||
this.status = this.getBoatStatus();
|
||||
if (this.status != BoatEntityBOP.Status.UNDER_WATER && this.status != BoatEntityBOP.Status.UNDER_FLOWING_WATER) {
|
||||
this.outOfControlTicks = 0.0F;
|
||||
} else {
|
||||
++this.outOfControlTicks;
|
||||
}
|
||||
|
||||
if (!this.world.isRemote && this.outOfControlTicks >= 60.0F) {
|
||||
this.removePassengers();
|
||||
}
|
||||
|
||||
if (this.getTimeSinceHit() > 0) {
|
||||
this.setTimeSinceHit(this.getTimeSinceHit() - 1);
|
||||
}
|
||||
|
||||
if (this.getDamageTaken() > 0.0F) {
|
||||
this.setDamageTaken(this.getDamageTaken() - 1.0F);
|
||||
}
|
||||
|
||||
this.prevPosX = this.posX;
|
||||
this.prevPosY = this.posY;
|
||||
this.prevPosZ = this.posZ;
|
||||
super.tick();
|
||||
this.tickLerp();
|
||||
if (this.canPassengerSteer()) {
|
||||
if (this.getPassengers().isEmpty() || !(this.getPassengers().get(0) instanceof PlayerEntity)) {
|
||||
this.setPaddleState(false, false);
|
||||
}
|
||||
|
||||
this.updateMotion();
|
||||
if (this.world.isRemote) {
|
||||
this.controlBoat();
|
||||
this.world.sendPacketToServer(new CSteerBoatPacket(this.getPaddleState(0), this.getPaddleState(1)));
|
||||
}
|
||||
|
||||
this.move(MoverType.SELF, this.getMotion());
|
||||
} else {
|
||||
this.setMotion(Vec3d.ZERO);
|
||||
}
|
||||
|
||||
this.updateRocking();
|
||||
|
||||
for(int i = 0; i <= 1; ++i) {
|
||||
if (this.getPaddleState(i)) {
|
||||
if (!this.isSilent() && (double)(this.paddlePositions[i] % ((float)Math.PI * 2F)) <= (double)((float)Math.PI / 4F) && ((double)this.paddlePositions[i] + (double)((float)Math.PI / 8F)) % (double)((float)Math.PI * 2F) >= (double)((float)Math.PI / 4F)) {
|
||||
SoundEvent soundevent = this.getPaddleSound();
|
||||
if (soundevent != null) {
|
||||
Vec3d vec3d = this.getLook(1.0F);
|
||||
double d0 = i == 1 ? -vec3d.z : vec3d.z;
|
||||
double d1 = i == 1 ? vec3d.x : -vec3d.x;
|
||||
this.world.playSound((PlayerEntity)null, this.posX + d0, this.posY, this.posZ + d1, soundevent, this.getSoundCategory(), 1.0F, 0.8F + 0.4F * this.rand.nextFloat());
|
||||
}
|
||||
}
|
||||
|
||||
this.paddlePositions[i] = (float)((double)this.paddlePositions[i] + (double)((float)Math.PI / 8F));
|
||||
} else {
|
||||
this.paddlePositions[i] = 0.0F;
|
||||
}
|
||||
}
|
||||
|
||||
this.doBlockCollisions();
|
||||
List<Entity> list = this.world.getEntitiesInAABBexcluding(this, this.getBoundingBox().grow((double)0.2F, (double)-0.01F, (double)0.2F), EntityPredicates.pushableBy(this));
|
||||
if (!list.isEmpty()) {
|
||||
boolean flag = !this.world.isRemote && !(this.getControllingPassenger() instanceof PlayerEntity);
|
||||
|
||||
for(int j = 0; j < list.size(); ++j) {
|
||||
Entity entity = list.get(j);
|
||||
if (!entity.isPassenger(this)) {
|
||||
if (flag && this.getPassengers().size() < 2 && !entity.isPassenger() && entity.getWidth() < this.getWidth() && entity instanceof LivingEntity && !(entity instanceof WaterMobEntity) && !(entity instanceof PlayerEntity)) {
|
||||
entity.startRiding(this);
|
||||
} else {
|
||||
this.applyEntityCollision(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void updateRocking() {
|
||||
if (this.world.isRemote) {
|
||||
int i = this.getRockingTicks();
|
||||
if (i > 0) {
|
||||
this.rockingIntensity += 0.05F;
|
||||
} else {
|
||||
this.rockingIntensity -= 0.1F;
|
||||
}
|
||||
|
||||
this.rockingIntensity = MathHelper.clamp(this.rockingIntensity, 0.0F, 1.0F);
|
||||
this.prevRockingAngle = this.rockingAngle;
|
||||
this.rockingAngle = 10.0F * (float)Math.sin((double)(0.5F * (float)this.world.getGameTime())) * this.rockingIntensity;
|
||||
} else {
|
||||
if (!this.rocking) {
|
||||
this.setRockingTicks(0);
|
||||
}
|
||||
|
||||
int k = this.getRockingTicks();
|
||||
if (k > 0) {
|
||||
--k;
|
||||
this.setRockingTicks(k);
|
||||
int j = 60 - k - 1;
|
||||
if (j > 0 && k == 0) {
|
||||
this.setRockingTicks(0);
|
||||
Vec3d vec3d = this.getMotion();
|
||||
if (this.field_203060_aN) {
|
||||
this.setMotion(vec3d.add(0.0D, -0.7D, 0.0D));
|
||||
this.removePassengers();
|
||||
} else {
|
||||
this.setMotion(vec3d.x, this.isPassenger(PlayerEntity.class) ? 2.7D : 0.6D, vec3d.z);
|
||||
}
|
||||
}
|
||||
|
||||
this.rocking = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected SoundEvent getPaddleSound() {
|
||||
switch(this.getBoatStatus()) {
|
||||
case IN_WATER:
|
||||
case UNDER_WATER:
|
||||
case UNDER_FLOWING_WATER:
|
||||
return SoundEvents.ENTITY_BOAT_PADDLE_WATER;
|
||||
case ON_LAND:
|
||||
return SoundEvents.ENTITY_BOAT_PADDLE_LAND;
|
||||
case IN_AIR:
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void tickLerp() {
|
||||
if (this.lerpSteps > 0 && !this.canPassengerSteer()) {
|
||||
double d0 = this.posX + (this.lerpX - this.posX) / (double)this.lerpSteps;
|
||||
double d1 = this.posY + (this.lerpY - this.posY) / (double)this.lerpSteps;
|
||||
double d2 = this.posZ + (this.lerpZ - this.posZ) / (double)this.lerpSteps;
|
||||
double d3 = MathHelper.wrapDegrees(this.lerpYaw - (double)this.rotationYaw);
|
||||
this.rotationYaw = (float)((double)this.rotationYaw + d3 / (double)this.lerpSteps);
|
||||
this.rotationPitch = (float)((double)this.rotationPitch + (this.lerpPitch - (double)this.rotationPitch) / (double)this.lerpSteps);
|
||||
--this.lerpSteps;
|
||||
this.setPosition(d0, d1, d2);
|
||||
this.setRotation(this.rotationYaw, this.rotationPitch);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPaddleState(boolean left, boolean right) {
|
||||
this.dataManager.set(field_199704_e, left);
|
||||
this.dataManager.set(field_199705_f, right);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public float getRowingTime(int side, float limbSwing) {
|
||||
return this.getPaddleState(side) ? (float)MathHelper.clampedLerp((double)this.paddlePositions[side] - (double)((float)Math.PI / 8F), (double)this.paddlePositions[side], (double)limbSwing) : 0.0F;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the boat is in water, gliding on land, or in air
|
||||
*/
|
||||
private BoatEntityBOP.Status getBoatStatus() {
|
||||
BoatEntityBOP.Status boatentity$status = this.getUnderwaterStatus();
|
||||
if (boatentity$status != null) {
|
||||
this.waterLevel = this.getBoundingBox().maxY;
|
||||
return boatentity$status;
|
||||
} else if (this.checkInWater()) {
|
||||
return BoatEntityBOP.Status.IN_WATER;
|
||||
} else {
|
||||
float f = this.getBoatGlide();
|
||||
if (f > 0.0F) {
|
||||
this.boatGlide = f;
|
||||
return BoatEntityBOP.Status.ON_LAND;
|
||||
} else {
|
||||
return BoatEntityBOP.Status.IN_AIR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float getWaterLevelAbove() {
|
||||
AxisAlignedBB axisalignedbb = this.getBoundingBox();
|
||||
int i = MathHelper.floor(axisalignedbb.minX);
|
||||
int j = MathHelper.ceil(axisalignedbb.maxX);
|
||||
int k = MathHelper.floor(axisalignedbb.maxY);
|
||||
int l = MathHelper.ceil(axisalignedbb.maxY - this.lastYd);
|
||||
int i1 = MathHelper.floor(axisalignedbb.minZ);
|
||||
int j1 = MathHelper.ceil(axisalignedbb.maxZ);
|
||||
|
||||
try (BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain()) {
|
||||
label161:
|
||||
for(int k1 = k; k1 < l; ++k1) {
|
||||
float f = 0.0F;
|
||||
|
||||
for(int l1 = i; l1 < j; ++l1) {
|
||||
for(int i2 = i1; i2 < j1; ++i2) {
|
||||
blockpos$pooledmutableblockpos.setPos(l1, k1, i2);
|
||||
IFluidState ifluidstate = this.world.getFluidState(blockpos$pooledmutableblockpos);
|
||||
if (ifluidstate.isTagged(FluidTags.WATER)) {
|
||||
f = Math.max(f, ifluidstate.func_215679_a(this.world, blockpos$pooledmutableblockpos));
|
||||
}
|
||||
|
||||
if (f >= 1.0F) {
|
||||
continue label161;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (f < 1.0F) {
|
||||
float f2 = (float)blockpos$pooledmutableblockpos.getY() + f;
|
||||
return f2;
|
||||
}
|
||||
}
|
||||
|
||||
float f1 = (float)(l + 1);
|
||||
return f1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides how much the boat should be gliding on the land (based on any slippery blocks)
|
||||
*/
|
||||
public float getBoatGlide() {
|
||||
AxisAlignedBB axisalignedbb = this.getBoundingBox();
|
||||
AxisAlignedBB axisalignedbb1 = new AxisAlignedBB(axisalignedbb.minX, axisalignedbb.minY - 0.001D, axisalignedbb.minZ, axisalignedbb.maxX, axisalignedbb.minY, axisalignedbb.maxZ);
|
||||
int i = MathHelper.floor(axisalignedbb1.minX) - 1;
|
||||
int j = MathHelper.ceil(axisalignedbb1.maxX) + 1;
|
||||
int k = MathHelper.floor(axisalignedbb1.minY) - 1;
|
||||
int l = MathHelper.ceil(axisalignedbb1.maxY) + 1;
|
||||
int i1 = MathHelper.floor(axisalignedbb1.minZ) - 1;
|
||||
int j1 = MathHelper.ceil(axisalignedbb1.maxZ) + 1;
|
||||
VoxelShape voxelshape = VoxelShapes.create(axisalignedbb1);
|
||||
float f = 0.0F;
|
||||
int k1 = 0;
|
||||
|
||||
try (BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain()) {
|
||||
for(int l1 = i; l1 < j; ++l1) {
|
||||
for(int i2 = i1; i2 < j1; ++i2) {
|
||||
int j2 = (l1 != i && l1 != j - 1 ? 0 : 1) + (i2 != i1 && i2 != j1 - 1 ? 0 : 1);
|
||||
if (j2 != 2) {
|
||||
for(int k2 = k; k2 < l; ++k2) {
|
||||
if (j2 <= 0 || k2 != k && k2 != l - 1) {
|
||||
blockpos$pooledmutableblockpos.setPos(l1, k2, i2);
|
||||
BlockState blockstate = this.world.getBlockState(blockpos$pooledmutableblockpos);
|
||||
if (!(blockstate.getBlock() instanceof LilyPadBlock) && VoxelShapes.compare(blockstate.getCollisionShape(this.world, blockpos$pooledmutableblockpos).withOffset((double)l1, (double)k2, (double)i2), voxelshape, IBooleanFunction.AND)) {
|
||||
f += blockstate.getSlipperiness(this.world, blockpos$pooledmutableblockpos, this);
|
||||
++k1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return f / (float)k1;
|
||||
}
|
||||
|
||||
private boolean checkInWater() {
|
||||
AxisAlignedBB axisalignedbb = this.getBoundingBox();
|
||||
int i = MathHelper.floor(axisalignedbb.minX);
|
||||
int j = MathHelper.ceil(axisalignedbb.maxX);
|
||||
int k = MathHelper.floor(axisalignedbb.minY);
|
||||
int l = MathHelper.ceil(axisalignedbb.minY + 0.001D);
|
||||
int i1 = MathHelper.floor(axisalignedbb.minZ);
|
||||
int j1 = MathHelper.ceil(axisalignedbb.maxZ);
|
||||
boolean flag = false;
|
||||
this.waterLevel = Double.MIN_VALUE;
|
||||
|
||||
try (BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain()) {
|
||||
for(int k1 = i; k1 < j; ++k1) {
|
||||
for(int l1 = k; l1 < l; ++l1) {
|
||||
for(int i2 = i1; i2 < j1; ++i2) {
|
||||
blockpos$pooledmutableblockpos.setPos(k1, l1, i2);
|
||||
IFluidState ifluidstate = this.world.getFluidState(blockpos$pooledmutableblockpos);
|
||||
if (ifluidstate.isTagged(FluidTags.WATER)) {
|
||||
float f = (float)l1 + ifluidstate.func_215679_a(this.world, blockpos$pooledmutableblockpos);
|
||||
this.waterLevel = Math.max((double)f, this.waterLevel);
|
||||
flag |= axisalignedbb.minY < (double)f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides whether the boat is currently underwater.
|
||||
*/
|
||||
@Nullable
|
||||
private BoatEntityBOP.Status getUnderwaterStatus() {
|
||||
AxisAlignedBB axisalignedbb = this.getBoundingBox();
|
||||
double d0 = axisalignedbb.maxY + 0.001D;
|
||||
int i = MathHelper.floor(axisalignedbb.minX);
|
||||
int j = MathHelper.ceil(axisalignedbb.maxX);
|
||||
int k = MathHelper.floor(axisalignedbb.maxY);
|
||||
int l = MathHelper.ceil(d0);
|
||||
int i1 = MathHelper.floor(axisalignedbb.minZ);
|
||||
int j1 = MathHelper.ceil(axisalignedbb.maxZ);
|
||||
boolean flag = false;
|
||||
|
||||
try (BlockPos.PooledMutableBlockPos blockpos$pooledmutableblockpos = BlockPos.PooledMutableBlockPos.retain()) {
|
||||
for(int k1 = i; k1 < j; ++k1) {
|
||||
for(int l1 = k; l1 < l; ++l1) {
|
||||
for(int i2 = i1; i2 < j1; ++i2) {
|
||||
blockpos$pooledmutableblockpos.setPos(k1, l1, i2);
|
||||
IFluidState ifluidstate = this.world.getFluidState(blockpos$pooledmutableblockpos);
|
||||
if (ifluidstate.isTagged(FluidTags.WATER) && d0 < (double)((float)blockpos$pooledmutableblockpos.getY() + ifluidstate.func_215679_a(this.world, blockpos$pooledmutableblockpos))) {
|
||||
if (!ifluidstate.isSource()) {
|
||||
BoatEntityBOP.Status boatentity$status = BoatEntityBOP.Status.UNDER_FLOWING_WATER;
|
||||
return boatentity$status;
|
||||
}
|
||||
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return flag ? BoatEntityBOP.Status.UNDER_WATER : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the boat's speed, based on momentum.
|
||||
*/
|
||||
private void updateMotion() {
|
||||
double d0 = (double)-0.04F;
|
||||
double d1 = this.hasNoGravity() ? 0.0D : (double)-0.04F;
|
||||
double d2 = 0.0D;
|
||||
this.momentum = 0.05F;
|
||||
if (this.previousStatus == BoatEntityBOP.Status.IN_AIR && this.status != BoatEntityBOP.Status.IN_AIR && this.status != BoatEntityBOP.Status.ON_LAND) {
|
||||
this.waterLevel = this.getBoundingBox().minY + (double)this.getHeight();
|
||||
this.setPosition(this.posX, (double)(this.getWaterLevelAbove() - this.getHeight()) + 0.101D, this.posZ);
|
||||
this.setMotion(this.getMotion().mul(1.0D, 0.0D, 1.0D));
|
||||
this.lastYd = 0.0D;
|
||||
this.status = BoatEntityBOP.Status.IN_WATER;
|
||||
} else {
|
||||
if (this.status == BoatEntityBOP.Status.IN_WATER) {
|
||||
d2 = (this.waterLevel - this.getBoundingBox().minY) / (double)this.getHeight();
|
||||
this.momentum = 0.9F;
|
||||
} else if (this.status == BoatEntityBOP.Status.UNDER_FLOWING_WATER) {
|
||||
d1 = -7.0E-4D;
|
||||
this.momentum = 0.9F;
|
||||
} else if (this.status == BoatEntityBOP.Status.UNDER_WATER) {
|
||||
d2 = (double)0.01F;
|
||||
this.momentum = 0.45F;
|
||||
} else if (this.status == BoatEntityBOP.Status.IN_AIR) {
|
||||
this.momentum = 0.9F;
|
||||
} else if (this.status == BoatEntityBOP.Status.ON_LAND) {
|
||||
this.momentum = this.boatGlide;
|
||||
if (this.getControllingPassenger() instanceof PlayerEntity) {
|
||||
this.boatGlide /= 2.0F;
|
||||
}
|
||||
}
|
||||
|
||||
Vec3d vec3d = this.getMotion();
|
||||
this.setMotion(vec3d.x * (double)this.momentum, vec3d.y + d1, vec3d.z * (double)this.momentum);
|
||||
this.deltaRotation *= this.momentum;
|
||||
if (d2 > 0.0D) {
|
||||
Vec3d vec3d1 = this.getMotion();
|
||||
this.setMotion(vec3d1.x, (vec3d1.y + d2 * 0.06153846016296973D) * 0.75D, vec3d1.z);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void controlBoat() {
|
||||
if (this.isBeingRidden()) {
|
||||
float f = 0.0F;
|
||||
if (this.leftInputDown) {
|
||||
--this.deltaRotation;
|
||||
}
|
||||
|
||||
if (this.rightInputDown) {
|
||||
++this.deltaRotation;
|
||||
}
|
||||
|
||||
if (this.rightInputDown != this.leftInputDown && !this.forwardInputDown && !this.backInputDown) {
|
||||
f += 0.005F;
|
||||
}
|
||||
|
||||
this.rotationYaw += this.deltaRotation;
|
||||
if (this.forwardInputDown) {
|
||||
f += 0.04F;
|
||||
}
|
||||
|
||||
if (this.backInputDown) {
|
||||
f -= 0.005F;
|
||||
}
|
||||
|
||||
this.setMotion(this.getMotion().add((double)(MathHelper.sin(-this.rotationYaw * ((float)Math.PI / 180F)) * f), 0.0D, (double)(MathHelper.cos(this.rotationYaw * ((float)Math.PI / 180F)) * f)));
|
||||
this.setPaddleState(this.rightInputDown && !this.leftInputDown || this.forwardInputDown, this.leftInputDown && !this.rightInputDown || this.forwardInputDown);
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePassenger(Entity passenger) {
|
||||
if (this.isPassenger(passenger)) {
|
||||
float f = 0.0F;
|
||||
float f1 = (float)((this.removed ? (double)0.01F : this.getMountedYOffset()) + passenger.getYOffset());
|
||||
if (this.getPassengers().size() > 1) {
|
||||
int i = this.getPassengers().indexOf(passenger);
|
||||
if (i == 0) {
|
||||
f = 0.2F;
|
||||
} else {
|
||||
f = -0.6F;
|
||||
}
|
||||
|
||||
if (passenger instanceof AnimalEntity) {
|
||||
f = (float)((double)f + 0.2D);
|
||||
}
|
||||
}
|
||||
|
||||
Vec3d vec3d = (new Vec3d((double)f, 0.0D, 0.0D)).rotateYaw(-this.rotationYaw * ((float)Math.PI / 180F) - ((float)Math.PI / 2F));
|
||||
passenger.setPosition(this.posX + vec3d.x, this.posY + (double)f1, this.posZ + vec3d.z);
|
||||
passenger.rotationYaw += this.deltaRotation;
|
||||
passenger.setRotationYawHead(passenger.getRotationYawHead() + this.deltaRotation);
|
||||
this.applyYawToEntity(passenger);
|
||||
if (passenger instanceof AnimalEntity && this.getPassengers().size() > 1) {
|
||||
int j = passenger.getEntityId() % 2 == 0 ? 90 : 270;
|
||||
passenger.setRenderYawOffset(((AnimalEntity)passenger).renderYawOffset + (float)j);
|
||||
passenger.setRotationYawHead(passenger.getRotationYawHead() + (float)j);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies this boat's yaw to the given entity. Used to update the orientation of its passenger.
|
||||
*/
|
||||
protected void applyYawToEntity(Entity entityToUpdate) {
|
||||
entityToUpdate.setRenderYawOffset(this.rotationYaw);
|
||||
float f = MathHelper.wrapDegrees(entityToUpdate.rotationYaw - this.rotationYaw);
|
||||
float f1 = MathHelper.clamp(f, -105.0F, 105.0F);
|
||||
entityToUpdate.prevRotationYaw += f1 - f;
|
||||
entityToUpdate.rotationYaw += f1 - f;
|
||||
entityToUpdate.setRotationYawHead(entityToUpdate.rotationYaw);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies this entity's orientation (pitch/yaw) to another entity. Used to update passenger orientation.
|
||||
*/
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void applyOrientationToEntity(Entity entityToUpdate) {
|
||||
this.applyYawToEntity(entityToUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeAdditional(CompoundNBT compound) {
|
||||
compound.putString("Type", this.getBoatType().getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* (abstract) Protected helper method to read subclass entity data from NBT.
|
||||
*/
|
||||
@Override
|
||||
protected void readAdditional(CompoundNBT compound) {
|
||||
if (compound.contains("Type", 8)) {
|
||||
this.setBoatType(Type.getTypeFromString(compound.getString("Type")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean processInitialInteract(PlayerEntity player, Hand hand) {
|
||||
if (player.isSneaking()) {
|
||||
return false;
|
||||
} else {
|
||||
if (!this.world.isRemote && this.outOfControlTicks < 60.0F) {
|
||||
player.startRiding(this);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateFallState(double y, boolean onGroundIn, BlockState state, BlockPos pos) {
|
||||
this.lastYd = this.getMotion().y;
|
||||
if (!this.isPassenger()) {
|
||||
if (onGroundIn) {
|
||||
if (this.fallDistance > 3.0F) {
|
||||
if (this.status != BoatEntityBOP.Status.ON_LAND) {
|
||||
this.fallDistance = 0.0F;
|
||||
return;
|
||||
}
|
||||
|
||||
this.fall(this.fallDistance, 1.0F);
|
||||
if (!this.world.isRemote && !this.removed) {
|
||||
this.remove();
|
||||
if (this.world.getGameRules().getBoolean(GameRules.DO_ENTITY_DROPS)) {
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
this.entityDropItem(this.getBoatType().asPlank());
|
||||
}
|
||||
|
||||
for(int j = 0; j < 2; ++j) {
|
||||
this.entityDropItem(Items.STICK);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.fallDistance = 0.0F;
|
||||
} else if (!this.world.getFluidState((new BlockPos(this)).down()).isTagged(FluidTags.WATER) && y < 0.0D) {
|
||||
this.fallDistance = (float)((double)this.fallDistance - y);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getPaddleState(int side) {
|
||||
return this.dataManager.<Boolean>get(side == 0 ? field_199704_e : field_199705_f) && this.getControllingPassenger() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the damage taken from the last hit.
|
||||
*/
|
||||
public void setDamageTaken(float damageTaken) {
|
||||
this.dataManager.set(DAMAGE_TAKEN, damageTaken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the damage taken from the last hit.
|
||||
*/
|
||||
public float getDamageTaken() {
|
||||
return this.dataManager.get(DAMAGE_TAKEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time to count down from since the last time entity was hit.
|
||||
*/
|
||||
public void setTimeSinceHit(int timeSinceHit) {
|
||||
this.dataManager.set(TIME_SINCE_HIT, timeSinceHit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the time since the last hit.
|
||||
*/
|
||||
public int getTimeSinceHit() {
|
||||
return this.dataManager.get(TIME_SINCE_HIT);
|
||||
}
|
||||
|
||||
private void setRockingTicks(int p_203055_1_) {
|
||||
this.dataManager.set(ROCKING_TICKS, p_203055_1_);
|
||||
}
|
||||
|
||||
private int getRockingTicks() {
|
||||
return this.dataManager.get(ROCKING_TICKS);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public float getRockingAngle(float partialTicks) {
|
||||
return MathHelper.lerp(partialTicks, this.prevRockingAngle, this.rockingAngle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the forward direction of the entity.
|
||||
*/
|
||||
public void setForwardDirection(int forwardDirection) {
|
||||
this.dataManager.set(FORWARD_DIRECTION, forwardDirection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the forward direction of the entity.
|
||||
*/
|
||||
public int getForwardDirection() {
|
||||
return this.dataManager.get(FORWARD_DIRECTION);
|
||||
}
|
||||
|
||||
public void setBoatType(Type boatType) {
|
||||
this.dataManager.set(BOAT_TYPE, boatType.ordinal());
|
||||
}
|
||||
|
||||
public Type getBoatType() {
|
||||
return Type.byId(this.dataManager.get(BOAT_TYPE));
|
||||
}
|
||||
|
||||
protected boolean canFitPassenger(Entity passenger) {
|
||||
return this.getPassengers().size() < 2 && !this.areEyesInFluid(FluidTags.WATER);
|
||||
}
|
||||
|
||||
/**
|
||||
* For vehicles, the first passenger is generally considered the controller and "drives" the vehicle. For example,
|
||||
* Pigs, Horses, and Boats are generally "steered" by the controlling passenger.
|
||||
*/
|
||||
@Nullable
|
||||
public Entity getControllingPassenger() {
|
||||
List<Entity> list = this.getPassengers();
|
||||
return list.isEmpty() ? null : list.get(0);
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public void updateInputs(boolean p_184442_1_, boolean p_184442_2_, boolean p_184442_3_, boolean p_184442_4_) {
|
||||
this.leftInputDown = p_184442_1_;
|
||||
this.rightInputDown = p_184442_2_;
|
||||
this.forwardInputDown = p_184442_3_;
|
||||
this.backInputDown = p_184442_4_;
|
||||
}
|
||||
|
||||
public IPacket<?> createSpawnPacket() {
|
||||
return new SSpawnObjectPacket(this);
|
||||
}
|
||||
|
||||
// Forge: Fix MC-119811 by instantly completing lerp on board
|
||||
@Override
|
||||
protected void addPassenger(Entity passenger) {
|
||||
super.addPassenger(passenger);
|
||||
if (this.canPassengerSteer() && this.lerpSteps > 0) {
|
||||
this.lerpSteps = 0;
|
||||
this.posX = this.lerpX;
|
||||
this.posY = this.lerpY;
|
||||
this.posZ = this.lerpZ;
|
||||
this.rotationYaw = (float)this.lerpYaw;
|
||||
this.rotationPitch = (float)this.lerpPitch;
|
||||
}
|
||||
}
|
||||
|
||||
public static enum Status {
|
||||
IN_WATER,
|
||||
UNDER_WATER,
|
||||
UNDER_FLOWING_WATER,
|
||||
ON_LAND,
|
||||
IN_AIR;
|
||||
}
|
||||
|
||||
public static enum Type {
|
||||
FIR(BOPBlocks.fir_planks, "fir"),
|
||||
REDWOOD(BOPBlocks.redwood_planks, "redwood"),
|
||||
CHERRY(BOPBlocks.cherry_planks, "cherry"),
|
||||
MAHOGANY(BOPBlocks.mahogany_planks, "mahogany"),
|
||||
JACARANDA(BOPBlocks.jacaranda_planks, "jacaranda"),
|
||||
PALM(BOPBlocks.palm_planks, "palm"),
|
||||
WILLOW(BOPBlocks.willow_planks, "willow"),
|
||||
DEAD(BOPBlocks.dead_planks, "dead"),
|
||||
MAGIC(BOPBlocks.magic_planks, "magic"),
|
||||
UMBRAN(BOPBlocks.umbran_planks, "umbran"),
|
||||
HELLBARK(BOPBlocks.hellbark_planks, "hellbark"),
|
||||
ETHEREAL(BOPBlocks.ethereal_planks, "ethereal");
|
||||
|
||||
private final String name;
|
||||
private final Block block;
|
||||
|
||||
private Type(Block p_i48146_3_, String p_i48146_4_) {
|
||||
this.name = p_i48146_4_;
|
||||
this.block = p_i48146_3_;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Block asPlank() {
|
||||
return this.block;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a boat type by it's enum ordinal
|
||||
* @return
|
||||
*/
|
||||
public static Type byId(int id) {
|
||||
Type[] aboatentity$type = values();
|
||||
if (id < 0 || id >= aboatentity$type.length) {
|
||||
id = 0;
|
||||
}
|
||||
|
||||
return aboatentity$type[id];
|
||||
}
|
||||
|
||||
public static Type getTypeFromString(String nameIn) {
|
||||
Type[] aboatentity$type = values();
|
||||
|
||||
for(int i = 0; i < aboatentity$type.length; ++i) {
|
||||
if (aboatentity$type[i].getName().equals(nameIn)) {
|
||||
return aboatentity$type[i];
|
||||
}
|
||||
}
|
||||
|
||||
return aboatentity$type[0];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package biomesoplenty.common.entity.item;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import net.minecraft.client.renderer.entity.model.EntityModel;
|
||||
import net.minecraft.client.renderer.entity.model.RendererModel;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.BoatEntity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BoatModelBOP extends EntityModel<BoatEntityBOP> {
|
||||
private final RendererModel[] field_78103_a = new RendererModel[5];
|
||||
private final RendererModel[] paddles = new RendererModel[2];
|
||||
private final RendererModel noWater;
|
||||
|
||||
public BoatModelBOP() {
|
||||
this.field_78103_a[0] = (new RendererModel(this, 0, 0)).setTextureSize(128, 64);
|
||||
this.field_78103_a[1] = (new RendererModel(this, 0, 19)).setTextureSize(128, 64);
|
||||
this.field_78103_a[2] = (new RendererModel(this, 0, 27)).setTextureSize(128, 64);
|
||||
this.field_78103_a[3] = (new RendererModel(this, 0, 35)).setTextureSize(128, 64);
|
||||
this.field_78103_a[4] = (new RendererModel(this, 0, 43)).setTextureSize(128, 64);
|
||||
int i = 32;
|
||||
int j = 6;
|
||||
int k = 20;
|
||||
int l = 4;
|
||||
int i1 = 28;
|
||||
this.field_78103_a[0].addBox(-14.0F, -9.0F, -3.0F, 28, 16, 3, 0.0F);
|
||||
this.field_78103_a[0].setRotationPoint(0.0F, 3.0F, 1.0F);
|
||||
this.field_78103_a[1].addBox(-13.0F, -7.0F, -1.0F, 18, 6, 2, 0.0F);
|
||||
this.field_78103_a[1].setRotationPoint(-15.0F, 4.0F, 4.0F);
|
||||
this.field_78103_a[2].addBox(-8.0F, -7.0F, -1.0F, 16, 6, 2, 0.0F);
|
||||
this.field_78103_a[2].setRotationPoint(15.0F, 4.0F, 0.0F);
|
||||
this.field_78103_a[3].addBox(-14.0F, -7.0F, -1.0F, 28, 6, 2, 0.0F);
|
||||
this.field_78103_a[3].setRotationPoint(0.0F, 4.0F, -9.0F);
|
||||
this.field_78103_a[4].addBox(-14.0F, -7.0F, -1.0F, 28, 6, 2, 0.0F);
|
||||
this.field_78103_a[4].setRotationPoint(0.0F, 4.0F, 9.0F);
|
||||
this.field_78103_a[0].rotateAngleX = ((float)Math.PI / 2F);
|
||||
this.field_78103_a[1].rotateAngleY = ((float)Math.PI * 1.5F);
|
||||
this.field_78103_a[2].rotateAngleY = ((float)Math.PI / 2F);
|
||||
this.field_78103_a[3].rotateAngleY = (float)Math.PI;
|
||||
this.paddles[0] = this.makePaddle(true);
|
||||
this.paddles[0].setRotationPoint(3.0F, -5.0F, 9.0F);
|
||||
this.paddles[1] = this.makePaddle(false);
|
||||
this.paddles[1].setRotationPoint(3.0F, -5.0F, -9.0F);
|
||||
this.paddles[1].rotateAngleY = (float)Math.PI;
|
||||
this.paddles[0].rotateAngleZ = 0.19634955F;
|
||||
this.paddles[1].rotateAngleZ = 0.19634955F;
|
||||
this.noWater = (new RendererModel(this, 0, 0)).setTextureSize(128, 64);
|
||||
this.noWater.addBox(-14.0F, -9.0F, -3.0F, 28, 16, 3, 0.0F);
|
||||
this.noWater.setRotationPoint(0.0F, -3.0F, 1.0F);
|
||||
this.noWater.rotateAngleX = ((float)Math.PI / 2F);
|
||||
}
|
||||
|
||||
public void render(BoatEntityBOP entityIn, float limbSwing, float limbSwingAmount, float ageInTicks, float netHeadYaw, float headPitch, float scale) {
|
||||
GlStateManager.rotatef(90.0F, 0.0F, 1.0F, 0.0F);
|
||||
this.setRotationAngles(entityIn, limbSwing, limbSwingAmount, ageInTicks, netHeadYaw, headPitch, scale);
|
||||
|
||||
for(int i = 0; i < 5; ++i) {
|
||||
this.field_78103_a[i].render(scale);
|
||||
}
|
||||
|
||||
this.renderPaddle(entityIn, 0, scale, limbSwing);
|
||||
this.renderPaddle(entityIn, 1, scale, limbSwing);
|
||||
}
|
||||
|
||||
public void renderMultipass(Entity entityIn, float partialTicks, float p_187054_3_, float p_187054_4_, float p_187054_5_, float p_187054_6_, float scale) {
|
||||
GlStateManager.rotatef(90.0F, 0.0F, 1.0F, 0.0F);
|
||||
GlStateManager.colorMask(false, false, false, false);
|
||||
this.noWater.render(scale);
|
||||
GlStateManager.colorMask(true, true, true, true);
|
||||
}
|
||||
|
||||
protected RendererModel makePaddle(boolean p_187056_1_) {
|
||||
RendererModel renderermodel = (new RendererModel(this, 62, p_187056_1_ ? 0 : 20)).setTextureSize(128, 64);
|
||||
int i = 20;
|
||||
int j = 7;
|
||||
int k = 6;
|
||||
float f = -5.0F;
|
||||
renderermodel.addBox(-1.0F, 0.0F, -5.0F, 2, 2, 18);
|
||||
renderermodel.addBox(p_187056_1_ ? -1.001F : 0.001F, -3.0F, 8.0F, 1, 6, 7);
|
||||
return renderermodel;
|
||||
}
|
||||
|
||||
protected void renderPaddle(BoatEntityBOP boat, int paddle, float scale, float limbSwing) {
|
||||
float f = boat.getRowingTime(paddle, limbSwing);
|
||||
RendererModel renderermodel = this.paddles[paddle];
|
||||
renderermodel.rotateAngleX = (float) MathHelper.clampedLerp((double)(-(float)Math.PI / 3F), (double)-0.2617994F, (double)((MathHelper.sin(-f) + 1.0F) / 2.0F));
|
||||
renderermodel.rotateAngleY = (float)MathHelper.clampedLerp((double)(-(float)Math.PI / 4F), (double)((float)Math.PI / 4F), (double)((MathHelper.sin(-f + 1.0F) + 1.0F) / 2.0F));
|
||||
if (paddle == 1) {
|
||||
renderermodel.rotateAngleY = (float)Math.PI - renderermodel.rotateAngleY;
|
||||
}
|
||||
|
||||
renderermodel.render(scale);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,87 @@
|
|||
package biomesoplenty.common.entity.item;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
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.entity.item.BoatEntity;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class BoatRendererBOP extends EntityRenderer<BoatEntityBOP> {
|
||||
private static final ResourceLocation[] BOAT_TEXTURES = new ResourceLocation[]{new ResourceLocation("biomesoplenty:textures/entity/boat/fir.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/redwood.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/cherry.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/mahogany.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/jacaranda.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/palm.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/willow.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/dead.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/magic.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/umbran.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/hellbark.png"), new ResourceLocation("biomesoplenty:textures/entity/boat/ethereal.png")};
|
||||
protected final BoatModelBOP field_76998_a = new BoatModelBOP();
|
||||
|
||||
public BoatRendererBOP(EntityRendererManager renderManagerIn) {
|
||||
super(renderManagerIn);
|
||||
this.shadowSize = 0.8F;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRender(BoatEntityBOP entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||
GlStateManager.pushMatrix();
|
||||
this.setupTranslation(x, y, z);
|
||||
this.setupRotation(entity, entityYaw, partialTicks);
|
||||
this.bindEntityTexture(entity);
|
||||
if (this.renderOutlines) {
|
||||
GlStateManager.enableColorMaterial();
|
||||
GlStateManager.setupSolidRenderingTextureCombine(this.getTeamColor(entity));
|
||||
}
|
||||
|
||||
this.field_76998_a.render(entity, partialTicks, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
|
||||
if (this.renderOutlines) {
|
||||
GlStateManager.tearDownSolidRenderingTextureCombine();
|
||||
GlStateManager.disableColorMaterial();
|
||||
}
|
||||
|
||||
GlStateManager.popMatrix();
|
||||
super.doRender(entity, x, y, z, entityYaw, partialTicks);
|
||||
}
|
||||
|
||||
public void setupRotation(BoatEntityBOP entityIn, float entityYaw, float partialTicks) {
|
||||
GlStateManager.rotatef(180.0F - entityYaw, 0.0F, 1.0F, 0.0F);
|
||||
float f = (float)entityIn.getTimeSinceHit() - partialTicks;
|
||||
float f1 = entityIn.getDamageTaken() - partialTicks;
|
||||
if (f1 < 0.0F) {
|
||||
f1 = 0.0F;
|
||||
}
|
||||
|
||||
if (f > 0.0F) {
|
||||
GlStateManager.rotatef(MathHelper.sin(f) * f * f1 / 10.0F * (float)entityIn.getForwardDirection(), 1.0F, 0.0F, 0.0F);
|
||||
}
|
||||
|
||||
float f2 = entityIn.getRockingAngle(partialTicks);
|
||||
if (!MathHelper.epsilonEquals(f2, 0.0F)) {
|
||||
GlStateManager.rotatef(entityIn.getRockingAngle(partialTicks), 1.0F, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
GlStateManager.scalef(-1.0F, -1.0F, 1.0F);
|
||||
}
|
||||
|
||||
public void setupTranslation(double x, double y, double z) {
|
||||
GlStateManager.translatef((float)x, (float)y + 0.375F, (float)z);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ResourceLocation getEntityTexture(BoatEntityBOP entity) {
|
||||
return BOAT_TEXTURES[entity.getBoatType().ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMultipass() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderMultipass(BoatEntityBOP entityIn, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||
GlStateManager.pushMatrix();
|
||||
this.setupTranslation(x, y, z);
|
||||
this.setupRotation(entityIn, entityYaw, partialTicks);
|
||||
this.bindEntityTexture(entityIn);
|
||||
this.field_76998_a.renderMultipass(entityIn, partialTicks, 0.0F, -0.1F, 0.0F, 0.0F, 0.0625F);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
}
|
85
src/main/java/biomesoplenty/common/item/BoatItemBOP.java
Normal file
85
src/main/java/biomesoplenty/common/item/BoatItemBOP.java
Normal file
|
@ -0,0 +1,85 @@
|
|||
package biomesoplenty.common.item;
|
||||
|
||||
import biomesoplenty.common.entity.item.BoatEntityBOP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.item.BoatEntity;
|
||||
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.ActionResultType;
|
||||
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.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class BoatItemBOP extends Item {
|
||||
private static final Predicate<Entity> field_219989_a = EntityPredicates.NOT_SPECTATING.and(Entity::canBeCollidedWith);
|
||||
private final BoatEntityBOP.Type type;
|
||||
|
||||
public BoatItemBOP(BoatEntityBOP.Type typeIn, Item.Properties properties) {
|
||||
super(properties);
|
||||
this.type = typeIn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to trigger the item's "innate" right click behavior. To handle when this item is used on a Block, see
|
||||
* {@link #onItemUse}.
|
||||
*/
|
||||
@Override
|
||||
public ActionResult<ItemStack> onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) {
|
||||
ItemStack itemstack = playerIn.getHeldItem(handIn);
|
||||
RayTraceResult raytraceresult = rayTrace(worldIn, playerIn, RayTraceContext.FluidMode.ANY);
|
||||
if (raytraceresult.getType() == RayTraceResult.Type.MISS) {
|
||||
return new ActionResult<>(ActionResultType.PASS, itemstack);
|
||||
} else {
|
||||
Vec3d vec3d = playerIn.getLook(1.0F);
|
||||
double d0 = 5.0D;
|
||||
List<Entity> list = worldIn.getEntitiesInAABBexcluding(playerIn, playerIn.getBoundingBox().expand(vec3d.scale(5.0D)).grow(1.0D), field_219989_a);
|
||||
if (!list.isEmpty()) {
|
||||
Vec3d vec3d1 = playerIn.getEyePosition(1.0F);
|
||||
|
||||
for(Entity entity : list) {
|
||||
AxisAlignedBB axisalignedbb = entity.getBoundingBox().grow((double)entity.getCollisionBorderSize());
|
||||
if (axisalignedbb.contains(vec3d1)) {
|
||||
return new ActionResult<>(ActionResultType.PASS, itemstack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (raytraceresult.getType() == RayTraceResult.Type.BLOCK) {
|
||||
|
||||
//TODO: Fix boats and remove temporary vanilla boat spawn
|
||||
BoatEntity boatentity = new BoatEntity(worldIn, raytraceresult.getHitVec().x, raytraceresult.getHitVec().y, raytraceresult.getHitVec().z);
|
||||
boatentity.setBoatType(BoatEntity.Type.OAK);
|
||||
|
||||
//BoatEntityBOP boatentity = new BoatEntityBOP(worldIn, raytraceresult.getHitVec().x, raytraceresult.getHitVec().y, raytraceresult.getHitVec().z);
|
||||
//boatentity.setBoatType(this.type);
|
||||
boatentity.rotationYaw = playerIn.rotationYaw;
|
||||
if (!worldIn.isCollisionBoxesEmpty(boatentity, boatentity.getBoundingBox().grow(-0.1D))) {
|
||||
return new ActionResult<>(ActionResultType.FAIL, itemstack);
|
||||
} else {
|
||||
if (!worldIn.isRemote) {
|
||||
worldIn.addEntity(boatentity);
|
||||
}
|
||||
|
||||
if (!playerIn.abilities.isCreativeMode) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
|
||||
playerIn.addStat(Stats.ITEM_USED.get(this));
|
||||
return new ActionResult<>(ActionResultType.SUCCESS, itemstack);
|
||||
}
|
||||
} else {
|
||||
return new ActionResult<>(ActionResultType.PASS, itemstack);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -13,6 +13,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import biomesoplenty.common.biome.nether.UndergardenBiome;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -107,13 +108,15 @@ public class ModBiomes
|
|||
|
||||
private static void registerBiomes()
|
||||
{
|
||||
//Technical Biomes (Need to be registered before main biomes that use them)
|
||||
gravel_beach = registerBiome(new GravelBeachBiome(), "gravel_beach");
|
||||
origin_beach = registerBiome(new OriginBeachBiome(), "origin_beach");
|
||||
white_beach = registerBiome(new WhiteBeachBiome(), "white_beach");
|
||||
alps_foothills = registerBiome(new AlpsFoothillsBiome(), "alps_foothills");
|
||||
redwood_forest_edge = registerBiome(new RedwoodForestEdgeBiome(), "redwood_forest_edge");
|
||||
volcano_edge = registerBiome(new VolcanoEdgeBiome(), "volcano_edge");
|
||||
|
||||
|
||||
//Overworld Biomes
|
||||
alps = registerBiome(new AlpsBiome(), "alps");
|
||||
bayou = registerBiome(new BayouBiome(), "bayou");
|
||||
bog = registerBiome(new BogBiome(), "bog");
|
||||
|
@ -168,10 +171,14 @@ public class ModBiomes
|
|||
wetland = registerBiome(new WetlandBiome(), "wetland");
|
||||
woodland = registerBiome(new WoodlandBiome(), "woodland");
|
||||
xeric_shrubland = registerBiome(new XericShrublandBiome(), "xeric_shrubland");
|
||||
|
||||
|
||||
//Nether Biomes
|
||||
undergarden = registerBiome(new UndergardenBiome(), "undergarden");
|
||||
|
||||
//End Biomes
|
||||
end_plains = registerBiome(new EndPlainsBiome(), "end_plains");
|
||||
|
||||
// Note: Rarity supports two decimal places
|
||||
//Sub/Island Biomes (Note: Rarity supports two decimal places)
|
||||
registerSubBiome(Biomes.DESERT, oasis, 0.1F, 100);
|
||||
registerSubBiome(Biomes.PLAINS, orchard, 0.5F, 100);
|
||||
registerSubBiome(brushland, xeric_shrubland, 1.0F, 100);
|
||||
|
@ -195,6 +202,7 @@ public class ModBiomes
|
|||
|
||||
private static void registerBiomeDictionaryTags()
|
||||
{
|
||||
//Overworld Biomes
|
||||
registerBiomeToDictionary(BOPBiomes.alps, Type.MOUNTAIN, Type.SNOWY, Type.COLD);
|
||||
registerBiomeToDictionary(BOPBiomes.alps_foothills, Type.MOUNTAIN, Type.SNOWY, Type.FOREST, Type.SPARSE, Type.COLD);
|
||||
registerBiomeToDictionary(BOPBiomes.bayou, Type.SWAMP, Type.HOT, Type.WET, Type.DENSE);
|
||||
|
@ -255,12 +263,12 @@ public class ModBiomes
|
|||
registerBiomeToDictionary(BOPBiomes.white_beach, Type.BEACH);
|
||||
registerBiomeToDictionary(BOPBiomes.woodland, Type.FOREST, Type.DENSE);
|
||||
registerBiomeToDictionary(BOPBiomes.xeric_shrubland, Type.SANDY, Type.SAVANNA, Type.LUSH, Type.HOT, Type.DRY, Type.SPARSE);
|
||||
|
||||
//registerBiomeToDictionary(BOPBiomes.corrupted_sands, Type.NETHER, Type.HOT, Type.DRY, Type.SANDY, Type.DENSE);
|
||||
//registerBiomeToDictionary(BOPBiomes.fungi_forest, Type.NETHER, Type.HOT, Type.MUSHROOM, Type.DENSE);
|
||||
//registerBiomeToDictionary(BOPBiomes.phantasmagoric_inferno, Type.NETHER, Type.HOT, Type.WASTELAND, Type.DRY, Type.MAGICAL, Type.SPOOKY);
|
||||
//registerBiomeToDictionary(BOPBiomes.undergarden, Type.NETHER, Type.HOT, Type.LUSH);
|
||||
//registerBiomeToDictionary(BOPBiomes.visceral_heap, Type.NETHER, Type.HOT, Type.WET);
|
||||
|
||||
//Nether Biomes
|
||||
registerBiomeToDictionary(BOPBiomes.undergarden, Type.NETHER, Type.HOT);
|
||||
|
||||
//End Biomes
|
||||
registerBiomeToDictionary(BOPBiomes.end_plains, Type.END);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -7,21 +7,25 @@
|
|||
******************************************************************************/
|
||||
package biomesoplenty.init;
|
||||
|
||||
import biomesoplenty.api.entity.BOPEntities;
|
||||
import biomesoplenty.common.entity.item.BoatEntityBOP;
|
||||
import biomesoplenty.common.entity.item.BoatRendererBOP;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityClassification;
|
||||
import net.minecraft.entity.EntityType;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.fml.client.registry.RenderingRegistry;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
public class ModEntities
|
||||
{
|
||||
public static void init()
|
||||
{
|
||||
//EntityType<EntityBoatBOP> boat_bop = createEntity(EntityBoatBOP::new, EntityClassification.MISC, "boat_bop", 80, 3, true);
|
||||
EntityType<BoatEntityBOP> boat_bop = createEntity(BoatEntityBOP::new, EntityClassification.MISC, "boat_bop", 80, 3, true);
|
||||
|
||||
//BOPEntities.boat_bop = boat_bop;
|
||||
BOPEntities.boat_bop = boat_bop;
|
||||
}
|
||||
|
||||
public static <T extends Entity> EntityType<T> createEntity(EntityType.IFactory<T> factory, EntityClassification classification, String name, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates)
|
||||
|
@ -36,6 +40,6 @@ public class ModEntities
|
|||
@OnlyIn(Dist.CLIENT)
|
||||
public static void registerRendering()
|
||||
{
|
||||
//RenderingRegistry.registerEntityRenderingHandler(EntityBoatBOP.class, manager -> new RenderBoatBOP(manager));
|
||||
RenderingRegistry.registerEntityRenderingHandler(BoatEntityBOP.class, manager -> new BoatRendererBOP(manager));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ package biomesoplenty.init;
|
|||
|
||||
import biomesoplenty.api.block.BOPBlocks;
|
||||
import biomesoplenty.api.sound.BOPSounds;
|
||||
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.item.AxeItem;
|
||||
|
@ -26,18 +28,18 @@ public class ModItems
|
|||
|
||||
music_disc_wanderer = registerItem(new MusicDiscItemBOP(BOPSounds.music_disc_wanderer), "music_disc_wanderer");
|
||||
|
||||
/*fir_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.FIR, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "fir_boat");
|
||||
redwood_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.REDWOOD, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "redwood_boat");
|
||||
cherry_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.CHERRY, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "cherry_boat");
|
||||
mahogany_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.MAHOGANY, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "mahogany_boat");
|
||||
jacaranda_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.JACARANDA, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "jacaranda_boat");
|
||||
palm_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.PALM, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "palm_boat");
|
||||
willow_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.WILLOW, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "willow_boat");
|
||||
dead_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.DEAD, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "dead_boat");
|
||||
magic_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.MAGIC, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "magic_boat");
|
||||
umbran_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.UMBRAN, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "umbran_boat");
|
||||
hellbark_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.HELLBARK, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "hellbark_boat");
|
||||
ethereal_boat = registerItem(new ItemBoatBOP(EntityBoatBOP.Type.ETHEREAL, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "ethereal_boat");*/
|
||||
fir_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.FIR, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "fir_boat");
|
||||
redwood_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.REDWOOD, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "redwood_boat");
|
||||
cherry_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.CHERRY, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "cherry_boat");
|
||||
mahogany_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.MAHOGANY, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "mahogany_boat");
|
||||
jacaranda_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.JACARANDA, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "jacaranda_boat");
|
||||
palm_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.PALM, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "palm_boat");
|
||||
willow_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.WILLOW, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "willow_boat");
|
||||
dead_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.DEAD, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "dead_boat");
|
||||
magic_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.MAGIC, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "magic_boat");
|
||||
umbran_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.UMBRAN, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "umbran_boat");
|
||||
hellbark_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.HELLBARK, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "hellbark_boat");
|
||||
ethereal_boat = registerItem(new BoatItemBOP(BoatEntityBOP.Type.ETHEREAL, (new Item.Properties()).maxStackSize(1).group(ItemGroupBOP.instance)), "ethereal_boat");
|
||||
|
||||
bop_icon = registerItem(new Item(new Item.Properties()), "bop_icon");
|
||||
}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/cherry_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/dead_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/ethereal_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/fir_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/hellbark_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/jacaranda_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/magic_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/mahogany_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/palm_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/redwood_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/umbran_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "item/generated",
|
||||
"textures": {
|
||||
"layer0": "biomesoplenty:items/willow_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:cherry_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:cherry_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:dead_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:dead_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:ethereal_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:ethereal_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:fir_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:fir_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:hellbark_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:hellbark_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:jacaranda_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:jacaranda_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:magic_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:magic_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:mahogany_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:mahogany_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:palm_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:palm_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:redwood_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:redwood_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:umbran_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:umbran_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"parent": "minecraft:recipes/root",
|
||||
"rewards": {
|
||||
"recipes": [
|
||||
"biomesoplenty:willow_boat"
|
||||
]
|
||||
},
|
||||
"criteria": {
|
||||
"in_water": {
|
||||
"trigger": "minecraft:enter_block",
|
||||
"conditions": {
|
||||
"block": "minecraft:water"
|
||||
}
|
||||
},
|
||||
"has_the_recipe": {
|
||||
"trigger": "minecraft:recipe_unlocked",
|
||||
"conditions": {
|
||||
"recipe": "biomesoplenty:willow_boat"
|
||||
}
|
||||
}
|
||||
},
|
||||
"requirements": [
|
||||
[
|
||||
"in_water",
|
||||
"has_the_recipe"
|
||||
]
|
||||
]
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:cherry_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:cherry_boat"
|
||||
}
|
||||
}
|
16
src/main/resources/data/biomesoplenty/recipes/dead_boat.json
Normal file
16
src/main/resources/data/biomesoplenty/recipes/dead_boat.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:dead_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:dead_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:ethereal_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:ethereal_boat"
|
||||
}
|
||||
}
|
16
src/main/resources/data/biomesoplenty/recipes/fir_boat.json
Normal file
16
src/main/resources/data/biomesoplenty/recipes/fir_boat.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:fir_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:fir_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:hellbark_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:hellbark_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:jacaranda_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:jacaranda_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:magic_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:magic_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:mahogany_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:mahogany_boat"
|
||||
}
|
||||
}
|
16
src/main/resources/data/biomesoplenty/recipes/palm_boat.json
Normal file
16
src/main/resources/data/biomesoplenty/recipes/palm_boat.json
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:palm_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:palm_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:redwood_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:redwood_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:umbran_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:umbran_boat"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "crafting_shaped",
|
||||
"group": "boat",
|
||||
"pattern": [
|
||||
"# #",
|
||||
"###"
|
||||
],
|
||||
"key": {
|
||||
"#": {
|
||||
"item": "biomesoplenty:willow_planks"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"item": "biomesoplenty:willow_boat"
|
||||
}
|
||||
}
|
17
src/main/resources/data/minecraft/tags/items/boats.json
Normal file
17
src/main/resources/data/minecraft/tags/items/boats.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"replace": false,
|
||||
"values": [
|
||||
"biomesoplenty:fir_boat",
|
||||
"biomesoplenty:redwood_boat",
|
||||
"biomesoplenty:cherry_boat",
|
||||
"biomesoplenty:mahogany_boat",
|
||||
"biomesoplenty:jacaranda_boat",
|
||||
"biomesoplenty:palm_boat",
|
||||
"biomesoplenty:willow_boat",
|
||||
"biomesoplenty:dead_boat",
|
||||
"biomesoplenty:magic_boat",
|
||||
"biomesoplenty:umbran_boat",
|
||||
"biomesoplenty:hellbark_boat",
|
||||
"biomesoplenty:ethereal_boat"
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue