Jump to content

level decreases on death


Recommended Posts

I'm using a lvl mod for my character and he loses exp on death but not level so i tried to use something like this and it works a first login

elseif inst.level == 1 then
	inst.expneededforlevel= 20
	inst.leveldrop = 9.9
	inst.components.health.maxhealth = math.ceil (55)
	inst.components.hunger.max = math.ceil (55)
	inst.components.sanity.max = math.ceil (55)

when i re-enter same world it says

Attempt to compare number with nil

and here is the code which causes this error

if inst.experience <= inst.leveldrop then ----this line
	inst.level = inst.level -1
end

 

Link to comment
Share on other sites

Simple. "Attempt to compare number with nil" tells you exactly what's wrong. One of the variables used in that if-statement is nil, and as such cannot be used in a calculation. You just need to do one of two things, depending on your implementation and the functionality you want:

1. Make sure to set the variables to a default value. If this is at a point where you cannot possibly have the value set already (e.g., during world generation, incl. player prefab instantiation) then, if it is nil when you are about to use it, set it to a default value before using it.

2. Check whether it is nil before using it, and simply skip the part of your code that wants to use it.

It really depends how the rest of your code works.

Link to comment
Share on other sites

nah im not able to fix it :/

--Level system
local function levelexp(inst, data)

local max_exp = 999999999994650
local min_exp = -99999999999999
local experience = math.min (inst.experience, max_exp, min_exp)
local max_level = 30
local min_level = 0
local level = math.min (inst.level, max_level, min_level)
local max_eatexp = 1275
local min_eatexp = 0
local eatexp = math.min (inst.eatexp, max_eatexp, min_eatexp)
local max_eatlevel = 50
local min_eatlevel = 0
local eatlevel = math.min (inst.eatlevel, max_eatlevel, min_eatlevel)
local max_bloodexp = 400
local min_bloodexp = 0
local bloodexp = math.min (inst.bloodexp, max_bloodexp, min_bloodexp)
local max_bloodlevel = 20
local min_bloodlevel = -10
local bloodlevel = math.min (inst.bloodlevel, max_bloodlevel, min_bloodlevel)
updateDamageMultiplier(inst)

local health_percent = inst.components.health:GetPercent()
local sanity_percent = inst.components.sanity:GetPercent()
local hunger_percent = inst.components.hunger:GetPercent()

if inst.eatlevel == 0 then
	inst.eatexpneeded = 1
	
elseif inst.eatlevel == 1 then
	inst.eatexpneeded = 3
	inst.eatleveldrop = 0.9
	
elseif inst.eatlevel == 2 then
	inst.eatexpneeded = 5
	inst.eatleveldrop = 2.9
	
elseif inst.eatlevel == 3 then
	inst.eatexpneeded = 7
	inst.eatleveldrop = 4.9
	
elseif inst.eatlevel == 4 then
	inst.eatexpneeded = 9
	inst.eatleveldrop = 6.9
	
elseif inst.eatlevel == 5 then
	inst.eatexpneeded = 11
	inst.eatleveldrop = 8.9
	
elseif inst.eatlevel == 6 then
	inst.eatexpneeded = 13
	inst.eatleveldrop = 10.9
	
elseif inst.eatlevel == 7 then
	inst.eatexpneeded = 15
	inst.eatleveldrop = 12.9
	
elseif inst.eatlevel == 8 then
	inst.eatexpneeded = 17
	inst.eatleveldrop = 14.9
	
elseif inst.eatlevel == 9 then
	inst.eatexpneeded = 19
	inst.eatleveldrop = 16.9
	
elseif inst.eatlevel == 10 then
	inst.eatexpneeded = 22
	inst.eatleveldrop = 18.9
	
elseif inst.eatlevel == 11 then
	inst.eatexpneeded = 25
	inst.eatleveldrop = 21.9
	
elseif inst.eatlevel == 12 then
	inst.eatexpneeded = 28
	inst.eatleveldrop = 24.9
	
elseif inst.eatlevel == 13 then
	inst.eatexpneeded = 31
	inst.eatleveldrop = 27.9
	
elseif inst.eatlevel == 14 then
	inst.eatexpneeded = 34
	inst.eatleveldrop = 30.9
	
elseif inst.eatlevel == 15 then
	inst.eatexpneeded = 37
	inst.eatleveldrop = 33.9
	
elseif inst.eatlevel == 16 then
	inst.eatexpneeded = 40
	inst.eatleveldrop = 36.9
	
elseif inst.eatlevel == 17 then
	inst.eatexpneeded = 43
	inst.eatleveldrop = 39.9
	
elseif inst.eatlevel == 18 then
	inst.eatexpneeded = 46
	inst.eatleveldrop = 42.9
	
elseif inst.eatlevel == 19 then
	inst.eatexpneeded = 49
	inst.eatleveldrop = 45.9
	
elseif inst.eatlevel == 20 then
	inst.eatexpneeded = 53
	inst.eatleveldrop = 48.9
	
elseif inst.eatlevel == 21 then
	inst.eatexpneeded = 57
	inst.eatleveldrop = 52.9
	
elseif inst.eatlevel == 22 then
	inst.eatexpneeded = 61
	inst.eatleveldrop = 56.9
	
elseif inst.eatlevel == 23 then
	inst.eatexpneeded = 65
	inst.eatleveldrop = 60.9
	
elseif inst.eatlevel == 24 then
	inst.eatexpneeded = 69
	inst.eatleveldrop = 64.9
	
elseif inst.eatlevel == 25 then
	inst.eatexpneeded = 73
	inst.eatleveldrop = 68.9
	
elseif inst.eatlevel == 26 then
	inst.eatexpneeded = 77
	inst.eatleveldrop = 72.9
	
elseif inst.eatlevel == 27 then
	inst.eatexpneeded = 81
	inst.eatleveldrop = 76.9
	
elseif inst.eatlevel == 28 then
	inst.eatexpneeded = 85
	inst.eatleveldrop = 80.9
	
elseif inst.eatlevel == 29 then
	inst.eatexpneeded = 89
	inst.eatleveldrop = 84.9
	
elseif inst.eatlevel == 30 then
	inst.eatexpneeded = 94
	inst.eatleveldrop = 88.9
	
elseif inst.eatlevel == 31 then
	inst.eatexpneeded = 99
	inst.eatleveldrop = 93.9
	
elseif inst.eatlevel == 32 then
	inst.eatexpneeded = 104
	inst.eatleveldrop = 98.9
	
elseif inst.eatlevel == 33 then
	inst.eatexpneeded = 109
	inst.eatleveldrop = 103.9
	
elseif inst.eatlevel == 34 then
	inst.eatexpneeded = 114
	inst.eatleveldrop = 108.9
	
elseif inst.eatlevel == 35 then
	inst.eatexpneeded = 119
	inst.eatleveldrop = 113.9
	
elseif inst.eatlevel == 36 then
	inst.eatexpneeded = 124
	inst.eatleveldrop = 118.9
	
elseif inst.eatlevel == 37 then
	inst.eatexpneeded = 129
	inst.eatleveldrop = 123.9
	
elseif inst.eatlevel == 38 then
	inst.eatexpneeded = 134
	inst.eatleveldrop = 128.9
	
elseif inst.eatlevel == 39 then
	inst.eatexpneeded = 139
	inst.eatleveldrop = 133.9
	
elseif inst.eatlevel == 40 then
	inst.eatexpneeded = 145
	inst.eatleveldrop = 138.9
end

if inst.bloodlevel == 0 then
inst.bloodexpneeded = 1
elseif inst.bloodlevel == 1 then
inst.bloodexpneeded = 2
inst.bloodleveldrop = 1
elseif inst.bloodlevel == 2 then
inst.bloodexpneeded = 4
inst.bloodleveldrop = 1
elseif inst.bloodlevel == 3 then
inst.bloodexpneeded = 8
inst.bloodleveldrop = 3
elseif inst.bloodlevel == 4 then
inst.bloodexpneeded = 16
inst.bloodleveldrop = 7
elseif inst.bloodlevel == 5 then
inst.bloodexpneeded = 32
inst.bloodleveldrop = 15
elseif inst.bloodlevel == 6 then
inst.bloodexpneeded = 42
inst.bloodleveldrop = 31
elseif inst.bloodlevel == 7 then
inst.bloodexpneeded = 52
inst.bloodleveldrop = 41
elseif inst.bloodlevel == 8 then
inst.bloodexpneeded = 62
inst.bloodleveldrop = 51
elseif inst.bloodlevel == 9 then
inst.bloodexpneeded = 72
inst.bloodleveldrop = 61
elseif inst.bloodlevel == 10 then
inst.bloodexpneeded = 82
inst.bloodleveldrop = 71
elseif inst.bloodlevel == 11 then
inst.bloodexpneeded = 97
inst.bloodleveldrop = 81
elseif inst.bloodlevel == 12 then
inst.bloodexpneeded = 112
inst.bloodleveldrop = 96
elseif inst.bloodlevel == 13 then
inst.bloodexpneeded = 127
inst.bloodleveldrop = 111
elseif inst.bloodlevel == 14 then
inst.bloodexpneeded = 142
inst.bloodleveldrop = 126
elseif inst.bloodlevel == 15 then
inst.bloodexpneeded = 157
inst.bloodleveldrop = 141
elseif inst.bloodlevel == 16 then
inst.bloodexpneeded = 177
inst.bloodleveldrop = 156
elseif inst.bloodlevel == 17 then
inst.bloodexpneeded = 197
inst.bloodleveldrop = 176
elseif inst.bloodlevel == 18 then
inst.bloodexpneeded = 217
inst.bloodleveldrop = 196
elseif inst.bloodlevel == 19 then
inst.bloodexpneeded = 237
inst.bloodleveldrop = 216
elseif inst.bloodlevel == 20 then
inst.bloodleveldrop = 236
end

if inst.level == 0 then
	inst.expneededforlevel= 10
elseif inst.level == 1 then
	inst.expneededforlevel= 20
	inst.leveldrop = 9.9
	inst.components.health.maxhealth = math.ceil (55)
	inst.components.hunger.max = math.ceil (55)
	inst.components.sanity.max = math.ceil (55)
	
elseif inst.level == 2 then
	inst.expneededforlevel= 40
	inst.leveldrop = 19.9
	inst.components.health.maxhealth = math.ceil (60)
	inst.components.hunger.max = math.ceil (60)
	inst.components.sanity.max = math.ceil (60)
	
elseif inst.level == 3 then
	inst.expneededforlevel= 70
	inst.leveldrop = 39.9
	inst.components.health.maxhealth = math.ceil (65)
	inst.components.hunger.max = math.ceil (65)
	inst.components.sanity.max = math.ceil (65)
	
elseif inst.level == 4 then
	inst.expneededforlevel= 110
	inst.leveldrop = 69.9
	inst.components.health.maxhealth = math.ceil (70)
	inst.components.hunger.max = math.ceil (70)
	inst.components.sanity.max = math.ceil (70)
	
elseif inst.level == 5 then
	inst.expneededforlevel= 160
	inst.leveldrop = 109.9
	inst.components.health.maxhealth = math.ceil (75)
	inst.components.hunger.max = math.ceil (75)
	inst.components.sanity.max = math.ceil (75)
	
elseif inst.level == 6 then
	inst.expneededforlevel= 220
	inst.leveldrop = 159.9
	inst.components.health.maxhealth = math.ceil (80)
	inst.components.hunger.max = math.ceil (80)
	inst.components.sanity.max = math.ceil (80)
	
elseif inst.level == 7 then
	inst.expneededforlevel= 290
	inst.leveldrop = 219.9
	inst.components.health.maxhealth = math.ceil (85)
	inst.components.hunger.max = math.ceil (85)
	inst.components.sanity.max = math.ceil (85)
	
