• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Lua System accepting only 2 cases

dkangel83

Member
Joined
Mar 31, 2010
Messages
148
Reaction score
18
Location
Brazil
Well im using a system to show what is the experience multiplier that the char is receiving but it only works if tow cases are set, more that, the code wont show..

im using this code to show the info needed

Code:
function onSay(player, words, param)
local p = player
local s = function(p, lv)
       local k = Game.getExperienceStage(lv)
       local st = p:getStamina()
       local pv = p:getVipDays()
       local pp = p:getPremiumDays()
        if pv > 0 and st > 2400 then
            return k*(1.5+1.2) .. " (vip exp and stamina bonus) "
        elseif pv > 0 and st < 840 then
            return k*(0.5+0.2) .. " (penalty for stamina too low) "
        elseif pp > 0 and pv == 0 and st > 2400 then
            return k*1.5 .. " (stamina bonus) "
        elseif pv == 0 and st < 840 then
            return k*0.5 .. " (stamina penalty) "
        elseif pp > 0 and pv == 0 and st > 841 and st < 2399 then
            return k .. " (normal) "
        elseif pp > 0 and pv > 0 and st > 841 and st < 2399 then
            return k*1.2 .. " (vip bonus) "
        elseif pp == 0 and pv > 0 and st > 841 and st < 2399 then
            return k*1.2 .. " (vip bonus) "
        elseif st < 1 then
           return 0 .. " (out of stamina) "
--        else
--           return k .. "(aqui)"
        end
    end

   if words == "!exp" then
     local lv = p:getLevel()
     p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You need " .. ((50 * lv^3) - (150 * lv^2) + (400 * lv)) / 3 - p:getExperience() .. " experience more, for " .. lv+1 .. " level.")
     p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Current rate: x" .. s(p, lv))
     return false
   end
  p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have to spend " .. math.ceil((p:getVocation():getRequiredManaSpent(p:getBaseMagicLevel() + 1) - p:getManaSpent()) / configManager.getNumber(configKeys.RATE_MAGIC))  .. " mana more, for next magic level.")
return false
end

After using !exp command if the char meets the requirement for 2 it shows on screen but if 3 it skip, and if no option it gives an error..

the example is.. a Char with vip time, premium and stamina above 40hrs ..

if pp > 0 and pv > 0 and st > 2400 then
return k*(1.5+1.2) .. " (vip exp and stamina bonus) "

i get this error
Code:
Lua Script Error: [TalkAction Interface]
data/talkactions/scripts/expmana.lua:onSay
data/talkactions/scripts/expmana.lua:32: attempt to concatenate a nil value
stack traceback:
        [C]: in function '__concat'
        data/talkactions/scripts/expmana.lua:32: in function <data/talkactions/scripts/expmana.lua:1>

BUT if i remove pp > 0 letting only the rest like in here
Code:
if pv > 0 and st > 2400 then
return k*(1.5+1.2) .. " (vip exp and stamina bonus) "

the system will work, console will show now errors and in game screen i'll receive the info
Code:
22:39 Current rate: x18.9 (vip exp and stamina bonus)

i also made changes in player.lua to fit with my needs but the same.. this time i get no errors but it doesnt counts the xp in right way. If the player is premium and with stamina above 40hrs it will receive the right xp but if the char is vip, is premium and stamina above 40hrs system will not count the line and will delivery the base xp..

Code:
    -- Stamina modifier
    if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
        useStamina(self)

        local staminaMinutes = self:getStamina()
        if staminaMinutes > 2400 and self:isPremium() then
            exp = exp * 1.5
        elseif staminaMinutes <= 840 then
            exp = exp * 0.5
        elseif staminaMinutes > 2400 and self:isPremium() and self:isVip() then
            exp = exp * (1.5 + 1.2)
        elseif staminaMinutes <= 840 and self:isVip() then
            exp = exp * (0.5 + 0.2)
        elseif staminaMinutes < 2399 and staminaMinutes > 841 and self:isVip() then
            exp = exp * 1.2
        end
    end

    return exp
end

is this a system thing that doesnt accept more than two cases or what?
 
The problem isnt with pp itself.. i just used as example.. i can use anything in case if only 2.. it can be

Code:
if '1st condition' and '2nd condition' then
it will work but if i add a 3rd condition or 4th like

Code:
if '1st condition' and '2nd condition' and '3rd condition' then
or
Code:
if '1st condition' and '2nd condition' and '3rd condition' and '4th condition' then

