use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class TrackingUtil method trackBlockChange.
@SuppressWarnings("rawtypes")
static boolean trackBlockChange(PhaseTracker phaseTracker, IMixinWorldServer mixinWorld, Chunk chunk, IBlockState currentState, IBlockState newState, BlockPos pos, BlockChangeFlag flags, PhaseContext<?> phaseContext, IPhaseState<?> phaseState) {
final SpongeBlockSnapshot originalBlockSnapshot;
final WorldServer minecraftWorld = mixinWorld.asMinecraftWorld();
if (((IPhaseState) phaseState).shouldCaptureBlockChangeOrSkip(phaseContext, pos)) {
// final IBlockState actualState = currentState.getActualState(minecraftWorld, pos);
originalBlockSnapshot = mixinWorld.createSpongeBlockSnapshot(currentState, currentState, pos, flags);
final List<BlockSnapshot> capturedSnapshots = phaseContext.getCapturedBlocks();
final Block newBlock = newState.getBlock();
associateBlockChangeWithSnapshot(phaseState, newBlock, currentState, originalBlockSnapshot, capturedSnapshots);
final IMixinChunk mixinChunk = (IMixinChunk) chunk;
final IBlockState originalBlockState = mixinChunk.setBlockState(pos, newState, currentState, originalBlockSnapshot);
if (originalBlockState == null) {
capturedSnapshots.remove(originalBlockSnapshot);
return false;
}
((IPhaseState) phaseState).postTrackBlock(originalBlockSnapshot, phaseTracker, phaseContext);
} else {
originalBlockSnapshot = (SpongeBlockSnapshot) BlockSnapshot.NONE;
final IMixinChunk mixinChunk = (IMixinChunk) chunk;
final IBlockState originalBlockState = mixinChunk.setBlockState(pos, newState, currentState, originalBlockSnapshot);
if (originalBlockState == null) {
return false;
}
}
if (newState.getLightOpacity() != currentState.getLightOpacity() || newState.getLightValue() != currentState.getLightValue()) {
minecraftWorld.profiler.startSection("checkLight");
minecraftWorld.checkLight(pos);
minecraftWorld.profiler.endSection();
}
return true;
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class RestoringBlockPhaseState method spawnEntityOrCapture.
@Override
public boolean spawnEntityOrCapture(GeneralizedContext context, Entity entity, int chunkX, int chunkZ) {
final User user = context.getNotifier().orElseGet(() -> context.getOwner().orElse(null));
if (user != null) {
entity.setCreator(user.getUniqueId());
}
final ArrayList<Entity> entities = new ArrayList<>(1);
entities.add(entity);
final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled() && event.getEntities().size() > 0) {
for (org.spongepowered.api.entity.Entity item : event.getEntities()) {
((IMixinWorldServer) item.getWorld()).forceSpawnEntity(item);
}
return true;
}
return false;
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class GeneralPhase method performPostBlockAdditions.
@SuppressWarnings("unchecked")
private static void performPostBlockAdditions(PhaseContext<?> postContext, List<Transaction<BlockSnapshot>> transactions, IPhaseState<?> unwindingState, PhaseContext<?> unwindingPhaseContext) {
// We have to use a proxy so that our pending changes are notified such that any accessors from block
// classes do not fail on getting the incorrect block state from the IBlockAccess
final SpongeProxyBlockAccess proxyBlockAccess = new SpongeProxyBlockAccess(transactions);
final CapturedMultiMapSupplier<BlockPos, ItemDropData> capturedBlockDrops = postContext.getBlockDropSupplier();
final CapturedMultiMapSupplier<BlockPos, EntityItem> capturedBlockItemEntityDrops = postContext.getBlockItemDropSupplier();
for (Transaction<BlockSnapshot> transaction : transactions) {
if (!transaction.isValid()) {
// Don't use invalidated block transactions during notifications, these only need to be restored
continue;
}
// Handle custom replacements
if (transaction.getCustom().isPresent()) {
transaction.getFinal().restore(true, BlockChangeFlags.ALL);
}
final SpongeBlockSnapshot oldBlockSnapshot = (SpongeBlockSnapshot) transaction.getOriginal();
final SpongeBlockSnapshot newBlockSnapshot = (SpongeBlockSnapshot) transaction.getFinal();
// Handle item drops captured
final Location<World> worldLocation = oldBlockSnapshot.getLocation().get();
final IMixinWorldServer mixinWorldServer = (IMixinWorldServer) worldLocation.getExtent();
final BlockPos pos = ((IMixinLocation) (Object) worldLocation).getBlockPos();
capturedBlockDrops.acceptAndRemoveIfPresent(pos, items -> TrackingUtil.spawnItemDataForBlockDrops(items, oldBlockSnapshot, unwindingPhaseContext, unwindingState));
capturedBlockItemEntityDrops.acceptAndRemoveIfPresent(pos, items -> TrackingUtil.spawnItemEntitiesForBlockDrops(items, oldBlockSnapshot, unwindingPhaseContext, unwindingState));
final WorldServer worldServer = mixinWorldServer.asMinecraftWorld();
SpongeHooks.logBlockAction(worldServer, oldBlockSnapshot.blockChange, transaction);
final SpongeBlockChangeFlag spongeFlag = oldBlockSnapshot.getChangeFlag();
final int updateFlag = spongeFlag.getRawFlag();
final IBlockState originalState = (IBlockState) oldBlockSnapshot.getState();
final IBlockState newState = (IBlockState) newBlockSnapshot.getState();
// Containers get placed automatically
final CapturedSupplier<BlockSnapshot> capturedBlockSupplier = postContext.getCapturedBlockSupplier();
if (spongeFlag.performBlockPhysics() && originalState.getBlock() != newState.getBlock() && !SpongeImplHooks.hasBlockTileEntity(newState.getBlock(), newState)) {
newState.getBlock().onBlockAdded(worldServer, pos, newState);
postContext.getCapturedEntitySupplier().acceptAndClearIfNotEmpty(entities -> {
final ArrayList<Entity> capturedEntities = new ArrayList<>(entities);
((IPhaseState) unwindingState).postProcessSpawns(unwindingPhaseContext, capturedEntities);
});
capturedBlockSupplier.acceptAndClearIfNotEmpty(blocks -> {
final List<BlockSnapshot> blockSnapshots = new ArrayList<>(blocks);
processBlockTransactionListsPost(postContext, blockSnapshots, unwindingState, unwindingPhaseContext);
});
}
proxyBlockAccess.proceed();
((IPhaseState) unwindingState).handleBlockChangeWithUser(oldBlockSnapshot.blockChange, transaction, unwindingPhaseContext);
if (spongeFlag.isNotifyClients()) {
// Since notifyBlockUpdate is basically to tell clients that the block position has changed,
// we need to respect that flag
worldServer.notifyBlockUpdate(pos, originalState, newState, updateFlag);
}
if (spongeFlag.updateNeighbors()) {
// Notify neighbors only if the change flag allowed it.
mixinWorldServer.spongeNotifyNeighborsPostBlockChange(pos, originalState, newState, spongeFlag);
} else if (spongeFlag.notifyObservers()) {
worldServer.updateObservingBlocksAt(pos, newState.getBlock());
}
capturedBlockSupplier.acceptAndClearIfNotEmpty(blocks -> {
final List<BlockSnapshot> blockSnapshots = new ArrayList<>(blocks);
blocks.clear();
processBlockTransactionListsPost(postContext, blockSnapshots, unwindingState, unwindingPhaseContext);
});
}
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class GeneralState method spawnEntityOrCapture.
/**
* A duplicate of {@link IPhaseState#spawnEntityOrCapture(PhaseContext, Entity, int, int)}
* such that the general states will not know what to do for entity spawns. Eventually, this is going to be centralized
* so that it's not always delegated between the phases and phase states.
*
* Basically, for this method, this is included only for the {@link GeneralPhase.State#COMPLETE}, all other
* will capture or spawn appropriately. In the case of explosions for example, the entities must be mapped
* according to the blocks broken so that the blocks themselves can be cancelled and the entities spawned
* are dropped from the game entirely before throwing additional events.
*
* @param context
* @param entity
* @param chunkX
* @param chunkZ
* @return
*/
@Override
public boolean spawnEntityOrCapture(G context, Entity entity, int chunkX, int chunkZ) {
final User user = context.getNotifier().orElseGet(() -> context.getOwner().orElse(null));
if (user != null) {
entity.setCreator(user.getUniqueId());
}
final ArrayList<Entity> entities = new ArrayList<>(1);
entities.add(entity);
final SpawnEntityEvent event = SpongeEventFactory.createSpawnEntityEvent(Sponge.getCauseStackManager().getCurrentCause(), entities);
SpongeImpl.postEvent(event);
if (!event.isCancelled() && event.getEntities().size() > 0) {
for (Entity item : event.getEntities()) {
((IMixinWorldServer) item.getWorld()).forceSpawnEntity(item);
}
return true;
}
return false;
}
use of org.spongepowered.common.interfaces.world.IMixinWorldServer in project SpongeCommon by SpongePowered.
the class MixinDedicatedServer method isBlockProtected.
/**
* @author zml - March 9th, 2016
* @author blood - July 7th, 2016 - Add cause tracker handling for throwing pre change block checks
* @author gabizou - July 7th, 2016 - Update for 1.10's cause tracking changes
*
* @reason Change spawn protection to take advantage of Sponge permissions. Rather than affecting only the default world like vanilla, this
* will apply to any world. Additionally, fire a spawn protection event
*/
@Overwrite
@Override
public boolean isBlockProtected(net.minecraft.world.World worldIn, BlockPos pos, EntityPlayer playerIn) {
// Mods such as ComputerCraft and Thaumcraft check this method before attempting to set a blockstate.
final PhaseTracker phaseTracker = PhaseTracker.getInstance();
final PhaseData peek = phaseTracker.getCurrentPhaseData();
final IPhaseState phaseState = peek.state;
if (phaseState == null || !phaseState.isInteraction()) {
// TODO BLOCK_PROTECTED flag
if (SpongeCommonEventFactory.callChangeBlockEventPre((IMixinWorldServer) worldIn, pos, playerIn).isCancelled()) {
return true;
}
}
BlockPos spawnPoint = worldIn.getSpawnPoint();
int protectionRadius = getSpawnProtectionSize();
return protectionRadius > 0 && Math.max(Math.abs(pos.getX() - spawnPoint.getX()), Math.abs(pos.getZ() - spawnPoint.getZ())) <= protectionRadius && !((Player) playerIn).hasPermission("minecraft.spawn-protection.override");
}
Aggregations