All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.minecraft.server.MobSpawnerAbstract Maven / Gradle / Ivy

package net.minecraft.server;

import com.google.common.collect.Lists;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.event.entity.CreatureSpawnEvent;

import java.util.List;
import java.util.Map;
import java.util.Random;
// CraftBukkit end

public abstract class MobSpawnerAbstract {
	
	public final List mobs = Lists.newArrayList();
	public SpawnData spawnData;
	
	/** Cached instance of the entity to render inside the spawner. */
	public Entity renderEntity;
	
	public String mobName = "Pig";
	
	/** The rotation of the mob inside the mob spawner */
	public double mobRotation;
	
	/** the previous rotation of the mob inside the mob spawner */
	public double prevMobRotation;
	
	public int spawnDelay = 20;
	public int minSpawnDelay = 200;
	public int maxSpawnDelay = 800;
	public int spawnCount = 4;
	public int maxNearbyEntities = 6;
	public int requiredPlayerRange = 16;
	public int spawnRange = 4;
	
	/**
  * Gets the entity name that should be spawned.
  */
	public String getMobName() {
		if (spawnData == null) {
			// CraftBukkit start - fix NPE
			if (this.mobName == null) {
				this.mobName = "Pig";
			}
			// CraftBukkit end
			if (this.mobName.equals("Minecart")) {
				this.mobName = "MinecartRideable";
			}
			
			return this.mobName;
		} else {
			return spawnData.entityType;
		}
	}
	
	public void setMobName(String s) {
		this.mobName = s;
	}
	
	/**
   * Returns true if there's a player close enough to this mob spawner to activate it.
   */
	public boolean isActivated() {
		final BlockPosition pos = getSpawnerPosition();
		return this.getSpawnerWorld().isPlayerNearby(pos.getCenterX(), pos.getCenterY(), pos.getCenterZ(), requiredPlayerRange);
	}
	
