private void RegenOutlineMesh(ClayFormingRecipe recipeToOutline, bool[,,] Voxels, int recipeLayer)
        {
            MeshData recipeOutlineMesh = new MeshData(24, 36, false, false, true, false);

            recipeOutlineMesh.SetMode(EnumDrawMode.Lines);

            int greenCol  = (156 << 24) | (100 << 16) | (200 << 8) | (100);
            int orangeCol = (156 << 24) | (226 << 16) | (171 << 8) | (92);

            MeshData greenVoxelMesh  = LineMeshUtil.GetCube(greenCol);
            MeshData orangeVoxelMesh = LineMeshUtil.GetCube(orangeCol);

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

            for (int x = 0; x < 16; x++)
            {
                int y = recipeLayer;
                for (int z = 0; z < 16; z++)
                {
                    bool shouldFill = recipeToOutline.Voxels[x, y, z];
                    bool didFill    = Voxels[x, y, z];

                    if (shouldFill == didFill)
                    {
                        continue;
                    }

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

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

                    voxelMeshOffset.Rgba = (shouldFill && !didFill) ? greenVoxelMesh.Rgba : orangeVoxelMesh.Rgba;

                    recipeOutlineMesh.AddMeshData(voxelMeshOffset);
                }
            }

            recipeOutlineMeshRef?.Dispose();
            recipeOutlineMeshRef = null;
            if (recipeOutlineMesh.VerticesCount > 0)
            {
                recipeOutlineMeshRef = api.Render.UploadMesh(recipeOutlineMesh);
            }
        }
Example #2
0
        private bool TrySetSelectedRecipe(int num)
        {
            baseMaterial = new ItemStack(api.World.GetItem(new AssetLocation("clay-" + workItemStack.Collectible.LastCodePart())));

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

            selectedRecipeNumber = new List <ClayFormingRecipe>(api.World.ClayFormingRecipes).IndexOf(recipe);
            return(selectedRecipeNumber >= 0);
        }
