use of org.spongepowered.api.data.Transaction in project SpongeForge by SpongePowered.
the class SpongeForgeEventFactory method createChangeBlockEventPlace.
public static ChangeBlockEvent.Place createChangeBlockEventPlace(BlockEvent.MultiPlaceEvent forgeEvent) {
final net.minecraft.world.World world = forgeEvent.getWorld();
if (world.isRemote) {
return null;
}
ImmutableList.Builder<Transaction<BlockSnapshot>> builder = new ImmutableList.Builder<Transaction<BlockSnapshot>>();
for (net.minecraftforge.common.util.BlockSnapshot blockSnapshot : forgeEvent.getReplacedBlockSnapshots()) {
final BlockPos snapshotPos = blockSnapshot.getPos();
BlockSnapshot originalSnapshot = ((IMixinBlockSnapshot) blockSnapshot).createSpongeBlockSnapshot();
BlockSnapshot finalSnapshot = ((World) world).createSnapshot(snapshotPos.getX(), snapshotPos.getY(), snapshotPos.getZ());
builder.add(new Transaction<>(originalSnapshot, finalSnapshot));
}
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData data = phaseTracker.getCurrentPhaseData();
User owner = data.context.getOwner().orElse(null);
User notifier = data.context.getNotifier().orElse(null);
EntityPlayer player = forgeEvent.getPlayer();
if (SpongeImplHooks.isFakePlayer(player)) {
Sponge.getCauseStackManager().addContext(EventContextKeys.FAKE_PLAYER, EntityUtil.toPlayer(player));
} else if (Sponge.getCauseStackManager().getCurrentCause() == null) {
Sponge.getCauseStackManager().pushCause(player);
}
if (owner != null) {
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, owner);
if (Sponge.getCauseStackManager().getCurrentCause() == null) {
Sponge.getCauseStackManager().pushCause(owner);
}
} else {
Sponge.getCauseStackManager().addContext(EventContextKeys.OWNER, (User) player);
if (Sponge.getCauseStackManager().getCurrentCause() == null) {
Sponge.getCauseStackManager().pushCause(player);
}
}
if (notifier != null) {
Sponge.getCauseStackManager().addContext(EventContextKeys.NOTIFIER, notifier);
}
return SpongeEventFactory.createChangeBlockEventPlace(Sponge.getCauseStackManager().getCurrentCause(), builder.build());
}
use of org.spongepowered.api.data.Transaction in project LanternServer by LanternPowered.
the class VanillaContainerInteractionBehavior method handleCreativeClick.
@Override
public void handleCreativeClick(ClientContainer clientContainer, @Nullable ClientSlot clientSlot, @Nullable ItemStack itemStack) {
final LanternPlayer player = clientContainer.getPlayer();
final CauseStack causeStack = CauseStack.current();
if (clientSlot == null) {
if (itemStack != null) {
causeStack.addContext(EventContextKeys.SPAWN_TYPE, SpawnTypes.DROPPED_ITEM);
LanternEventHelper.handleDroppedItemSpawning(player.getTransform(), itemStack.createSnapshot());
}
} else if (clientSlot instanceof ClientSlot.Slot) {
final AbstractSlot slot = ((ClientSlot.Slot) clientSlot).getSlot();
final PeekedSetTransactionResult result = slot.peekSet(itemStack);
// We do not know the remaining stack in the cursor,
// so just use none as new item
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(LanternItemStack.toSnapshot(itemStack), ItemStackSnapshot.NONE);
final ClickInventoryEvent.Creative event = SpongeEventFactory.createClickInventoryEventCreative(causeStack.getCurrentCause(), cursorTransaction, this.container, this.container.transformSlots(result.getTransactions()));
finishInventoryEvent(event);
}
}
use of org.spongepowered.api.data.Transaction in project LanternServer by LanternPowered.
the class VanillaContainerInteractionBehavior method handleDoubleClick.
@Override
public void handleDoubleClick(ClientContainer clientContainer, ClientSlot clientSlot) {
final LanternPlayer player = clientContainer.getPlayer();
if (player != this.container.getPlayerInventory().getCarrier().orElse(null) || !(clientSlot instanceof ClientSlot.Slot)) {
return;
}
final AbstractSlot slot = ((ClientSlot.Slot) clientSlot).getSlot();
final ItemStackSnapshot oldItem = LanternItemStack.toSnapshot(getCursorItem());
ItemStackSnapshot newItem = oldItem;
final List<SlotTransaction> transactions = new ArrayList<>();
if (getCursorItem() != null && !(slot instanceof OutputSlot)) {
final ItemStack cursorItem = getCursorItem().copy();
int quantity = cursorItem.getQuantity();
final int maxQuantity = cursorItem.getMaxStackQuantity();
if (quantity < maxQuantity) {
final AbstractInventory inventory;
if (clientContainer instanceof PlayerClientContainer) {
inventory = this.container.getPlayerInventory().getView(LanternPlayerInventory.View.ALL_PRIORITY_MAIN);
} else {
inventory = AbstractOrderedInventory.viewBuilder().inventory(this.container.getOpenInventory()).inventory(this.container.getPlayerInventory().getView(LanternPlayerInventory.View.PRIORITY_MAIN_AND_HOTBAR)).build();
}
// Try first to get enough unfinished stacks
PeekedPollTransactionResult peekResult = inventory.peekPoll(maxQuantity - quantity, stack -> stack.getQuantity() < stack.getMaxStackQuantity() && ((LanternItemStack) cursorItem).similarTo(stack)).orElse(null);
if (peekResult != null) {
quantity += peekResult.getPolledItem().getQuantity();
transactions.addAll(peekResult.getTransactions());
}
// Get the last items for the stack from a full stack
if (quantity <= maxQuantity) {
peekResult = this.container.peekPoll(maxQuantity - quantity, stack -> stack.getQuantity() >= stack.getMaxStackQuantity() && ((LanternItemStack) cursorItem).similarTo(stack)).orElse(null);
if (peekResult != null) {
quantity += peekResult.getPolledItem().getQuantity();
transactions.addAll(peekResult.getTransactions());
}
}
cursorItem.setQuantity(quantity);
newItem = cursorItem.createSnapshot();
}
}
final CauseStack causeStack = CauseStack.current();
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(oldItem, newItem);
final ClickInventoryEvent.Double event = SpongeEventFactory.createClickInventoryEventDouble(causeStack.getCurrentCause(), cursorTransaction, this.container, this.container.transformSlots(transactions));
finishInventoryEvent(event);
}
use of org.spongepowered.api.data.Transaction in project LanternServer by LanternPowered.
the class VanillaContainerInteractionBehavior method handleDrag.
@Override
public void handleDrag(ClientContainer clientContainer, List<ClientSlot> clientSlots, MouseButton mouseButton) {
final LanternPlayer player = clientContainer.getPlayer();
if (player != this.container.getPlayerInventory().getCarrier().orElse(null)) {
return;
}
final List<AbstractSlot> slots = clientSlots.stream().filter(clientSlot -> clientSlot instanceof ClientSlot.Slot).map(clientSlot -> ((ClientSlot.Slot) clientSlot).getSlot()).collect(Collectors.toList());
if (slots.size() != clientSlots.size()) {
// TODO: Is this the behavior we want?
return;
}
final ItemStack cursorItem = getCursorItem();
if (cursorItem == null || cursorItem.isEmpty()) {
return;
}
final CauseStack causeStack = CauseStack.current();
if (mouseButton == MouseButton.LEFT) {
final int quantity = cursorItem.getQuantity();
final int slotCount = slots.size();
final int itemsPerSlot = quantity / slotCount;
final int rest = quantity - itemsPerSlot * slotCount;
final List<SlotTransaction> transactions = new ArrayList<>();
for (AbstractSlot slot : slots) {
final ItemStack itemStack = cursorItem.copy();
itemStack.setQuantity(itemsPerSlot);
transactions.addAll(slot.peekOffer(itemStack).getTransactions());
}
ItemStackSnapshot newCursorItem = ItemStackSnapshot.NONE;
if (rest > 0) {
final ItemStack itemStack = cursorItem.copy();
itemStack.setQuantity(rest);
newCursorItem = LanternItemStackSnapshot.wrap(itemStack);
}
final ItemStackSnapshot oldCursorItem = cursorItem.createSnapshot();
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(oldCursorItem, newCursorItem);
final ClickInventoryEvent.Drag.Primary event = SpongeEventFactory.createClickInventoryEventDragPrimary(causeStack.getCurrentCause(), cursorTransaction, this.container, transactions);
finishInventoryEvent(event);
} else if (mouseButton == MouseButton.RIGHT) {
int quantity = cursorItem.getQuantity();
final int size = Math.min(slots.size(), quantity);
final List<SlotTransaction> transactions = new ArrayList<>();
for (AbstractSlot slot : slots) {
final ItemStack itemStack = cursorItem.copy();
itemStack.setQuantity(1);
transactions.addAll(slot.peekOffer(itemStack).getTransactions());
}
quantity -= size;
ItemStackSnapshot newCursorItem = ItemStackSnapshot.NONE;
if (quantity > 0) {
final ItemStack itemStack = cursorItem.copy();
itemStack.setQuantity(quantity);
newCursorItem = LanternItemStackSnapshot.wrap(itemStack);
}
final ItemStackSnapshot oldCursorItem = getCursorItem().createSnapshot();
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(oldCursorItem, newCursorItem);
final ClickInventoryEvent.Drag.Secondary event = SpongeEventFactory.createClickInventoryEventDragSecondary(causeStack.getCurrentCause(), cursorTransaction, this.container, this.container.transformSlots(transactions));
finishInventoryEvent(event);
} else {
// TODO: Middle mouse drag mode
}
}
use of org.spongepowered.api.data.Transaction in project LanternServer by LanternPowered.
the class PlayerContainerSession method setRawOpenContainer.
private boolean setRawOpenContainer(CauseStack causeStack, @Nullable LanternContainer container, boolean sendClose, boolean client) {
try (CauseStack.Frame frame = causeStack.pushCauseFrame()) {
if (this.openContainer != container) {
frame.addContext(EventContextKeys.PLAYER, this.player);
ItemStackSnapshot cursorItem = ItemStackSnapshot.NONE;
if (this.openContainer != null) {
final ItemStackSnapshot cursorItemSnapshot = this.openContainer.getCursorSlot().peek().map(LanternItemStackSnapshot::wrap).orElse(LanternItemStackSnapshot.none());
final InteractInventoryEvent.Close event = SpongeEventFactory.createInteractInventoryEventClose(frame.getCurrentCause(), new Transaction<>(cursorItemSnapshot, ItemStackSnapshot.NONE), this.openContainer);
Sponge.getEventManager().post(event);
if (event.isCancelled()) {
// Stop the client from closing the container, resend the open message
if (client) {
// This can't be done to the player inventory, player inventory uses index 0
// The optional should always return something at this point, otherwise
// something is broken
final ClientContainer clientContainer = getClientContainer();
if (clientContainer.getContainerId() != 0) {
// Reinitialize the client container
clientContainer.init();
return false;
}
} else {
// Just return
return false;
}
}
final Transaction<ItemStackSnapshot> transaction = event.getCursorTransaction();
if (transaction.isValid()) {
if (transaction.getFinal().isEmpty()) {
// Add the event that caused the drop to the cause
frame.pushCause(event);
LanternEventHelper.handleDroppedItemSpawning(this.player.getTransform(), transaction.getOriginal());
frame.popCause();
} else {
cursorItem = transaction.getFinal();
}
}
// Close the inventory
this.openContainer.close(causeStack);
} else {
sendClose = false;
}
if (container != null) {
final Transaction<ItemStackSnapshot> cursorTransaction = new Transaction<>(ItemStackSnapshot.NONE, cursorItem);
final InteractInventoryEvent.Open event = SpongeEventFactory.createInteractInventoryEventOpen(frame.getCurrentCause(), cursorTransaction, container);
Sponge.getEventManager().post(event);
if (event.isCancelled()) {
if (cursorTransaction.isValid()) {
final ItemStackSnapshot cursorItem1 = cursorTransaction.getFinal();
if (!cursorItem1.isEmpty()) {
// Add the event that caused the drop to the cause
frame.pushCause(event);
LanternEventHelper.handleDroppedItemSpawning(this.player.getTransform(), cursorItem1);
frame.popCause();
}
}
return false;
}
if (cursorTransaction.isValid()) {
final ItemStackSnapshot cursorItem1 = cursorTransaction.getFinal();
container.getCursorSlot().setRawItemStack(cursorItem1.createStack());
}
sendClose = false;
container.addViewer(this.player);
}
if (sendClose && getContainerId() != 0) {
this.player.getConnection().send(new MessagePlayInOutCloseWindow(getContainerId()));
}
if (this.openContainer != null) {
this.openContainer.removeViewer(this.player);
}
}
this.openContainer = container;
return true;
}
}
Aggregations