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