Пример #1
0
 public override void OnNPCDoStockpile(ref NPCBase.NPCState state)
 {
     state.Inventory.TryDump(usedNPC.Colony.UsedStockpile);
     if (todoblocks.Count < 1)
     {
         ServerManager.TryChangeBlock(position, BlockTypes.Builtin.BuiltinBlocks.Air);
         return;
     }
     state.JobIsDone = true;
     if (!ToSleep)
     {
         shouldTakeItems = true;
         for (int i = todoblocks.Count - 1; i >= 0; i--)
         {
             BlueprintTodoBlock block = todoblocks[i];
             if (!block.typename.Equals("air"))
             {
                 ushort typeindex;
                 if (ItemTypes.IndexLookup.TryGetIndex(TypeHelper.RotatableToBasetype(block.typename), out typeindex))
                 {
                     if (usedNPC.Colony.UsedStockpile.TryRemove(typeindex, 1))
                     {
                         shouldTakeItems = false;
                         state.Inventory.Add(typeindex, 1);
                         if (state.Inventory.UsedCapacity >= state.Inventory.Capacity) // workaround for capacity issue
                         {
                             if (state.Inventory.TryGetOneItem(typeindex))
                             {
                                 usedNPC.Colony.UsedStockpile.Add(typeindex, 1);
                             }
                             return;
                         }
                     }
                 }
                 else
                 {
                     Chat.Send(usedNPC.Colony.Owner, string.Format("Bob here from site at {0}, the item type '{1}' does not exist. Ignoring it...", position, block.typename));
                     todoblocks.RemoveAt(i);
                 }
             }
             else
             {
                 shouldTakeItems = false;
             }
         }
     }
     if (todoblocks.Count < 1)
     {
         ServerManager.TryChangeBlock(position, BlockTypes.Builtin.BuiltinBlocks.Air);
         return;
     }
     else if (shouldTakeItems)
     {
         state.JobIsDone = false;
         state.SetIndicator(NPCIndicatorType.MissingItem, 6f, ItemTypes.IndexLookup.GetIndex(todoblocks[todoblocks.Count - 1].typename));
     }
 }
Пример #2
0
 public override void OnNPCAtStockpile(ref NPCBase.NPCState state)
 {
     state.Inventory.Dump(usedNPC.Colony.UsedStockpile);
     if (Todoblocks.Count < 1)
     {
         ServerManager.TryChangeBlock(position, BuiltinBlocks.Air, owner);
         return;
     }
     state.JobIsDone = true;
     if (!ToSleep)
     {
         ShouldTakeItems = true;
         for (int i = Todoblocks.Count - 1; i >= 0; i--)
         {
             BlueprintTodoBlock block = Todoblocks [i];
             if (!block.Typename.Equals("air"))
             {
                 if (LookupAndWarnItemIndex(TypeHelper.RotatableToBasetype(block.Typename), out ushort typeindex))
                 {
                     if (usedNPC.Colony.UsedStockpile.TryRemove(typeindex, 1))
                     {
                         ShouldTakeItems = false;
                         state.Inventory.Add(typeindex, 1);
                         if (state.Inventory.UsedCapacity >= state.Inventory.Capacity) // workaround for capacity issue
                         {
                             if (state.Inventory.TryGetOneItem(typeindex))
                             {
                                 usedNPC.Colony.UsedStockpile.Add(typeindex, 1);
                             }
                             return;
                         }
                     }
                 }
                 else
                 {
                     Todoblocks.RemoveAt(i);
                 }
             }
             else
             {
                 ShouldTakeItems = false;
             }
         }
     }
     if (Todoblocks.Count < 1)
     {
         ServerManager.TryChangeBlock(position, BuiltinBlocks.Air, owner);
         return;
     }
     if (ShouldTakeItems)
     {
         state.JobIsDone = false;
         state.SetIndicator(new Shared.IndicatorState(6f, ItemTypes.IndexLookup.GetIndex(Todoblocks [Todoblocks.Count - 1].Typename), true, false));
     }
 }
