mirror of
https://github.com/GeyserMC/Geyser.git
synced 2025-12-29 03:39:22 +00:00
Fixup HappyGhastEntity#isClientControlled check
This commit is contained in:
@@ -51,6 +51,7 @@ import org.geysermc.geyser.scoreboard.Team;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
@@ -537,6 +538,32 @@ public class LivingEntity extends Entity {
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean hasBodyArmor() {
|
||||
return this.hasValidEquippableItemForSlot(EquipmentSlot.BODY);
|
||||
}
|
||||
|
||||
private boolean hasValidEquippableItemForSlot(EquipmentSlot slot) {
|
||||
// MojMap LivingEntity#hasItemInSlot
|
||||
GeyserItemStack itemInSlot = equipment.get(slot);
|
||||
if (itemInSlot != null) {
|
||||
// MojMap LivingEntity#isEquippableInSlot
|
||||
Equippable equippable = itemInSlot.getComponent(DataComponentTypes.EQUIPPABLE);
|
||||
if (equippable != null) {
|
||||
return slot == equippable.slot() &&
|
||||
canUseSlot(slot) &&
|
||||
EntityUtils.equipmentUsableByEntity(session, equippable, this.definition.entityType());
|
||||
} else {
|
||||
return slot == EquipmentSlot.MAIN_HAND && canUseSlot(EquipmentSlot.MAIN_HAND);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the complete attribute value to send to Bedrock. Will be overriden if attributes need to be cached.
|
||||
*/
|
||||
|
||||
@@ -30,8 +30,10 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.TrigMath;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.AttributeData;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.entity.vehicle.ClientVehicle;
|
||||
@@ -42,12 +44,16 @@ import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.session.cache.tags.Tag;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.Attribute;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class HappyGhastEntity extends AnimalEntity implements ClientVehicle {
|
||||
@@ -180,12 +186,7 @@ public class HappyGhastEntity extends AnimalEntity implements ClientVehicle {
|
||||
|
||||
@Override
|
||||
public boolean isClientControlled() {
|
||||
// TODO proper check, just lazy
|
||||
if (body == null) {
|
||||
return false;
|
||||
}
|
||||
// TODO must have ai check
|
||||
if (staysStill) {
|
||||
if (!hasBodyArmor() || getFlag(EntityFlag.NO_AI) || staysStill) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -195,4 +196,25 @@ public class HappyGhastEntity extends AnimalEntity implements ClientVehicle {
|
||||
private Entity getFirstPassenger() {
|
||||
return passengers.isEmpty() ? null : passengers.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateAttribute(Attribute javaAttribute, List<AttributeData> newAttributes) {
|
||||
super.updateAttribute(javaAttribute, newAttributes);
|
||||
if (javaAttribute.getType() instanceof AttributeType.Builtin type) {
|
||||
switch (type) {
|
||||
case FLYING_SPEED -> {
|
||||
AttributeData attributeData = calculateAttribute(javaAttribute, GeyserAttributeType.FLYING_SPEED);
|
||||
vehicleComponent.setFlyingSpeed(attributeData.getValue());
|
||||
}
|
||||
case CAMERA_DISTANCE -> {
|
||||
vehicleComponent.setCameraDistance((float) AttributeUtils.calculateValue(javaAttribute));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
return slot != EquipmentSlot.BODY ? super.canUseSlot(slot) : this.isAlive() && !this.isBaby();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.geysermc.geyser.session.cache.tags.Tag;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
@@ -195,4 +196,9 @@ public class StriderEntity extends AnimalEntity implements Tickable, ClientVehic
|
||||
public boolean canWalkOnLava() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
return slot != EquipmentSlot.SADDLE ? super.canUseSlot(slot) : this.isAlive() && !this.isBaby();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ import org.geysermc.geyser.session.cache.tags.Tag;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
@@ -154,4 +155,9 @@ public class PigEntity extends TemperatureVariantAnimal implements Tickable, Cli
|
||||
public JavaRegistryKey<BuiltInVariant> variantRegistry() {
|
||||
return JavaRegistries.PIG_VARIANT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
return slot != EquipmentSlot.SADDLE ? super.canUseSlot(slot) : this.isAlive() && !this.isBaby();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.session.cache.tags.Tag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
@@ -286,4 +287,13 @@ public class AbstractHorseEntity extends AnimalEntity {
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
if (slot != EquipmentSlot.SADDLE) {
|
||||
return super.canUseSlot(slot);
|
||||
} else {
|
||||
return isAlive() && !isBaby() && getFlag(EntityFlag.TAMED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -44,4 +45,9 @@ public class HorseEntity extends AbstractHorseEntity {
|
||||
dirtyMetadata.put(EntityDataTypes.VARIANT, value & 255);
|
||||
dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, (value >> 8) % 5);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.session.cache.tags.Tag;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.EquipmentSlot;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
@@ -61,4 +62,9 @@ public class LlamaEntity extends ChestedHorseEntity {
|
||||
protected @Nullable Tag<Item> getFoodTag() {
|
||||
return ItemTag.LLAMA_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canUseSlot(EquipmentSlot slot) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.cloudburstmc.math.vector.Vector3f;
|
||||
public interface ClientVehicle {
|
||||
VehicleComponent<?> getVehicleComponent();
|
||||
|
||||
// LivingEntity#getRiddenInput
|
||||
// MojMap LivingEntity#getRiddenInput
|
||||
Vector3f getRiddenInput(Vector2f input);
|
||||
|
||||
// MojMap LivingEntity#getRiddenSpeed
|
||||
|
||||
@@ -27,25 +27,31 @@ package org.geysermc.geyser.entity.vehicle;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.cloudburstmc.math.vector.Vector2f;
|
||||
import org.cloudburstmc.math.vector.Vector3d;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.erosion.util.BlockPositionIterator;
|
||||
import org.geysermc.geyser.entity.type.living.animal.HappyGhastEntity;
|
||||
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
|
||||
import org.geysermc.geyser.level.block.Blocks;
|
||||
import org.geysermc.geyser.level.block.Fluid;
|
||||
import org.geysermc.geyser.level.block.type.BlockState;
|
||||
import org.geysermc.geyser.level.physics.BoundingBox;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.attribute.AttributeType;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class HappyGhastVehicleComponent extends VehicleComponent<HappyGhastEntity> {
|
||||
|
||||
@Getter @Setter
|
||||
private float flyingSpeed;
|
||||
private float cameraDistance;
|
||||
|
||||
public HappyGhastVehicleComponent(HappyGhastEntity vehicle, float stepHeight) {
|
||||
super(vehicle, stepHeight);
|
||||
flyingSpeed = 0.05f; // Happy Ghast has different default
|
||||
// Happy Ghast has different defaults
|
||||
flyingSpeed = 0.05f;
|
||||
moveSpeed = 0.05f;
|
||||
cameraDistance = 8.0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,6 +60,26 @@ public class HappyGhastVehicleComponent extends VehicleComponent<HappyGhastEntit
|
||||
vehicle.setYaw(vehicle.getYaw() + addYaw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMount() {
|
||||
super.onMount();
|
||||
SessionPlayerEntity playerEntity = vehicle.getSession().getPlayerEntity();
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION, false);
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION_DEGREES, 181f);
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.SEAT_THIRD_PERSON_CAMERA_RADIUS, cameraDistance);
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.SEAT_CAMERA_RELAX_DISTANCE_SMOOTHING, cameraDistance * 0.75f);
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.CONTROLLING_RIDER_SEAT_INDEX, (byte) 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDismount() {
|
||||
super.onDismount();
|
||||
SessionPlayerEntity playerEntity = vehicle.getSession().getPlayerEntity();
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.SEAT_THIRD_PERSON_CAMERA_RADIUS, (float) AttributeType.Builtin.CAMERA_DISTANCE.getDef());
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.SEAT_CAMERA_RELAX_DISTANCE_SMOOTHING, cameraDistance * 0.75f);
|
||||
playerEntity.getDirtyMetadata().put(EntityDataTypes.CONTROLLING_RIDER_SEAT_INDEX, (byte) 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called every session tick while the player is mounted on the vehicle.
|
||||
*/
|
||||
@@ -72,6 +98,7 @@ public class HappyGhastVehicleComponent extends VehicleComponent<HappyGhastEntit
|
||||
case LAVA -> 0.5f;
|
||||
case EMPTY -> 0.91f;
|
||||
};
|
||||
// HappyGhast#travel
|
||||
travel(ctx, flyingSpeed * 5.0f / 3.0f);
|
||||
vehicle.setMotion(vehicle.getMotion().mul(drag));
|
||||
}
|
||||
@@ -98,7 +125,4 @@ public class HappyGhastVehicleComponent extends VehicleComponent<HappyGhastEntit
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public class GoodLuckImplementingThisException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -592,7 +592,7 @@ public class VehicleComponent<T extends LivingEntity & ClientVehicle> {
|
||||
*
|
||||
* @return true if there was a horizontal collision
|
||||
*/
|
||||
// Mojmap: LivingEntity#moveRelative
|
||||
// Mojmap: LivingEntity#moveRelative / LivingEntity#move
|
||||
protected boolean travel(VehicleContext ctx, float speed) {
|
||||
Vector3f motion = vehicle.getMotion();
|
||||
|
||||
|
||||
@@ -44,11 +44,14 @@ import org.geysermc.geyser.entity.type.living.animal.horse.CamelEntity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.registry.JavaRegistries;
|
||||
import org.geysermc.geyser.session.cache.tags.GeyserHolderSet;
|
||||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.Effect;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.GameMode;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.Equippable;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
@@ -283,23 +286,12 @@ public final class EntityUtils {
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION_DEGREES, 90f);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_HAS_ROTATION, true);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET_DEGREES, -90f);
|
||||
} else if (mount instanceof HappyGhastEntity) {
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION, false);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION_DEGREES, 181f);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_THIRD_PERSON_CAMERA_RADIUS, 8f);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_CAMERA_RELAX_DISTANCE_SMOOTHING, 6f);
|
||||
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.CONTROLLING_RIDER_SEAT_INDEX, (byte) 0);
|
||||
}
|
||||
} else {
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION, false);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_LOCK_RIDER_ROTATION_DEGREES, 0f);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_HAS_ROTATION, false);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_ROTATION_OFFSET_DEGREES, 0f);
|
||||
// TODO what are defaults here???
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_THIRD_PERSON_CAMERA_RADIUS, 8f);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.SEAT_CAMERA_RELAX_DISTANCE_SMOOTHING, 6f);
|
||||
passenger.getDirtyMetadata().put(EntityDataTypes.CONTROLLING_RIDER_SEAT_INDEX, (byte) 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,6 +355,15 @@ public final class EntityUtils {
|
||||
return translatedEntityName("minecraft", typeName, session);
|
||||
}
|
||||
|
||||
public static boolean equipmentUsableByEntity(GeyserSession session, Equippable equippable, EntityType entity) {
|
||||
if (equippable.allowedEntities() == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
GeyserHolderSet<EntityType> holderSet = GeyserHolderSet.fromHolderSet(JavaRegistries.ENTITY_TYPE, equippable.allowedEntities());
|
||||
return session.getTagCache().is(holderSet, entity);
|
||||
}
|
||||
|
||||
private EntityUtils() {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user