GreenDevil Posted July 26, 2022 Share Posted July 26, 2022 Hey guys! I'm wanting to make a weapon that applies dot with a base attack or replace flat out damage with dot, whichever way is easier would be much appreciated. Think of it is a poison effect on a whip. Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/ Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 (edited) Hello o/ this shouldn't be too hard to pull off, in your weapon's prefab file under where you would put the "weapon" component, you'll need to have at least these two fields with it inst:AddComponent("weapon") inst.components.weapon:SetDamage(YOUR_WEAPON_DAMAGE_PER_HIT) inst.components.weapon:SetOnAttack(onattack) Where SetDamage is self-explanitory, but SetOnAttack will be passed the argument "onattack" which is a function you haven't declared yet, but it'll go somewhere up above near your weapon prefab's other local functions (if any). Then in your onattack function, you're able to pass it 3 parameters, inst, attacker, and target, where inst is your weapon, attacker is the player attacking, and the target is their target. The main one we're going to want is the target since we're going to want to apply the poison effect to them. Inside your onattack function, you're basically just going to want to set up a periodic task to deal damage to your target for a certain amount of time. You're probably going to want to figure out how much poison damage you want it to do per swing beforehand, but it would essentially look like this local poison_length = 30 -- seconds local poison_interval = 3 -- seconds local poison_damage = 50 -- total -- If you want a wind-up time poison_length = poison_length + poison_interval local poison_tick = poison_damage / (poison_length / poison_interval) local function onattack(inst, attacker, target) if not target or not target.components.health then return end if target.poison_task ~= nil then target.poison_task:Cancel() end target.poison_task = DoPeriodicTask(poison_interval, function(inst) -- By having the "false" in the DoDelta, it will enable the sound of your -- health falling whenever a poison tick happens, may be useful if a player -- gets poisoned, but if you dont want the sound then switch it to "true" target.components.health:DoDelta(poison_tick, false, "poison") end, poison_interval) -- you only need the poison_interval here if you want the windup if target.poisoncure_task ~= nil then target.poisoncure_task:Cancel() end target.poisoncure_task = DoTaskInTime(poison_length, function(inst) target.poison_task:Cancel() target.poison_task = nil target.poisoncure_task = nil end) end That should at least get the dot working, but you might want to add some other things like maybe tinting the target green temporarily while they're poisoned just for better conveyance. You could also add in things like a chance to get poisoned by adding in a math.random condition if you want as well. EDIT: You may also have to filter out targets that aren't "poisonable" as well, as this may also affect inanimate objects with health such as walls. That can also be done in the onattack callback. Edited July 26, 2022 by w00tyd00d Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1588973 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 48 minutes ago, w00tyd00d said: Hello o/ this shouldn't be too hard to pull off, in your weapon's prefab file under where you would put the "weapon" component, you'll need to have at least these two fields with it inst:AddComponent("weapon") inst.components.weapon:SetDamage(YOUR_WEAPON_DAMAGE_PER_HIT) inst.components.weapon:SetOnAttack(onattack) Where SetDamage is self-explanitory, but SetOnAttack will be passed the argument "onattack" which is a function you haven't declared yet, but it'll go somewhere up above near your weapon prefab's other local functions (if any). Then in your onattack function, you're able to pass it 3 parameters, inst, attacker, and target, where inst is your weapon, attacker is the player attacking, and the target is their target. The main one we're going to want is the target since we're going to want to apply the poison effect to them. Inside your onattack function, you're basically just going to want to set up a periodic task to deal damage to your target for a certain amount of time. You're probably going to want to figure out how much poison damage you want it to do per swing beforehand, but it would essentially look like this local poison_length = 30 -- seconds local poison_interval = 3 -- seconds local poison_damage = 50 -- total -- If you want a wind-up time poison_length = poison_length + poison_interval local poison_tick = poison_damage / (poison_length / poison_interval) local function onattack(inst, attacker, target) if not target or not target.components.health then return end if target.poison_task ~= nil then target.poison_task:Cancel() end target.poison_task = DoPeriodicTask(poison_interval, function(inst) -- By having the "false" in the DoDelta, it will enable the sound of your -- health falling whenever a poison tick happens, may be useful if a player -- gets poisoned, but if you dont want the sound then switch it to "true" target.components.health:DoDelta(poison_tick, false, "poison") end, poison_interval) -- you only need the poison_interval here if you want the windup if target.poisoncure_task ~= nil then target.poisoncure_task:Cancel() end target.poisoncure_task = DoTaskInTime(poison_length, function(inst) target.poison_task:Cancel() target.poison_task = nil target.poisoncure_task = nil end) end That should at least get the dot working, but you might want to add some other things like maybe tinting the target green temporarily while they're poisoned just for better conveyance. You could also add in things like a chance to get poisoned by adding in a math.random condition if you want as well. EDIT: You may also have to filter out targets that aren't "poisonable" as well, as this may also affect inanimate objects with health such as walls. That can also be done in the onattack callback. for the onattack function where do I put it and this is the function, right? local SetOnAttack = onattack? Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1588991 Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 10 minutes ago, GreenDevil said: for the onattack function where do I put it Somewhere up above in your weapon's prefab file 10 minutes ago, GreenDevil said: and this is the function, right? local SetOnAttack = onattack? Noo haha you have to pass it as an argument to the SetOnAttack function in your weapon's "weapon" component, like I had written up above ^ This should also be located in your weapon's prefab somewhere below the TheWorld.ismastersim check inst:AddComponent("weapon") inst.components.weapon:SetDamage(YOUR_WEAPON_DAMAGE_PER_HIT) inst.components.weapon:SetOnAttack(onattack) Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1588997 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 53 minutes ago, w00tyd00d said: Somewhere up above in your weapon's prefab file Noo haha you have to pass it as an argument to the SetOnAttack function in your weapon's "weapon" component, like I had written up above ^ This should also be located in your weapon's prefab somewhere below the TheWorld.ismastersim check inst:AddComponent("weapon") inst.components.weapon:SetDamage(YOUR_WEAPON_DAMAGE_PER_HIT) inst.components.weapon:SetOnAttack(onattack) please help D: https://www.toptal.com/developers/hastebin/edocezicak.lua Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589031 Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 It looks like you started a function declaration at line 28 but then never finished it, but in actuality it shouldn't even be there at all lol basically delete line 28 and then try it again Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589056 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 6 minutes ago, w00tyd00d said: It looks like you started a function declaration at line 28 but then never finished it, but in actuality it shouldn't even be there at all lol basically delete line 28 and then try it again This is what I get once I attack. Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589062 Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 Oh that's my fault, both DoTaskInTime and DoPeriodicTask need to be called from the target, replace them with target:DoTaskInTime and target:DoPeriodicTask respectively Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589063 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 12 minutes ago, w00tyd00d said: Oh that's my fault, both DoTaskInTime and DoPeriodicTask need to be called from the target, replace them with target:DoTaskInTime and target:DoPeriodicTask respectively I can load in but when I attack it doesn't do the DoT damage, it just does the weapon damage. Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589068 Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 (edited) Actually I just realized it should also be a negative number in the DoDelta call as well, else you'll actually end up healing your target over time instead of poisoning them lol so make sure that DoDelta receives -poison_tick as an argument. Was your target healing over time or was that not having any effect either? EDIT: Also in each nameless function passed in both task functions, switch out inst for target so it says function(target), again my b Edited July 26, 2022 by w00tyd00d Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589071 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 (edited) it worked thanks! also how would I add a chance factor for poison to inflict and when it does particles come out? Edited July 26, 2022 by GreenDevil Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589099 Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 (edited) Eyy happy to hear it! The way it's set up it shouldn't stack, it will just refresh the duration of it (and restart the poison intervals). Though if you wanted to add a cooldown, just set up a third task and have your onattack check if that task exists and if it does, just return (same with the guard clause you already have at the top, you can just append it on the end of that) so something like this local function onattack(inst, attacker, target) if not target or not target.components.health or target.poison_CD then return end if target.poison_task ~= nil then target.poison_task:Cancel() end target.poison_task = target:DoPeriodicTask(poison_interval, function(target) -- By having the "false" in the DoDelta, it will enable the sound of your -- health falling whenever a poison tick happens, may be useful if a player -- gets poisoned, but if you dont want the sound then switch it to "true" target.components.health:DoDelta(-poison_tick, false, "poison") end, poison_interval) -- you only need the poison_interval here if you want the windup if target.poisoncure_task ~= nil then target.poisoncure_task:Cancel() end target.poisoncure_task = target:DoTaskInTime(poison_length, function(target) target.poison_task:Cancel() target.poison_task = nil target.poisoncure_task = nil end) target.poison_CD = target:DoTaskInTime(COOLDOWN_TIME_HERE, function(target) target.poison_CD = nil end) end The nice thing about storing it on the target is that way even if they get attacked by another source of poison, the cooldown will still be in effect. If you want the cooldown to be tracked via the weapon instead, just replace target with inst with everything to do with the poison_CD variable Edited July 27, 2022 by w00tyd00d 1 Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589109 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 5 minutes ago, w00tyd00d said: Eyy happy to hear it! The way it's set up it shouldn't stack, it will just refresh the duration of it (and restart the poison intervals). Though if you wanted to add a cooldown, just set up a third task and have your onattack check if that task exists and if it does, just return (same with the guard clause you already have at the top, you can just ammend it on the end of that) so something like this local function onattack(inst, attacker, target) if not target or not target.components.health or target.poison_CD then return end if target.poison_task ~= nil then target.poison_task:Cancel() end target.poison_task = target:DoPeriodicTask(poison_interval, function(target) -- By having the "false" in the DoDelta, it will enable the sound of your -- health falling whenever a poison tick happens, may be useful if a player -- gets poisoned, but if you dont want the sound then switch it to "true" target.components.health:DoDelta(-poison_tick, false, "poison") end, poison_interval) -- you only need the poison_interval here if you want the windup if target.poisoncure_task ~= nil then target.poisoncure_task:Cancel() end target.poisoncure_task = target:DoTaskInTime(poison_length, function(target) target.poison_task:Cancel() target.poison_task = nil target.poisoncure_task = nil end) target.poison_CD = target:DoTaskInTime(COOLDOWN_TIME_HERE, function(target) target.poison_CD = nil end) end The nice thing about storing it on the target is that way even if they get attacked by another source of poison, the cooldown will still be in effect. If you want the cooldown to be tracked via the weapon instead, just replace target with inst with everything to do with the poison_CD variable is there any way for particles to come out or to change the hue of the enemy when poison is inflicted? Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589115 Share on other sites More sharing options...
w00tyd00d Posted July 26, 2022 Share Posted July 26, 2022 (edited) This is unfortunately where my expertise ends, I'm not really too familiar with the art side of things much at all haha I know you can use SpawnPrefab(prefab) to spawn in FX particles, tho I wouldn't know as far as which ones would work best for it. You can also use target.AnimeState:SetMultColour(r, g, b, a) or target.AnimeState:SetAddColour (r, g, b, a) to modulate color on the target, but I'm not 100% certain on how to reverse it lol my guess would be either setting the r,g,b values to all 0 or all 1 as they're additive/multiplicative, but you're going to have to experiment with it on your own. Edited July 26, 2022 by w00tyd00d 1 Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589122 Share on other sites More sharing options...
GreenDevil Posted July 26, 2022 Author Share Posted July 26, 2022 11 minutes ago, w00tyd00d said: This is unfortunately where my expertise ends, I'm not really too familiar with the art side of things much at all haha I know you can use SpawnPrefab(prefab) to spawn in FX particles, tho I wouldn't know as far as which ones would work best for it. You can also use target.AnimeState:SetMultColour(r, g, b, a) or target.AnimeState:SetAddColour (r, g, b, a) to modulate color on the target, but I'm not 100% certain on how to reverse it lol my guess would be either setting the r,g,b values to all 0 or all 1 as they're additive/multiplicative, but you're going to have to experiment with it on your own. no worries I got the particles but how do i add another gui display for the cooldown? like the health but instead it shows a cooldown timer? Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589125 Share on other sites More sharing options...
w00tyd00d Posted July 27, 2022 Share Posted July 27, 2022 4 minutes ago, GreenDevil said: but how do i add another gui display for the cooldown? like the health but instead it shows a cooldown timer? Well I've never actually added a widget myself, but that's where you'll find your answer. First you'll need to adjust how the poison_CD variable works because there's no (easy) way of seeing how much time is left. If you want to keep track of the remaining seconds, I'd rename your current inst.poison_CD to inst.poison_CD_task and then add another variable called something like inst.poison_CD_time and track it like this local function onattack(inst, attacker, target) if not target or not target.components.health or target.poison_CD_task then return end if target.poison_task ~= nil then target.poison_task:Cancel() end target.poison_task = target:DoPeriodicTask(poison_interval, function(target) -- By having the "false" in the DoDelta, it will enable the sound of your -- health falling whenever a poison tick happens, may be useful if a player -- gets poisoned, but if you dont want the sound then switch it to "true" target.components.health:DoDelta(-poison_tick, false, "poison") end, poison_interval) -- you only need the poison_interval here if you want the windup if target.poisoncure_task ~= nil then target.poisoncure_task:Cancel() end target.poisoncure_task = target:DoTaskInTime(poison_length, function(target) target.poison_task:Cancel() target.poison_task = nil target.poisoncure_task = nil end) target.poison_CD_time = YOUR_COOLDOWN_LENGTH target.poison_CD_task = target:DoPeriodicTask(1, function(target) target.poison_CD_time = target.poison_CD_time - 1 if target.poison_CD_time == 0 then target.poison_CD_task:Cancel() target.poison_CD_task = nil end end) end Then your target will be able to read their own information to be able to able to reference it for the widget. Godspeed soldier o7 1 Link to comment https://forums.kleientertainment.com/forums/topic/142119-how-do-i-add-a-dot-effect-onto-a-weapon/#findComment-1589128 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