mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Merge remote-tracking branch 'refs/remotes/origin/master' into feature/floodgate-merge
# Conflicts: # bootstrap/bungeecord/base/build.gradle.kts # bootstrap/spigot/base/build.gradle.kts # bootstrap/spigot/base/src/main/java/org/geysermc/geyser/platform/spigot/GeyserSpigotInjector.java # bootstrap/velocity/base/build.gradle.kts # core/build.gradle.kts # core/src/main/java/org/geysermc/geyser/GeyserImpl.java # core/src/main/java/org/geysermc/geyser/dump/DumpInfo.java # core/src/main/java/org/geysermc/geyser/entity/type/FireworkEntity.java # core/src/main/java/org/geysermc/geyser/network/netty/LocalSession.java # core/src/main/java/org/geysermc/geyser/session/GeyserSession.java # core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaCustomPayloadTranslator.java # core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaLoginTranslator.java # gradle.properties # gradle/libs.versions.toml # settings.gradle.kts
This commit is contained in:
commit
9f32ba81b1
503 changed files with 19812 additions and 4402 deletions
|
@ -6,6 +6,10 @@ plugins {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
constraints {
|
||||
implementation(libs.raknet) // Ensure protocol does not override the RakNet version
|
||||
}
|
||||
|
||||
api(libs.floodgate.core)
|
||||
compileOnlyApi(libs.base.api)
|
||||
compileOnlyApi(projects.isolation)
|
||||
|
@ -44,6 +48,8 @@ dependencies {
|
|||
implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-x86_64" } }
|
||||
implementation(libs.netty.transport.native.epoll) { artifact { classifier = "linux-aarch_64" } }
|
||||
implementation(libs.netty.transport.native.kqueue) { artifact { classifier = "osx-x86_64" } }
|
||||
implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-x86_64" } }
|
||||
implementation(libs.netty.transport.native.io.uring) { artifact { classifier = "linux-aarch_64" } }
|
||||
|
||||
// Adventure text serialization
|
||||
api(libs.bundles.adventure)
|
||||
|
@ -64,11 +70,6 @@ dependencies {
|
|||
api(libs.events)
|
||||
}
|
||||
|
||||
configurations.api {
|
||||
// This is still experimental - additionally, it could only really benefit standalone
|
||||
exclude(group = "io.netty.incubator", module = "netty-incubator-transport-native-io_uring")
|
||||
}
|
||||
|
||||
tasks.processResources {
|
||||
// This is solely for backwards compatibility for other programs that used this file before the switch to gradle.
|
||||
// It used to be generated by the maven Git-Commit-Id-Plugin
|
||||
|
@ -99,7 +100,7 @@ configure<BlossomExtension> {
|
|||
}
|
||||
|
||||
fun Project.buildNumber(): Int =
|
||||
(System.getenv("GITHUB_RUN_NUMBER") ?: jenkinsBuildNumber())?.let { Integer.parseInt(it) } ?: -1
|
||||
(System.getenv("BUILD_NUMBER"))?.let { Integer.parseInt(it) } ?: -1
|
||||
|
||||
inner class GitInfo {
|
||||
val branch: String
|
||||
|
@ -132,9 +133,6 @@ inner class GitInfo {
|
|||
}
|
||||
}
|
||||
|
||||
// todo remove this when we're not using Jenkins anymore
|
||||
fun jenkinsBuildNumber(): String? = System.getenv("BUILD_NUMBER")
|
||||
|
||||
// Manual task to download the bedrock data files from the CloudburstMC/Data repository
|
||||
// Invoke with ./gradlew :core:downloadBedrockData --suffix=1_20_70
|
||||
// Set suffix to the current Bedrock version
|
||||
|
|
|
@ -29,7 +29,6 @@ import com.fasterxml.jackson.core.JsonParser;
|
|||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.steveice10.packetlib.tcp.TcpSession;
|
||||
import io.netty.channel.epoll.Epoll;
|
||||
import io.netty.util.NettyRuntime;
|
||||
import io.netty.util.concurrent.DefaultThreadFactory;
|
||||
|
@ -46,7 +45,6 @@ import org.cloudburstmc.protocol.bedrock.codec.BedrockCodec;
|
|||
import org.geysermc.api.Geyser;
|
||||
import org.geysermc.cumulus.form.Form;
|
||||
import org.geysermc.cumulus.form.util.FormBuilder;
|
||||
import org.geysermc.erosion.packet.Packets;
|
||||
import org.geysermc.floodgate.core.FloodgatePlatform;
|
||||
import org.geysermc.geyser.api.GeyserApi;
|
||||
import org.geysermc.geyser.api.command.CommandSource;
|
||||
|
@ -86,6 +84,7 @@ import org.geysermc.geyser.text.GeyserLocale;
|
|||
import org.geysermc.geyser.text.MinecraftLocale;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.*;
|
||||
import org.geysermc.mcprotocollib.network.tcp.TcpSession;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
|
@ -394,7 +393,7 @@ public class GeyserImpl implements GeyserApi {
|
|||
|
||||
pendingMicrosoftAuthentication = new PendingMicrosoftAuthentication(config.getPendingAuthenticationTimeout());
|
||||
|
||||
Packets.initGeyser();
|
||||
//Packets.initGeyser();
|
||||
|
||||
if (Epoll.isAvailable()) {
|
||||
this.erosionUnixListener = new UnixSocketClientListener();
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.command.defaults;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.ClientCommand;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.command.GeyserCommand;
|
||||
import org.geysermc.geyser.command.GeyserCommandSource;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.ClientCommand;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.ServerboundClientCommandPacket;
|
||||
|
||||
public class StatisticsCommand extends GeyserCommand {
|
||||
|
||||
|
|
|
@ -40,9 +40,11 @@ import org.geysermc.geyser.api.network.AuthType;
|
|||
import org.geysermc.geyser.network.CIDRMatcher;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
import org.geysermc.geyser.text.GeyserLocale;
|
||||
import org.geysermc.geyser.util.WebUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
@ -245,7 +247,18 @@ public abstract class GeyserJacksonConfiguration implements GeyserConfiguration
|
|||
List<CIDRMatcher> matchers = this.whitelistedIPsMatchers;
|
||||
if (matchers == null) {
|
||||
synchronized (this) {
|
||||
this.whitelistedIPsMatchers = matchers = proxyProtocolWhitelistedIPs.stream()
|
||||
// Check if proxyProtocolWhitelistedIPs contains URLs we need to fetch and parse by line
|
||||
List<String> whitelistedCIDRs = new ArrayList<>();
|
||||
for (String ip: proxyProtocolWhitelistedIPs) {
|
||||
if (!ip.startsWith("http")) {
|
||||
whitelistedCIDRs.add(ip);
|
||||
continue;
|
||||
}
|
||||
|
||||
WebUtils.getLineStream(ip).forEach(whitelistedCIDRs::add);
|
||||
}
|
||||
|
||||
this.whitelistedIPsMatchers = matchers = whitelistedCIDRs.stream()
|
||||
.map(CIDRMatcher::new)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
|
|
@ -27,8 +27,8 @@ package org.geysermc.geyser.dump;
|
|||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.api.util.PlatformType;
|
||||
import org.geysermc.geyser.text.AsteriskSerializer;
|
||||
|
||||
import java.util.List;
|
||||
|
|
|
@ -55,12 +55,7 @@ import java.net.InetSocketAddress;
|
|||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
|
@ -77,6 +72,7 @@ public class DumpInfo {
|
|||
private final GeyserConfiguration config;
|
||||
private final Floodgate floodgate;
|
||||
private final Object2IntMap<BedrockPlatform> userPlatforms;
|
||||
private final int connectionAttempts;
|
||||
private final HashInfo hashInfo;
|
||||
private final RamInfo ramInfo;
|
||||
private LogsInfo logsInfo;
|
||||
|
@ -128,6 +124,8 @@ public class DumpInfo {
|
|||
userPlatforms.put(device, userPlatforms.getOrDefault(device, 0) + 1);
|
||||
}
|
||||
|
||||
this.connectionAttempts = GeyserImpl.getInstance().getGeyserServer().getConnectionAttempts();
|
||||
|
||||
this.bootstrapInfo = GeyserImpl.getInstance().getBootstrap().getDumpInfo();
|
||||
|
||||
this.flagsInfo = new FlagsInfo();
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.geysermc.geyser.GeyserImpl;
|
||||
import org.geysermc.geyser.entity.factory.EntityFactory;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.translator.entity.EntityMetadataTranslator;
|
||||
|
@ -49,10 +50,10 @@ import java.util.function.BiConsumer;
|
|||
* @param <T> the entity type this definition represents
|
||||
*/
|
||||
public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, EntityType entityType, String identifier,
|
||||
float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
float width, float height, float offset, GeyserEntityProperties registeredProperties, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
|
||||
public static <T extends Entity> Builder<T> inherited(EntityFactory<T> factory, EntityDefinition<? super T> parent) {
|
||||
return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, new ObjectArrayList<>(parent.translators));
|
||||
return new Builder<>(factory, parent.entityType, parent.identifier, parent.width, parent.height, parent.offset, parent.registeredProperties, new ObjectArrayList<>(parent.translators));
|
||||
}
|
||||
|
||||
public static <T extends Entity> Builder<T> builder(EntityFactory<T> factory) {
|
||||
|
@ -87,6 +88,7 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
private float width;
|
||||
private float height;
|
||||
private float offset = 0.00001f;
|
||||
private GeyserEntityProperties registeredProperties;
|
||||
private final List<EntityMetadataTranslator<? super T, ?, ?>> translators;
|
||||
|
||||
private Builder(EntityFactory<T> factory) {
|
||||
|
@ -94,13 +96,14 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
translators = new ObjectArrayList<>();
|
||||
}
|
||||
|
||||
public Builder(EntityFactory<T> factory, EntityType type, String identifier, float width, float height, float offset, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
public Builder(EntityFactory<T> factory, EntityType type, String identifier, float width, float height, float offset, GeyserEntityProperties registeredProperties, List<EntityMetadataTranslator<? super T, ?, ?>> translators) {
|
||||
this.factory = factory;
|
||||
this.type = type;
|
||||
this.identifier = identifier;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.offset = offset;
|
||||
this.registeredProperties = registeredProperties;
|
||||
this.translators = translators;
|
||||
}
|
||||
|
||||
|
@ -127,6 +130,11 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> properties(GeyserEntityProperties registeredProperties) {
|
||||
this.registeredProperties = registeredProperties;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <U, EM extends EntityMetadata<U, ? extends MetadataType<U>>> Builder<T> addTranslator(MetadataType<U> type, BiConsumer<T, EM> translateFunction) {
|
||||
translators.add(new EntityMetadataTranslator<>(type, translateFunction));
|
||||
return this;
|
||||
|
@ -149,10 +157,13 @@ public record EntityDefinition<T extends Entity>(EntityFactory<T> factory, Entit
|
|||
if (identifier == null && type != null) {
|
||||
identifier = "minecraft:" + type.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, translators);
|
||||
EntityDefinition<T> definition = new EntityDefinition<>(factory, type, identifier, width, height, offset, registeredProperties, translators);
|
||||
if (register && definition.entityType() != null) {
|
||||
Registries.ENTITY_DEFINITIONS.get().putIfAbsent(definition.entityType(), definition);
|
||||
Registries.JAVA_ENTITY_IDENTIFIERS.get().putIfAbsent("minecraft:" + type.name().toLowerCase(Locale.ROOT), definition);
|
||||
if (definition.registeredProperties() != null) {
|
||||
Registries.BEDROCK_ENTITY_PROPERTIES.get().add(definition.registeredProperties().toNbtMap(identifier));
|
||||
}
|
||||
}
|
||||
return definition;
|
||||
}
|
||||
|
|
|
@ -25,12 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.MetadataType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.geyser.entity.type.living.monster.raid.RavagerEntity;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.MetadataType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityProperties;
|
||||
import org.geysermc.geyser.entity.type.*;
|
||||
import org.geysermc.geyser.entity.type.living.*;
|
||||
import org.geysermc.geyser.entity.type.living.animal.*;
|
||||
|
@ -53,8 +55,9 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
|
|||
public final class EntityDefinitions {
|
||||
public static final EntityDefinition<AllayEntity> ALLAY;
|
||||
public static final EntityDefinition<AreaEffectCloudEntity> AREA_EFFECT_CLOUD;
|
||||
public static final EntityDefinition<ArmadilloEntity> ARMADILLO;
|
||||
public static final EntityDefinition<ArmorStandEntity> ARMOR_STAND;
|
||||
public static final EntityDefinition<TippedArrowEntity> ARROW;
|
||||
public static final EntityDefinition<ArrowEntity> ARROW;
|
||||
public static final EntityDefinition<AxolotlEntity> AXOLOTL;
|
||||
public static final EntityDefinition<BatEntity> BAT;
|
||||
public static final EntityDefinition<BeeEntity> BEE;
|
||||
|
@ -130,7 +133,7 @@ public final class EntityDefinitions {
|
|||
public static final EntityDefinition<ThrownPotionEntity> POTION;
|
||||
public static final EntityDefinition<PufferFishEntity> PUFFERFISH;
|
||||
public static final EntityDefinition<RabbitEntity> RABBIT;
|
||||
public static final EntityDefinition<RaidParticipantEntity> RAVAGER;
|
||||
public static final EntityDefinition<RavagerEntity> RAVAGER;
|
||||
public static final EntityDefinition<AbstractFishEntity> SALMON;
|
||||
public static final EntityDefinition<SheepEntity> SHEEP;
|
||||
public static final EntityDefinition<ShulkerEntity> SHULKER;
|
||||
|
@ -200,7 +203,6 @@ public final class EntityDefinitions {
|
|||
.type(EntityType.AREA_EFFECT_CLOUD)
|
||||
.height(0.5f).width(1.0f)
|
||||
.addTranslator(MetadataType.FLOAT, AreaEffectCloudEntity::setRadius)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue()))
|
||||
.addTranslator(null) // Waiting
|
||||
.addTranslator(MetadataType.PARTICLE, AreaEffectCloudEntity::setParticle)
|
||||
.build();
|
||||
|
@ -376,10 +378,10 @@ public final class EntityDefinitions {
|
|||
.addTranslator(MetadataType.BYTE, AbstractArrowEntity::setArrowFlags)
|
||||
.addTranslator(null) // "Piercing level"
|
||||
.build();
|
||||
ARROW = EntityDefinition.inherited(TippedArrowEntity::new, abstractArrowBase)
|
||||
ARROW = EntityDefinition.inherited(ArrowEntity::new, abstractArrowBase)
|
||||
.type(EntityType.ARROW)
|
||||
.heightAndWidth(0.25f)
|
||||
.addTranslator(MetadataType.INT, TippedArrowEntity::setPotionEffectColor)
|
||||
.addTranslator(MetadataType.INT, ArrowEntity::setPotionEffectColor)
|
||||
.build();
|
||||
SPECTRAL_ARROW = EntityDefinition.inherited(abstractArrowBase.factory(), abstractArrowBase)
|
||||
.type(EntityType.SPECTRAL_ARROW)
|
||||
|
@ -452,8 +454,7 @@ public final class EntityDefinitions {
|
|||
EntityDefinition<LivingEntity> livingEntityBase = EntityDefinition.inherited(LivingEntity::new, entityBase)
|
||||
.addTranslator(MetadataType.BYTE, LivingEntity::setLivingEntityFlags)
|
||||
.addTranslator(MetadataType.FLOAT, LivingEntity::setHealth)
|
||||
.addTranslator(MetadataType.INT,
|
||||
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_COLOR, entityMetadata.getValue()))
|
||||
.addTranslator(MetadataType.PARTICLES, LivingEntity::setParticles)
|
||||
.addTranslator(MetadataType.BOOLEAN,
|
||||
(livingEntity, entityMetadata) -> livingEntity.getDirtyMetadata().put(EntityDataTypes.EFFECT_AMBIENCE, (byte) (((BooleanEntityMetadata) entityMetadata).getPrimitiveValue() ? 1 : 0)))
|
||||
.addTranslator(null) // Arrow count
|
||||
|
@ -672,7 +673,7 @@ public final class EntityDefinitions {
|
|||
SLIME = EntityDefinition.inherited(SlimeEntity::new, mobEntityBase)
|
||||
.type(EntityType.SLIME)
|
||||
.heightAndWidth(0.51f)
|
||||
.addTranslator(MetadataType.INT, SlimeEntity::setScale)
|
||||
.addTranslator(MetadataType.INT, SlimeEntity::setSlimeScale)
|
||||
.build();
|
||||
MAGMA_CUBE = EntityDefinition.inherited(MagmaCubeEntity::new, SLIME)
|
||||
.type(EntityType.MAGMA_CUBE)
|
||||
|
@ -745,9 +746,9 @@ public final class EntityDefinitions {
|
|||
.type(EntityType.PILLAGER)
|
||||
.height(1.8f).width(0.6f)
|
||||
.offset(1.62f)
|
||||
.addTranslator(null) // Charging; doesn't have an equivalent on Bedrock //TODO check
|
||||
.addTranslator(MetadataType.BOOLEAN, PillagerEntity::setChargingCrossbow)
|
||||
.build();
|
||||
RAVAGER = EntityDefinition.inherited(raidParticipantEntityBase.factory(), raidParticipantEntityBase)
|
||||
RAVAGER = EntityDefinition.inherited(RavagerEntity::new, raidParticipantEntityBase)
|
||||
.type(EntityType.RAVAGER)
|
||||
.height(1.9f).width(1.2f)
|
||||
.build();
|
||||
|
@ -770,6 +771,20 @@ public final class EntityDefinitions {
|
|||
|
||||
// Extends ageable
|
||||
{
|
||||
ARMADILLO = EntityDefinition.inherited(ArmadilloEntity::new, ageableEntityBase)
|
||||
.type(EntityType.ARMADILLO)
|
||||
.height(0.65f).width(0.7f)
|
||||
.properties(new GeyserEntityProperties.Builder()
|
||||
.addEnum(
|
||||
"minecraft:armadillo_state",
|
||||
"unrolled",
|
||||
"rolled_up",
|
||||
"rolled_up_peeking",
|
||||
"rolled_up_relaxing",
|
||||
"rolled_up_unrolling")
|
||||
.build())
|
||||
.addTranslator(MetadataType.ARMADILLO_STATE, ArmadilloEntity::setArmadilloState)
|
||||
.build();
|
||||
AXOLOTL = EntityDefinition.inherited(AxolotlEntity::new, ageableEntityBase)
|
||||
.type(EntityType.AXOLOTL)
|
||||
.height(0.42f).width(0.7f)
|
||||
|
@ -780,6 +795,9 @@ public final class EntityDefinitions {
|
|||
BEE = EntityDefinition.inherited(BeeEntity::new, ageableEntityBase)
|
||||
.type(EntityType.BEE)
|
||||
.heightAndWidth(0.6f)
|
||||
.properties(new GeyserEntityProperties.Builder()
|
||||
.addBoolean("minecraft:has_nectar")
|
||||
.build())
|
||||
.addTranslator(MetadataType.BYTE, BeeEntity::setBeeFlags)
|
||||
.addTranslator(MetadataType.INT, BeeEntity::setAngerTime)
|
||||
.build();
|
||||
|
@ -937,8 +955,7 @@ public final class EntityDefinitions {
|
|||
LLAMA = EntityDefinition.inherited(LlamaEntity::new, chestedHorseEntityBase)
|
||||
.type(EntityType.LLAMA)
|
||||
.height(1.87f).width(0.9f)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.STRENGTH, entityMetadata.getValue()))
|
||||
.addTranslator(MetadataType.INT, LlamaEntity::setCarpetedColor)
|
||||
.addTranslator(MetadataType.INT, LlamaEntity::setStrength)
|
||||
.addTranslator(MetadataType.INT, (entity, entityMetadata) -> entity.getDirtyMetadata().put(EntityDataTypes.VARIANT, entityMetadata.getValue()))
|
||||
.build();
|
||||
TRADER_LLAMA = EntityDefinition.inherited(TraderLlamaEntity::new, LLAMA)
|
||||
|
@ -947,7 +964,7 @@ public final class EntityDefinitions {
|
|||
.build();
|
||||
}
|
||||
|
||||
EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.inherited(TameableEntity::new, ageableEntityBase)
|
||||
EntityDefinition<TameableEntity> tameableEntityBase = EntityDefinition.<TameableEntity>inherited(null, ageableEntityBase) // No factory, is abstract
|
||||
.addTranslator(MetadataType.BYTE, TameableEntity::setTameableFlags)
|
||||
.addTranslator(MetadataType.OPTIONAL_UUID, TameableEntity::setOwner)
|
||||
.build();
|
||||
|
@ -971,6 +988,7 @@ public final class EntityDefinitions {
|
|||
.addTranslator(MetadataType.BOOLEAN, (wolfEntity, entityMetadata) -> wolfEntity.setFlag(EntityFlag.INTERESTED, ((BooleanEntityMetadata) entityMetadata).getPrimitiveValue()))
|
||||
.addTranslator(MetadataType.INT, WolfEntity::setCollarColor)
|
||||
.addTranslator(MetadataType.INT, WolfEntity::setWolfAngerTime)
|
||||
.addTranslator(MetadataType.WOLF_VARIANT, WolfEntity::setWolfVariant)
|
||||
.build();
|
||||
|
||||
// As of 1.18 these don't track entity data at all
|
||||
|
|
|
@ -49,9 +49,10 @@ public enum GeyserAttributeType {
|
|||
ATTACK_KNOCKBACK("minecraft:generic.attack_knockback", null, 1.5f, Float.MAX_VALUE, 0f),
|
||||
ATTACK_SPEED("minecraft:generic.attack_speed", null, 0f, 1024f, 4f),
|
||||
MAX_HEALTH("minecraft:generic.max_health", null, 0f, 1024f, 20f),
|
||||
SCALE("minecraft:generic.scale", null, 0.0625f, 16f, 1f), // Unused. Do we need this?
|
||||
|
||||
// Bedrock Attributes
|
||||
ABSORPTION(null, "minecraft:absorption", 0f, Float.MAX_VALUE, 0f),
|
||||
ABSORPTION(null, "minecraft:absorption", 0f, 1024f, 0f),
|
||||
EXHAUSTION(null, "minecraft:player.exhaustion", 0f, 5f, 0f),
|
||||
EXPERIENCE(null, "minecraft:player.experience", 0f, 1f, 0f),
|
||||
EXPERIENCE_LEVEL(null, "minecraft:player.level", 0f, 24791.00f, 0f),
|
||||
|
@ -66,6 +67,10 @@ public enum GeyserAttributeType {
|
|||
private final float maximum;
|
||||
private final float defaultValue;
|
||||
|
||||
public AttributeData getAttribute() {
|
||||
return getAttribute(defaultValue);
|
||||
}
|
||||
|
||||
public AttributeData getAttribute(float value) {
|
||||
return getAttribute(value, maximum);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.properties;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.geysermc.geyser.entity.properties.type.BooleanProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.EnumProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.FloatProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.IntProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.PropertyType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@EqualsAndHashCode
|
||||
@ToString
|
||||
public class GeyserEntityProperties {
|
||||
private final ObjectArrayList<PropertyType> properties;
|
||||
private final Object2IntMap<String> propertyIndices;
|
||||
|
||||
private GeyserEntityProperties(ObjectArrayList<PropertyType> properties,
|
||||
Object2IntMap<String> propertyIndices) {
|
||||
this.properties = properties;
|
||||
this.propertyIndices = propertyIndices;
|
||||
}
|
||||
|
||||
public NbtMap toNbtMap(String entityType) {
|
||||
NbtMapBuilder mapBuilder = NbtMap.builder();
|
||||
List<NbtMap> nbtProperties = new ArrayList<>();
|
||||
|
||||
for (PropertyType property : properties) {
|
||||
nbtProperties.add(property.nbtMap());
|
||||
}
|
||||
mapBuilder.putList("properties", NbtType.COMPOUND, nbtProperties);
|
||||
|
||||
return mapBuilder.putString("type", entityType).build();
|
||||
}
|
||||
|
||||
public @NonNull List<PropertyType> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public int getPropertyIndex(String name) {
|
||||
return propertyIndices.getOrDefault(name, -1);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final ObjectArrayList<PropertyType> properties = new ObjectArrayList<>();
|
||||
private final Object2IntMap<String> propertyIndices = new Object2IntOpenHashMap<>();
|
||||
|
||||
public Builder addInt(@NonNull String name, int min, int max) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new IntProperty(name, min, max);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addInt(@NonNull String name) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new IntProperty(name, Integer.MIN_VALUE, Integer.MAX_VALUE);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addFloat(@NonNull String name, float min, float max) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new FloatProperty(name, min, max);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addFloat(@NonNull String name) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new FloatProperty(name, Float.MIN_NORMAL, Float.MAX_VALUE);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addBoolean(@NonNull String name) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new BooleanProperty(name);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addEnum(@NonNull String name, List<String> values) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
PropertyType property = new EnumProperty(name, values);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder addEnum(@NonNull String name, String... values) {
|
||||
if (propertyIndices.containsKey(name)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Property with name " + name + " already exists on builder!");
|
||||
}
|
||||
List<String> valuesList = Arrays.asList(values); // Convert array to list
|
||||
PropertyType property = new EnumProperty(name, valuesList);
|
||||
this.properties.add(property);
|
||||
propertyIndices.put(name, properties.size() - 1);
|
||||
return this;
|
||||
}
|
||||
|
||||
public GeyserEntityProperties build() {
|
||||
return new GeyserEntityProperties(properties, propertyIndices);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.properties;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.FloatEntityProperty;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.IntEntityProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.EnumProperty;
|
||||
import org.geysermc.geyser.entity.properties.type.PropertyType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class GeyserEntityPropertyManager {
|
||||
|
||||
private final GeyserEntityProperties properties;
|
||||
|
||||
private final ObjectArrayList<IntEntityProperty> intEntityProperties = new ObjectArrayList<>();
|
||||
private final ObjectArrayList<FloatEntityProperty> floatEntityProperties = new ObjectArrayList<>();
|
||||
|
||||
public GeyserEntityPropertyManager(GeyserEntityProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void add(String propertyName, int value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
intEntityProperties.add(new IntEntityProperty(index, value));
|
||||
}
|
||||
|
||||
public void add(String propertyName, boolean value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
intEntityProperties.add(new IntEntityProperty(index, value ? 1 : 0));
|
||||
}
|
||||
|
||||
public void add(String propertyName, String value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
PropertyType property = properties.getProperties().get(index);
|
||||
int enumIndex = ((EnumProperty) property).getIndex(value);
|
||||
intEntityProperties.add(new IntEntityProperty(index, enumIndex));
|
||||
}
|
||||
|
||||
public void add(String propertyName, float value) {
|
||||
int index = properties.getPropertyIndex(propertyName);
|
||||
floatEntityProperties.add(new FloatEntityProperty(index, value));
|
||||
}
|
||||
|
||||
public boolean hasFloatProperties() {
|
||||
return !this.floatEntityProperties.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasIntProperties() {
|
||||
return !this.intEntityProperties.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasProperties() {
|
||||
return hasFloatProperties() || hasIntProperties();
|
||||
}
|
||||
|
||||
public ObjectArrayList<IntEntityProperty> intProperties() {
|
||||
return this.intEntityProperties;
|
||||
}
|
||||
|
||||
public void applyIntProperties(List<IntEntityProperty> properties) {
|
||||
properties.addAll(intEntityProperties);
|
||||
intEntityProperties.clear();
|
||||
}
|
||||
|
||||
public ObjectArrayList<FloatEntityProperty> floatProperties() {
|
||||
return this.floatEntityProperties;
|
||||
}
|
||||
|
||||
public void applyFloatProperties(List<FloatEntityProperty> properties) {
|
||||
properties.addAll(floatEntityProperties);
|
||||
floatEntityProperties.clear();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.properties.type;
|
||||
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public class BooleanProperty implements PropertyType {
|
||||
private final String name;
|
||||
|
||||
public BooleanProperty(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putInt("type", 2)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.properties.type;
|
||||
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EnumProperty implements PropertyType {
|
||||
private final String name;
|
||||
private final List<String> values;
|
||||
private final Object2IntMap<String> valueIndexMap;
|
||||
|
||||
public EnumProperty(String name, List<String> values) {
|
||||
this.name = name;
|
||||
this.values = values;
|
||||
this.valueIndexMap = new Object2IntOpenHashMap<>(values.size());
|
||||
for (int i = 0; i < values.size(); i++) {
|
||||
valueIndexMap.put(values.get(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putList("enum", NbtType.STRING, values)
|
||||
.putInt("type", 3)
|
||||
.build();
|
||||
}
|
||||
|
||||
public int getIndex(String value) {
|
||||
return valueIndexMap.getOrDefault(value, -1);
|
||||
}
|
||||
}
|
|
@ -23,34 +23,28 @@
|
|||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.item;
|
||||
package org.geysermc.geyser.entity.properties.type;
|
||||
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.IntTag;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public interface DyeableLeatherItem {
|
||||
public class FloatProperty implements PropertyType {
|
||||
private final String name;
|
||||
private final float max;
|
||||
private final float min;
|
||||
|
||||
static void translateNbtToBedrock(CompoundTag tag) {
|
||||
CompoundTag displayTag = tag.get("display");
|
||||
if (displayTag == null) {
|
||||
return;
|
||||
}
|
||||
IntTag color = displayTag.remove("color");
|
||||
if (color != null) {
|
||||
tag.put(new IntTag("customColor", color.getValue()));
|
||||
}
|
||||
public FloatProperty(String name, float min, float max) {
|
||||
this.name = name;
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
static void translateNbtToJava(CompoundTag tag) {
|
||||
IntTag color = tag.get("customColor");
|
||||
if (color == null) {
|
||||
return;
|
||||
}
|
||||
CompoundTag displayTag = tag.get("display");
|
||||
if (displayTag == null) {
|
||||
displayTag = new CompoundTag("display");
|
||||
}
|
||||
displayTag.put(color);
|
||||
tag.remove("customColor");
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putFloat("max", max)
|
||||
.putFloat("min", min)
|
||||
.putInt("type", 1)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.properties.type;
|
||||
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public class IntProperty implements PropertyType {
|
||||
private final String name;
|
||||
private final int max;
|
||||
private final int min;
|
||||
|
||||
public IntProperty(String name, int min, int max) {
|
||||
this.name = name;
|
||||
this.max = max;
|
||||
this.min = min;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NbtMap nbtMap() {
|
||||
return NbtMap.builder()
|
||||
.putString("name", name)
|
||||
.putInt("max", max)
|
||||
.putInt("min", min)
|
||||
.putInt("type", 0)
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.properties.type;
|
||||
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
||||
public interface PropertyType {
|
||||
NbtMap nbtMap();
|
||||
}
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.level.particle.Particle;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -35,6 +32,11 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -51,7 +53,7 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_DURATION, Integer.MAX_VALUE);
|
||||
|
||||
// This disabled client side shrink of the cloud
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 0.0f);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, 3.0f);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_RATE, Float.MIN_VALUE);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_CHANGE_ON_PICKUP, Float.MIN_VALUE);
|
||||
|
||||
|
@ -60,7 +62,7 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
|
||||
public void setRadius(FloatEntityMetadata entityMetadata) {
|
||||
// Anything less than 0.5 will cause the cloud to despawn
|
||||
float value = Math.max(entityMetadata.getPrimitiveValue(), 0.5f);
|
||||
float value = MathUtils.clamp(entityMetadata.getPrimitiveValue(), 0.5f, 32.0f);
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_RADIUS, value);
|
||||
dirtyMetadata.put(EntityDataTypes.WIDTH, 2.0f * value);
|
||||
}
|
||||
|
@ -69,5 +71,9 @@ public class AreaEffectCloudEntity extends Entity {
|
|||
Particle particle = entityMetadata.getValue();
|
||||
Registries.PARTICLES.map(particle.getType(), p -> p.levelEventType() instanceof ParticleType particleType ? particleType : null).ifPresent(type ->
|
||||
dirtyMetadata.put(EntityDataTypes.AREA_EFFECT_CLOUD_PARTICLE, type));
|
||||
|
||||
if (particle.getData() instanceof EntityEffectParticleData effectParticleData) {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, effectParticleData.getColor());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,21 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.item.TippedArrowPotion;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Internally this is known as TippedArrowEntity but is used with tipped arrows and normal arrows
|
||||
*/
|
||||
public class TippedArrowEntity extends AbstractArrowEntity {
|
||||
public class ArrowEntity extends AbstractArrowEntity {
|
||||
|
||||
public TippedArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
public ArrowEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
|
@ -25,24 +25,23 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
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;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BoatEntity extends Entity {
|
||||
public class BoatEntity extends Entity implements Tickable {
|
||||
|
||||
/**
|
||||
* Required when IS_BUOYANT is sent in order for boats to work in the water. <br>
|
||||
|
@ -58,6 +57,7 @@ public class BoatEntity extends Entity {
|
|||
private float paddleTimeLeft;
|
||||
private boolean isPaddlingRight;
|
||||
private float paddleTimeRight;
|
||||
private boolean doTick;
|
||||
|
||||
/**
|
||||
* Saved for using the "pick" functionality on a boat.
|
||||
|
@ -133,34 +133,16 @@ public class BoatEntity extends Entity {
|
|||
|
||||
public void setPaddlingLeft(BooleanEntityMetadata entityMetadata) {
|
||||
isPaddlingLeft = entityMetadata.getPrimitiveValue();
|
||||
if (isPaddlingLeft) {
|
||||
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
|
||||
// This is an asynchronous method that emulates Bedrock rowing until "false" is sent.
|
||||
paddleTimeLeft = 0f;
|
||||
if (!this.passengers.isEmpty()) {
|
||||
// Get the entity by the first stored passenger and convey motion in this manner
|
||||
Entity entity = this.passengers.get(0);
|
||||
if (entity != null) {
|
||||
updateLeftPaddle(session, entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Indicate that the row position should be reset
|
||||
if (!isPaddlingLeft) {
|
||||
paddleTimeLeft = 0.0f;
|
||||
dirtyMetadata.put(EntityDataTypes.ROW_TIME_LEFT, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
public void setPaddlingRight(BooleanEntityMetadata entityMetadata) {
|
||||
isPaddlingRight = entityMetadata.getPrimitiveValue();
|
||||
if (isPaddlingRight) {
|
||||
paddleTimeRight = 0f;
|
||||
if (!this.passengers.isEmpty()) {
|
||||
Entity entity = this.passengers.get(0);
|
||||
if (entity != null) {
|
||||
updateRightPaddle(session, entity);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!isPaddlingRight) {
|
||||
paddleTimeRight = 0.0f;
|
||||
dirtyMetadata.put(EntityDataTypes.ROW_TIME_RIGHT, 0.0f);
|
||||
}
|
||||
}
|
||||
|
@ -186,29 +168,26 @@ public class BoatEntity extends Entity {
|
|||
}
|
||||
}
|
||||
|
||||
private void updateLeftPaddle(GeyserSession session, Entity rower) {
|
||||
@Override
|
||||
public void tick() {
|
||||
// Java sends simply "true" and "false" (is_paddling_left), Bedrock keeps sending packets as you're rowing
|
||||
doTick = !doTick; // Run every 100 ms
|
||||
if (!doTick || passengers.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Entity rower = passengers.get(0);
|
||||
if (rower == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPaddlingLeft) {
|
||||
paddleTimeLeft += ROWING_SPEED;
|
||||
sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_LEFT, paddleTimeLeft);
|
||||
|
||||
session.scheduleInEventLoop(() ->
|
||||
updateLeftPaddle(session, rower),
|
||||
100,
|
||||
TimeUnit.MILLISECONDS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateRightPaddle(GeyserSession session, Entity rower) {
|
||||
if (isPaddlingRight) {
|
||||
paddleTimeRight += ROWING_SPEED;
|
||||
sendAnimationPacket(session, rower, AnimatePacket.Action.ROW_RIGHT, paddleTimeRight);
|
||||
|
||||
session.scheduleInEventLoop(() ->
|
||||
updateRightPaddle(session, rower),
|
||||
100,
|
||||
TimeUnit.MILLISECONDS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
|
|
@ -25,13 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -42,27 +35,26 @@ import org.cloudburstmc.math.vector.Vector3f;
|
|||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityAbsolutePacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.RemoveEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
import org.geysermc.geyser.api.entity.type.GeyserEntity;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
|
||||
import org.geysermc.geyser.entity.properties.GeyserEntityPropertyManager;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -126,6 +118,8 @@ public class Entity implements GeyserEntity {
|
|||
@Setter(AccessLevel.PROTECTED) // For players
|
||||
private boolean flagsDirty = false;
|
||||
|
||||
protected final GeyserEntityPropertyManager propertyManager;
|
||||
|
||||
public Entity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
this.session = session;
|
||||
|
||||
|
@ -140,6 +134,8 @@ public class Entity implements GeyserEntity {
|
|||
|
||||
this.valid = false;
|
||||
|
||||
this.propertyManager = new GeyserEntityPropertyManager(definition.registeredProperties());
|
||||
|
||||
setPosition(position);
|
||||
setAirSupply(getMaxAir());
|
||||
|
||||
|
@ -200,11 +196,9 @@ public class Entity implements GeyserEntity {
|
|||
|
||||
/**
|
||||
* Despawns the entity
|
||||
*
|
||||
* @return can be deleted
|
||||
*/
|
||||
public boolean despawnEntity() {
|
||||
if (!valid) return true;
|
||||
public void despawnEntity() {
|
||||
if (!valid) return;
|
||||
|
||||
for (Entity passenger : passengers) { // Make sure all passengers on the despawned entity are updated
|
||||
if (passenger == null) continue;
|
||||
|
@ -218,7 +212,6 @@ public class Entity implements GeyserEntity {
|
|||
session.sendUpstreamPacket(removeEntityPacket);
|
||||
|
||||
valid = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void moveRelative(double relX, double relY, double relZ, float yaw, float pitch, boolean isOnGround) {
|
||||
|
@ -360,6 +353,23 @@ public class Entity implements GeyserEntity {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the Bedrock entity properties to the client
|
||||
*/
|
||||
public void updateBedrockEntityProperties() {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propertyManager.hasProperties()) {
|
||||
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket();
|
||||
entityDataPacket.setRuntimeEntityId(geyserId);
|
||||
propertyManager.applyIntProperties(entityDataPacket.getProperties().getIntProperties());
|
||||
propertyManager.applyFloatProperties(entityDataPacket.getProperties().getFloatProperties());
|
||||
session.sendUpstreamPacket(entityDataPacket);
|
||||
}
|
||||
}
|
||||
|
||||
public void setFlags(ByteEntityMetadata entityMetadata) {
|
||||
byte xd = entityMetadata.getPrimitiveValue();
|
||||
setFlag(EntityFlag.ON_FIRE, ((xd & 0x01) == 0x01) && !getFlag(EntityFlag.FIRE_IMMUNE)); // Otherwise immune entities sometimes flicker onfire
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -72,6 +72,9 @@ public class FireballEntity extends ThrowableEntity {
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (removedInVoid()) {
|
||||
return;
|
||||
}
|
||||
moveAbsoluteImmediate(tickMovement(position), getYaw(), getPitch(), getHeadYaw(), false, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,25 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.ListTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
import org.cloudburstmc.nbt.NbtMapBuilder;
|
||||
import org.cloudburstmc.nbt.NbtType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityMotionPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
import org.geysermc.geyser.level.FireworkColor;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.geyser.translator.item.BedrockItemBuilder;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -58,73 +51,16 @@ public class FireworkEntity extends Entity {
|
|||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
CompoundTag tag = item.getNbt();
|
||||
|
||||
if (tag == null) {
|
||||
DataComponents components = item.getDataComponents();
|
||||
if (components == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CompoundTag fireworks = tag.get("Fireworks");
|
||||
if (fireworks == null) {
|
||||
// Thank you Mineplex very cool
|
||||
return;
|
||||
}
|
||||
// TODO this looked the same, so I'm going to assume it is and (keep below comment if true)
|
||||
// Translate using item methods to get firework NBT for Bedrock
|
||||
BedrockItemBuilder builder = new BedrockItemBuilder();
|
||||
Items.FIREWORK_ROCKET.translateComponentsToBedrock(session, components, builder);
|
||||
|
||||
NbtMapBuilder fireworksBuilder = NbtMap.builder();
|
||||
if (fireworks.get("Flight") != null) {
|
||||
fireworksBuilder.putByte("Flight", MathUtils.getNbtByte(fireworks.get("Flight").getValue()));
|
||||
}
|
||||
|
||||
List<NbtMap> explosions = new ArrayList<>();
|
||||
if (fireworks.get("Explosions") != null) {
|
||||
for (Tag effect : ((ListTag) fireworks.get("Explosions")).getValue()) {
|
||||
CompoundTag effectData = (CompoundTag) effect;
|
||||
NbtMapBuilder effectBuilder = NbtMap.builder();
|
||||
|
||||
if (effectData.get("Type") != null) {
|
||||
effectBuilder.putByte("FireworkType", MathUtils.getNbtByte(effectData.get("Type").getValue()));
|
||||
}
|
||||
|
||||
if (effectData.get("Colors") != null) {
|
||||
int[] oldColors = (int[]) effectData.get("Colors").getValue();
|
||||
byte[] colors = new byte[oldColors.length];
|
||||
|
||||
int i = 0;
|
||||
for (int color : oldColors) {
|
||||
colors[i++] = FireworkColor.fromJavaRGB(color);
|
||||
}
|
||||
|
||||
effectBuilder.putByteArray("FireworkColor", colors);
|
||||
}
|
||||
|
||||
if (effectData.get("FadeColors") != null) {
|
||||
int[] oldColors = (int[]) effectData.get("FadeColors").getValue();
|
||||
byte[] colors = new byte[oldColors.length];
|
||||
|
||||
int i = 0;
|
||||
for (int color : oldColors) {
|
||||
colors[i++] = FireworkColor.fromJavaRGB(color);
|
||||
}
|
||||
|
||||
effectBuilder.putByteArray("FireworkFade", colors);
|
||||
}
|
||||
|
||||
if (effectData.get("Trail") != null) {
|
||||
effectBuilder.putByte("FireworkTrail", MathUtils.getNbtByte(effectData.get("Trail").getValue()));
|
||||
}
|
||||
|
||||
if (effectData.get("Flicker") != null) {
|
||||
effectBuilder.putByte("FireworkFlicker", MathUtils.getNbtByte(effectData.get("Flicker").getValue()));
|
||||
}
|
||||
|
||||
explosions.add(effectBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
fireworksBuilder.putList("Explosions", NbtType.COMPOUND, explosions);
|
||||
|
||||
NbtMapBuilder builder = NbtMap.builder();
|
||||
builder.put("Fireworks", fireworksBuilder.build());
|
||||
dirtyMetadata.put(EntityDataTypes.DISPLAY_FIREWORK, builder.build());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.erosion.util.BlockPositionIterator;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.player.PlayerEntity;
|
||||
|
@ -38,6 +37,7 @@ import org.geysermc.geyser.level.physics.BoundingBox;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.collision.BlockCollision;
|
||||
import org.geysermc.geyser.util.BlockUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
@ -133,6 +133,9 @@ public class FishingHookEntity extends ThrowableEntity {
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (removedInVoid()) {
|
||||
return;
|
||||
}
|
||||
if (hooked || !isInAir() && !isInWater() || isOnGround()) {
|
||||
motion = Vector3f.ZERO;
|
||||
return;
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,16 +25,16 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AnimatePacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.packet.ingame.serverbound.player.ServerboundSwingPacket;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
|
@ -37,7 +35,9 @@ import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
@ -74,7 +74,7 @@ public class ItemEntity extends ThrowableEntity {
|
|||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (isInWater()) {
|
||||
if (removedInVoid() || isInWater()) {
|
||||
return;
|
||||
}
|
||||
if (!isOnGround() || (motion.getX() * motion.getX() + motion.getZ() * motion.getZ()) > 0.00001) {
|
||||
|
|
|
@ -25,12 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.math.vector.Vector3i;
|
||||
import org.cloudburstmc.nbt.NbtMap;
|
||||
|
@ -39,12 +34,17 @@ import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.BlockEntityDataPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateBlockPacket;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.inventory.item.ItemTranslator;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InventoryUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
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.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -148,7 +148,7 @@ public class ItemFrameEntity extends Entity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean despawnEntity() {
|
||||
public void despawnEntity() {
|
||||
UpdateBlockPacket updateBlockPacket = new UpdateBlockPacket();
|
||||
updateBlockPacket.setDataLayer(0);
|
||||
updateBlockPacket.setBlockPosition(bedrockPosition);
|
||||
|
@ -161,7 +161,6 @@ public class ItemFrameEntity extends Entity {
|
|||
session.getItemFrameCache().remove(bedrockPosition, this);
|
||||
|
||||
valid = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
private NbtMap getDefaultTag() {
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,16 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.Attribute;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.attribute.AttributeType;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import com.github.steveice10.opennbt.tag.builtin.CompoundTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
@ -55,8 +45,23 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.translator.item.ItemTranslator;
|
||||
import org.geysermc.geyser.util.AttributeUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
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.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.EntityEffectParticleData;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.Particle;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.level.particle.ParticleType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
@ -69,7 +74,7 @@ public class LivingEntity extends Entity {
|
|||
protected ItemData leggings = ItemData.AIR;
|
||||
protected ItemData boots = ItemData.AIR;
|
||||
protected ItemData hand = ItemData.AIR;
|
||||
protected ItemData offHand = ItemData.AIR;
|
||||
protected ItemData offhand = ItemData.AIR;
|
||||
|
||||
@Getter(value = AccessLevel.NONE)
|
||||
protected float health = 1f; // The default value in Java Edition before any entity metadata is sent
|
||||
|
@ -81,12 +86,58 @@ public class LivingEntity extends Entity {
|
|||
*/
|
||||
private boolean isMaxFrozenState = false;
|
||||
|
||||
/**
|
||||
* The base scale entity data, without attributes applied. Used for such cases as baby variants.
|
||||
*/
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private float scale;
|
||||
/**
|
||||
* The scale sent through the Java attributes packet
|
||||
*/
|
||||
@Getter(AccessLevel.NONE)
|
||||
@Setter(AccessLevel.NONE)
|
||||
private float attributeScale;
|
||||
|
||||
public LivingEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setHelmet(ItemStack stack) {
|
||||
this.helmet = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setChestplate(ItemStack stack) {
|
||||
this.chestplate = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setLeggings(ItemStack stack) {
|
||||
this.leggings = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setBoots(ItemStack stack) {
|
||||
this.boots = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setHand(ItemStack stack) {
|
||||
this.hand = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void setOffhand(ItemStack stack) {
|
||||
this.offhand = ItemTranslator.translateToBedrock(session, stack);
|
||||
}
|
||||
|
||||
public void switchHands() {
|
||||
ItemData offhand = this.offhand;
|
||||
this.offhand = this.hand;
|
||||
this.hand = offhand;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initializeMetadata() {
|
||||
// Initialize here so overriding classes don't have 0 values
|
||||
this.scale = 1f;
|
||||
this.attributeScale = 1f;
|
||||
super.initializeMetadata();
|
||||
// Matches Bedrock behavior; is always set to this
|
||||
dirtyMetadata.put(EntityDataTypes.STRUCTURAL_INTEGRITY, 1);
|
||||
|
@ -121,6 +172,37 @@ public class LivingEntity extends Entity {
|
|||
session.sendUpstreamPacket(attributesPacket);
|
||||
}
|
||||
|
||||
// TODO: support all particle types
|
||||
public void setParticles(ObjectEntityMetadata<List<Particle>> entityMetadata) {
|
||||
List<Particle> particles = entityMetadata.getValue();
|
||||
float r = 0f;
|
||||
float g = 0f;
|
||||
float b = 0f;
|
||||
|
||||
int count = 0;
|
||||
for (Particle particle : particles) {
|
||||
if (particle.getType() != ParticleType.ENTITY_EFFECT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int color = ((EntityEffectParticleData) particle.getData()).getColor();
|
||||
r += ((color >> 16) & 0xFF) / 255f;
|
||||
g += ((color >> 8) & 0xFF) / 255f;
|
||||
b += ((color) & 0xFF) / 255f;
|
||||
count++;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
if (count > 0) {
|
||||
r = r / count * 255f;
|
||||
g = g / count * 255f;
|
||||
b = b / count * 255f;
|
||||
result = (int) r << 16 | (int) g << 8 | (int) b;
|
||||
}
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, result);
|
||||
}
|
||||
|
||||
public @Nullable Vector3i setBedPosition(EntityMetadata<Optional<Vector3i>, ?> entityMetadata) {
|
||||
Optional<Vector3i> optionalPos = entityMetadata.getValue();
|
||||
if (optionalPos.isPresent()) {
|
||||
|
@ -135,7 +217,7 @@ public class LivingEntity extends Entity {
|
|||
protected boolean hasShield(boolean offhand) {
|
||||
ItemMapping shieldMapping = session.getItemMappings().getStoredItems().shield();
|
||||
if (offhand) {
|
||||
return offHand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
return this.offhand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
} else {
|
||||
return hand.getDefinition().equals(shieldMapping.getBedrockDefinition());
|
||||
}
|
||||
|
@ -164,6 +246,21 @@ public class LivingEntity extends Entity {
|
|||
return freezingPercentage;
|
||||
}
|
||||
|
||||
protected void setScale(float scale) {
|
||||
this.scale = scale;
|
||||
applyScale();
|
||||
}
|
||||
|
||||
private void setAttributeScale(float scale) {
|
||||
this.attributeScale = scale;
|
||||
applyScale();
|
||||
}
|
||||
|
||||
private void applyScale() {
|
||||
// Take any adjustments Bedrock requires, and compute it alongside the attribute's additional changes
|
||||
this.dirtyMetadata.put(EntityDataTypes.SCALE, scale * attributeScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Bedrock health attribute constructed from the data sent from the server
|
||||
*/
|
||||
|
@ -194,9 +291,9 @@ public class LivingEntity extends Entity {
|
|||
/**
|
||||
* Checks to see if a nametag interaction would go through.
|
||||
*/
|
||||
// Implementation note for 1.20.5: this code was moved to the NameTag item.
|
||||
protected final InteractionResult checkInteractWithNameTag(GeyserItemStack itemStack) {
|
||||
CompoundTag nbt = itemStack.getNbt();
|
||||
if (nbt != null && nbt.get("display") instanceof CompoundTag displayTag && displayTag.get("Name") instanceof StringTag) {
|
||||
if (itemStack.getComponent(DataComponentType.CUSTOM_NAME) != null) {
|
||||
// The mob shall be named
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
@ -247,7 +344,7 @@ public class LivingEntity extends Entity {
|
|||
|
||||
MobEquipmentPacket offHandPacket = new MobEquipmentPacket();
|
||||
offHandPacket.setRuntimeEntityId(geyserId);
|
||||
offHandPacket.setItem(offHand);
|
||||
offHandPacket.setItem(offhand);
|
||||
offHandPacket.setHotbarSlot(-1);
|
||||
offHandPacket.setInventorySlot(0);
|
||||
offHandPacket.setContainerId(ContainerId.OFFHAND);
|
||||
|
@ -255,6 +352,15 @@ public class LivingEntity extends Entity {
|
|||
session.sendUpstreamPacket(offHandPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a SWING_ARM animation packet is received
|
||||
*
|
||||
* @return true if an ATTACK_START event should be used instead
|
||||
*/
|
||||
public boolean useArmSwingAttack() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attributes are properties of an entity that are generally more runtime-based instead of permanent properties.
|
||||
* Movement speed, current attack damage with a weapon, current knockback resistance.
|
||||
|
@ -299,7 +405,12 @@ public class LivingEntity extends Entity {
|
|||
case GENERIC_MOVEMENT_SPEED -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.MOVEMENT_SPEED));
|
||||
case GENERIC_FOLLOW_RANGE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.FOLLOW_RANGE));
|
||||
case GENERIC_KNOCKBACK_RESISTANCE -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.KNOCKBACK_RESISTANCE));
|
||||
case HORSE_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH));
|
||||
case GENERIC_JUMP_STRENGTH -> newAttributes.add(calculateAttribute(javaAttribute, GeyserAttributeType.HORSE_JUMP_STRENGTH));
|
||||
case GENERIC_SCALE -> {
|
||||
// Attribute on Java, entity data on Bedrock
|
||||
setAttributeScale((float) AttributeUtils.calculateValue(javaAttribute));
|
||||
updateBedrockMetadata();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
@ -35,6 +32,9 @@ import org.geysermc.geyser.entity.EntityDefinitions;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
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;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddPaintingPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.PaintingType;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -49,7 +49,7 @@ public class PaintingEntity extends Entity {
|
|||
// Wait until we get the metadata needed
|
||||
}
|
||||
|
||||
public void setPaintingType(ObjectEntityMetadata<com.github.steveice10.mc.protocol.data.game.entity.type.PaintingType> entityMetadata) {
|
||||
public void setPaintingType(ObjectEntityMetadata<org.geysermc.mcprotocollib.protocol.data.game.entity.type.PaintingType> entityMetadata) {
|
||||
PaintingType type = PaintingType.getByPaintingType(entityMetadata.getValue());
|
||||
AddPaintingPacket addPaintingPacket = new AddPaintingPacket();
|
||||
addPaintingPacket.setUniqueEntityId(geyserId);
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SetEntityDataPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import net.kyori.adventure.text.Component;
|
||||
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.geyser.translator.text.MessageTranslator;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -34,6 +33,7 @@ import org.cloudburstmc.protocol.bedrock.packet.MoveEntityDeltaPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.level.block.BlockStateValues;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -55,6 +55,9 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||
*/
|
||||
@Override
|
||||
public void tick() {
|
||||
if (removedInVoid()) {
|
||||
return;
|
||||
}
|
||||
moveAbsoluteImmediate(position.add(motion), getYaw(), getPitch(), getHeadYaw(), isOnGround(), false);
|
||||
float drag = getDrag();
|
||||
float gravity = getGravity();
|
||||
|
@ -170,14 +173,14 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean despawnEntity() {
|
||||
public void despawnEntity() {
|
||||
if (definition.entityType() == EntityType.ENDER_PEARL) {
|
||||
LevelEventPacket particlePacket = new LevelEventPacket();
|
||||
particlePacket.setType(LevelEvent.PARTICLE_TELEPORT);
|
||||
particlePacket.setPosition(position);
|
||||
session.sendUpstreamPacket(particlePacket);
|
||||
}
|
||||
return super.despawnEntity();
|
||||
super.despawnEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -191,4 +194,17 @@ public class ThrowableEntity extends Entity implements Tickable {
|
|||
moveAbsoluteImmediate(position, yaw, pitch, headYaw, isOnGround, teleported);
|
||||
lastJavaPosition = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the entity if it is 64 blocks below the world.
|
||||
*
|
||||
* @return true if the entity was removed
|
||||
*/
|
||||
public boolean removedInVoid() {
|
||||
if (position.getY() < session.getDimensionType().minY() - 64) {
|
||||
session.getEntityCache().removeEntity(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.ItemStack;
|
||||
import com.github.steveice10.opennbt.tag.builtin.StringTag;
|
||||
import com.github.steveice10.opennbt.tag.builtin.Tag;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -38,6 +34,11 @@ import org.geysermc.geyser.inventory.item.Potion;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.Registries;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponentType;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.DataComponents;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.component.PotionContents;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
|
@ -53,21 +54,22 @@ public class ThrownPotionEntity extends ThrowableItemEntity {
|
|||
public void setItem(EntityMetadata<ItemStack, ?> entityMetadata) {
|
||||
ItemStack itemStack = entityMetadata.getValue();
|
||||
if (itemStack == null) {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
||||
dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0);
|
||||
setFlag(EntityFlag.ENCHANTED, false);
|
||||
setFlag(EntityFlag.LINGERING, false);
|
||||
} else {
|
||||
// As of Java 1.19.3, the server/client doesn't seem to care of the item is actually a potion?
|
||||
if (itemStack.getNbt() != null) {
|
||||
Tag potionTag = itemStack.getNbt().get("Potion");
|
||||
if (potionTag instanceof StringTag) {
|
||||
Potion potion = Potion.getByJavaIdentifier(((StringTag) potionTag).getValue());
|
||||
DataComponents components = itemStack.getDataComponents();
|
||||
if (components != null) {
|
||||
PotionContents potionContents = components.get(DataComponentType.POTION_CONTENTS);
|
||||
if (potionContents != null) {
|
||||
Potion potion = Potion.getByJavaId(potionContents.getPotionId());
|
||||
if (potion != null) {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, (int) potion.getBedrockId());
|
||||
dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, potion.getBedrockId());
|
||||
setFlag(EntityFlag.ENCHANTED, !NON_ENCHANTED_POTIONS.contains(potion));
|
||||
} else {
|
||||
dirtyMetadata.put(EntityDataTypes.EFFECT_COLOR, 0);
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionTag.getValue());
|
||||
dirtyMetadata.put(EntityDataTypes.AUX_VALUE_DATA, (short) 0);
|
||||
GeyserImpl.getInstance().getLogger().debug("Unknown java potion: " + potionContents.getPotionId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -34,6 +33,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,12 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -44,12 +43,12 @@ public class AgeableEntity extends CreatureEntity {
|
|||
protected void initializeMetadata() {
|
||||
super.initializeMetadata();
|
||||
// Required as of 1.19.3 Java
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, getAdultSize());
|
||||
setScale(getAdultSize());
|
||||
}
|
||||
|
||||
public void setBaby(BooleanEntityMetadata entityMetadata) {
|
||||
boolean isBaby = entityMetadata.getPrimitiveValue();
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, isBaby ? getBabySize() : getAdultSize());
|
||||
setScale(isBaby ? getBabySize() : getAdultSize());
|
||||
setFlag(EntityFlag.BABY, isBaby);
|
||||
|
||||
setBoundingBoxHeight(definition.height() * (isBaby ? getBabySize() : getAdultSize()));
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,10 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import lombok.Getter;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -43,6 +39,11 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
@ -99,11 +100,11 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean despawnEntity() {
|
||||
public void despawnEntity() {
|
||||
if (secondEntity != null) {
|
||||
secondEntity.despawnEntity();
|
||||
}
|
||||
return super.despawnEntity();
|
||||
super.despawnEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -257,38 +258,38 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setHelmet(ItemData helmet) {
|
||||
public void setHelmet(ItemStack helmet) {
|
||||
super.setHelmet(helmet);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChestplate(ItemData chestplate) {
|
||||
public void setChestplate(ItemStack chestplate) {
|
||||
super.setChestplate(chestplate);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLeggings(ItemData leggings) {
|
||||
public void setLeggings(ItemStack leggings) {
|
||||
super.setLeggings(leggings);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBoots(ItemData boots) {
|
||||
public void setBoots(ItemStack boots) {
|
||||
super.setBoots(boots);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHand(ItemData hand) {
|
||||
public void setHand(ItemStack hand) {
|
||||
super.setHand(hand);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOffHand(ItemData offHand) {
|
||||
super.setOffHand(offHand);
|
||||
public void setOffhand(ItemStack offHand) {
|
||||
super.setOffhand(offHand);
|
||||
updateSecondEntityStatus(true);
|
||||
}
|
||||
|
||||
|
@ -310,7 +311,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
if (!isInvisible) {
|
||||
// The armor stand isn't invisible. We good.
|
||||
setFlag(EntityFlag.INVISIBLE, false);
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, getScale());
|
||||
setScale(getScale());
|
||||
updateOffsetRequirement(false);
|
||||
|
||||
if (secondEntity != null) {
|
||||
|
@ -324,9 +325,9 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
}
|
||||
boolean isNametagEmpty = nametag.isEmpty();
|
||||
if (!isNametagEmpty && (!helmet.equals(ItemData.AIR) || !chestplate.equals(ItemData.AIR) || !leggings.equals(ItemData.AIR)
|
||||
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offHand.equals(ItemData.AIR))) {
|
||||
|| !boots.equals(ItemData.AIR) || !hand.equals(ItemData.AIR) || !offhand.equals(ItemData.AIR))) {
|
||||
// Reset scale of the proper armor stand
|
||||
this.dirtyMetadata.put(EntityDataTypes.SCALE, getScale());
|
||||
setScale(getScale());
|
||||
// Set the proper armor stand to invisible to show armor
|
||||
setFlag(EntityFlag.INVISIBLE, true);
|
||||
// Update the position of the armor stand
|
||||
|
@ -349,7 +350,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
// Guarantee this copy is NOT invisible
|
||||
secondEntity.setFlag(EntityFlag.INVISIBLE, false);
|
||||
// Scale to 0 to show nametag
|
||||
secondEntity.getDirtyMetadata().put(EntityDataTypes.SCALE, 0.0f);
|
||||
secondEntity.setScale(0f);
|
||||
// No bounding box as we don't want to interact with this entity
|
||||
secondEntity.getDirtyMetadata().put(EntityDataTypes.WIDTH, 0.0f);
|
||||
secondEntity.getDirtyMetadata().put(EntityDataTypes.HEIGHT, 0.0f);
|
||||
|
@ -359,7 +360,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
} else if (isNametagEmpty) {
|
||||
// We can just make an invisible entity
|
||||
// Reset scale of the proper armor stand
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, getScale());
|
||||
setScale(getScale());
|
||||
// Set the proper armor stand to invisible to show armor
|
||||
setFlag(EntityFlag.INVISIBLE, true);
|
||||
// Update offset
|
||||
|
@ -373,7 +374,7 @@ public class ArmorStandEntity extends LivingEntity {
|
|||
// Nametag is not empty and there is no armor
|
||||
// We don't need to make a new entity
|
||||
setFlag(EntityFlag.INVISIBLE, false);
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, 0.0f);
|
||||
setScale(0f);
|
||||
// As the above is applied, we need an offset
|
||||
updateOffsetRequirement(!isMarker);
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -49,7 +50,7 @@ public class DolphinEntity extends WaterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||
return InteractiveTag.FEED;
|
||||
}
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
|
@ -58,7 +59,7 @@ public class DolphinEntity extends WaterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().isFish(itemInHand)) {
|
||||
if (!itemInHand.isEmpty() && session.getTagCache().is(ItemTag.FISHES, itemInHand)) {
|
||||
// Feed
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -35,6 +34,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -40,6 +38,8 @@ import org.geysermc.geyser.item.type.SpawnEggItem;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
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.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -39,8 +38,8 @@ public class SlimeEntity extends MobEntity {
|
|||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setScale(IntEntityMetadata entityMetadata) {
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, 0.10f + entityMetadata.getPrimitiveValue());
|
||||
public void setSlimeScale(IntEntityMetadata entityMetadata) {
|
||||
setScale(0.10f + entityMetadata.getPrimitiveValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -36,6 +34,8 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -62,6 +62,6 @@ public class TadpoleEntity extends AbstractFishEntity {
|
|||
}
|
||||
|
||||
private boolean isFood(GeyserItemStack itemStack) {
|
||||
return itemStack.asItem() == Items.SLIME_BALL;
|
||||
return session.getTagCache().is(ItemTag.FROG_FOOD, itemStack);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,39 +25,40 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.AgeableEntity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class AnimalEntity extends AgeableEntity {
|
||||
public abstract class AnimalEntity extends AgeableEntity {
|
||||
|
||||
public AnimalEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public final boolean canEat(GeyserItemStack itemStack) {
|
||||
return canEat(itemStack.asItem());
|
||||
protected final boolean canEat(GeyserItemStack itemStack) {
|
||||
ItemTag tag = getFoodTag();
|
||||
if (tag == null) {
|
||||
return false;
|
||||
}
|
||||
return session.getTagCache().is(tag, itemStack);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this is a valid item to breed with for this animal.
|
||||
* @return the tag associated with this animal for eating food. Null for nothing or different behavior.
|
||||
*/
|
||||
public boolean canEat(Item item) {
|
||||
// This is what it defaults to. OK.
|
||||
return item == Items.WHEAT;
|
||||
}
|
||||
protected abstract @Nullable ItemTag getFoodTag();
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* Copyright (c) 2019-2024 GeyserMC. http://geysermc.org
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* @author GeyserMC
|
||||
* @link https://github.com/GeyserMC/Geyser
|
||||
*/
|
||||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.ArmadilloState;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ArmadilloEntity extends AnimalEntity {
|
||||
private ArmadilloState armadilloState = ArmadilloState.IDLE;
|
||||
|
||||
public ArmadilloEntity(GeyserSession session, int entityId, long geyserId, UUID uuid,
|
||||
EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
public void setArmadilloState(ObjectEntityMetadata<ArmadilloState> entityMetadata) {
|
||||
armadilloState = entityMetadata.getValue();
|
||||
|
||||
switch (armadilloState) {
|
||||
case IDLE -> propertyManager.add("minecraft:armadillo_state", "unrolled");
|
||||
case ROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up");
|
||||
case SCARED -> propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing");
|
||||
case UNROLLING -> propertyManager.add("minecraft:armadillo_state", "rolled_up_unrolling");
|
||||
}
|
||||
|
||||
updateBedrockEntityProperties();
|
||||
}
|
||||
|
||||
public void onPeeking() {
|
||||
// Technically we should wait if not currently scared
|
||||
if (armadilloState == ArmadilloState.SCARED) {
|
||||
propertyManager.add("minecraft:armadillo_state", "rolled_up_peeking");
|
||||
updateBedrockEntityProperties();
|
||||
|
||||
// Needed for consecutive peeks
|
||||
session.scheduleInEventLoop(() -> {
|
||||
if (armadilloState == ArmadilloState.SCARED) {
|
||||
propertyManager.add("minecraft:armadillo_state", "rolled_up_relaxing");
|
||||
updateBedrockEntityProperties();
|
||||
}
|
||||
}, 250, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.ARMADILLO_FOOD;
|
||||
}
|
||||
}
|
|
@ -25,19 +25,20 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
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.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
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;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -60,8 +61,9 @@ public class AxolotlEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isAxolotlTemptItem(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.AXOLOTL_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,16 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -57,7 +58,8 @@ public class BeeEntity extends AnimalEntity {
|
|||
// If the bee has stung
|
||||
dirtyMetadata.put(EntityDataTypes.MARK_VARIANT, (xd & 0x04) == 0x04 ? 1 : 0);
|
||||
// If the bee has nectar or not
|
||||
setFlag(EntityFlag.POWERED, (xd & 0x08) == 0x08);
|
||||
propertyManager.add("minecraft:has_nectar", (xd & 0x08) == 0x08);
|
||||
updateBedrockEntityProperties();
|
||||
}
|
||||
|
||||
public void setAngerTime(IntEntityMetadata entityMetadata) {
|
||||
|
@ -66,7 +68,8 @@ public class BeeEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isFlower(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.BEE_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,24 +25,23 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChickenEntity extends AnimalEntity {
|
||||
private static final Set<Item> VALID_FOOD = Set.of(Items.WHEAT_SEEDS, Items.MELON_SEEDS, Items.PUMPKIN_SEEDS, Items.BEETROOT_SEEDS);
|
||||
|
||||
public ChickenEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return VALID_FOOD.contains(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.CHICKEN_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -34,8 +34,10 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -64,4 +66,10 @@ public class CowEntity extends AnimalEntity {
|
|||
session.playSoundEvent(SoundEvent.MILK, position);
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.COW_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,14 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -55,7 +56,8 @@ public class FoxEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isFoxFood(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.FOX_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
|
@ -76,7 +76,8 @@ public class FrogEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.SLIME_BALL;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.FROG_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
|
@ -37,7 +35,11 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -94,4 +96,10 @@ public class GoatEntity extends AnimalEntity {
|
|||
private void setHornCount() {
|
||||
dirtyMetadata.put(EntityDataTypes.GOAT_HORN_COUNT, (hasLeftHorn ? 1 : 0) + (hasRightHorn ? 1 : 0));
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.GOAT_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,13 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -40,6 +41,8 @@ public class HoglinEntity extends AnimalEntity {
|
|||
|
||||
public HoglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
dirtyMetadata.put(EntityDataTypes.TARGET_EID, session.getPlayerEntity().getGeyserId());
|
||||
setFlag(EntityFlag.SHAKING, isShaking());
|
||||
}
|
||||
|
||||
public void setImmuneToZombification(BooleanEntityMetadata entityMetadata) {
|
||||
|
@ -54,8 +57,9 @@ public class HoglinEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.CRIMSON_FUNGUS;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.HOGLIN_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,4 +71,9 @@ public class HoglinEntity extends AnimalEntity {
|
|||
protected boolean isEnemy() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useArmSwingAttack() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,22 +25,22 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.FlowerItem;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class MooshroomEntity extends AnimalEntity {
|
||||
public class MooshroomEntity extends CowEntity {
|
||||
private boolean isBrown = false;
|
||||
|
||||
public MooshroomEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
|
@ -77,7 +77,7 @@ public class MooshroomEntity extends AnimalEntity {
|
|||
} else if (!isBaby && isAlive() && itemInHand.asItem() == Items.SHEARS) {
|
||||
// Shear items
|
||||
return InteractionResult.SUCCESS;
|
||||
} else if (isBrown && session.getTagCache().isSmallFlower(itemInHand) && itemInHand.asItem() instanceof FlowerItem) {
|
||||
} else if (isBrown && session.getTagCache().is(ItemTag.SMALL_FLOWERS, itemInHand)) {
|
||||
// ?
|
||||
return InteractionResult.SUCCESS;
|
||||
}
|
||||
|
|
|
@ -25,17 +25,17 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -46,8 +46,9 @@ public class OcelotEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.COD || item == Items.SALMON;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.OCELOT_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -37,11 +34,13 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -62,7 +61,8 @@ public class PandaEntity extends AnimalEntity {
|
|||
EntityEventPacket packet = new EntityEventPacket();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.setType(EntityEventType.EATING_ITEM);
|
||||
packet.setData(session.getItemMappings().getStoredItems().bamboo().getBedrockDefinition().getRuntimeId() << 16);
|
||||
// As of 1.20.5 - pandas can eat cake
|
||||
packet.setData(this.hand.getDefinition().getRuntimeId() << 16);
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
|
@ -89,8 +89,9 @@ public class PandaEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.BAMBOO;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.PANDA_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,18 +25,18 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -47,8 +47,9 @@ public class PigEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.CARROT || item == Items.POTATO || item == Items.BEETROOT;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.PIG_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -39,7 +40,8 @@ public class PolarBearEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return false;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.AbstractFishEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -67,7 +67,8 @@ public class RabbitEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.DANDELION || item == Items.CARROT || item == Items.GOLDEN_CARROT;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.RABBIT_FOOD;
|
||||
}
|
||||
}
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -36,8 +35,11 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -55,6 +57,12 @@ public class SheepEntity extends AnimalEntity {
|
|||
dirtyMetadata.put(EntityDataTypes.COLOR, (byte) color);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.SHEEP_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.SnifferState;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.LevelEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
|
@ -37,8 +35,11 @@ import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEventPacket;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.EntityDefinitions;
|
||||
import org.geysermc.geyser.entity.type.Tickable;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.SnifferState;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ObjectEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -71,8 +72,9 @@ public class SnifferEntity extends AnimalEntity implements Tickable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return session.getTagCache().isSnifferFood(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.SNIFFER_FOOD;
|
||||
}
|
||||
|
||||
public void setSnifferState(ObjectEntityMetadata<SnifferState> entityMetadata) {
|
||||
|
|
|
@ -25,20 +25,20 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.EntityUtils;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -94,8 +94,9 @@ public class StriderEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.WARPED_FUNGUS;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.STRIDER_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,14 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.AbstractFishEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
|
|
@ -25,13 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -50,8 +50,9 @@ public class TurtleEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.SEAGRASS;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.TURTLE_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,9 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
|
@ -40,21 +39,16 @@ import org.geysermc.geyser.entity.attribute.GeyserAttributeType;
|
|||
import org.geysermc.geyser.entity.type.living.animal.AnimalEntity;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AbstractHorseEntity extends AnimalEntity {
|
||||
/**
|
||||
* A list of all foods a horse/donkey can eat on Java Edition.
|
||||
* Used to display interactive tag if needed.
|
||||
*/
|
||||
private static final Set<Item> DONKEY_AND_HORSE_FOODS = Set.of(Items.GOLDEN_APPLE, Items.ENCHANTED_GOLDEN_APPLE,
|
||||
Items.GOLDEN_CARROT, Items.SUGAR, Items.APPLE, Items.WHEAT, Items.HAY_BLOCK);
|
||||
|
||||
public AbstractHorseEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
@ -124,8 +118,9 @@ public class AbstractHorseEntity extends AnimalEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return DONKEY_AND_HORSE_FOODS.contains(item);
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.HORSE_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,9 +25,7 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.Pose;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
|
@ -35,9 +33,11 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerType;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.Item;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.Pose;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -90,8 +90,8 @@ public class CamelEntity extends AbstractHorseEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.CACTUS;
|
||||
protected @Nullable ItemTag getFoodTag() {
|
||||
return ItemTag.CAMEL_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
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.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,19 +25,24 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MobArmorEquipmentPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.MathUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LlamaEntity extends ChestedHorseEntity {
|
||||
/**
|
||||
* Used to calculate inventory size
|
||||
*/
|
||||
@Getter
|
||||
private int strength = 1;
|
||||
|
||||
public LlamaEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
@ -45,32 +50,13 @@ public class LlamaEntity extends ChestedHorseEntity {
|
|||
dirtyMetadata.put(EntityDataTypes.CONTAINER_STRENGTH_MODIFIER, 3); // Presumably 3 slots for every 1 strength
|
||||
}
|
||||
|
||||
/**
|
||||
* Color equipped on the llama
|
||||
*/
|
||||
public void setCarpetedColor(IntEntityMetadata entityMetadata) {
|
||||
// Bedrock treats llama decoration as armor
|
||||
MobArmorEquipmentPacket equipmentPacket = new MobArmorEquipmentPacket();
|
||||
equipmentPacket.setRuntimeEntityId(geyserId);
|
||||
// -1 means no armor
|
||||
int carpetIndex = entityMetadata.getPrimitiveValue();
|
||||
if (carpetIndex > -1 && carpetIndex <= 15) {
|
||||
// The damage value is the dye color that Java sends us, for pre-1.16.220
|
||||
// The item is always going to be a carpet
|
||||
equipmentPacket.setChestplate(session.getItemMappings().getCarpets().get(carpetIndex));
|
||||
} else {
|
||||
equipmentPacket.setChestplate(ItemData.AIR);
|
||||
}
|
||||
// Required to fill out the rest of the equipment or Bedrock ignores it, including above else statement if removing armor
|
||||
equipmentPacket.setBoots(ItemData.AIR);
|
||||
equipmentPacket.setHelmet(ItemData.AIR);
|
||||
equipmentPacket.setLeggings(ItemData.AIR);
|
||||
|
||||
session.sendUpstreamPacket(equipmentPacket);
|
||||
public void setStrength(IntEntityMetadata entityMetadata) {
|
||||
strength = MathUtils.constrain(entityMetadata.getPrimitiveValue(), 1, 5);
|
||||
this.dirtyMetadata.put(EntityDataTypes.STRENGTH, strength);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.WHEAT || item == Items.HAY_BLOCK;
|
||||
protected @Nullable ItemTag getFoodTag() {
|
||||
return ItemTag.LLAMA_FOOD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.horse;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
@ -33,6 +32,7 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,27 +25,27 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.tameable;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class CatEntity extends TameableEntity {
|
||||
|
||||
private byte collarColor;
|
||||
private byte collarColor = 14; // Red - default
|
||||
|
||||
public CatEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
@ -76,10 +76,7 @@ public class CatEntity extends TameableEntity {
|
|||
@Override
|
||||
public void setTameableFlags(ByteEntityMetadata entityMetadata) {
|
||||
super.setTameableFlags(entityMetadata);
|
||||
// Update collar color if tamed
|
||||
if (getFlag(EntityFlag.TAMED)) {
|
||||
dirtyMetadata.put(EntityDataTypes.COLOR, collarColor);
|
||||
}
|
||||
updateCollarColor();
|
||||
}
|
||||
|
||||
public void setCatVariant(IntEntityMetadata entityMetadata) {
|
||||
|
@ -101,6 +98,10 @@ public class CatEntity extends TameableEntity {
|
|||
|
||||
public void setCollarColor(IntEntityMetadata entityMetadata) {
|
||||
collarColor = (byte) entityMetadata.getPrimitiveValue();
|
||||
updateCollarColor();
|
||||
}
|
||||
|
||||
private void updateCollarColor() {
|
||||
// Needed or else wild cats are a red color
|
||||
if (getFlag(EntityFlag.TAMED)) {
|
||||
dirtyMetadata.put(EntityDataTypes.COLOR, collarColor);
|
||||
|
@ -108,8 +109,8 @@ public class CatEntity extends TameableEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return item == Items.COD || item == Items.SALMON;
|
||||
protected @Nullable ItemTag getFoodTag() {
|
||||
return ItemTag.CAT_FOOD;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.tameable;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
|
@ -34,8 +34,10 @@ import org.geysermc.geyser.inventory.GeyserItemStack;
|
|||
import org.geysermc.geyser.item.Items;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
@ -49,16 +51,17 @@ public class ParrotEntity extends TameableEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
return false;
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isTameFood(Item item) {
|
||||
return TAMING_FOOD.contains(item);
|
||||
return session.getTagCache().is(ItemTag.PARROT_FOOD, item);
|
||||
}
|
||||
|
||||
private boolean isPoisonousFood(Item item) {
|
||||
return item == Items.COOKIE;
|
||||
return session.getTagCache().is(ItemTag.PARROT_POISONOUS_FOOD, item);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
|
|
@ -25,21 +25,21 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.tameable;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import lombok.Getter;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import lombok.Getter;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.entity.type.living.animal.AnimalEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public class TameableEntity extends AnimalEntity {
|
||||
public abstract class TameableEntity extends AnimalEntity {
|
||||
/**
|
||||
* Used in the interactive tag manager to track if the session player owns this entity
|
||||
*/
|
||||
|
|
|
@ -25,22 +25,31 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.animal.tameable;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.UpdateAttributesPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.inventory.item.Enchantment;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.item.type.DyeItem;
|
||||
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.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.geyser.util.ItemUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
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.item.ItemStack;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -54,7 +63,9 @@ public class WolfEntity extends TameableEntity {
|
|||
Items.PORKCHOP, Items.BEEF, Items.RABBIT, Items.COOKED_PORKCHOP, Items.COOKED_BEEF, Items.ROTTEN_FLESH, Items.MUTTON, Items.COOKED_MUTTON,
|
||||
Items.COOKED_RABBIT);
|
||||
|
||||
private byte collarColor;
|
||||
private byte collarColor = 14; // Red - default
|
||||
|
||||
private boolean isCurseOfBinding = false;
|
||||
|
||||
public WolfEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
|
@ -64,19 +75,27 @@ public class WolfEntity extends TameableEntity {
|
|||
public void setTameableFlags(ByteEntityMetadata entityMetadata) {
|
||||
super.setTameableFlags(entityMetadata);
|
||||
// Reset wolf color
|
||||
byte xd = entityMetadata.getPrimitiveValue();
|
||||
boolean angry = (xd & 0x02) == 0x02;
|
||||
if (angry) {
|
||||
if (getFlag(EntityFlag.ANGRY)) {
|
||||
dirtyMetadata.put(EntityDataTypes.COLOR, (byte) 0);
|
||||
} else if (getFlag(EntityFlag.TAMED)) {
|
||||
updateCollarColor();
|
||||
|
||||
// This fixes tail angle when taming
|
||||
UpdateAttributesPacket packet = new UpdateAttributesPacket();
|
||||
packet.setRuntimeEntityId(geyserId);
|
||||
packet.setAttributes(Collections.singletonList(createHealthAttribute()));
|
||||
session.sendUpstreamPacket(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public void setCollarColor(IntEntityMetadata entityMetadata) {
|
||||
collarColor = (byte) entityMetadata.getPrimitiveValue();
|
||||
if (getFlag(EntityFlag.ANGRY)) {
|
||||
return;
|
||||
if (!getFlag(EntityFlag.ANGRY) && getFlag(EntityFlag.TAMED)) {
|
||||
updateCollarColor();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCollarColor() {
|
||||
dirtyMetadata.put(EntityDataTypes.COLOR, collarColor);
|
||||
if (ownerBedrockId == 0) {
|
||||
// If a color is set and there is no owner entity ID, set one.
|
||||
|
@ -92,10 +111,25 @@ public class WolfEntity extends TameableEntity {
|
|||
dirtyMetadata.put(EntityDataTypes.COLOR, time != 0 ? (byte) 0 : collarColor);
|
||||
}
|
||||
|
||||
// 1.20.5+
|
||||
public void setWolfVariant(IntEntityMetadata entityMetadata) {
|
||||
WolfVariant wolfVariant = session.getRegistryCache().wolfVariants().byId(entityMetadata.getPrimitiveValue());
|
||||
if (wolfVariant == null) {
|
||||
wolfVariant = WolfVariant.PALE;
|
||||
}
|
||||
dirtyMetadata.put(EntityDataTypes.VARIANT, wolfVariant.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canEat(Item item) {
|
||||
// Cannot be a baby to eat these foods
|
||||
return WOLF_FOODS.contains(item) && !isBaby();
|
||||
@Nullable
|
||||
protected ItemTag getFoodTag() {
|
||||
return ItemTag.WOLF_FOOD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChestplate(ItemStack stack) {
|
||||
super.setChestplate(stack);
|
||||
isCurseOfBinding = ItemUtils.getEnchantmentLevel(stack.getDataComponents(), Enchantment.JavaEnchantment.BINDING_CURSE) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -112,16 +146,30 @@ public class WolfEntity extends TameableEntity {
|
|||
if (itemInHand.asItem() == Items.BONE && !getFlag(EntityFlag.TAMED)) {
|
||||
// Bone and untamed - can tame
|
||||
return InteractiveTag.TAME;
|
||||
} else {
|
||||
if (itemInHand.asItem() instanceof DyeItem item) {
|
||||
}
|
||||
if (getFlag(EntityFlag.TAMED) && ownerBedrockId == session.getPlayerEntity().getGeyserId()) {
|
||||
if (itemInHand.asItem() instanceof DyeItem dyeItem) {
|
||||
// If this fails, as of Java Edition 1.18.1, you cannot toggle sit/stand
|
||||
if (item.dyeColor() != this.collarColor) {
|
||||
if (dyeItem.dyeColor() != this.collarColor) {
|
||||
return InteractiveTag.DYE;
|
||||
} else {
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
}
|
||||
} else if (getFlag(EntityFlag.TAMED) && ownerBedrockId == session.getPlayerEntity().getGeyserId()) {
|
||||
// Tamed and owned by player - can sit/stand
|
||||
return getFlag(EntityFlag.SITTING) ? InteractiveTag.STAND : InteractiveTag.SIT;
|
||||
}
|
||||
if (itemInHand.asItem() == Items.WOLF_ARMOR && !this.chestplate.isValid() && !getFlag(EntityFlag.BABY)) {
|
||||
return InteractiveTag.EQUIP_WOLF_ARMOR;
|
||||
}
|
||||
if (itemInHand.asItem() == Items.SHEARS && this.chestplate.isValid()
|
||||
&& (!isCurseOfBinding || session.getGameMode().equals(GameMode.CREATIVE))) {
|
||||
return InteractiveTag.REMOVE_WOLF_ARMOR;
|
||||
}
|
||||
if (Items.WOLF_ARMOR.isValidRepairItem(itemInHand.asItem()) && getFlag(EntityFlag.SITTING) &&
|
||||
this.chestplate.isValid() && this.chestplate.getTag() != null &&
|
||||
this.chestplate.getTag().getInt("Damage") > 0) {
|
||||
return InteractiveTag.REPAIR_WOLF_ARMOR;
|
||||
}
|
||||
// Tamed and owned by player - can sit/stand
|
||||
return getFlag(EntityFlag.SITTING) ? InteractiveTag.STAND : InteractiveTag.SIT;
|
||||
}
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
}
|
||||
|
@ -137,4 +185,34 @@ public class WolfEntity extends TameableEntity {
|
|||
return InteractionResult.PASS;
|
||||
}
|
||||
}
|
||||
|
||||
// Ordered by bedrock id
|
||||
public enum WolfVariant {
|
||||
PALE,
|
||||
ASHEN,
|
||||
BLACK,
|
||||
CHESTNUT,
|
||||
RUSTY,
|
||||
SNOWY,
|
||||
SPOTTED,
|
||||
STRIPED,
|
||||
WOODS;
|
||||
|
||||
private static final WolfVariant[] VALUES = values();
|
||||
|
||||
private final String javaIdentifier;
|
||||
|
||||
WolfVariant() {
|
||||
this.javaIdentifier = "minecraft:" + this.name().toLowerCase(Locale.ROOT);
|
||||
}
|
||||
|
||||
public static @Nullable WolfVariant getByJavaIdentifier(String javaIdentifier) {
|
||||
for (WolfVariant wolfVariant : VALUES) {
|
||||
if (wolfVariant.javaIdentifier.equals(javaIdentifier)) {
|
||||
return wolfVariant;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.merchant;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
|
@ -37,6 +36,7 @@ import org.geysermc.geyser.item.Items;
|
|||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.merchant;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.VillagerData;
|
||||
import lombok.Getter;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
|
@ -38,6 +36,8 @@ import org.geysermc.geyser.entity.EntityDefinition;
|
|||
import org.geysermc.geyser.registry.BlockRegistries;
|
||||
import org.geysermc.geyser.registry.type.BlockMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.VillagerData;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
|
|
@ -25,11 +25,13 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.ItemDefinition;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -45,5 +47,17 @@ public class AbstractSkeletonEntity extends MonsterEntity {
|
|||
byte xd = entityMetadata.getPrimitiveValue();
|
||||
// A bit of a loophole so the hands get raised - set the target ID to its own ID
|
||||
dirtyMetadata.put(EntityDataTypes.TARGET_EID, ((xd & 4) == 4) ? geyserId : 0);
|
||||
|
||||
if ((xd & 4) == 4) {
|
||||
ItemDefinition bow = session.getItemMappings().getStoredItems().bow().getBedrockDefinition();
|
||||
setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, this.hand.getDefinition() == bow || this.offhand.getDefinition() == bow);
|
||||
} else {
|
||||
setFlag(EntityFlag.FACING_TARGET_TO_RANGE_ATTACK, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useArmSwingAttack() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,14 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.type.EntityType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -38,6 +41,16 @@ public class BasePiglinEntity extends MonsterEntity {
|
|||
|
||||
public BasePiglinEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
// Both TARGET_EID and BLOCK are needed for melee attack animation
|
||||
dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(1));
|
||||
setFlag(EntityFlag.SHAKING, isShaking());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMobFlags(ByteEntityMetadata entityMetadata) {
|
||||
super.setMobFlags(entityMetadata);
|
||||
byte xd = entityMetadata.getPrimitiveValue();
|
||||
dirtyMetadata.put(EntityDataTypes.TARGET_EID, (xd & 4) == 4 ? session.getPlayerEntity().getGeyserId() : 0);
|
||||
}
|
||||
|
||||
public void setImmuneToZombification(BooleanEntityMetadata entityMetadata) {
|
||||
|
@ -50,4 +63,9 @@ public class BasePiglinEntity extends MonsterEntity {
|
|||
protected boolean isShaking() {
|
||||
return (!isImmuneToZombification && !session.getDimensionType().piglinSafe()) || super.isShaking();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useArmSwingAttack() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,9 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
|
@ -35,8 +32,12 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
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;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -65,7 +66,7 @@ public class CreeperEntity extends MonsterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractiveTag testMobInteraction(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) {
|
||||
if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) {
|
||||
return InteractiveTag.IGNITE_CREEPER;
|
||||
} else {
|
||||
return super.testMobInteraction(hand, itemInHand);
|
||||
|
@ -75,7 +76,7 @@ public class CreeperEntity extends MonsterEntity {
|
|||
@NonNull
|
||||
@Override
|
||||
protected InteractionResult mobInteract(@NonNull Hand hand, @NonNull GeyserItemStack itemInHand) {
|
||||
if (session.getTagCache().isCreeperIgniter(itemInHand.asItem())) {
|
||||
if (session.getTagCache().is(ItemTag.CREEPER_IGNITERS, itemInHand)) {
|
||||
// Ignite creeper - as of 1.19.3
|
||||
session.playSoundEvent(SoundEvent.IGNITE, position);
|
||||
return InteractionResult.SUCCESS;
|
||||
|
|
|
@ -25,23 +25,19 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import lombok.Data;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.ParticleType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityEventType;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.AddEntityPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.EntityEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.LevelEventPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.PlaySoundPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.SpawnParticleEffectPacket;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.*;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Tickable;
|
||||
import org.geysermc.geyser.entity.type.living.MobEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.util.DimensionUtils;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.FloatEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
|
@ -148,11 +144,11 @@ public class EnderDragonEntity extends MobEntity implements Tickable {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean despawnEntity() {
|
||||
public void despawnEntity() {
|
||||
for (EnderDragonPartEntity part : allParts) {
|
||||
part.despawnEntity();
|
||||
}
|
||||
return super.despawnEntity();
|
||||
super.despawnEntity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.SoundEvent;
|
||||
import org.cloudburstmc.protocol.bedrock.data.definitions.BlockDefinition;
|
||||
|
@ -35,6 +33,8 @@ import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
|||
import org.cloudburstmc.protocol.bedrock.packet.LevelSoundEvent2Packet;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.FlyingEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -36,7 +35,11 @@ public class GiantEntity extends MonsterEntity {
|
|||
|
||||
public GiantEntity(GeyserSession session, int entityId, long geyserId, UUID uuid, EntityDefinition<?> definition, Vector3f position, Vector3f motion, float yaw, float pitch, float headYaw) {
|
||||
super(session, entityId, geyserId, uuid, definition, position, motion, yaw, pitch, headYaw);
|
||||
}
|
||||
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, 6f);
|
||||
@Override
|
||||
protected void initializeMetadata() {
|
||||
super.initializeMetadata();
|
||||
setScale(6f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,12 +25,12 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.Entity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
|
@ -25,12 +25,11 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.FlyingEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.IntEntityMetadata;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -46,7 +45,7 @@ public class PhantomEntity extends FlyingEntity {
|
|||
|
||||
setBoundingBoxWidth(boundsScale * definition.width());
|
||||
setBoundingBoxHeight(boundsScale * definition.height());
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, modelScale);
|
||||
setScale(modelScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,18 +25,24 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ContainerId;
|
||||
import org.cloudburstmc.protocol.bedrock.data.inventory.ItemData;
|
||||
import org.cloudburstmc.protocol.bedrock.packet.MobEquipmentPacket;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.inventory.GeyserItemStack;
|
||||
import org.geysermc.geyser.item.Items;
|
||||
import org.geysermc.geyser.registry.type.ItemMapping;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.geyser.session.cache.tags.ItemTag;
|
||||
import org.geysermc.geyser.util.InteractionResult;
|
||||
import org.geysermc.geyser.util.InteractiveTag;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.BooleanEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.player.Hand;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.item.ItemStack;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -48,24 +54,72 @@ public class PiglinEntity extends BasePiglinEntity {
|
|||
|
||||
public void setBaby(BooleanEntityMetadata entityMetadata) {
|
||||
boolean isBaby = entityMetadata.getPrimitiveValue();
|
||||
dirtyMetadata.put(EntityDataTypes.SCALE, isBaby? .55f : 1f);
|
||||
setScale(isBaby? .55f : 1f);
|
||||
setFlag(EntityFlag.BABY, isBaby);
|
||||
|
||||
updateMountOffset();
|
||||
}
|
||||
|
||||
public void setChargingCrossbow(BooleanEntityMetadata entityMetadata) {
|
||||
setFlag(EntityFlag.CHARGING, entityMetadata.getPrimitiveValue());
|
||||
boolean charging = entityMetadata.getPrimitiveValue();
|
||||
setFlag(EntityFlag.CHARGING, charging);
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, charging ? (byte) 64 : (byte) 0); // TODO: gradually increase
|
||||
}
|
||||
|
||||
public void setDancing(BooleanEntityMetadata entityMetadata) {
|
||||
setFlag(EntityFlag.DANCING, entityMetadata.getPrimitiveValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHand(ItemStack stack) {
|
||||
ItemMapping crossbow = session.getItemMappings().getStoredItems().crossbow();
|
||||
boolean toCrossbow = stack != null && stack.getId() == crossbow.getJavaItem().javaId();
|
||||
|
||||
if (toCrossbow ^ this.hand.getDefinition() == crossbow.getBedrockDefinition()) { // If switching to/from crossbow
|
||||
dirtyMetadata.put(EntityDataTypes.BLOCK, session.getBlockMappings().getDefinition(toCrossbow ? 0 : 1));
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0);
|
||||
setFlag(EntityFlag.CHARGED, false);
|
||||
setFlag(EntityFlag.USING_ITEM, false);
|
||||
updateBedrockMetadata();
|
||||
|
||||
if (this.hand.isValid()) {
|
||||
MobEquipmentPacket mobEquipmentPacket = new MobEquipmentPacket();
|
||||
mobEquipmentPacket.setRuntimeEntityId(geyserId);
|
||||
mobEquipmentPacket.setContainerId(ContainerId.INVENTORY);
|
||||
mobEquipmentPacket.setInventorySlot(0);
|
||||
mobEquipmentPacket.setHotbarSlot(-1);
|
||||
mobEquipmentPacket.setItem(ItemData.AIR);
|
||||
session.sendUpstreamPacket(mobEquipmentPacket);
|
||||
}
|
||||
}
|
||||
|
||||
super.setHand(stack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateMainHand(GeyserSession session) {
|
||||
super.updateMainHand(session);
|
||||
|
||||
if (this.hand.getDefinition() == session.getItemMappings().getStoredItems().crossbow().getBedrockDefinition()) {
|
||||
if (this.hand.getTag() != null && this.hand.getTag().containsKey("chargedItem")) {
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, Byte.MAX_VALUE);
|
||||
setFlag(EntityFlag.CHARGING, false);
|
||||
setFlag(EntityFlag.CHARGED, true);
|
||||
setFlag(EntityFlag.USING_ITEM, true);
|
||||
} else if (getFlag(EntityFlag.CHARGED)) {
|
||||
dirtyMetadata.put(EntityDataTypes.CHARGE_AMOUNT, (byte) 0);
|
||||
setFlag(EntityFlag.CHARGED, false);
|
||||
setFlag(EntityFlag.USING_ITEM, false);
|
||||
}
|
||||
}
|
||||
|
||||
updateBedrockMetadata();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOffHand(GeyserSession session) {
|
||||
// Check if the Piglin is holding Gold and set the ADMIRING flag accordingly so its pose updates
|
||||
setFlag(EntityFlag.ADMIRING, session.getTagCache().shouldPiglinAdmire(session.getItemMappings().getMapping(this.offHand).getJavaItem()));
|
||||
setFlag(EntityFlag.ADMIRING, session.getTagCache().is(ItemTag.PIGLIN_LOVED, session.getItemMappings().getMapping(this.offhand).getJavaItem()));
|
||||
super.updateBedrockMetadata();
|
||||
|
||||
super.updateOffHand(session);
|
||||
|
|
|
@ -25,15 +25,15 @@
|
|||
|
||||
package org.geysermc.geyser.entity.type.living.monster;
|
||||
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import com.github.steveice10.mc.protocol.data.game.entity.object.Direction;
|
||||
import org.cloudburstmc.math.vector.Vector3f;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityDataTypes;
|
||||
import org.cloudburstmc.protocol.bedrock.data.entity.EntityFlag;
|
||||
import org.geysermc.geyser.entity.EntityDefinition;
|
||||
import org.geysermc.geyser.entity.type.living.GolemEntity;
|
||||
import org.geysermc.geyser.session.GeyserSession;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.EntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.metadata.type.ByteEntityMetadata;
|
||||
import org.geysermc.mcprotocollib.protocol.data.game.entity.object.Direction;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue