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 <TemperateForesterDefinition>(player, min, max, npcID);
                            if (!AreaJobTracker.RegisterAreaJob(job))
                            {
                                job.OnRemove();
                            }
                        }
                    } catch (System.Exception e) {
                        Log.WriteException("Exception loading legacy area job data", e);
                    }
                }
                legacyJSON = null;
            }
        }
Пример #2
0
        public static void OpenMenu(Players.Player player, PlayerClickedData playerClickData)
        {
            if (ItemTypes.IndexLookup.TryGetIndex(SchematicTool.NAME, out var schematicItem) &&
                playerClickData.TypeSelected == schematicItem)
            {
                if (player.ActiveColony == null)
                {
                    PandaChat.Send(player, _localizationHelper, "ErrorOpening", ChatColor.red);
                    return;
                }

                if (!_awaitingClick.ContainsKey(player))
                {
                    SendMainMenu(player);
                }
                else
                {
                    var tuple = _awaitingClick[player];
                    _awaitingClick.Remove(player);

                    switch (tuple.Item1)
                    {
                    case SchematicClickType.Build:
                        Vector3Int location = playerClickData.GetVoxelHit().BlockHit.Add(0, 1, 0);
                        var        args     = new JSONNode();
                        args.SetAs("constructionType", GameLoader.NAMESPACE + ".SchematicBuilder");
                        args.SetAs(SchematicBuilderLoader.NAME + ".SchematicName", tuple.Item2);
                        args.SetAs(SchematicBuilderLoader.NAME + ".Rotation", tuple.Item3);

                        if (SchematicReader.TryGetSchematic(tuple.Item2, player.ActiveColony.ColonyID, location, out var schematic))
                        {
                            if (tuple.Item3 >= Schematic.Rotation.Right)
                            {
                                schematic.Rotate();
                            }

                            if (tuple.Item3 >= Schematic.Rotation.Back)
                            {
                                schematic.Rotate();
                            }

                            if (tuple.Item3 >= Schematic.Rotation.Left)
                            {
                                schematic.Rotate();
                            }

                            var maxSize = location.Add(schematic.XMax - 1, schematic.YMax - 1, schematic.ZMax - 1);
                            AreaJobTracker.CreateNewAreaJob("pipliz.constructionarea", args, player.ActiveColony, location, maxSize);
                            AreaJobTracker.SendData(player);
                        }

                        break;

                    case SchematicClickType.Archetect:

                        break;
                    }
                }
            }
        }
Пример #3
0
        bool CreateFieldAndJob(Vector3Int center)
        {
            if (!IsClear(center.Add(-5, 0, -5), 11, 2, 11))
            {
                return(false);
            }
            var crateZ = -4 + Random.Next(10);

            BlockPlacementHelper.PlaceBlock(center.Add(-5, 0, crateZ), BuiltinBlocks.Crate, Owner);
            BlockPlacementHelper.PlaceBlock(center.Add(-5, 1, crateZ), BuiltinBlocks.TorchYP, Owner);
            var min = center.Add(-4, 0, -4);
            var max = center.Add(5, 0, 5);

            for (int x = min.x; x < max.x; x++)
            {
                for (int z = min.z; z < max.z; z++)
                {
                    bool solid;
                    if (!World.TryIsSolid(new Vector3Int(x, center.y - 1, z), out solid) || !solid)
                    {
                        return(false);
                    }
                }
            }
            AreaJobTracker.CreateNewAreaJob("pipliz.wheatfarm", Owner, min, max);
            return(true);
        }
Пример #4
0
        public void SetCorner2(Vector3Int newPos, Players.Player player)
        {
            pos2    = newPos;
            corner1 = Vector3Int.Min(pos1, pos2);
            corner2 = Vector3Int.Max(pos1, pos2);

            AreaJobTracker.SendData(player);
        }
 // add player to list
 public static bool Add(Players.Player player)
 {
     if (playerList.Contains(player))
     {
         return(false);
     }
     playerList.Add(player);
     AreaJobTracker.SendData(player);
     return(true);
 }
 // remove player from list
 public static bool Remove(Players.Player player)
 {
     if (playerList.Contains(player))
     {
         playerList.Remove(player);
         AreaJobTracker.SendData(player);
         return(true);
     }
     return(false);
 }
