use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.
the class PlayerInteractionHandler method handleBrokenBlock.
private void handleBrokenBlock() {
final Location<World> location = new Location<>(this.player.getWorld(), this.diggingBlock);
final CauseStack causeStack = CauseStack.current();
try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
frame.pushCause(this.player);
// Add context
frame.addContext(EventContextKeys.PLAYER, this.player);
frame.addContext(ContextKeys.INTERACTION_LOCATION, location);
frame.addContext(ContextKeys.BLOCK_LOCATION, location);
final BehaviorContextImpl context = new BehaviorContextImpl(causeStack);
final BlockState blockState = location.getBlock();
final LanternBlockType blockType = (LanternBlockType) blockState.getType();
if (context.process(blockType.getPipeline().pipeline(BreakBlockBehavior.class), (ctx, behavior) -> behavior.tryBreak(blockType.getPipeline(), ctx)).isSuccess()) {
context.accept();
this.diggingBlock = null;
this.diggingBlockType = null;
} else {
context.revert();
// TODO: Resend tile entity data, action data, ... ???
this.player.sendBlockChange(this.diggingBlock, blockState);
}
if (this.lastBreakState != -1) {
sendBreakUpdate(-1);
}
}
}
use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.
the class LanternPlayer method handleRespawn.
public void handleRespawn() {
Transform<World> transform = getTransform();
final LanternWorld world = (LanternWorld) transform.getExtent();
if (isDead()) {
// TODO: Get the proper spawn location
final Transform<World> toTransform = new Transform<>(transform.getExtent(), new Vector3d(0, 100, 0));
// Make the player less dead...
setDead(false);
// Reset player settings
offer(Keys.HEALTH, get(Keys.MAX_HEALTH).get());
offer(Keys.FOOD_LEVEL, get(LanternKeys.MAX_FOOD_LEVEL).get());
offer(Keys.ABSORPTION, 0.0);
offer(Keys.EXHAUSTION, DEFAULT_EXHAUSTION);
offer(Keys.SATURATION, DEFAULT_SATURATION);
offer(Keys.POTION_EFFECTS, new ArrayList<>());
offer(LanternKeys.SCORE, 0);
final CauseStack causeStack = CauseStack.current();
try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
frame.pushCause(this);
frame.addContext(EventContextKeys.PLAYER, this);
final RespawnPlayerEvent event = SpongeEventFactory.createRespawnPlayerEvent(causeStack.getCurrentCause(), transform, toTransform, this, this, false, true);
Sponge.getEventManager().post(event);
// Get the to transform, this can be overridden in the event
transform = event.getToTransform();
}
}
setWorld(world, (LanternWorld) transform.getExtent());
setPosition(transform.getPosition());
}
use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.
the class LanternEntity method remove.
public void remove(RemoveState removeState) {
checkNotNull(removeState, "removeState");
if (this.removeState == removeState) {
return;
}
this.removeState = removeState;
if (removeState == RemoveState.DESTROYED) {
setVehicle(null);
clearPassengers();
// don't do it if the entity is dead.
if (!isDead()) {
setDead(true);
final CauseStack causeStack = CauseStack.current();
// TODO: Message channel?
final DestructEntityEvent event = SpongeEventFactory.createDestructEntityEvent(causeStack.getCurrentCause(), MessageChannel.TO_NONE, Optional.empty(), new MessageEvent.MessageFormatter(), this, false);
postDestructEvent(event);
}
}
}
use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.
the class LanternEntity method damage.
@Override
public boolean damage(double damage, DamageSource damageSource) {
checkNotNull(damageSource, "damageSource");
final Optional<Double> optHealth = get(Keys.HEALTH);
if (!optHealth.isPresent()) {
// entities without health, instantly destroying them.
if (damageSource.getType() == DamageTypes.VOID) {
remove(RemoveState.DESTROYED);
return true;
}
return false;
}
// Always throw the event. Plugins may want to override
// default checking behavior.
boolean cancelled = false;
// if the player is in creative mode
if (!damageSource.doesAffectCreative() && get(Keys.GAME_MODE).orElse(null) == GameModes.CREATIVE) {
cancelled = true;
}
final List<Tuple<DamageFunction, Consumer<DamageEntityEvent>>> damageFunctions = new ArrayList<>();
// Only collect damage modifiers if the event isn't cancelled
if (!cancelled) {
collectDamageFunctions(damageFunctions);
}
// TODO: Damage modifiers, etc.
final CauseStack causeStack = CauseStack.current();
try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
frame.pushCause(damageSource);
frame.addContext(EventContextKeys.DAMAGE_TYPE, damageSource.getType());
final DamageEntityEvent event = SpongeEventFactory.createDamageEntityEvent(frame.getCurrentCause(), damageFunctions.stream().map(Tuple::getFirst).collect(Collectors.toList()), this, damage);
event.setCancelled(cancelled);
Sponge.getEventManager().post(event);
if (event.isCancelled()) {
return false;
}
damageFunctions.forEach(tuple -> tuple.getSecond().accept(event));
damage = event.getFinalDamage();
if (damage > 0) {
offer(Keys.HEALTH, Math.max(optHealth.get() - damage, 0));
}
final double exhaustion = damageSource.getExhaustion();
getValue(Keys.EXHAUSTION).ifPresent(value -> offer(Keys.EXHAUSTION, Math.min(value.getMaxValue(), value.get() + exhaustion)));
}
triggerEvent(DamagedEntityEvent.of());
return true;
}
use of org.lanternpowered.server.event.CauseStack in project LanternServer by LanternPowered.
the class LanternItem method combineItemStacks.
@Nullable
private CombineData combineItemStacks(int pickupDelay, int despawnDelay) {
// Remove items with no item stack
final ItemStackSnapshot itemStackSnapshot1 = get(Keys.REPRESENTED_ITEM).orElse(null);
if (itemStackSnapshot1 == null || itemStackSnapshot1.isEmpty()) {
remove();
return null;
}
final int max = itemStackSnapshot1.getType().getMaxStackQuantity();
int quantity1 = itemStackSnapshot1.getQuantity();
// Check if the stack is already at it's maximum size
if (quantity1 >= max) {
return null;
}
final CauseStack causeStack = CauseStack.current();
final CauseStack.Frame frame = causeStack.pushCauseFrame();
frame.pushCause(this);
// Search for surrounding items
final Set<Entity> entities = getWorld().getIntersectingEntities(getBoundingBox().get().expand(0.6, 0.0, 0.6), entity -> entity != this && entity instanceof LanternItem);
ItemStack itemStack1 = null;
for (Entity entity : entities) {
final int pickupDelay1 = entity.get(Keys.PICKUP_DELAY).orElse(0);
if (pickupDelay1 == NO_PICKUP_DELAY) {
continue;
}
final ItemStackSnapshot itemStackSnapshot2 = entity.get(Keys.REPRESENTED_ITEM).get();
int quantity2 = itemStackSnapshot2.getQuantity();
// make sure that the stacks can be merged
if (quantity2 >= max || !LanternItemStack.areSimilar(itemStackSnapshot1, itemStackSnapshot2)) {
continue;
}
// Call the merge event
final ItemMergeItemEvent event = SpongeEventFactory.createItemMergeItemEvent(causeStack.getCurrentCause(), (Item) entity, this);
Sponge.getEventManager().post(event);
if (event.isCancelled()) {
continue;
}
// Merge the items
quantity1 += quantity2;
if (quantity1 > max) {
quantity2 = quantity1 - max;
quantity1 = max;
// Create a new stack and offer it back the entity
final ItemStack itemStack2 = itemStackSnapshot2.createStack();
itemStack2.setQuantity(quantity2);
// The snapshot can be wrapped
entity.offer(Keys.REPRESENTED_ITEM, LanternItemStackSnapshot.wrap(itemStack2));
} else {
// The other entity is completely drained and will be removed
entity.offer(Keys.REPRESENTED_ITEM, ItemStackSnapshot.NONE);
entity.remove();
}
// The item stack has changed
if (itemStack1 == null) {
itemStack1 = itemStackSnapshot1.createStack();
}
itemStack1.setQuantity(quantity1);
// When merging items, also merge the pickup and despawn delays
pickupDelay = Math.max(pickupDelay, pickupDelay1);
despawnDelay = Math.max(despawnDelay, entity.get(Keys.DESPAWN_DELAY).orElse(NO_DESPAWN_DELAY));
// The stack is already full, stop here
if (quantity1 == max) {
break;
}
}
causeStack.popCauseFrame(frame);
if (itemStack1 != null) {
offer(Keys.REPRESENTED_ITEM, LanternItemStackSnapshot.wrap(itemStack1));
return new CombineData(pickupDelay, despawnDelay);
}
return null;
}
Aggregations