A job for a bored scripter!

Post Reply
bluekirby0
Developer
Posts: 707
Joined: Sun Jul 22, 2012 12:11 am

A job for a bored scripter!

Post by bluekirby0 » Tue Sep 18, 2012 10:24 pm

Ok, so we have a lot of quests that were written a while ago, and while they are rock solid, things could be a bit more efficient. ZeDingo has been going through and making all the appropriate variables into locals, but one thing that will take a bit of thought to fix up are all the quests that store variables with bitmasks.

If you see something like this in a LUA script:

Code: Select all

npc1 = 1
npc2 = 2
npc3 = 4
npc4 = 8
then things can be improved! There is a set of three LUA functions that are fairly new (only added about 3-4 months ago) that are made for handling stuff like this. Those functions are:

Code: Select all

setMaskBit(varname,position,state)
getMaskBit(varname,position)
isMaskFull(varname,size)
Now it might not be terribly obvious how those work unless you are familiar with bitmasks already. The only things you need to know are:
  1. You now have to use getVar to retrieve the value before using these functions!
  2. They are only useful for true/false values. If you need something more complex, then use setVar/getVar instead.
  3. They can be used to store a lot of true/false related to the same quest values in a single variable for quick lookup.
  4. The "varname" should be something unique to the quest, and is stored in the same place setVar stores things, so you should not try to share a name with another variable.
  5. Position should start from 0 and count up by 1 for each additional value you need to store. Do not leave gaps in positions.
  6. State is a true or false condition, and should by entered as true or false
  7. getMaskBit and isMaskFull return true or false, and can be evaluated without a comparison in an if statement.
  8. getMaskBit should be used to test a single position, while isMaskFull should be used to see if ALL of the positions are true.
  9. setMaskBit now returns a value! Be sure to update your variable with the value it returns or you will be testing against an outdated variable!
  10. Size should be the highest position number used in your quest.
  11. When you no longer need the mask, you erase it just like a normal variable via setVar(varname,0)
So, for a practical example of how all this works, you can reference scripts/zones/Norg/npcs/Mamaulabion.lua where all of the logic is contained in a single script. You will probably need to make changes in several scripts for other quests. If you have any questions, ask me here or in IRC!

EDIT: The proper use of these functions has changed! Take a fresh look at Mamaulabion's script and the bold points above for changes!

thrydwolf
Posts: 30
Joined: Sat Aug 25, 2012 5:32 am

Re: A job for a bored scripter!

Post by thrydwolf » Sat Sep 29, 2012 9:48 pm

Thanks Blue! I did 1 or two quests with the previous bitmask functions last year, so I will go back and update those. I think I may try to fix others are well. Thanks!!!

thrydwolf
Posts: 30
Joined: Sat Aug 25, 2012 5:32 am

Re: A job for a bored scripter!

Post by thrydwolf » Sat Sep 29, 2012 10:45 pm

I have a request, can you add another function that counts the number of positions that have the state passed?

countBitMask(varname,state,size)

Thanks!!!

bluekirby0
Developer
Posts: 707
Joined: Sun Jul 22, 2012 12:11 am

Re: A job for a bored scripter!

Post by bluekirby0 » Mon Oct 01, 2012 9:15 am

You mean you need a count of how many bits are set to true/1? If so then you wouldn't need to pass a state to it...just a variable and a size. You could also implement it directly in LUA but it would be kind of a pain without bitwise operators available (it would involve a lot of conditional arithmetic).

If you really need to count how many are false with something like that, then (size - countBitMask(varname,size) could still do that for you.

thrydwolf
Posts: 30
Joined: Sat Aug 25, 2012 5:32 am

Re: A job for a bored scripter!

Post by thrydwolf » Mon Oct 01, 2012 10:56 pm

Yeah, I think a function for counting the true bitmasks would be great. I don't see it in lua_baseentity. It would sure beat my method (which I have not tested yet):

Code: Select all

local count = 0;
if (getMaskBit(QuestHatInHand_var,1)) then count = count + 1; end
if (getMaskBit(QuestHatInHand_var,2)) then count = count + 1; end
if (getMaskBit(QuestHatInHand_var,3)) then count = count + 1; end
if (getMaskBit(QuestHatInHand_var,4)) then count = count + 1; end
if (getMaskBit(QuestHatInHand_var,5)) then count = count + 1; end 
if (getMaskBit(QuestHatInHand_var,6)) then count = count + 1; end
if (getMaskBit(QuestHatInHand_var,7)) then count = count + 1; end
if (getMaskBit(QuestHatInHand_var,8)) then Count = count + 1; end

bluekirby0
Developer
Posts: 707
Joined: Sun Jul 22, 2012 12:11 am

Re: A job for a bored scripter!

Post by bluekirby0 » Tue Oct 02, 2012 2:09 am

http://code.google.com/p/onetimexi/source/detail?r=1842

I will warn you now since I read the wiki page on that quest, that those functions only handle 32-bit values so if you set size to something bigger than 32 with any of the MaskBit functions you will get a bogus result. In other words, if you store all of the 133 NPCs that can trigger for that quest in the same bitmask, you won't be able to read it correctly with these functions.

If you have a legitimate need to work around that, then there are tricks you can use...let me know.

User avatar
diatanato
Developer
Posts: 112
Joined: Thu Aug 30, 2012 9:59 pm

Re: A job for a bored scripter!

Post by diatanato » Tue Oct 02, 2012 7:37 am


thrydwolf
Posts: 30
Joined: Sat Aug 25, 2012 5:32 am

Re: A job for a bored scripter!

Post by thrydwolf » Tue Oct 02, 2012 8:19 pm

Thanks Blue and Diatanato!!! This will make scripting certain quests MUCH easier. Wahoo!!!!

Post Reply