minecraft-source/src/net/minecraft/world/level/BaseSpawner.java

285 lines
12 KiB
Java

package net.minecraft.world.level;
import java.util.AbstractList;
import org.apache.logging.log4j.LogManager;
import java.util.function.Function;
import net.minecraft.nbt.Tag;
import net.minecraft.util.WeighedRandom;
import java.util.Iterator;
import net.minecraft.nbt.ListTag;
import java.util.Optional;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.SpawnGroupData;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.entity.SpawnPlacements;
import net.minecraft.world.entity.MobSpawnType;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.core.Registry;
import net.minecraft.world.entity.EntityType;
import net.minecraft.core.BlockPos;
import net.minecraft.ResourceLocationException;
import net.minecraft.util.StringUtil;
import net.minecraft.resources.ResourceLocation;
import com.google.common.collect.Lists;
import javax.annotation.Nullable;
import net.minecraft.world.entity.Entity;
import java.util.List;
import org.apache.logging.log4j.Logger;
public abstract class BaseSpawner {
private static final Logger LOGGER;
private int spawnDelay;
private final List<SpawnData> spawnPotentials;
private SpawnData nextSpawnData;
private double spin;
private double oSpin;
private int minSpawnDelay;
private int maxSpawnDelay;
private int spawnCount;
@Nullable
private Entity displayEntity;
private int maxNearbyEntities;
private int requiredPlayerRange;
private int spawnRange;
public BaseSpawner() {
this.spawnDelay = 20;
this.spawnPotentials = Lists.newArrayList();
this.nextSpawnData = new SpawnData();
this.minSpawnDelay = 200;
this.maxSpawnDelay = 800;
this.spawnCount = 4;
this.maxNearbyEntities = 6;
this.requiredPlayerRange = 16;
this.spawnRange = 4;
}
@Nullable
private ResourceLocation getEntityId() {
final String string2 = this.nextSpawnData.getTag().getString("id");
try {
return StringUtil.isNullOrEmpty(string2) ? null : new ResourceLocation(string2);
}
catch (ResourceLocationException r3) {
final BlockPos fk4 = this.getPos();
BaseSpawner.LOGGER.warn("Invalid entity id '{}' at spawner {}:[{},{},{}]", string2, this.getLevel().dimension.getType(), fk4.getX(), fk4.getY(), fk4.getZ());
return null;
}
}
public void setEntityId(final EntityType<?> akr) {
this.nextSpawnData.getTag().putString("id", Registry.ENTITY_TYPE.getKey(akr).toString());
}
private boolean isNearPlayer() {
final BlockPos fk2 = this.getPos();
return this.getLevel().hasNearbyAlivePlayer(fk2.getX() + 0.5, fk2.getY() + 0.5, fk2.getZ() + 0.5, this.requiredPlayerRange);
}
public void tick() {
if (!this.isNearPlayer()) {
this.oSpin = this.spin;
return;
}
final Level bjt2 = this.getLevel();
final BlockPos fk3 = this.getPos();
if (bjt2.isClientSide) {
final double double4 = fk3.getX() + (double)bjt2.random.nextFloat();
final double double5 = fk3.getY() + (double)bjt2.random.nextFloat();
final double double6 = fk3.getZ() + (double)bjt2.random.nextFloat();
bjt2.addParticle(ParticleTypes.SMOKE, double4, double5, double6, 0.0, 0.0, 0.0);
bjt2.addParticle(ParticleTypes.FLAME, double4, double5, double6, 0.0, 0.0, 0.0);
if (this.spawnDelay > 0) {
--this.spawnDelay;
}
this.oSpin = this.spin;
this.spin = (this.spin + 1000.0f / (this.spawnDelay + 200.0f)) % 360.0;
}
else {
if (this.spawnDelay == -1) {
this.delay();
}
if (this.spawnDelay > 0) {
--this.spawnDelay;
return;
}
boolean boolean4 = false;
for (int integer5 = 0; integer5 < this.spawnCount; ++integer5) {
final CompoundTag jt6 = this.nextSpawnData.getTag();
final Optional<EntityType<?>> optional7 = EntityType.by(jt6);
if (!optional7.isPresent()) {
this.delay();
return;
}
final ListTag jz8 = jt6.getList("Pos", 6);
final int integer6 = jz8.size();
final double double7 = (integer6 >= 1) ? jz8.getDouble(0) : (fk3.getX() + (bjt2.random.nextDouble() - bjt2.random.nextDouble()) * this.spawnRange + 0.5);
final double double8 = (integer6 >= 2) ? jz8.getDouble(1) : (fk3.getY() + bjt2.random.nextInt(3) - 1);
final double double9 = (integer6 >= 3) ? jz8.getDouble(2) : (fk3.getZ() + (bjt2.random.nextDouble() - bjt2.random.nextDouble()) * this.spawnRange + 0.5);
if (bjt2.noCollision(optional7.get().getAABB(double7, double8, double9))) {
if (SpawnPlacements.<Entity>checkSpawnRules(optional7.get(), bjt2.getLevel(), MobSpawnType.SPAWNER, new BlockPos(double7, double8, double9), bjt2.getRandom())) {
final Entity akn2 = EntityType.loadEntityRecursive(jt6, bjt2, akn -> {
akn.moveTo(double7, double8, double9, akn.yRot, akn.xRot);
return akn;
});
if (akn2 == null) {
this.delay();
return;
}
final int integer7 = bjt2.<Entity>getEntitiesOfClass(akn2.getClass(), new AABB(fk3.getX(), fk3.getY(), fk3.getZ(), fk3.getX() + 1, fk3.getY() + 1, fk3.getZ() + 1).inflate(this.spawnRange)).size();
if (integer7 >= this.maxNearbyEntities) {
this.delay();
return;
}
akn2.moveTo(akn2.getX(), akn2.getY(), akn2.getZ(), bjt2.random.nextFloat() * 360.0f, 0.0f);
if (akn2 instanceof Mob) {
final Mob akx18 = (Mob)akn2;
if (!akx18.checkSpawnRules(bjt2, MobSpawnType.SPAWNER)) {
continue;
}
if (!akx18.checkSpawnObstruction(bjt2)) {
continue;
}
if (this.nextSpawnData.getTag().size() == 1 && this.nextSpawnData.getTag().contains("id", 8)) {
((Mob)akn2).finalizeSpawn(bjt2, bjt2.getCurrentDifficultyAt(new BlockPos(akn2)), MobSpawnType.SPAWNER, null, null);
}
}
this.addWithPassengers(akn2);
bjt2.levelEvent(2004, fk3, 0);
if (akn2 instanceof Mob) {
((Mob)akn2).spawnAnim();
}
boolean4 = true;
}
}
}
if (boolean4) {
this.delay();
}
}
}
private void addWithPassengers(final Entity akn) {
if (!this.getLevel().addFreshEntity(akn)) {
return;
}
for (final Entity akn2 : akn.getPassengers()) {
this.addWithPassengers(akn2);
}
}
private void delay() {
if (this.maxSpawnDelay <= this.minSpawnDelay) {
this.spawnDelay = this.minSpawnDelay;
}
else {
this.spawnDelay = this.minSpawnDelay + this.getLevel().random.nextInt(this.maxSpawnDelay - this.minSpawnDelay);
}
if (!this.spawnPotentials.isEmpty()) {
this.setNextSpawnData(WeighedRandom.<SpawnData>getRandomItem(this.getLevel().random, this.spawnPotentials));
}
this.broadcastEvent(1);
}
public void load(final CompoundTag jt) {
this.spawnDelay = jt.getShort("Delay");
this.spawnPotentials.clear();
if (jt.contains("SpawnPotentials", 9)) {
final ListTag jz3 = jt.getList("SpawnPotentials", 10);
for (int integer4 = 0; integer4 < jz3.size(); ++integer4) {
this.spawnPotentials.add(new SpawnData(jz3.getCompound(integer4)));
}
}
if (jt.contains("SpawnData", 10)) {
this.setNextSpawnData(new SpawnData(1, jt.getCompound("SpawnData")));
}
else if (!this.spawnPotentials.isEmpty()) {
this.setNextSpawnData(WeighedRandom.<SpawnData>getRandomItem(this.getLevel().random, this.spawnPotentials));
}
if (jt.contains("MinSpawnDelay", 99)) {
this.minSpawnDelay = jt.getShort("MinSpawnDelay");
this.maxSpawnDelay = jt.getShort("MaxSpawnDelay");
this.spawnCount = jt.getShort("SpawnCount");
}
if (jt.contains("MaxNearbyEntities", 99)) {
this.maxNearbyEntities = jt.getShort("MaxNearbyEntities");
this.requiredPlayerRange = jt.getShort("RequiredPlayerRange");
}
if (jt.contains("SpawnRange", 99)) {
this.spawnRange = jt.getShort("SpawnRange");
}
if (this.getLevel() != null) {
this.displayEntity = null;
}
}
public CompoundTag save(final CompoundTag jt) {
final ResourceLocation sm3 = this.getEntityId();
if (sm3 == null) {
return jt;
}
jt.putShort("Delay", (short)this.spawnDelay);
jt.putShort("MinSpawnDelay", (short)this.minSpawnDelay);
jt.putShort("MaxSpawnDelay", (short)this.maxSpawnDelay);
jt.putShort("SpawnCount", (short)this.spawnCount);
jt.putShort("MaxNearbyEntities", (short)this.maxNearbyEntities);
jt.putShort("RequiredPlayerRange", (short)this.requiredPlayerRange);
jt.putShort("SpawnRange", (short)this.spawnRange);
jt.put("SpawnData", this.nextSpawnData.getTag().copy());
final ListTag jz4 = new ListTag();
if (this.spawnPotentials.isEmpty()) {
((AbstractList<CompoundTag>)jz4).add(this.nextSpawnData.save());
}
else {
for (final SpawnData bkh6 : this.spawnPotentials) {
((AbstractList<CompoundTag>)jz4).add(bkh6.save());
}
}
jt.put("SpawnPotentials", jz4);
return jt;
}
@Nullable
public Entity getOrCreateDisplayEntity() {
if (this.displayEntity == null) {
this.displayEntity = EntityType.loadEntityRecursive(this.nextSpawnData.getTag(), this.getLevel(), Function.<Entity>identity());
if (this.nextSpawnData.getTag().size() == 1 && this.nextSpawnData.getTag().contains("id", 8) && this.displayEntity instanceof Mob) {
((Mob)this.displayEntity).finalizeSpawn(this.getLevel(), this.getLevel().getCurrentDifficultyAt(new BlockPos(this.displayEntity)), MobSpawnType.SPAWNER, null, null);
}
}
return this.displayEntity;
}
public boolean onEventTriggered(final int integer) {
if (integer == 1 && this.getLevel().isClientSide) {
this.spawnDelay = this.minSpawnDelay;
return true;
}
return false;
}
public void setNextSpawnData(final SpawnData bkh) {
this.nextSpawnData = bkh;
}
public abstract void broadcastEvent(final int integer);
public abstract Level getLevel();
public abstract BlockPos getPos();
public double getSpin() {
return this.spin;
}
public double getoSpin() {
return this.oSpin;
}
static {
LOGGER = LogManager.getLogger();
}
}