Package mrtjp.projectred.integration

Source Code of mrtjp.projectred.integration.BundledGateLogic$BusRandomizer

package mrtjp.projectred.integration;

import codechicken.lib.data.MCDataInput;
import codechicken.lib.data.MCDataOutput;
import codechicken.lib.raytracer.ExtendedMOP;
import codechicken.lib.raytracer.IndexedCuboid6;
import codechicken.lib.vec.Cuboid6;
import codechicken.lib.vec.Vector3;
import mrtjp.core.vec.VecLib;
import mrtjp.projectred.api.IBundledEmitter;
import mrtjp.projectred.api.IConnectable;
import mrtjp.projectred.api.IScrewdriver;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.MovingObjectPosition;

import java.util.List;
import java.util.Random;

import static mrtjp.projectred.transmission.BundledCommons.*;

public abstract class BundledGateLogic extends RedstoneGateLogic<BundledGatePart>
{
    public static BundledGateLogic create(BundledGatePart gate, int subID)
    {
        if (subID == 22)
            return new BusTransceiver(gate);
        if (subID == 28)
            return new BusRandomizer(gate);
        if (subID == 29)
            return new BusConverter(gate);
        if (subID == 30)
            return new BusInputPanel(gate);
        return null;
    }

    public BundledGateLogic(BundledGatePart gate)
    {
        this.gate = gate;
    }

    public BundledGatePart gate;

    @Override
    public boolean canConnectTo(BundledGatePart gate, IConnectable wire, int r)
    {
        if (super.canConnectTo(gate, wire, r))
            return true;
        if (wire instanceof IBundledEmitter)
            return canConnectBundled(gate, r);
        return false;
    }

    public boolean canConnectBundled(BundledGatePart gate, int r)
    {
        return canConnectBundled(gate.shape(), r);
    }

    public boolean canConnectBundled(int shape, int r)
    {
        return ((bundledInputMask(shape)|bundledOutputMask(shape))&1<<r) != 0;
    }

    public int bundledInputMask(int shape)
    {
        return 0;
    }

    public int bundledOutputMask(int shape)
    {
        return 0;
    }

    @Override
    public int getOutput(BundledGatePart gate, int r)
    {
        return (gate.state&0x10<<r) != 0 ? 15 : 0;
    }

    public byte[] getBundledOutput(BundledGatePart gate, int r)
    {
        return null;
    }

    @Override
    public void onChange(BundledGatePart gate)
    {
    }

    @Override
    public void scheduledTick(BundledGatePart gate)
    {
    }

    public void save(NBTTagCompound tag)
    {
    }

    public void load(NBTTagCompound tag)
    {
    }

    public void readDesc(MCDataInput packet)
    {
    }

    public void writeDesc(MCDataOutput packet)
    {
    }

    public void read(MCDataInput packet, int switch_key)
    {
    }

    public static class BusTransceiver extends BundledGateLogic
    {
        public byte[] input0, output0, input2, output2;

        public BusTransceiver(BundledGatePart gate)
        {
            super(gate);
        }

        @Override
        public void save(NBTTagCompound tag)
        {
            saveSignal(tag, "in0", input0);
            saveSignal(tag, "out0", output0);
            saveSignal(tag, "in2", input2);
            saveSignal(tag, "out2", output2);
        }

        @Override
        public void load(NBTTagCompound tag)
        {
            input0 = loadSignal(tag, "in0");
            input2 = loadSignal(tag, "in2");
            output0 = loadSignal(tag, "out0");
            output2 = loadSignal(tag, "out2");
        }

        @Override
        public void readDesc(MCDataInput packet)
        {
            unpackClientData(packet.readInt());
        }

        @Override
        public void writeDesc(MCDataOutput packet)
        {
            packet.writeInt(packClientData());
        }

        @Override
        public void read(MCDataInput packet, int switch_key)
        {
            if (switch_key == 11)
                unpackClientData(packet.readInt());
        }

        public void sendClientUpdate()
        {
            gate.getWriteStream(11).writeInt(packClientData());
        }

        public int packClientData()
        {
            return packDigital(output0)|packDigital(output2)<<16;
        }

        public void unpackClientData(int packed)
        {
            output0 = unpackDigital(output0, packed&0xFFFF);
            output2 = unpackDigital(output2, packed>>>16);
        }

        @Override
        public int bundledInputMask(int shape)
        {
            return 1|4;
        }

        @Override
        public int bundledOutputMask(int shape)
        {
            return 1|4;
        }

        @Override
        public int inputMask(int shape)
        {
            return 2|8;
        }

        @Override
        public int outputMask(int shape)
        {
            return 0;
        }

        @Override
        public byte[] getBundledOutput(BundledGatePart gate, int r)
        {
            return r == 0 ? output0 : output2;
        }

