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 }); } }
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); }
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)); }
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())); }
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())); }
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); }
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); }
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); }