Search in sources :

Example 11 with IMixinChunkProviderServer

use of org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer in project SpongeForge by SpongePowered.

the class SpongeForgeEventFactory method callWorldLoadEvent.

private static LoadWorldEvent callWorldLoadEvent(Event event) {
    LoadWorldEvent spongeEvent = (LoadWorldEvent) event;
    // Since Forge only uses a single save handler, we need to make sure to pass the overworld's handler.
    // This makes sure that mods dont attempt to save/read their data from the wrong location.
    final net.minecraft.world.World minecraftWorld = (net.minecraft.world.World) spongeEvent.getTargetWorld();
    ((IMixinWorld) spongeEvent.getTargetWorld()).setCallingWorldEvent(true);
    ((IMixinChunkProviderServer) minecraftWorld.getChunkProvider()).setForceChunkRequests(true);
    ((IMixinEventBus) MinecraftForge.EVENT_BUS).post(new WorldEvent.Load(minecraftWorld), true);
    ((IMixinChunkProviderServer) minecraftWorld.getChunkProvider()).setForceChunkRequests(false);
    ((IMixinWorld) minecraftWorld).setCallingWorldEvent(false);
    return spongeEvent;
}
Also used : IMixinEventBus(org.spongepowered.mod.interfaces.IMixinEventBus) LoadWorldEvent(org.spongepowered.api.event.world.LoadWorldEvent) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) LoadWorldEvent(org.spongepowered.api.event.world.LoadWorldEvent) EntityJoinWorldEvent(net.minecraftforge.event.entity.EntityJoinWorldEvent) UnloadWorldEvent(org.spongepowered.api.event.world.UnloadWorldEvent) WorldEvent(net.minecraftforge.event.world.WorldEvent) SaveWorldEvent(org.spongepowered.api.event.world.SaveWorldEvent) TargetWorldEvent(org.spongepowered.api.event.world.TargetWorldEvent) World(org.spongepowered.api.world.World) IMixinWorld(org.spongepowered.common.interfaces.world.IMixinWorld) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer)

Example 12 with IMixinChunkProviderServer

use of org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer in project SpongeCommon by SpongePowered.

the class MixinEntity method setLocation.

