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;
                    }
                }
            }
        }
Example #2
0
 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;
 }
Example #3
0
        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);
        }
Example #4
0
        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());
        }
Example #5
0
        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));
 }