Search in sources :

Example 1 with WorldClient

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

the class EntityHumanoid method tick.

@Override
public void tick() {
    eyePosition = stance.get() == EntityHumanoidStance.CROUCHING ? 1.15 : 1.65;
    // Only  if we are allowed to
    boolean tick = false;
    if (this instanceof EntityControllable) {
        Controller controller = ((EntityControllable) this).getControllerComponent().getController();
        if (controller == null)
            tick = (getWorld() instanceof WorldMaster);
        else if (getWorld() instanceof WorldClient && ((WorldClient) getWorld()).getClient().getPlayer().equals(controller))
            tick = true;
    } else
        tick = (getWorld() instanceof WorldMaster);
    if (tick) {
        // The actual moment the jump takes effect
        // voxelIn != null && voxelIn.getType().isLiquid();
        boolean inWater = isInWater();
        if (jumpForce > 0.0 && (!justJumped || inWater)) {
            // Set the velocity
            getVelocityComponent().setVelocityY(jumpForce);
            justJumped = true;
            metersWalked = 0.0;
            jumpForce = 0.0;
        }
        // Set acceleration vector to wanted speed - actual speed
        if (isDead())
            targetVelocity = new Vector3d(0.0);
        acceleration = new Vector3d(targetVelocity.x() - getVelocityComponent().getVelocity().x(), 0, targetVelocity.z() - getVelocityComponent().getVelocity().z());
        // Limit maximal acceleration depending if we're on the groud or not, we accelerate 2x faster on ground
        double maxAcceleration = isOnGround() ? 0.010 : 0.005;
        if (inWater)
            maxAcceleration = 0.005;
        if (acceleration.length() > maxAcceleration) {
            acceleration.normalize();
            acceleration.mul(maxAcceleration);
        }
    }
    // Plays the walking sounds
    handleWalkingEtcSounds();
    // Tick : will move the entity, solve velocity/acceleration and so on
    super.tick();
}
Also used : Vector3d(org.joml.Vector3d) Controller(io.xol.chunkstories.api.entity.Controller) EntityControllable(io.xol.chunkstories.api.entity.interfaces.EntityControllable) WorldClient(io.xol.chunkstories.api.world.WorldClient) WorldMaster(io.xol.chunkstories.api.world.WorldMaster)

Example 2 with WorldClient

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

the class ItemFirearm method onControllerInput.

