public override void SetPropagationDirection(MechPowerPath path)
        {
            BlockFacing turnDir = path.NetworkDir();

            if (this.turnDir1 != null)
            //rotate the input turn direction if it's an angled gear   (this helps later blocks to know which sense the network is turning)
            {
                if (turnDir == turnDir1)
                {
                    turnDir = turnDir2.Opposite;
                }
                else if (turnDir == turnDir2)
                {
                    turnDir = turnDir1.Opposite;
                }
                else if (turnDir == turnDir2.Opposite)
                {
                    turnDir = turnDir1;
                }
                else if (turnDir == turnDir1.Opposite)
                {
                    turnDir = turnDir2;
                }
                path = new MechPowerPath(turnDir, path.gearingRatio, null, false);
            }
            base.SetPropagationDirection(path);
        }
Example #2
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);
        }
        protected override MechPowerPath[] GetMechPowerExits(MechPowerPath fromExitTurnDir)
        {
            if (!engaged)
            {
                return(new MechPowerPath[0]);
            }

            return(base.GetMechPowerExits(fromExitTurnDir));
        }
        protected override MechPowerPath[] GetMechPowerExits(MechPowerPath fromExitTurnDir)
        {
            // This method could be called from another (earlier in the loading chunk) block's Initialise() method, i.e. before this itself is initialised.
            if (this.orientation == null)
            {
                this.SetOrientations();
            }

            string orientations = (Block as BlockAngledGears).Orientation;

            if (orientations.Length < 2 || orientations[0] != orientations[1])
            {
                bool          invert     = fromExitTurnDir.invert;
                BlockFacing[] connectors = (Block as BlockAngledGears).Facings;
                BlockFacing   inputSide  = fromExitTurnDir.OutFacing;
                if (!connectors.Contains(inputSide))
                {
                    inputSide = inputSide.Opposite;
                    invert    = !invert;
                }

                // The code for removing the inputSide from the MechPowerExits is unwanted for a newly placed AngledGears block - it needs to seek networks on both faces if newly placed
                if (!newlyPlaced)
                {
                    connectors = connectors.Remove(inputSide);
                }
                MechPowerPath[] paths = new MechPowerPath[connectors.Length];
                for (int i = 0; i < paths.Length; i++)
                {
                    BlockFacing pathFacing = connectors[i];

                    // An angled gear's output side rotates in the opposite sense from the input side
                    paths[i] = new MechPowerPath(pathFacing, this.GearedRatio, null, pathFacing == inputSide ? invert : !invert);
                }
                return(paths);
            }
            else
            {
                // Alternative code for a small gear connected to a Large Gear - essentially pass through
                MechPowerPath[] paths = new MechPowerPath[2];
                paths[0] = new MechPowerPath(this.orientation.Opposite, this.GearedRatio, null, this.orientation == fromExitTurnDir.OutFacing ? !fromExitTurnDir.invert : fromExitTurnDir.invert);
                paths[1] = new MechPowerPath(this.orientation, this.GearedRatio, null, this.orientation == fromExitTurnDir.OutFacing ? fromExitTurnDir.invert : !fromExitTurnDir.invert);
                return(paths);
            }
        }
Example #5
0
        public virtual void SetPropagationDirection(MechPowerPath path)
        {
            BlockFacing turnDir = path.NetworkDir();

            if (this.propagationDir == turnDir.Opposite && this.network != null)
            {
                if (!network.DirectionHasReversed)
                {
                    network.TurnDir = network.TurnDir == EnumRotDirection.Clockwise ? EnumRotDirection.Counterclockwise : EnumRotDirection.Clockwise;
                }
                network.DirectionHasReversed = true;
            }
            this.propagationDir = turnDir;
            this.GearedRatio    = path.gearingRatio;
            if (DEBUG)
            {
                Api.Logger.Notification("setting dir " + this.propagationDir + " " + this.Position);
            }
        }
 protected override MechPowerPath[] GetMechPowerExits(MechPowerPath fromExitTurnDir)
 {
     if (this.orientation == null)
     {
         this.SetOrientations();                            //this method could be called from another (earlier in the loading chunk) block's Initialise() method, i.e. before this itself is initialised.
     }
     if (largeGear == null)
     {
         if (newlyPlaced)
         {
             fromExitTurnDir.invert = !fromExitTurnDir.invert;
         }
         BlockFacing[] connectors       = (Block as BlockAngledGears).Facings;
         BlockFacing   inputSide        = fromExitTurnDir.invert ? fromExitTurnDir.OutFacing : fromExitTurnDir.OutFacing.Opposite;
         bool          inputSideMatches = connectors.Contains(inputSide);
         if (!newlyPlaced)   //the code for removing the inputSide from the MechPowerExits is unwanted for a newly placed AngledGears block - it needs to seek networks on both faces if newly placed
         {
             if (inputSideMatches)
             {
                 connectors = connectors.Remove(inputSide);
             }
             else
             {
                 connectors = connectors.Remove(fromExitTurnDir.OutFacing);
             }
         }
         MechPowerPath[] paths = new MechPowerPath[connectors.Length];
         for (int i = 0; i < paths.Length; i++)
         {
             BlockFacing pathFacing = connectors[i];
             paths[i] = new MechPowerPath(pathFacing, this.GearedRatio, null, connectors.Length < 2 && fromExitTurnDir.OutFacing == pathFacing.Opposite || inputSideMatches && pathFacing != inputSide || !inputSideMatches && pathFacing != inputSide.Opposite ? fromExitTurnDir.invert : !fromExitTurnDir.invert);
         }
         return(paths);
     }
     else
     {
         //alternative code for a small gear connected to a Large Gear - essentially pass through
         MechPowerPath[] paths = new MechPowerPath[2];
         paths[0] = new MechPowerPath(this.orientation.Opposite, this.GearedRatio, null, this.orientation == fromExitTurnDir.OutFacing ? !fromExitTurnDir.invert : fromExitTurnDir.invert);
         paths[1] = new MechPowerPath(this.orientation, this.GearedRatio, null, this.orientation == fromExitTurnDir.OutFacing ? fromExitTurnDir.invert : !fromExitTurnDir.invert);
         return(paths);
     }
 }
        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);
        }
