Search in sources :

Example 16 with WorldMaster

use of io.xol.chunkstories.api.world.WorldMaster in project chunkstories by Hugobros3.

the class ServerPlayer method save.

/**
 * Serializes the stuff describing this player
 */
public void save() {
    long lastTime = playerDataFile.getLong("timeplayed", 0);
    long lastLogin = playerDataFile.getLong("lastlogin", 0);
    if (controlledEntity != null) {
        // Useless, kept for admin easyness, scripts, whatnot
        Location controlledEntityLocation = controlledEntity.getLocation();
        // Safely assumes as a SERVER the world will be master ;)
        WorldMaster world = (WorldMaster) controlledEntityLocation.getWorld();
        playerDataFile.setDouble("posX", controlledEntityLocation.x());
        playerDataFile.setDouble("posY", controlledEntityLocation.y());
        playerDataFile.setDouble("posZ", controlledEntityLocation.z());
        playerDataFile.setString("world", world.getWorldInfo().getInternalName());
        // Serializes the whole player entity !!!
        SerializedEntityFile playerEntityFile = new SerializedEntityFile(world.getFolderPath() + "/players/" + this.getName().toLowerCase() + ".csf");
        playerEntityFile.write(controlledEntity);
    }
    // Telemetry (EVIL)
    playerDataFile.setString("timeplayed", "" + (lastTime + (System.currentTimeMillis() - lastLogin)));
    playerDataFile.save();
    System.out.println("Player profile " + name + " saved.");
}
Also used : SerializedEntityFile(io.xol.chunkstories.entity.SerializedEntityFile) WorldMaster(io.xol.chunkstories.api.world.WorldMaster) Location(io.xol.chunkstories.api.Location)

Example 17 with WorldMaster

use of io.xol.chunkstories.api.world.WorldMaster in project chunkstories by Hugobros3.

the class WorldImplementation method tick.

@Override
public void tick() {
    // Iterates over every entity
    try {
        entitiesLock.writeLock().lock();
        Iterator<Entity> iter = this.getAllLoadedEntities();
        Entity entity;
        while (iter.hasNext()) {
            entity = iter.next();
            // Check entity's region is loaded
            if (entity.getChunk() != null)
                entity.tick();
            else
                // Tries to snap the entity to the region if it ends up being loaded
                ((EntityBase) entity).positionComponent.trySnappingToChunk();
        }
    } finally {
        entitiesLock.writeLock().unlock();
    }
    // Increase the ticks counter
    worldTicksCounter++;
    // Time cycle
    if (this instanceof WorldMaster && internalData.getBoolean("doTimeCycle", true))
        if (worldTicksCounter % 60 == 0)
            worldTime++;
}
Also used : EntityBase(io.xol.chunkstories.api.entity.EntityBase) Entity(io.xol.chunkstories.api.entity.Entity) WorldMaster(io.xol.chunkstories.api.world.WorldMaster)

Example 18 with WorldMaster

use of io.xol.chunkstories.api.world.WorldMaster in project chunkstories by Hugobros3.

the class WorldImplementation method spawnPlayer.

public void spawnPlayer(Player player) {
    if (!(this instanceof WorldMaster))
        throw new UnsupportedOperationException("Only Master Worlds can do this");
    Entity savedEntity = null;
    SerializedEntityFile playerEntityFile = new SerializedEntityFile(this.getFolderPath() + "/players/" + player.getName().toLowerCase() + ".csf");
    if (playerEntityFile.exists())
        savedEntity = playerEntityFile.read(this);
    Location previousLocation = null;
    if (savedEntity != null)
        previousLocation = savedEntity.getLocation();
    PlayerSpawnEvent playerSpawnEvent = new PlayerSpawnEvent(player, (WorldMaster) this, savedEntity, previousLocation);
    getGameContext().getPluginManager().fireEvent(playerSpawnEvent);
    if (!playerSpawnEvent.isCancelled()) {
        Entity entity = playerSpawnEvent.getEntity();
        Location actualSpawnLocation = playerSpawnEvent.getSpawnLocation();
        if (actualSpawnLocation == null)
            actualSpawnLocation = this.getDefaultSpawnLocation();
        // TODO EntitySimplePlayer ?
        if (entity == null || ((entity instanceof EntityLiving) && (((EntityLiving) entity).isDead())))
            entity = this.gameContext.getContent().entities().getEntityDefinition("player").create(actualSpawnLocation);
        else
            // entity = new EntityPlayer(this, 0d, 0d, 0d, player.getName()); //Default entity
            entity.setUUID(-1);
        // Name your player !
        if (entity instanceof EntityNameable)
            ((EntityNameable) entity).getNameComponent().setName(player.getName());
        entity.setLocation(actualSpawnLocation);
        addEntity(entity);
        if (entity instanceof EntityControllable)
            player.setControlledEntity((EntityControllable) entity);
        else
            System.out.println("Error : entity is not controllable");
    }
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) EntityLiving(io.xol.chunkstories.api.entity.EntityLiving) SerializedEntityFile(io.xol.chunkstories.entity.SerializedEntityFile) PlayerSpawnEvent(io.xol.chunkstories.api.events.player.PlayerSpawnEvent) EntityNameable(io.xol.chunkstories.api.entity.interfaces.EntityNameable) EntityControllable(io.xol.chunkstories.api.entity.interfaces.EntityControllable) WorldMaster(io.xol.chunkstories.api.world.WorldMaster) Location(io.xol.chunkstories.api.Location)

Example 19 with WorldMaster

use of io.xol.chunkstories.api.world.WorldMaster in project chunkstories by Hugobros3.

the class CubicChunk method pokeInternal.

/**
 * The 'core' of the core, this private function is responsible for placing and
 * keeping everyone up to snuff on block modifications. It all comes back to this really.
 */
private ActualChunkVoxelContext pokeInternal(final int worldX, final int worldY, final int worldZ, Voxel newVoxel, final int sunlight, final int blocklight, final int metadata, int raw_data, final boolean use_raw_data, final boolean update, final boolean return_context, final WorldModificationCause cause) {
    int x = sanitizeCoordinate(worldX);
    int y = sanitizeCoordinate(worldY);
    int z = sanitizeCoordinate(worldZ);
    ActualChunkVoxelContext cell_pre = peek(x, y, z);
    Voxel formerVoxel = cell_pre.getVoxel();
    assert formerVoxel != null;
    FreshFutureCell future = new FreshFutureCell(cell_pre);
    if (use_raw_data) {
        // We need this for voxel placement logic
        newVoxel = world.getContentTranslator().getVoxelForId(VoxelFormat.id(raw_data));
        // Build the future from parsing the raw data
        future.setVoxel(newVoxel);
        future.setSunlight(VoxelFormat.sunlight(raw_data));
        future.setBlocklight(VoxelFormat.blocklight(raw_data));
        future.setMetaData(VoxelFormat.meta(raw_data));
    } else {
        // Build the raw data from the set parameters by editing the in-place data
        // (because we allow only editing some aspects of the cell data)
        raw_data = cell_pre.getData();
        if (newVoxel != null) {
            raw_data = VoxelFormat.changeId(raw_data, world.getContentTranslator().getIdForVoxel(newVoxel));
            future.setVoxel(newVoxel);
        }
        if (sunlight >= 0) {
            raw_data = VoxelFormat.changeSunlight(raw_data, sunlight);
            future.setSunlight(sunlight);
        }
        if (blocklight >= 0) {
            raw_data = VoxelFormat.changeBlocklight(raw_data, blocklight);
            future.setBlocklight(blocklight);
        }
        if (metadata >= 0) {
            raw_data = VoxelFormat.changeMeta(raw_data, metadata);
            future.setMetaData(metadata);
        }
    }
    try {
        if (newVoxel == null || formerVoxel.equals(newVoxel)) {
            formerVoxel.onModification(cell_pre, future, cause);
        } else {
            formerVoxel.onRemove(cell_pre, cause);
            newVoxel.onPlace(future, cause);
        }
    } catch (WorldException e) {
        // Abort !
        if (return_context)
            return cell_pre;
        else
            return null;
    }
    // Allocate if it makes sense
    if (chunkVoxelData == null)
        chunkVoxelData = atomicalyCreateInternalData();
    chunkVoxelData[x * 32 * 32 + y * 32 + z] = raw_data;
    if (newVoxel != null && !formerVoxel.equals(newVoxel))
        newVoxel.whenPlaced(future);
    // Update lightning
    if (update)
        lightBaker.computeLightSpread(x, y, z, cell_pre.raw_data, raw_data);
    // Increment the modifications counter
    compr_uncomittedBlockModifications.incrementAndGet();
    // Don't spam the thread creation spawn
    occlusion.unbakedUpdates.incrementAndGet();
    // Update related summary
    if (update)
        world.getRegionsSummariesHolder().updateOnBlockPlaced(x, y, z, future);
    // Mark the nearby chunks to be re-rendered
    if (update) {
        int sx = chunkX;
        int ex = sx;
        int sy = chunkY;
        int ey = sy;
        int sz = chunkZ;
        int ez = sz;
        if (x == 0)
            sx--;
        else if (x == 31)
            ex++;
        if (y == 0)
            sy--;
        else if (y == 31)
            ey++;
        if (z == 0)
            sz--;
        else if (z == 31)
            ez++;
        for (int ix = sx; ix <= ex; ix++) for (int iy = sy; iy <= ey; iy++) for (int iz = sz; iz <= ez; iz++) {
            Chunk chunk = world.getChunk(ix, iy, iz);
            if (chunk != null && chunk instanceof ChunkRenderable)
                ((ChunkRenderable) chunk).meshUpdater().requestMeshUpdate();
        }
    }
    // If this is a 'master' world, notify remote users of the change !
    if (update && world instanceof WorldMaster && !(world instanceof WorldTool)) {
        PacketVoxelUpdate packet = new PacketVoxelUpdate(new ActualChunkVoxelContext(chunkX * 32 + x, chunkY * 32 + y, chunkZ * 32 + z, raw_data));
        Iterator<WorldUser> pi = this.chunkHolder.users.iterator();
        while (pi.hasNext()) {
            WorldUser user = pi.next();
            if (!(user instanceof RemotePlayer))
                continue;
            RemotePlayer player = (RemotePlayer) user;
            Entity clientEntity = player.getControlledEntity();
            if (clientEntity == null)
                // Ignore clients that aren't playing
                continue;
            player.pushPacket(packet);
        }
    }
    if (return_context)
        return new ActualChunkVoxelContext(chunkX * 32 + x, chunkY * 32 + y, chunkZ * 32 + z, raw_data);
    else
        return null;
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) WorldUser(io.xol.chunkstories.api.world.WorldUser) WorldException(io.xol.chunkstories.api.exceptions.world.WorldException) ChunkRenderable(io.xol.chunkstories.api.rendering.world.chunk.ChunkRenderable) Chunk(io.xol.chunkstories.api.world.chunk.Chunk) PacketVoxelUpdate(io.xol.chunkstories.api.net.packets.PacketVoxelUpdate) RemotePlayer(io.xol.chunkstories.api.server.RemotePlayer) WorldTool(io.xol.chunkstories.world.WorldTool) Voxel(io.xol.chunkstories.api.voxel.Voxel) WorldMaster(io.xol.chunkstories.api.world.WorldMaster)