	public void updateSpawner() {
		if (this.isActivated()) {
			final World world = getSpawnerWorld();
			final BlockPosition pos = this.getSpawnerPosition();
			double d0;
			
			if (world.isClientSide) {
				double d1 = (float) pos.getX() + world.random.nextFloat();
				double d2 = (float) pos.getY() + world.random.nextFloat();
				
				d0 = (float) pos.getZ() + world.random.nextFloat();
				world.addParticle(EnumParticle.SMOKE_NORMAL, d1, d2, d0, 0.0D, 0.0D, 0.0D);
				world.addParticle(EnumParticle.FLAME, d1, d2, d0, 0.0D, 0.0D, 0.0D);
				if (this.spawnDelay > 0) {
					--this.spawnDelay;
				}
				
				this.prevMobRotation = this.mobRotation;
				this.mobRotation = (this.mobRotation + (double) (1000.0F / ((float) this.spawnDelay + 200.0F))) % 360.0D;
			} else {
				if (this.spawnDelay == -1)
					this.resetTimer();
				
				if (this.spawnDelay > 0) {
					--this.spawnDelay;
					return;
				}
				
				boolean flag = false;
				final Random random = world.random;
				
				for (int i = 0; i < this.spawnCount; ++i) {
					final Entity entity = EntityTypes.createEntityByName(this.getMobName(), world);
					
					if (entity == null)
						return;
					
					int j = world.a(entity.getClass(), (new AxisAlignedBB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)).grow(this.spawnRange, this.spawnRange, this.spawnRange)).size();
					
					if (j >= this.maxNearbyEntities) {
						this.resetTimer();
						return;
					}
					
					d0 = (double) pos.getX() + (random.nextDouble() - random.nextDouble()) * (double) this.spawnRange + 0.5D;
					double d3 = pos.getY() + random.nextInt(3) - 1;
					double d4 = (double) pos.getZ() + (random.nextDouble() - random.nextDouble()) * (double) this.spawnRange + 0.5D;
					final EntityInsentient insentient = entity instanceof EntityInsentient ? (EntityInsentient) entity : null;
					
					entity.setPositionRotation(d0, d3, d4, random.nextFloat() * 360.0F, 0.0F);
					if (insentient == null || insentient.getCanSpawnHere() && insentient.isNotColliding()) {
						this.spawnNewEntity(entity, true);
						world.triggerEffect(2004, pos, 0);
						if (insentient != null) {
							insentient.spawnExplosionParticle();
						}
						
						flag = true;
					}
				}
				
				if (flag) {
					this.resetTimer();
				}
			}
			
		}
	}
	
	public Entity spawnNewEntity(Entity entity, boolean spawn) {
		if (spawnData != null) {
			final BlockPosition pos = getSpawnerPosition();
			
			NBTTagCompound tag = new NBTTagCompound();
			
			entity.writeToNBTOptional(tag);
			
			for (final Map.Entry entry : spawnData.data.all().entrySet()) {
				tag.set(entry.getKey(), entry.getValue().clone());
			}
			
			entity.readFromNBT(tag);
			
			if (entity.world != null && spawn) {
				if (!CraftEventFactory.callSpawnerSpawnEvent(entity, pos.getX(), pos.getY(), pos.getZ()).isCancelled()) {
					entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER);
					
					if (entity.world.spigotConfig.nerfSpawnerMobs)
						entity.fromMobSpawner = true;
				}
			}
			
			NBTTagCompound nbttagcompound1;
			
			for (Entity entity1 = entity; tag.hasKeyOfType("Riding", 10); tag = nbttagcompound1) {
				nbttagcompound1 = tag.getCompound("Riding");
				Entity entity2 = EntityTypes.createEntityByName(nbttagcompound1.getString("id"), entity.world);
				
				if (entity2 != null) {
					NBTTagCompound nbttagcompound2 = new NBTTagCompound();
					
					entity2.writeToNBTOptional(nbttagcompound2);
					
					for (Map.Entry entry : nbttagcompound1.all().entrySet()) {
						nbttagcompound2.set(entry.getKey(), entry.getValue().clone());
					}
					
					entity2.readFromNBT(nbttagcompound2);
					entity2.setPositionRotation(entity1.locX, entity1.locY, entity1.locZ, entity1.yaw, entity1.pitch);

					if (CraftEventFactory.callSpawnerSpawnEvent(entity2, pos.getX(), pos.getY(), pos.getZ()).isCancelled())
						continue;
					
					if (entity.world != null && spawn)
						entity.world.addEntity(entity2, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit
					
					entity1.mount(entity2);
				}
				
				entity1 = entity2;
			}
		} else if (entity instanceof EntityLiving && entity.world != null && spawn) {
			if (entity instanceof EntityInsentient) {
				((EntityInsentient) entity).prepare(entity.world.E(new BlockPosition(entity)), null);
			}

			if (!CraftEventFactory.callSpawnerSpawnEvent(entity, this.getSpawnerPosition().getX(), this.getSpawnerPosition().getY(), this.getSpawnerPosition().getZ()).isCancelled()) {
				entity.world.addEntity(entity, CreatureSpawnEvent.SpawnReason.SPAWNER);

				if (entity.world.spigotConfig.nerfSpawnerMobs)
					entity.fromMobSpawner = true;
			}
		}
		
		return entity;
	}
	
	public void resetTimer() {
		if (this.maxSpawnDelay <= this.minSpawnDelay) {
			this.spawnDelay = this.minSpawnDelay;
		} else {
			int i = this.maxSpawnDelay - this.minSpawnDelay;
			
			this.spawnDelay = this.minSpawnDelay + this.getSpawnerWorld().random.nextInt(i);
		}
		
		if (this.mobs.size() > 0) {
			this.setSpawnData(WeightedRandom.a(this.getSpawnerWorld().random, this.mobs));
		}
		
		this.a(1);
	}
	
	public void readFromNBT(NBTTagCompound tag) {
		this.mobName = tag.getString("EntityId");
		this.spawnDelay = tag.getShort("Delay");
		this.mobs.clear();
		if (tag.hasKeyOfType("SpawnPotentials", 9)) {
			NBTTagList nbttaglist = tag.getList("SpawnPotentials", 10);
			
			for (int i = 0; i < nbttaglist.size(); ++i) {
				this.mobs.add(new SpawnData(nbttaglist.getCompound(i)));
			}
		}
		
		if (tag.hasKeyOfType("SpawnData", 10)) {
			this.setSpawnData(new SpawnData(tag.getCompound("SpawnData"), this.mobName));
		} else {
			this.setSpawnData(null);
		}
		
		if (tag.hasKeyOfType("MinSpawnDelay", 99)) {
			this.minSpawnDelay = tag.getShort("MinSpawnDelay");
			this.maxSpawnDelay = tag.getShort("MaxSpawnDelay");
			this.spawnCount = tag.getShort("SpawnCount");
		}
		
		if (tag.hasKeyOfType("MaxNearbyEntities", 99)) {
			this.maxNearbyEntities = tag.getShort("MaxNearbyEntities");
			this.requiredPlayerRange = tag.getShort("RequiredPlayerRange");
		}
		
		if (tag.hasKeyOfType("SpawnRange", 99)) {
			this.spawnRange = tag.getShort("SpawnRange");
		}
		
		if (this.getSpawnerWorld() != null) {
			this.renderEntity = null;
		}
		
	}
	
	public void writeToNBT(NBTTagCompound tag) {
		String s = this.getMobName();
		
		if (!UtilColor.b(s)) {
			tag.setString("EntityId", s);
			tag.setShort("Delay", (short) this.spawnDelay);
			tag.setShort("MinSpawnDelay", (short) this.minSpawnDelay);
			tag.setShort("MaxSpawnDelay", (short) this.maxSpawnDelay);
			tag.setShort("SpawnCount", (short) this.spawnCount);
			tag.setShort("MaxNearbyEntities", (short) this.maxNearbyEntities);
			tag.setShort("RequiredPlayerRange", (short) this.requiredPlayerRange);
			tag.setShort("SpawnRange", (short) this.spawnRange);
			if (spawnData != null) {
				tag.set("SpawnData", spawnData.data.clone());
			}
			
			if (spawnData != null || this.mobs.size() > 0) {
				NBTTagList nbttaglist = new NBTTagList();
				
				if (this.mobs.size() > 0) {
					for (SpawnData mobspawnerabstract_a : this.mobs) {
						nbttaglist.add(mobspawnerabstract_a.toNBT());
					}
				} else {
					nbttaglist.add(spawnData.toNBT());
				}
				
				tag.set("SpawnPotentials", nbttaglist);
			}
			
		}
	}
	
	/**
  * Sets the delay to minDelay if parameter given is 1, else return false.
  */
	public boolean setDelayToMin(int i) {
		if (i == 1 && this.getSpawnerWorld().isClientSide) {
			this.spawnDelay = this.minSpawnDelay;
			return true;
		} else {
			return false;
		}
	}
	
	public List getMobs() {
		return mobs;
	}
	
	public double getMobRotation() {
		return mobRotation;
	}
	
	public double getPrevMobRotation() {
		return prevMobRotation;
	}
	
	public SpawnData getSpawnData() {
		return this.spawnData;
	}
	
	public void setSpawnData(SpawnData data) {
		this.spawnData = data;
	}
	
	public abstract void a(int id);
	
	public abstract World getSpawnerWorld();
	
	public abstract BlockPosition getSpawnerPosition();
	
	public static class SpawnData extends WeightedRandom.WeightedRandomChoice {
		
		private final NBTTagCompound data;
		private final String entityType;
		
		public SpawnData(NBTTagCompound tag) {
			this(tag.getCompound("Properties"), tag.getString("Type"), tag.getInt("Weight"));
		}
		
		public SpawnData(NBTTagCompound nbttagcompound, String s) {
			this(nbttagcompound, s, 1);
		}
		
		private SpawnData(NBTTagCompound tag, String s, int i) {
			super(i);
			if (s.equals("Minecart")) {
				if (tag != null) {
					s = EntityMinecartAbstract.EnumMinecartType.a(tag.getInt("Type")).b();
				} else {
					s = "MinecartRideable";
				}
			}
			
			this.data = tag;
			this.entityType = s;
		}
		
		public NBTTagCompound toNBT() {
			NBTTagCompound tag = new NBTTagCompound();
			
			tag.set("Properties", this.data);
			tag.setString("Type", this.entityType);
			tag.setInt("Weight", this.a);
			return tag;
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy