public static void FillGhost(ConstructionArea area, IIterationType iteration)
        {
            ItemType ghostBlock = ItemTypes.GetType("ghost");

            int num1 = 4096;

            while (num1-- > 0)
            {
                Vector3Int currentPosition = iteration.CurrentPosition;
                ushort     val;
                if (World.TryGetTypeAt(currentPosition, out val))
                {
                    if (val == (ushort)0 || (int)val == (int)BuiltinBlocks.Indices.water)
                    {
                        SendGhostBlock(area.Owner, currentPosition, ghostBlock);
                    }
                }
                iteration.MoveNext();
            }
        }
Пример #2
0
        public void DoJob(IIterationType iterationType, IAreaJob areaJob, ConstructionJob job, ref NPC.NPCBase.NPCState state)
        {
            if (iterationType == null || buildType == null || buildType.ItemIndex == 0)
            {
                AreaJobTracker.RemoveJob(areaJob);
                return;
            }

            int iMax = 4096;

            while (iMax-- > 0)
            {
                Vector3Int jobPosition = iterationType.CurrentPosition;

                ushort foundTypeIndex;
                if (World.TryGetTypeAt(jobPosition, out foundTypeIndex))
                {
                    if (foundTypeIndex == 0 || foundTypeIndex == BuiltinBlocks.Water)
                    {
                        Stockpile ownerStockPile = Stockpile.GetStockPile(areaJob.Owner);
                        if (ownerStockPile.Contains(buildType.ItemIndex))
                        {
                            if (ServerManager.TryChangeBlock(jobPosition, buildType.ItemIndex, areaJob.Owner, ServerManager.SetBlockFlags.DefaultAudio))
                            {
                                if (--job.storedItems == 0)
                                {
                                    state.JobIsDone = true;
                                }
                                ownerStockPile.TryRemove(buildType.ItemIndex);
                                if (iterationType.MoveNext())
                                {
                                    state.SetIndicator(new Shared.IndicatorState(GetCooldown(), buildType.ItemIndex));
                                }
                                else
                                {
                                    // failed to find next position to do job at, self-destruct
                                    state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorIdle));
                                    AreaJobTracker.RemoveJob(areaJob);
                                }
                                return;
                            }
                            else
                            {
                                // shouldn't really happen, world not loaded (just checked)
                                state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorMissing, true, false));
                            }
                        }
                        else
                        {
                            // missing building item
                            state.SetIndicator(new Shared.IndicatorState(Random.NextFloat(5f, 8f), buildType.ItemIndex, true, false));
                        }
                        return;                         // either changed a block or set indicator, job done
                    }
                    else
                    {
                        // move iterator, not placing at non-air blocks
                        if (iterationType.MoveNext())
                        {
                            continue;                             // found non-air, try next loop
                        }
                        else
                        {
                            // failed to find next position to do job at, self-destruct
                            state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorIdle));
                            AreaJobTracker.RemoveJob(areaJob);
                            return;
                        }
                    }
                    // unreachable
                }
                else
                {
                    state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorMissing, true, false));
                    return;                     // end loop, wait for world to load
                }
                // unreachable
            }
            // reached loop count limit
            Assert.IsTrue(iMax <= 0);
            state.SetCooldown(1.0);
        }
Пример #3
0
        public void DoJob(
            IIterationType iterationType,
            IAreaJob areaJob,
            ConstructionJobInstance job,
            ref NPCBase.NPCState state)
        {
            if (iterationType == null)
            {
                AreaJobTracker.RemoveJob(areaJob);
            }
            else
            {
                Stockpile stockpile = areaJob.Owner.Stockpile;
                int       num       = 4096;
                while (num-- > 0)
                {
                    Vector3Int currentPosition = iterationType.CurrentPosition;
                    if (!currentPosition.IsValid)
                    {
                        state.SetIndicator(new IndicatorState(5f, BuiltinBlocks.Indices.erroridle, false, true), true);
                        AreaJobTracker.RemoveJob(areaJob);
                        return;
                    }
                    ushort val;
                    if (World.TryGetTypeAt(currentPosition, out val))
                    {
                        if (val == (ushort)0)
                        {
                            iterationType.MoveNext();
                            continue;
                        }

                        ItemTypes.ItemType type = ItemTypes.GetType(val);
                        if (!type.IsDestructible)
                        {
                            iterationType.MoveNext();
                            continue;
                        }
                        if (type != this.digType)
                        {
                            bool flag = false;
                            for (ItemTypes.ItemType parentItemType = type.ParentItemType; parentItemType != (ItemTypes.ItemType)null; parentItemType = parentItemType.ParentItemType)
                            {
                                if (parentItemType == this.digType)
                                {
                                    flag = true;
                                    break;
                                }
                            }
                            if (!flag)
                            {
                                iterationType.MoveNext();
                                continue;
                            }
                        }
                        if (!stockpile.Contains(this.buildType.ItemIndex, 1))
                        {
                            float num2 = Random.NextFloat(5f, 8f);
                            job.Owner.Stats.RecordNPCIdleSeconds(job.NPCType, num2);
                            state.SetIndicator(new IndicatorState(num2, this.buildType.ItemIndex, true, false), true);
                            return;
                        }

                        if (ServerManager.TryChangeBlock(currentPosition, this.buildType, (BlockChangeRequestOrigin)areaJob.Owner, ESetBlockFlags.DefaultAudio) == EServerChangeBlockResult.Success)
                        {
                            stockpile.TryRemove(this.buildType.ItemIndex, 1, true);
                            float cooldown = ReplacerSpecial.GetCooldown((float)type.DestructionTime * (1f / 1000f));
                            ReplacerSpecial.GatherResults.Clear();
                            List <ItemTypes.ItemTypeDrops> onRemoveItems = type.OnRemoveItems;
                            for (int index = 0; index < onRemoveItems.Count; ++index)
                            {
                                ReplacerSpecial.GatherResults.Add(onRemoveItems[index]);
                            }
                            ModLoader.Callbacks.OnNPCGathered.Invoke((IJob)job, currentPosition, ReplacerSpecial.GatherResults);
                            InventoryItem weightedRandom = ItemTypes.ItemTypeDrops.GetWeightedRandom(ReplacerSpecial.GatherResults);
                            if (weightedRandom.Amount > 0)
                            {
                                state.SetIndicator(new IndicatorState(cooldown, weightedRandom.Type, false, true), true);
                            }
                            else
                            {
                                state.SetCooldown((double)cooldown);
                            }
                            state.Inventory.Add((IList <ItemTypes.ItemTypeDrops>)ReplacerSpecial.GatherResults);
                            ++job.StoredItemCount;
                            iterationType.MoveNext();
                            if (job.StoredItemCount < this.MaxGatheredPerRun)
                            {
                                return;
                            }
                            job.ShouldTakeItems = true;
                            state.JobIsDone     = true;
                            return;
                        }
                        state.SetIndicator(new IndicatorState(5f, BuiltinBlocks.Indices.missingerror, true, false), true);
                        return;
                    }
                    else
                    {
                        state.SetIndicator(new IndicatorState(5f, BuiltinBlocks.Indices.missingerror, true, false), true);
                        return;
                    }
                }
                state.SetCooldown(0.8, 1.2);
            }
        }
Пример #4
0
        public void DoJob(IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ref NPC.NPCBase.NPCState state)
        {
            if (iterationType == null)
            {
                AreaJobTracker.RemoveJob(areaJob);
                return;
            }

            int iMax = 4096;

            while (iMax-- > 0)
            {
                Vector3Int jobPosition = iterationType.CurrentPosition;
                if (!jobPosition.IsValid)
                {
                    // failed to find next position to do job at, self-destruct
                    state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.Indices.erroridle));
                    AreaJobTracker.RemoveJob(areaJob);
                    return;
                }
                ushort foundTypeIndex;
                if (World.TryGetTypeAt(jobPosition, out foundTypeIndex))
                {
                    iterationType.MoveNext();
                    if (foundTypeIndex != 0)
                    {
                        ItemTypes.ItemType foundType = ItemTypes.GetType(foundTypeIndex);

                        if (!foundType.IsDestructible)
                        {
                            continue;                             // skip this block, retry
                        }

                        if (ServerManager.TryChangeBlock(jobPosition, foundTypeIndex, 0, areaJob.Owner, ESetBlockFlags.DefaultAudio) == EServerChangeBlockResult.Success)
                        {
                            float blockDestructionTime = GetCooldown(foundType.DestructionTime * 0.001f);
                            GatherResults.Clear();
                            var itemList = foundType.OnRemoveItems;
                            for (int i = 0; i < itemList.Count; i++)
                            {
                                GatherResults.Add(itemList[i]);
                            }

                            ModLoader.Callbacks.OnNPCGathered.Invoke(job, jobPosition, GatherResults);

                            InventoryItem toShow = ItemTypes.ItemTypeDrops.GetWeightedRandom(GatherResults);
                            if (toShow.Amount > 0)
                            {
                                state.SetIndicator(new Shared.IndicatorState(blockDestructionTime, toShow.Type));
                            }
                            else
                            {
                                state.SetCooldown(blockDestructionTime);
                            }
                            state.Inventory.Add(GatherResults);

                            job.StoredItemCount++;
                            if (job.StoredItemCount >= MaxGatheredPerRun)
                            {
                                job.ShouldTakeItems = true;
                                state.JobIsDone     = true;
                            }
                        }
                        else
                        {
                            state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.Indices.missingerror, true, false));
                        }
                        return;                         // either changed a block or set indicator, job done
                    }
                    else
                    {
                        continue;                         // found air, try next loop
                    }
                    // unreachable
                }
                else
                {
                    state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.Indices.missingerror, true, false));
                    return;                     // end loop, wait for world to load
                }
                // unreachable
            }
            // reached loop count limit
            Assert.IsTrue(iMax <= 0);
            state.SetCooldown(1.0);
        }
        public void DoJob(IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ref NPCBase.NPCState state)
        {
            int i   = 0;
            var bpi = iterationType as SchematicIterator;

            if (bpi == null)
            {
                SettlersLogger.Log(ChatColor.yellow, "iterationType must be of type SchematicIterator for the SchematicBuilder.");
                state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                AreaJobTracker.RemoveJob(areaJob);
                return;
            }

            while (true) // This is to move past air.
            {
                if (i > 4000)
                {
                    break;
                }

                var adjX      = iterationType.CurrentPosition.x - bpi.BuilderSchematic.StartPos.x;
                var adjY      = iterationType.CurrentPosition.y - bpi.BuilderSchematic.StartPos.y;
                var adjZ      = iterationType.CurrentPosition.z - bpi.BuilderSchematic.StartPos.z;
                var block     = bpi.BuilderSchematic.GetBlock(adjX, adjY, adjZ);
                var mapped    = block.MappedBlock;
                var buildType = ItemTypes.GetType(mapped.CSIndex);

                if (buildType == null)
                {
                    state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                    AreaJobTracker.RemoveJob(areaJob);
                    return;
                }

                if (World.TryGetTypeAt(iterationType.CurrentPosition, out ushort foundTypeIndex))
                {
                    i++;
                    var founditemId = ItemId.GetItemId(foundTypeIndex);

                    if (foundTypeIndex == buildType.ItemIndex || buildType.Name.Contains("bedend") || (founditemId.Name.Contains("bedend") && buildType.ItemIndex == ColonyBuiltIn.ItemTypes.AIR)) // check if the blocks are the same, if they are, move past. Most of the time this will be air.
                    {
                        if (iterationType.MoveNext())
                        {
                            continue;
                        }
                        else
                        {
                            if (_needsChunkLoaded.Contains(bpi))
                            {
                                _needsChunkLoaded.Remove(bpi);
                            }

                            state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                            AreaJobTracker.RemoveJob(areaJob);
                            return;
                        }
                    }

                    Stockpile ownerStockPile = areaJob.Owner.Stockpile;

                    bool stockpileContainsBuildItem = buildType.ItemIndex == ColonyBuiltIn.ItemTypes.AIR.Id;

                    if (!stockpileContainsBuildItem && ownerStockPile.Contains(buildType.ItemIndex))
                    {
                        stockpileContainsBuildItem = true;
                    }

                    if (!stockpileContainsBuildItem && buildType.Name.Contains("bed") && ownerStockPile.Contains(ItemId.GetItemId("bed")))
                    {
                        stockpileContainsBuildItem = true;
                    }

                    if (!stockpileContainsBuildItem &&
                        !string.IsNullOrWhiteSpace(buildType.ParentType) &&
                        ownerStockPile.Contains(buildType.ParentItemType.ItemIndex))
                    {
                        stockpileContainsBuildItem = true;
                    }

                    if (stockpileContainsBuildItem)
                    {
                        if (foundTypeIndex != ColonyBuiltIn.ItemTypes.AIR.Id && foundTypeIndex != ColonyBuiltIn.ItemTypes.WATER.Id)
                        {
                            var foundItem = ItemTypes.GetType(foundTypeIndex);

                            if (foundItem != null && foundItem.ItemIndex != ColonyBuiltIn.ItemTypes.AIR.Id && foundItem.OnRemoveItems != null && foundItem.OnRemoveItems.Count > 0)
                            {
                                ownerStockPile.Add(foundItem.OnRemoveItems.Select(itm => itm.item).ToList());
                            }
                        }

                        var changeResult = ServerManager.TryChangeBlock(iterationType.CurrentPosition, buildType.ItemIndex, new BlockChangeRequestOrigin(job.Owner), ESetBlockFlags.DefaultAudio);

                        if (changeResult == EServerChangeBlockResult.Success)
                        {
                            if (buildType.ItemIndex != ColonyBuiltIn.ItemTypes.AIR.Id)
                            {
                                if (--job.StoredItemCount <= 0)
                                {
                                    job.ShouldTakeItems = true;
                                    state.JobIsDone     = true;
                                }

                                ownerStockPile.TryRemove(buildType.ItemIndex);

                                if (buildType.Name.Contains("bed"))
                                {
                                    ownerStockPile.TryRemove(ItemId.GetItemId("bed"));
                                }
                            }
                        }
                        else if (changeResult != EServerChangeBlockResult.CancelledByCallback)
                        {
                            if (!_needsChunkLoaded.Contains(bpi))
                            {
                                _needsChunkLoaded.Add(bpi);
                            }

                            state.SetIndicator(new Shared.IndicatorState(5f, buildType.Name));
                            ChunkQueue.QueuePlayerSurrounding(iterationType.CurrentPosition.ToChunk());
                            return;
                        }
                    }
                    else
                    {
                        state.SetIndicator(new Shared.IndicatorState(5f, buildType.Name, true, false));
                        return;
                    }
                }
                else
                {
                    if (!_needsChunkLoaded.Contains(bpi))
                    {
                        _needsChunkLoaded.Add(bpi);
                    }

                    ChunkQueue.QueuePlayerSurrounding(iterationType.CurrentPosition.ToChunk());
                    state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                    return;
                }


                if (iterationType.MoveNext())
                {
                    if (buildType.ItemIndex != ColonyBuiltIn.ItemTypes.AIR.Id)
                    {
                        state.SetIndicator(new Shared.IndicatorState(GetCooldown(), buildType.ItemIndex));
                    }
                    else
                    {
                        state.SetIndicator(new Shared.IndicatorState(GetCooldown(), foundTypeIndex));
                    }

                    return;
                }
                else
                {
                    if (_needsChunkLoaded.Contains(bpi))
                    {
                        _needsChunkLoaded.Remove(bpi);
                    }

                    // failed to find next position to do job at, self-destruct
                    state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                    AreaJobTracker.RemoveJob(areaJob);
                    return;
                }
            }

            if (iterationType.MoveNext())
            {
                state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                return;
            }
            else
            {
                if (_needsChunkLoaded.Contains(bpi))
                {
                    _needsChunkLoaded.Remove(bpi);
                }

                // failed to find next position to do job at, self-destruct
                state.SetIndicator(new Shared.IndicatorState(5f, ColonyBuiltIn.ItemTypes.ERRORIDLE.Name));
                AreaJobTracker.RemoveJob(areaJob);
                SettlersLogger.Log(ChatColor.yellow, "Failed to MoveNext after while. Iterator position: {0}.", iterationType.CurrentPosition);
                return;
            }
        }
