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