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