Example #8
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);
        }
        public override void SetPropagationDirection(MechPowerPath path)
        {
            BlockFacing turnDir = path.NetworkDir();

            if (turnDir != BlockFacing.UP && turnDir != BlockFacing.DOWN)
            {
                turnDir          = path.IsInvertedTowards(Position) ? BlockFacing.UP : BlockFacing.DOWN; //network coming in (clockwise) from any of the 4 sides should then propagate (clockwise) in the down direction
                this.GearedRatio = path.gearingRatio / ratio;
            }
            else
            {
                this.GearedRatio = path.gearingRatio;
            }
            if (this.propagationDir == turnDir.Opposite && this.network != null)
            {
                if (!network.DirectionHasReversed)
                {
                    network.TurnDir = network.TurnDir == EnumRotDirection.Clockwise ? EnumRotDirection.Counterclockwise : EnumRotDirection.Clockwise;
                }
                network.DirectionHasReversed = true;
            }
            this.propagationDir = turnDir;
        }
Example #10
0
 /// <summary>
 /// Must return the path mechanical power takes, assuming block is aligned so that the given entry direction is a valid path, and preserve inverted state
 /// </summary>
 /// <param name="entryDir"></param>
 /// <returns></returns>
 protected virtual MechPowerPath[] GetMechPowerExits(MechPowerPath entryDir)
 {
     // Most blocks - like axles - have two power exits in opposite directions
     return(new MechPowerPath[] { entryDir, new MechPowerPath(entryDir.OutFacing.Opposite, entryDir.gearingRatio, Position, !entryDir.invert) });
 }
Example #11
0
        protected virtual bool spreadTo(ICoreAPI api, MechanicalNetwork network, BlockPos exitPos, MechPowerPath propagatePath, out Vec3i missingChunkPos)
        {
            missingChunkPos = null;
            BEBehaviorMPBase      beMechBase = api.World.BlockAccessor.GetBlockEntity(exitPos)?.GetBehavior <BEBehaviorMPBase>();
            IMechanicalPowerBlock mechBlock  = beMechBase?.Block as IMechanicalPowerBlock;

            if (DEBUG)
            {
                api.Logger.Notification("attempting spread to " + exitPos + (beMechBase == null ? " -" : ""));
            }

            if (beMechBase == null && api.World.BlockAccessor.GetChunkAtBlockPos(exitPos) == null)
            {
                if (OutsideMap(api.World.BlockAccessor, exitPos))
                {
                    return(true);                                               //Network discovery should not fail if there cannot be a block in this position
                }
                missingChunkPos = new Vec3i(exitPos.X / api.World.BlockAccessor.ChunkSize, exitPos.Y / api.World.BlockAccessor.ChunkSize, exitPos.Z / api.World.BlockAccessor.ChunkSize);
                return(false);
            }

            if (beMechBase != null && mechBlock.HasMechPowerConnectorAt(api.World, exitPos, propagatePath.OutFacing.Opposite))
            {
                beMechBase.Api = api;
                if (!beMechBase.JoinAndSpreadNetworkToNeighbours(api, network, propagatePath, out missingChunkPos))
                {
                    return(false);
                }
            }
            else if (DEBUG)
            {
                api.Logger.Notification("no connector at " + exitPos + " " + propagatePath.OutFacing.Opposite);
            }

            return(true);
        }
Example #12
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);
        }
 protected override MechPowerPath[] GetMechPowerExits(MechPowerPath fromExitTurnDir)
 {
     return(new MechPowerPath[0]);
 }
 protected override MechPowerPath[] GetMechPowerExits(MechPowerPath fromExitTurnDir)
 {
     // This but' a dead end, baby!
     return(new MechPowerPath[0]);
 }