mirror of
https://github.com/PaperMC/Paper.git
synced 2025-01-02 09:21:57 +01:00
#1354: Improve spawner API and add API for Trial Spawners
By: coll1234567 <joshl5324@gmail.com>
This commit is contained in:
parent
c59410cfbc
commit
820bc6423d
5 changed files with 677 additions and 12 deletions
|
@ -1,5 +1,27 @@
|
|||
--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
|
||||
+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java
|
||||
@@ -57,16 +57,16 @@
|
||||
private static final int MAX_MOB_TRACKING_DISTANCE = 47;
|
||||
private static final int MAX_MOB_TRACKING_DISTANCE_SQR = MathHelper.square(47);
|
||||
private static final float SPAWNING_AMBIENT_SOUND_CHANCE = 0.02F;
|
||||
- private final TrialSpawnerConfig normalConfig;
|
||||
- private final TrialSpawnerConfig ominousConfig;
|
||||
+ public TrialSpawnerConfig normalConfig; // PAIL - private->public, -final
|
||||
+ public TrialSpawnerConfig ominousConfig; // PAIL - private->public, -final
|
||||
private final TrialSpawnerData data;
|
||||
- private final int requiredPlayerRange;
|
||||
- private final int targetCooldownLength;
|
||||
+ public int requiredPlayerRange; // PAIL - private->public, -final
|
||||
+ public int targetCooldownLength; // PAIL - private->public, -final
|
||||
public final TrialSpawner.b stateAccessor;
|
||||
private PlayerDetector playerDetector;
|
||||
private final PlayerDetector.a entitySelector;
|
||||
private boolean overridePeacefulAndMobSpawnRule;
|
||||
- private boolean isOminous;
|
||||
+ public boolean isOminous; // PAIL - private->public
|
||||
|
||||
public Codec<TrialSpawner> codec() {
|
||||
return RecordCodecBuilder.create((instance) -> {
|
||||
@@ -219,13 +219,13 @@
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ import net.minecraft.util.random.SimpleWeightedRandomList;
|
|||
import net.minecraft.util.random.WeightedEntry.b;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.entity.EquipmentTable;
|
||||
import net.minecraft.world.level.MobSpawnerAbstract;
|
||||
import net.minecraft.world.level.MobSpawnerData;
|
||||
import net.minecraft.world.level.block.entity.TileEntityMobSpawner;
|
||||
import org.bukkit.Location;
|
||||
|
@ -75,60 +76,94 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa
|
|||
|
||||
@Override
|
||||
public void setSpawnedEntity(EntitySnapshot snapshot) {
|
||||
setSpawnedEntity(this.getSnapshot().getSpawner(), snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedEntity(SpawnerEntry spawnerEntry) {
|
||||
Preconditions.checkArgument(spawnerEntry != null, "Entry cannot be null");
|
||||
|
||||
setSpawnedEntity(this.getSnapshot().getSpawner(), spawnerEntry.getSnapshot(), spawnerEntry.getSpawnRule(), spawnerEntry.getEquipment());
|
||||
}
|
||||
|
||||
public static void setSpawnedEntity(MobSpawnerAbstract spawner, EntitySnapshot snapshot, SpawnRule spawnRule, SpawnerEntry.Equipment equipment) {
|
||||
spawner.spawnPotentials = SimpleWeightedRandomList.empty(); // need clear the spawnPotentials to avoid nextSpawnData being replaced later
|
||||
|
||||
if (snapshot == null) {
|
||||
spawner.nextSpawnData = new MobSpawnerData();
|
||||
return;
|
||||
}
|
||||
NBTTagCompound compoundTag = ((CraftEntitySnapshot) snapshot).getData();
|
||||
|
||||
this.getSnapshot().getSpawner().spawnPotentials = SimpleWeightedRandomList.empty();
|
||||
this.getSnapshot().getSpawner().nextSpawnData = new MobSpawnerData(compoundTag, Optional.empty(), Optional.empty());
|
||||
spawner.nextSpawnData = new MobSpawnerData(compoundTag, Optional.ofNullable(toMinecraftRule(spawnRule)), getEquipment(equipment));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotentialSpawn(EntitySnapshot snapshot, int weight, SpawnRule spawnRule) {
|
||||
addPotentialSpawn(this.getSnapshot().getSpawner(), snapshot, weight, spawnRule, null);
|
||||
}
|
||||
|
||||
public static void addPotentialSpawn(MobSpawnerAbstract spawner, EntitySnapshot snapshot, int weight, SpawnRule spawnRule, SpawnerEntry.Equipment equipment) {
|
||||
Preconditions.checkArgument(snapshot != null, "Snapshot cannot be null");
|
||||
|
||||
NBTTagCompound compoundTag = ((CraftEntitySnapshot) snapshot).getData();
|
||||
|
||||
SimpleWeightedRandomList.a<MobSpawnerData> builder = SimpleWeightedRandomList.builder(); // PAIL rename Builder
|
||||
this.getSnapshot().getSpawner().spawnPotentials.unwrap().forEach(entry -> builder.add(entry.data(), entry.getWeight().asInt()));
|
||||
builder.add(new MobSpawnerData(compoundTag, Optional.ofNullable(toMinecraftRule(spawnRule)), Optional.empty()), weight);
|
||||
this.getSnapshot().getSpawner().spawnPotentials = builder.build();
|
||||
spawner.spawnPotentials.unwrap().forEach(entry -> builder.add(entry.data(), entry.getWeight().asInt()));
|
||||
builder.add(new MobSpawnerData(compoundTag, Optional.ofNullable(toMinecraftRule(spawnRule)), getEquipment(equipment)), weight);
|
||||
spawner.spawnPotentials = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotentialSpawn(SpawnerEntry spawnerEntry) {
|
||||
Preconditions.checkArgument(spawnerEntry != null, "Entry cannot be null");
|
||||
|
||||
addPotentialSpawn(spawnerEntry.getSnapshot(), spawnerEntry.getSpawnWeight(), spawnerEntry.getSpawnRule());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPotentialSpawns(Collection<SpawnerEntry> entries) {
|
||||
setPotentialSpawns(this.getSnapshot().getSpawner(), entries);
|
||||
}
|
||||
|
||||
public static void setPotentialSpawns(MobSpawnerAbstract spawner, Collection<SpawnerEntry> entries) {
|
||||
Preconditions.checkArgument(entries != null, "Entries cannot be null");
|
||||
|
||||
SimpleWeightedRandomList.a<MobSpawnerData> builder = SimpleWeightedRandomList.builder();
|
||||
for (SpawnerEntry spawnerEntry : entries) {
|
||||
NBTTagCompound compoundTag = ((CraftEntitySnapshot) spawnerEntry.getSnapshot()).getData();
|
||||
builder.add(new MobSpawnerData(compoundTag, Optional.ofNullable(toMinecraftRule(spawnerEntry.getSpawnRule())), getEquipment(spawnerEntry.getEquipment())), spawnerEntry.getSpawnWeight());
|
||||
}
|
||||
this.getSnapshot().getSpawner().spawnPotentials = builder.build();
|
||||
spawner.spawnPotentials = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpawnerEntry> getPotentialSpawns() {
|
||||
return getPotentialSpawns(this.getSnapshot().getSpawner());
|
||||
}
|
||||
|
||||
public static List<SpawnerEntry> getPotentialSpawns(MobSpawnerAbstract spawner) {
|
||||
List<SpawnerEntry> entries = new ArrayList<>();
|
||||
|
||||
for (b<MobSpawnerData> entry : this.getSnapshot().getSpawner().spawnPotentials.unwrap()) { // PAIL rename Wrapper
|
||||
for (b<MobSpawnerData> entry : spawner.spawnPotentials.unwrap()) { // PAIL rename Wrapper
|
||||
CraftEntitySnapshot snapshot = CraftEntitySnapshot.create(entry.data().getEntityToSpawn());
|
||||
|
||||
if (snapshot != null) {
|
||||
SpawnRule rule = entry.data().customSpawnRules().map(this::fromMinecraftRule).orElse(null);
|
||||
SpawnRule rule = entry.data().customSpawnRules().map(CraftCreatureSpawner::fromMinecraftRule).orElse(null);
|
||||
entries.add(new SpawnerEntry(snapshot, entry.getWeight().asInt(), rule, getEquipment(entry.data().equipment())));
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
private MobSpawnerData.a toMinecraftRule(SpawnRule rule) { // PAIL rename CustomSpawnRules
|
||||
public static MobSpawnerData.a toMinecraftRule(SpawnRule rule) { // PAIL rename CustomSpawnRules
|
||||
if (rule == null) {
|
||||
return null;
|
||||
}
|
||||
return new MobSpawnerData.a(new InclusiveRange<>(rule.getMinBlockLight(), rule.getMaxBlockLight()), new InclusiveRange<>(rule.getMinSkyLight(), rule.getMaxSkyLight()));
|
||||
}
|
||||
|
||||
private SpawnRule fromMinecraftRule(MobSpawnerData.a rule) {
|
||||
public static SpawnRule fromMinecraftRule(MobSpawnerData.a rule) {
|
||||
InclusiveRange<Integer> blockLight = rule.blockLightLimit();
|
||||
InclusiveRange<Integer> skyLight = rule.skyLightLimit();
|
||||
|
||||
|
@ -240,7 +275,7 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa
|
|||
return new CraftCreatureSpawner(this, location);
|
||||
}
|
||||
|
||||
private static Optional<EquipmentTable> getEquipment(SpawnerEntry.Equipment bukkit) {
|
||||
public static Optional<EquipmentTable> getEquipment(SpawnerEntry.Equipment bukkit) {
|
||||
if (bukkit == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
@ -251,7 +286,7 @@ public class CraftCreatureSpawner extends CraftBlockEntityState<TileEntityMobSpa
|
|||
);
|
||||
}
|
||||
|
||||
private static SpawnerEntry.Equipment getEquipment(Optional<EquipmentTable> optional) {
|
||||
public static SpawnerEntry.Equipment getEquipment(Optional<EquipmentTable> optional) {
|
||||
return optional.map((nms) -> new SpawnerEntry.Equipment(
|
||||
CraftLootTable.minecraftToBukkit(nms.lootTable()),
|
||||
new HashMap<>(nms.slotDropChances().entrySet().stream().collect(Collectors.toMap((entry) -> CraftEquipmentSlot.getSlot(entry.getKey()), Map.Entry::getValue)))
|
||||
|
|
|
@ -1,18 +1,162 @@
|
|||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.world.level.block.TrialSpawnerBlock;
|
||||
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.TrialSpawner;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.spawner.TrialSpawnerConfiguration;
|
||||
|
||||
public class CraftTrialSpawner extends CraftBlockEntityState<TrialSpawnerBlockEntity> implements TrialSpawner {
|
||||
|
||||
private final CraftTrialSpawnerConfiguration normalConfig;
|
||||
private final CraftTrialSpawnerConfiguration ominousConfig;
|
||||
|
||||
public CraftTrialSpawner(World world, TrialSpawnerBlockEntity tileEntity) {
|
||||
super(world, tileEntity);
|
||||
this.normalConfig = new CraftTrialSpawnerConfiguration(tileEntity.getTrialSpawner().getNormalConfig(), getSnapshot());
|
||||
this.ominousConfig = new CraftTrialSpawnerConfiguration(tileEntity.getTrialSpawner().getOminousConfig(), getSnapshot());
|
||||
}
|
||||
|
||||
protected CraftTrialSpawner(CraftTrialSpawner state, Location location) {
|
||||
super(state, location);
|
||||
this.normalConfig = state.normalConfig;
|
||||
this.ominousConfig = state.ominousConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCooldownLength() {
|
||||
return getSnapshot().trialSpawner.getTargetCooldownLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCooldownLength(int ticks) {
|
||||
getSnapshot().trialSpawner.targetCooldownLength = ticks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return getSnapshot().trialSpawner.getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
getSnapshot().trialSpawner.requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Player> getTrackedPlayers() {
|
||||
ImmutableSet.Builder<Player> players = ImmutableSet.builder();
|
||||
|
||||
for (UUID uuid : getTrialData().detectedPlayers) {
|
||||
Player player = Bukkit.getPlayer(uuid);
|
||||
if (player != null) {
|
||||
players.add(player);
|
||||
}
|
||||
}
|
||||
return players.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrackingPlayer(Player player) {
|
||||
Preconditions.checkArgument(player != null, "Player cannot be null");
|
||||
|
||||
return getTrialData().detectedPlayers.contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTrackingPlayer(Player player) {
|
||||
Preconditions.checkArgument(player != null, "Player cannot be null");
|
||||
|
||||
getTrialData().detectedPlayers.add(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTrackingPlayer(Player player) {
|
||||
Preconditions.checkArgument(player != null, "Player cannot be null");
|
||||
|
||||
getTrialData().detectedPlayers.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<Entity> getTrackedEntities() {
|
||||
ImmutableSet.Builder<Entity> entities = ImmutableSet.builder();
|
||||
|
||||
for (UUID uuid : getTrialData().currentMobs) {
|
||||
Entity entity = Bukkit.getEntity(uuid);
|
||||
if (entity != null) {
|
||||
entities.add(entity);
|
||||
}
|
||||
}
|
||||
return entities.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTrackingEntity(Entity entity) {
|
||||
Preconditions.checkArgument(entity != null, "Entity cannot be null");
|
||||
|
||||
return getTrialData().currentMobs.contains(entity.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTrackingEntity(Entity entity) {
|
||||
Preconditions.checkArgument(entity != null, "Entity cannot be null");
|
||||
|
||||
getTrialData().currentMobs.add(entity.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopTrackingEntity(Entity entity) {
|
||||
Preconditions.checkArgument(entity != null, "Entity cannot be null");
|
||||
|
||||
getTrialData().currentMobs.remove(entity.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOminous() {
|
||||
return getHandle().getValue(TrialSpawnerBlock.OMINOUS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOminous(boolean ominous) {
|
||||
getSnapshot().trialSpawner.isOminous = ominous;
|
||||
if (ominous) {
|
||||
setData(getHandle().setValue(TrialSpawnerBlock.OMINOUS, true));
|
||||
// TODO: Consider calling TrialSpawnerData#resetAfterBecomingOminous in update(...), but note that method also removes entities
|
||||
return;
|
||||
}
|
||||
|
||||
setData(getHandle().setValue(TrialSpawnerBlock.OMINOUS, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrialSpawnerConfiguration getNormalConfiguration() {
|
||||
return normalConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrialSpawnerConfiguration getOminousConfiguration() {
|
||||
return ominousConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyTo(TrialSpawnerBlockEntity tileEntity) {
|
||||
super.applyTo(tileEntity);
|
||||
|
||||
tileEntity.trialSpawner.normalConfig = normalConfig.toMinecraft();
|
||||
tileEntity.trialSpawner.ominousConfig = ominousConfig.toMinecraft();
|
||||
}
|
||||
|
||||
private TrialSpawnerData getTrialData() {
|
||||
return getSnapshot().getTrialSpawner().getData();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,305 @@
|
|||
package org.bukkit.craftbukkit.block;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||
import net.minecraft.util.random.WeightedEntry.b;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.level.MobSpawnerData;
|
||||
import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerConfig;
|
||||
import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData;
|
||||
import org.bukkit.block.spawner.SpawnRule;
|
||||
import org.bukkit.block.spawner.SpawnerEntry;
|
||||
import org.bukkit.craftbukkit.CraftLootTable;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntitySnapshot;
|
||||
import org.bukkit.craftbukkit.entity.CraftEntityType;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.loot.LootTable;
|
||||
import org.bukkit.spawner.TrialSpawnerConfiguration;
|
||||
|
||||
public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration {
|
||||
private final TrialSpawnerBlockEntity snapshot;
|
||||
|
||||
private int spawnRange;
|
||||
private float totalMobs;
|
||||
private float simultaneousMobs;
|
||||
private float totalMobsAddedPerPlayer;
|
||||
private float simultaneousMobsAddedPerPlayer;
|
||||
private int ticksBetweenSpawn;
|
||||
private SimpleWeightedRandomList<MobSpawnerData> spawnPotentialsDefinition;
|
||||
private SimpleWeightedRandomList<ResourceKey<net.minecraft.world.level.storage.loot.LootTable>> lootTablesToEject;
|
||||
private ResourceKey<net.minecraft.world.level.storage.loot.LootTable> itemsToDropWhenOminous;
|
||||
|
||||
public CraftTrialSpawnerConfiguration(TrialSpawnerConfig minecraft, TrialSpawnerBlockEntity snapshot) {
|
||||
this.snapshot = snapshot;
|
||||
|
||||
this.spawnRange = minecraft.spawnRange();
|
||||
this.totalMobs = minecraft.totalMobs();
|
||||
this.simultaneousMobs = minecraft.simultaneousMobs();
|
||||
this.totalMobsAddedPerPlayer = minecraft.totalMobsAddedPerPlayer();
|
||||
this.simultaneousMobsAddedPerPlayer = minecraft.simultaneousMobsAddedPerPlayer();
|
||||
this.ticksBetweenSpawn = minecraft.ticksBetweenSpawn();
|
||||
this.spawnPotentialsDefinition = minecraft.spawnPotentialsDefinition();
|
||||
this.lootTablesToEject = minecraft.lootTablesToEject();
|
||||
this.itemsToDropWhenOminous = minecraft.itemsToDropWhenOminous();
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getSpawnedType() {
|
||||
if (spawnPotentialsDefinition.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<EntityTypes<?>> type = EntityTypes.by(spawnPotentialsDefinition.unwrap().get(0).data().getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedType(EntityType entityType) {
|
||||
if (entityType == null) {
|
||||
getTrialData().nextSpawnData = Optional.empty();
|
||||
spawnPotentialsDefinition = SimpleWeightedRandomList.empty(); // need clear the spawnPotentials to avoid nextSpawnData being replaced later
|
||||
return;
|
||||
}
|
||||
Preconditions.checkArgument(entityType != EntityType.UNKNOWN, "Can't spawn EntityType %s from mob spawners!", entityType);
|
||||
|
||||
MobSpawnerData data = new MobSpawnerData();
|
||||
data.getEntityToSpawn().putString("id", BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString());
|
||||
getTrialData().nextSpawnData = Optional.of(data);
|
||||
spawnPotentialsDefinition = SimpleWeightedRandomList.single(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBaseSpawnsBeforeCooldown() {
|
||||
return totalMobs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseSpawnsBeforeCooldown(float amount) {
|
||||
totalMobs = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getBaseSimultaneousEntities() {
|
||||
return simultaneousMobs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBaseSimultaneousEntities(float amount) {
|
||||
simultaneousMobs = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAdditionalSpawnsBeforeCooldown() {
|
||||
return totalMobsAddedPerPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdditionalSpawnsBeforeCooldown(float amount) {
|
||||
totalMobsAddedPerPlayer = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getAdditionalSimultaneousEntities() {
|
||||
return simultaneousMobsAddedPerPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAdditionalSimultaneousEntities(float amount) {
|
||||
simultaneousMobsAddedPerPlayer = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDelay() {
|
||||
return ticksBetweenSpawn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDelay(int delay) {
|
||||
Preconditions.checkArgument(delay >= 0, "Delay cannot be less than 0");
|
||||
|
||||
ticksBetweenSpawn = delay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpawnRange() {
|
||||
return spawnRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnRange(int spawnRange) {
|
||||
this.spawnRange = spawnRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntitySnapshot getSpawnedEntity() {
|
||||
SimpleWeightedRandomList<MobSpawnerData> potentials = spawnPotentialsDefinition;
|
||||
if (potentials.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CraftEntitySnapshot.create(potentials.unwrap().get(0).data().getEntityToSpawn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedEntity(EntitySnapshot snapshot) {
|
||||
setSpawnedEntity(snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedEntity(SpawnerEntry spawnerEntry) {
|
||||
Preconditions.checkArgument(spawnerEntry != null, "Entry cannot be null");
|
||||
|
||||
setSpawnedEntity(spawnerEntry.getSnapshot(), spawnerEntry.getSpawnRule(), spawnerEntry.getEquipment());
|
||||
}
|
||||
|
||||
private void setSpawnedEntity(EntitySnapshot snapshot, SpawnRule spawnRule, SpawnerEntry.Equipment equipment) {
|
||||
if (snapshot == null) {
|
||||
getTrialData().nextSpawnData = Optional.empty();
|
||||
spawnPotentialsDefinition = SimpleWeightedRandomList.empty(); // need clear the spawnPotentials to avoid nextSpawnData being replaced later
|
||||
return;
|
||||
}
|
||||
|
||||
NBTTagCompound compoundTag = ((CraftEntitySnapshot) snapshot).getData();
|
||||
MobSpawnerData data = new MobSpawnerData(compoundTag, Optional.ofNullable(CraftCreatureSpawner.toMinecraftRule(spawnRule)), CraftCreatureSpawner.getEquipment(equipment));
|
||||
|
||||
getTrialData().nextSpawnData = Optional.of(data);
|
||||
spawnPotentialsDefinition = SimpleWeightedRandomList.single(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotentialSpawn(EntitySnapshot snapshot, int weight, SpawnRule spawnRule) {
|
||||
addPotentialSpawn(snapshot, weight, spawnRule, null);
|
||||
}
|
||||
|
||||
private void addPotentialSpawn(EntitySnapshot snapshot, int weight, SpawnRule spawnRule, SpawnerEntry.Equipment equipment) {
|
||||
Preconditions.checkArgument(snapshot != null, "Snapshot cannot be null");
|
||||
|
||||
NBTTagCompound compoundTag = ((CraftEntitySnapshot) snapshot).getData();
|
||||
|
||||
SimpleWeightedRandomList.a<MobSpawnerData> builder = SimpleWeightedRandomList.builder(); // PAIL rename Builder
|
||||
spawnPotentialsDefinition.unwrap().forEach(entry -> builder.add(entry.data(), entry.getWeight().asInt()));
|
||||
builder.add(new MobSpawnerData(compoundTag, Optional.ofNullable(CraftCreatureSpawner.toMinecraftRule(spawnRule)), CraftCreatureSpawner.getEquipment(equipment)), weight);
|
||||
spawnPotentialsDefinition = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotentialSpawn(SpawnerEntry spawnerEntry) {
|
||||
Preconditions.checkArgument(spawnerEntry != null, "Entry cannot be null");
|
||||
|
||||
addPotentialSpawn(spawnerEntry.getSnapshot(), spawnerEntry.getSpawnWeight(), spawnerEntry.getSpawnRule(), spawnerEntry.getEquipment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPotentialSpawns(Collection<SpawnerEntry> entries) {
|
||||
Preconditions.checkArgument(entries != null, "Entries cannot be null");
|
||||
|
||||
SimpleWeightedRandomList.a<MobSpawnerData> builder = SimpleWeightedRandomList.builder();
|
||||
for (SpawnerEntry spawnerEntry : entries) {
|
||||
NBTTagCompound compoundTag = ((CraftEntitySnapshot) spawnerEntry.getSnapshot()).getData();
|
||||
builder.add(new MobSpawnerData(compoundTag, Optional.ofNullable(CraftCreatureSpawner.toMinecraftRule(spawnerEntry.getSpawnRule())), CraftCreatureSpawner.getEquipment(spawnerEntry.getEquipment())), spawnerEntry.getSpawnWeight());
|
||||
}
|
||||
spawnPotentialsDefinition = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpawnerEntry> getPotentialSpawns() {
|
||||
List<SpawnerEntry> entries = new ArrayList<>();
|
||||
|
||||
for (b<MobSpawnerData> entry : spawnPotentialsDefinition.unwrap()) { // PAIL rename Wrapper
|
||||
CraftEntitySnapshot snapshot = CraftEntitySnapshot.create(entry.data().getEntityToSpawn());
|
||||
|
||||
if (snapshot != null) {
|
||||
SpawnRule rule = entry.data().customSpawnRules().map(CraftCreatureSpawner::fromMinecraftRule).orElse(null);
|
||||
entries.add(new SpawnerEntry(snapshot, entry.getWeight().asInt(), rule));
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<LootTable, Integer> getPossibleRewards() {
|
||||
Map<LootTable, Integer> tables = new HashMap<>();
|
||||
|
||||
for (b<ResourceKey<net.minecraft.world.level.storage.loot.LootTable>> entry : lootTablesToEject.unwrap()) {
|
||||
LootTable table = CraftLootTable.minecraftToBukkit(entry.data());
|
||||
if (table != null) {
|
||||
tables.put(table, entry.getWeight().asInt());
|
||||
}
|
||||
}
|
||||
|
||||
return tables;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPossibleReward(LootTable table, int weight) {
|
||||
Preconditions.checkArgument(table != null, "Table cannot be null");
|
||||
Preconditions.checkArgument(weight >= 1, "Weight must be at least 1");
|
||||
|
||||
SimpleWeightedRandomList.a<ResourceKey<net.minecraft.world.level.storage.loot.LootTable>> builder = SimpleWeightedRandomList.builder();
|
||||
lootTablesToEject.unwrap().forEach(entry -> builder.add(entry.data(), entry.getWeight().asInt()));
|
||||
builder.add(CraftLootTable.bukkitToMinecraft(table), weight);
|
||||
lootTablesToEject = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removePossibleReward(LootTable table) {
|
||||
Preconditions.checkArgument(table != null, "Key cannot be null");
|
||||
|
||||
ResourceKey<net.minecraft.world.level.storage.loot.LootTable> minecraftKey = CraftLootTable.bukkitToMinecraft(table);
|
||||
SimpleWeightedRandomList.a<ResourceKey<net.minecraft.world.level.storage.loot.LootTable>> builder = SimpleWeightedRandomList.builder();
|
||||
|
||||
for (b<ResourceKey<net.minecraft.world.level.storage.loot.LootTable>> entry : lootTablesToEject.unwrap()) {
|
||||
if (!entry.data().equals(minecraftKey)) {
|
||||
builder.add(entry.data(), entry.getWeight().asInt());
|
||||
}
|
||||
}
|
||||
lootTablesToEject = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPossibleRewards(Map<LootTable, Integer> rewards) {
|
||||
if (rewards == null || rewards.isEmpty()) {
|
||||
lootTablesToEject = SimpleWeightedRandomList.empty();
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleWeightedRandomList.a<ResourceKey<net.minecraft.world.level.storage.loot.LootTable>> builder = SimpleWeightedRandomList.builder();
|
||||
rewards.forEach((table, weight) -> {
|
||||
Preconditions.checkArgument(table != null, "Table cannot be null");
|
||||
Preconditions.checkArgument(weight >= 1, "Weight must be at least 1");
|
||||
|
||||
builder.add(CraftLootTable.bukkitToMinecraft(table), weight);
|
||||
});
|
||||
|
||||
lootTablesToEject = builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return snapshot.trialSpawner.getRequiredPlayerRange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
snapshot.trialSpawner.requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
private TrialSpawnerData getTrialData() {
|
||||
return snapshot.getTrialSpawner().getData();
|
||||
}
|
||||
|
||||
protected TrialSpawnerConfig toMinecraft() {
|
||||
return new TrialSpawnerConfig(spawnRange, totalMobs, simultaneousMobs, totalMobsAddedPerPlayer, simultaneousMobsAddedPerPlayer, ticksBetweenSpawn, spawnPotentialsDefinition, lootTablesToEject, itemsToDropWhenOminous);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,20 @@
|
|||
package org.bukkit.craftbukkit.entity;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.util.random.SimpleWeightedRandomList;
|
||||
import net.minecraft.world.entity.EntityTypes;
|
||||
import net.minecraft.world.entity.vehicle.EntityMinecartMobSpawner;
|
||||
import net.minecraft.world.level.MobSpawnerData;
|
||||
import org.bukkit.block.spawner.SpawnRule;
|
||||
import org.bukkit.block.spawner.SpawnerEntry;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.block.CraftCreatureSpawner;
|
||||
import org.bukkit.entity.EntitySnapshot;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.minecart.SpawnerMinecart;
|
||||
|
||||
final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMinecart {
|
||||
|
@ -9,6 +22,152 @@ final class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMine
|
|||
super(server, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityType getSpawnedType() {
|
||||
MobSpawnerData spawnData = getHandle().getSpawner().nextSpawnData;
|
||||
if (spawnData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Optional<EntityTypes<?>> type = EntityTypes.by(spawnData.getEntityToSpawn());
|
||||
return type.map(CraftEntityType::minecraftToBukkit).orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedType(EntityType entityType) {
|
||||
if (entityType == null) {
|
||||
getHandle().getSpawner().spawnPotentials = SimpleWeightedRandomList.empty(); // need clear the spawnPotentials to avoid nextSpawnData being replaced later
|
||||
getHandle().getSpawner().nextSpawnData = new MobSpawnerData();
|
||||
return;
|
||||
}
|
||||
Preconditions.checkArgument(entityType != EntityType.UNKNOWN, "Can't spawn EntityType %s from mob spawners!", entityType);
|
||||
|
||||
RandomSource rand = getHandle().level().getRandom();
|
||||
getHandle().getSpawner().setEntityId(CraftEntityType.bukkitToMinecraft(entityType), getHandle().level(), rand, getHandle().blockPosition());
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntitySnapshot getSpawnedEntity() {
|
||||
MobSpawnerData spawnData = getHandle().getSpawner().nextSpawnData;
|
||||
if (spawnData == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return CraftEntitySnapshot.create(spawnData.getEntityToSpawn());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedEntity(EntitySnapshot snapshot) {
|
||||
CraftCreatureSpawner.setSpawnedEntity(getHandle().getSpawner(), snapshot, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnedEntity(SpawnerEntry spawnerEntry) {
|
||||
Preconditions.checkArgument(spawnerEntry != null, "Entry cannot be null");
|
||||
|
||||
CraftCreatureSpawner.setSpawnedEntity(getHandle().getSpawner(), spawnerEntry.getSnapshot(), spawnerEntry.getSpawnRule(), spawnerEntry.getEquipment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotentialSpawn(EntitySnapshot snapshot, int weight, SpawnRule spawnRule) {
|
||||
CraftCreatureSpawner.addPotentialSpawn(getHandle().getSpawner(), snapshot, weight, spawnRule, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPotentialSpawn(SpawnerEntry spawnerEntry) {
|
||||
Preconditions.checkArgument(spawnerEntry != null, "Entry cannot be null");
|
||||
|
||||
CraftCreatureSpawner.addPotentialSpawn(getHandle().getSpawner(), spawnerEntry.getSnapshot(), spawnerEntry.getSpawnWeight(), spawnerEntry.getSpawnRule(), spawnerEntry.getEquipment());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPotentialSpawns(Collection<SpawnerEntry> entries) {
|
||||
CraftCreatureSpawner.setPotentialSpawns(getHandle().getSpawner(), entries);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SpawnerEntry> getPotentialSpawns() {
|
||||
return CraftCreatureSpawner.getPotentialSpawns(getHandle().getSpawner());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDelay() {
|
||||
return getHandle().getSpawner().spawnDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDelay(int delay) {
|
||||
getHandle().getSpawner().spawnDelay = delay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMinSpawnDelay() {
|
||||
return getHandle().getSpawner().minSpawnDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinSpawnDelay(int spawnDelay) {
|
||||
Preconditions.checkArgument(spawnDelay <= getMaxSpawnDelay(), "Minimum Spawn Delay must be less than or equal to Maximum Spawn Delay");
|
||||
getHandle().getSpawner().minSpawnDelay = spawnDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxSpawnDelay() {
|
||||
return getHandle().getSpawner().maxSpawnDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxSpawnDelay(int spawnDelay) {
|
||||
Preconditions.checkArgument(spawnDelay > 0, "Maximum Spawn Delay must be greater than 0.");
|
||||
Preconditions.checkArgument(spawnDelay >= getMinSpawnDelay(), "Maximum Spawn Delay must be greater than or equal to Minimum Spawn Delay");
|
||||
getHandle().getSpawner().maxSpawnDelay = spawnDelay;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxNearbyEntities() {
|
||||
return getHandle().getSpawner().maxNearbyEntities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxNearbyEntities(int maxNearbyEntities) {
|
||||
getHandle().getSpawner().maxNearbyEntities = maxNearbyEntities;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpawnCount() {
|
||||
return getHandle().getSpawner().spawnCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnCount(int count) {
|
||||
getHandle().getSpawner().spawnCount = count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRequiredPlayerRange() {
|
||||
return getHandle().getSpawner().requiredPlayerRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredPlayerRange(int requiredPlayerRange) {
|
||||
getHandle().getSpawner().requiredPlayerRange = requiredPlayerRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSpawnRange() {
|
||||
return getHandle().getSpawner().spawnRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpawnRange(int spawnRange) {
|
||||
getHandle().getSpawner().spawnRange = spawnRange;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EntityMinecartMobSpawner getHandle() {
|
||||
return (EntityMinecartMobSpawner) entity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftMinecartMobSpawner";
|
||||
|
|
Loading…
Reference in a new issue