nicknightyx Posted July 4, 2018 Share Posted July 4, 2018 I wanted to add critical hit perk to my character and found @SuperDavid 's post. For the code below, all credit goes to @IronHunter. This is in the modmain, I kept getting compare number to nil warning from the underlined line. And the line above it worked fine. Problem seems to be the self.inst.critChance but it was declared in the same way as self.inst.gcp_c in the character's prefab. I'm now confused, need some help. Thanks. Spoiler AddComponentPostInit("combat", function(Combat) local OldCalcDamage = Combat.CalcDamage Combat.CalcDamage = function(self, target, weapon, ...) local old_damage = nil -- local crit = self.inst.critChance -- local critdmg = self.inst.critDmg local critdmg = 1.5 -- if math.random() <= 0.5 and target and self.inst.prefab == "hisoka" and self.inst.gcp_c >= 3 then if math.random() <= self.inst.critChance and target and self.inst.prefab == "hisoka" and self.inst.gcp_c >= 3 then if weapon then -- if its a weapon old_damage = weapon.components.weapon.damage weapon.components.weapon.damage = old_damage * critdmg self.inst.components.health:DoDelta(weapon.components.weapon.damage/2) else -- if we attack with something not using the weapon component old_damage = self.defaultdamage self.defaultdamage = old_damage * critdmg self.inst.components.health:DoDelta(self.defaultdamage/2) end -- visual effects and other stuff you can add local fx = SpawnPrefab("explode_small") local x, y, z = target.Transform:GetWorldPosition() fx.Transform:SetPosition(x, y, z) end local ret = OldCalcDamage(self, target, weapon, ...) if old_damage then-- reseting back to non crit damage if weapon then weapon.components.weapon.damage = old_damage else self.defaultdamage = old_damage end end return ret end end) hisoka7-3.zip Link to comment Share on other sites More sharing options...
nicknightyx Posted July 6, 2018 Author Share Posted July 6, 2018 Bbb Link to comment Share on other sites More sharing options...
Joachim Posted July 6, 2018 Share Posted July 6, 2018 (edited) Where are you setting critChance? I presume you define it in hisoka's prefab constructor function. In any case the problem is quite simple: critChance has not been defined, therefore it is nil. Note that the component postinit will be executed for every prefab that the combat component, not just hisoka. So the solution would be to switch around the check as follows; if self.inst.prefab == "hisoka" and math.random() <= self.inst.critChance and self.inst.gcp_c >= 3 then This works because of the way the interpreter resolves logical operators. If the condition is X and Y, then both X and Y must be true in order for the condition to be true. So if X is false, then there is no reason to evaluate Y, so it is skipped and the condition as a whole returns false. Your mistake was to not take advantage of this property of logical operators, so self.inst.critChance was evaluated before the interpreter reached the hisoka check, throwing an error when the instance was not hisoka. In short, the order matters! You could also make the postinit less dependent on hisoka and allow other prefabs to use this function as well, by simply checking if critChance exists and in that case proceed: if self.inst.critChance and math.random() <= self.inst.critChance and self.inst.gcp_c >= 3 then This is a more robust version, so I would prefer this version over the previous version. You could still restrict it to just hisoka (by only setting critChance for hisoka), but writing generic code is generally good practice, especially if it doesn't increase complexity like in this situation. Edited July 6, 2018 by Joachim Link to comment Share on other sites More sharing options...
nicknightyx Posted July 7, 2018 Author Share Posted July 7, 2018 @Joachim It worked, thank you so much! You are amazing! Although if I use if self.inst.critChance and math.random() <= self.inst.critChance and self.inst.gcp_c >= 3 then It would crash. Have to execute the perfab postinit before any self.variable I guess. Link to comment Share on other sites More sharing options...
IronHunter Posted July 7, 2018 Share Posted July 7, 2018 1 minute ago, nicknightyx said: @Joachim It worked, thank you so much! You are amazing! Although if I use if self.inst.critChance and math.random() <= self.inst.critChance and self.inst.gcp_c >= 3 then It would crash. Have to execute the perfab postinit before any self.variable I guess. This is because it runs for all entities with the combat component that runs this function. Hence why the prefab check is really important as the swamp wars will proc and crash this. Alternatively you can check to make sure critchance isn't nil. I have released my personal modified version of the crit code that I use in my mods for others to use as they wish. It doesn't require any modifications. As it allows greater compatibility amongst characters. Crit Code Link to comment Share on other sites More sharing options...
nicknightyx Posted July 7, 2018 Author Share Posted July 7, 2018 15 hours ago, IronHunter said: This is because it runs for all entities with the combat component that runs this function. Hence why the prefab check is really important as the swamp wars will proc and crash this. Alternatively you can check to make sure critchance isn't nil. I have released my personal modified version of the crit code that I use in my mods for others to use as they wish. It doesn't require any modifications. As it allows greater compatibility amongst characters. Crit Code Thanks for the explanation! I finally understand. 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