use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method callInteractItemEventPrimary.
public static InteractItemEvent callInteractItemEventPrimary(EntityPlayer player, ItemStack stack, EnumHand hand, @Nullable Vector3d hitVec, Object hitTarget) {
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
if (hitTarget instanceof Entity) {
Sponge.getCauseStackManager().addContext(EventContextKeys.ENTITY_HIT, ((Entity) hitTarget));
} else if (hitTarget instanceof BlockSnapshot) {
Sponge.getCauseStackManager().addContext(EventContextKeys.BLOCK_HIT, (BlockSnapshot) hitTarget);
}
InteractItemEvent.Primary event;
if (hand == EnumHand.MAIN_HAND) {
event = SpongeEventFactory.createInteractItemEventPrimaryMainHand(Sponge.getCauseStackManager().getCurrentCause(), HandTypes.MAIN_HAND, Optional.ofNullable(hitVec), ItemStackUtil.snapshotOf(stack));
} else {
event = SpongeEventFactory.createInteractItemEventPrimaryOffHand(Sponge.getCauseStackManager().getCurrentCause(), HandTypes.OFF_HAND, Optional.ofNullable(hitVec), ItemStackUtil.snapshotOf(stack));
}
SpongeImpl.postEvent(event);
return event;
}
}
use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method callChangeBlockEventModifyLiquidMix.
public static ChangeBlockEvent.Modify callChangeBlockEventModifyLiquidMix(net.minecraft.world.World worldIn, BlockPos pos, IBlockState state, @Nullable Object source) {
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData data = phaseTracker.getCurrentPhaseData();
BlockState fromState = BlockUtil.fromNative(worldIn.getBlockState(pos));
BlockState toState = BlockUtil.fromNative(state);
User owner = data.context.getOwner().orElse(null);
User notifier = data.context.getNotifier().orElse(null);
if (source == null) {
// If source is null the source is the block itself
source = LocatableBlock.builder().state(fromState).world(((World) worldIn)).position(pos.getX(), pos.getY(), pos.getZ()).build();
}
try (CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
Sponge.getCauseStackManager().pushCause(source);
Sponge.getCauseStackManager().addContext(EventContextKeys.LIQUID_MIX, (World) worldIn);
if (owner != null) {
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner);
}
if (notifier != null) {
Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier);
}
WorldProperties world = ((World) worldIn).getProperties();
Vector3i position = new Vector3i(pos.getX(), pos.getY(), pos.getZ());
Transaction<BlockSnapshot> transaction = new Transaction<>(BlockSnapshot.builder().blockState(fromState).world(world).position(position).build(), BlockSnapshot.builder().blockState(toState).world(world).position(position).build());
ChangeBlockEvent.Modify event = SpongeEventFactory.createChangeBlockEventModify(Sponge.getCauseStackManager().getCurrentCause(), Collections.singletonList(transaction));
SpongeImpl.postEvent(event);
return event;
}
}
use of org.spongepowered.api.block.BlockSnapshot 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.block.BlockSnapshot in project SpongeCommon by SpongePowered.
the class MixinEntityLightningBolt method onStrikeBlock.
private boolean onStrikeBlock(net.minecraft.world.World world, BlockPos pos, IBlockState blockState) {
if (!this.effect && ((World) world).containsBlock(pos.getX(), pos.getY(), pos.getZ())) {
Vector3i pos3i = VecHelper.toVector3i(pos);
Transaction<BlockSnapshot> transaction = new Transaction<BlockSnapshot>(new SpongeBlockSnapshotBuilder().blockState((BlockState) world.getBlockState(pos)).world(((World) world).getProperties()).position(pos3i).build(), new SpongeBlockSnapshotBuilder().blockState((BlockState) blockState).world(((World) world).getProperties()).position(pos3i).build());
if (!this.struckBlocks.contains(transaction)) {
this.struckBlocks.add(transaction);
}
return true;
}
return false;
}
use of org.spongepowered.api.block.BlockSnapshot in project SpongeCommon by SpongePowered.
the class SpongeHooks method getFriendlyCauseName.
public static String getFriendlyCauseName(Cause cause) {
String causedBy = "Unknown";
Object rootCause = cause.root();
if (rootCause instanceof User) {
User user = (User) rootCause;
causedBy = user.getName();
} else if (rootCause instanceof EntityItem) {
EntityItem item = (EntityItem) rootCause;
causedBy = item.getItem().getDisplayName();
} else if (rootCause instanceof Entity) {
Entity causeEntity = (Entity) rootCause;
causedBy = causeEntity.getName();
} else if (rootCause instanceof BlockSnapshot) {
BlockSnapshot snapshot = (BlockSnapshot) rootCause;
causedBy = snapshot.getState().getType().getId();
} else if (rootCause instanceof CatalogType) {
CatalogType type = (CatalogType) rootCause;
causedBy = type.getId();
} else if (rootCause instanceof PluginContainer) {
PluginContainer plugin = (PluginContainer) rootCause;
causedBy = plugin.getId();
} else {
causedBy = rootCause.getClass().getName();
}
return causedBy;
}
Aggregations