public static void AddConnectedBlock(ICSType cSType) { if (cSType.ConnectedBlock != null && !string.IsNullOrEmpty(cSType.ConnectedBlock.BlockType)) { cSType.ConnectedBlock.Connections.Sort(); BlockLookup[cSType.name] = cSType; if (!_connectedBlockLookup.ContainsKey(cSType.ConnectedBlock.BlockType)) { _connectedBlockLookup.Add(cSType.ConnectedBlock.BlockType, new Dictionary <List <BlockSide>, ICSType>(new ListComparer <BlockSide>())); } _connectedBlockLookup[cSType.ConnectedBlock.BlockType][cSType.ConnectedBlock.Connections] = cSType; if (cSType.ConnectedBlock.Connections.Count == 2 && ((cSType.ConnectedBlock.Connections.Contains(BlockSide.Xn) && cSType.ConnectedBlock.Connections.Contains(BlockSide.Xp)) || (cSType.ConnectedBlock.Connections.Contains(BlockSide.Yn) && cSType.ConnectedBlock.Connections.Contains(BlockSide.Yp)) || (cSType.ConnectedBlock.Connections.Contains(BlockSide.Zn) && cSType.ConnectedBlock.Connections.Contains(BlockSide.Zp)))) { foreach (var side in cSType.ConnectedBlock.Connections) { var newBlockList = new List <BlockSide>() { side }; _connectedBlockLookup[cSType.ConnectedBlock.BlockType][newBlockList] = cSType; } } } }
public TrainTransport(Vector3 position, AnimationManager.AnimatedObject animatedObject, ICSType trainType) { _meshedVehicleDescription = new MeshedVehicleDescription(new ClientMeshedObject(animatedObject.ObjType), trainType.TrainConfiguration.playerSeatOffset, trainType.TrainConfiguration.AllowPlayerToEditBlocksWhileRiding); _animatedObject = animatedObject; Position = position; TrainType = trainType; _trainId = ItemId.GetItemId(trainType.name); _idealHeightFromTrack = TrainType.TrainConfiguration.IdealHeightFromTrack; Delay = TrainType.TrainConfiguration.MoveTimePerBlockMs; ManaCostPerBlock = TrainType.TrainConfiguration.EnergyCostPerBlock; }
public static TrainTransport CreateTrain(ICSType cSType, Vector3 spawnPosition) { TrainTransport trainTransport = new TrainTransport(spawnPosition, TrainAnimations[cSType.name], cSType); TransportManager.RegisterTransport(trainTransport); if (!string.IsNullOrEmpty(cSType.ConnectedBlock?.BlockType)) { if (!TrainTransports.ContainsKey(cSType.ConnectedBlock.BlockType)) { TrainTransports.Add(cSType.ConnectedBlock.BlockType, new List <TrainTransport>()); } TrainTransports[cSType.ConnectedBlock.BlockType].Add(trainTransport); } return(trainTransport); }
public static List <ICSType> GetPermutations(ICSType baseBlock) { Dictionary <List <BlockSide>, ICSType> cSTypes = new Dictionary <List <BlockSide>, ICSType>(new ListComparer <BlockSide>()); if (baseBlock.ConnectedBlock != null && !string.IsNullOrWhiteSpace(baseBlock.ConnectedBlock.CalculationType) && baseBlock.ConnectedBlock.Connections != null && baseBlock.ConnectedBlock.Connections.Count > 0) { var itemJson = JsonConvert.SerializeObject(baseBlock, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore, Formatting = Formatting.None }); PermutateItems(baseBlock, cSTypes, itemJson, baseBlock.ConnectedBlock.Connections); } return(cSTypes.Values.ToList()); }
public TransportManager.ETransportUpdateResult Update() { if (_removed) { return(TransportManager.ETransportUpdateResult.Remove); } var currentPositionInt = new Pipliz.Vector3Int(Position); var heightFromTrack = _idealHeightFromTrack; if (TrackPosition == Pipliz.Vector3Int.zero) { for (int i = -1; i > _idealHeightFromTrack * -1; i--) { var trackPos = currentPositionInt.Add(0, i, 0); if (World.TryGetTypeAt(trackPos, out ItemTypes.ItemType possibleTrack) && ConnectedBlockSystem.BlockLookup.TryGetValue(possibleTrack.Name, out var track) && track.ConnectedBlock.CalculationType == _trackCalculationType.name && TrainType.ConnectedBlock.BlockType == track.ConnectedBlock.BlockType) { heightFromTrack = i * -1; TrackPosition = trackPos; break; } } } if (heightFromTrack != _idealHeightFromTrack) { Position = currentPositionInt.Add(0, heightFromTrack, 0).Vector; _meshedVehicleDescription.Object.SendMoveToInterpolated(Position, Quaternion.identity, (float)GetDelayMillisecondsToNextUpdate() / 1000f, _animatedObject.ObjSettings); } else if (TrackPosition != Pipliz.Vector3Int.zero) { bool moved = false; ICSType trainStation = null; if (_trainMoveTime < TimeCycle.TotalHours) { if (_minStopNextTime < TimeCycle.TotalHours) { foreach (var stationSide in _trackCalculationType.AvailableBlockSides) { var stationCheck = TrackPosition.GetBlockOffset(stationSide); if (World.TryGetTypeAt(stationCheck, out ItemTypes.ItemType possibleStation) && ItemCache.CSItems.TryGetValue(possibleStation.Name, out var station) && station.TrainStationSettings != null && station.TrainStationSettings.BlockType == TrainType.ConnectedBlock.BlockType) { trainStation = station; foreach (var kvp in RoamingJobManager.Objectives.Values) { if (kvp.TryGetValue(trainStation.TrainStationSettings.ObjectiveCategory, out var locDic) && locDic.TryGetValue(stationCheck, out var roamingJobState)) { var manaNeeded = RoamingJobState.GetActionsMaxEnergy(TrainType.TrainConfiguration.EnergyActionEnergyName, roamingJobState.Colony, TrainType.TrainConfiguration.RoamingJobCategory) - _energy; var existing = roamingJobState.GetActionEnergy(TrainType.TrainConfiguration.EnergyActionEnergyName); bool isWorked = true; try { if (roamingJobState.Colony.JobFinder.JobsData != null) { foreach (var job in roamingJobState.Colony.JobFinder.JobsData.OpenJobs) { try { if (job != null && job.GetJobLocation() == stationCheck) { isWorked = false; break; } } catch { } } } } catch (Exception ex) { if (roamingJobState.Colony.JobFinder == null) { APILogger.Log("roamingJobState.Colony.JobFinder == null"); } if (roamingJobState.Colony.JobFinder.JobsData == null) { APILogger.Log("roamingJobState.Colony.JobFinder.JobsData == null"); } if (roamingJobState.Colony.JobFinder.JobsData.OpenJobs == null) { APILogger.Log("roamingJobState.Colony.JobFinder.JobsData.OpenJobs == null"); } APILogger.LogError(ex); } if (!isWorked) { Indicator.SendIconIndicatorNear(stationCheck.Add(0, 1, 0).Vector, new IndicatorState(10, "npcicon", true, false)); } else if (existing > 0) { if (existing >= manaNeeded) { roamingJobState.SubtractFromActionEnergy(TrainType.TrainConfiguration.EnergyActionEnergyName, manaNeeded); _energy = RoamingJobState.GetActionsMaxEnergy(TrainType.TrainConfiguration.EnergyActionEnergyName, roamingJobState.Colony, TrainType.TrainConfiguration.RoamingJobCategory); roamingJobState.SubtractFromActionEnergy(TrainType.TrainConfiguration.DurabilityActionEnergyName, .01f); } else { roamingJobState.SubtractFromActionEnergy(TrainType.TrainConfiguration.EnergyActionEnergyName, existing); _energy += existing; roamingJobState.SubtractFromActionEnergy(TrainType.TrainConfiguration.DurabilityActionEnergyName, .01f); } Indicator.SendIconIndicatorNear(stationCheck.Add(0, 1, 0).Vector, new IndicatorState(10, TrainType.TrainConfiguration.EnergyType)); _minStopNextTime = TimeCycle.TotalHours + 2; _trainMoveTime = TimeCycle.TotalHours + 1; existing = roamingJobState.GetActionEnergy(TrainType.TrainConfiguration.EnergyActionEnergyName); } else { Indicator.SendIconIndicatorNear(stationCheck.Add(0, 1, 0).Vector, new IndicatorState(10, TrainType.TrainConfiguration.EnergyType, true, false)); } break; } } } } } if (trainStation == null && _energy > 0) { foreach (var side in _trackCalculationType.AvailableBlockSides) { var searchSide = TrackPosition.GetBlockOffset(side); var proposePos = currentPositionInt.GetBlockOffset(side).Vector; if (World.TryGetTypeAt(searchSide, out ItemTypes.ItemType possibleTrack) && ConnectedBlockSystem.BlockLookup.TryGetValue(possibleTrack.Name, out var track) && track.ConnectedBlock.CalculationType == _trackCalculationType.name && TrainType.ConnectedBlock.BlockType == track.ConnectedBlock.BlockType && proposePos != _prevPosition) { _prevPosition = Position; TrackPosition = searchSide; Position = currentPositionInt.GetBlockOffset(side).Vector; _meshedVehicleDescription.Object.SendMoveToInterpolated(Position, Quaternion.identity, (float)GetDelayMillisecondsToNextUpdate() / 1000f, _animatedObject.ObjSettings); _energy -= ManaCostPerBlock; if (_energy < 0) { _energy = 0; } ChunkQueue.QueueBannerBox(TrackPosition.Add(-30, -30, -30).ToChunk(), TrackPosition.Add(30, 30, 30).ToChunk()); moved = true; break; } } } } if (!moved) { _meshedVehicleDescription.Object.SendMoveToInterpolated(Position, Quaternion.identity, (float)GetDelayMillisecondsToNextUpdate() / 1000f, _animatedObject.ObjSettings); } if (!moved && _energy > 0) { _prevPosition = Vector3.zero; } if (!moved && _energy <= 0) { _trainMoveTime = 0; Indicator.SendIconIndicatorNear(new Pipliz.Vector3Int(Position).Add(0, 2, 0).Vector, new IndicatorState((float)GetDelayMillisecondsToNextUpdate() / 1000f, TrainType.TrainConfiguration.EnergyType, true, false)); } } return(TransportManager.ETransportUpdateResult.KeepUpdating); }
public static bool TryGetConnectingBlock(string blockType, List <BlockSide> neededSides, out ICSType connectedBlock) { connectedBlock = null; if (_connectedBlockLookup.ContainsKey(blockType)) { if (!_connectedBlockLookup[blockType].TryGetValue(neededSides, out connectedBlock)) { IEnumerable <KeyValuePair <List <BlockSide>, ICSType> > lookup = _connectedBlockLookup[blockType]; if (neededSides.Contains(BlockSide.XpYp) || neededSides.Contains(BlockSide.XnYp) || neededSides.Contains(BlockSide.ZpYp) || neededSides.Contains(BlockSide.ZnYp)) { lookup = lookup.Reverse(); } foreach (var kvp in lookup) { if (_blockSideComparer.Equals(kvp.Key, neededSides)) { connectedBlock = kvp.Value; break; } } } return(connectedBlock != null); } return(false); }
public static bool TryGetChangedBlockTypeAtPosition(Vector3Int centerBlock, string blockType, IConnectedBlockCalculationType calculationType, out ICSType newBlock) { List <BlockSide> connectedBlocks = GetConnectedBlocks(centerBlock, blockType, calculationType); return(TryGetConnectingBlock(blockType, connectedBlocks, out newBlock)); }
private static void PermutateItems(ICSType baseBlock, Dictionary <List <BlockSide>, ICSType> cSTypes, string itemJson, List <BlockSide> connections, IConnectedBlockCalculationType connectedBlockCalculationType) { foreach (RotationAxis axis in connectedBlockCalculationType.AxisRotations) { foreach (BlockRotationDegrees rotationDegrees in _blockRotationDegrees) { var rotationEuler = new SerializableVector3(); var rotatedList = new List <BlockSide>(); var currentRotation = rotationDegrees; if (baseBlock.meshRotationEuler != null) { rotationEuler.x = baseBlock.meshRotationEuler.x; rotationEuler.y = baseBlock.meshRotationEuler.y; rotationEuler.z = baseBlock.meshRotationEuler.z; } switch (axis) { case RotationAxis.X: rotationEuler.x += (int)rotationDegrees; if (rotationEuler.x > (int)BlockRotationDegrees.TwoSeventy) { rotationEuler.x -= 360; } currentRotation = (BlockRotationDegrees)rotationEuler.x; break; case RotationAxis.Y: rotationEuler.y += (int)rotationDegrees; if (rotationEuler.y > (int)BlockRotationDegrees.TwoSeventy) { rotationEuler.y -= 360; } currentRotation = (BlockRotationDegrees)rotationEuler.x; break; case RotationAxis.Z: rotationEuler.z += (int)rotationDegrees; if (rotationEuler.z > (int)BlockRotationDegrees.TwoSeventy) { rotationEuler.z -= 360; } currentRotation = (BlockRotationDegrees)rotationEuler.x; break; } if (connections.Count() == connections.Distinct().Count()) { foreach (var side in connections) { Vector3 connectionPoint = side.GetVector(); Vector3 eulerRotation = new Vector3(rotationEuler.x, rotationEuler.y, rotationEuler.z); Vector3 rotatedConnectionPoint = Quaternion.Euler(eulerRotation) * connectionPoint; if (rotatedConnectionPoint == Vector3.zero) { rotatedConnectionPoint = connectionPoint; } rotatedList.Add(rotatedConnectionPoint.GetBlocksideFromVector()); } } rotatedList.Sort(); if (rotatedList.Count != 0 && !rotatedList.Contains(BlockSide.Invalid) && rotatedList.Count == rotatedList.Distinct().Count() && !cSTypes.ContainsKey(rotatedList) && !rotatedList.All(r => r == rotatedList.First())) { bool hasCalculationTypes = rotatedList.Count <= connectedBlockCalculationType.MaxConnections; foreach (var side in rotatedList) { if (!connectedBlockCalculationType.AvailableBlockSides.Contains(side)) { hasCalculationTypes = false; } } var newItem = JsonConvert.DeserializeObject <CSType>(itemJson); newItem.meshRotationEuler = rotationEuler; newItem.ConnectedBlock = new ConnectedBlock() { BlockType = baseBlock.ConnectedBlock.BlockType, CalculationType = baseBlock.ConnectedBlock.CalculationType, Connections = rotatedList, BlockRotationDegrees = currentRotation, RotationAxis = axis }; newItem.categories = null; newItem.name = string.Concat(newItem.name, ".", GetItemName(newItem.ConnectedBlock.Connections)); if (hasCalculationTypes) { cSTypes[newItem.ConnectedBlock.Connections] = newItem; } PermutateItems(newItem, cSTypes, itemJson, connections, connectedBlockCalculationType); } } } }
public static bool TryGetConnectingBlock(string blockType, List <BlockSide> neededSides, out ICSType connectedBlock) { connectedBlock = null; return(_connectedBlockLookup.ContainsKey(blockType) && _connectedBlockLookup[blockType].TryGetValue(neededSides, out connectedBlock)); }