rons0n Posted September 5, 2017 Share Posted September 5, 2017 (edited) Hi everyone, working on a very watered down version of Korrigan's potions and I noticed that his stat enhancing potions stack making it so you can do basically reach infinite in that stat. Korrigans example: local assets= { Asset("ANIM", "anim/violencepotion.zip"), Asset("ATLAS", "images/inventoryimages/violencepotion.xml"), Asset("IMAGE", "images/inventoryimages/violencepotion.tex"), } --Normal Potions Value local violencevalue = TUNING.VIOLENCEVALUE local function ondrinkviolence(inst, eater) eater.components.talker:Say("ROID RAGE!", 4) if eater.components.combat.damagemultiplier == nil then eater.components.combat.damagemultiplier = 1 end eater.components.combat.damagemultiplier = eater.components.combat.damagemultiplier * violencevalue eater:DoTaskInTime(180, function() eater.components.combat.damagemultiplier = .50 eater.components.talker:Say("-Damage Multiplier Removed-", 10) end) end local function fn() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddNetwork() MakeInventoryPhysics(inst) inst.AnimState:SetBank("violencepotion") inst.AnimState:SetBuild("violencepotion") inst.AnimState:PlayAnimation("idle") inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst:AddComponent("inspectable") inst:AddComponent("stackable") inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM inst:AddComponent("edible") inst.components.edible.foodtype = FOODTYPE.MEAT inst.components.edible.hungervalue = 0 --gives 10 by default inst.components.edible:SetOnEatenFn(ondrinkviolence) inst:AddComponent("inventoryitem") inst.components.inventoryitem.imagename = "violencepotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/violencepotion.xml" --inst:AddComponent("edible") --inst.components.edible.hungervalue = 0 --gives 10 by default inst:AddComponent("tradable") MakeHauntableLaunch(inst) return inst end return Prefab("common/inventory/violencepotion", fn, assets) I know Felix's Marvelous Potions Mod had a way to remedy this problem but it looked way beyond my comprehension. Isn't there an easier way to make it so if person uses this potion once, he can't use it again until the cooldown is finished(Different from Felix's approach). Or is Felix's solution the best way to go at it? Felix Example: local assets= { Asset("ANIM", "anim/healthpotion.zip"), Asset("ATLAS", "images/inventoryimages/armorpotion.xml"), Asset("IMAGE", "images/inventoryimages/armorpotion.tex"), Asset("ATLAS", "images/inventoryimages/armorpotion_off.xml"), Asset("IMAGE", "images/inventoryimages/armorpotion_off.tex"), Asset("SOUNDPACKAGE", "sound/potion_sounds.fev"), Asset("SOUND", "sound/potion_sounds.fsb") } local prefabs = { } local function endeffect(inst) if inst:HasTag("potioncooldown") then local olddefense = inst.components.health.absorb local newdefense = (olddefense - TUNING.ARMORPOTIONBUFF) inst.components.health:SetAbsorptionAmount(newdefense) inst:RemoveTag("potioncooldown") inst._fx2 = SpawnPrefab("attune_ghost_in_fx") inst._fx2.entity:SetParent(inst.entity) inst._fx2.Transform:SetPosition(0, 0, 0) if inst._fx ~= nil then inst._fx:Remove() end inst:PushEvent("potioncheck") else end end local function onbecameghost(inst) if inst:HasTag("potioncooldown") then inst:RemoveTag("potioncooldown") inst:PushEvent("potioncheck") local olddefense = inst.components.health.absorb local newdefense = (olddefense - TUNING.ARMORPOTIONBUFF) inst.components.health:SetAbsorptionAmount(newdefense) if inst._fx ~= nil then inst._fx:Remove() end end end local function givepotion(inst) local potion = "powerpotion" local item = SpawnPrefab(potion) if inst.components.inventory ~= nil then item.components.inventoryitem:SetOwner(inst) inst.components.inventory:GiveItem(item) end end local function OnEaten(inst, eater) if eater:HasTag("potioncooldown") and eater:HasTag("player") then eater:DoTaskInTime(0, givepotion) eater.components.talker:Say("My body is still recovering from the last potion.") eater.sg:GoToState("refuseeat") else eater._fx = SpawnPrefab("armorpotionfx") eater._fx.entity:SetParent(eater.entity) eater._fx.Transform:SetPosition(0, 3, 0) eater:AddTag("potioncooldown") eater:ListenForEvent("ms_becameghost", onbecameghost) eater:DoTaskInTime(TUNING.BUFFPOTIONCD , endeffect) eater.SoundEmitter:PlaySound("potion_sounds/potion/drink_potion") if eater.components.health then local olddefense = eater.components.health.absorb local newdefense = (olddefense + TUNING.ARMORPOTIONBUFF) eater.components.health:SetAbsorptionAmount(newdefense) end eater:PushEvent("potioncheck") end end ------------------------------------------------------=========================== local function UpdateInventoryState(inst) local viewer = inst.components.inventoryitem:GetGrandOwner() while viewer ~= nil and viewer.components.container ~= nil do viewer = viewer.components.container.opener end if viewer ~= nil then if viewer:HasTag("potioncooldown") then inst:RemoveComponent("edible") inst.components.inventoryitem.imagename = "armorpotion_off" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion_off.xml" inst:PushEvent("imagechange") else if inst.components.edible == nil then inst:AddComponent("edible") end if inst.components.edible.foodtype == FOODTYPE.GENERIC then inst.components.edible.foodtype = FOODTYPE.GOODIES end inst.components.inventoryitem.imagename = "armorpotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion.xml" inst:PushEvent("imagechange") inst.components.edible.healthvalue = 0 inst.components.edible.hungervalue = 0 inst.components.edible.sanityvalue = 0 inst.components.edible:SetOnEatenFn(OnEaten) end end end local function StopWatchingSanity(inst) if inst._sanitywatching ~= nil then inst:RemoveEventCallback("potioncheck", inst.OnWatchSanityDelta, inst._sanitywatching) inst._sanitywatching = nil end end local function WatchSanity(inst, target) StopWatchingSanity(inst) if target ~= nil then inst:ListenForEvent("potioncheck", inst.OnWatchSanityDelta, target) inst._sanitywatching = target end end local function StopWatchingForOpener(inst) if inst._openerwatching ~= nil then inst:RemoveEventCallback("onopen", inst.OnContainerOpened, inst._openerwatching) inst:RemoveEventCallback("onclose", inst.OnContainerClosed, inst._openerwatching) inst._openerwatching = nil end end local function WatchForOpener(inst, target) StopWatchingForOpener(inst) if target ~= nil then inst:ListenForEvent("onopen", inst.OnContainerOpened, target) inst:ListenForEvent("onclose", inst.OnContainerClosed, target) inst._openerwatching = target end end local function BeginWatch(inst) inst.components.inventoryitem:SetOnPutInInventoryFn(function(inst, owner) if owner.components.container ~= nil then WatchForOpener(inst, owner) WatchSanity(inst, owner.components.container.opener) else StopWatchingForOpener(inst) WatchSanity(inst, owner) end UpdateInventoryState(inst) end) inst.components.inventoryitem:SetOnDroppedFn(function(inst) StopWatchingSanity(inst) UpdateInventoryState(inst) end) end local function onload(inst, data) end ----------------------------------------------========================== local function fn(Sim) local inst = CreateEntity() local trans = inst.entity:AddTransform() local anim = inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddNetwork() MakeInventoryPhysics(inst) anim:SetBank("healthpotion") anim:SetBuild("healthpotion") anim:PlayAnimation("armor") inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst.entity:SetPristine() inst:AddComponent("inspectable") inst:AddComponent("inventoryitem") inst.components.inventoryitem.imagename = "armorpotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion.xml" inst:AddComponent("stackable") inst:AddTag("waterproofer") inst:AddComponent("waterproofer") inst.components.waterproofer:SetEffectiveness(0.01) ---------------------------------------- inst.OnWatchSanityDelta = function(viewer) if viewer:HasTag("potioncooldown") then inst:RemoveComponent("edible") inst.components.inventoryitem.imagename = "armorpotion_off" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion_off.xml" inst:PushEvent("imagechange") else if inst.components.edible == nil then inst:AddComponent("edible") end inst.components.inventoryitem.imagename = "armorpotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion.xml" inst:PushEvent("imagechange") inst.components.edible.healthvalue = 0 inst.components.edible.hungervalue = 0 inst.components.edible.sanityvalue = 0 if inst.components.edible.foodtype == FOODTYPE.GENERIC then inst.components.edible.foodtype = FOODTYPE.GOODIES end inst.components.edible:SetOnEatenFn(OnEaten) end end inst.OnContainerOpened = function(container, data) WatchSanity(inst, data.doer) UpdateInventoryState(inst) end inst.OnContainerClosed = function() StopWatchingSanity(inst) UpdateInventoryState(inst) end inst._sanitywatching = nil inst._openerwatching = nil inst.OnLoad = onload inst:AddComponent("edible") inst.components.edible.healthvalue = 0 inst.components.edible.hungervalue = 0 inst.components.edible.sanityvalue = 0 inst.components.edible.foodtype = FOODTYPE.GOODIES inst.components.edible:SetOnEatenFn(OnEaten) ----------------------------------------- BeginWatch(inst) return inst end return Prefab( "common/inventory/armorpotion", fn, assets) Edited September 5, 2017 by rons0n Link to comment Share on other sites More sharing options...
rons0n Posted September 5, 2017 Author Share Posted September 5, 2017 Well I finally found my solution, just a matter of using tags and a component that drops item if they dont have the tag. But Im now confused on how to add a global tag for all characters to who join the server, lose tag when they become ghost, and gain tag when becoming human. Last step before I could get this bad boy done, much appreciated if anyone can help! Link to comment Share on other sites More sharing options...
RedHairedHero Posted September 29, 2017 Share Posted September 29, 2017 On 9/5/2017 at 12:45 PM, rons0n said: Hi everyone, working on a very watered down version of Korrigan's potions and I noticed that his stat enhancing potions stack making it so you can do basically reach infinite in that stat. Korrigans example: Hide contents local assets= { Asset("ANIM", "anim/violencepotion.zip"), Asset("ATLAS", "images/inventoryimages/violencepotion.xml"), Asset("IMAGE", "images/inventoryimages/violencepotion.tex"), } --Normal Potions Value local violencevalue = TUNING.VIOLENCEVALUE local function ondrinkviolence(inst, eater) eater.components.talker:Say("ROID RAGE!", 4) if eater.components.combat.damagemultiplier == nil then eater.components.combat.damagemultiplier = 1 end eater.components.combat.damagemultiplier = eater.components.combat.damagemultiplier * violencevalue eater:DoTaskInTime(180, function() eater.components.combat.damagemultiplier = .50 eater.components.talker:Say("-Damage Multiplier Removed-", 10) end) end local function fn() local inst = CreateEntity() inst.entity:AddTransform() inst.entity:AddAnimState() inst.entity:AddNetwork() MakeInventoryPhysics(inst) inst.AnimState:SetBank("violencepotion") inst.AnimState:SetBuild("violencepotion") inst.AnimState:PlayAnimation("idle") inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst:AddComponent("inspectable") inst:AddComponent("stackable") inst.components.stackable.maxsize = TUNING.STACK_SIZE_SMALLITEM inst:AddComponent("edible") inst.components.edible.foodtype = FOODTYPE.MEAT inst.components.edible.hungervalue = 0 --gives 10 by default inst.components.edible:SetOnEatenFn(ondrinkviolence) inst:AddComponent("inventoryitem") inst.components.inventoryitem.imagename = "violencepotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/violencepotion.xml" --inst:AddComponent("edible") --inst.components.edible.hungervalue = 0 --gives 10 by default inst:AddComponent("tradable") MakeHauntableLaunch(inst) return inst end return Prefab("common/inventory/violencepotion", fn, assets) I know Felix's Marvelous Potions Mod had a way to remedy this problem but it looked way beyond my comprehension. Isn't there an easier way to make it so if person uses this potion once, he can't use it again until the cooldown is finished(Different from Felix's approach). Or is Felix's solution the best way to go at it? Felix Example: Reveal hidden contents local assets= { Asset("ANIM", "anim/healthpotion.zip"), Asset("ATLAS", "images/inventoryimages/armorpotion.xml"), Asset("IMAGE", "images/inventoryimages/armorpotion.tex"), Asset("ATLAS", "images/inventoryimages/armorpotion_off.xml"), Asset("IMAGE", "images/inventoryimages/armorpotion_off.tex"), Asset("SOUNDPACKAGE", "sound/potion_sounds.fev"), Asset("SOUND", "sound/potion_sounds.fsb") } local prefabs = { } local function endeffect(inst) if inst:HasTag("potioncooldown") then local olddefense = inst.components.health.absorb local newdefense = (olddefense - TUNING.ARMORPOTIONBUFF) inst.components.health:SetAbsorptionAmount(newdefense) inst:RemoveTag("potioncooldown") inst._fx2 = SpawnPrefab("attune_ghost_in_fx") inst._fx2.entity:SetParent(inst.entity) inst._fx2.Transform:SetPosition(0, 0, 0) if inst._fx ~= nil then inst._fx:Remove() end inst:PushEvent("potioncheck") else end end local function onbecameghost(inst) if inst:HasTag("potioncooldown") then inst:RemoveTag("potioncooldown") inst:PushEvent("potioncheck") local olddefense = inst.components.health.absorb local newdefense = (olddefense - TUNING.ARMORPOTIONBUFF) inst.components.health:SetAbsorptionAmount(newdefense) if inst._fx ~= nil then inst._fx:Remove() end end end local function givepotion(inst) local potion = "powerpotion" local item = SpawnPrefab(potion) if inst.components.inventory ~= nil then item.components.inventoryitem:SetOwner(inst) inst.components.inventory:GiveItem(item) end end local function OnEaten(inst, eater) if eater:HasTag("potioncooldown") and eater:HasTag("player") then eater:DoTaskInTime(0, givepotion) eater.components.talker:Say("My body is still recovering from the last potion.") eater.sg:GoToState("refuseeat") else eater._fx = SpawnPrefab("armorpotionfx") eater._fx.entity:SetParent(eater.entity) eater._fx.Transform:SetPosition(0, 3, 0) eater:AddTag("potioncooldown") eater:ListenForEvent("ms_becameghost", onbecameghost) eater:DoTaskInTime(TUNING.BUFFPOTIONCD , endeffect) eater.SoundEmitter:PlaySound("potion_sounds/potion/drink_potion") if eater.components.health then local olddefense = eater.components.health.absorb local newdefense = (olddefense + TUNING.ARMORPOTIONBUFF) eater.components.health:SetAbsorptionAmount(newdefense) end eater:PushEvent("potioncheck") end end ------------------------------------------------------=========================== local function UpdateInventoryState(inst) local viewer = inst.components.inventoryitem:GetGrandOwner() while viewer ~= nil and viewer.components.container ~= nil do viewer = viewer.components.container.opener end if viewer ~= nil then if viewer:HasTag("potioncooldown") then inst:RemoveComponent("edible") inst.components.inventoryitem.imagename = "armorpotion_off" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion_off.xml" inst:PushEvent("imagechange") else if inst.components.edible == nil then inst:AddComponent("edible") end if inst.components.edible.foodtype == FOODTYPE.GENERIC then inst.components.edible.foodtype = FOODTYPE.GOODIES end inst.components.inventoryitem.imagename = "armorpotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion.xml" inst:PushEvent("imagechange") inst.components.edible.healthvalue = 0 inst.components.edible.hungervalue = 0 inst.components.edible.sanityvalue = 0 inst.components.edible:SetOnEatenFn(OnEaten) end end end local function StopWatchingSanity(inst) if inst._sanitywatching ~= nil then inst:RemoveEventCallback("potioncheck", inst.OnWatchSanityDelta, inst._sanitywatching) inst._sanitywatching = nil end end local function WatchSanity(inst, target) StopWatchingSanity(inst) if target ~= nil then inst:ListenForEvent("potioncheck", inst.OnWatchSanityDelta, target) inst._sanitywatching = target end end local function StopWatchingForOpener(inst) if inst._openerwatching ~= nil then inst:RemoveEventCallback("onopen", inst.OnContainerOpened, inst._openerwatching) inst:RemoveEventCallback("onclose", inst.OnContainerClosed, inst._openerwatching) inst._openerwatching = nil end end local function WatchForOpener(inst, target) StopWatchingForOpener(inst) if target ~= nil then inst:ListenForEvent("onopen", inst.OnContainerOpened, target) inst:ListenForEvent("onclose", inst.OnContainerClosed, target) inst._openerwatching = target end end local function BeginWatch(inst) inst.components.inventoryitem:SetOnPutInInventoryFn(function(inst, owner) if owner.components.container ~= nil then WatchForOpener(inst, owner) WatchSanity(inst, owner.components.container.opener) else StopWatchingForOpener(inst) WatchSanity(inst, owner) end UpdateInventoryState(inst) end) inst.components.inventoryitem:SetOnDroppedFn(function(inst) StopWatchingSanity(inst) UpdateInventoryState(inst) end) end local function onload(inst, data) end ----------------------------------------------========================== local function fn(Sim) local inst = CreateEntity() local trans = inst.entity:AddTransform() local anim = inst.entity:AddAnimState() inst.entity:AddSoundEmitter() inst.entity:AddNetwork() MakeInventoryPhysics(inst) anim:SetBank("healthpotion") anim:SetBuild("healthpotion") anim:PlayAnimation("armor") inst.entity:SetPristine() if not TheWorld.ismastersim then return inst end inst.entity:SetPristine() inst:AddComponent("inspectable") inst:AddComponent("inventoryitem") inst.components.inventoryitem.imagename = "armorpotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion.xml" inst:AddComponent("stackable") inst:AddTag("waterproofer") inst:AddComponent("waterproofer") inst.components.waterproofer:SetEffectiveness(0.01) ---------------------------------------- inst.OnWatchSanityDelta = function(viewer) if viewer:HasTag("potioncooldown") then inst:RemoveComponent("edible") inst.components.inventoryitem.imagename = "armorpotion_off" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion_off.xml" inst:PushEvent("imagechange") else if inst.components.edible == nil then inst:AddComponent("edible") end inst.components.inventoryitem.imagename = "armorpotion" inst.components.inventoryitem.atlasname = "images/inventoryimages/armorpotion.xml" inst:PushEvent("imagechange") inst.components.edible.healthvalue = 0 inst.components.edible.hungervalue = 0 inst.components.edible.sanityvalue = 0 if inst.components.edible.foodtype == FOODTYPE.GENERIC then inst.components.edible.foodtype = FOODTYPE.GOODIES end inst.components.edible:SetOnEatenFn(OnEaten) end end inst.OnContainerOpened = function(container, data) WatchSanity(inst, data.doer) UpdateInventoryState(inst) end inst.OnContainerClosed = function() StopWatchingSanity(inst) UpdateInventoryState(inst) end inst._sanitywatching = nil inst._openerwatching = nil inst.OnLoad = onload inst:AddComponent("edible") inst.components.edible.healthvalue = 0 inst.components.edible.hungervalue = 0 inst.components.edible.sanityvalue = 0 inst.components.edible.foodtype = FOODTYPE.GOODIES inst.components.edible:SetOnEatenFn(OnEaten) ----------------------------------------- BeginWatch(inst) return inst end return Prefab( "common/inventory/armorpotion", fn, assets) You could always put a cap on the maximum they can drink. For example perform a check on how much their damage multiplier is before they consume the potion. If eater.components.combat.damagemultiplier < 3 then ... perform normal function else "Too much rage my belly hurts" end 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