TheBigDeal Posted February 27, 2018 Share Posted February 27, 2018 Hello! I was wondering a couple of things, Firstly how would I make a character have the ability to dodge say 40% of all attacks done to them? I guess it would en tale no damage being given on a random chance basic and maybe a "miss" sound being played. I can do the sound just the dodge part I have no idea where to start. Also speaking of starting, I made a couple mods a while ago and am getting back into it but forgot alot of stuff, what are some good resources to have for the scripting aspect of modding? Every tutorial I have seen thus far is always just the basics and never really explains any scripting or anything. Thank you! Link to comment Share on other sites More sharing options...
IronHunter Posted February 27, 2018 Share Posted February 27, 2018 Spoiler --------------------------To use this code simply add the variable inst.dodgechance = 0 ----< Dodge Users >----a number between 0 and 1 with 1 being 100% chance to dodge for that character --------------------------For example if you want 40% simply add inst.dodgechance = 0.4 to your character AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) local dodgechance = self.inst.dodgechance or 0 --default dodgechance for all characters is 0 do not change this unless you want enemies to dodge as well. if self.inst.components.inventory then --if you want items to also bestow dodgechance simply add inst.dodgechance to the respective item, this stacks multiplicatively local dodgegear = {}--otherwise this if statement can be commented out. for k, v in pairs(GLOBAL.EQUIPSLOTS) do table.insert(dodgegear, self.inst.components.inventory:GetEquippedItem(v)) end for k,v in pairs(dodgegear) do if v.dodgechance then dodgechance = 1-((1-dodgechance)*(1-v.dodgechance)) end --stacks multiplicatively end end if dodgechance > 0 and math.random() <= dodgechance then --print("dodged") -- visual effects and other stuff you can add local x, y, z = self.inst.Transform:GetWorldPosition() SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) --damage = 0.01 --use this if u want to still do the attacked animation return false --use this if u want to skip the attacked animation end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) This is loosely something I use in my personal mod, which features dodgechance and items that provide it. If you want a more personal version you can modify it, to just affect your prefab instead. AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) if self.inst.prefab == "wilson" then --change to your character local dodgechance = 0.4 --change this number between 0-1 with this example being 40% if dodgechance > 0 and math.random() <= dodgechance then --print("dodged") -- visual effects and other stuff you can add local x, y, z = self.inst.Transform:GetWorldPosition() SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) --damage = 0.01 --use this if u want to still do the attacked animation return false --use this if u want to skip the attacked animation end end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) Choose one and place it into your modmain.lua For scripting I would google lua scripting, this is a great way to understand basic programming interactions as well as prebuilt functions. It is also ideal to look at how other people made similar mods to what you are looking to do and learn from what they did. Reverse engineering to a degree. Using notepad++ find in files feature has been a game changer for me and has made modding much easier being able to find code that is similar to what I am designing. Cheers, Iron_Hunter Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 1, 2018 Author Share Posted March 1, 2018 On 2/27/2018 at 3:27 AM, IronHunter said: Â Hide contents --------------------------To use this code simply add the variable inst.dodgechance = 0 ----< Dodge Users >----a number between 0 and 1 with 1 being 100% chance to dodge for that character --------------------------For example if you want 40% simply add inst.dodgechance = 0.4 to your character AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) local dodgechance = self.inst.dodgechance or 0 --default dodgechance for all characters is 0 do not change this unless you want enemies to dodge as well. if self.inst.components.inventory then --if you want items to also bestow dodgechance simply add inst.dodgechance to the respective item, this stacks multiplicatively local dodgegear = {}--otherwise this if statement can be commented out. for k, v in pairs(GLOBAL.EQUIPSLOTS) do table.insert(dodgegear, self.inst.components.inventory:GetEquippedItem(v)) end for k,v in pairs(dodgegear) do if v.dodgechance then dodgechance = 1-((1-dodgechance)*(1-v.dodgechance)) end --stacks multiplicatively end end if dodgechance > 0 and math.random() <= dodgechance then --print("dodged") -- visual effects and other stuff you can add local x, y, z = self.inst.Transform:GetWorldPosition() SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) --damage = 0.01 --use this if u want to still do the attacked animation return false --use this if u want to skip the attacked animation end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) This is loosely something I use in my personal mod, which features dodgechance and items that provide it. If you want a more personal version you can modify it, to just affect your prefab instead. AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) if self.inst.prefab == "wilson" then --change to your character local dodgechance = 0.4 --change this number between 0-1 with this example being 40% if dodgechance > 0 and math.random() <= dodgechance then --print("dodged") -- visual effects and other stuff you can add local x, y, z = self.inst.Transform:GetWorldPosition() SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) --damage = 0.01 --use this if u want to still do the attacked animation return false --use this if u want to skip the attacked animation end end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) Choose one and place it into your modmain.lua For scripting I would google lua scripting, this is a great way to understand basic programming interactions as well as prebuilt functions. It is also ideal to look at how other people made similar mods to what you are looking to do and learn from what they did. Reverse engineering to a degree. Using notepad++ find in files feature has been a game changer for me and has made modding much easier being able to find code that is similar to what I am designing. Cheers, Iron_Hunter So I tried both of them, both giving the same error it seems. [00:00:28]: [string "scripts/modutil.lua"]:330: Must specify a string for your custom action! Example: "Perform My Action" LUA ERROR stack traceback: =[C] in function 'assert' scripts/modutil.lua(330,1) in function 'AddAction' ../mods/WD Gaster/modmain.lua(116,1) in main chunk =[C] in function 'xpcall' scripts/util.lua(709,1) in function 'RunInEnvironment' scripts/mods.lua(511,1) in function 'InitializeModMain' scripts/mods.lua(485,1) in function 'LoadMods' scripts/main.lua(267,1) in function 'ModSafeStartup' scripts/main.lua(327,1) =[C] in function 'SetPersistentString' scripts/mainfunctions.lua(26,1) in function 'SavePersistentString' scripts/modindex.lua(77,1) =[C] in function 'GetPersistentString' scripts/modindex.lua(64,1) in function 'BeginStartupSequence' scripts/main.lua(326,1) in function 'callback' scripts/modindex.lua(542,1) =[C] in function 'GetPersistentString' scripts/modindex.lua(516,1) in function 'Load' scripts/main.lua(325,1) in main chunk [00:00:28]: [string "scripts/mainfunctions.lua"]:1029: variable 'global_error_widget' is not declared LUA ERROR stack traceback: =[C] in function 'error' scripts/strict.lua(23,1) scripts/mainfunctions.lua(1029,1) =[C] in function 'SetPersistentString' scripts/mainfunctions.lua(26,1) in function 'SavePersistentString' scripts/modindex.lua(77,1) =[C] in function 'GetPersistentString' scripts/modindex.lua(64,1) in function 'BeginStartupSequence' scripts/main.lua(326,1) in function 'callback' scripts/modindex.lua(542,1) =[C] in function 'GetPersistentString' scripts/modindex.lua(516,1) in function 'Load' scripts/main.lua(325,1) in main chunk I put the dodgechance to 1 to see it work before I make it an actually balanced number. Also thanks, I will have to google it and find a good tutorial. Link to comment Share on other sites More sharing options...
IronHunter Posted March 2, 2018 Share Posted March 2, 2018 Could you either attach or send me your mod files, so that I can proof read it. I don't know why you are getting that error, but the error seems to be saying something unrelated to this code. Cheers, Iron_Hunter Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 2, 2018 Author Share Posted March 2, 2018 (edited) Here is my modmain. dodge is near the bottom. Error only happened once I added it. EDIT: Actually it seems to be doing it regardless.... removed file and I'll reply when I figure out whats causing it... now its a mystery. Â ALRIGHT, got the crash to not happen, Other issues persist and hopefully I can fix those. But as for the dodging it's saying "attempt to call global 'SpawnPrefab' (a nil value) LUA ERROR stack traceback: then it gives the error back to this line: SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) Alright i removed the spawnprefabs and it works flawlessly, now to just get that line to work. Edited March 2, 2018 by TheBigDeal Link to comment Share on other sites More sharing options...
IronHunter Posted March 2, 2018 Share Posted March 2, 2018 1 hour ago, TheBigDeal said: Here is my modmain. dodge is near the bottom. Error only happened once I added it. EDIT: Actually it seems to be doing it regardless.... removed file and I'll reply when I figure out whats causing it... now its a mystery.  ALRIGHT, got the crash to not happen, Other issues persist and hopefully I can fix those. But as for the dodging it's saying "attempt to call global 'SpawnPrefab' (a nil value) LUA ERROR stack traceback: then it gives the error back to this line: SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) Alright i removed the spawnprefabs and it works flawlessly, now to just get that line to work. Simply add local SpawnPrefab = Global.SpawnPrefab before the addcomponentpostinit or use Global.SpawnPrefab in front of the SpawnPrefabs which ever works for you. Cheers, Iron_Hunter Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 2, 2018 Author Share Posted March 2, 2018 (edited) AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) local dodgechance = self.inst.dodgechance or 0 if dodgechance > 0 and math.random() <= dodgechance then local x, y, z = self.inst.Transform:GetWorldPosition() Global.SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) Global.SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) return false end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) So I made it into this but it's saying "attempt to index global 'Global' (a nil value). I also tried to do this: local SpawnPrefab = Global.SpawnPrefab AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) local dodgechance = self.inst.dodgechance or 0 if dodgechance > 0 and math.random() <= dodgechance then local x, y, z = self.inst.Transform:GetWorldPosition() SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) return false end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) And that also did not work it seems. Edited March 2, 2018 by TheBigDeal Link to comment Share on other sites More sharing options...
IronHunter Posted March 2, 2018 Share Posted March 2, 2018 (edited) Spoiler 27 minutes ago, TheBigDeal said: AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) local dodgechance = self.inst.dodgechance or 0 if dodgechance > 0 and math.random() <= dodgechance then local x, y, z = self.inst.Transform:GetWorldPosition() Global.SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) Global.SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) return false end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) So I made it into this but it's saying "attempt to index global 'Global' (a nil value). I also tried to do this: local SpawnPrefab = Global.SpawnPrefab AddComponentPostInit("combat", function(self) local oldGetAttacked = self.GetAttacked function self:GetAttacked(attacker, damage, weapon, stimuli) local dodgechance = self.inst.dodgechance or 0 if dodgechance > 0 and math.random() <= dodgechance then local x, y, z = self.inst.Transform:GetWorldPosition() SpawnPrefab("sand_puff_large_back").Transform:SetPosition(x, y - .1, z) SpawnPrefab("sand_puff_large_front").Transform:SetPosition(x, y, z) return false end return oldGetAttacked(self, attacker, damage, weapon, stimuli) end end) And that also did not work it seems. Derp...Global needs to be all caps GLOBAL... my bad, the same way I had it for GLOBAL.EQUIPSLOTS in the original post. Work and late night coding don't mix lols. Cheers, Iron_Hunter Edited March 2, 2018 by IronHunter quote size Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 2, 2018 Author Share Posted March 2, 2018 3 minutes ago, IronHunter said: Â Reveal hidden contents Derp...Global needs to be all caps GLOBAL... my bad, the same way I had it for GLOBAL.EQUIPSLOTS in the original post. Work and late night coding don't mix lols. Cheers, Iron_Hunter Alright! that worked, even though it seems setting the dodge chance to 1 isn't 100% dodgeable, its fine as it wont be set to that anyways. To continue with the dodging, my character has two forms also so the dodge needs to be adaptable, I already tried act.dodge chance = 1 in my modmain for him changing forms. if the inst.dodge chance isn't 1 also it doesn't seem to be all the time leading me to think its not working as it should be. Any idea why/how I can make it change? Also, this is a bit off the current topic. But I also have a teleportation system in place with an item (Right click and it teleports you to the cursor). I want to transfer the teleportation to a key bind X. How could I make it so X will teleport the character to the position of the mouse and lose a bit of sanity? If that's even possible. Here is the code for that so you have an idea of how it works. local TRANSFORM = GLOBAL.Action() TRANSFORM.str = "Transform" TRANSFORM.id = "TRANSFORM" TRANSFORM.fn = function(act) if act.target.normal_mode == true and act.target.transform_cooldown == nil then act.target.normal_mode = nil act.target.transform_cooldown = true act.target.AnimState:SetBuild("transformationform") act.target.components.talker:Say("Transforming...") act.target:DoTaskInTime(5, function() act.target.transform_cooldown = nil end) act.dodgechance = 1 elseif act.target.normal_mode == nil and act.target.transform_cooldown == nil then act.target.normal_mode = true act.target.AnimState:SetBuild("regularform) act.target.components.talker:Say("Undoing the Transformation...") act.dodgechance = 1 elseif act.target.transform_cooldown == true then act.target.components.talker:Say("That's impossible...") act.target:PushEvent("emote", { anim = "emoteXL_facepalm", mounted = true }) end end Thank you so much for answering my questions! Link to comment Share on other sites More sharing options...
IronHunter Posted March 2, 2018 Share Posted March 2, 2018 I'll look at your other code tomorrow, but if you copied the code correctly, it should be working. I tested the original code on my own mod and it works just fine, do note that this only allows you to dodge stuff that would cause you to take damage, not health loss from fire/starvation/temperature etc. There are a number of mods on the workshop that bind a key to do something, you can pretty much copy that bind key function and use those. I don't usually like using keybinds as they aren't friendly to controllers, which a lot of my friends use to play this game. I am out of time for tonight, got to go to bed. Cheers, Iron_Hunter Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 2, 2018 Author Share Posted March 2, 2018 21 minutes ago, IronHunter said: I'll look at your other code tomorrow, but if you copied the code correctly, it should be working. I tested the original code on my own mod and it works just fine, do note that this only allows you to dodge stuff that would cause you to take damage, not health loss from fire/starvation/temperature etc. There are a number of mods on the workshop that bind a key to do something, you can pretty much copy that bind key function and use those. I don't usually like using keybinds as they aren't friendly to controllers, which a lot of my friends use to play this game. I am out of time for tonight, got to go to bed. Cheers, Iron_Hunter Hmm, that's a fair point, sadly with the character i am making it's an ability he can do and not an item so I'm not sure how I would get around that. Maybe some configuration that will give you a item or use a key bind in the mod config could work. Or maybe I can bind or for controllers to be a mix, say X + A or something like that. And as for the damage, I was checking it by spawning Hounds and letting them attack me, having inst.dodgechance = 1 in my character.lua makes it 100%, just not sure is the act.dodge chance is working, Sorry if I worded that weirdly beforehand. Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 5, 2018 Author Share Posted March 5, 2018 On 3/2/2018 at 3:04 AM, IronHunter said: I'll look at your other code tomorrow, but if you copied the code correctly, it should be working. I tested the original code on my own mod and it works just fine, do note that this only allows you to dodge stuff that would cause you to take damage, not health loss from fire/starvation/temperature etc. There are a number of mods on the workshop that bind a key to do something, you can pretty much copy that bind key function and use those. I don't usually like using keybinds as they aren't friendly to controllers, which a lot of my friends use to play this game. I am out of time for tonight, got to go to bed. Cheers, Iron_Hunter Ey, don't mean to be a bug but have you been able to look it over yet? Link to comment Share on other sites More sharing options...
IronHunter Posted March 5, 2018 Share Posted March 5, 2018 53 minutes ago, TheBigDeal said: Ey, don't mean to be a bug but have you been able to look it over yet? Been busy with Work, and life, from a quick look have you tried using act.doer.dodgechance? act.doer references the prefab performing the action, as for the keybind thing I'll have to look at that when I have more time. I seriously recommend you check out somebody else's mod that uses keybinds and just copy that for your character, then use it to run the action. If anybody else wants to help him with the keybind thing, that is cool too. Cheers, Iron_Hunter Link to comment Share on other sites More sharing options...
TheBigDeal Posted March 6, 2018 Author Share Posted March 6, 2018 22 hours ago, IronHunter said: Been busy with Work, and life, from a quick look have you tried using act.doer.dodgechance? act.doer references the prefab performing the action, as for the keybind thing I'll have to look at that when I have more time. I seriously recommend you check out somebody else's mod that uses keybinds and just copy that for your character, then use it to run the action. If anybody else wants to help him with the keybind thing, that is cool too. Cheers, Iron_Hunter Alright, I'll give that a try, thank you so much for all the help you've given. Though I already have the transform key to a keybind so it's not so much the keybind that troubles me it's more of getting the keybind to teleport. 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