use of net.glowstone.block.GlowBlock in project Glowstone by GlowstoneMC.
the class GlowLivingEntity method pulse.
////////////////////////////////////////////////////////////////////////////
// Internals
@Override
public void pulse() {
super.pulse();
if (isDead()) {
deathTicks++;
if (deathTicks >= 20 && getClass() != GlowPlayer.class) {
remove();
}
}
// invulnerability
if (noDamageTicks > 0) {
--noDamageTicks;
}
Material mat = getEyeLocation().getBlock().getType();
// breathing
if (mat == Material.WATER || mat == Material.STATIONARY_WATER) {
if (canTakeDamage(DamageCause.DROWNING)) {
--airTicks;
if (airTicks <= -20) {
airTicks = 0;
damage(1, DamageCause.DROWNING);
}
}
} else {
airTicks = maximumAir;
}
if (isTouchingMaterial(Material.CACTUS)) {
damage(1, DamageCause.CONTACT);
}
if (location.getY() < -64) {
// no canTakeDamage call - pierces through game modes
damage(4, DamageCause.VOID);
}
if (isWithinSolidBlock())
damage(1, DamageCause.SUFFOCATION);
if (getLocation().getBlock().getType() == Material.LAVA || getLocation().getBlock().getType() == Material.STATIONARY_LAVA) {
damage(4, DamageCause.LAVA);
if (swamInLava) {
setFireTicks(getFireTicks() + 2);
} else {
setFireTicks(getFireTicks() + 300);
swamInLava = true;
}
} else {
swamInLava = false;
if (getLocation().getBlock().getType() == Material.WATER || getLocation().getBlock().getType() == Material.STATIONARY_WATER) {
setFireTicks(0);
}
}
// potion effects
List<PotionEffect> effects = new ArrayList<>(potionEffects.values());
for (PotionEffect effect : effects) {
// pulse effect
PotionEffectType type = effect.getType();
GlowPotionEffect glowType = GlowPotionEffect.getEffect(type);
if (glowType != null) {
glowType.pulse(this, effect);
}
if (effect.getDuration() > 0) {
// reduce duration and re-add
addPotionEffect(new PotionEffect(type, effect.getDuration() - 1, effect.getAmplifier(), effect.isAmbient()), true);
} else {
// remove
removePotionEffect(type);
}
}
if (getFireTicks() > 0 && getFireTicks() % 20 == 0) {
damage(1, DamageCause.FIRE_TICK);
}
GlowBlock under = (GlowBlock) getLocation().getBlock().getRelative(BlockFace.DOWN);
BlockType type = ItemTable.instance().getBlock(under.getType());
if (type != null) {
type.onEntityStep(under, this);
}
nextAmbientTime--;
if (!isDead() && getAmbientSound() != null && nextAmbientTime == 0 && !isSilent()) {
double v = ThreadLocalRandom.current().nextDouble();
if (v <= 0.2) {
world.playSound(getLocation(), getAmbientSound(), getSoundVolume(), getSoundPitch());
}
}
if (nextAmbientTime == 0) {
nextAmbientTime = getAmbientDelay();
}
}
use of net.glowstone.block.GlowBlock in project Glowstone by GlowstoneMC.
the class BlockBed method getExitLocation.
/**
* Returns an 'empty' block next to the bed used to put the player at when they exit a bed / respawn.
*
* @param head head of the bed
* @param foot foot of the bed
* @return Exit block or {@code null} if all spots are blocked
*/
public static Block getExitLocation(GlowBlock head, GlowBlock foot) {
// First check blocks near head
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
Block b = head.getRelative(x, 0, z);
boolean floorValid = b.getRelative(BlockFace.DOWN).getType().isSolid();
boolean bottomValid = isValidSpawn(b.getType());
boolean topValid = isValidSpawn(b.getRelative(BlockFace.UP).getType());
if (floorValid && bottomValid && topValid) {
return b;
}
}
}
// Then check the last three blocks near foot
BlockFace face = head.getFace(foot);
int modX = face.getModX();
int modZ = face.getModZ();
for (int x = modX == 0 ? -1 : modX; x <= (modX == 0 ? 1 : modX); x++) {
for (int z = modZ == 0 ? -1 : modZ; z <= (modZ == 0 ? 1 : modZ); z++) {
Block b = foot.getRelative(x, 0, z);
boolean floorValid = b.getRelative(BlockFace.DOWN).getType().isSolid();
boolean bottomValid = isValidSpawn(b.getType());
boolean topValid = isValidSpawn(b.getRelative(BlockFace.UP).getType());
if (floorValid && bottomValid && topValid) {
return b;
}
}
}
return null;
}
use of net.glowstone.block.GlowBlock in project Glowstone by GlowstoneMC.
the class GlowWorld method pulseTickMap.
private void pulseTickMap() {
ItemTable itemTable = ItemTable.instance();
for (Location location : getTickMap()) {
if (!location.getChunk().isLoaded()) {
continue;
}
BlockType type = itemTable.getBlock(Material.getMaterial(getBlockTypeIdAt(location)));
if (type == null) {
cancelPulse(location);
continue;
}
GlowBlock block = (GlowBlock) location.getBlock();
Integer speed = type.getPulseTickSpeed(block);
boolean once = type.isPulseOnce(block);
if (speed == 0) {
continue;
}
if (worldAge % speed == 0) {
type.receivePulse(block);
if (once) {
cancelPulse(location);
}
}
}
}
use of net.glowstone.block.GlowBlock in project Glowstone by GlowstoneMC.
the class Explosion method explodeWithEvent.
public boolean explodeWithEvent() {
if (power < 0.1f)
return true;
Set<BlockVector> droppedBlocks = calculateBlocks();
EntityExplodeEvent event = EventFactory.callEvent(new EntityExplodeEvent(source, location, toBlockList(droppedBlocks), yield));
if (event.isCancelled())
return false;
yield = event.getYield();
playOutSoundAndParticles();
List<Block> blocks = toBlockList(droppedBlocks);
for (Block block : blocks) {
handleBlockExplosion((GlowBlock) block);
}
if (incendiary) {
for (Block block : blocks) {
setBlockOnFire((GlowBlock) block);
}
}
Collection<GlowPlayer> affectedPlayers = damageEntities();
for (GlowPlayer player : affectedPlayers) {
playOutExplosion(player, droppedBlocks);
}
return true;
}
use of net.glowstone.block.GlowBlock in project Glowstone by GlowstoneMC.
the class BlockPlacementHandler method handle.
@Override
public void handle(GlowSession session, BlockPlacementMessage message) {
//TODO: Hand handling instead of .getHeldItem()
GlowPlayer player = session.getPlayer();
if (player == null)
return;
//GlowServer.logger.info(session + ": " + message);
/*
* The client sends this packet for the following cases:
* Right click air:
* - Send direction=-1 packet for any non-null item
* Right click block:
* - Send packet with all values filled
* - If client DOES NOT expect a block placement to result:
* - Send direction=-1 packet (unless item is null)
*
* Client will expect a block placement to result from blocks and from
* certain items (e.g. sugarcane, sign). We *could* opt to trust the
* client on this, but the server's view of events (particularly under
* the Bukkit API, or custom ItemTypes) may differ from the client's.
*
* In order to avoid firing two events for one interact, the two
* packet case must be handled here. Care must also be taken that a
* right-click air of an expected-place item immediately after is
* not considered part of the same action.
*/
Action action = Action.RIGHT_CLICK_BLOCK;
GlowBlock clicked = player.getWorld().getBlockAt(message.getX(), message.getY(), message.getZ());
/*
* Check if the message is a -1. If we *just* got a message with the
* values filled, discard it, otherwise perform right-click-air.
*/
if (message.getDirection() == -1) {
BlockPlacementMessage previous = session.getPreviousPlacement();
// session.setPreviousPlacement(null);
return;
// }
}
// Set previous placement message
session.setPreviousPlacement(message);
// Get values from the message
Vector clickedLoc = new Vector(message.getCursorX(), message.getCursorY(), message.getCursorZ());
BlockFace face = convertFace(message.getDirection());
ItemStack holding = player.getItemInHand();
boolean rightClickedAir = false;
// check that a block-click wasn't against air
if (clicked == null || clicked.getType() == Material.AIR) {
action = Action.RIGHT_CLICK_AIR;
// inform the player their perception of reality is wrong
if (holding.getType().isBlock()) {
player.sendBlockChange(clicked.getLocation(), Material.AIR, (byte) 0);
return;
} else {
rightClickedAir = true;
}
}
// call interact event
PlayerInteractEvent event = EventFactory.onPlayerInteract(player, action, rightClickedAir ? null : clicked, face);
//GlowServer.logger.info("Interact: " + action + " " + clicked + " " + face);
// attempt to use interacted block
// DEFAULT is treated as ALLOW, and sneaking is always considered
boolean useInteractedBlock = event.useInteractedBlock() != Result.DENY;
if (useInteractedBlock && !rightClickedAir && (!player.isSneaking() || InventoryUtil.isEmpty(holding))) {
BlockType blockType = ItemTable.instance().getBlock(clicked.getType());
if (blockType != null) {
useInteractedBlock = blockType.blockInteract(player, clicked, face, clickedLoc);
} else {
GlowServer.logger.info("Unknown clicked block, " + clicked.getType());
}
} else {
useInteractedBlock = false;
}
// follows ALLOW/DENY: default to if no block was interacted with
if (selectResult(event.useItemInHand(), !useInteractedBlock) && holding != null) {
ItemType type = ItemTable.instance().getItem(holding.getType());
if (!rightClickedAir && holding.getType() != Material.AIR && !type.canOnlyUseSelf()) {
type.rightClickBlock(player, clicked, face, holding, clickedLoc);
}
}
// in case something is unimplemented or otherwise screwy on our side
if (!rightClickedAir) {
revert(player, clicked);
revert(player, clicked.getRelative(face));
}
// if there's been a change in the held item, make it valid again
if (!InventoryUtil.isEmpty(holding)) {
if (holding.getType().getMaxDurability() > 0 && holding.getDurability() > holding.getType().getMaxDurability()) {
holding.setAmount(holding.getAmount() - 1);
holding.setDurability((short) 0);
}
if (holding.getAmount() <= 0) {
holding = null;
}
}
player.setItemInHand(holding);
}
Aggregations