elseif inst.level == 8 then
	inst.expneededforlevel= 370
	inst.leveldrop = 289.9
	inst.components.health.maxhealth = math.ceil (90)
	inst.components.hunger.max = math.ceil (90)
	inst.components.sanity.max = math.ceil (90)
	
elseif inst.level == 9 then
	inst.expneededforlevel= 460
	inst.leveldrop = 369.9
	inst.components.health.maxhealth = math.ceil (95)
	inst.components.hunger.max = math.ceil (95)
	inst.components.sanity.max = math.ceil (95)
	
elseif inst.level == 10 then
	inst.expneededforlevel= 560
	inst.leveldrop = 459.9
	inst.components.health.maxhealth = math.ceil (100)
	inst.components.hunger.max = math.ceil (100)
	inst.components.sanity.max = math.ceil (100)
	
elseif inst.level == 11 then
	inst.expneededforlevel= 670
	inst.leveldrop = 559.9
	inst.components.health.maxhealth = math.ceil (110)
	inst.components.hunger.max = math.ceil (110)
	inst.components.sanity.max = math.ceil (110)
	
elseif inst.level == 12 then
	inst.expneededforlevel= 790
	inst.leveldrop = 669.9
	inst.components.health.maxhealth = math.ceil (120)
	inst.components.hunger.max = math.ceil (120)
	inst.components.sanity.max = math.ceil (120)
	
elseif inst.level == 13 then
	inst.expneededforlevel= 920
	inst.leveldrop = 789.9
	inst.components.health.maxhealth = math.ceil (130)
	inst.components.hunger.max = math.ceil (130)
	inst.components.sanity.max = math.ceil (130)
	
elseif inst.level == 14 then
	inst.expneededforlevel= 1060
	inst.leveldrop = 919.9
	inst.components.health.maxhealth = math.ceil (140)
	inst.components.hunger.max = math.ceil (140)
	inst.components.sanity.max = math.ceil (140)
	
elseif inst.level == 15 then
	inst.expneededforlevel= 1210
	inst.leveldrop = 1059.9
	inst.components.health.maxhealth = math.ceil (150)
	inst.components.hunger.max = math.ceil (150)
	inst.components.sanity.max = math.ceil (150)
	
elseif inst.level == 16 then
	inst.expneededforlevel= 1370
	inst.leveldrop = 1209.9
	inst.components.health.maxhealth = math.ceil (160)
	inst.components.hunger.max = math.ceil (160)
	inst.components.sanity.max = math.ceil (160)
	
elseif inst.level == 17 then
	inst.expneededforlevel= 1540
	inst.leveldrop = 1369.9
	inst.components.health.maxhealth = math.ceil (170)
	inst.components.hunger.max = math.ceil (170)
	inst.components.sanity.max = math.ceil (170)
	
elseif inst.level == 18 then
	inst.expneededforlevel= 1720
	inst.leveldrop = 1539.9
	inst.components.health.maxhealth = math.ceil (180)
	inst.components.hunger.max = math.ceil (180)
	inst.components.sanity.max = math.ceil (180)
	
elseif inst.level == 19 then
	inst.expneededforlevel= 1910
	inst.leveldrop = 1719.9
	inst.components.health.maxhealth = math.ceil (190)
	inst.components.hunger.max = math.ceil (190)
	inst.components.sanity.max = math.ceil (190)
	
elseif inst.level == 20 then
	inst.expneededforlevel= 2110
	inst.leveldrop = 1909.9
	inst.components.health.maxhealth = math.ceil (200)
	inst.components.hunger.max = math.ceil (200)
	inst.components.sanity.max = math.ceil (200)
	
elseif inst.level == 21 then
	inst.expneededforlevel= 2320
	inst.leveldrop = 2109.9
	inst.components.health.maxhealth = math.ceil (210)
	inst.components.hunger.max = math.ceil (210)
	inst.components.sanity.max = math.ceil (210)
	
elseif inst.level == 22 then
	inst.expneededforlevel= 2540
	inst.leveldrop = 2319.9
	inst.components.health.maxhealth = math.ceil (220)
	inst.components.hunger.max = math.ceil (220)
	inst.components.sanity.max = math.ceil (220)
	