Пример #7
0
        public static void OnTryChangeBlockUser(ModLoader.OnTryChangeBlockData userData)
        {
            if (userData.TypeNew == ItemTypes.IndexLookup.GetIndex("Ulfric.ColonyAddOns.Blocks.AppleBasket") && userData.TypeOld == BuiltinBlocks.Air)
            {
                Logger.Log("Check if area is clear for AppleFarmer");
                Vector3Int position = userData.Position;
                int        xlen     = 7;
                int        zlen     = 7;
                int        radius   = 3;

                //set NW corner
                Vector3Int nwcorner = new Vector3Int(position.x - radius, position.y, position.z - radius);
                Vector3Int secorner = new Vector3Int(position.x + radius, position.y, position.z + radius);

                bool blocked = false;
                for (int x = 0; x <= xlen; x++)
                {
                    for (int z = 0; z <= zlen; z++)
                    {
                        if (World.TryGetTypeAt(nwcorner.Add(x, 0, z), out ushort val) && val != BuiltinBlocks.Air)
                        {
                            blocked = true;
                        }
                    }
                }

                if (blocked)
                {
                    Chat.Send(userData.RequestedByPlayer, "Apple Farmer 9 x 9 area is blocked.");
                }
                else
                {
                    AreaJobTracker.CreateNewAreaJob("Ulfric.ColonyAddOns.AreaJobs.AppleFarm", userData.RequestedByPlayer, nwcorner, secorner);

                    ThreadManager.InvokeOnMainThread(delegate()
                    {
                        ServerManager.TryChangeBlock(position, userData.TypeNew);
                    }, 0.1f);
                }
            }
            if (userData.TypeOld == ItemTypes.IndexLookup.GetIndex("Ulfric.ColonyAddOns.Blocks.AppleBasket") && userData.TypeNew == BuiltinBlocks.Air)
            {
                Logger.Log("Remove job");
                Vector3Int position = userData.Position;
                int        xlen     = 7;
                int        zlen     = 7;
                int        radius   = 3;

                //set NW corner
                Vector3Int nwcorner = new Vector3Int(position.x - radius, position.y, position.z - radius);
                Vector3Int secorner = new Vector3Int(position.x + radius, position.y, position.z + radius);
                AreaJobTracker.RemoveJobAt(nwcorner, secorner);
            }
        }
 static void Load()
 {
     if (queuedDefinitions != null)
     {
         for (int i = 0; i < queuedDefinitions.Count; i++)
         {
             try {
                 AreaJobTracker.RegisterAreaJobDefinition((IAreaJobDefinition)Activator.CreateInstance(queuedDefinitions[i]));
             } catch (Exception e) {
                 Log.WriteException(e);
             }
         }
         queuedDefinitions = null;
     }
 }
Пример #9
0
        public virtual void LoadJSON(JSONNode node)
        {
            JSONNode table = node.GetAs <JSONNode>("table");

            foreach (var pair in table.LoopObject())
            {
                Players.Player player = Players.GetPlayer(NetworkID.Parse(pair.Key));
                JSONNode       array  = pair.Value;
                for (int i = 0; i < array.ChildCount; i++)
                {
                    var job = CreateAreaJob(player, array[i]);
                    if (!AreaJobTracker.RegisterAreaJob(job))
                    {
                        job.OnRemove();
                    }
                }
            }
        }
Пример #10
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);
        }
