public void CheckEngaged(IBlockAccessor access, bool updateNetwork)
        {
            BlockFacing side          = orients[0] == BlockFacing.NORTH ? BlockFacing.EAST : BlockFacing.NORTH;
            bool        clutchEngaged = false;
            BEClutch    bec           = access.GetBlockEntity(Position.AddCopy(side)) as BEClutch;

            if (bec?.Facing == side.Opposite)
            {
                clutchEngaged = bec.Engaged;
            }
            if (!clutchEngaged)
            {
                bec = access.GetBlockEntity(Position.AddCopy(side.Opposite)) as BEClutch;
                if (bec?.Facing == side)
                {
                    clutchEngaged = bec.Engaged;
                }
            }
            if (clutchEngaged != this.engaged)
            {
                this.engaged = clutchEngaged;
                if (updateNetwork)
                {
                    this.ChangeState(clutchEngaged);
                }
            }
        }
Exemple #2
0
        public override void Initialize(ICoreAPI api, JsonObject properties)
        {
            base.Initialize(api, properties);

            if (api.Side == EnumAppSide.Client)
            {
                capi = api as ICoreClientAPI;
            }

            orientations = Block.Variant["orientation"];
            switch (orientations)
            {
            case "ns":
                AxisSign   = new int[] { 0, 0, -1 };
                orients[0] = BlockFacing.NORTH;
                orients[1] = BlockFacing.SOUTH;

                sides[0] = Position.AddCopy(BlockFacing.WEST);
                sides[1] = Position.AddCopy(BlockFacing.EAST);
                break;

            case "we":
                AxisSign   = new int[] { -1, 0, 0 };
                orients[0] = BlockFacing.WEST;
                orients[1] = BlockFacing.EAST;

                sides[0] = Position.AddCopy(BlockFacing.NORTH);
                sides[1] = Position.AddCopy(BlockFacing.SOUTH);
                break;
            }
        }
Exemple #3
0
        public bool tryConnect(BlockFacing toFacing)
        {
            MechanicalNetwork newNetwork;

            BlockPos pos = Position.AddCopy(toFacing);
            IMechanicalPowerBlock connectedToBlock = Api.World.BlockAccessor.GetBlock(pos) as IMechanicalPowerBlock;

            if (DEBUG)
            {
                Api.Logger.Notification("tryConnect at " + this.Position + " towards " + toFacing + " " + pos);
            }

            if (connectedToBlock == null || !connectedToBlock.HasMechPowerConnectorAt(Api.World, pos, toFacing.Opposite))
            {
                return(false);
            }
            newNetwork = connectedToBlock.GetNetwork(Api.World, pos);
            if (newNetwork != null)
            {
                IMechanicalPowerDevice node = Api.World.BlockAccessor.GetBlockEntity(pos).GetBehavior <BEBehaviorMPBase>() as IMechanicalPowerDevice;

                connectedToBlock.DidConnectAt(Api.World, pos, toFacing.Opposite);  //do this first to set the new Angled Gear block correctly prior to getting propagation direction
                BlockFacing   newTurnDir = node.GetPropagationDirectionInput();
                MechPowerPath curPath    = new MechPowerPath(toFacing, node.GetGearedRatio(toFacing), pos, !node.IsPropagationDirection(Position, toFacing));
                SetPropagationDirection(curPath);
                MechPowerPath[] paths = GetMechPowerExits(curPath);
                JoinNetwork(newNetwork);

                for (int i = 0; i < paths.Length; i++)
                {
                    //if (paths[i].OutFacing == toFacing) continue;
                    if (DEBUG)
                    {
                        Api.Logger.Notification("== spreading path " + (paths[i].invert ? "-" : "") + paths[i].OutFacing + "  " + paths[i].gearingRatio);
                    }
                    BlockPos exitPos = Position.AddCopy(paths[i].OutFacing);

                    bool chunkLoaded = spreadTo(Api, newNetwork, exitPos, paths[i], out _);
                    if (!chunkLoaded)
                    {
                        LeaveNetwork();
                        return(true);
                    }
                }

                return(true);
            }
            else if (this.network != null)
            {
                BEBehaviorMPBase node = Api.World.BlockAccessor.GetBlockEntity(pos)?.GetBehavior <BEBehaviorMPBase>();
                if (node != null)
                {
                    return(node.tryConnect(toFacing.Opposite));
                }
            }

            return(false);
        }
        internal float RotationNeighbour(int side, bool allowIndirect)
        {
            BlockPos pos = Position.AddCopy(orients[side]);
            IMechanicalPowerBlock block = Api.World.BlockAccessor.GetBlock(pos) as IMechanicalPowerBlock;

            if (block?.HasMechPowerConnectorAt(Api.World, pos, orients[side].Opposite) != true)
            {
                block = null;
            }
            BlockEntity            be   = block == null ? null : Api.World.BlockAccessor.GetBlockEntity(pos);
            IMechanicalPowerDevice node = be?.GetBehavior <BEBehaviorMPBase>() as IMechanicalPowerDevice;

            if (node is BEBehaviorMPTransmission trans && !trans.engaged)
            {
                node = null;
            }
            float rot;

            if (node == null || node.Network == null)
            {
                if (this.engaged && allowIndirect)
                {
                    rot           = this.RotationNeighbour(1 - side, false);
                    rotPrev[side] = rot;
                }
                else
                {
                    rot = rotPrev[side];
                }
            }
            else
            {
                rot = node.Network.AngleRad * node.GearedRatio;
                bool invert = node.GetPropagationDirection() != orients[side];
                if (side == 1)
                {
                    invert = !invert;
                }
                if (invert)
                {
                    rot = GameMath.TWOPI - rot;
                }
                rotPrev[side] = rot;
            }
            return(rot);
        }
        protected override MechPowerPath[] GetMechPowerExits(MechPowerPath pathDir)
        {
            BlockFacing   face  = pathDir.OutFacing;
            BELargeGear3m beg   = Blockentity as BELargeGear3m;
            int           index = 0;

            if (face == BlockFacing.UP || face == BlockFacing.DOWN)
            {
                MechPowerPath[] paths = new MechPowerPath[2 + beg.CountGears(Api)];
                paths[index]   = pathDir;
                paths[++index] = new MechPowerPath(pathDir.OutFacing.Opposite, pathDir.gearingRatio, null, !pathDir.invert);
                bool sideInvert = face == BlockFacing.DOWN ^ pathDir.invert;
                for (int i = 0; i < 4; i++)
                {
                    BlockFacing horizFace = BlockFacing.HORIZONTALS[i];
                    if (beg.HasGearAt(Api, Position.AddCopy(horizFace)))
                    {
                        paths[++index] = new MechPowerPath(horizFace, pathDir.gearingRatio * ratio, null, sideInvert);                                                   //invert all horizontal output paths
                    }
                }
                return(paths);
            }

            MechPowerPath[] pathss = new MechPowerPath[2 + beg.CountGears(Api)];
            bool            invert = pathDir.IsInvertedTowards(Position);

            pathss[0] = new MechPowerPath(BlockFacing.DOWN, pathDir.gearingRatio / ratio, null, invert);
            pathss[1] = new MechPowerPath(BlockFacing.UP, pathDir.gearingRatio / ratio, null, !invert);
            index     = 1;
            bool sidesInvert = face == BlockFacing.DOWN ^ !invert;  //invert power in the opposite sense if power fed in from one of the sides instead of through up/down axle

            for (int i = 0; i < 4; i++)
            {
                BlockFacing horizFace = BlockFacing.HORIZONTALS[i];
                if (beg.HasGearAt(Api, Position.AddCopy(horizFace)))
                {
                    pathss[++index] = new MechPowerPath(horizFace, pathDir.gearingRatio, null, sidesInvert);                                                   //horizontals match the gearing ratio of the input horizontal
                }
            }
            return(pathss);
        }
Exemple #6
0
        protected override MechPowerPath[] GetMechPowerExits(MechPowerPath pathDir)
        {
            BlockFacing   face  = pathDir.OutFacing;
            BELargeGear3m beg   = Blockentity as BELargeGear3m;
            int           index = 0;

            if (face == BlockFacing.UP || face == BlockFacing.DOWN)
            {
                MechPowerPath[] paths = new MechPowerPath[2 + beg.CountGears(Api)];
                paths[index]   = pathDir;
                paths[++index] = new MechPowerPath(pathDir.OutFacing.Opposite, pathDir.gearingRatio, null, !pathDir.invert);
                for (int i = 0; i < 4; i++)
                {
                    BlockFacing horizFace = BlockFacing.HORIZONTALS[i];
                    if (beg.HasGearAt(Api, Position.AddCopy(horizFace)))
                    {
                        paths[++index] = new MechPowerPath(horizFace, pathDir.gearingRatio * ratio, null, face == BlockFacing.DOWN ^ pathDir.invert);                                                   //invert all horizontal output paths
                    }
                }
                return(paths);
            }

            MechPowerPath[] pathss = new MechPowerPath[2 + beg.CountGears(Api)];
            bool            invert = pathDir.IsInvertedTowards(Position);

            pathss[0] = new MechPowerPath(BlockFacing.DOWN, pathDir.gearingRatio / ratio, null, invert);
            pathss[1] = new MechPowerPath(BlockFacing.UP, pathDir.gearingRatio / ratio, null, !invert);
            index     = 1;
            for (int i = 0; i < 4; i++)
            {
                BlockFacing horizFace = BlockFacing.HORIZONTALS[i];
                if (beg.HasGearAt(Api, Position.AddCopy(horizFace)))
                {
                    pathss[++index] = new MechPowerPath(horizFace, pathDir.gearingRatio, null, (face.Opposite == horizFace || face == BlockFacing.DOWN) ^ !invert);                                                   //horizontals match the gearing ratio of the input horizontal; invert unless its the input side
                }
            }
            return(pathss);
        }
