use of org.spongepowered.api.event.block.ChangeBlockEvent in project HuskyCrates-Sponge by codeHusky.
the class HuskyCrates method placeBlock.
@Listener
public void placeBlock(ChangeBlockEvent event) {
if (event.getCause().root() instanceof Player) {
Player plr = (Player) event.getCause().root();
if (event instanceof ChangeBlockEvent.Place || event instanceof ChangeBlockEvent.Break) {
BlockType t = event.getTransactions().get(0).getOriginal().getLocation().get().getBlock().getType();
Location<World> location = event.getTransactions().get(0).getOriginal().getLocation().get();
location.getBlock().toContainer().set(DataQuery.of("rock"), 1);
//location.getBlock().with()
if (validCrateBlocks.contains(t)) {
//crateUtilities.recognizeChest(event.getTransactions().get(0).getOriginal().getLocation().get());
if (event instanceof ChangeBlockEvent.Place) {
if (plr.getItemInHand(HandTypes.MAIN_HAND).isPresent()) {
Optional<Object> tt = plr.getItemInHand(HandTypes.MAIN_HAND).get().toContainer().get(DataQuery.of("UnsafeData", "crateID"));
if (tt.isPresent()) {
String crateID = tt.get().toString();
if (!plr.hasPermission("huskycrates.tester")) {
event.setCancelled(true);
return;
}
if (!crateUtilities.physicalCrates.containsKey(location))
crateUtilities.physicalCrates.put(location, new PhysicalCrate(location, crateID, this));
crateUtilities.physicalCrates.get(location).createHologram();
updatePhysicalCrates();
}
}
}
} else {
if (crateUtilities.physicalCrates.containsKey(location)) {
if (!plr.hasPermission("huskycrates.tester")) {
event.setCancelled(true);
return;
}
crateUtilities.flag = true;
crateUtilities.physicalCrates.get(location).as.remove();
crateUtilities.physicalCrates.remove(location);
updatePhysicalCrates();
}
}
}
}
}
use of org.spongepowered.api.event.block.ChangeBlockEvent in project SpongeCommon by SpongePowered.
the class TrackingUtil method throwMultiEventsAndCreatePost.
public static ChangeBlockEvent.Post throwMultiEventsAndCreatePost(ImmutableList<Transaction<BlockSnapshot>>[] transactionArrays, List<ChangeBlockEvent> blockEvents, ChangeBlockEvent[] mainEvents) {
if (!blockEvents.isEmpty()) {
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
for (BlockChange blockChange : BlockChange.values()) {
final ChangeBlockEvent mainEvent = mainEvents[blockChange.ordinal()];
if (mainEvent != null) {
Sponge.getCauseStackManager().pushCause(mainEvent);
}
}
final ImmutableList<Transaction<BlockSnapshot>> transactions = transactionArrays[MULTI_CHANGE_INDEX];
final ChangeBlockEvent.Post post = SpongeEventFactory.createChangeBlockEventPost(Sponge.getCauseStackManager().getCurrentCause(), transactions);
SpongeImpl.postEvent(post);
return post;
}
}
return null;
}
use of org.spongepowered.api.event.block.ChangeBlockEvent in project SpongeCommon by SpongePowered.
the class GeneralPhase method processBlockTransactionListsPost.
/**
* @param snapshotsToProcess
* @param unwindingState
* @param unwinding
*/
@SuppressWarnings({ "unchecked" })
public static void processBlockTransactionListsPost(PhaseContext<?> postContext, List<BlockSnapshot> snapshotsToProcess, IPhaseState<?> unwindingState, PhaseContext<?> unwinding) {
final List<Transaction<BlockSnapshot>> invalidTransactions = new ArrayList<>();
ImmutableList<Transaction<BlockSnapshot>>[] transactionArrays = new ImmutableList[TrackingUtil.EVENT_COUNT];
ImmutableList.Builder<Transaction<BlockSnapshot>>[] transactionBuilders = new ImmutableList.Builder[TrackingUtil.EVENT_COUNT];
for (int i = 0; i < TrackingUtil.EVENT_COUNT; i++) {
transactionBuilders[i] = new ImmutableList.Builder<>();
}
final List<ChangeBlockEvent> blockEvents = new ArrayList<>();
for (BlockSnapshot snapshot : snapshotsToProcess) {
// This processes each snapshot to assign them to the correct event in the next area, with the
// correct builder array entry.
TrackingUtil.TRANSACTION_PROCESSOR.apply(transactionBuilders).accept(TrackingUtil.TRANSACTION_CREATION.apply(snapshot));
}
for (int i = 0; i < TrackingUtil.EVENT_COUNT; i++) {
// Build each event array
transactionArrays[i] = transactionBuilders[i].build();
}
// Clear captured snapshots after processing them
postContext.getCapturedBlocksOrEmptyList().clear();
final ChangeBlockEvent[] mainEvents = new ChangeBlockEvent[BlockChange.values().length];
// This likely needs to delegate to the phase in the event we don't use the source object as the main object causing the block changes
// case in point for WorldTick event listeners since the players are captured non-deterministically
// Creates the block events accordingly to the transaction arrays
TrackingUtil.iterateChangeBlockEvents(transactionArrays, blockEvents, mainEvents);
// We create the post event and of course post it in the method, regardless whether any transactions are invalidated or not
final ChangeBlockEvent.Post postEvent = TrackingUtil.throwMultiEventsAndCreatePost(transactionArrays, blockEvents, mainEvents);
if (postEvent == null) {
// Means that we have had no actual block changes apparently?
return;
}
// transactions of the preceeding block events)
for (ChangeBlockEvent blockEvent : blockEvents) {
// Need to only check if the event is cancelled, If it is, restore
if (blockEvent.isCancelled()) {
// Don't restore the transactions just yet, since we're just marking them as invalid for now
for (Transaction<BlockSnapshot> transaction : Lists.reverse(blockEvent.getTransactions())) {
transaction.setValid(false);
}
}
}
// Finally check the post event
if (postEvent.isCancelled()) {
// Of course, if post is cancelled, just mark all transactions as invalid.
for (Transaction<BlockSnapshot> transaction : postEvent.getTransactions()) {
transaction.setValid(false);
}
}
// Because after, we will restore all the invalid transactions in reverse order.
for (Transaction<BlockSnapshot> transaction : postEvent.getTransactions()) {
if (!transaction.isValid()) {
invalidTransactions.add(transaction);
}
}
if (!invalidTransactions.isEmpty()) {
// or the events were cancelled), again in reverse order of which they were received.
for (Transaction<BlockSnapshot> transaction : Lists.reverse(invalidTransactions)) {
transaction.getOriginal().restore(true, BlockChangeFlags.NONE);
if (unwindingState.tracksBlockSpecificDrops()) {
// Cancel any block drops or harvests for the block change.
// This prevents unnecessary spawns.
final Location<World> location = transaction.getOriginal().getLocation().orElse(null);
if (location != null) {
// Cancel any block drops performed, avoids any item drops, regardless
final BlockPos pos = ((IMixinLocation) (Object) location).getBlockPos();
postContext.getBlockDropSupplier().removeAllIfNotEmpty(pos);
}
}
}
invalidTransactions.clear();
}
performPostBlockAdditions(postContext, postEvent.getTransactions(), unwindingState, unwinding);
}
use of org.spongepowered.api.event.block.ChangeBlockEvent in project SpongeCommon by SpongePowered.
the class CustomExplosionState method processBlockCaptures.
@SuppressWarnings({ "unchecked" })
private void processBlockCaptures(List<BlockSnapshot> snapshots, Explosion explosion, Cause cause, PhaseContext<?> context) {
if (snapshots.isEmpty()) {
return;
}
ImmutableList<Transaction<BlockSnapshot>>[] transactionArrays = new ImmutableList[TrackingUtil.EVENT_COUNT];
ImmutableList.Builder<Transaction<BlockSnapshot>>[] transactionBuilders = new ImmutableList.Builder[TrackingUtil.EVENT_COUNT];
for (int i = 0; i < TrackingUtil.EVENT_COUNT; i++) {
transactionBuilders[i] = new ImmutableList.Builder<>();
}
final List<ChangeBlockEvent> blockEvents = new ArrayList<>();
for (BlockSnapshot snapshot : snapshots) {
// This processes each snapshot to assign them to the correct event in the next area, with the
// correct builder array entry.
TrackingUtil.TRANSACTION_PROCESSOR.apply(transactionBuilders).accept(TrackingUtil.TRANSACTION_CREATION.apply(snapshot));
}
for (int i = 0; i < TrackingUtil.EVENT_COUNT; i++) {
// Build each event array
transactionArrays[i] = transactionBuilders[i].build();
}
// Clear captured snapshots after processing them
context.getCapturedBlocksOrEmptyList().clear();
final ChangeBlockEvent[] mainEvents = new ChangeBlockEvent[BlockChange.values().length];
// case in point for WorldTick event listeners since the players are captured non-deterministically
try (StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
if (context.getNotifier().isPresent()) {
Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, context.getNotifier().get());
}
if (context.getOwner().isPresent()) {
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, context.getOwner().get());
}
try {
this.associateAdditionalCauses(this, context);
} catch (Exception e) {
// TODO - this should be a thing to associate additional objects in the cause, or context, but for now it's just a simple
// try catch to avoid bombing on performing block changes.
}
// Creates the block events accordingly to the transaction arrays
// Needs to throw events
iterateChangeBlockEvents(transactionArrays, blockEvents, mainEvents);
// Copied from TrackingUtil#throwMultiEventsAndCreatePost
for (BlockChange blockChange : BlockChange.values()) {
final ChangeBlockEvent mainEvent = mainEvents[blockChange.ordinal()];
if (mainEvent != null) {
Sponge.getCauseStackManager().pushCause(mainEvent);
}
}
final ImmutableList<Transaction<BlockSnapshot>> transactions = transactionArrays[TrackingUtil.MULTI_CHANGE_INDEX];
final ExplosionEvent.Post postEvent = SpongeEventFactory.createExplosionEventPost(cause, explosion, transactions);
if (postEvent == null) {
// Means that we have had no actual block changes apparently?
return;
}
SpongeImpl.postEvent(postEvent);
final List<Transaction<BlockSnapshot>> invalid = new ArrayList<>();
boolean noCancelledTransactions = true;
// transactions of the preceeding block events)
for (ChangeBlockEvent blockEvent : blockEvents) {
// Need to only check if the event is cancelled, If it is, restore
if (blockEvent.isCancelled()) {
noCancelledTransactions = false;
// Don't restore the transactions just yet, since we're just marking them as invalid for now
for (Transaction<BlockSnapshot> transaction : Lists.reverse(blockEvent.getTransactions())) {
transaction.setValid(false);
}
}
}
// Finally check the post event
if (postEvent.isCancelled()) {
// Of course, if post is cancelled, just mark all transactions as invalid.
noCancelledTransactions = false;
for (Transaction<BlockSnapshot> transaction : postEvent.getTransactions()) {
transaction.setValid(false);
}
}
// Because after, we will restore all the invalid transactions in reverse order.
for (Transaction<BlockSnapshot> transaction : postEvent.getTransactions()) {
if (!transaction.isValid()) {
invalid.add(transaction);
// Cancel any block drops performed, avoids any item drops, regardless
final Location<World> location = transaction.getOriginal().getLocation().orElse(null);
if (location != null) {
final BlockPos pos = ((IMixinLocation) (Object) location).getBlockPos();
context.getBlockItemDropSupplier().removeAllIfNotEmpty(pos);
}
}
}
if (!invalid.isEmpty()) {
// We need to set this value and return it to signify that some transactions were cancelled
noCancelledTransactions = false;
// or the events were cancelled), again in reverse order of which they were received.
for (Transaction<BlockSnapshot> transaction : Lists.reverse(invalid)) {
transaction.getOriginal().restore(true, BlockChangeFlags.NONE);
// Cancel any block drops or harvests for the block change.
// This prevents unnecessary spawns.
final Location<World> location = transaction.getOriginal().getLocation().orElse(null);
if (location != null) {
final BlockPos pos = ((IMixinLocation) (Object) location).getBlockPos();
context.getBlockDropSupplier().removeAllIfNotEmpty(pos);
}
}
}
TrackingUtil.performBlockAdditions(postEvent.getTransactions(), this, context, noCancelledTransactions);
}
}
use of org.spongepowered.api.event.block.ChangeBlockEvent in project SpongeForge by SpongePowered.
the class SpongeForgeEventFactory method createBlockEvent.
// Block events
public static BlockEvent createBlockEvent(Event event) {
ChangeBlockEvent spongeEvent = (ChangeBlockEvent) event;
Location<World> location = spongeEvent.getTransactions().get(0).getOriginal().getLocation().get();
net.minecraft.world.World world = (net.minecraft.world.World) location.getExtent();
BlockPos pos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
BlockEvent forgeEvent = new BlockEvent(world, pos, world.getBlockState(pos));
return forgeEvent;
}
Aggregations