Пример #11
0
        public void OnAssemblyLoaded(string path)
        {
            //Register loader for Construction job callback
            ConstructionArea.RegisterLoader((IConstructionLoader) new ReplacerSpecialLoader());
            ConstructionArea.RegisterLoader((IConstructionLoader) new ShapeBuilderLoader("wingdings.walls"));
            ConstructionArea.RegisterLoader((IConstructionLoader) new ShapeBuilderLoader("wingdings.pyramid"));
            ConstructionArea.RegisterLoader((IConstructionLoader) new ShapeBuilderLoader("wingdings.circle"));

            //Override identifier so we can create our own callback using the Construction Job
            AreaJobTracker.RegisterAreaJobDefinition(new CustomConstructionAreaJobDefinition());
            CommandToolManager.AddAreaJobSettings(new ConstructionAreaToolSettings("wingdings.tooljob.walls", "wingdings.walls", "wingdings.builder.2d", EConstructionKind.Builder, 1, EAreaItemSelectionFilter.ComboBuildable));
            CommandToolManager.AddAreaJobSettings(new ConstructionAreaToolSettings("wingdings.tooljob.pyramid", "wingdings.pyramid", "wingdings.builder.3d", EConstructionKind.Builder, 1, EAreaItemSelectionFilter.ComboBuildable));
            CommandToolManager.AddAreaJobSettings(new ConstructionAreaToolSettings("wingdings.tooljob.circle", "wingdings.circle", "wingdings.builder.2d", EConstructionKind.Builder, 1, EAreaItemSelectionFilter.ComboBuildable));

            //dictionary.Add("pipliz.digger", ("popup.tooljob.diggera", "popup.tooljob.diggerb"));
            CommandToolManager.AddButtonTooltip("wingdings.tooljob.replacer", "wingdings.tooljob.replacera", "wingdings.tooljob.replacerb");
            CommandToolManager.AddButtonTooltip("wingdings.tooljob.walls", "wingdings.tooljob.wallsa", "wingdings.tooljob.wallsb");
            CommandToolManager.AddButtonTooltip("wingdings.tooljob.pyramid", "wingdings.tooljob.pyramida", "wingdings.tooljob.pyramidb");
            CommandToolManager.AddButtonTooltip("wingdings.tooljob.circle", "wingdings.tooljob.circlea", "wingdings.tooljob.circleb");
        }
        public bool TryDoCommand(Players.Player causedBy, string chattext, List <string> splits)
        {
            if (!splits[0].Equals("/areashow"))
            {
                return(false);
            }
            if (!PermissionsManager.CheckAndWarnPermission(causedBy, AntiGrief.MOD_PREFIX + "areashow"))
            {
                return(true);
            }

            // if parameter action given toggle all areas shown
            Match  m      = Regex.Match(chattext, @"/areashow ?(?<action>.+)?");
            string action = m.Groups["action"].Value;

            if (action.Equals("add"))
            {
                if (AreaShowManager.Add(causedBy))
                {
                    Chat.Send(causedBy, "You now see area jobs of all players");
                }
                return(true);
            }
            else if (action.Equals("remove"))
            {
                if (AreaShowManager.Remove(causedBy))
                {
                    Chat.Send(causedBy, "You no longer see area jobs of all players");
                }
                return(true);
            }

            // without action parameter just trigger a data send
            AreaJobTracker.SendData(causedBy);
            return(true);
        }
Пример #13
0
        public override void OnNPCAtJob(ref NPCBase.NPCState state)
        {
            if (constructionArea != null && !constructionArea.IsValid)
            {
                constructionArea = null;
            }

            if (worldTypeChecked)
            {
                Vector3 pos = usedNPC.Position.Vector;
                if (worldType == BuiltinBlocks.ConstructionJobXP)
                {
                    usedNPC.LookAt(pos + Vector3.right);
                }
                else if (worldType == BuiltinBlocks.ConstructionJobXN)
                {
                    usedNPC.LookAt(pos + Vector3.left);
                }
                else if (worldType == BuiltinBlocks.ConstructionJobZP)
                {
                    usedNPC.LookAt(pos + Vector3.forward);
                }
                else if (worldType == BuiltinBlocks.ConstructionJobZN)
                {
                    usedNPC.LookAt(pos + Vector3.back);
                }
            }

            if (constructionArea == null)
            {
                List <IAreaJob> jobs;
                if (AreaJobTracker.ExistingAreaAt(position.Add(-1, -1, -1), position.Add(1, 1, 1), out jobs))
                {
                    for (int i = 0; i < jobs.Count; i++)
                    {
                        ConstructionArea neighbourArea = jobs[i] as ConstructionArea;
                        if (neighbourArea != null)
                        {
                            constructionArea = neighbourArea;
                            break;
                        }
                    }
                    AreaJobTracker.AreaJobListPool.Return(jobs);
                }

                if (constructionArea == null)
                {
                    if (isAreaPresenceTestDone)
                    {
                        state.SetCooldown(0.5);
                        ServerManager.TryChangeBlock(position, 0);
                    }
                    else
                    {
                        state.SetIndicator(new Shared.IndicatorState(Random.NextFloat(3f, 5f), BuiltinBlocks.ErrorIdle));
                        isAreaPresenceTestDone = true;
                    }
                    return;
                }
            }

            Assert.IsNotNull(constructionArea);
            constructionArea.DoJob(this, ref state);
        }
Пример #14
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;
            }
        }
Пример #15
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);
            }
        }
