コード例 #1
0
ファイル: RecipedBlockMod.cs プロジェクト: OmegaRogue/Nuterra
        public void RegisterRecipe()
        {
            List <RecipeTable.Recipe> GSORecipes = new List <RecipeTable.Recipe>();

            foreach (var list in RecipeManager.inst.recipeTable.m_RecipeLists)
            {
                if (list.m_Name == "gsofab")
                {
                    GSORecipes = list.m_Recipes;
                }
            }


            var Bacon = new RecipeTable.Recipe()
            {
                m_BuildTimeSeconds = 1,
                m_InputItems       = new RecipeTable.Recipe.ItemSpec[]
                {
                    new RecipeTable.Recipe.ItemSpec(new ItemTypeInfo(ObjectTypes.Chunk, (int)ChunkTypes.OleiteJelly), 4),
                    new RecipeTable.Recipe.ItemSpec(new ItemTypeInfo(ObjectTypes.Chunk, (int)ChunkTypes.Wood), 4)
                },
                m_OutputType  = RecipeTable.Recipe.OutputType.Items,
                m_OutputItems = new RecipeTable.Recipe.ItemSpec[]
                {
                    new RecipeTable.Recipe.ItemSpec(new ItemTypeInfo(ObjectTypes.Block, 10000), 1)
                }
            };

            GSORecipes.Add(Bacon);
        }
コード例 #2
0
        internal static void RegisterRecipe(CustomRecipeStruct customRecipe)
        {
            List <RecipeTable.Recipe> recipeList = null;
            var recipeTable = Singleton.Manager <RecipeManager> .inst.recipeTable;

            foreach (RecipeTable.RecipeList list in recipeTable.m_RecipeLists)
            {
                if (list.m_Name == customRecipe.NameOfFabricator)
                {
                    recipeList = list.m_Recipes;
                    break;
                }
            }

            if (recipeList == null)
            {
                Console.WriteLine("Creating new recipe table '" + customRecipe.NameOfFabricator + "'...");
                recipeList = new List <RecipeTable.Recipe>();
                var NewRecipeItem = new RecipeTable.RecipeList()
                {
                    m_Name    = customRecipe.NameOfFabricator,
                    m_Recipes = recipeList,
                };
                recipeTable.m_RecipeLists.Add(NewRecipeItem);
            }

            var InputItems = new RecipeTable.Recipe.ItemSpec[customRecipe.Inputs.Length];

            for (int i = 0; i < customRecipe.Inputs.Length; i++)
            {
                InputItems[i] = customRecipe.Inputs[i].ItemSpec();
            }

            var OutputItems = new RecipeTable.Recipe.ItemSpec[customRecipe.Outputs.Length];

            for (int j = 0; j < customRecipe.Outputs.Length; j++)
            {
                OutputItems[j] = customRecipe.Outputs[j].ItemSpec();
            }

            var Recipe = new RecipeTable.Recipe()
            {
                m_BuildTimeSeconds = customRecipe.BuildTime,
                m_InputItems       = InputItems,
                m_OutputType       = customRecipe.OutputType,
                m_OutputItems      = OutputItems
            };

            recipeList.Add(Recipe);
        }