        public byte[] getBundledInput(int r)
        {
            return raiseSignal(copySignal(gate.getBundledInput(r)), getBundledOutput(gate, r));// or'd with our output
        }

        @Override
        public void onChange(BundledGatePart gate)
        {
            boolean inputChanged = false;

            int oldInput = gate.state()&0xF;
            int newInput = getInput(gate, 2|8);
            if (oldInput != newInput)
            {
                gate.setState(gate.state()&0xF0|newInput);
                inputChanged = true;
            }

            byte[] newInput0 = getBundledInput(0);
            if (!signalsEqual(input0, newInput0))
            {
                input0 = newInput0;
                inputChanged = true;
            }

            byte[] newInput2 = getBundledInput(2);
            if (!signalsEqual(input2, newInput2))
            {
                input2 = newInput2;
                inputChanged = true;
            }

            if (inputChanged) gate.onInputChange();

            if (!signalsEqual(output0, getBundledOutput(0)) || !signalsEqual(output2, getBundledOutput(2)))
                gate.scheduleTick(2);
        }

        public byte[] getBundledOutput(int r)
        {
            int input = gate.state()&0xF;
            if (gate.shape() == 1)
                input = GatePart.flipMaskZ(input);

            if (r == 0)
                return (input&2) != 0 ? input2 : null;
            if (r == 2)
                return (input&8) != 0 ? input0 : null;

            return null;
        }

        @Override
        public void scheduledTick(BundledGatePart gate)
        {
            output0 = getBundledOutput(0);
            output2 = getBundledOutput(2);

            onChange(gate);
            gate.onOutputChange(1|4);
            sendClientUpdate();
        }

        @Override
        public boolean cycleShape(BundledGatePart gate)
        {
            gate.setShape(gate.shape() == 0 ? 1 : 0);
            return true;
        }

        @Override
        public int lightLevel()
        {
            return 0;
        }
    }

    public static class BusRandomizer extends BundledGateLogic
    {
        public Random rand = new Random();

        byte[] unpackedOut = new byte[16];
        int output = 0;
        int mask = 0xFFFF;

        public BusRandomizer(BundledGatePart gate)
        {
            super(gate);
        }

        @Override
        public int bundledOutputMask(int shape)
        {
            return 5;
        }

        @Override
        public int inputMask(int shape)
        {
            return 10;
        }

        @Override
        public int outputMask(int shape)
        {
            return 0;
        }

        @Override
        public void onChange(BundledGatePart gate)
        {
            boolean inputChanged = false;

            int oldInput = gate.state()&0xF;
            int newInput = getInput(gate, 10);
            if (oldInput != newInput)
            {
                gate.setState(gate.state()&0xF0|newInput);
                inputChanged = true;
            }

            int newMask = packDigital(gate.getBundledInput(2));
            if (newMask == 0) newMask = 0xFFFF;
            if (mask != newMask)
            {
                mask = newMask;
                inputChanged = true;
                sendMaskUpdate();
            }

            if (inputChanged) gate.onInputChange();

            if (newInput != 0) gate.scheduleTick(2);
        }

        @Override
        public void scheduledTick(BundledGatePart gate)
        {
            int oldOut = output;
            output = (gate.state()&0xF) != 0 ? gate.shape() == 0 ? calc1BitOut() : calcNBitOut() : oldOut;
            if (oldOut != output)
            {
                unpackedOut = unpackDigital(unpackedOut, output);
                gate.onOutputChange(1);
                sendOutUpdate();
            }
            onChange(gate);
        }

        private int calc1BitOut()
        {
            int high = Integer.bitCount(mask);
            int n = rand.nextInt(high);
            int v = 0;
            for (int i = 0; i < 16; i++) if ((mask&1<<i) != 0 && v++ == n) return 1<<i;
            return 0;
        }

        private int calcNBitOut()
        {
            int out = 0;
            for (int i = 0; i < 16; i++) if ((mask&1<<i) != 0 && rand.nextBoolean()) out |= 1<<i;
            return out;
        }

        @Override
        public void readDesc(MCDataInput packet)
        {
            output = packet.readUShort();
            mask = packet.readUShort();
        }

        @Override
        public void writeDesc(MCDataOutput packet)
        {
            packet.writeShort(output);
            packet.writeShort(mask);
        }

        @Override
        public void read(MCDataInput packet, int switch_key)
        {
            if (switch_key == 11)
                output = packet.readUShort();
            else if (switch_key == 12)
                mask = packet.readUShort();
        }

        private void sendOutUpdate()
        {
            gate.getWriteStream(11).writeShort(output);
        }

        private void sendMaskUpdate()
        {
            gate.getWriteStream(12).writeShort(mask);
        }

        @Override
        public void save(NBTTagCompound tag)
        {
            tag.setShort("in", (short)(mask&0xFFFF));
            tag.setShort("out", (short)(output&0xFFFF));
        }