@Override
public boolean setLocation(Location<World> location) {
    checkNotNull(location, "The location was null!");
    if (isRemoved()) {
        return false;
    }
    try (final BasicPluginContext context = PluginPhase.State.TELEPORT.createPhaseContext().buildAndSwitch()) {
        // TODO Add a 'Move' plugin phase or just keep it under Teleport?
        try (final CauseStackManager.StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame()) {
            if (!Sponge.getCauseStackManager().getCurrentContext().containsKey(EventContextKeys.TELEPORT_TYPE)) {
                Sponge.getCauseStackManager().addContext(EventContextKeys.TELEPORT_TYPE, TeleportTypes.PLUGIN);
            }
            // TODO These methods need a Cause (maybe wait till Cause PR)
            // TODO Need to not fire Teleport in all cases (especially when movement is local)
            MoveEntityEvent.Teleport event = EntityUtil.handleDisplaceEntityTeleportEvent((net.minecraft.entity.Entity) (Object) this, location);
            if (event.isCancelled()) {
                return false;
            }
            location = event.getToTransform().getLocation();
            this.rotationPitch = (float) event.getToTransform().getPitch();
            this.rotationYaw = (float) event.getToTransform().getYaw();
        }
        final IMixinChunkProviderServer chunkProviderServer = (IMixinChunkProviderServer) ((WorldServer) this.world).getChunkProvider();
        chunkProviderServer.setForceChunkRequests(true);
        final net.minecraft.entity.Entity thisEntity = (net.minecraft.entity.Entity) (Object) this;
        final List<net.minecraft.entity.Entity> passengers = thisEntity.getPassengers();
        boolean isTeleporting = true;
        if (location.getExtent().getUniqueId() != ((World) this.world).getUniqueId()) {
            final net.minecraft.world.World nmsWorld = (net.minecraft.world.World) location.getExtent();
            if ((net.minecraft.entity.Entity) (Object) this instanceof EntityPlayerMP) {
                // Close open containers
                final EntityPlayerMP entityPlayerMP = (EntityPlayerMP) (Object) this;
                if (entityPlayerMP.openContainer != entityPlayerMP.inventoryContainer) {
                    // Call API method to make sure we capture it
                    ((Player) entityPlayerMP).closeInventory();
                }
            }
            EntityUtil.changeWorld((net.minecraft.entity.Entity) (Object) this, location, ((IMixinWorldServer) this.world).getDimensionId(), ((IMixinWorldServer) nmsWorld).getDimensionId());
        } else {
            double distance = location.getPosition().distance(this.getPosition());
            if (distance <= 4) {
                isTeleporting = false;
            }
            if (thisEntity instanceof EntityPlayerMP && ((EntityPlayerMP) thisEntity).connection != null) {
                final EntityPlayerMP entityPlayerMP = (EntityPlayerMP) thisEntity;
                // No reason to attempt to load chunks unless we're teleporting
                if (isTeleporting) {
                    // Close open containers
                    if (entityPlayerMP.openContainer != entityPlayerMP.inventoryContainer) {
                        // Call API method to make sure we capture it
                        ((Player) entityPlayerMP).closeInventory();
                    }
                    ((WorldServer) location.getExtent()).getChunkProvider().loadChunk(location.getChunkPosition().getX(), location.getChunkPosition().getZ());
                }
                entityPlayerMP.connection.setPlayerLocation(location.getX(), location.getY(), location.getZ(), thisEntity.rotationYaw, thisEntity.rotationPitch);
                // Set last move to teleport target
                ((IMixinNetHandlerPlayServer) entityPlayerMP.connection).setLastMoveLocation(null);
            } else {
                setPosition(location.getPosition().getX(), location.getPosition().getY(), location.getPosition().getZ());
            }
        }
        if (isTeleporting) {
            // Re-attach passengers
            for (net.minecraft.entity.Entity passenger : passengers) {
                passenger.startRiding(thisEntity, true);
            }
        }
        chunkProviderServer.setForceChunkRequests(false);
        return true;
    }
}
Also used : Entity(org.spongepowered.api.entity.Entity) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Player(org.spongepowered.api.entity.living.player.Player) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) World(org.spongepowered.api.world.World) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer) BasicPluginContext(org.spongepowered.common.event.tracking.phase.plugin.BasicPluginContext) CauseStackManager(org.spongepowered.api.event.CauseStackManager) EntityPlayerMP(net.minecraft.entity.player.EntityPlayerMP) IMixinNetHandlerPlayServer(org.spongepowered.common.interfaces.network.IMixinNetHandlerPlayServer)

Example 13 with IMixinChunkProviderServer

use of org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer in project SpongeCommon by SpongePowered.

the class MixinChunk method onLoadReturn.

@Inject(method = "onLoad", at = @At("RETURN"))
public void onLoadReturn(CallbackInfo ci) {
    for (Direction direction : CARDINAL_DIRECTIONS) {
        Vector3i neighborPosition = this.getPosition().add(direction.asBlockOffset());
        IMixinChunkProviderServer spongeChunkProvider = (IMixinChunkProviderServer) this.world.getChunkProvider();
        net.minecraft.world.chunk.Chunk neighbor = spongeChunkProvider.getLoadedChunkWithoutMarkingActive(neighborPosition.getX(), neighborPosition.getZ());
        if (neighbor != null) {
            int neighborIndex = directionToIndex(direction);
            int oppositeNeighborIndex = directionToIndex(direction.getOpposite());
            this.setNeighborChunk(neighborIndex, neighbor);
            ((IMixinChunk) neighbor).setNeighborChunk(oppositeNeighborIndex, (net.minecraft.world.chunk.Chunk) (Object) this);
        }
    }
    SpongeImpl.postEvent(SpongeEventFactory.createLoadChunkEvent(Sponge.getCauseStackManager().getCurrentCause(), (Chunk) this));
    if (!this.world.isRemote) {
        SpongeHooks.logChunkLoad(this.world, this.chunkPos);
    }
}
Also used : IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Vector3i(com.flowpowered.math.vector.Vector3i) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(org.spongepowered.api.world.Chunk) Direction(org.spongepowered.api.util.Direction) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 14 with IMixinChunkProviderServer

