Search in sources :

Example 1 with ParticleFX

use of ebf.tim.models.ParticleFX in project Trains-In-Motion-1.7.10 by EternalBlueFlame.

the class GenericRailTransport method onUpdate.

/**
     * <h2> on entity update </h2>
     *
     * defines what should be done every tick
     * used for:
     * managing the list of bogies and seats, respawning them if they disappear.
     * managing speed, acceleration. and direction.
     * managing rotationYaw and rotationPitch.
     * updating rider entity positions if there is no one riding the core seat.
     * calling on link management.
     * @see #manageLinks()
     * syncing the owner entity ID with client.
     * being sure the transport is listed in the main class (for lighting management).
     * @see ClientProxy#onTick(TickEvent.ClientTickEvent)
     * and updating the lighting block.
     */
@Override
public void onUpdate() {
    //if the cart has fallen out of the map, destroy it.
    if (posY < -64.0D & isDead) {
        worldObj.removeEntity(this);
    }
    if (this.chunkTicket == null) {
        this.requestTicket();
    }
    //always be sure the bogies exist on client and server.
    if (!worldObj.isRemote && (frontBogie == null || backBogie == null)) {
        //spawn frontLinkedTransport bogie
        vectorCache[1][0] = getLengthFromCenter();
        vectorCache[0] = RailUtility.rotatePoint(vectorCache[1], rotationPitch, rotationYaw, 0);
        frontBogie = new EntityBogie(worldObj, posX + vectorCache[0][0], posY + vectorCache[0][1], posZ + vectorCache[0][2], getEntityId(), true);
        frontBogie.setVelocity(frontVelocityX, 0, frontVelocityZ);
        //spawn backLinkedTransport bogie
        vectorCache[1][0] = -getLengthFromCenter();
        vectorCache[0] = RailUtility.rotatePoint(vectorCache[1], rotationPitch, rotationYaw, 0);
        backBogie = new EntityBogie(worldObj, posX + vectorCache[0][0], posY + vectorCache[0][1], posZ + vectorCache[0][2], getEntityId(), false);
        backBogie.setVelocity(backVelocityX, 0, backVelocityZ);
        worldObj.spawnEntityInWorld(frontBogie);
        worldObj.spawnEntityInWorld(backBogie);
        if (getRiderOffsets() != null && getRiderOffsets().length > 1 && seats.size() < getRiderOffsets().length) {
            for (int i = 0; i < getRiderOffsets().length - 1; i++) {
                EntitySeat seat = new EntitySeat(worldObj, posX, posY, posZ, getEntityId(), i);
                worldObj.spawnEntityInWorld(seat);
                seats.add(seat);
            }
        }
    }
    /*
         * run the hitbox check whether or not the bogies exist so we can ensure interaction even during severe client-sided error.
         *check if the bogies exist, because they may not yet, and if they do, check if they are actually moving or colliding.
         * no point in processing movement if they aren't moving or if the train hit something.
         * if it is clear however, then we need to add velocity to the bogies based on the current state of the train's speed and fuel, and reposition the train.
         * but either way we have to position the bogies around the train, just to be sure they don't accidentally fly off at some point.
         *
         */
    if (frontBogie != null && backBogie != null) {
        //handle movement.
        if (!hitboxHandler.getCollision(this)) {
            frontBogie.minecartMove(rotationPitch, rotationYaw, getBoolean(boolValues.BRAKE), getBoolean(boolValues.RUNNING), getType().isTrain());
            backBogie.minecartMove(rotationPitch, rotationYaw, getBoolean(boolValues.BRAKE), getBoolean(boolValues.RUNNING), getType().isTrain());
        } else {
            frontBogie.addVelocity(-frontBogie.motionX, -frontBogie.motionY, -frontBogie.motionZ);
            backBogie.addVelocity(-backBogie.motionX, -backBogie.motionY, -backBogie.motionZ);
            frontBogie.minecartMove(rotationPitch, rotationYaw, getBoolean(boolValues.BRAKE), getBoolean(boolValues.RUNNING), getType().isTrain());
            backBogie.minecartMove(rotationPitch, rotationYaw, getBoolean(boolValues.BRAKE), getBoolean(boolValues.RUNNING), getType().isTrain());
        }
        frontVelocityX = frontBogie.motionX;
        frontVelocityZ = frontBogie.motionZ;
        backVelocityX = backBogie.motionX;
        backVelocityZ = backBogie.motionZ;
        //position this
        setPosition(((frontBogie.posX + backBogie.posX) * 0.5D), ((frontBogie.posY + backBogie.posY) * 0.5D), ((frontBogie.posZ + backBogie.posZ) * 0.5D));
        setRotation((float) Math.toDegrees(Math.atan2(frontBogie.posZ - backBogie.posZ, frontBogie.posX - backBogie.posX)), MathHelper.floor_double(Math.acos(frontBogie.posY / backBogie.posY) * RailUtility.degreesD));
        if (ticksExisted % 2 == 0) {
            //align bogies
            vectorCache[1][0] = getLengthFromCenter();
            vectorCache[0] = rotatePoint(vectorCache[1], rotationPitch, rotationYaw, 0.0f);
            frontBogie.setPosition(vectorCache[0][0] + posX, frontBogie.posY, vectorCache[0][2] + posZ);
            vectorCache[1][0] = -getLengthFromCenter();
            vectorCache[0] = rotatePoint(vectorCache[1], rotationPitch, rotationYaw, 0.0f);
            backBogie.setPosition(vectorCache[0][0] + posX, backBogie.posY, vectorCache[0][2] + posZ);
        }
        manageLinks();
    }
    //rider updating isn't called if there's no driver/conductor, so just in case of that, we reposition the seats here too.
    if (riddenByEntity == null && getRiderOffsets() != null) {
        for (int i = 0; i < seats.size(); i++) {
            vectorCache[0] = rotatePoint(getRiderOffsets()[i], rotationPitch, rotationYaw, 0);
            vectorCache[0][0] += posX;
            vectorCache[0][1] += posY;
            vectorCache[0][2] += posZ;
            seats.get(i).setPosition(vectorCache[0][0], vectorCache[0][1], vectorCache[0][2]);
        }
    }
    //be sure the owner entityID is currently loaded, this variable is dynamic so we don't save it to NBT.
    if (!worldObj.isRemote && ticksExisted % 5 == 0) {
        manageFuel();
        @Nullable Entity player = CommonProxy.getEntityFromUuid(owner);
        if (player != null) {
            ownerID = player.getEntityId();
        }
        //sync the linked transports with client, and on server, easier to use an ID than a UUID.
        Entity linkedTransport = CommonProxy.getEntityFromUuid(frontLinkedTransport);
        frontLinkedID = linkedTransport instanceof GenericRailTransport ? linkedTransport.getEntityId() : 0;
        linkedTransport = CommonProxy.getEntityFromUuid(backLinkedTransport);
        backLinkedID = linkedTransport instanceof GenericRailTransport ? linkedTransport.getEntityId() : 0;
        if (updateWatchers) {
            if (fluidTank != null) {
                dataWatcher.updateObject(20, fluidTank.amount);
            }
            this.dataWatcher.updateObject(19, ownerID);
            this.dataWatcher.updateObject(17, bools.toInt());
            this.dataWatcher.updateObject(21, linkedTransport instanceof GenericRailTransport ? linkedTransport.getEntityId() : 0);
            this.dataWatcher.updateObject(22, linkedTransport instanceof GenericRailTransport ? linkedTransport.getEntityId() : 0);
        }
    }
    /*
         * be sure the client proxy has a reference to this so the lamps can be updated, and then every other tick, attempt to update the lamp position if it's necessary.
         */
    if (backBogie != null && !isDead && worldObj.isRemote) {
        if (ClientProxy.EnableLights && !ClientProxy.carts.contains(this)) {
            ClientProxy.carts.add(this);
        }
        if (lamp.Y > 1 && ticksExisted % 2 == 1) {
            vectorCache[0][0] = this.posX + getLampOffset().xCoord;
            vectorCache[0][1] = this.posY + getLampOffset().yCoord;
            vectorCache[0][2] = this.posZ + getLampOffset().zCoord;
            lamp.ShouldUpdate(worldObj, RailUtility.rotatePoint(vectorCache[0], rotationPitch, rotationYaw, 0));
        }
        //update the particles here rather than on render tick, it's not as smooth, but close enough and far less CPU use.
        if (ClientProxy.EnableSmokeAndSteam) {
            int itteration = 0;
            int maxSpawnThisTick = 0;
            for (float[] smoke : getSmokeOffset()) {
                for (int i = 0; i < smoke[4]; i++) {
                    //define the position
                    vectorCache[7][0] = smoke[0];
                    vectorCache[7][1] = smoke[1];
                    vectorCache[7][2] = smoke[2];
                    vectorCache[8] = RailUtility.rotatePoint(vectorCache[7], rotationPitch, rotationYaw, 0);
                    //this helps make them spawn more evenly rather than all at once. It also helps prevent a lot of lag.
                    if (getBoolean(boolValues.RUNNING) && particles.size() <= itteration && maxSpawnThisTick < 5) {
                        particles.add(new ParticleFX(posZ, posY, posX, smoke[3], vectorCache[8], backBogie.motionX + (rand.nextInt(40) - 20) * 0.001f, smoke[1] * 0.05, backBogie.motionZ + (rand.nextInt(40) - 20) * 0.001f));
                        maxSpawnThisTick++;
                    } else if (maxSpawnThisTick == 0) {
                        //if the particles have finished spawning in, move them.
                        particles.get(itteration).onUpdate(this, posX, posY, posZ, getBoolean(boolValues.RUNNING));
                    }
                    itteration++;
                }
            }
        }
    }
}
Also used : Entity(net.minecraft.entity.Entity) ParticleFX(ebf.tim.models.ParticleFX) RailUtility.rotatePoint(ebf.tim.utility.RailUtility.rotatePoint) Nullable(javax.annotation.Nullable)

Aggregations

ParticleFX (ebf.tim.models.ParticleFX)1 RailUtility.rotatePoint (ebf.tim.utility.RailUtility.rotatePoint)1 Nullable (javax.annotation.Nullable)1 Entity (net.minecraft.entity.Entity)1