elseif inst.level == 23 then
	inst.expneededforlevel= 2770
	inst.leveldrop = 2539.9
	inst.components.health.maxhealth = math.ceil (230)
	inst.components.hunger.max = math.ceil (230)
	inst.components.sanity.max = math.ceil (230)
	
elseif inst.level == 24 then
	inst.expneededforlevel= 3010
	inst.leveldrop = 2769.9
	inst.components.health.maxhealth = math.ceil (240)
	inst.components.hunger.max = math.ceil (240)
	inst.components.sanity.max = math.ceil (240)
	
elseif inst.level == 25 then
	inst.expneededforlevel= 3260
	inst.leveldrop =3009.9
	inst.components.health.maxhealth = math.ceil (250)
	inst.components.hunger.max = math.ceil (250)
	inst.components.sanity.max = math.ceil (250)
	
elseif inst.level == 26 then
	inst.expneededforlevel= 3520
	inst.leveldrop = 3259.9
	inst.components.health.maxhealth = math.ceil (260)
	inst.components.hunger.max = math.ceil (260)
	inst.components.sanity.max = math.ceil (260)
	
elseif inst.level == 27 then
	inst.expneededforlevel= 3790
	inst.leveldrop = 3519.9
	inst.components.health.maxhealth = math.ceil (270)
	inst.components.hunger.max = math.ceil (270)
	inst.components.sanity.max = math.ceil (270)
	
elseif inst.level == 28 then
	inst.expneededforlevel= 4070
	inst.leveldrop = 3789.9
	inst.components.health.maxhealth = math.ceil (280)
	inst.components.hunger.max = math.ceil (280)
	inst.components.sanity.max = math.ceil (280)
	
elseif inst.level == 29 then
	inst.expneededforlevel= 4360
	inst.leveldrop = 4069.9
	inst.components.health.maxhealth = math.ceil (290)
	inst.components.hunger.max = math.ceil (290)
	inst.components.sanity.max = math.ceil (290)
	
elseif inst.level == 30 then
	inst.leveldrop = 4359.9
	inst.components.health.maxhealth = math.ceil (300)
	inst.components.hunger.max = math.ceil (300)
	inst.components.sanity.max = math.ceil (300)
end

if inst.experience >= inst.expneededforlevel then
	inst.SoundEmitter:PlaySound("kitsura/characters/kitsura/level up")
	inst.level = inst.level + 1
	inst.components.talker:Say("Level Up!! Level \n".. (inst.level) )
end

if inst.bloodexp >= inst.bloodexpneeded then
	inst.bloodlevel = inst.bloodlevel + 1
	inst.SoundEmitter:PlaySound("kitsura/characters/kitsura/bloodsound")
end

if inst.eatexp >= inst.eatexpneeded then
	inst.SoundEmitter:PlaySound("kitsura/characters/kitsura/eatlevelup")
	inst.eatlevel = inst.eatlevel + 1
	inst.components.talker:Say("I'm getting stronger")
end


if inst.bloodexp <= inst.bloodleveldrop and inst.bloodlevel >= 1 then
	inst.bloodlevel = (inst.bloodlevel - 1)
end

	inst.components.health:SetPercent(health_percent)
	inst.components.hunger:SetPercent(hunger_percent)
	inst.components.sanity:SetPercent(sanity_percent)
end

here is the full code i tried lots of things but not working

Link to comment
Share on other sites

The error in question has a lot to do with context and state, so without knowing where this code is located and when and where it is executed, it's hard for us to help without seeing the full code, which is why I only wrote those hints.

I'm guessing that this is happening because you call your levelexp() function in your character's master_postinit. If so, then the character instance doesn't have its "experience" or "leveldrop" variable set yet (unless you specifically set them before calling levelexp()). If you want to use your levelexp() in both OnLoad() and in your master_postinit(), then you have to make sure that the function can handle both situations. But I would advise you to figure out a way to not call levelexp() in your character's master_postinit, and instead always just set the variables to their default starting values. Any player being loaded into the game will have OnLoad() called on them anyway, where I assume you load in their current level and experience, so there's no need for them to have levelexp() called in their master_postinit.

