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); }
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); } }
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); }
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; }
/// <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) }); }
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); }
/// <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]); }