Пример #6
0
        public void DoJob(IIterationType iterationType, IAreaJob job, ref NPC.NPCBase.NPCState state)
        {
            if (iterationType == null)
            {
                AreaJobTracker.RemoveJob(job);
                return;
            }

            while (true)
            {
                Vector3Int jobPosition = iterationType.CurrentPosition;

                ushort foundTypeIndex;
                if (World.TryGetTypeAt(jobPosition, out foundTypeIndex))
                {
                    if (!iterationType.MoveNext())
                    {
                        // failed to find next position to do job at, self-destruct
                        state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorIdle));
                        AreaJobTracker.RemoveJob(job);
                        return;
                    }
                    if (foundTypeIndex != 0)
                    {
                        ItemTypes.ItemType foundType = ItemTypes.GetType(foundTypeIndex);

                        if (!foundType.IsDestructible)
                        {
                            continue;                             // skip this block, retry
                        }

                        if (ServerManager.TryChangeBlock(jobPosition, 0, job.Owner, ServerManager.SetBlockFlags.DefaultAudio))
                        {
                            InventoryItem typeDropped   = InventoryItem.Empty;
                            var           onRemoveItems = ItemTypes.GetType(foundTypeIndex).OnRemoveItems;
                            for (int i = 0; i < onRemoveItems.Count; i++)
                            {
                                if (Random.NextDouble() <= onRemoveItems[i].chance)
                                {
                                    typeDropped = onRemoveItems[i].item;
                                    state.Inventory.Add(typeDropped);
                                }
                            }

                            float blockDestructionTime = GetCooldown(foundType.DestructionTime * 0.001f);
                            if (typeDropped.Amount > 0)
                            {
                                state.SetIndicator(new Shared.IndicatorState(blockDestructionTime, typeDropped.Type));
                            }
                            else
                            {
                                state.SetCooldown(blockDestructionTime);
                            }
                        }
                        else
                        {
                            state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorMissing, true, false));
                        }
                        return;                         // either changed a block or set indicator, job done
                    }
                    else
                    {
                        continue;                         // found air, try next loop
                    }
                    // unreachable
                }
                else
                {
                    state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorMissing, true, false));
                    return;                     // end loop, wait for world to load
                }
                // unreachable
            }
            // unreachable
        }