Подводный транспорт(или в-водный транспорт)

Версия Minecraft
1.12.2
5,018
47
783
Всем привет! Задумал сделать подводную лодку, но так как с энтитями я никогда не работал, я понемногу зашел в тупик. Я думал все просто - унаследую лодку и переопределю метод где заменю IN_WATER на UNDER_WATER. Но не тут то было. Вообщем, я смог сделать, чтобы она передвигалась под водой... но вот как сделать чтобы она всплывала\погружалась, я так и не придумал. Код прикладываю.

Если конкретно:
1) не понял, в каком методе это делать
2) Не понял, как это сделать

Осмотр класса игрока результатов не дал.
Java:
public class EntitySubmarine extends EntityBoat
{
    
    public EntitySubmarine(World worldIn)
    {
        super(worldIn);
    //    this.paddlePositions = new float[2];
        this.preventEntitySpawning = true;
        this.setSize(1.375F, 0.5625F);
    }

    public EntitySubmarine(World worldIn, double x, double y, double z)
    {
        this(worldIn);
        this.setPosition(x, y, z);
        this.motionX = 0.0D;
        this.motionY = 0.0D;
        this.motionZ = 0.0D;
        this.prevPosX = x;
        this.prevPosY = y;
        this.prevPosZ = z;
    }
 
       public void onUpdate()
        {
          
            this.previousStatus = this.status;
            this.status = this.getBoatStatus();
            if (this.status != EntityBoat.Status.UNDER_WATER && this.status != EntityBoat.Status.UNDER_FLOWING_WATER)
            {
                this.outOfControlTicks = 0.0F;
            }
            else
            {
                this.outOfControlTicks = 0.0F;
            }



            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.onUpdate();
            this.tickLerp();

            if (this.canPassengerSteer())
            {
                 this.handleWaterMovement();
                if (this.getPassengers().isEmpty() || !(this.getPassengers().get(0) instanceof EntityPlayer))
                {
                    this.setPaddleState(false, false);
                }

                this.updateMotion();

                if (this.world.isRemote)
                {
                    
                    this.controlBoat();
                    this.world.sendPacketToServer(new CPacketSteerBoat(this.getPaddleState(0), this.getPaddleState(1)));
                }

                this.move(MoverType.SELF, this.motionX, this.motionY, this.motionZ);
            }
            else
            {
                this.motionX = 0.0D;
                this.motionY = 0.0D;
                this.motionZ = 0.0D;
            }

            for (int i = 0; i <= 1; ++i)
            {
                if (this.getPaddleState(i))
                {
                    if (!this.isSilent() && (double)(this.paddlePositions[i] % ((float)Math.PI * 2F)) <= (Math.PI / 4D) && ((double)this.paddlePositions[i] + 0.39269909262657166D) % (Math.PI * 2D) >= (Math.PI / 4D))
                    {
                        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((EntityPlayer)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] + 0.39269909262657166D);
                }
                else
                {
                    this.paddlePositions[i] = 0.0F;
                }
            }

            this.doBlockCollisions();
            List<Entity> list = this.world.getEntitiesInAABBexcluding(this, this.getEntityBoundingBox().grow(0.20000000298023224D, -0.009999999776482582D, 0.20000000298023224D), EntitySelectors.getTeamCollisionPredicate(this));

            if (!list.isEmpty())
            {
                boolean flag = !this.world.isRemote && !(this.getControllingPassenger() instanceof EntityPlayer);

                for (int j = 0; j < list.size(); ++j)
                {
                    Entity entity = list.get(j);

                    if (!entity.isPassenger(this))
                    {
                        if (flag && this.getPassengers().size() < 2 && !entity.isRiding() && entity.width < this.width && entity instanceof EntityLivingBase && !(entity instanceof EntityWaterMob) && !(entity instanceof EntityPlayer))
                        {
                            entity.startRiding(this);
                        }
                        else
                        {
                            this.applyEntityCollision(entity);
                        }
                    }
                }
            }
        }
       public void updateMotion()
        {
            double d0 = -0.03999999910593033D;
            double d1 = this.hasNoGravity() ? 0.0D : -0.03999999910593033D;
            double d2 = 0.0D;
            this.momentum = 0.05F;

            if (this.previousStatus == EntityBoat.Status.IN_AIR && this.status != EntityBoat.Status.IN_AIR && this.status != EntityBoat.Status.ON_LAND)
            {
                this.waterLevel = this.getEntityBoundingBox().minY + (double)this.height;
                this.setPosition(this.posX, (double)(this.getWaterLevelAbove() - this.height) + 0.101D, this.posZ);
                this.motionY = 0.0D;
                this.lastYd = 0.0D;
                this.status = EntityBoat.Status.UNDER_WATER;
            }
            else
            {
                if (this.status == EntityBoat.Status.IN_WATER)
                {
                    d2 = (this.waterLevel - this.getEntityBoundingBox().minY) / (double)this.height;
                    this.momentum = 0.9F;
                }
                else if (this.status == EntityBoat.Status.UNDER_FLOWING_WATER)
                {
                    d1 = -7.0E-4D;
                    this.momentum = 0.9F;
                }
                else if (this.status == EntityBoat.Status.UNDER_WATER)
                {
                     d2 = (this.waterLevel - this.getEntityBoundingBox().minY);
                    this.momentum = this.boatGlide;

                    if (this.getControllingPassenger() instanceof EntityPlayer)
                    {
                        this.boatGlide /= 2.0F;
                    }
                }
                else if (this.status == EntityBoat.Status.IN_AIR)
                {
                    this.momentum = 0.9F;
                }
                else if (this.status == EntityBoat.Status.ON_LAND)
                {
                    this.momentum = this.boatGlide;

                    if (this.getControllingPassenger() instanceof EntityPlayer)
                    {
                        this.boatGlide /= 2.0F;
                    }
                }

                this.motionX *= (double)this.momentum;
                this.motionZ *= (double)this.momentum;
                this.deltaRotation *= this.momentum;
                this.motionY += d1;

                if (d2 > 0.0D)
                {
                    double d3 = 0.65D;
                    this.motionY += d2 * 0.06153846016296973D;
                    double d4 = 0.75D;
                    this.motionY *= 0.75D;
                }
            }
        }
}
 
