mathem99 Posted March 29 Share Posted March 29 (edited) Hello! I need help with coding something, I'm working on a potion station that works similarly to a crock pot, you put 4 ingredients in they get deleted and out spews out potions! The potions you can brew is based on what level the Player's skills component is at (maximum is 3) The following code is... not working very well. I got so desperate I even used ChatGPT in order to help me but I got nowhere. What I'm trying to achieve: Make it so that it spews out up to 3 potions randomly [WORKING] Make it spew out a large potions (25% chance) or a small potion (75% chance) [WORKING] Have multiple recipes per potion craft! [Not sure if it's working] If the ingredients don't match up with any of the recipes then spew out Wet Goop. (For some reason the station ALWAYS spews out wetgoop even if the ingredients match up with the recipe) I'm only sending the part where the potions pop out, the rest works just fine but if you need more information (like the component for the brewery or the rest of the prefab's code) then just reply So, here's the code: Spoiler local function OnScienceWasMade(inst) local player = GetPlayer() local brewingSkillLevel = player.components.skills and player.components.skills.potion_brewing or 0 -- Define potion recipes based on brewing skill level -- Key (numeric) = skill level -- Value = all recipes for specified skill level -- Each recipe consists of arrays of ingredients and corresponding potions local all_potion_recipes_ever = { [1] = { { recipes = { {"flint", "flint", "flint", "flint"}, {"flint", "flint", "flint", "cutgrass"} }, potions = { {prefab = "potion_embers", rarity = 75}, {prefab = "potion_sparks", rarity = 25} } } }, [2] = { { recipes = { {"rocks", "rocks", "rocks", "rocks"}, {"rocks", "rocks", "rocks", "twigs"}, }, potions = { {prefab = "potion_plant_small", rarity = 75}, {prefab = "potion_plant_large", rarity = 25} } } }, [3] = { { recipes = { {"cutgrass", "cutgrass", "cutgrass", "cutgrass"}, {"cutgrass", "cutgrass", "cutgrass", "rocks"}, }, potions = { {prefab = "potion_sanity_small", rarity = 75}, {prefab = "potion_sanity_large", rarity = 25} } }, { recipes = { {"twigs", "twigs", "twigs", "twigs"}, {"twigs", "twigs", "twigs", "rocks"} }, potions = { {prefab = "potion_health_small", rarity = 75}, {prefab = "potion_health_large", rarity = 25} } } } } -- Choose recipe based on brewing skill level local recipeInfo = all_potion_recipes_ever[brewingSkillLevel] if recipeInfo == nil then -- If brewing skill level is greater than 3, use the recipe for level 3 recipeInfo = all_potion_recipes_ever[3] end -- Determine number of potions to drop (up to 3) local numPotions = math.random(3) for i = 1, numPotions do local selectedRecipe = nil for _, recipe in ipairs(recipeInfo) do local canCraft = true for _, ingredient in ipairs(recipe.recipes) do local ingredientCount = 0 for _, ing in ipairs(recipe.recipes) do if ing == ingredient then ingredientCount = ingredientCount + 1 end end local requiredCount = 1 -- Default required count is 1 if ingredientCount > 1 then requiredCount = ingredientCount end if not inst.components.container:Has(ingredient, requiredCount) then canCraft = false break end end if canCraft then selectedRecipe = recipe break end end if selectedRecipe then local potionTypes = selectedRecipe.potions local totalRarity = 0 for _, potion in ipairs(potionTypes) do totalRarity = totalRarity + potion.rarity end local randomValue = math.random(totalRarity) local cumulativeRarity = 0 local selectedPotion for _, potion in ipairs(potionTypes) do cumulativeRarity = cumulativeRarity + potion.rarity if randomValue <= cumulativeRarity then selectedPotion = potion.prefab break end end local x, y, z = inst.Transform:GetWorldPosition() local reward = SpawnPrefab(selectedPotion) local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0, 2.5, 0) reward.Transform:SetPosition(pt:Get()) local down = TheCamera:GetDownVec() local angle = math.atan2(down.z, down.x) + (math.random() * 60 - 30) * DEGREES local sp = math.random() * 4 + 2 reward.Physics:SetVel(sp * math.cos(angle), math.random() * 2 + 4, sp * math.sin(angle)) reward.components.inventoryitem:OnStartFalling() else -- If no recipe fulfills the requirement, spawn "wetgoop" local reward = SpawnPrefab("wetgoop") local x, y, z = inst.Transform:GetWorldPosition() reward.Transform:SetPosition(x, y, z) reward.components.inventoryitem:OnStartFalling() end end PlayAnimation(inst, "cooking_finish") inst.SoundEmitter:KillSound("brew") inst.SoundEmitter:PlaySound("dontstarve/common/potionbrewer/finish") inst:ListenForEvent("animover", OnInactive) inst._firefx.AnimState:PlayAnimation("cooking_finish_fire") inst:ListenForEvent("animover", OnFireFXOver, inst._firefx) end I hope there's anyone who can help me. Thank you for reading! Edited March 29 by mathem99 Link to comment Share on other sites More sharing options...
_zwb Posted March 29 Share Posted March 29 Put the selectedRecipe variable outside of the for loop, like this -- Determine number of potions to drop (up to 3) local numPotions = math.random(3) local selectedRecipe for i = 1, numPotions do for _, recipe in ipairs(recipeInfo) do Link to comment Share on other sites More sharing options...
mathem99 Posted March 30 Author Share Posted March 30 9 hours ago, _zwb said: Put the selectedRecipe variable outside of the for loop, like this -- Determine number of potions to drop (up to 3) local numPotions = math.random(3) local selectedRecipe for i = 1, numPotions do for _, recipe in ipairs(recipeInfo) do Thank you for the reply, sadly this doesn't seem to change the fact that the result is always wetgoop. Link to comment Share on other sites More sharing options...
mathem99 Posted March 30 Author Share Posted March 30 (edited) I made a new interpretation of the potion-brewing and here it is: local potion_recipe_common = { potion_health_small = { { ingredients = { "twigs", "twigs", "twigs", "twigs" }, skill_level = 3 }, { ingredients = { "cutgrass", "cutgrass", "cutgrass", "cutgrass" }, skill_level = 3 } }, potion_sanity_small = { { ingredients = { "carrot", "carrot", "carrot", "carrot" }, skill_level = 3 } }, potion_plant_small = { { ingredients = { "bluegem", "bluegem", "bluegem", "bluegem" }, skill_level = 2 } }, potion_embers = { { ingredients = { "redgem", "redgem", "redgem", "redgem" }, skill_level = 1 } } } local potion_recipe_rare = { potion_health_large = { { ingredients = { "twigs", "twigs", "twigs", "twigs" }, skill_level = 3 }, { ingredients = { "cutgrass", "cutgrass", "cutgrass", "cutgrass" }, skill_level = 3 } }, potion_sanity_large = { { ingredients = { "carrot", "carrot", "carrot", "carrot" }, skill_level = 3 } }, potion_plant_large = { { ingredients = { "bluegem", "bluegem", "bluegem", "bluegem" }, skill_level = 2 } }, potion_sparks = { { ingredients = { "redgem", "redgem", "redgem", "redgem" }, skill_level = 1 } } } local function GetPotionToBrew(items, skill_level, is_large) local potential_potions = {} local rare_potions = {} local potion_recipe = is_large and potion_recipe_rare or potion_recipe_common for potion_name, recipes in pairs(potion_recipe) do for _, recipe in ipairs(recipes) do if skill_level >= recipe.skill_level then local valid = true for i, item in ipairs(items) do if recipe.ingredients[i] ~= item.prefab then valid = false break end end if valid then table.insert(is_large and rare_potions or potential_potions, potion_name) end elseif skill_level <= 0 then return "wetgoop" end end end if #rare_potions > 0 and is_large then return rare_potions[math.random(#rare_potions)] elseif #potential_potions > 0 then return potential_potions[math.random(#potential_potions)] else return "wetgoop" end end local function OnScienceWasMade(inst) local player = GetPlayer() local skill_level = player.components.skills and player.components.skills.potion_brewing or 0 local rewarditem local maxDrops = math.random(3) for i = 1, maxDrops do local is_large = math.random() <= 0.25 local potion_type if is_large then potion_type = GetPotionToBrew(inst.components.container.slots, skill_level, true) else potion_type = GetPotionToBrew(inst.components.container.slots, skill_level, false) end if potion_type then local x, y, z = inst.Transform:GetWorldPosition() local reward = SpawnPrefab(potion_type) local pt = Vector3(inst.Transform:GetWorldPosition()) + Vector3(0, 2.5, 0) reward.Transform:SetPosition(pt:Get()) local down = TheCamera:GetDownVec() local angle = math.atan2(down.z, down.x) + (math.random() * 60 - 30) * DEGREES local sp = math.random() * 4 + 2 reward.Physics:SetVel(sp * math.cos(angle), math.random() * 2 + 4, sp * math.sin(angle)) reward.components.inventoryitem:OnStartFalling() end end PlayAnimation(inst, "cooking_finish") inst.SoundEmitter:KillSound("brew") inst.SoundEmitter:PlaySound("dontstarve/common/potionbrewer/finish") inst:ListenForEvent("animover", OnInactive) inst._firefx.AnimState:PlayAnimation("cooking_finish_fire") inst:ListenForEvent("animover", OnFireFXOver, inst._firefx) end It seems to work! But I don't know if there's a cleaner way of going about it. Edited March 30 by mathem99 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now