Пример #16
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);
        }
Пример #17
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
        }
Пример #18
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);
        }
Пример #19
0
        private static void Right_Click(Players.Player player)
        {
            int forester = last_forester.GetValueOrDefault(player.ID, 0);

            AreaJobTracker.CommandToolTypeData data = new AreaJobTracker.CommandToolTypeData();

            switch (forester)
            {
            default:
            case 0:
                data.LocaleEntry = "popup.tooljob.cherryforester";
                data.AreaType    = "Khanx.CherryForester";
                break;

            case 1:
                data.LocaleEntry = "popup.tooljob.taigaforester";
                data.AreaType    = "Khanx.TaigaForester";
                break;

            case 2:
                data.LocaleEntry = "popup.tooljob.oliveforester";
                data.AreaType    = "Khanx.OliveForester";
                break;

            case 3:
                data.LocaleEntry = "popup.tooljob.autumredforester";
                data.AreaType    = "Khanx.AutummRedForester";
                break;

            case 4:
                data.LocaleEntry = "popup.tooljob.autummorangeforester";
                data.AreaType    = "Khanx.AutummOrangeForester";
                break;

            case 5:
                data.LocaleEntry = "popup.tooljob.autumyellowforester";
                data.AreaType    = "Khanx.AutummYellowForester";
                break;

            case 6:
                data.LocaleEntry = "popup.tooljob.darktemperateforester";
                data.AreaType    = "Khanx.DarkTemperateForester";
                break;

            case 7:
                data.LocaleEntry = "popup.tooljob.temperateforester";
                data.AreaType    = "Khanx.TemperateForester";
                break;

            case 8:
                data.LocaleEntry = "popup.tooljob.lighttemperateforester";
                data.AreaType    = "Khanx.LightTemperateForester";
                break;
            }

            data.Minimum3DBlockCount = 36;
            data.Maximum3DBlockCount = 100;
            data.Minimum2DBlockCount = 36;
            data.Maximum2DBlockCount = 100;
            data.MinimumHeight       = 1;
            data.MaximumHeight       = 3;
            data.OneAreaOnly         = true;

            AreaJobTracker.StartCommandToolSelection(player, data);
        }
Пример #20
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;
            }
        }
Пример #21
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);
            }
        }