Example #3
0
        public override void OnReceivedClientPacket(IPlayer player, int packetid, byte[] data)
        {
            if (packetid == (int)EnumClayFormingPacket.CancelSelect)
            {
                if (baseMaterial != null)
                {
                    Api.World.SpawnItemEntity(baseMaterial, Pos.ToVec3d().Add(0.5));
                }
                Api.World.BlockAccessor.SetBlock(0, Pos);
            }

            if (packetid == (int)EnumClayFormingPacket.SelectRecipe)
            {
                int recipeid             = SerializerUtil.Deserialize <int>(data);
                ClayFormingRecipe recipe = Api.World.ClayFormingRecipes.FirstOrDefault(r => r.RecipeId == recipeid);

                if (recipe == null)
                {
                    Api.World.Logger.Error("Client tried to selected clayforming 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)EnumClayFormingPacket.OnUserOver)
            {
                Vec3i       voxelPos;
                bool        mouseMode;
                BlockFacing facing;
                using (MemoryStream ms = new MemoryStream(data))
                {
                    BinaryReader reader = new BinaryReader(ms);
                    voxelPos  = new Vec3i(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                    mouseMode = reader.ReadBoolean();
                    facing    = BlockFacing.ALLFACES[reader.ReadInt16()];
                }

                //   api.World.Logger.Notification("ok got use over packet from {0} at pos {1}", player.PlayerName, voxelPos);

                OnUseOver(player, voxelPos, facing, mouseMode);
            }
        }
        public void RegenMesh(ItemStack workitem, bool[,,] Voxels, ClayFormingRecipe recipeToOutline, int recipeLayer)
        {
            workItemMeshRef?.Dispose();
            workItemMeshRef = null;

            if (workitem == null)
            {
                return;
            }

            if (recipeToOutline != null)
            {
                RegenOutlineMesh(recipeToOutline, Voxels, recipeLayer);
            }

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

            float subPixelPaddingx = api.BlockTextureAtlas.SubPixelPaddingX;
            float subPixelPaddingy = api.BlockTextureAtlas.SubPixelPaddingY;

            TextureAtlasPosition tpos            = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("clayform")), workitem.Collectible.Code.ToShortString());
            MeshData             singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f));

            singleVoxelMesh.Rgba = new byte[6 * 4 * 4].Fill((byte)255);
            CubeMeshUtil.SetXyzFacesAndPacketNormals(singleVoxelMesh);

            texId = tpos.atlasTextureId;

            for (int i = 0; i < singleVoxelMesh.Uv.Length; i++)
            {
                if (i % 2 > 0)
                {
                    singleVoxelMesh.Uv[i] = tpos.y1 + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size.Height - subPixelPaddingy;
                }
                else
                {
                    singleVoxelMesh.Uv[i] = tpos.x1 + singleVoxelMesh.Uv[i] * 2f / api.BlockTextureAtlas.Size.Width - subPixelPaddingx;
                }
            }

            singleVoxelMesh.XyzFaces      = (byte[])CubeMeshUtil.CubeFaceIndices.Clone();
            singleVoxelMesh.XyzFacesCount = 6;

            for (int i = 0; i < 6; i++)
            {
                singleVoxelMesh.Flags[i * 4] = singleVoxelMesh.Flags[i * 4 + 1] = singleVoxelMesh.Flags[i * 4 + 2] = singleVoxelMesh.Flags[i * 4 + 3] = VertexFlags.PackNormal(BlockFacing.ALLFACES[i].Normali);
            }



            singleVoxelMesh.SeasonColorMapIds  = new byte[6];
            singleVoxelMesh.ClimateColorMapIds = new byte[6];
            singleVoxelMesh.ColorMapIdsCount   = 6;


            MeshData voxelMeshOffset = singleVoxelMesh.Clone();

            for (int x = 0; x < 16; x++)
            {
                for (int y = 0; 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 < singleVoxelMesh.xyz.Length; i += 3)
                        {
                            voxelMeshOffset.xyz[i]     = px + singleVoxelMesh.xyz[i];
                            voxelMeshOffset.xyz[i + 1] = py + singleVoxelMesh.xyz[i + 1];
                            voxelMeshOffset.xyz[i + 2] = pz + singleVoxelMesh.xyz[i + 2];
                        }

                        float offsetX = ((((x + 4 * y) % 16f / 16f)) * 32f) / api.BlockTextureAtlas.Size.Width;
                        float offsetY = (pz * 32f) / api.BlockTextureAtlas.Size.Height;

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

                        workItemMesh.AddMeshData(voxelMeshOffset);
                    }
                }
            }

            workItemMeshRef = api.Render.UploadMesh(workItemMesh);
        }
        public void RegenMesh(ItemStack workitem, bool[,,] Voxels, ClayFormingRecipe recipeToOutline, int recipeLayer)
        {
            if (workItemMeshRef != null)
            {
                api.Render.DeleteMesh(workItemMeshRef);
                workItemMeshRef = null;
            }

            if (workitem == null)
            {
                return;
            }

            if (recipeToOutline != null)
            {
                RegenOutlineMesh(recipeToOutline, Voxels, recipeLayer);
            }

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

            workItemMesh.Flags = null;
            workItemMesh.Rgba2 = null;

            float subPixelPadding = api.BlockTextureAtlas.SubPixelPadding;

            TextureAtlasPosition tpos            = api.BlockTextureAtlas.GetPosition(api.World.GetBlock(new AssetLocation("clayform")), "clay");
            MeshData             singleVoxelMesh = CubeMeshUtil.GetCubeOnlyScaleXyz(1 / 32f, 1 / 32f, new Vec3f(1 / 32f, 1 / 32f, 1 / 32f));

            singleVoxelMesh.Rgba = CubeMeshUtil.GetShadedCubeRGBA(ColorUtil.WhiteArgb, CubeMeshUtil.DefaultBlockSideShadings, false);

            texId = tpos.atlasTextureId;

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

            singleVoxelMesh.XyzFaces      = (int[])CubeMeshUtil.CubeFaceIndices.Clone();
            singleVoxelMesh.XyzFacesCount = 6;
            singleVoxelMesh.Tints         = new int[6];
            singleVoxelMesh.Flags         = null;
            singleVoxelMesh.TintsCount    = 6;


            MeshData voxelMeshOffset = singleVoxelMesh.Clone();

            for (int x = 0; x < 16; x++)
            {
                for (int y = 0; 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 < singleVoxelMesh.xyz.Length; i += 3)
                        {
                            voxelMeshOffset.xyz[i]     = px + singleVoxelMesh.xyz[i];
                            voxelMeshOffset.xyz[i + 1] = py + singleVoxelMesh.xyz[i + 1];
                            voxelMeshOffset.xyz[i + 2] = pz + singleVoxelMesh.xyz[i + 2];
                        }

                        float offsetX = ((((x + 4 * y) % 16f / 16f)) * 32f) / api.BlockTextureAtlas.Size;
                        float offsetZ = (pz * 32f) / api.BlockTextureAtlas.Size;

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

                        workItemMesh.AddMeshData(voxelMeshOffset);
                    }
                }
            }

            workItemMeshRef = api.Render.UploadMesh(workItemMesh);
        }
 public static void RegisterClayFormingRecipe(this ICoreServerAPI api, ClayFormingRecipe r)
 {
     api.ModLoader.GetModSystem <RecipeRegistrySystem>().RegisterClayFormingRecipe(r);
 }
        /// <summary>
        /// Registers a new clay forming 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 RegisterClayFormingRecipe(ClayFormingRecipe recipe)
        {
            recipe.RecipeId = ClayFormingRecipes.Count + 1;

            ClayFormingRecipes.Add(recipe);
        }