public override void OnReceivedClientPacket(IPlayer player, int packetid, byte[] data)
        {
            if (packetid == (int)EnumAnvilPacket.SelectRecipe)
            {
                int            recipeid = SerializerUtil.Deserialize <int>(data);
                SmithingRecipe recipe   = api.World.SmithingRecipes.FirstOrDefault(r => r.RecipeId == recipeid);

                if (recipe == null)
                {
                    api.World.Logger.Error("Client tried to selected smithing recipe with id {0}, but no such recipe exists!");
                    return;
                }

                selectedRecipeId = recipe.RecipeId;

                // Tell server to save this chunk to disk again
                MarkDirty();
                api.World.BlockAccessor.GetChunkAtBlockPos(pos.X, pos.Y, pos.Z).MarkModified();
            }

            if (packetid == (int)EnumAnvilPacket.OnUserOver)
            {
                Vec3i voxelPos;
                using (MemoryStream ms = new MemoryStream(data))
                {
                    BinaryReader reader = new BinaryReader(ms);
                    voxelPos = new Vec3i(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                }

                OnUseOver(player, voxelPos, new BlockSelection()
                {
                    Position = pos
                });
            }
        }
Exemple #2
0
        private Vec3i findFreeMetalVoxel()
        {
            SmithingRecipe recipe = SelectedRecipe;

            int ymax = recipe.QuantityLayers;

            for (int y = 5; y >= 0; y--)
            {
                for (int z = 0; z < 16; z++)
                {
                    for (int x = 0; x < 16; x++)
                    {
                        bool requireMetalHere = y >= ymax ? false : recipe.Voxels[x, y, z];
                        EnumVoxelMaterial mat = (EnumVoxelMaterial)Voxels[x, y, z];

                        if (!requireMetalHere && mat == EnumVoxelMaterial.Metal)
                        {
                            return(new Vec3i(x, y, z));
                        }
                    }
                }
            }

            return(null);
        }
Exemple #3
0
        private int FindSmithingRecipeNumber(int num)
        {
            baseMaterial = new ItemStack(api.World.GetItem(new AssetLocation("ingot-" + workItemStack.Collectible.LastCodePart())));

            SmithingRecipe recipe = api.World.SmithingRecipes
                                    .Where(r => r.Ingredient.SatisfiesAsIngredient(baseMaterial))
                                    .OrderBy(r => r.Output.ResolvedItemstack.GetName())
                                    .ElementAtOrDefault(num)
            ;

            return(new List <SmithingRecipe>(api.World.SmithingRecipes).IndexOf(recipe));
        }
Exemple #4
0
        public override void GetHeldItemInfo(ItemSlot inSlot, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo)
        {
            base.GetHeldItemInfo(inSlot, dsc, world, withDebugInfo);

            int            recipeId = inSlot.Itemstack.Attributes.GetInt("selectedRecipeId");
            SmithingRecipe recipe   = api.World.SmithingRecipes.FirstOrDefault(r => r.RecipeId == recipeId);

            if (recipe == null)
            {
                dsc.AppendLine("Unknown work item");
                return;
            }

            dsc.AppendLine(Lang.Get("Unfinished {0}", recipe.Output.ResolvedItemstack.GetName()));
        }
Exemple #5
0
        internal string PrintDebugText()
        {
            SmithingRecipe recipe = SelectedRecipe;


            EnumHelveWorkableMode?mode = (workItemStack?.Collectible as IAnvilWorkable)?.GetHelveWorkableMode(workItemStack, this);

            StringBuilder sb = new StringBuilder();

            sb.AppendLine("Workitem: " + workItemStack);
            sb.AppendLine("Recipe: " + recipe?.Name);
            sb.AppendLine("Matches recipe: " + MatchesRecipe());
            sb.AppendLine("Helve Workable: " + mode);

            return(sb.ToString());
        }
        public override void GetHeldItemInfo(ItemSlot inSlot, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo)
        {
            base.GetHeldItemInfo(inSlot, dsc, world, withDebugInfo);

            int selectedRecipeNumber = inSlot.Itemstack.Attributes.GetInt("selectedRecipeNumber");

            if (selectedRecipeNumber < 0 || selectedRecipeNumber >= world.SmithingRecipes.Count)
            {
                dsc.AppendLine("Unknown work item");
                return;
            }

            SmithingRecipe smithRecipe = world.SmithingRecipes[selectedRecipeNumber];

            dsc.AppendLine(Lang.Get("Unfinished {0}", smithRecipe.Output.ResolvedItemstack.GetName()));
        }
Exemple #7
0
        public override void GetHeldItemInfo(ItemStack stack, StringBuilder dsc, IWorldAccessor world, bool withDebugInfo)
        {
            base.GetHeldItemInfo(stack, dsc, world, withDebugInfo);

            int selectedRecipeNumber = stack.Attributes.GetInt("selectedRecipeNumber");

            if (selectedRecipeNumber < 0 || selectedRecipeNumber >= world.SmithingRecipes.Length)
            {
                dsc.AppendLine("Unknown work item");
                return;
            }

            SmithingRecipe smithRecipe = world.SmithingRecipes[selectedRecipeNumber];

            dsc.AppendLine("Unfinished " + smithRecipe.Name);
        }
Exemple #8
0
        private void RegenOutlineMesh(SmithingRecipe recipeToOutline)
        {
            recipeOutlineMeshRef?.Dispose();

            MeshData recipeOutlineMesh = new MeshData(24, 36, false, false, true, false, false);

            recipeOutlineMesh.SetMode(EnumDrawMode.Lines);

            MeshData voxelMesh = LineMeshUtil.GetCube((180 << 24) | (100 << 16) | (200 << 8) | (200));

            for (int i = 0; i < voxelMesh.xyz.Length; i++)
            {
                voxelMesh.xyz[i] = voxelMesh.xyz[i] / 32f + 1 / 32f;
            }
            MeshData voxelMeshOffset = voxelMesh.Clone();

            for (int x = 0; x < 16; x++)
            {
                int y = 10;
                for (int z = 0; z < 16; z++)
                {
                    if (!recipeToOutline.Voxels[x, z])
                    {
                        continue;
                    }

                    float px = x / 16f;
                    float py = y / 16f;
                    float pz = z / 16f;

                    for (int i = 0; i < voxelMesh.xyz.Length; i += 3)
                    {
                        voxelMeshOffset.xyz[i]     = px + voxelMesh.xyz[i];
                        voxelMeshOffset.xyz[i + 1] = py + voxelMesh.xyz[i + 1];
                        voxelMeshOffset.xyz[i + 2] = pz + voxelMesh.xyz[i + 2];
                    }

                    recipeOutlineMesh.AddMeshData(voxelMeshOffset);
                }
            }

            recipeOutlineMeshRef = api.Render.UploadMesh(recipeOutlineMesh);
        }
        public void RegenMesh(ItemStack ingot, bool[,,] Voxels, SmithingRecipe recipeToOutline)
        {
            if (workItemMeshRef != null)
            {
                api.Render.DeleteMesh(workItemMeshRef);
                workItemMeshRef = null;
            }

            if (ingot == null)
            {
                return;
            }

            if (recipeToOutline != null)
            {
                RegenOutlineMesh(recipeToOutline);
            }

            this.ingot = ingot;
            MeshData workItemMesh = new MeshData(24, 36, false);

            TextureAtlasPosition tpos      = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("ingotpile")), ingot.Collectible.LastCodePart());
            MeshData             voxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f));

            texId = tpos.atlasTextureId;

            for (int i = 0; i < voxelMesh.Uv.Length; i++)
            {
                voxelMesh.Uv[i] = (i % 2 > 0 ? tpos.y1 : tpos.x1) + voxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size;
            }

            voxelMesh.XyzFaces      = (int[])CubeMeshUtil.CubeFaceIndices.Clone();
            voxelMesh.XyzFacesCount = 6;
            voxelMesh.Tints         = new int[6];
            voxelMesh.Flags         = new int[24];
            voxelMesh.TintsCount    = 6;
            for (int i = 0; i < voxelMesh.Rgba.Length; i++)
            {
                voxelMesh.Rgba[i] = 255;
            }
            voxelMesh.Rgba2 = voxelMesh.Rgba;


            MeshData voxelMeshOffset = voxelMesh.Clone();

            for (int x = 0; x < 16; x++)
            {
                for (int y = 10; y < 16; y++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        if (!Voxels[x, y, z])
                        {
                            continue;
                        }

                        float px = x / 16f;
                        float py = y / 16f;
                        float pz = z / 16f;

                        for (int i = 0; i < voxelMesh.xyz.Length; i += 3)
                        {
                            voxelMeshOffset.xyz[i]     = px + voxelMesh.xyz[i];
                            voxelMeshOffset.xyz[i + 1] = py + voxelMesh.xyz[i + 1];
                            voxelMeshOffset.xyz[i + 2] = pz + voxelMesh.xyz[i + 2];
                        }

                        float offsetX = (px * 32f) / api.BlockTextureAtlas.Size;
                        float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size;

                        for (int i = 0; i < voxelMesh.Uv.Length; i += 2)
                        {
                            voxelMeshOffset.Uv[i]     = voxelMesh.Uv[i] + offsetX;
                            voxelMeshOffset.Uv[i + 1] = voxelMesh.Uv[i + 1] + offsetZ;
                        }

                        workItemMesh.AddMeshData(voxelMeshOffset);
                    }
                }
            }

            workItemMeshRef = api.Render.UploadMesh(workItemMesh);
        }