use of org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer in project SpongeCommon by SpongePowered.

the class MixinChunk method onUnload.

@Inject(method = "onUnload", at = @At("RETURN"))
public void onUnload(CallbackInfo ci) {
    for (Direction direction : CARDINAL_DIRECTIONS) {
        Vector3i neighborPosition = this.getPosition().add(direction.asBlockOffset());
        IMixinChunkProviderServer spongeChunkProvider = (IMixinChunkProviderServer) this.world.getChunkProvider();
        net.minecraft.world.chunk.Chunk neighbor = spongeChunkProvider.getLoadedChunkWithoutMarkingActive(neighborPosition.getX(), neighborPosition.getZ());
        if (neighbor != null) {
            int neighborIndex = directionToIndex(direction);
            int oppositeNeighborIndex = directionToIndex(direction.getOpposite());
            this.setNeighborChunk(neighborIndex, null);
            ((IMixinChunk) neighbor).setNeighborChunk(oppositeNeighborIndex, null);
        }
    }
    if (!this.world.isRemote) {
        SpongeImpl.postEvent(SpongeEventFactory.createUnloadChunkEvent(Sponge.getCauseStackManager().getCurrentCause(), (Chunk) this));
        SpongeHooks.logChunkUnload(this.world, this.chunkPos);
    }
}
Also used : IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Vector3i(com.flowpowered.math.vector.Vector3i) IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(org.spongepowered.api.world.Chunk) Direction(org.spongepowered.api.util.Direction) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 15 with IMixinChunkProviderServer

use of org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer in project SpongeCommon by SpongePowered.

the class MixinChunkCache method onConstruct.

@Redirect(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/World;getChunkFromChunkCoords(II)Lnet/minecraft/world/chunk/Chunk;"))
private Chunk onConstruct(World worldIn, int chunkX, int chunkZ) {
    if (worldIn.isRemote) {
        return worldIn.getChunkFromChunkCoords(chunkX, chunkZ);
    }
    final net.minecraft.world.chunk.Chunk chunk = ((IMixinChunkProviderServer) worldIn.getChunkProvider()).getLoadedChunkWithoutMarkingActive(chunkX, chunkZ);
    IMixinChunk spongeChunk = (IMixinChunk) chunk;
    if (chunk == null || chunk.unloadQueued || !spongeChunk.areNeighborsLoaded()) {
        return null;
    }
    return chunk;
}
Also used : IMixinChunk(org.spongepowered.common.interfaces.IMixinChunk) Chunk(net.minecraft.world.chunk.Chunk) IMixinChunkProviderServer(org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer) Redirect(org.spongepowered.asm.mixin.injection.Redirect)

Aggregations

IMixinChunkProviderServer (org.spongepowered.common.interfaces.world.gen.IMixinChunkProviderServer)24 Chunk (net.minecraft.world.chunk.Chunk)16 IMixinChunk (org.spongepowered.common.interfaces.IMixinChunk)15 BlockPos (net.minecraft.util.math.BlockPos)9 IMixinWorldServer (org.spongepowered.common.interfaces.world.IMixinWorldServer)5 Direction (org.spongepowered.api.util.Direction)4 PhaseTracker (org.spongepowered.common.event.tracking.PhaseTracker)4 Vector3i (com.flowpowered.math.vector.Vector3i)3 WorldServer (net.minecraft.world.WorldServer)3 World (org.spongepowered.api.world.World)3 Overwrite (org.spongepowered.asm.mixin.Overwrite)3 Inject (org.spongepowered.asm.mixin.injection.Inject)3 IMixinWorld (org.spongepowered.common.interfaces.world.IMixinWorld)3 EntityPlayer (net.minecraft.entity.player.EntityPlayer)2 EnumFacing (net.minecraft.util.EnumFacing)2 World (net.minecraft.world.World)2 NotifyNeighborBlockEvent (org.spongepowered.api.event.block.NotifyNeighborBlockEvent)2 Chunk (org.spongepowered.api.world.Chunk)2 Redirect (org.spongepowered.asm.mixin.injection.Redirect)2 WorldTimingsHandler (co.aikar.timings.WorldTimingsHandler)1