system will not count it.. like it doesnt exist..

also with player.lua as you can see in the main post
 
that isn't the case at all. if you're going to do if one and two and three then before the first if, print all of those values, you might be surprised to find that one of them isn't as you think it is.

edit: if you're honestly concerned about having more than 2, then use brackets.

if (condition one and condition two) and condition three then
 
I think you are hitting a short circuiting. It happens when you have all ands and one of them is false, or all ors and one of them is true. When one of the conditions is false, all of them together can't be true (by the rule X and FALSE = FALSE), so if the second one is false, the third and fourth never get even tested.
 
well im trying using this one

Code:
function onSay(player, words, param)
local p = player
local s = function(p, lv)
       local k = Game.getExperienceStage(lv)
       local st = p:getStamina()
       local pv = p:getVipDays()
       local pp = p:getPremiumDays()
        if pp > 0 and pv > 0 and st > 2400 then
            return k*(1.5+1.2) .. " (vip exp and stamina bonus) "
        elseif pv > 0 and st < 840 then
            return k*(0.5+0.2) .. " (penalty for stamina too low) "
        elseif pp > 0 and pv == 0 and st > 2400 then
            return k*1.5 .. " (stamina bonus) "
        elseif pv == 0 and st < 840 then
            return k*0.5 .. " (stamina penalty) "
        elseif pp > 0 and pv == 0 and st > 841 and st < 2399 then
            return k .. " (normal) "
        elseif pp > 0 and pv > 0 and st > 841 and st < 2399 then
            return k*1.2 .. " (vip bonus) "
        elseif pp == 0 and pv > 0 and st > 841 and st < 2399 then
            return k*1.2 .. " (vip bonus) "
        elseif st < 1 then
           return 0 .. " (out of stamina) "
--        else
--           return k .. "(aqui)"
        end
    end

   if words == "!exp" then
     local lv = p:getLevel()
     p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You need " .. ((50 * lv^3) - (150 * lv^2) + (400 * lv)) / 3 - p:getExperience() .. " experience more, for " .. lv+1 .. " level.")
     p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Current rate: x" .. s(p, lv))
     return false
   end
  p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "You have to spend " .. math.ceil((p:getVocation():getRequiredManaSpent(p:getBaseMagicLevel() + 1) - p:getManaSpent()) / configManager.getNumber(configKeys.RATE_MAGIC))  .. " mana more, for next magic level.")
return false
end

i tried to make every possible option, and sorry for being noob, how could i use print to see wht is happening? it will be really helpful so i can find the problem :D

the 'else' was to see where it stop.. it it pass all of them and show (aqui) when i use !exp

even if the player meets all requirementes
about player.lua in the first post theres the full code too..
 
print("stufftoprint")
you can also print multiple things at once, either by concatenating values, or just using commas.
print("thing one " .. " thing two")
print("thing1", variable, tablevalue, blablabla)
so what you'd want if doing if conditionone and conditiontwo and conditionthree is to print like this:
print(variableone, variabletwo, variablethree)
May aswell do exactly this:
print(k, st, pv, pp)
it will print the values on one line with a tabspace between them.
 
i got what Lordfire told too.. about having false condition so it wont continue.. i'll print thinsg here to see any relevant information .. i need many cases cuz im going to use premy and vip system together.. both having its bonus stats.. thast why i need checking the possibilities..

also in player.lua..
 
Definitely nothing wrong with having many possible cases, just have to make sure they're all covered. the reason you got the error before, was because none of the cases were true, and there was no else statement so it returned nil, and then the second sendTextMessage errored out by trying to concatenate a nil value.
 
If you want a clue, don't return everywhere. Calculate the bonus progressively, then return the final value.

For instance:
Code:
bonus = 1.0
if player:getVipDays() > 0 then
  bonus = bonus * 1.2
end
if player:isPremium() then
  bonus = bonus * 1.5
end
return bonus
 
Code:
p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Current rate: x" .. s(p, lv))
concatenation is when you combine strings together. the '..' does this. It's like math, but for strings.
when you call s(p, lv) and try to add it into the other string, it causes an error, because the function did not return a value, because it hit an unhandled case. If it doesn't return a value, it's considered nil. It doesn't exist. And you can't add nil to a string, number or anything. It isn't a real value. That's why the console error told you that it was attempting to concatenate a nil value.
 
If you want a clue, don't return everywhere. Calculate the bonus progressively, then return the final value.