@Override
public boolean onControllerInput(Entity user, ItemPile pile, Input input, Controller controller) {
    // Don't do anything with the left mouse click
    if (input.getName().startsWith("mouse.")) {
        return true;
    }
    if (input.getName().equals("shootGun")) {
        if (user instanceof EntityLiving) {
            EntityLiving shooter = (EntityLiving) user;
            // Serverside checks
            // if (user.getWorld() instanceof WorldMaster)
            {
                // Is the reload cooldown done
                if (cooldownEnd > System.currentTimeMillis())
                    return false;
                // Do we have any bullets to shoot
                boolean bulletPresence = (user instanceof EntityCreative && ((EntityCreative) user).isCreativeMode()) || checkBullet(pile);
                if (!bulletPresence) {
                    // Dry.ogg
                    return true;
                } else if (!(user instanceof EntityCreative && ((EntityCreative) user).isCreativeMode())) {
                    consumeBullet(pile);
                }
            }
            // Jerk client view a bit
            if (shooter.getWorld() instanceof WorldClient) {
                EntityComponentRotation rot = ((EntityLiving) user).getEntityRotationComponent();
                rot.applyInpulse(shake * (Math.random() - 0.5) * 3.0, shake * -(Math.random() - 0.25) * 5.0);
            }
            // Play sounds
            if (controller != null) {
                controller.getSoundManager().playSoundEffect(this.soundName, Mode.NORMAL, user.getLocation(), 1.0f, 1.0f, 1.0f, (float) soundRange);
            }
            playAnimation();
            // Raytrace shot
            Vector3d eyeLocation = new Vector3d(shooter.getLocation());
            if (shooter instanceof EntityPlayer)
                eyeLocation.add(new Vector3d(0.0, ((EntityPlayer) shooter).eyePosition, 0.0));
            // For each shot
            for (int ss = 0; ss < shots; ss++) {
                Vector3d direction = new Vector3d(shooter.getDirectionLookingAt());
                direction.add(new Vector3d(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5).normalize().mul(accuracy / 100d));
                direction.normalize();
                // Find wall collision
                Location shotBlock = user.getWorld().collisionsManager().raytraceSolid(eyeLocation, direction, range);
                Vector3dc nearestLocation = null;
                // Loops to try and break blocks
                boolean brokeLastBlock = false;
                while (user.getWorld() instanceof WorldMaster && shotBlock != null) {
                    WorldCell peek = user.getWorld().peekSafely(shotBlock);
                    // int data = peek.getData();
                    Voxel voxel = peek.getVoxel();
                    brokeLastBlock = false;
                    if (!voxel.isAir() && voxel.getMaterial().resolveProperty("bulletBreakable") != null && voxel.getMaterial().resolveProperty("bulletBreakable").equals("true")) {
                        // TODO Spawn an event to check if it's okay
                        // Destroy it
                        peek.setVoxel(voxel.store().air());
                        brokeLastBlock = true;
                        for (int i = 0; i < 25; i++) {
                            Vector3d smashedVoxelParticleDirection = new Vector3d(direction);
                            smashedVoxelParticleDirection.mul(2.0);
                            smashedVoxelParticleDirection.add(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
                            smashedVoxelParticleDirection.normalize();
                            user.getWorld().getParticlesManager().spawnParticleAtPositionWithVelocity("voxel_frag", shotBlock, smashedVoxelParticleDirection);
                        }
                        user.getWorld().getSoundManager().playSoundEffect("sounds/environment/glass.ogg", Mode.NORMAL, shotBlock, (float) Math.random() * 0.2f + 0.9f, 1.0f);
                        // Re-raytrace the ray
                        shotBlock = user.getWorld().collisionsManager().raytraceSolid(eyeLocation, direction, range);
                    } else
                        break;
                }
                // Spawn decal and particles on block the bullet embedded itself in
                if (shotBlock != null && !brokeLastBlock) {
                    Location shotBlockOuter = user.getWorld().collisionsManager().raytraceSolidOuter(eyeLocation, direction, range);
                    if (shotBlockOuter != null) {
                        Vector3d normal = shotBlockOuter.sub(shotBlock);
                        double NbyI2x = 2.0 * direction.dot(normal);
                        Vector3d NxNbyI2x = new Vector3d(normal);
                        NxNbyI2x.mul(NbyI2x);
                        Vector3d reflected = new Vector3d(direction);
                        reflected.sub(NxNbyI2x);
                        // Vector3d.sub(direction, NxNbyI2x, reflected);
                        // shotBlock.setX(shotBlock.getX() + 1);
                        WorldCell peek = user.getWorld().peekSafely(shotBlock);
                        for (CollisionBox box : peek.getTranslatedCollisionBoxes()) {
                            Vector3dc thisLocation = box.lineIntersection(eyeLocation, direction);
                            if (thisLocation != null) {
                                if (nearestLocation == null || nearestLocation.distance(eyeLocation) > thisLocation.distance(eyeLocation))
                                    nearestLocation = thisLocation;
                            }
                        }
                        Vector3d particleSpawnPosition = new Vector3d(nearestLocation);
                        // Position adjustements so shot blocks always shoot proper particles
                        if (shotBlock.x() - particleSpawnPosition.x() <= -1.0)
                            particleSpawnPosition.add(-0.01, 0d, 0d);
                        if (shotBlock.y() - particleSpawnPosition.y() <= -1.0)
                            particleSpawnPosition.add(0d, -0.01, 0d);
                        if (shotBlock.z() - particleSpawnPosition.z() <= -1.0)
                            particleSpawnPosition.add(0d, 0d, -0.01);
                        for (int i = 0; i < 25; i++) {
                            Vector3d untouchedReflection = new Vector3d(reflected);
                            Vector3d random = new Vector3d(Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0);
                            random.mul(0.5);
                            untouchedReflection.add(random);
                            untouchedReflection.normalize();
                            untouchedReflection.mul(0.25);
                            // Vector3d ppos = new Vector3d(particleSpawnPosition);
                            controller.getParticlesManager().spawnParticleAtPositionWithVelocity("voxel_frag", particleSpawnPosition, untouchedReflection);
                        }
                        controller.getSoundManager().playSoundEffect(peek.getVoxel().getMaterial().resolveProperty("landingSounds"), Mode.NORMAL, particleSpawnPosition, 1, 0.05f);
                        /*double bspeed = 5/60.0 * (1 + Math.random() * 3 * Math.random());
							Vector3d ppos = new Vector3d(reflected);
							ppos.normalize();
							ppos.scale(0.5);
							ppos.add(nearestLocation);
							WorldEffects.createFireball(shooter.getWorld(), ppos, 1f, damage*0.15*bspeed, (float) (0.0 + 0.05*damage));
							*/
                        controller.getDecalsManager().drawDecal(nearestLocation, normal.negate(), new Vector3d(0.5), "bullethole");
                    }
                }
                // Hitreg takes place on server bois
                if (shooter.getWorld() instanceof WorldMaster) {
                    // Iterate over each found entities
                    Iterator<Entity> shotEntities = user.getWorld().collisionsManager().rayTraceEntities(eyeLocation, direction, 256f);
                    while (shotEntities.hasNext()) {
                        Entity shotEntity = shotEntities.next();
                        // Don't shoot itself & only living things get shot
                        if (!shotEntity.equals(shooter) && shotEntity instanceof EntityLiving) {
                            // Get hit location
                            for (HitBox hitBox : ((EntityLiving) shotEntity).getHitBoxes()) {
                                Vector3dc hitPoint = hitBox.lineIntersection(eyeLocation, direction);
                                if (hitPoint == null)
                                    continue;
                                // System.out.println("shot" + hitBox.getName());
                                // Deal damage
                                ((EntityLiving) shotEntity).damage(pileAsDamageCause(pile), hitBox, (float) damage);
                                // Spawn blood particles
                                Vector3d bloodDir = direction.normalize().mul(0.75);
                                for (int i = 0; i < 120; i++) {
                                    Vector3d random = new Vector3d(Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0, Math.random() * 2.0 - 1.0);
                                    random.mul(0.25);
                                    random.add(bloodDir);
                                    shooter.getWorld().getParticlesManager().spawnParticleAtPositionWithVelocity("blood", hitPoint, random);
                                }
                                // Spawn blood on walls
                                if (nearestLocation != null)
                                    shooter.getWorld().getDecalsManager().drawDecal(nearestLocation, bloodDir, new Vector3d(Math.min(3, shots) * damage / 20f), "blood");
                            }
                        }
                    }
                }
            }
            controller.getParticlesManager().spawnParticleAtPosition("muzzle", eyeLocation);
            FirearmShotEvent event = new FirearmShotEvent(this, shooter, controller);
            shooter.getWorld().getGameContext().getPluginManager().fireEvent(event);
            return (shooter.getWorld() instanceof WorldMaster);
        }
    }
    return false;
}
Also used : EntityComponentRotation(io.xol.chunkstories.api.entity.components.EntityComponentRotation) Entity(io.xol.chunkstories.api.entity.Entity) HitBox(io.xol.chunkstories.api.entity.EntityLiving.HitBox) WorldCell(io.xol.chunkstories.api.world.World.WorldCell) EntityLiving(io.xol.chunkstories.api.entity.EntityLiving) EntityCreative(io.xol.chunkstories.api.entity.interfaces.EntityCreative) WorldClient(io.xol.chunkstories.api.world.WorldClient) Vector3dc(org.joml.Vector3dc) Vector3d(org.joml.Vector3d) Voxel(io.xol.chunkstories.api.voxel.Voxel) EntityPlayer(io.xol.chunkstories.core.entity.EntityPlayer) WorldMaster(io.xol.chunkstories.api.world.WorldMaster) Location(io.xol.chunkstories.api.Location) CollisionBox(io.xol.chunkstories.api.physics.CollisionBox)

Example 3 with WorldClient

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

the class HeightmapImplementation method setSummaryData.

public void setSummaryData(int[] heightData, int[] voxelData) {
    // texturesUpToDate.set(false);
    // 512kb per summary, use of max mipmaps for heights
    heights = new int[(int) Math.ceil(256 * 256 * (1 + 1 / 3D))];
    ids = new int[(int) Math.ceil(256 * 256 * (1 + 1 / 3D))];
    System.arraycopy(heightData, 0, heights, 0, 256 * 256);
    System.arraycopy(voxelData, 0, ids, 0, 256 * 256);
    recomputeMetadata();
    summaryLoaded.set(true);
    if (world instanceof WorldClient) {
        ((WorldClient) world).getWorldRenderer().getSummariesTexturesHolder().warnDataHasArrived(regionX, regionZ);
    }
    // Already have clients waiting for it ? Satisfy these messieurs
    usersLock.lock();
    for (RemotePlayer user : usersWaitingForIntialData) {
        user.pushPacket(new PacketHeightmap(this));
    }
    usersWaitingForIntialData.clear();
    usersLock.unlock();
}
Also used : PacketHeightmap(io.xol.chunkstories.net.packets.PacketHeightmap) RemotePlayer(io.xol.chunkstories.api.server.RemotePlayer) WorldClient(io.xol.chunkstories.api.world.WorldClient)

Example 4 with WorldClient

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

the class ChunkHolderImplementation method createChunk.

public CubicChunk createChunk(CompressedData data) {
    this.chunkLock.writeLock().lock();
    if (this.chunk != null) {
        System.out.println("Warning: creating a chunk but the chunkholder already had one, ignoring");
        this.chunkLock.writeLock().unlock();
        return this.chunk;
    }
    CubicChunk chunk;
    if (region.world instanceof WorldClient) {
        chunk = createClientChunk(this, x, y, z, data);
    // chunk = data == null ? new ClientChunk(this, x, y, z) : new ClientChunk(this, x, y, z, data);
    } else
        chunk = data == null ? new CubicChunk(this, x, y, z) : new CubicChunk(this, x, y, z, data);
    if (this.chunk == null && chunk != null)
        regionLoadedChunks.add(chunk);
    this.chunk = chunk;
    if (region.getWorld() instanceof WorldClient)
        ((WorldClient) region.getWorld()).getWorldRenderer().flagChunksModified();
    this.chunkLock.writeLock().unlock();
    // Already have clients waiting for it ? Satisfy these messieurs
    usersLock.lock();
    for (RemotePlayer user : usersWaitingForIntialData) {
        user.pushPacket(new PacketChunkCompressedData(chunk, data));
    }
    usersWaitingForIntialData.clear();
    usersLock.unlock();
    return chunk;
}
Also used : PacketChunkCompressedData(io.xol.chunkstories.net.packets.PacketChunkCompressedData) RemotePlayer(io.xol.chunkstories.api.server.RemotePlayer) WorldClient(io.xol.chunkstories.api.world.WorldClient)

Example 5 with WorldClient

use of io.xol.chunkstories.api.world.WorldClient 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)