Exemple #7
0
        /// <summary>
        /// Network propagation has a power path direction (for the network discovery process) and normally power transmission will be in the same sense, but it may be inverted (e.g. if a block is inserted in a way which joins two existing networks)
        /// </summary>
        public virtual bool JoinAndSpreadNetworkToNeighbours(ICoreAPI api, MechanicalNetwork network, MechPowerPath exitTurnDir, out Vec3i missingChunkPos)
        {
            missingChunkPos = null;
            if (this.network?.networkId == network?.networkId)
            {
                return(true);                                               // Already got the message
            }
            if (DEBUG)
            {
                api.Logger.Notification("Spread to " + this.Position + " with direction " + exitTurnDir.OutFacing + (exitTurnDir.invert ? "-" : "") + " Network:" + network.networkId);
            }
            SetPropagationDirection(exitTurnDir);

            JoinNetwork(network);
            (Block as IMechanicalPowerBlock).DidConnectAt(api.World, Position, exitTurnDir.OutFacing.Opposite);

            MechPowerPath[] paths = GetMechPowerExits(exitTurnDir);
            for (int i = 0; i < paths.Length; i++)
            {
                //if (paths[i].OutFacing == exitTurnDir.OutFacing.GetOpposite()) continue;   //currently commented out to force testing of path in both directions, though usually (maybe always) the OutFacing.getOpposite() sense will return quickly - anyhow, it seems to work with this commented out
                if (DEBUG)
                {
                    api.Logger.Notification("-- spreading path " + (paths[i].invert ? "-" : "") + paths[i].OutFacing + "  " + paths[i].gearingRatio);
                }
                BlockPos exitPos     = Position.AddCopy(paths[i].OutFacing);
                bool     chunkLoaded = spreadTo(api, network, exitPos, paths[i], out missingChunkPos);

                if (!chunkLoaded)
                {
                    //LeaveNetwork();    //we don't want to set the network to null here, as then there would be nowhere to store the missingChunkPos
                    return(false);
                }
            }

            return(true);
        }
Exemple #8
0
        public virtual MechanicalNetwork CreateJoinAndDiscoverNetwork(BlockFacing powerOutFacing)
        {
            BlockPos neibPos = Position.AddCopy(powerOutFacing);
            IMechanicalPowerBlock neibMechBlock = null;

            neibMechBlock = Api.World.BlockAccessor.GetBlock(neibPos) as IMechanicalPowerBlock;

            MechanicalNetwork neibNetwork = neibMechBlock == null ? null : neibMechBlock.GetNetwork(Api.World, neibPos);

            if (neibNetwork == null || !neibNetwork.Valid)
            {
                MechanicalNetwork newNetwork = this.network;
                if (newNetwork == null)
                {
                    newNetwork = manager.CreateNetwork(this);
                    JoinNetwork(newNetwork);
                    if (DEBUG)
                    {
                        Api.Logger.Notification("===setting inturn at " + Position + " " + powerOutFacing);
                    }
                    SetPropagationDirection(new MechPowerPath(powerOutFacing, 1));
                }

                Vec3i missingChunkPos;
                bool  chunksLoaded = spreadTo(Api, newNetwork, neibPos, new MechPowerPath(GetPropagationDirection(), this.gearedRatio), out missingChunkPos);
                if (network == null)
                {
                    if (DEBUG)
                    {
                        Api.Logger.Notification("Incomplete chunkloading, possible issues with mechanical network around block " + neibPos);
                    }
                    return(null);
                }

                if (!chunksLoaded)
                {
                    network.AwaitChunkThenDiscover(missingChunkPos);
                    manager.testFullyLoaded(network); // To trigger that allFullyLoaded gets false
                    return(network);
                }
                else
                {
                    IMechanicalPowerDevice node = Api.World.BlockAccessor.GetBlockEntity(neibPos)?.GetBehavior <BEBehaviorMPBase>() as IMechanicalPowerDevice;
                    if (node != null)
                    {
                        BlockFacing facing = node.GetPropagationDirectionInput();
                        SetPropagationDirection(new MechPowerPath(facing, node.GetGearedRatio(facing), neibPos));
                    }
                }
            }
            else
            {
                BEBehaviorMPBase neib = Api.World.BlockAccessor.GetBlockEntity(neibPos).GetBehavior <BEBehaviorMPBase>();
                if (OutFacingForNetworkDiscovery != null)
                {
                    if (tryConnect(OutFacingForNetworkDiscovery))
                    {
                        this.gearedRatio = neib.GetGearedRatio(OutFacingForNetworkDiscovery);  //no need to set propagationDir, it's already been set by tryConnect
                    }
                }
                else
                {
                    JoinNetwork(neibNetwork);
                    SetPropagationDirection(new MechPowerPath(neib.propagationDir, neib.GetGearedRatio(neib.propagationDir), neibPos));
                }
            }

            return(network);
        }
