mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Fix Squid Animation (#2398)
This commit is contained in:
parent
0e72952e0b
commit
d7fbdaf93d
6 changed files with 123 additions and 11 deletions
|
@ -46,6 +46,7 @@ import org.geysermc.connector.entity.player.PlayerEntity;
|
|||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.chat.MessageTranslator;
|
||||
import org.geysermc.connector.utils.MathUtils;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -83,11 +84,11 @@ public class Entity {
|
|||
this.valid = false;
|
||||
|
||||
setPosition(position);
|
||||
setAir(getMaxAir());
|
||||
|
||||
metadata.put(EntityData.SCALE, 1f);
|
||||
metadata.put(EntityData.COLOR, 0);
|
||||
metadata.put(EntityData.MAX_AIR_SUPPLY, (short) 300);
|
||||
metadata.put(EntityData.AIR_SUPPLY, (short) 0);
|
||||
metadata.put(EntityData.MAX_AIR_SUPPLY, getMaxAir());
|
||||
metadata.put(EntityData.LEASH_HOLDER_EID, -1L);
|
||||
metadata.put(EntityData.BOUNDING_BOX_HEIGHT, entityType.getHeight());
|
||||
metadata.put(EntityData.BOUNDING_BOX_WIDTH, entityType.getWidth());
|
||||
|
@ -255,11 +256,7 @@ public class Entity {
|
|||
}
|
||||
break;
|
||||
case 1: // Air/bubbles
|
||||
if ((int) entityMetadata.getValue() == 300) {
|
||||
metadata.put(EntityData.AIR_SUPPLY, (short) 0); // Otherwise the bubble counter remains in the UI
|
||||
} else {
|
||||
metadata.put(EntityData.AIR_SUPPLY, (short) (int) entityMetadata.getValue());
|
||||
}
|
||||
setAir((int) entityMetadata.getValue());
|
||||
break;
|
||||
case 2: // custom name
|
||||
if (entityMetadata.getValue() instanceof Component) {
|
||||
|
@ -334,6 +331,18 @@ public class Entity {
|
|||
metadata.put(EntityData.FREEZING_EFFECT_STRENGTH, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an int from 0 - this entity's maximum air - (air / maxAir) represents the percentage of bubbles left
|
||||
* @param amount the amount of air
|
||||
*/
|
||||
protected void setAir(int amount) {
|
||||
metadata.put(EntityData.AIR_SUPPLY, (short) MathUtils.constrain(amount, 0, getMaxAir()));
|
||||
}
|
||||
|
||||
protected int getMaxAir() {
|
||||
return 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* x = Pitch, y = HeadYaw, z = Yaw
|
||||
*
|
||||
|
|
|
@ -26,10 +26,78 @@
|
|||
package org.geysermc.connector.entity.living;
|
||||
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.connector.entity.Tickable;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
import org.geysermc.connector.network.session.GeyserSession;
|
||||
import org.geysermc.connector.network.translators.world.block.BlockStateValues;
|
||||
|
||||
public class SquidEntity extends WaterEntity implements Tickable {
|
||||
|
||||
private float pitch;
|
||||
private float yaw;
|
||||
|
||||
private float targetPitch;
|
||||
private float targetYaw;
|
||||
|
||||
private boolean inWater;
|
||||
|
||||
public class SquidEntity extends WaterEntity {
|
||||
public SquidEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||
this.yaw = rotation.getX();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick(GeyserSession session) {
|
||||
if (inWater) {
|
||||
pitch += (targetPitch - pitch) * 0.1f;
|
||||
yaw += (targetYaw - yaw) * 0.1f;
|
||||
} else {
|
||||
pitch += (-90 - pitch) * 0.02f;
|
||||
}
|
||||
super.moveAbsolute(session, position, Vector3f.from(yaw, 0, yaw), onGround, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveRelative(GeyserSession session, double relX, double relY, double relZ, Vector3f rotation, boolean isOnGround) {
|
||||
super.moveRelative(session, relX, relY, relZ, rotation, isOnGround);
|
||||
checkInWater(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveAbsolute(GeyserSession session, Vector3f position, Vector3f rotation, boolean isOnGround, boolean teleported) {
|
||||
super.moveAbsolute(session, position, rotation, isOnGround, teleported);
|
||||
checkInWater(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRotation(Vector3f rotation) {
|
||||
// Let the Java server control yaw when the squid is out of water
|
||||
if (!inWater) {
|
||||
yaw = rotation.getX();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMotion(Vector3f motion) {
|
||||
super.setMotion(motion);
|
||||
|
||||
double horizontalSpeed = Math.sqrt(motion.getX() * motion.getX() + motion.getZ() * motion.getZ());
|
||||
targetPitch = (float) Math.toDegrees(-Math.atan2(horizontalSpeed, motion.getY()));
|
||||
targetYaw = (float) Math.toDegrees(-Math.atan2(motion.getX(), motion.getZ()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vector3f getBedrockRotation() {
|
||||
return Vector3f.from(pitch, yaw, yaw);
|
||||
}
|
||||
|
||||
private void checkInWater(GeyserSession session) {
|
||||
if (getMetadata().getFlags().getFlag(EntityFlag.RIDING)) {
|
||||
inWater = false;
|
||||
} else {
|
||||
int block = session.getConnector().getWorldManager().getBlockAt(session, position.toInt());
|
||||
inWater = BlockStateValues.getWaterLevel(block) != -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,11 @@
|
|||
package org.geysermc.connector.entity.living;
|
||||
|
||||
import com.nukkitx.math.vector.Vector3f;
|
||||
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
|
||||
import org.geysermc.connector.entity.type.EntityType;
|
||||
|
||||
public class WaterEntity extends CreatureEntity {
|
||||
|
||||
public WaterEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
|
||||
super(entityId, geyserId, entityType, position, motion, rotation);
|
||||
|
||||
metadata.put(EntityData.AIR_SUPPLY, (short) 400);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,4 +62,9 @@ public class AxolotlEntity extends AnimalEntity {
|
|||
public boolean canEat(GeyserSession session, String javaIdentifierStripped, ItemMapping mapping) {
|
||||
return javaIdentifierStripped.equals("tropical_fish_bucket");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getMaxAir() {
|
||||
return 6000;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,6 +119,15 @@ public class SessionPlayerEntity extends PlayerEntity {
|
|||
super.setHealth(health);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setAir(int amount) {
|
||||
if (amount == getMaxAir()) {
|
||||
super.setAir(0); // Hide the bubble counter from the UI for the player
|
||||
} else {
|
||||
super.setAir(amount);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeData createHealthAttribute() {
|
||||
// Max health must be divisible by two in bedrock
|
||||
|
|
|
@ -42,6 +42,7 @@ public class MathUtils {
|
|||
|
||||
/**
|
||||
* If number is greater than the max, set it to max, and if number is lower than low, set it to low.
|
||||
*
|
||||
* @param num number to calculate
|
||||
* @param min the lowest value the number can be
|
||||
* @param max the greatest value the number can be
|
||||
|
@ -53,6 +54,29 @@ public class MathUtils {
|
|||
if (num > max) {
|
||||
num = max;
|
||||
}
|
||||
|
||||
if (num < min) {
|
||||
num = min;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* If number is greater than the max, set it to max, and if number is lower than low, set it to low.
|
||||
*
|
||||
* @param num number to calculate
|
||||
* @param min the lowest value the number can be
|
||||
* @param max the greatest value the number can be
|
||||
* @return - min if num is lower than min <br>
|
||||
* - max if num is greater than max <br>
|
||||
* - num otherwise
|
||||
*/
|
||||
public static int constrain(int num, int min, int max) {
|
||||
if (num > max) {
|
||||
num = max;
|
||||
}
|
||||
|
||||
if (num < min) {
|
||||
num = min;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue