Search in sources :

Example 26 with Location

use of io.xol.chunkstories.api.Location in project chunkstories by Hugobros3.

the class DefaultWorldCollisionsManager method raytraceSolid.

private Location raytraceSolid(Vector3dc initialPosition, Vector3dc directionIn, double limit, boolean outer, boolean selectable) {
    Vector3d direction = new Vector3d();
    directionIn.normalize(direction);
    // direction.scale(0.02);
    // float distance = 0f;
    CellData cell;
    // Voxel vox;
    int x, y, z;
    x = (int) Math.floor(initialPosition.x());
    y = (int) Math.floor(initialPosition.y());
    z = (int) Math.floor(initialPosition.z());
    // DDA algorithm
    // It requires double arrays because it works using loops over each dimension
    double[] rayOrigin = new double[3];
    double[] rayDirection = new double[3];
    rayOrigin[0] = initialPosition.x();
    rayOrigin[1] = initialPosition.y();
    rayOrigin[2] = initialPosition.z();
    rayDirection[0] = direction.x();
    rayDirection[1] = direction.y();
    rayDirection[2] = direction.z();
    int[] voxelCoords = new int[] { x, y, z };
    int[] voxelDelta = new int[] { 0, 0, 0 };
    double[] deltaDist = new double[3];
    double[] next = new double[3];
    int[] step = new int[3];
    int side = 0;
    // Prepare distances
    for (int i = 0; i < 3; ++i) {
        double deltaX = rayDirection[0] / rayDirection[i];
        double deltaY = rayDirection[1] / rayDirection[i];
        double deltaZ = rayDirection[2] / rayDirection[i];
        deltaDist[i] = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
        if (rayDirection[i] < 0.f) {
            step[i] = -1;
            next[i] = (rayOrigin[i] - voxelCoords[i]) * deltaDist[i];
        } else {
            step[i] = 1;
            next[i] = (voxelCoords[i] + 1.f - rayOrigin[i]) * deltaDist[i];
        }
    }
    do {
        // DDA steps
        side = 0;
        for (int i = 1; i < 3; ++i) {
            if (next[side] > next[i]) {
                side = i;
            }
        }
        next[side] += deltaDist[side];
        voxelCoords[side] += step[side];
        voxelDelta[side] += step[side];
        x = voxelCoords[0];
        y = voxelCoords[1];
        z = voxelCoords[2];
        cell = world.peekSafely(x, y, z);
        if (cell.getVoxel().getDefinition().isSolid() || (selectable && cell.getVoxel().getDefinition().isSelectable())) {
            boolean collides = false;
            for (CollisionBox box : cell.getTranslatedCollisionBoxes()) {
                // System.out.println(box);
                Vector3dc collisionPoint = box.lineIntersection(initialPosition, direction);
                if (collisionPoint != null) {
                    collides = true;
                // System.out.println("collides @ "+collisionPoint);
                }
            }
            if (collides) {
                if (!outer)
                    return new Location(world, x, y, z);
                else {
                    // Back off a bit
                    switch(side) {
                        case 0:
                            x -= step[side];
                            break;
                        case 1:
                            y -= step[side];
                            break;
                        case 2:
                            z -= step[side];
                            break;
                    }
                    return new Location(world, x, y, z);
                }
            }
        }
    // distance += deltaDist[side];
    } while (voxelDelta[0] * voxelDelta[0] + voxelDelta[1] * voxelDelta[1] + voxelDelta[2] * voxelDelta[2] < limit * limit);
    return null;
}
Also used : Vector3dc(org.joml.Vector3dc) Vector3d(org.joml.Vector3d) CellData(io.xol.chunkstories.api.world.cell.CellData) CollisionBox(io.xol.chunkstories.api.physics.CollisionBox) Location(io.xol.chunkstories.api.Location)

Example 27 with Location

use of io.xol.chunkstories.api.Location 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 28 with Location

use of io.xol.chunkstories.api.Location in project chunkstories-core by Hugobros3.

the class EntityLivingImplementation method tick.

@Override
public void tick() {
    if (getWorld() == null)
        return;
    // Despawn counter is strictly a client matter
    if (getWorld() instanceof WorldMaster) {
        if (isDead()) {
            deathDespawnTimer--;
            if (deathDespawnTimer < 0) {
                world.removeEntity(this);
                return;
            }
        }
        // Fall damage
        if (isOnGround()) {
            if (!wasStandingLastTick && !Double.isNaN(lastStandingHeight)) {
                double fallDistance = lastStandingHeight - this.positionComponent.getLocation().y();
                if (fallDistance > 0) {
                    // System.out.println("Fell "+fallDistance+" meters");
                    if (fallDistance > 5) {
                        float fallDamage = (float) (fallDistance * fallDistance / 2);
                        System.out.println(this + "Took " + fallDamage + " hp of fall damage");
                        this.damage(DAMAGE_CAUSE_FALL, fallDamage);
                    }
                }
            }
            lastStandingHeight = this.positionComponent.getLocation().y();
        }
        this.wasStandingLastTick = isOnGround();
    }
    boolean shouldDoTick = false;
    if (this instanceof EntityControllable) {
        Controller controller = ((EntityControllable) this).getControllerComponent().getController();
        if (controller == null)
            shouldDoTick = (getWorld() instanceof WorldMaster);
        else if (getWorld() instanceof WorldClient && ((WorldClient) getWorld()).getClient().getPlayer().equals(controller))
            shouldDoTick = true;
    } else
        shouldDoTick = (getWorld() instanceof WorldMaster);
    if (shouldDoTick) {
        Vector3dc ogVelocity = getVelocityComponent().getVelocity();
        Vector3d velocity = new Vector3d(ogVelocity);
        Vector2f headRotationVelocity = this.getEntityRotationComponent().tickInpulse();
        getEntityRotationComponent().addRotation(headRotationVelocity.x(), headRotationVelocity.y());
        // voxelIn = VoxelsStore.get().getVoxelById(VoxelFormat.id(world.getVoxelData(positionComponent.getLocation())));
        // voxelIn.getType().isLiquid();
        boolean inWater = isInWater();
        // Gravity
        if (!(this instanceof EntityFlying && ((EntityFlying) this).getFlyingComponent().get())) {
            double terminalVelocity = inWater ? -0.05 : -0.5;
            if (velocity.y() > terminalVelocity)
                velocity.y = (velocity.y() - 0.008);
            if (velocity.y() < terminalVelocity)
                velocity.y = (terminalVelocity);
            // Water limits your overall movement
            double targetSpeedInWater = 0.02;
            if (inWater) {
                if (velocity.length() > targetSpeedInWater) {
                    double decelerationThen = Math.pow((velocity.length() - targetSpeedInWater), 1.0);
                    // System.out.println(decelerationThen);
                    double maxDeceleration = 0.006;
                    if (decelerationThen > maxDeceleration)
                        decelerationThen = maxDeceleration;
                    // System.out.println(decelerationThen);
                    acceleration.add(new Vector3d(velocity).normalize().negate().mul(decelerationThen));
                // acceleration.add(0.0, decelerationThen * (velocity.y() > 0.0 ? 1.0 : -1.0), 0.0);
                }
            }
        }
        // Acceleration
        velocity.x = (velocity.x() + acceleration.x());
        velocity.y = (velocity.y() + acceleration.y());
        velocity.z = (velocity.z() + acceleration.z());
        // TODO ugly
        if (!world.isChunkLoaded((int) (double) positionComponent.getLocation().x() / 32, (int) (double) positionComponent.getLocation().y() / 32, (int) (double) positionComponent.getLocation().z() / 32)) {
            velocity.set(0d, 0d, 0d);
        }
        // Eventually moves
        Vector3dc remainingToMove = moveWithCollisionRestrain(velocity.x(), velocity.y(), velocity.z());
        Vector2d remaining2d = new Vector2d(remainingToMove.x(), remainingToMove.z());
        // Auto-step logic
        if (remaining2d.length() > 0.001 && isOnGround()) {
            // Cap max speed we can get through the bump ?
            if (remaining2d.length() > 0.20d) {
                System.out.println("Too fast, capping");
                remaining2d.normalize();
                remaining2d.mul(0.20);
            }
            // Get whatever we are colliding with
            // Test if setting yourself on top would be ok
            // Do it if possible
            // TODO remake proper
            Vector3d blockedMomentum = new Vector3d(remaining2d.x(), 0, remaining2d.y());
            for (double d = 0.25; d < 0.5; d += 0.05) {
                // I don't want any of this to reflect on the object, because it causes ugly jumps in the animation
                Vector3dc canMoveUp = this.canMoveWithCollisionRestrain(new Vector3d(0.0, d, 0.0));
                // It can go up that bit
                if (canMoveUp.length() == 0.0f) {
                    // Would it help with being stuck ?
                    Vector3d tryFromHigher = new Vector3d(this.getLocation());
                    tryFromHigher.add(new Vector3d(0.0, d, 0.0));
                    Vector3dc blockedMomentumRemaining = this.canMoveWithCollisionRestrain(tryFromHigher, blockedMomentum);
                    // If length of remaining momentum < of what we requested it to do, that means it *did* go a bit further away
                    if (blockedMomentumRemaining.length() < blockedMomentum.length()) {
                        // Where would this land ?
                        Vector3d afterJump = new Vector3d(tryFromHigher);
                        afterJump.add(blockedMomentum);
                        afterJump.sub(blockedMomentumRemaining);
                        // land distance = whatever is left of our -0.55 delta when it hits the ground
                        Vector3dc landDistance = this.canMoveWithCollisionRestrain(afterJump, new Vector3d(0.0, -d, 0.0));
                        afterJump.add(new Vector3d(0.0, -d, 0.0));
                        afterJump.sub(landDistance);
                        this.setLocation(new Location(world, afterJump));
                        remaining2d = new Vector2d(blockedMomentumRemaining.x(), blockedMomentumRemaining.z());
                        break;
                    }
                }
            }
        }
        // Collisions, snap to axises
        if (Math.abs(remaining2d.x()) >= 0.001d)
            velocity.x = (0d);
        if (Math.abs(remaining2d.y()) >= 0.001d)
            velocity.z = (0d);
        // Stap it
        if (isOnGround() && velocity.y() < 0)
            velocity.y = (0d);
        else if (isOnGround())
            velocity.y = (0d);
        getVelocityComponent().setVelocity(velocity);
    }
}
Also used : EntityFlying(io.xol.chunkstories.api.entity.interfaces.EntityFlying) Controller(io.xol.chunkstories.api.entity.Controller) WorldClient(io.xol.chunkstories.api.world.WorldClient) Vector3dc(org.joml.Vector3dc) Vector2d(org.joml.Vector2d) Vector3d(org.joml.Vector3d) Vector2f(org.joml.Vector2f) EntityControllable(io.xol.chunkstories.api.entity.interfaces.EntityControllable) WorldMaster(io.xol.chunkstories.api.world.WorldMaster) Location(io.xol.chunkstories.api.Location)

Example 29 with Location

use of io.xol.chunkstories.api.Location in project chunkstories-core by Hugobros3.

the class EntityPlayer method getBlockLookingAt.

@Override
public Location getBlockLookingAt(boolean inside) {
    Vector3d initialPosition = new Vector3d(getLocation());
    initialPosition.add(new Vector3d(0, eyePosition, 0));
    Vector3d direction = new Vector3d(getDirectionLookingAt());
    if (inside)
        return world.collisionsManager().raytraceSelectable(new Location(world, initialPosition), direction, 256.0);
    else
        return world.collisionsManager().raytraceSolidOuter(new Location(world, initialPosition), direction, 256.0);
}
Also used : Vector3d(org.joml.Vector3d) Location(io.xol.chunkstories.api.Location)

Example 30 with Location

use of io.xol.chunkstories.api.Location in project chunkstories-core by Hugobros3.

the class EntityPlayer method onControllerInput.

@Override
public boolean onControllerInput(Input input, Controller controller) {
    // We are moving inventory bringup here !
    if (input.getName().equals("inventory") && world instanceof WorldClient) {
        if (creativeMode.get()) {
            ((WorldClient) getWorld()).getClient().openInventories(this.inventoryComponent.getInventory(), new InventoryLocalCreativeMenu(world));
        } else {
            ((WorldClient) getWorld()).getClient().openInventories(this.inventoryComponent.getInventory(), this.armor.getInventory());
        }
        return true;
    }
    Location blockLocation = this.getBlockLookingAt(true);
    double maxLen = 1024;
    if (blockLocation != null) {
        Vector3d diff = new Vector3d(blockLocation).sub(this.getLocation());
        // Vector3d dir = diff.clone().normalize();
        maxLen = diff.length();
    }
    Vector3d initialPosition = new Vector3d(getLocation());
    initialPosition.add(new Vector3d(0, eyePosition, 0));
    Vector3dc direction = getDirectionLookingAt();
    Iterator<Entity> i = world.collisionsManager().rayTraceEntities(initialPosition, direction, maxLen);
    while (i.hasNext()) {
        Entity e = i.next();
        if (e.handleInteraction(this, input))
            return true;
    }
    ItemPile itemSelected = getSelectedItemComponent().getSelectedItem();
    if (itemSelected != null) {
        // See if the item handles the interaction
        if (itemSelected.getItem().onControllerInput(this, itemSelected, input, controller))
            return true;
    }
    if (getWorld() instanceof WorldMaster) {
        // Creative mode features building and picking.
        if (this.getCreativeModeComponent().get()) {
            if (input.getName().equals("mouse.left")) {
                if (blockLocation != null) {
                    // Player events mod
                    if (controller instanceof Player) {
                        Player player = (Player) controller;
                        WorldCell cell = world.peekSafely(blockLocation);
                        FutureCell future = new FutureCell(cell);
                        future.setVoxel(this.getDefinition().store().parent().voxels().air());
                        future.setBlocklight(0);
                        future.setSunlight(0);
                        future.setMetaData(0);
                        PlayerVoxelModificationEvent event = new PlayerVoxelModificationEvent(cell, future, EntityCreative.CREATIVE_MODE, player);
                        // Anyone has objections ?
                        world.getGameContext().getPluginManager().fireEvent(event);
                        if (event.isCancelled())
                            return true;
                        Vector3d rnd = new Vector3d();
                        for (int k = 0; k < 40; k++) {
                            rnd.set(blockLocation);
                            rnd.add(Math.random() * 0.98, Math.random() * 0.98, Math.random() * 0.98);
                            world.getParticlesManager().spawnParticleAtPosition("voxel_frag", rnd);
                        }
                        world.getSoundManager().playSoundEffect("sounds/gameplay/voxel_remove.ogg", Mode.NORMAL, blockLocation, 1.0f, 1.0f);
                        try {
                            world.poke(future, this);
                        // world.poke((int)blockLocation.x, (int)blockLocation.y, (int)blockLocation.z, null, 0, 0, 0, this);
                        } catch (WorldException e) {
                        // Discard but maybe play some effect ?
                        }
                        return true;
                    }
                }
            } else if (input.getName().equals("mouse.middle")) {
                if (blockLocation != null) {
                    CellData ctx = this.getWorld().peekSafely(blockLocation);
                    if (!ctx.getVoxel().isAir()) {
                        // Spawn new itemPile in his inventory
                        ItemVoxel item = (ItemVoxel) world.getGameContext().getContent().items().getItemDefinition("item_voxel").newItem();
                        item.voxel = ctx.getVoxel();
                        item.voxelMeta = ctx.getMetaData();
                        ItemPile itemVoxel = new ItemPile(item);
                        this.getInventory().setItemPileAt(getSelectedItemComponent().getSelectedSlot(), 0, itemVoxel);
                        return true;
                    }
                }
            }
        }
    }
    // Then we check if the world minds being interacted with
    return world.handleInteraction(this, blockLocation, input);
}
Also used : Entity(io.xol.chunkstories.api.entity.Entity) Player(io.xol.chunkstories.api.player.Player) LocalPlayer(io.xol.chunkstories.api.client.LocalPlayer) ItemVoxel(io.xol.chunkstories.api.item.ItemVoxel) WorldCell(io.xol.chunkstories.api.world.World.WorldCell) WorldException(io.xol.chunkstories.api.exceptions.world.WorldException) WorldClient(io.xol.chunkstories.api.world.WorldClient) ItemPile(io.xol.chunkstories.api.item.inventory.ItemPile) CellData(io.xol.chunkstories.api.world.cell.CellData) Vector3dc(org.joml.Vector3dc) FutureCell(io.xol.chunkstories.api.world.cell.FutureCell) PlayerVoxelModificationEvent(io.xol.chunkstories.api.events.player.voxel.PlayerVoxelModificationEvent) Vector3d(org.joml.Vector3d) InventoryLocalCreativeMenu(io.xol.chunkstories.core.item.inventory.InventoryLocalCreativeMenu) WorldMaster(io.xol.chunkstories.api.world.WorldMaster) Location(io.xol.chunkstories.api.Location)

