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); }
private static bool MoveNext(IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ArchitectIterator bpi, int prvX, int prvY, int prvZ) { 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); } if (!bpi.MoveNext()) { CleanupJob(iterationType, areaJob, job, bpi, prvX, prvY, prvZ); return(false); } return(true); }
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(); } }
static void Postfix(BuilderBasic __instance, IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ref NPCBase.NPCState state) { // Log.WriteWarning("BuilderBasicHookDoJob::Postfix"); npc = null; }
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; } }
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 SetIterationType(IIterationType type) { iterationType = type; }
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 }
static void Postfix(BuilderBasic __instance, IIterationType iterationType, IAreaJob areaJob, ConstructionJobInstance job, ref NPCBase.NPCState state) { DebugLog.Write(MethodBase.GetCurrentMethod().DeclaringType + "::" + MethodBase.GetCurrentMethod().Name); npc = null; }