Aggregations

WorldClient (io.xol.chunkstories.api.world.WorldClient)11 Vector3d (org.joml.Vector3d)8 WorldMaster (io.xol.chunkstories.api.world.WorldMaster)6 Location (io.xol.chunkstories.api.Location)4 Vector3dc (org.joml.Vector3dc)4 Entity (io.xol.chunkstories.api.entity.Entity)3 EntityControllable (io.xol.chunkstories.api.entity.interfaces.EntityControllable)3 Voxel (io.xol.chunkstories.api.voxel.Voxel)3 Controller (io.xol.chunkstories.api.entity.Controller)2 ItemVoxel (io.xol.chunkstories.api.item.ItemVoxel)2 ItemPile (io.xol.chunkstories.api.item.inventory.ItemPile)2 RemotePlayer (io.xol.chunkstories.api.server.RemotePlayer)2 WorldCell (io.xol.chunkstories.api.world.World.WorldCell)2 LocalPlayer (io.xol.chunkstories.api.client.LocalPlayer)1 EntityLiving (io.xol.chunkstories.api.entity.EntityLiving)1 HitBox (io.xol.chunkstories.api.entity.EntityLiving.HitBox)1 EntityComponentRotation (io.xol.chunkstories.api.entity.components.EntityComponentRotation)1 EntityCreative (io.xol.chunkstories.api.entity.interfaces.EntityCreative)1 EntityFlying (io.xol.chunkstories.api.entity.interfaces.EntityFlying)1 PlayerVoxelModificationEvent (io.xol.chunkstories.api.events.player.voxel.PlayerVoxelModificationEvent)1