Aggregations

Location (io.xol.chunkstories.api.Location)35 Entity (io.xol.chunkstories.api.entity.Entity)17 Player (io.xol.chunkstories.api.player.Player)12 WorldMaster (io.xol.chunkstories.api.world.WorldMaster)12 Vector3d (org.joml.Vector3d)12 EntityControllable (io.xol.chunkstories.api.entity.interfaces.EntityControllable)9 EntityLiving (io.xol.chunkstories.api.entity.EntityLiving)6 Vector3dc (org.joml.Vector3dc)6 CollisionBox (io.xol.chunkstories.api.physics.CollisionBox)5 World (io.xol.chunkstories.api.world.World)5 CellData (io.xol.chunkstories.api.world.cell.CellData)5 EntityCreative (io.xol.chunkstories.api.entity.interfaces.EntityCreative)4 WorldClient (io.xol.chunkstories.api.world.WorldClient)4 PlayerVoxelModificationEvent (io.xol.chunkstories.api.events.player.voxel.PlayerVoxelModificationEvent)3 WorldException (io.xol.chunkstories.api.exceptions.world.WorldException)3 Texture2D (io.xol.chunkstories.api.rendering.textures.Texture2D)3 FutureCell (io.xol.chunkstories.api.world.cell.FutureCell)3 EntityPlayer (io.xol.chunkstories.core.entity.EntityPlayer)3 Matrix4f (org.joml.Matrix4f)3 Vector2d (org.joml.Vector2d)3