public override void FinishLoading()
        {
            base.FinishLoading();
            if (legacyJSON != null)
            {
                foreach (var pair in legacyJSON.LoopObject())
                {
                    try {
                        Players.Player player = Players.GetPlayer(NetworkID.Parse(pair.Key));

                        for (int i = 0; i < pair.Value.ChildCount; i++)
                        {
                            JSONNode jobNode = pair.Value[i];

                            int        npcID = jobNode.GetAsOrDefault("npcID", 0);
                            Vector3Int min   = (Vector3Int)jobNode["positionMin"];
                            Vector3Int max   = (Vector3Int)jobNode["positionMax"];

                            var job = new DefaultFarmerAreaJob <AppleForesterDefinition>(player, min, max, npcID);
                            if (!AreaJobTracker.RegisterAreaJob(job))
                            {
                                job.OnRemove();
                            }
                            AreaJobTracker.RemoveJob(job);
                        }
                    } catch (System.Exception e) {
                        Log.WriteException("Exception loading legacy area job data", e);
                    }
                }
                legacyJSON = null;
            }
        }
Exemple #2
0
        private static void CleanupJob(IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ArchitectIterator bpi, int prvX, int prvY, int prvZ)
        {
            if (_needsChunkLoaded.Contains(bpi))
            {
                _needsChunkLoaded.Remove(bpi);
            }

            if (bpi.PreviousPosition != Pipliz.Vector3Int.invalidPos &&
                prvX <= bpi.BuilderSchematic.XMax &&
                prvY <= bpi.BuilderSchematic.YMax &&
                prvZ <= bpi.BuilderSchematic.ZMax &&
                !bpi.BuilderSchematic.Blocks[prvX, prvY, prvZ].BlockID.Contains("bedend"))
            {
                ServerManager.TryChangeBlock(bpi.PreviousPosition, ItemId.GetItemId(bpi.BuilderSchematic.Blocks[prvX, prvY, prvZ].BlockID).Id, new BlockChangeRequestOrigin(job.Owner), ESetBlockFlags.DefaultAudio);
            }

            SchematicReader.SaveSchematic(areaJob.Owner, bpi.BuilderSchematic);
            AreaJobTracker.RemoveJob(areaJob);
        }
Exemple #3
0
        public void DoJob(IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ref NPCBase.NPCState state)
        {
            int i   = 0;
            var bpi = iterationType as ArchitectIterator;

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

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

                i++;

                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 prvX = bpi.PreviousPosition.x - bpi.BuilderSchematic.StartPos.x;
                var prvY = bpi.PreviousPosition.y - bpi.BuilderSchematic.StartPos.y;
                var prvZ = bpi.PreviousPosition.z - bpi.BuilderSchematic.StartPos.z;

                if (World.TryGetTypeAt(iterationType.CurrentPosition, out ItemTypes.ItemType foundType))
                {
                    state.SetCooldown(2);
                    state.SetIndicator(new Shared.IndicatorState(2, foundType.Name));

                    if (foundType.ItemIndex == ColonyBuiltIn.ItemTypes.AIR ||
                        foundType.Name == ColonyBuiltIn.ItemTypes.BANNER)
                    {
                        if (!MoveNext(iterationType, areaJob, job, bpi, prvX, prvY, prvZ))
                        {
                            return;
                        }

                        continue;
                    }

                    try
                    {
                        bpi.BuilderSchematic.Blocks[adjX, adjY, adjZ].BlockID = foundType.Name;
                    }
                    catch (IndexOutOfRangeException)
                    {
                        SettlersLogger.Log(ChatColor.red, $"Index out of range on ArchitectBuilder {adjX}, {adjY}, {adjZ} to a max of {bpi.BuilderSchematic.Blocks.GetLength(0)}, {bpi.BuilderSchematic.Blocks.GetLength(1)}, {bpi.BuilderSchematic.Blocks.GetLength(2)}.");

                        CleanupJob(iterationType, areaJob, job, bpi, prvX, prvY, prvZ);
                        break;
                    }

                    if (!foundType.Name.Contains("bedend"))
                    {
                        ServerManager.TryChangeBlock(iterationType.CurrentPosition, SettlersBuiltIn.ItemTypes.SELECTOR.Id, new BlockChangeRequestOrigin(job.Owner), ESetBlockFlags.DefaultAudio);
                    }

                    MoveNext(iterationType, areaJob, job, bpi, prvX, prvY, prvZ);
                }
                else
                {
                    if (!_needsChunkLoaded.Contains(bpi))
                    {
                        _needsChunkLoaded.Add(bpi);
                    }

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

                break;
            }
        }
Exemple #4
0
        public virtual void OnNPCAtJob(IAreaJob job, ref Vector3Int positionSub, ref NPCBase.NPCState state, ref bool shouldDumpInventory)
        {
            if (stages == null || stages.Length < 2)
            {
                state.SetCooldown(1.0);
                return;
            }
            state.JobIsDone = true;
            if (positionSub.IsValid)
            {
                ushort type;
                if (World.TryGetTypeAt(positionSub, out type))
                {
                    ushort typeSeeds = stages[0];
                    ushort typeFinal = stages[stages.Length - 1];
                    if (type == 0)
                    {
                        if (state.Inventory.TryGetOneItem(typeSeeds) ||
                            job.NPC.Colony.UsedStockpile.TryRemove(typeSeeds))
                        {
                            ushort typeBelow;
                            if (World.TryGetTypeAt(positionSub.Add(0, -1, 0), out typeBelow))
                            {
                                // check for fertile below
                                if (ItemTypes.GetType(typeBelow).IsFertile)
                                {
                                    ServerManager.TryChangeBlock(positionSub, typeSeeds, job.Owner, ServerManager.SetBlockFlags.DefaultAudio);
                                    state.SetCooldown(1.0);
                                    shouldDumpInventory = false;
                                }
                                else
                                {
                                    // not fertile below
                                    AreaJobTracker.RemoveJob(job);
                                    state.SetCooldown(2.0);
                                }
                            }
                            else
                            {
                                // didn't load this part of the world
                                state.SetCooldown(Random.NextFloat(3f, 6f));
                            }
                        }
                        else
                        {
                            state.SetIndicator(new Shared.IndicatorState(2f, typeSeeds, true, false));
                            shouldDumpInventory = state.Inventory.UsedCapacity > 0f;
                        }
                    }
                    else if (type == typeFinal)
                    {
                        if (ServerManager.TryChangeBlock(positionSub, 0, job.Owner, ServerManager.SetBlockFlags.DefaultAudio))
                        {
                            GatherResults.Clear();
                            var results = ItemTypes.GetType(typeFinal).OnRemoveItems;
                            for (int i = 0; i < results.Count; i++)
                            {
                                GatherResults.Add(results[i]);
                            }

                            ModLoader.TriggerCallbacks(ModLoader.EModCallbackType.OnNPCGathered, job as IJob, positionSub, GatherResults);

                            job.NPC.Inventory.Add(GatherResults);
                        }
                        state.SetCooldown(1.0);
                        shouldDumpInventory = false;
                    }
                    else
                    {
                        shouldDumpInventory = state.Inventory.UsedCapacity > 0f;

                        Server.GrowableBlocks.IGrowableBlock block;
                        if (Server.GrowableBlocks.GrowableBlockManager.TryGetGrowableBlock(positionSub, out block))
                        {
                            state.SetCooldown(5.0);
                        }
                        else
                        {
                            bool found = false;
                            for (int i = 0; i < stages.Length; i++)
                            {
                                if (stages[i] == type)
                                {
                                    ItemTypesServer.OnChange(positionSub, 0, type, null);
                                    state.SetIndicator(new Shared.IndicatorState(2f, type));
                                    state.SetCooldown(0.2);
                                    found = true;
                                    break;
                                }
                            }
                            if (!found)
                            {
                                state.SetCooldown(5.0);
                            }
                        }
                    }
                }
                else
                {
                    state.SetCooldown(Random.NextFloat(3f, 6f));
                }
                positionSub = Vector3Int.invalidPos;
            }
            else
            {
                state.SetCooldown(10.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);
        }
Exemple #6
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);
            }
        }
Exemple #7
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;
            }
        }
Exemple #9
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
        }
Exemple #10
0
        public virtual void DoJob(IJob job, ref NPCBase.NPCState state)
        {
            while (iterationChunk0.y >= (positionMin.y & -16))
            {
                while (iterationChunk0.x <= (positionMax.x & -16))
                {
                    while (iterationChunk0.z <= (positionMax.z & -16))
                    {
                        while (iterationChunk1.y >= iterationChunk0.y)
                        {
                            while (iterationChunk1.x < iterationChunk0.x + 16)
                            {
                                while (iterationChunk1.z < iterationChunk0.z + 16)
                                {
                                    while (iterationChunk2.y >= iterationChunk1.y)
                                    {
                                        while (iterationChunk2.x < iterationChunk1.x + 8)
                                        {
                                            while (iterationChunk2.z < iterationChunk1.z + 8)
                                            {
                                                while (iterationPosition.y >= 0)
                                                {
                                                    while (iterationPosition.x < 4)
                                                    {
                                                        while (iterationPosition.z < 4)
                                                        {
                                                            Vector3Int pos = iterationChunk2 + iterationPosition;
                                                            if (DoJobAt(job, ref state, ref pos))
                                                            {
                                                                return;
                                                            }
                                                        }
                                                        iterationPosition.z = 0;
                                                        iterationPosition.x++;
                                                    }
                                                    iterationPosition.x = 0;
                                                    iterationPosition.y--;
                                                }

                                                // completed 4x4x4 box, increment z & reset iteration position
                                                iterationPosition  = new Vector3Int(0, 4, 0);
                                                iterationChunk2.z += 4;
                                            }
                                            // completed 4x4x4 box row, increment x & reset z to start the new row
                                            iterationChunk2.x += 4;
                                            iterationChunk2.z  = iterationChunk1.z;
                                        }
                                        // completed 4x4x4 box layer, decrement y & reset x to start the new layer
                                        iterationChunk2.y -= 4;
                                        iterationChunk2.x  = iterationChunk1.x;
                                    }

                                    // completed 8x8x8 box, increment z & reset sub-boxes
                                    iterationChunk1.z += 8;
                                    iterationChunk2    = iterationChunk1.Add(0, 4, 0);
                                }

                                // completed 8x8x8 box row, increment x & reset z to start the new row
                                iterationChunk1.x += 8;
                                iterationChunk1.z  = iterationChunk0.z;
                                iterationChunk2    = iterationChunk1.Add(0, 4, 0);
                            }

                            // completed 8x8x8 box layer, restart at lower level
                            iterationChunk1.x  = iterationChunk0.x;
                            iterationChunk1.y -= 8;
                            iterationChunk2    = iterationChunk1.Add(0, 4, 0);
                        }

                        // completed 16x16x16 chunk, increment z & reset 8x8x8 cube position
                        iterationChunk0.z += 16;
                        iterationChunk1    = iterationChunk0.Add(0, 8, 0);
                        iterationChunk2    = iterationChunk0.Add(0, 8 + 4, 0);
                    }
                    // completed 16x16x16 chunk row, increment x & reset z to start the new row
                    iterationChunk0.z  = positionMin.z & -16;
                    iterationChunk0.x += 16;
                    iterationChunk1    = iterationChunk0.Add(0, 8, 0);
                    iterationChunk2    = iterationChunk0.Add(0, 8 + 4, 0);
                }
                // completed 16x16x16 chunk layer, decrement y
                iterationChunk0.x  = positionMin.x & -16;
                iterationChunk0.y -= 16;
                iterationChunk1    = iterationChunk0.Add(0, 8, 0);
                iterationChunk2    = iterationChunk0.Add(0, 8 + 4, 0);
            }

            // completed area, remove it
            state.SetIndicator(new Shared.IndicatorState(5f, BuiltinBlocks.ErrorIdle));
            AreaJobTracker.RemoveJob(this);
        }
        public static async void RewindColonyBlocks(Colony colony)
        {
            foreach (var npc in colony.Followers.ToList())
            {
                npc.health = 0;

                if (npc.Job is IAreaJob areaJob)
                {
                    AreaJobTracker.RemoveJob(areaJob);
                }

                npc.ClearJob();
                npc.OnDeath();
            }

            RoamingJobManager.Objectives.Remove(colony);

            ServerManager.ColonyTracker.ColoniesLock.EnterWriteLock();
            ServerManager.ColonyTracker.ColoniesByID.Remove(colony.ColonyID);
            Colony newcolony = new Colony(colony.ColonyID);

            newcolony.Stockpile.AddEnumerable(from unresolved in ServerManager.WorldSettingsReadOnly.InitialStockpile
                                              select new InventoryItem(unresolved.type, unresolved.amount));
            ServerManager.ColonyTracker.ColoniesByID.Add(newcolony.ColonyID, newcolony);
            ServerManager.ColonyTracker.ColoniesLock.ExitWriteLock();
            ServerManager.ColonyTracker.Save();

            await Task.Run(() =>
            {
                try
                {
                    var colonyName = colony.Name;

                    using (TrackedPositionContext db = new TrackedPositionContext())
                    {
                        foreach (var trackedPos in db.Positions.Where(p => p.ColonyId == colonyName))
                        {
                            var oldest = db.Positions.Where(o => o.X == trackedPos.X && o.Y == trackedPos.Y && o.Z == trackedPos.Z && o.TimeTracked < trackedPos.TimeTracked).OrderBy(tp => tp.TimeTracked).FirstOrDefault();

                            if (oldest == default(TrackedPosition))
                            {
                                oldest = trackedPos;
                            }

                            if (!_queuedPositions.Any(pos => pos.Equals(oldest)))
                            {
                                lock (_queuedPositions)
                                    _queuedPositions.Add(oldest);

                                ChunkQueue.QueuePlayerRequest(oldest.GetVector().ToChunk(), colony.Owners.FirstOrDefault());
                            }
                        }

                        if (_queuedPositions.Count <= 0)
                        {
                            return;
                        }

                        System.Threading.Thread.Sleep(10000);

                        List <TrackedPosition> replaced = new List <TrackedPosition>();

                        foreach (var trackedPos in _queuedPositions)
                        {
                            if (ServerManager.TryChangeBlock(trackedPos.GetVector(), (ushort)trackedPos.BlockId) == EServerChangeBlockResult.Success)
                            {
                                replaced.Add(trackedPos);
                            }
                        }

                        lock (_queuedPositions)
                        {
                            db.Positions.RemoveRange(_queuedPositions);
                            foreach (var replace in replaced)
                            {
                                _queuedPositions.Remove(replace);
                            }
                        }

                        db.SaveChanges();
                    }
                }
                catch (DbEntityValidationException e)
                {
                    ProcessEntityException(e);
                }
                catch (Exception ex)
                {
                    PandaLogger.LogError(ex);
                }
            });
        }