Exemple #10
0
        public virtual void OnHelveHammerHit()
        {
            if (workItemStack == null || !CanWorkCurrent)
            {
                return;
            }

            SmithingRecipe recipe = SelectedRecipe;

            if (recipe == null)
            {
                return;
            }

            var mode = (workItemStack.Collectible as IAnvilWorkable).GetHelveWorkableMode(workItemStack, this);

            if (mode == EnumHelveWorkableMode.NotWorkable)
            {
                return;
            }

            rotation = 0;
            int   ymax = recipe.QuantityLayers;
            Vec3i usableMetalVoxel;

            if (mode == EnumHelveWorkableMode.TestSufficientVoxelsWorkable)
            {
                usableMetalVoxel = findFreeMetalVoxel();

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int y = 0; y < 6; y++)
                        {
                            bool requireMetalHere = y >= ymax ? false : recipe.Voxels[x, y, z];

                            EnumVoxelMaterial mat = (EnumVoxelMaterial)Voxels[x, y, z];

                            if (mat == EnumVoxelMaterial.Slag)
                            {
                                Voxels[x, y, z] = (byte)EnumVoxelMaterial.Empty;
                                onHelveHitSuccess(mat, null, x, y, z);
                                return;
                            }

                            if (requireMetalHere && usableMetalVoxel != null && mat == EnumVoxelMaterial.Empty)
                            {
                                Voxels[x, y, z] = (byte)EnumVoxelMaterial.Metal;
                                Voxels[usableMetalVoxel.X, usableMetalVoxel.Y, usableMetalVoxel.Z] = (byte)EnumVoxelMaterial.Empty;

                                onHelveHitSuccess(mat, usableMetalVoxel, x, y, z);
                                return;
                            }
                        }
                    }
                }

                if (usableMetalVoxel != null)
                {
                    Voxels[usableMetalVoxel.X, usableMetalVoxel.Y, usableMetalVoxel.Z] = (byte)EnumVoxelMaterial.Empty;
                    onHelveHitSuccess(EnumVoxelMaterial.Metal, null, usableMetalVoxel.X, usableMetalVoxel.Y, usableMetalVoxel.Z);
                    return;
                }
            }
            else
            {
                for (int y = 5; y >= 0; y--)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int x = 0; x < 16; x++)
                        {
                            bool requireMetalHere = y >= ymax ? false : recipe.Voxels[x, y, z];

                            EnumVoxelMaterial mat = (EnumVoxelMaterial)Voxels[x, y, z];

                            if (requireMetalHere && mat == EnumVoxelMaterial.Metal)
                            {
                                continue;
                            }
                            if (!requireMetalHere && mat == EnumVoxelMaterial.Empty)
                            {
                                continue;
                            }

                            if (requireMetalHere && mat == EnumVoxelMaterial.Empty)
                            {
                                Voxels[x, y, z] = (byte)EnumVoxelMaterial.Metal;
                            }
                            else
                            {
                                Voxels[x, y, z] = (byte)EnumVoxelMaterial.Empty;
                            }

                            onHelveHitSuccess(mat == EnumVoxelMaterial.Empty ? EnumVoxelMaterial.Metal : mat, null, x, y, z);

                            return;
                        }
                    }
                }
            }
        }
 public static void RegisterSmithingRecipe(this ICoreServerAPI api, SmithingRecipe r)
 {
     api.ModLoader.GetModSystem <RecipeRegistrySystem>().RegisterSmithingRecipe(r);
 }
        /// <summary>
        /// Registers a new metal smithing recipe. These are sent to the client during connect, so only need to register them on the server side.
        /// </summary>
        /// <param name="recipe"></param>
        public void RegisterSmithingRecipe(SmithingRecipe recipe)
        {
            recipe.RecipeId = SmithingRecipes.Count + 1;

            SmithingRecipes.Add(recipe);
        }