Search in sources :

Example 1 with EditableCell

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

the class ItemMeleeWeapon method onControllerInput.

@Override
public boolean onControllerInput(Entity owner, ItemPile pile, Input input, Controller controller) {
    if (input.getName().startsWith("mouse.left")) {
        // Checks current swing is done
        if (System.currentTimeMillis() - currentSwingStart > swingDuration) {
            currentSwingStart = System.currentTimeMillis();
            hasHitYet = false;
        }
        return true;
    } else if (input.getName().equals("shootGun") && owner.getWorld() instanceof WorldMaster) {
        // Actually hits
        EntityLiving shooter = (EntityLiving) owner;
        Vector3dc direction = shooter.getDirectionLookingAt();
        Vector3d eyeLocation = new Vector3d(shooter.getLocation());
        if (shooter instanceof EntityPlayer)
            eyeLocation.add(new Vector3d(0.0, ((EntityPlayer) shooter).eyePosition, 0.0));
        // Find wall collision
        Location shotBlock = owner.getWorld().collisionsManager().raytraceSolid(eyeLocation, direction, range);
        Vector3d nearestLocation = new Vector3d();
        // Loops to try and break blocks
        while (owner.getWorld() instanceof WorldMaster && shotBlock != null) {
            EditableCell peek = owner.getWorld().peekSafely(shotBlock);
            if (!peek.getVoxel().isAir() && peek.getVoxel().getMaterial().resolveProperty("bulletBreakable") != null && peek.getVoxel().getMaterial().resolveProperty("bulletBreakable").equals("true")) {
                // TODO: Spawn an event to check if it's okay
                // Destroy it
                peek.setVoxel(getDefinition().store().parent().voxels().air());
                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();
                    owner.getWorld().getParticlesManager().spawnParticleAtPositionWithVelocity("voxel_frag", shotBlock, smashedVoxelParticleDirection);
                }
                owner.getWorld().getSoundManager().playSoundEffect("sounds/environment/glass.ogg", Mode.NORMAL, shotBlock, (float) Math.random() * 0.2f + 0.9f, 1.0f);
                // Re-raytrace the ray
                shotBlock = owner.getWorld().collisionsManager().raytraceSolid(eyeLocation, direction, range);
            } else
                break;
        }
        if (shotBlock != null) {
            Location shotBlockOuter = owner.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);
                CellData peek = owner.getWorld().peekSafely(shotBlock);
                // This seems fine
                for (CollisionBox box : peek.getTranslatedCollisionBoxes()) {
                    Vector3dc thisLocation = box.lineIntersection(eyeLocation, direction);
                    if (thisLocation != null) {
                        if (nearestLocation == null || nearestLocation.distance(eyeLocation) > thisLocation.distance(eyeLocation))
                            nearestLocation.set(thisLocation);
                    }
                }
                // Position adjustements so shot blocks always shoot proper particles
                if (shotBlock.x() - nearestLocation.x() <= -1.0)
                    nearestLocation.add(-0.01, 0.0, 0.0);
                if (shotBlock.y() - nearestLocation.y() <= -1.0)
                    nearestLocation.add(0.0, -0.01, 0.0);
                if (shotBlock.z() - nearestLocation.z() <= -1.0)
                    nearestLocation.add(0.0, 0.0, -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(nearestLocation);
                    owner.getWorld().getParticlesManager().spawnParticleAtPositionWithVelocity("voxel_frag", ppos, untouchedReflection);
                    owner.getWorld().getSoundManager().playSoundEffect(owner.getWorld().peekSafely(shotBlock).getVoxel().getMaterial().resolveProperty("landingSounds"), Mode.NORMAL, ppos, 1, 0.25f);
                }
                owner.getWorld().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 = owner.getWorld().collisionsManager().rayTraceEntities(eyeLocation, direction, range);
            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;
                        // Deal damage
                        ((EntityLiving) shotEntity).damage(pileAsDamageCause(pile), hitBox, (float) damage);
                        // Spawn blood particles
                        Vector3d bloodDir = new Vector3d();
                        direction.normalize(bloodDir).mul(0.25);
                        for (int i = 0; i < 250; 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(3.0), "blood");
                    }
                }
            }
        }
    }
    return false;
}
Also used : Vector3dc(org.joml.Vector3dc) Entity(io.xol.chunkstories.api.entity.Entity) HitBox(io.xol.chunkstories.api.entity.EntityLiving.HitBox) EntityLiving(io.xol.chunkstories.api.entity.EntityLiving) Vector3d(org.joml.Vector3d) Iterator(java.util.Iterator) EntityPlayer(io.xol.chunkstories.core.entity.EntityPlayer) CellData(io.xol.chunkstories.api.world.cell.CellData) WorldMaster(io.xol.chunkstories.api.world.WorldMaster) EditableCell(io.xol.chunkstories.api.world.cell.EditableCell) Location(io.xol.chunkstories.api.Location) CollisionBox(io.xol.chunkstories.api.physics.CollisionBox)