Пример #3
0
 public override void OnNPCAtJob(ref NPCBase.NPCState state)
 {
     state.JobIsDone = true;
     usedNPC.LookAt(position.Vector);
     if (!state.Inventory.IsEmpty)
     {
         state.Inventory.Dump(BlockInventory);
     }
     if (Todoblocks.Count < 1)
     {
         BlockInventory.Dump(usedNPC.Inventory);
         ShouldTakeItems = true;
     }
     else
     {
         bool placed = false;
         if (!ItemTypes.IndexLookup.TryGetIndex(Fullname, out ushort bluetype))
         {
             string msg = $"Bob here from site at {position}, the blueprint '{Fullname}' does not exist, stopped work here";
             Log.WriteError(msg);
             Chat.Send(usedNPC.Colony.Owner, msg);
             Todoblocks.Clear();
             return;
         }
         ushort scaffoldType = ItemTypes.IndexLookup.GetIndex(ScaffoldsModEntries.SCAFFOLD_ITEM_TYPE);
         string jobname      = TypeHelper.RotatableToBasetype(Fullname);
         for (int i = Todoblocks.Count - 1; i >= 0; i--)
         {
             BlueprintTodoBlock todoblock    = Todoblocks [i];
             Vector3Int         realPosition = todoblock.GetWorldPosition(jobname, position, bluetype);
             if (realPosition.y <= 0)
             {
                 Todoblocks.RemoveAt(i);
                 continue;
             }
             string todoblockBaseTypename    = TypeHelper.RotatableToBasetype(todoblock.Typename);
             string todoblockRotatedTypename = todoblock.Typename;
             if (!todoblockBaseTypename.Equals(todoblock.Typename))
             {
                 Vector3Int jobVec      = TypeHelper.RotatableToVector(Fullname);
                 Vector3Int blockVec    = TypeHelper.RotatableToVector(todoblock.Typename);
                 Vector3Int combinedVec = new Vector3Int(-jobVec.z * blockVec.x + jobVec.x * blockVec.z, 0, jobVec.x * blockVec.x + jobVec.z * blockVec.z);
                 todoblockRotatedTypename = todoblockBaseTypename + TypeHelper.VectorToXZ(combinedVec);
             }
             if (!LookupAndWarnItemIndex(todoblockRotatedTypename, out ushort todoblockRotatedType))
             {
                 Todoblocks.RemoveAt(i);
             }
             else if (!World.TryGetTypeAt(realPosition, out ushort actualType) || actualType == todoblockRotatedType)
             {
                 Todoblocks.RemoveAt(i);
             }
             else
             {
                 if (!LookupAndWarnItemIndex(todoblockBaseTypename, out ushort todoblockBaseType))
                 {
                     Todoblocks.RemoveAt(i);
                 }
                 else if (todoblockRotatedType == BuiltinBlocks.Air || BlockInventory.TryGetOneItem(todoblockBaseType))
                 {
                     Todoblocks.RemoveAt(i);
                     if (ServerManager.TryChangeBlock(realPosition, todoblockRotatedType, owner))
                     {
                         state.JobIsDone = true;
                         if (todoblockRotatedType == BuiltinBlocks.Air)
                         {
                             state.SetCooldown(ConstructionModEntries.EXCAVATION_DELAY);
                             state.SetIndicator(new Shared.IndicatorState(ConstructionModEntries.EXCAVATION_DELAY, actualType));
                         }
                         else if (!BlockInventory.IsEmpty && i > 0)
                         {
                             state.SetIndicator(new Shared.IndicatorState(0.5f, todoblockRotatedType));
                         }
                         if (actualType != BuiltinBlocks.Air && actualType != BuiltinBlocks.Water && actualType != scaffoldType)
                         {
                             usedNPC.Inventory.Add(ItemTypes.GetType(actualType).OnRemoveItems);
                         }
                         placed = true;
                         break;
                     }
                 }
             }
         }
         if (!placed)
         {
             BlockInventory.Dump(usedNPC.Inventory);
             ShouldTakeItems = true;
         }
     }
 }
        public static void LoadBlueprints(string blueprintsPath)
        {
            long startLoadingBlueprints = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
            Dictionary <string, string> prefixesBlueprints = new Dictionary <string, string> ();
            Dictionary <string, string> prefixesCapsules   = new Dictionary <string, string> ();

            string [] prefixFiles = Directory.GetFiles(Path.Combine(ConstructionModEntries.AssetsDirectory, "localization"), "prefixes.json", SearchOption.AllDirectories);
            foreach (string filepath in prefixFiles)
            {
                try {
                    JSONNode jsonPrefixes;
                    if (JSON.Deserialize(filepath, out jsonPrefixes, false))
                    {
                        string locName = Directory.GetParent(filepath).Name;
                        Pipliz.Log.Write($"Found prefixes localization file for '{locName}' localization");
                        string blueprintsPrefix;
                        if (jsonPrefixes.TryGetAs("blueprints", out blueprintsPrefix))
                        {
                            prefixesBlueprints [locName] = blueprintsPrefix;
                        }
                        string capsulesPrefix;
                        if (jsonPrefixes.TryGetAs("capsules", out capsulesPrefix))
                        {
                            prefixesCapsules [locName] = capsulesPrefix;
                        }
                    }
                } catch (Exception exception) {
                    Pipliz.Log.WriteError($"Exception reading localization from {filepath}; {exception.Message}");
                }
            }
            Pipliz.Log.Write($"Loading blueprints from {blueprintsPath}");
            string [] files = Directory.GetFiles(blueprintsPath, "**.json", SearchOption.AllDirectories);
            foreach (string filepath in files)
            {
                try {
                    JSONNode json;
                    if (JSON.Deserialize(filepath, out json, false))
                    {
                        string filename      = Path.GetFileName(filepath);
                        string blueprintName = Path.GetFileNameWithoutExtension(filepath).Replace(" ", "_").ToLower();
                        int    offx          = 0;
                        int    offy          = 0;
                        int    offz          = 0;
                        Dictionary <string, BlueprintTodoBlock> blocks = new Dictionary <string, BlueprintTodoBlock> ();
                        JSONNode jsonBlocks;
                        if (json.NodeType == NodeType.Object)
                        {
                            if (!json.TryGetAs("blocks", out jsonBlocks))
                            {
                                Pipliz.Log.WriteError($"Expected 'blocks' key in json {filename}");
                                continue;
                            }
                            JSONNode jsonOffset;
                            if (json.TryGetAs("offset", out jsonOffset))
                            {
                                offx = -jsonOffset.GetAs <int> ("x");
                                offy = -jsonOffset.GetAs <int> ("y");
                                offz = -jsonOffset.GetAs <int> ("z");
                            }
                            JSONNode jsonLocalization;
                            if (json.TryGetAs("localization", out jsonLocalization))
                            {
                                foreach (KeyValuePair <string, JSONNode> locEntry in jsonLocalization.LoopObject())
                                {
                                    string labelPrefix;
                                    string capsulePrefix;
                                    if (prefixesBlueprints.TryGetValue(locEntry.Key, out labelPrefix))
                                    {
                                        labelPrefix = labelPrefix.Trim();
                                    }
                                    else
                                    {
                                        labelPrefix = "Blueprint";
                                    }
                                    if (prefixesCapsules.TryGetValue(locEntry.Key, out capsulePrefix))
                                    {
                                        capsulePrefix = capsulePrefix.Trim();
                                    }
                                    else
                                    {
                                        capsulePrefix = "Emperor Capsule";
                                    }
                                    string   label = ((string)locEntry.Value.BareObject).Trim();
                                    JSONNode locNode;
                                    if (!BlueprintsLocalizations.TryGetValue(locEntry.Key, out locNode))
                                    {
                                        locNode = new JSONNode().SetAs <JSONNode> ("types", new JSONNode());
                                        BlueprintsLocalizations.Add(locEntry.Key, locNode);
                                    }
                                    locNode.GetAs <JSONNode> ("types").SetAs(blueprintName, labelPrefix + " " + label);
                                    locNode.GetAs <JSONNode> ("types").SetAs(blueprintName + CapsulesModEntries.CAPSULE_SUFFIX, capsulePrefix + " " + label);
                                }
                            }
                        }
                        else
                        {
                            jsonBlocks = json; // fallback everything is an array
                            Pipliz.Log.Write($"No json object defined in '{filename}', using full content as blocks array");
                            int maxx = 0, maxy = 0, maxz = 0;
                            foreach (JSONNode node in jsonBlocks.LoopArray())
                            {
                                int x = getJSONInt(node, "startx", "x", 0, false);
                                if (x < offx)
                                {
                                    offx = x;
                                }
                                if (x > maxx)
                                {
                                    maxx = x;
                                }
                                int y = getJSONInt(node, "starty", "y", 0, false);
                                if (y < offy)
                                {
                                    offy = y;
                                }
                                if (y > maxy)
                                {
                                    maxy = y;
                                }
                                int z = getJSONInt(node, "startz", "z", 0, false);
                                if (z < offz)
                                {
                                    offz = z;
                                }
                                if (z > maxz)
                                {
                                    maxz = z;
                                }
                            }
                            for (int x = 0; x <= -offx + maxx; x++) // add auto-clear area
                            {
                                for (int y = 0; y <= -offz + maxy; y++)
                                {
                                    for (int z = 0; z <= -offz + maxz; z++)
                                    {
                                        blocks [$"{x}?{y}?{z}"] = new BlueprintTodoBlock(x, y, z, "air");
                                    }
                                }
                            }
                        }
                        BlueprintTodoBlock originBlock = null;
                        foreach (JSONNode node in jsonBlocks.LoopArray())
                        {
                            int    startx = getJSONInt(node, "startx", "x", 0, false);
                            int    starty = getJSONInt(node, "starty", "y", 0, false);
                            int    startz = getJSONInt(node, "startz", "z", 0, false);
                            string typename;
                            if (!node.TryGetAs("typename", out typename))
                            {
                                if (!node.TryGetAs("t", out typename))
                                {
                                    throw new Exception($"typename not defined or not a string");
                                }
                            }
                            if (typename.EndsWith("x+"))
                            {
                                typename = typename.Substring(0, typename.Length - 2) + "x-";
                            }
                            else if (typename.EndsWith("x-"))
                            {
                                typename = typename.Substring(0, typename.Length - 2) + "x+";
                            }
                            int width = getJSONInt(node, "width", "w", 1, true);
                            int height = getJSONInt(node, "height", "h", 1, true);
                            int depth = getJSONInt(node, "depth", "d", 1, true);
                            int dx = 1, dy = 1, dz = 1;
                            if (width < 0)
                            {
                                dx = -1;
                            }
                            if (height < 0)
                            {
                                dy = -1;
                            }
                            if (depth < 0)
                            {
                                dz = -1;
                            }
                            for (int x = startx; x *dx < (startx + width) * dx; x += dx)
                            {
                                for (int y = starty; y *dy < (starty + height) * dy; y += dy)
                                {
                                    for (int z = startz; z *dz < (startz + depth) * dz; z += dz)
                                    {
                                        int absX = x - offx, absY = y - offy, absZ = z - offz;
                                        BlueprintTodoBlock b = new BlueprintTodoBlock(absX, absY, absZ, typename);
                                        if (absX == 0 && absY == 0 && absZ == -1) // do not replace the blueprint box itself (yet)
                                        {
                                            originBlock = b;
                                        }
                                        else
                                        {
                                            blocks [$"{absX}?{absY}?{absZ}"] = b;
                                        }
                                    }
                                }
                            }
                        }
                        if (originBlock != null)
                        {
                            blocks [$"{0}?{0}?{-1}"] = originBlock;
                        }
                        Blueprints.Add(BLUEPRINTS_PREFIX + blueprintName, blocks.Values.ToList());
                        Pipliz.Log.Write($"Added blueprint '{BLUEPRINTS_PREFIX + blueprintName}' with {blocks.Count} blocks from {filename}");
                    }
                } catch (Exception exception) {
                    Pipliz.Log.WriteError($"Exception while loading from {filepath}; {exception.Message}");
                }
            }
            Pipliz.Log.Write($"Loaded blueprints in {DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond - startLoadingBlueprints} ms");
        }
Пример #5
0
 public override void OnNPCDoJob(ref NPCBase.NPCState state)
 {
     state.JobIsDone = true;
     usedNPC.LookAt(position.Vector);
     if (!state.Inventory.IsEmpty)
     {
         state.Inventory.Dump(blockInventory);
     }
     if (todoblocks.Count < 1)
     {
         blockInventory.Dump(usedNPC.Inventory);
         shouldTakeItems = true;
     }
     else
     {
         bool   placed       = false;
         ushort bluetype     = ItemTypes.IndexLookup.GetIndex(fullname);
         ushort scaffoldType = ItemTypes.IndexLookup.GetIndex(ScaffoldsModEntries.SCAFFOLD_ITEM_TYPE);
         string jobname      = fullname.Substring(0, fullname.Length - 2);
         for (int i = todoblocks.Count - 1; i >= 0; i--)
         {
             BlueprintTodoBlock todoblock    = todoblocks[i];
             Vector3Int         realPosition = todoblock.GetWorldPosition(jobname, position, bluetype);
             if (realPosition.y <= 0)
             {
                 todoblocks.RemoveAt(i);
                 continue;
             }
             ushort newType = ItemTypes.IndexLookup.GetIndex(todoblock.typename);
             ushort actualType;
             if (World.TryGetTypeAt(realPosition, out actualType) && actualType != newType)
             {
                 ushort baseType = ItemTypes.IndexLookup.GetIndex(TypeHelper.RotatableToBasetype(todoblock.typename));
                 if (newType == BlockTypes.Builtin.BuiltinBlocks.Air || blockInventory.TryGetOneItem(baseType))
                 {
                     todoblocks.RemoveAt(i);
                     if (ServerManager.TryChangeBlock(realPosition, newType, ServerManager.SetBlockFlags.DefaultAudio))
                     {
                         state.JobIsDone = true;
                         if (newType == BlockTypes.Builtin.BuiltinBlocks.Air)
                         {
                             OverrideCooldown(ConstructionModEntries.EXCAVATION_DELAY);
                             state.SetIndicator(NPCIndicatorType.MissingItem, ConstructionModEntries.EXCAVATION_DELAY, actualType);
                         }
                         else if (!blockInventory.IsEmpty && i > 0)
                         {
                             state.SetIndicator(NPCIndicatorType.Crafted, TimeBetweenJobs, ItemTypes.IndexLookup.GetIndex(todoblocks[i].typename));
                         }
                         if (actualType != BlockTypes.Builtin.BuiltinBlocks.Air && actualType != scaffoldType)
                         {
                             usedNPC.Inventory.Add(ItemTypes.RemovalItems(actualType));
                         }
                         placed = true;
                         break;
                     }
                 }
             }
             else
             {
                 todoblocks.RemoveAt(i);
             }
         }
         if (!placed)
         {
             blockInventory.Dump(usedNPC.Inventory);
             shouldTakeItems = true;
         }
     }
 }