Stored Bee API

This commit is contained in:
EOT3000
2025-01-12 17:39:50 -08:00
committed by granny
parent 7e8af548ea
commit 9235733eca
7 changed files with 312 additions and 344 deletions

View File

@@ -9,3 +9,48 @@
private static final int MIN_TICKS_BEFORE_REENTERING_HIVE = 400;
private static final int MIN_OCCUPATION_TICKS_NECTAR = 2400;
public static final int MIN_OCCUPATION_TICKS_NECTARLESS = 600;
@@ -154,11 +_,33 @@
return list;
}
+ // Purpur start - Stored Bee API
+ public List<Entity> releaseBee(BlockState iblockdata, BeehiveBlockEntity.BeeData data, BeehiveBlockEntity.BeeReleaseStatus tileentitybeehive_releasestatus, boolean force) {
+ List<Entity> list = Lists.newArrayList();
+
+ BeehiveBlockEntity.releaseOccupant(this.level, this.worldPosition, iblockdata, data.occupant, list, tileentitybeehive_releasestatus, this.savedFlowerPos, force);
+
+ if (!list.isEmpty()) {
+ stored.remove(data);
+
+ super.setChanged();
+ }
+
+ return list;
+ }
+ // Purpur end - Stored Bee API
+
@VisibleForDebug
public int getOccupantCount() {
return this.stored.size();
}
+ // Purpur start - Stored Bee API
+ public List<BeeData> getStored() {
+ return stored;
+ }
+ // Purpur end - Stored Bee API
+
// Paper start - Add EntityBlockStorage clearEntities
public void clearBees() {
this.stored.clear();
@@ -408,8 +_,8 @@
return this.stored.stream().map(BeehiveBlockEntity.BeeData::toOccupant).toList();
}
- static class BeeData {
- private final BeehiveBlockEntity.Occupant occupant;
+ public static class BeeData { // Purpur - make public - Stored Bee API
+ public final BeehiveBlockEntity.Occupant occupant; // Purpur - make public - Stored Bee API
private int exitTickCounter; // Paper - Fix bees aging inside hives; separate counter for checking if bee should exit to reduce exit attempts
private int ticksInHive;

View File

@@ -0,0 +1,81 @@
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java
@@ -16,8 +_,15 @@
public class CraftBeehive extends CraftBlockEntityState<BeehiveBlockEntity> implements Beehive {
+ private final List<org.purpurmc.purpur.entity.StoredEntity<Bee>> storage = new ArrayList<>(); // Purpur - Stored Bee API
+
public CraftBeehive(World world, BeehiveBlockEntity tileEntity) {
super(world, tileEntity);
+ // Purpur start - load bees to be able to modify them individually - Stored Bee API
+ for(BeehiveBlockEntity.BeeData data : tileEntity.getStored()) {
+ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(data, this));
+ }
+ // Purpur end - Stored Bee API
}
protected CraftBeehive(CraftBeehive state, Location location) {
@@ -76,14 +_,54 @@
}
}
+ storage.clear(); // Purpur - Stored Bee API
return bees;
}
+ // Purpur start - Stored Bee API
+ @Override
+ public Bee releaseEntity(org.purpurmc.purpur.entity.StoredEntity<Bee> entity) {
+ ensureNoWorldGeneration();
+
+ if(!getEntities().contains(entity)) {
+ return null;
+ }
+
+ if(isPlaced()) {
+ BeehiveBlockEntity beehive = ((BeehiveBlockEntity) this.getTileEntityFromWorld());
+ BeehiveBlockEntity.BeeData data = ((org.purpurmc.purpur.entity.PurpurStoredBee) entity).getHandle();
+
+ List<Entity> list = beehive.releaseBee(getHandle(), data, BeeReleaseStatus.BEE_RELEASED, true);
+
+ if (list.size() == 1) {
+ storage.remove(entity);
+
+ return (Bee) list.get(0).getBukkitEntity();
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public List<org.purpurmc.purpur.entity.StoredEntity<Bee>> getEntities() {
+ return new ArrayList<>(storage);
+ }
+ // Purpur end - Stored Bee API
+
@Override
public void addEntity(Bee entity) {
Preconditions.checkArgument(entity != null, "Entity must not be null");
+ int length = this.getSnapshot().getStored().size(); // Purpur - Stored Bee API
this.getSnapshot().addOccupant(((CraftBee) entity).getHandle());
+
+ // Purpur start - check if new bee was added, and if yes, add to stored bees - Stored Bee API
+ List<BeehiveBlockEntity.BeeData> storedBeeData = this.getSnapshot().getStored();
+ if(length < storedBeeData.size()) {
+ storage.add(new org.purpurmc.purpur.entity.PurpurStoredBee(storedBeeData.getLast(), this));
+ }
+ // Purpur end - Stored Bee API
}
@Override
@@ -100,6 +_,7 @@
@Override
public void clearEntities() {
getSnapshot().clearBees();
+ storage.clear(); // Purpur - Stored Bee API
}
// Paper end
}

View File

@@ -0,0 +1,106 @@
package org.purpurmc.purpur.entity;
import io.papermc.paper.adventure.PaperAdventure;
import net.kyori.adventure.text.Component;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.level.block.entity.BeehiveBlockEntity;
import org.bukkit.block.EntityBlockStorage;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer;
import org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry;
import org.bukkit.entity.Bee;
import org.bukkit.entity.EntityType;
import org.bukkit.persistence.PersistentDataContainer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Locale;
public class PurpurStoredBee implements StoredEntity<Bee> {
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
private final EntityBlockStorage<Bee> blockStorage;
private final BeehiveBlockEntity.BeeData handle;
private final CraftPersistentDataContainer persistentDataContainer = new CraftPersistentDataContainer(PurpurStoredBee.DATA_TYPE_REGISTRY);
private Component customName;
public PurpurStoredBee(BeehiveBlockEntity.BeeData data, EntityBlockStorage<Bee> blockStorage) {
this.handle = data;
this.blockStorage = blockStorage;
CompoundTag customData = handle.occupant.entityData().copyTag();
this.customName = customData.contains("CustomName")
? PaperAdventure.asAdventure(net.minecraft.network.chat.Component.Serializer.fromJson(customData.getString("CustomName"), MinecraftServer.getDefaultRegistryAccess()))
: null;
if(customData.contains("BukkitValues", Tag.TAG_COMPOUND)) {
this.persistentDataContainer.putAll(customData.getCompound("BukkitValues"));
}
}
public BeehiveBlockEntity.BeeData getHandle() {
return handle;
}
@Override
public @Nullable Component customName() {
return customName;
}
@Override
public void customName(@Nullable Component customName) {
this.customName = customName;
}
@Override
public @Nullable String getCustomName() {
return PaperAdventure.asPlain(customName, Locale.US);
}
@Override
public void setCustomName(@Nullable String name) {
customName(name != null ? Component.text(name) : null);
}
@Override
public @NotNull PersistentDataContainer getPersistentDataContainer() {
return persistentDataContainer;
}
@Override
public boolean hasBeenReleased() {
return !blockStorage.getEntities().contains(this);
}
@Override
public @Nullable Bee release() {
return blockStorage.releaseEntity(this);
}
@Override
public @Nullable EntityBlockStorage<Bee> getBlockStorage() {
if(hasBeenReleased()) {
return null;
}
return blockStorage;
}
@Override
public @NotNull EntityType getType() {
return EntityType.BEE;
}
@Override
public void update() {
handle.occupant.entityData().copyTag().put("BukkitValues", this.persistentDataContainer.toTagCompound());
if(customName == null) {
handle.occupant.entityData().copyTag().remove("CustomName");
} else {
handle.occupant.entityData().copyTag().putString("CustomName", net.minecraft.network.chat.Component.Serializer.toJson(PaperAdventure.asVanilla(customName), MinecraftServer.getDefaultRegistryAccess()));
}
}
}