Example 2 with EditableCell

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

the class VoxelDoor method handleInteraction.

// Meta
// 0x0 -> open/close
// 0x1 -> left/right hinge || left = 0 right = 1 (left is default)
// 0x2-0x4 -> side ( VoxelSide << 2 )
@Override
public boolean handleInteraction(Entity entity, ChunkCell voxelContext, Input input) {
    if (!input.getName().equals("mouse.right"))
        return false;
    if (!(entity.getWorld() instanceof WorldMaster))
        return true;
    boolean isOpen = ((voxelContext.getMetaData() >> 0) & 0x1) == 1;
    boolean hingeSide = ((voxelContext.getMetaData() >> 1) & 0x1) == 1;
    int facingPassed = (voxelContext.getMetaData() >> 2) & 0x3;
    boolean newState = !isOpen;
    int newData = computeMeta(newState, hingeSide, facingPassed);
    Location otherPartLocation = voxelContext.getLocation();
    if (top)
        otherPartLocation.add(0.0, -1.0, 0.0);
    else
        otherPartLocation.add(0.0, 1.0, 0.0);
    EditableCell otherLocationPeek = voxelContext.getWorld().peekSafely(otherPartLocation);
    if (otherLocationPeek.getVoxel() instanceof VoxelDoor) {
        System.out.println("new door status : " + newState);
        voxelContext.getWorld().getSoundManager().playSoundEffect("sounds/voxels/door.ogg", Mode.NORMAL, voxelContext.getLocation(), 1.0f, 1.0f);
        voxelContext.setMetaData(newData);
        otherLocationPeek.setMetaData(newData);
    // otherPartLocation.setVoxelDataAtLocation(VoxelFormat.changeMeta(otherPartLocation.getVoxelDataAtLocation(), newData));
    } else {
        store.parent().logger().error("Incomplete door @ " + otherPartLocation);
    }
    return true;
}
Also used : WorldMaster(io.xol.chunkstories.api.world.WorldMaster) EditableCell(io.xol.chunkstories.api.world.cell.EditableCell) Location(io.xol.chunkstories.api.Location)

Aggregations

Location (io.xol.chunkstories.api.Location)2 WorldMaster (io.xol.chunkstories.api.world.WorldMaster)2 EditableCell (io.xol.chunkstories.api.world.cell.EditableCell)2 Entity (io.xol.chunkstories.api.entity.Entity)1 EntityLiving (io.xol.chunkstories.api.entity.EntityLiving)1 HitBox (io.xol.chunkstories.api.entity.EntityLiving.HitBox)1 CollisionBox (io.xol.chunkstories.api.physics.CollisionBox)1 CellData (io.xol.chunkstories.api.world.cell.CellData)1 EntityPlayer (io.xol.chunkstories.core.entity.EntityPlayer)1 Iterator (java.util.Iterator)1 Vector3d (org.joml.Vector3d)1 Vector3dc (org.joml.Vector3dc)1