Example 20 with WorldMaster

use of io.xol.chunkstories.api.world.WorldMaster in project chunkstories by Hugobros3.

the class HashMapWorldRegionsHolder method unloadsUselessData.

public Fence unloadsUselessData() {
    // We might want to wait for a few things
    CompoundFence compoundFence = new CompoundFence();
    // Prevents unloading a region whilst one of it's chunk holders is being aquired
    noConcurrentRegionCreationDestruction.acquireUninterruptibly();
    // Iterates over loaded regions and unloads unused ones
    Iterator<RegionImplementation> regionsIterator = this.getLoadedRegions();
    while (regionsIterator.hasNext()) {
        RegionImplementation region = regionsIterator.next();
        // Processes users, remove null ones
        region.unloadsUnusedChunks();
        // If no users have registered for any chunks
        if (region.isUnused() && region.canBeUnloaded()) {
            // This is the only way to ensure all entities end up in a single region file and we don't have uuid conflicts
            if (world instanceof WorldMaster)
                compoundFence.add(region.unloadAndSave());
            else
                // Immediate
                region.unload();
        }
    }
    noConcurrentRegionCreationDestruction.release();
    return compoundFence;
}
Also used : CompoundFence(io.xol.chunkstories.util.concurrency.CompoundFence) WorldMaster(io.xol.chunkstories.api.world.WorldMaster)

Aggregations

WorldMaster (io.xol.chunkstories.api.world.WorldMaster)27 Location (io.xol.chunkstories.api.Location)12 Entity (io.xol.chunkstories.api.entity.Entity)12 EntityControllable (io.xol.chunkstories.api.entity.interfaces.EntityControllable)9 Player (io.xol.chunkstories.api.player.Player)8 Vector3d (org.joml.Vector3d)8 Controller (io.xol.chunkstories.api.entity.Controller)6 WorldClient (io.xol.chunkstories.api.world.WorldClient)6 ItemPile (io.xol.chunkstories.api.item.inventory.ItemPile)5 Voxel (io.xol.chunkstories.api.voxel.Voxel)5 World (io.xol.chunkstories.api.world.World)5 Vector3dc (org.joml.Vector3dc)5 WorldException (io.xol.chunkstories.api.exceptions.world.WorldException)4 EntityLiving (io.xol.chunkstories.api.entity.EntityLiving)3 PlayerVoxelModificationEvent (io.xol.chunkstories.api.events.player.voxel.PlayerVoxelModificationEvent)3 ItemVoxel (io.xol.chunkstories.api.item.ItemVoxel)3 CellData (io.xol.chunkstories.api.world.cell.CellData)3 FutureCell (io.xol.chunkstories.api.world.cell.FutureCell)3 SerializedEntityFile (io.xol.chunkstories.entity.SerializedEntityFile)3 LocalPlayer (io.xol.chunkstories.api.client.LocalPlayer)2