5,018
47
783
Просто поднимать лодку с игроком?
гениально. Вопрос не в том, что сделать, а как.
лошади когда она прыгает)
Она прыгает не по желанию игрока, а только когда натыкается на блок. Т.е она сама прыгает, игрок тут не причем.
 
2,932
44
598
Она прыгает не по желанию игрока, а только когда натыкается на блок. Т.е она сама прыгает, игрок тут не причем.
Эм... Если нажать на пробел она как бы пригнет :/ 0_о ...
 
Последнее редактирование:
5,018
47
783
Эм... Если нажать на пробел она как бы пригнет
да. глянул. Но там атрибут с которым, чует моя жопа, будет овермного гемора, потому что он какой то навороченный. Надо что то попроще, типо как в игроке.
 
7,099
324
1,509
Сделай, чтобы она ускорялась по направлению взгляда при зажатой W
 
5,018
47
783
Последнее редактирование:
5,018
47
783
5,018
47
783
Не работает(

Java:
 public void updateMotion()
        {
            double d0 = -0.03999999910593033D;
            double d1 = this.hasNoGravity() ? 0.0D : -0.03999999910593033D;
            double d2 = 0.0D;
            this.momentum = 0.05F;

            if (this.previousStatus == EntityBoat.Status.IN_AIR && this.status != EntityBoat.Status.IN_AIR && this.status != EntityBoat.Status.ON_LAND)
            {
                this.waterLevel = this.getEntityBoundingBox().minY + (double)this.height;
               
            double xLookVec = this.getControllingPassenger().getLookVec().x;
                double yLookVec = this.getControllingPassenger().getLookVec().y;
                double zLookVec = this.getControllingPassenger().getLookVec().z;
                this.setPosition(xLookVec,yLookVec,zLookVec);
                this.motionY = 0.0D;
                this.lastYd = 0.0D;
                this.status = EntityBoat.Status.UNDER_WATER;
            }
            else
            {
                if (this.status == EntityBoat.Status.IN_WATER)
                {
                    d2 = (this.waterLevel - this.getEntityBoundingBox().minY) / (double)this.height;
                    this.momentum = 0.9F;
                }
                else if (this.status == EntityBoat.Status.UNDER_FLOWING_WATER)
                {
                    d1 = -7.0E-4D;
                    this.momentum = 0.9F;
                }
                else if (this.status == EntityBoat.Status.UNDER_WATER)
                {
                     d2 = (this.waterLevel - this.getEntityBoundingBox().minY);
                    this.momentum = this.boatGlide;

                    if (this.getControllingPassenger() instanceof EntityPlayer)
                    {
                        this.boatGlide /= 2.0F;
                    }
                }
                else if (this.status == EntityBoat.Status.IN_AIR)
                {
                    this.momentum = 0.9F;
                }
                else if (this.status == EntityBoat.Status.ON_LAND)
                {
                    this.momentum = this.boatGlide;

                    if (this.getControllingPassenger() instanceof EntityPlayer)
                    {
                        this.boatGlide /= 2.0F;
                    }
                }

                this.motionX *= (double)this.momentum;
                this.motionZ *= (double)this.momentum;
                this.deltaRotation *= this.momentum;
                this.motionY += d1;

                if (d2 > 0.0D)
                {
                    double d3 = 0.65D;
                    this.motionY += d2 * 0.06153846016296973D;
                    double d4 = 0.75D;
                    this.motionY *= 0.75D;
                }
            }
        }
 
Последнее редактирование:
7,099
324
1,509
На клиенте когда игрок зажимает клавишу отправляй пакет, что клавиша зажата(для отжатия тоже отправляй).
На сервере при ловле пакета ставь переменной в сущности значение из пакета(нажато или отжато)
В onUpdate давай ускорение лодке, когда переменная == true:
entity.addVelocity(lookVex.x,lookVec...)
Иначе замедляй лодку(типа, трение)
 
5,018
47
783
Я тут нашел метод ...
Глянь может и без пакетов можно)
Java:
    public void controlBoat()
    {
        if (this.isBeingRidden())
        {
            float f = 0.0F;

            if (this.leftInputDown)
            {
                this.deltaRotation += -1.0F;
            }

            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.motionX += (double)(MathHelper.sin(-this.rotationYaw * 0.017453292F) * f);
            this.motionZ += (double)(MathHelper.cos(this.rotationYaw * 0.017453292F) * f);
            this.setPaddleState(this.rightInputDown && !this.leftInputDown || this.forwardInputDown, this.leftInputDown && !this.rightInputDown || this.forwardInputDown);
        }
    }
 
5,018
47
783
В общем я сделал вот так. Ничего не работает
:)
Java:
    public void controlSubmarine()
    {
        if (this.isBeingRidden())
        {
            float f = 0.0F;

            if (this.leftInputDown)
            {
                this.deltaRotation += -1.0F;
            }

            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;
                this.motionY += this.getControllingPassenger().getLookVec().y * f;
            }

            if (this.backInputDown)
            {
                f -= 0.005F;
            }
            
            double xLookVec = this.getControllingPassenger().getLookVec().x;
            double yLookVec = this.getControllingPassenger().getLookVec().y;
            double zLookVec = this.getControllingPassenger().getLookVec().z;
            this.motionX += (double)(MathHelper.sin(-this.rotationYaw * 0.017453292F) * f);
            
            this.motionZ += (double)(MathHelper.cos(this.rotationYaw * 0.017453292F) * f);
          
            this.setPaddleState(this.rightInputDown && !this.leftInputDown || this.forwardInputDown, this.leftInputDown && !this.rightInputDown || this.forwardInputDown);
        }
    }
 
5,018
47
783
Хотя нет, наврал. Работает. Но только если задирать курсор чисто вверх.
Еще - лодка медленно опускается вниз, если не двигаться.
 
5,018
47
783
Сверху