Exemple #9
0
    private void CheckWater(float dt)
    {
        willSpeed = 0;
        BlockPos block1pos = Position.AddCopy(face.GetCCW()).AddCopy(face.GetCCW());
        Block    block1    = Api.World.BlockAccessor.GetBlock(block1pos);
        Block    block2    = Api.World.BlockAccessor.GetBlock(block1pos.AddCopy(BlockFacing.DOWN));
        Block    block3    = Api.World.BlockAccessor.GetBlock(block1pos.AddCopy(BlockFacing.UP));

        if (block1.Code.BeginsWith("game", "water-d"))
        {
            willSpeed++;
        }
        if (block2.Code.BeginsWith("game", "water-d"))
        {
            willSpeed++;
        }
        if (block3.Code.BeginsWith("game", "water-d"))
        {
            willSpeed++;
        }
        BlockPos block2pos = Position.AddCopy(face.GetCW()).AddCopy(face.GetCW());
        Block    block21   = Api.World.BlockAccessor.GetBlock(block2pos);
        Block    block22   = Api.World.BlockAccessor.GetBlock(block2pos.AddCopy(BlockFacing.DOWN));
        Block    block23   = Api.World.BlockAccessor.GetBlock(block2pos.AddCopy(BlockFacing.UP));

        if (block21.Code.BeginsWith("game", "water-d"))
        {
            willSpeed--;
        }
        if (block22.Code.BeginsWith("game", "water-d"))
        {
            willSpeed--;
        }
        if (block23.Code.BeginsWith("game", "water-d"))
        {
            willSpeed--;
        }
        BlockPos block4pos  = Position.AddCopy(BlockFacing.DOWN).AddCopy(BlockFacing.DOWN);
        Block    block4     = Api.World.BlockAccessor.GetBlock(block4pos);
        Block    block5     = Api.World.BlockAccessor.GetBlock(block4pos.AddCopy(face.GetCCW()));
        Block    block6     = Api.World.BlockAccessor.GetBlock(block4pos.AddCopy(face.GetCW()));
        string   waterpath  = "water-" + face.GetCW().Code[0];
        string   waterpath2 = "water-" + face.GetCCW().Code[0];

        if (block4.Code.BeginsWith("game", waterpath))
        {
            willSpeed++;
        }
        else if (block4.Code.BeginsWith("game", waterpath2))
        {
            willSpeed--;
        }
        if (block5.Code.BeginsWith("game", waterpath))
        {
            willSpeed++;
        }
        else if (block5.Code.BeginsWith("game", waterpath2))
        {
            willSpeed--;
        }
        if (block6.Code.BeginsWith("game", waterpath))
        {
            willSpeed++;
        }
        else if (block6.Code.BeginsWith("game", waterpath2))
        {
            willSpeed--;
        }
        if (willSpeed < 0)
        {
            willSpeed = Math.Abs(willSpeed);
            //SetPropagationDirection(new MechPowerPath(face.Opposite, 1 /*GearedRatio*/, null, true));
            propagationDir = OutFacingForNetworkDiscovery.Opposite;
        }
        else
        {
            //SetPropagationDirection(new MechPowerPath(face.Opposite, 1 /*GearedRatio*/, null, false));
            propagationDir = OutFacingForNetworkDiscovery;
        }
    }