コード例 #3
0
        // This method should add a module to the TankBlock prefab
        public override bool CreateModuleForBlock(int blockID, ModdedBlockDefinition def, TankBlock block, JToken jToken)
        {
            try
            {
                Debug.Log("[Nuterra] Loading CustomBlock module");

                if (jToken.Type == JTokenType.Object)
                {
                    JObject jData = (JObject)jToken;

                    // Get the mod contents so we can search for additional assets
                    ModContainer container = ManMods.inst.FindMod(def);
                    ModContents  mod       = container != null ? container.Contents : null;
                    if (mod == null)
                    {
                        Debug.LogError("[Nuterra] Could not find mod that this unoffical block is part of");
                        return(false);
                    }

                    // ------------------------------------------------------
                    // Basics like name, desc etc. The Official Mod Tool lets us set these already, but we might want to override
                    def.m_BlockDisplayName = TryParse(jData, "Name", def.m_BlockDisplayName);
                    def.m_BlockDescription = TryParse(jData, "Description", def.m_BlockDescription);
                    // Ignore block ID. Official loader handles IDs automatically.
                    // Ignore corporation. Custom corps no longer have a fixed ID, so we should use the official tool to set corp IDs.
                    //def.m_Corporation = TryParse(jData, "Corporation", def.m_Corporation);
                    block.m_BlockCategory = def.m_Category = TryParseEnum(jData, "Category", def.m_Category);
                    def.m_Rarity          = TryParseEnum(jData, "Rarity", def.m_Rarity);
                    def.m_Grade           = TryParse(jData, "Grade", def.m_Grade);

                    // Recipe
                    if (jData.TryGetValue("Recipe", out JToken jRecipe))
                    {
                        RecipeTable.Recipe recipe = new RecipeTable.Recipe();
                        Dictionary <ChunkTypes, RecipeTable.Recipe.ItemSpec> dictionary = new Dictionary <ChunkTypes, RecipeTable.Recipe.ItemSpec>();

                        int RecipePrice = 0;
                        if (jRecipe is JValue rString)
                        {
                            string[] recipeString = rString.ToObject <string>().Replace(" ", "").Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string item in recipeString)
                            {
                                RecipePrice += AppendToRecipe(dictionary, item, 1);
                            }
                        }
                        else if (jRecipe is JObject rObject)
                        {
                            foreach (var item in rObject)
                            {
                                RecipePrice += AppendToRecipe(dictionary, item.Key, item.Value.ToObject <int>());
                            }
                        }
                        else if (jRecipe is JArray rArray)
                        {
                            foreach (var item in rArray)
                            {
                                RecipePrice += AppendToRecipe(dictionary, item.ToString(), 1);
                            }
                        }


                        recipe.m_InputItems = new RecipeTable.Recipe.ItemSpec[dictionary.Count];
                        dictionary.Values.CopyTo(recipe.m_InputItems, 0);
                        recipe.m_OutputItems[0] = new RecipeTable.Recipe.ItemSpec(new ItemTypeInfo(ObjectTypes.Block, blockID), 1);
                        Singleton.Manager <RecipeManager> .inst.RegisterCustomBlockFabricatorRecipe(blockID, def.m_Corporation, recipe);

                        def.m_Price = RecipePrice;
                    }
                    // TODO: RecipeTable

                    def.m_Price     = TryParseEnum(jData, "Price", def.m_Price);
                    def.m_MaxHealth = TryParse(jData, "HP", def.m_MaxHealth);

                    // ------------------------------------------------------
                    #region Reference - Copy a vanilla block
                    Debug.Log("[Nuterra] Starting references");
                    bool keepRenderers          = TryParse(jData, "KeepRenderers", true);
                    bool keepReferenceRenderers = TryParse(jData, "KeepReferenceRenderers", true);
                    bool keepColliders          = TryParse(jData, "KeepColliders", true);

                    if (TryGetStringMultipleKeys(jData, out string referenceBlock, "GamePrefabReference", "PrefabReference"))
                    {
                        // This code block copies our chosen reference block
                        // TTQMM REF: BlockPrefabBuilder.Initialize

                        GameObject originalGameObject = TTReferences.FindBlockFromString(referenceBlock);
                        if (originalGameObject != null)
                        {
                            GameObject newObject = UnityEngine.Object.Instantiate(originalGameObject);
                            // Assign this back to block for further processing
                            block = GetOrAddComponent <TankBlock>(newObject.transform);
                            //TankBlock original = originalGameObject.GetComponent<TankBlock>();
                            //TankBlock copy = UnityEngine.Object.Instantiate(original);
                            TankBlockTemplate fakeTemplate = newObject.AddComponent <TankBlockTemplate>();
                            // Cheeky hack to swap the prefab
                            // The official block loader doesn't expect this to happen, but I will assume
                            // for now that you are making 100% official or 100% unofficial JSONs
                            def.m_PhysicalPrefab = fakeTemplate;

                            Debug.Log($"[Nuterra] Found game prefab reference as {newObject}");

                            // TTQMM REF: DirectoryBlockLoader.CreateJSONBlock, the handling of these flags is a bit weird
                            if (keepRenderers && !keepColliders)
                            {
                                RemoveChildren <Collider>(block);
                            }
                            if (!keepRenderers && !keepReferenceRenderers)
                            {
                                RemoveChildren <MeshRenderer>(block);
                                RemoveChildren <TankTrack>(block);
                                RemoveChildren <SkinnedMeshRenderer>(block);
                                RemoveChildren <MeshFilter>(block);

                                if (!keepColliders)
                                {
                                    RemoveChildren <Collider>(block);
                                }
                            }

                            newObject.layer = Globals.inst.layerTank;
                            newObject.tag   = "TankBlock";


                            bool hasRefOffset   = TryGetTokenMultipleKeys(jData, out JToken jOffset, "ReferenceOffset", "PrefabOffset", "PrefabPosition");
                            bool hasRefRotation = TryGetTokenMultipleKeys(jData, out JToken jEuler, "ReferenceRotationOffset", "PrefabRotation");
                            bool hasRefScale    = TryGetTokenMultipleKeys(jData, out JToken jScale, "ReferenceScale", "PrefabScale");

                            if (hasRefOffset || hasRefRotation || hasRefScale)
                            {
                                Vector3 offset = hasRefOffset ? GetVector3(jOffset) : Vector3.zero;
                                Vector3 scale  = hasRefScale ? GetVector3(jScale) : Vector3.one;
                                Vector3 euler  = hasRefRotation ? GetVector3(jEuler) : Vector3.zero;

                                foreach (Transform child in newObject.transform)
                                {
                                    if (hasRefOffset)
                                    {
                                        child.localPosition += offset;
                                    }
                                    if (hasRefRotation)
                                    {
                                        child.localEulerAngles += euler;
                                    }
                                    if (hasRefScale)
                                    {
                                        child.localScale += scale;
                                    }
                                }
                            }
                        }
                        else
                        {
                            Debug.LogError($"[Nuterra] Failed to find GamePrefabReference {referenceBlock}");
                        }
                    }
                    #endregion
                    // ------------------------------------------------------

                    // ------------------------------------------------------
                    // Get some references set up for the next phase, now our prefab is setup
                    Damageable   damageable   = GetOrAddComponent <Damageable>(block);
                    ModuleDamage moduleDamage = GetOrAddComponent <ModuleDamage>(block);
                    Visible      visible      = GetOrAddComponent <Visible>(block);
                    Transform    transform    = block.transform;
                    transform.position   = Vector3.zero;
                    transform.rotation   = Quaternion.identity;
                    transform.localScale = Vector3.one;

                    // ------------------------------------------------------
                    #region Additional References
                    if (TryGetStringMultipleKeys(jData, out string referenceExplosion, "DeathExplosionReference", "ExplosionReference"))
                    {
                        GameObject refBlock = TTReferences.FindBlockFromString(referenceExplosion);
                        if (refBlock != null)
                        {
                            moduleDamage.deathExplosion = refBlock.GetComponent <ModuleDamage>().deathExplosion;
                            Debug.Log($"[Nuterra] Swapped death explosion for {refBlock}");
                        }
                    }
                    #endregion
                    // ------------------------------------------------------

                    // ------------------------------------------------------
                    #region Tweaks
                    // BlockExtents is a way of quickly doing a cuboid Filled Cell setup
                    if (jData.TryGetValue("BlockExtents", out JToken jExtents) && jExtents.Type == JTokenType.Object)
                    {
                        List <IntVector3> filledCells = new List <IntVector3>();
                        int x = ((JObject)jExtents).GetValue("x").ToObject <int>();
                        int y = ((JObject)jExtents).GetValue("y").ToObject <int>();
                        int z = ((JObject)jExtents).GetValue("z").ToObject <int>();
                        for (int i = 0; i < x; i++)
                        {
                            for (int j = 0; j < y; j++)
                            {
                                for (int k = 0; k < z; k++)
                                {
                                    filledCells.Add(new IntVector3(i, j, k));
                                }
                            }
                        }
                        block.filledCells = filledCells.ToArray();
                        Debug.Log("[Nuterra] Overwrote BlockExtents");
                    }
                    // CellMap / CellsMap
                    if (TryGetTokenMultipleKeys(jData, out JToken jCellMap, "CellMap", "CellsMap"))
                    {
                        string[][]        ZYXCells = jCellMap.ToObject <string[][]>();
                        List <IntVector3> cells    = new List <IntVector3>();
                        for (int z = 0; z < ZYXCells.Length; z++)
                        {
                            string[] YXslice = ZYXCells[z];
                            if (YXslice == null)
                            {
                                continue;
                            }

                            for (int y = 0, ry = YXslice.Length - 1; ry >= 0; y++, ry--)
                            {
                                string Xline = YXslice[ry];
                                if (Xline == null)
                                {
                                    continue;
                                }

                                for (int x = 0; x < Xline.Length; x++)
                                {
                                    char cell = Xline[x];
                                    if (cell != ' ')
                                    {
                                        cells.Add(new IntVector3(x, y, z));
                                    }
                                }
                            }
                        }
                        block.filledCells = cells.ToArray();
                    }
                    // TODO: APsOnlyAtBottom / MakeAPsAtBottom
                    if (jData.TryGetValue("Cells", out JToken jCells) && jCells.Type == JTokenType.Array)
                    {
                        List <IntVector3> filledCells = new List <IntVector3>();
                        foreach (JObject jCell in (JArray)jCells)
                        {
                            filledCells.Add(GetVector3Int(jCell));
                        }
                        block.filledCells = filledCells.ToArray();
                    }
                    // APs
                    if (jData.TryGetValue("APs", out JToken jAPList) && jAPList.Type == JTokenType.Array)
                    {
                        List <Vector3> aps = new List <Vector3>();
                        foreach (JToken token in (JArray)jAPList)
                        {
                            aps.Add(GetVector3(token));
                        }
                        block.attachPoints = aps.ToArray();
                    }
                    // Some basic block stats
                    damageable.DamageableType = (ManDamage.DamageableType)TryParse(jData, "DamageableType", (int)damageable.DamageableType);
                    if (TryGetFloatMultipleKeys(jData, out float fragility, moduleDamage.m_DamageDetachFragility, "DetachFragility", "Fragility"))
                    {
                        moduleDamage.m_DamageDetachFragility = fragility;
                    }

                    block.m_DefaultMass = TryParse(jData, "Mass", block.m_DefaultMass);

                    // Center of Mass
                    JArray jComVector = null;
                    if (jData.TryGetValue("CenterOfMass", out JToken com1) && com1.Type == JTokenType.Array)
                    {
                        jComVector = (JArray)com1;
                    }
                    if (jData.TryGetValue("CentreOfMass ", out JToken com2) && com2.Type == JTokenType.Array)
                    {
                        jComVector = (JArray)com2;
                    }
                    if (jComVector != null)
                    {
                        Transform comTrans = block.transform.Find("CentreOfMass");
                        if (comTrans == null)
                        {
                            comTrans = new GameObject("CentreOfMass").transform;
                            comTrans.SetParent(block.transform);
                            comTrans.localScale    = Vector3.one;
                            comTrans.localRotation = Quaternion.identity;
                        }
                        comTrans.localPosition = new Vector3(jComVector[0].ToObject <float>(), jComVector[1].ToObject <float>(), jComVector[2].ToObject <float>());

                        // TODO: Weird thing about offseting colliders from Nuterra
                        //for (int i = 0; i < Prefab.transform.childCount; i++)
                        //{
                        //	transform = Prefab.transform.GetChild(i);
                        //	if (transform.name.Length < 5 && transform.name.EndsWith("col")) // "[a-z]col"
                        //		transform.localPosition = CenterOfMass;
                        //}
                    }

                    // TODO: RotationGroup

                    // IconName override
                    if (jData.TryGetValue("IconName", out JToken jIconName) && jIconName.Type == JTokenType.String)
                    {
                        UnityEngine.Object obj = mod.FindAsset(jIconName.ToString());
                        if (obj != null)
                        {
                            if (obj is Sprite sprite)
                            {
                                def.m_Icon = sprite.texture;
                            }
                            else if (obj is Texture2D texture)
                            {
                                def.m_Icon = texture;
                            }
                            else
                            {
                                Debug.LogWarning($"Found unknown object type {obj.GetType()} for icon override for {block.name}");
                            }
                        }
                    }

                    // TODO: Emission Mode
                    // Filepath? For reparse?
                    #endregion
                    // ------------------------------------------------------

                    // Start recursively adding objects with the root.
                    // Calling it this way and treating the root as a sub-object prevents a lot of code duplication
                    RecursivelyAddSubObject(block, mod, block.transform, jData, TTReferences.kMissingTextureTankBlock, false);

                    // Weird export fix up for meshes
                    // Flip everything in x
                    foreach (MeshRenderer mr in block.GetComponentsInChildren <MeshRenderer>())
                    {
                        mr.transform.localScale = new Vector3(-mr.transform.localScale.x, mr.transform.localScale.y, mr.transform.localScale.z);
                    }
                    foreach (MeshCollider mc in block.GetComponentsInChildren <MeshCollider>())
                    {
                        if (mc.GetComponent <MeshRenderer>() == null)                       // Skip ones with both. Don't want to double flip
                        {
                            mc.transform.localScale = new Vector3(-mc.transform.localScale.x, mc.transform.localScale.y, mc.transform.localScale.z);
                        }
                    }

                    return(true);
                }
                return(false);
            }
            catch (Exception e)
            {
                Debug.LogError($"[Nuterra] Caught exception {e}");
                return(false);
            }
        }