For instance:
Code:
bonus = 1.0
if player:getVipDays() > 0 then
  bonus = bonus * 1.2
end
if player:isPremium() then
  bonus = bonus * 1.5
end
return bonus
i'll try , this one apepar to be a better code

Code:
p:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, "Current rate: x" .. s(p, lv))
concatenation is when you combine strings together. the '..' does this. It's like math, but for strings.
when you call s(p, lv) and try to add it into the other string, it causes an error, because the function did not return a value, because it hit an unhandled case. If it doesn't return a value, it's considered nil. It doesn't exist. And you can't add nil to a string, number or anything. It isn't a real value. That's why the console error told you that it was attempting to concatenate a nil value.

thanks for explanation

i was starting to right every possibility and well no error for metting more than 2 cases :D

the print 7 2520 10 10 from

Code:
        if pp > 0 and pv > 0 and st > 2400 then
            print(k, st, pv, pp)
            return k*(1.5+1.2) .. " (vip exp and stamina bonus) "
        else
           return k .. "(aqui)"
        end

and in-game

03:00 You need 359 experience more, for 5 level.
03:00 Current rate: x18.9 (vip exp and stamina bonus)
 
generally you'd want to do the print before the first if statement, so if it doesn't pass a statement, you can still see why. if one of those had been false, it would not have printed anything
 
i have only one by now.. i did it to test what LordFire said about ..

I think you are hitting a short circuiting. It happens when you have all ands and one of them is false, or all ors and one of them is true. When one of the conditions is false, all of them together can't be true (by the rule X and FALSE = FALSE), so if the second one is false, the third and fourth never get even tested.

but i'll add another and print it after.. i think my mistake was to do all at once.. im starting on it.. and i'll test 1 by one.. till make it fit to my need.. i'll use the LordFire code after.. to see how works better.. and then i'll go to player lua.. cuz this code is only to show how much, not to make the char gain the exp.. anyway.. cuz both of you i got it and i understood it better.. :D

but i'll post here what it gives me after adding more statements

Sorry for my bad english :p
 
You'll want this:
Code:
print(k, st, pv, pp)
if pp > 0 and pv > 0 and st > 2400 then
return k*(1.5+1.2) .. " (vip exp and stamina bonus) "
else
return k .. "(aqui)"
end
The way you had it, it won't print if the statement ends up false. the print is just to check what the values are, so we want that to happen first, in case the checks don't return true.
 
:D im getting it slowly :D right now i have it

Code:
        print(k, st, pv, pp)
        if pp > 0 and pv > 0 and st > 2400 then
            return k*(1.5+1.2) .. " (vip exp and stamina bonus) "
        elseif pp == 0 and pv > 0 and st > 2400 then
            return k*1.2 .. " (vip bonus) "
        else
           return k .. "(all false)"
        end
(i still need to use LordFire code.. but right now im just testing to see where i'll get an error)
and im making tests

char free with vip and full stamina (console)
Code:
7       2520    10      0

(in-game)
Code:
03:21 You need 100 experience more, for 2 level.
03:21 Current rate: x8.4 (vip bonus)

char free, no vip, and full stamina (sonsole)
Code:
7       2520    0       0

(in-game)
Code:
03:21 You need 100 experience more, for 2 level.
03:21 Current rate: x7(all false)

char premium, vip and full stamina (console)
Code:
7       2520    10      10

(in-game)
Code:
03:26 You need 359 experience more, for 5 level.
03:26 Current rate: x18.9 (vip exp and stamina bonus)


so may i assume that is the same way in player.lua?

Code:
    -- Stamina modifier
    if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then
        useStamina(self)

        local staminaMinutes = self:getStamina()
        if staminaMinutes > 2400 and self:isPremium() then
            exp = exp * 1.5
        elseif staminaMinutes <= 840 then
            exp = exp * 0.5
        elseif staminaMinutes > 2400 and self:isPremium() and self:isVip() then
            exp = exp * (1.5 + 1.2)
        elseif staminaMinutes <= 840 and self:isVip() then
            exp = exp * (0.5 + 0.2)
        elseif staminaMinutes < 2399 and staminaMinutes > 841 and self:isVip() then
            exp = exp * 1.2
        end
    end
 
As long as you have an 'else' statement, you shouldn't get any errors. Assuming the return value from the else is not nil.
else means if it isn't any of the above if/elseif statements, it'll do what's after the else. It's a catch-all fail-safe.
 
Back
Top Bottom