        @Override
        public void load(NBTTagCompound tag)
        {
            mask = tag.getShort("in");
            output = tag.getShort("out");
            unpackedOut = unpackDigital(unpackedOut, output);
        }

        @Override
        public byte[] getBundledOutput(BundledGatePart gate, int r)
        {
            return r == 0 ? unpackedOut : null;
        }

        @Override
        public boolean cycleShape(BundledGatePart gate)
        {
            gate.setShape(gate.shape()^1);
            return true;
        }

        @Override
        public int lightLevel()
        {
            return 0;
        }
    }

    public static class BusConverter extends BundledGateLogic
    {
        public int bIn, bOut;
        public int rsIn, rsOut;
        public byte[] bOutUnpacked;

        public BusConverter(BundledGatePart gate)
        {
            super(gate);
        }

        public void setBOut(int newBOut)
        {
            if (bOut == newBOut) return;
            bOut = newBOut;
            bOutUnpacked = unpackDigital(bOutUnpacked, bOut);
        }

        @Override
        public int bundledOutputMask(int shape){ return shape == 0 ? 1 : 0; }

        @Override
        public int bundledInputMask(int shape){ return shape == 0 ? 0 : 1; }

        @Override
        public int outputMask(int shape){ return shape == 0 ? 10 : 14; }

        @Override
        public int inputMask(int shape){ return shape == 0 ? 4 : 0; }

        @Override
        public void save(NBTTagCompound tag)
        {
            tag.setByte("in", (byte)rsIn);
            tag.setByte("out", (byte)rsOut);
            tag.setByte("in0", (byte)bIn);
            tag.setByte("out0", (byte)bOut);
        }

        @Override
        public void load(NBTTagCompound tag)
        {
            rsIn = tag.getByte("in");
            rsOut = tag.getByte("out");
            bIn = tag.getByte("in0");
            setBOut(tag.getByte("out0"));
        }

        @Override
        public void onChange(BundledGatePart gate)
        {
            boolean changed = false;

            int oldRSIn = rsIn;
            rsIn = gate.shape() == 0 ? gate.getRedstoneInput(2)/17 : 0;
            if (oldRSIn != rsIn) changed = true;

            int oldBIn = bIn;
            bIn = gate.shape() == 0 ? 0 : packDigital(gate.getBundledInput(0));
            if (oldBIn != bIn) changed = true;

            if (changed)
            {
                gate.onInputChange();
                gate.scheduleTick(2);
                sendClientUpdate();
            }
        }

        @Override
        public void scheduledTick(BundledGatePart gate)
        {
            int changeMask = 0;

            int oldBOut = bOut;
            setBOut(gate.shape() == 0 ? rsIn > 0 ? 1<<rsIn : 0 : 0);
            if (oldBOut != bOut) changeMask |= 1;

            int oldRSOut = rsOut;
            rsOut = gate.shape() == 0 ? 0 : mostSignificantBit(bIn);
            if (rsOut != oldRSOut) changeMask |= 4;

            int oldOut2 = gate.state()>>4;
            int newOut2 = (gate.shape() == 0 ? rsIn : bIn) != 0 ? 10 : 0;
            if (oldOut2 != newOut2)
            {
                gate.setState(gate.state()&0xF|newOut2<<4);
                changeMask |= 10;
            }

            if (changeMask != 0)
            {
                gate.onOutputChange(changeMask);
                sendClientUpdate();
            }
            onChange(gate);
        }

        @Override
        public int getOutput(BundledGatePart gate, int r)
        {
            return gate.shape() != 0 && r == 2 ? rsOut : (gate.state()&0x10<<r) != 0 ? 15 : 0;
        }

        @Override
        public byte[] getBundledOutput(BundledGatePart gate, int r)
        {
            return gate.shape() == 0 && r == 0 ? bOutUnpacked : null;
        }

        /**
         * Shape 0: Analog to Digital (RS to Bundled)
         * Shape 1: Digital to Analog (Bundled to RS)
         */
        @Override
        public boolean cycleShape(BundledGatePart gate)
        {
            gate.setShape(gate.shape()^1);
            return true;
        }

        @Override
        public int lightLevel()
        {
            return 0;
        }

        public int packClientData()
        {
            //bbbb BBBB rrrr RRRR
            //R - rsIn
            //r - rsOut
            //B - bundled in
            //b - bunbled out
            return rsIn|rsOut<<4|mostSignificantBit(bIn)<<8|mostSignificantBit(bOut)<<12;
        }

        public void unpackClientData(int data)
        {
            rsIn = data&0xF;
            rsOut = data>>4&0xF;
            bIn = 1<<(data>>8&0xF);
            setBOut(1<<(data>>12&0xF));
        }

