Temporary home page.
Useful engine stuff
Functions stuff
Useful trick when dealing with functions with multiple returned values :
function first(a, b)
end
function second()
return a, b
end
Calling first(second()) will pass both output values from second() as the two input values of first().
The function iif(cond, if_true, if_false) is dangerous to those who already used the A?B:C operator in C (or similar), because it doesn't work in the same way. No matter the value of the condition, both values (if_true and if_false) will be evaluated, so you cannot use iif in that example (you'll get SIGFPE if I remember correctly) :
value = rand(0,5) stuff = iif(value ~= 0, 1000 / value, 999999)
Flag stuff
new_copy = flag_dup(old_copy) is needed whenever you need to copy a flagset that will be modified later. It makes a deep copy of the flagset.
flag_free(old_flag, true) must be called everytime you stop using a flagset, to avoid memory leak.
There are two ways to iterate through a flagset :
for iter = 1, flag_max_key(flag) do
if flag[iter] then
-- Do stuff
end
end
Or
for iter = 1, flag.size do
if (flag.node[iter].flags & FLAG_FLAG_USED) ~= 0 then
-- Do stuff
end
end
The second method is faster, particularly when the keys can take very large values, but you don't get any guarantee on the order of traversal.
Debugging
To print stuff to the console instead of the main screen, use the print() command instead of message().
Repeating Keys
If you want the player to be able to use 'n' to repeat the use of a skill, or use SLAK to create macro using said skill, you need to use repeat_keys. There are two functions : repeat_keys.pull() and repeat_keys.push(). push() store one number, while pull() get it back. Example :
local ret, rep = repeat_keys.pull()
if not ret then
-- Ask for user input and put it in rep
repeat_keys.push(rep)
end
-- Do stuff with rep
You can easily chain more than one pull() or push() if you need to store more than one number. But you need have the same number of each. The most important thing to remember is that you can store any number, not only key presses.
Item management
Many items function need the item index instead the item object. A good way to get it is by using the compute_slot() function. Once you have that, you can also use the get_object() function to get the item object.
item = compute_slot(inven, index) obj1 = get_object(item) obj2 = player.inventory[inven][index]
Both obj1 and obj2 will refer to the same item object.
Monster memory system
Lets say you want to add some information in the monster recall display. You simply need to add a new entry using memory.entrydesc_add(). The second parameter to that function should be another function taking a race pointer and a table as arguments, and returning a string.
function memory.example(r_ptr, entry)
return "Something."
end
memory.entrydesc_add("example", memory.example)
Now, lets say you actually want the player to learn the displayed information :
Kills dependent information
This is the easy way to do it. The player will be able to see more and more information as his character (and his ancestors) kill more of the creature. You should grab the r_tkills variable of the race pointer, which houses the number of kills from both the character and his ancestors.
function memory.example(r_ptr, entry)
local kills = r_ptr.r_tkills
if kills >= 50 then
return " @It@ hates you."
else
return " You do not know if @it@ likes you or not."
end
end
Note : The string returned will be processed to change all the pronouns to the correct ones. So @it@ will either become it, he or she.
Direct knowledge
If you want to have the player learns information whenever he is in contact with it, you need to a little more work. For example, if you want the player only learn about the monster AC when he attack it, then you need to store the information whenever the player attacks a monster.
First, you need to declare a new category. You should avoid numbers from 0 to 5 since they are used in the engine.
memory.RT_AC = 1000
Then the information will be stored in deep_get{memory.get_entry(race_info(m_ptr),m_ptr.ego),category}, where category is what you just declared. Note : the data can be a table.
-- Player attack code
deep_get{memory.get_entry(race_info(m_ptr),m_ptr.ego),memory.RT_AC} = true
And in the memory code, you can get back the information :
function memory.ac(r_ptr, entry)
local known = deep_get{entry,memory.RT_AC}
if known then
return " AC = "..r_ptr.ac.."."
else
return ""
end
end
Note : Instead of only storing a boolean value in the memory, you could store a counter which would be incremented each time the player get some information, and make the memory depends on that counter.
ToME Wiki