Пример #22
0
        public static void PressButton(ButtonPressCallbackData data)
        {
            switch (data.ButtonIdentifier)
            {
            case GameLoader.NAMESPACE + ".SetScemanticName":
                NetworkMenu saveMenu = new NetworkMenu();
                saveMenu.LocalStorage.SetAs("header", _localizationHelper.LocalizeOrDefault("SaveSchematic", data.Player));
                saveMenu.Width            = 600;
                saveMenu.Height           = 300;
                saveMenu.ForceClosePopups = true;
                saveMenu.Items.Add(new Label(new LabelData(_localizationHelper.GetLocalizationKey("SaveInstructions"), UnityEngine.Color.black)));
                saveMenu.Items.Add(new InputField("Construction.SetArchitectArea"));
                saveMenu.Items.Add(new ButtonCallback(GameLoader.NAMESPACE + ".SetArchitectArea", new LabelData(_localizationHelper.GetLocalizationKey("Start"), UnityEngine.Color.black)));

                NetworkMenuManager.SendServerPopup(data.Player, saveMenu);
                break;

            case GameLoader.NAMESPACE + ".SetArchitectArea":
                NetworkMenuManager.CloseServerPopup(data.Player);
                if (data.Storage.TryGetAs("Construction.SetArchitectArea", out string schematicName))
                {
                    var colonySaves = GameLoader.Schematic_SAVE_LOC + $"\\{data.Player.ActiveColony.ColonyID}\\";

                    if (!Directory.Exists(colonySaves))
                    {
                        Directory.CreateDirectory(colonySaves);
                    }

                    var schematicFile = Path.Combine(colonySaves, schematicName + ".schematic");

                    if (File.Exists(schematicFile))
                    {
                        File.Delete(schematicFile);
                    }

                    var metaDataSave = Path.Combine(GameLoader.Schematic_SAVE_LOC, schematicName + ".schematic.metadata.json");

                    if (File.Exists(metaDataSave))
                    {
                        File.Delete(metaDataSave);
                    }

                    AreaJobTracker.StartCommandToolSelection(data.Player, new GenericCommandToolSettings()
                    {
                        Key                 = "pipliz.constructionarea",
                        TranslationKey      = _localizationHelper.LocalizeOrDefault("Architect", data.Player),
                        JSONData            = new JSONNode().SetAs(ArchitectLoader.NAME + ".ArchitectSchematicName", schematicName).SetAs("constructionType", GameLoader.NAMESPACE + ".Architect"),
                        OneAreaOnly         = true,
                        Maximum3DBlockCount = int.MaxValue,
                        Maximum2DBlockCount = int.MaxValue,
                        MaximumHeight       = int.MaxValue,
                        MinimumHeight       = 1,
                        Minimum2DBlockCount = 1,
                        Minimum3DBlockCount = 1
                    });
                }

                break;

            case GameLoader.NAMESPACE + ".ShowMainMenu":
                SendMainMenu(data.Player);
                break;

            case GameLoader.NAMESPACE + ".ShowBuildDetails":
                List <FileInfo> options = SchematicReader.GetSchematics(data.Player);
                var             index   = data.Storage.GetAs <int>(Selected_Schematic);

                if (options.Count > index)
                {
                    var selectedSchematic = options[index];

                    if (SchematicReader.TryGetSchematicMetadata(selectedSchematic.Name, data.Player.ActiveColony.ColonyID, out SchematicMetadata schematicMetadata))
                    {
                        if (schematicMetadata.Blocks.Count == 1 && schematicMetadata.Blocks.ContainsKey(ColonyBuiltIn.ItemTypes.AIR.Id))
                        {
                            PandaChat.Send(data.Player, _localizationHelper, "invlaidSchematic", ChatColor.red);
                        }
                        {
                            NetworkMenu menu = new NetworkMenu();
                            menu.Width  = 800;
                            menu.Height = 600;
                            menu.LocalStorage.SetAs("header", selectedSchematic.Name.Replace(".schematic", "") + " " + _localizationHelper.LocalizeOrDefault("Details", data.Player));

                            menu.Items.Add(new Label(new LabelData(_localizationHelper.LocalizeOrDefault("Height", data.Player) + ": " + schematicMetadata.MaxY, UnityEngine.Color.black)));
                            menu.Items.Add(new Label(new LabelData(_localizationHelper.LocalizeOrDefault("Width", data.Player) + ": " + schematicMetadata.MaxZ, UnityEngine.Color.black)));
                            menu.Items.Add(new Label(new LabelData(_localizationHelper.LocalizeOrDefault("Length", data.Player) + ": " + schematicMetadata.MaxX, UnityEngine.Color.black)));
                            menu.LocalStorage.SetAs(Selected_Schematic, selectedSchematic.Name);

                            List <ValueTuple <IItem, int> > headerItems = new List <ValueTuple <IItem, int> >();
                            headerItems.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData("  ", UnityEngine.Color.black)), 200));
                            headerItems.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData(_localizationHelper.LocalizeOrDefault("Item", data.Player), UnityEngine.Color.black)), 200));
                            headerItems.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData(_localizationHelper.LocalizeOrDefault("Required", data.Player), UnityEngine.Color.black)), 200));
                            headerItems.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData(_localizationHelper.LocalizeOrDefault("InStockpile", data.Player), UnityEngine.Color.black)), 200));
                            menu.Items.Add(new HorizontalRow(headerItems));

                            foreach (var kvp in schematicMetadata.Blocks)
                            {
                                try
                                {
                                    if (ItemTypes.TryGetType(kvp.Key, out ItemTypes.ItemType item))
                                    {
                                        var stockpileCount = 0;
                                        data.Player.ActiveColony.Stockpile.Items.TryGetValue(item.ItemIndex, out stockpileCount);

                                        List <ValueTuple <IItem, int> > items = new List <ValueTuple <IItem, int> >();
                                        items.Add(ValueTuple.Create <IItem, int>(new ItemIcon(kvp.Key), 200));
                                        items.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData(item.Name, UnityEngine.Color.black, UnityEngine.TextAnchor.MiddleLeft, 18, LabelData.ELocalizationType.Type)), 200));
                                        items.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData(" x " + kvp.Value.Count, UnityEngine.Color.black)), 200));
                                        items.Add(ValueTuple.Create <IItem, int>(new Label(new LabelData(" x " + stockpileCount, UnityEngine.Color.black)), 200));
                                        menu.Items.Add(new HorizontalRow(items));
                                    }
                                    else
                                    {
                                        SettlersLogger.Log(ChatColor.orange, "Unknown item for schematic: {0}", kvp.Key);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    SettlersLogger.LogError(ex);
                                }
                            }

                            menu.Items.Add(new DropDown(new LabelData(_localizationHelper.GetLocalizationKey("Rotation"), UnityEngine.Color.black), Selected_Schematic + ".Rotation", _rotation.Select(r => r.ToString()).ToList()));
                            menu.Items.Add(new HorizontalSplit(new ButtonCallback(GameLoader.NAMESPACE + ".ShowMainMenu", new LabelData("Back", UnityEngine.Color.black, UnityEngine.TextAnchor.MiddleCenter)),
                                                               new ButtonCallback(GameLoader.NAMESPACE + ".SetBuildArea", new LabelData("Build", UnityEngine.Color.black, UnityEngine.TextAnchor.MiddleCenter))));
                            menu.LocalStorage.SetAs(Selected_Schematic + ".Rotation", 0);

                            NetworkMenuManager.SendServerPopup(data.Player, menu);
                        }
                    }
                }

                break;

            case GameLoader.NAMESPACE + ".SetBuildArea":
                var scem     = data.Storage.GetAs <string>(Selected_Schematic);
                var rotation = data.Storage.GetAs <int>(Selected_Schematic + ".Rotation");

                SettlersLogger.Log("Schematic: {0}", scem);

                if (SchematicReader.TryGetSchematicMetadata(scem, data.Player.ActiveColony.ColonyID, out SchematicMetadata metadata))
                {
                    if (metadata.Blocks.Count == 1 && metadata.Blocks.ContainsKey(ColonyBuiltIn.ItemTypes.AIR.Id))
                    {
                        PandaChat.Send(data.Player, _localizationHelper, "invlaidSchematic", ChatColor.red);
                    }
                    {
                        _awaitingClick[data.Player] = Tuple.Create(SchematicClickType.Build, scem, _rotation[rotation]);
                        PandaChat.Send(data.Player, _localizationHelper, "instructions");
                        NetworkMenuManager.CloseServerPopup(data.Player);
                    }
                }

                break;
            }
        }