        public void sendClientUpdate()
        {
            gate.getWriteStream(11).writeShort(packClientData());
        }

        @Override
        public void readDesc(MCDataInput packet)
        {
            unpackClientData(packet.readUShort());
        }

        @Override
        public void writeDesc(MCDataOutput packet)
        {
            packet.writeShort(packClientData());
        }

        @Override
        public void read(MCDataInput packet, int key)
        {
            if (key == 11) unpackClientData(packet.readUShort());
        }
    }

    public static class BusInputPanel extends BundledGateLogic
    {
        public static IndexedCuboid6[] unpressed;
        public static IndexedCuboid6[] pressed;

        static
        {
            unpressed = VecLib.buildCubeArray(4, 4, new Cuboid6(3, 1, 3, 13, 3, 13), new Vector3(-0.25, 0, -0.25));
            pressed = VecLib.buildCubeArray(4, 4, new Cuboid6(3, 1, 3, 13, 2.5, 13), new Vector3(-0.25, 0, -0.25));
        }

        public int pressMask = 0;

        public int bOut = 0;
        public byte[] bOutUnpack;

        public void setBOut(int newBOut)
        {
            if (bOut == newBOut) return;
            bOut = (short)newBOut;
            bOutUnpack = unpackDigital(bOutUnpack, bOut);
        }

        public BusInputPanel(BundledGatePart gate)
        {
            super(gate);
        }

        @Override
        public void addSubParts(BundledGatePart part, List<IndexedCuboid6> list)
        {
            for (int i = 0; i < 16; i++)
            {
                IndexedCuboid6[] array = (pressMask&1<<i) == 0 ? unpressed : pressed;
                list.add(new IndexedCuboid6(i, array[i].copy().apply(VecLib.orientT(part.orientation))));
            }
        }

        @Override
        public boolean activate(BundledGatePart part, EntityPlayer player, ItemStack held, MovingObjectPosition hit)
        {
            if (held != null && held.getItem() instanceof IScrewdriver) return false;
            ExtendedMOP hit1 = (ExtendedMOP)hit;
            int hitdata = ((Integer)hit1.data);
            if (hitdata != -1)
            {
                pressMask ^= (1<<hitdata);
                if (!part.world().isRemote) onChange(part);
                return true;
            }
            return false;
        }

        @Override
        public int bundledOutputMask(int shape)
        {
            return 4;
        }

        @Override
        public int bundledInputMask(int shape)
        {
            return 0;
        }

        @Override
        public int outputMask(int shape)
        {
            return 0;
        }

        @Override
        public int inputMask(int shape)
        {
            return 1;
        }

        @Override
        public void save(NBTTagCompound tag)
        {
            tag.setShort("press", (short)pressMask);
            tag.setShort("mask", (short)bOut);
        }

        @Override
        public void load(NBTTagCompound tag)
        {
            pressMask = tag.getShort("press");
            setBOut(tag.getShort("mask"));
        }

        @Override
        public void onChange(BundledGatePart gate)
        {
            boolean inputChanged = false;

            int oldInput = gate.state()&0xF;
            int newInput = getInput(gate, 1);
            if (oldInput != newInput)
            {
                gate.setState(gate.state()&0xF0|newInput);
                inputChanged = true;
            }

            if ((gate.state()&1) != 0) pressMask = 0;

            int oldBInput = bOut;
            int newBInput = pressMask;
            if (oldBInput != newBInput)
            {
                inputChanged = true;
            }

            if (inputChanged)
            {
                gate.onInputChange();
                gate.scheduleTick(2);
            }
        }

        @Override
        public void scheduledTick(BundledGatePart gate)
        {
            boolean outputChanged = false;

            int oldBOut = bOut;
            int newBOut = pressMask;
            if (oldBOut != newBOut)
            {
                setBOut(pressMask);
                outputChanged = true;
                sendClientUpdate();
            }

            if (outputChanged)
                gate.onOutputChange(bundledOutputMask(gate.shape()));

            onChange(gate);
        }

        @Override
        public int getOutput(BundledGatePart gate, int r)
        {
            return (gate.state()&0x10<<r) != 0 ? 15 : 0;
        }

        @Override
        public byte[] getBundledOutput(BundledGatePart gate, int r)
        {
            return bOutUnpack;
        }

        public void sendClientUpdate()
        {
            gate.getWriteStream(11).writeShort(pressMask);
        }

        @Override
        public void read(MCDataInput packet, int key)
        {
            if (key == 11) pressMask = packet.readUShort();
        }

        @Override
        public void readDesc(MCDataInput packet)
        {
            pressMask = packet.readUShort();
        }

        @Override
        public void writeDesc(MCDataOutput packet)
        {
            packet.writeShort(pressMask);
        }
    }
}
TOP

Related Classes of mrtjp.projectred.integration.BundledGateLogic$BusRandomizer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.