Anyway, as I said, I have no context, so I don't even know if you also call levelexp() in OnLoad(). It should be enough to just load the variable values from the saved data, and ONLY call levelexp() when the character actually levels up. There's absolutely no reason to go through all of that code every time the character gains experience. I would move all the code that has to do with levelling up into its own function, and then make another function called GainExp() which receives an amount of experience, adds it to the player's experience variable, checks it against the required experience for the next level (do this in a loop to allow gaining more levels in one go, like, if you kill a boss very early or something), and calls the function for levelling up.

Edited by Ultroman
  • Like 1
Link to comment
Share on other sites

1 hour ago, Ultroman said:

The error in question has a lot to do with context and state, so without knowing where this code is located and when and where it is executed, it's hard for us to help without seeing the full code, which is why I only wrote those hints.

I'm guessing that this is happening because you call your levelexp() function in your character's master_postinit. If so, then the character instance doesn't have its "experience" or "leveldrop" variable set yet (unless you specifically set them before calling levelexp()). If you want to use your levelexp() in both OnLoad() and in your master_postinit(), then you have to make sure that the function can handle both situations. But I would advise you to figure out a way to not call levelexp() in your character's master_postinit, and instead always just set the variables to their default starting values. Any player being loaded into the game will have OnLoad() called on them anyway, where I assume you load in their current level and experience, so there's no need for them to have levelexp() called in their master_postinit.

Anyway, as I said, I have no context, so I don't even know if you also call levelexp() in OnLoad(). It should be enough to just load the variable values from the saved data, and ONLY call levelexp() when the character actually levels up. There's absolutely no reason to go through all of that code every time the character gains experience. I would move all the code that has to do with levelling up into its own function, and then make another function called GainExp() which receives an amount of experience, adds it to the player's experience variable, checks it against the required experience for the next level (do this in a loop to allow gaining more levels in one go, like, if you kill a boss very early or something), and calls the function for levelling up.

well im not sure how to do that tbh i can upload my mod file if you need the problem is im using this code for level up and

if inst.bloodexp >= inst.bloodexpneeded then
	inst.bloodlevel = inst.bloodlevel + 1
	inst.SoundEmitter:PlaySound("kitsura/characters/kitsura/bloodsound")
end

this one for level down

if inst.bloodexp <= inst.bloodleveldrop and inst.bloodlevel >= 1 then
	inst.bloodlevel = (inst.bloodlevel - 1)
end

so the only difference between them one has + and other one has - i tried lots of stuff but none of them worked. here is the file if you need. Also i'll try to find something that not crush

Kitsura.rar

Link to comment
Share on other sites

I'm sorry, but this is the biggest cluster**** of code I've ever seen. So many variable-checks and hard-coded values all over the place (particularly your OnBeingAttacked), and absolutely no indentation structure. I can't help you debug this. All I can tell you, is that one of the variables you're trying to use is nil, and you need to find out why. You can use the print-statements to figure out which variable is nil, by outputting some information before executing the offending line (example using your initial error):

if inst.experience == nil then
	print("inst.experience is nil !!!!!!!!!!!!!!!!!!!!!!")
end

if inst.leveldrop == nil then
	print("inst.leveldrop is nil !!!!!!!!!!!!!!!!!!!!!!")
end

if inst.experience <= inst.leveldrop then ----this line
	inst.level = inst.level -1
end

Then you can read back through the code and find out what could cause it to be nil at this point. Repeat until you've found the problem.

To get back to the code, it'd be much easier for you to work with, if you develop functions to calculate the individual values for a given level, or even stored them in a table so you can easily look them up. You can also save the resulting values to the player instance using OnSave, and then load them in OnLoad when the player logs back in. Things like your freeze-application thresholds could probably be changed to a percentage of the maximum health, instead of there being specific values for each level. If you can find a way to do something like that, then you would be able to compress 25 if-statements into one.

Edited by Ultroman
  • Like 1
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...