Пример #23
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);
        }
Пример #24
0
        public virtual void OnNPCAtJob(BlockJobInstance blockJobInstance, ref NPCState state)
        {
            ConstructionJobInstance instance = (ConstructionJobInstance)blockJobInstance;

            if (BlockTypes.ContainsByReference(instance.BlockType, out int index))
            {
                Vector3 rotate = instance.NPC.Position.Vector;
                switch (index)
                {
                case 1:
                    rotate.x -= 1f;
                    break;

                case 2:
                    rotate.x += 1f;
                    break;

                case 3:
                    rotate.z -= 1f;
                    break;

                case 4:
                    rotate.z += 1f;
                    break;
                }
                instance.NPC.LookAt(rotate);
            }
            if (instance.ConstructionArea != null && !instance.ConstructionArea.IsValid)
            {
                instance.ConstructionArea = null;
            }

            if (instance.ConstructionArea == null)
            {
                if (AreaJobTracker.ExistingAreaAt(instance.Position.Add(-1, -1, -1), instance.Position.Add(1, 1, 1), out List <IAreaJob> jobs))
                {
                    for (int i = 0; i < jobs.Count; i++)
                    {
                        if (jobs[i] is ConstructionArea neighbourArea)
                        {
                            instance.ConstructionArea = neighbourArea;
                            break;
                        }
                    }
                    AreaJobTracker.AreaJobListPool.Return(jobs);
                }

                if (instance.ConstructionArea == null)
                {
                    if (instance.DidAreaPresenceTest)
                    {
                        state.SetCooldown(0.5);
                        ServerManager.TryChangeBlock(instance.Position, instance.BlockType, BuiltinBlocks.Types.air, instance.Owner);
                    }
                    else
                    {
                        state.SetIndicator(new Shared.IndicatorState(Random.NextFloat(3f, 5f), BuiltinBlocks.Indices.erroridle));
                        instance.DidAreaPresenceTest = true;
                    }
                    return;
                }
            }

            Assert.IsNotNull(instance.ConstructionArea);
            instance.ConstructionArea.DoJob(instance, ref state);
        }
Пример #25
0
        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);
                }
            });
        }