blob: fc8eb510a7627e43f425326c0c5ed5e2027924aa [file] [log] [blame] [raw]
package net.glowstone.entity;
import com.flowpowered.network.Message;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import lombok.Getter;
import lombok.Setter;
import net.glowstone.EventFactory;
import net.glowstone.Explosion;
import net.glowstone.net.message.play.entity.SpawnObjectMessage;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.util.Vector;
public class GlowTntPrimed extends GlowExplosive implements TNTPrimed {
@Getter
@Setter
private int fuseTicks;
@Setter
private Entity source;
/**
* Get the player that ignited the TNT.
*
* @return Player that ignited the TNT
*/
public GlowPlayer getPlayer() {
Entity source = getSource();
return (source instanceof GlowPlayer) ? (GlowPlayer) source : null;
}
/**
* Creates a primed TNT block, not associated with any igniting entity.
*
* @param location the location
*/
public GlowTntPrimed(Location location) {
this(location, null);
}
/**
* Creates a primed TNT block.
*
* @param location the location
* @param source the entity that ignited this; may be null
*/
public GlowTntPrimed(Location location, Entity source) {
super(location, Explosion.POWER_TNT);
setSize(0.98f, 0.98f);
fuseTicks = 0;
ThreadLocalRandom rand = ThreadLocalRandom.current();
int multiplier = rand.nextBoolean() ? 1 : -1;
double x = 0;
double z = 0;
double mag = rand.nextDouble(0, 0.02);
if (rand.nextBoolean()) {
x = multiplier * mag;
} else {
z = multiplier * mag;
}
setVelocity(new Vector(x, 0.2, z));
this.source = source;
}
/**
* Sets whether this TNT was ignited by an explosion or not. This is not tracked, but affects
* the fuse length.
*
* @param ignitedByExplosion whether this TNT was ignited by an explosion
*/
public void setIgnitedByExplosion(boolean ignitedByExplosion) {
if (ignitedByExplosion) {
// if ignited by an explosion, the fuseTicks should be a random number between 10 and 30
// ticks
fuseTicks = ThreadLocalRandom.current().nextInt(10, 31);
} else {
fuseTicks = 80;
}
}
@Override
public void pulse() {
super.pulse();
fuseTicks--;
if (fuseTicks <= 0) {
explode();
} else {
world.playEffect(location.clone().add(0, 0.5, 0), Effect.SMOKE, 0);
}
}
private void explode() {
ExplosionPrimeEvent event = EventFactory.callEvent(new ExplosionPrimeEvent(this));
if (!event.isCancelled()) {
Location location = getLocation();
world.createExplosion(this,
location.getX(), location.getY() + 0.06125, location.getZ(),
event.getRadius(), event.getFire(), true);
}
remove();
}
@Override
public List<Message> createSpawnMessage() {
return Collections.singletonList(new SpawnObjectMessage(
entityId, getUniqueId(), 50, location));
}
@Override
public final Entity getSource() {
return (source != null && source.isValid()) ? source : null;
}
@Override
public final EntityType getType() {
return EntityType.PRIMED_TNT;
}
}