I'm getting stuck on the following. Probably pretty easy for you all, but I'm relatively new to LUA scripting.
return function ()
local getuservar = gma.user.getvar
local cmd = function(syntax, ...)
gma.cmd(syntax:format(...))
end
local Effect_Attribute = getuservar('Effect_Attribute')
local Effect_Group = getuservar('Effect_Group')
local Form = getuservar('Effect_Dim_Gr1')
cmd('copy image "B Form %s Active" at "B Effect Form %s %s" /m',Form, Effect_Attribute, Effect_Group)
end
That works perfectly.
What I would like to do is to create a string formatting for the getuservar, that looks something like:
local Effect_Attribute = getuservar('Effect_Attribute')
local Effect_Group = getuservar('Effect_Group')
local Form = getuservar('Effect_%s_%s', Effect_Attribute, Effect_Group)
How should I change the part of
local cmd = function(syntax, ...)
gma.cmd(syntax:format(...))
end
So, that I could use this style of formatting for my getuservar?
Related
I want to create a mapping in my neovim lua setup such that when I have a visual selection and hit <leader>ps, a telescope search is initiated with the selected text.
Here is what I have for the moment:
local builtin = require('telescope.builtin')
local function get_visual_selection()
local s_start = vim.fn.getpos("'<")
local s_end = vim.fn.getpos("'>")
local n_lines = math.abs(s_end[2] - s_start[2]) + 1
local lines = vim.api.nvim_buf_get_lines(0, s_start[2] - 1, s_end[2], false)
lines[1] = string.sub(lines[1], s_start[3], -1)
if n_lines == 1 then
lines[n_lines] = string.sub(lines[n_lines], 1, s_end[3] - s_start[3] + 1)
else
lines[n_lines] = string.sub(lines[n_lines], 1, s_end[3])
end
return table.concat(lines, '\n')
end
vim.keymap.set('n', '<leader>ps', function() -- works fine
builtin.grep_string({ search = vim.fn.input("Grep > ") });
end)
vim.keymap.set('v', '<leader>ps', function() -- gets the same first value for sel everytime!
local sel = get_visual_selection();
builtin.grep_string({ search = vim.fn.input("Grep > " .. sel) });
end)
This code works on the first time; but then the first text retrieved from selection never changes! I get the first text I selected over and over. I don't understand what is causing that. It seems the function gets hit by some sort of caching mechanism from lua...?
I finally used a different and simpler way of doing this exact thing using a remap, yank and paste; I still don't know what's wrong in my question's lua script though.
Here is the working lua map:
vim.keymap.set('v', '<leader>ps', 'y<leader>ps<C-r>*', { remap = true });
Hello I am trying to get some data from a text file and put it into a table.
Im not sure how to add more then one pattern while also doing what I want, I know this pattern by its self %a+ finds letters and %b{} finds brackets, but I am not sure how to combine them together so that I find the letters as a key and the brackets as a value and have them be put into a table that I could use.
text file :
left = {{0,63},{16,63},{32,63},{48,63}}
right = {{0,21},{16,21},{32,21},{48,21}}
up = {{0,42},{16,42},{32,42},{48,42}}
down = {{0,0},{16,0},{32,0},{48,0}}
code:
local function get_animations(file_path)
local animation_table = {}
local file = io.open(file_path,"r")
local contents = file:read("*a")
for k, v in string.gmatch(contents, ("(%a+)=(%b{})")) do -- A gets words and %b{} finds brackets
animation_table[k] = v
print("key : " .. k.. " Value : ".. v)
end
file:close()
end
get_animations("Sprites/Player/MainPlayer.txt")
This is valid Lua code, why not simply execute it?
left = {{0,63},{16,63},{32,63},{48,63}}
right = {{0,21},{16,21},{32,21},{48,21}}
up = {{0,42},{16,42},{32,42},{48,42}}
down = {{0,0},{16,0},{32,0},{48,0}}
If you don't want the data in globals, use the string library to turn it into
return {
left = {{0,63},{16,63},{32,63},{48,63}},
right = {{0,21},{16,21},{32,21},{48,21}},
up = {{0,42},{16,42},{32,42},{48,42}},
down = {{0,0},{16,0},{32,0},{48,0}},
}
befor you execute it.
If you insist on parsing that file you can use a something like this for each line:
local line = "left = {{0,63},{16,63},{32,63},{48,63}}"
print(line:match("^%w+"))
for num1, num2 in a:gmatch("(%d+),(%d+)") do
print(num1, num2)
end
This should be enough to get you started. Of course you wouldn't print those values but put them into a table.
I'm currently starting work on a text adventure game in Lua--no addons, just pure Lua for my first project. In essence, here is my problem; I'm trying to find out how I can do a "reverse lookup" of a table using one of its variables. Here's an example of what I've tried to do:
print("What are you trying to take?")
bag = {}
gold = {name="Gold",ap=3}
x = io.read("*l")
if x == "Gold" then
table.insert(bag,gold)
print("You took the " .. gold.name .. ".")
end
Obviously, writing a line like this with every single object in the game would be very... exhausting--especially since I think I'll be able to use this solution for not just taking items but movement from room to room using a reverse lookup with each room's (x,y) coordinates. Anyone have any ideas on how to make a more flexible system that can find a table by the player typing in one of its variables? Thanks in advance!
-blockchainporter
This doesn't directly answer your question as you asked it, but I think it would serve the purpose of what you are trying to do. I create a table called 'loot' which can hold many objects, and the player can place any of these in their 'bag' by typing the name.
bag = {}
loot = {
{name="Gold", qty=3},
{name="Axe", qty=1},
}
print("What are you trying to take?")
x = io.read("*l")
i = 1
while loot[i] do
if (x == loot[i].name) then
table.insert(bag, table.remove(loot,i))
else
i = i + 1
end
end
For bonus points, you could check 'bag' to see if the player has some of that item already and then just update the quantity...
while loot[i] do
if (x == loot[i].name) then
j, found = 1, nil
while bag[j] do
if (x == bag[j].name) then
found = true
bag[j].qty = bag[j].qty + loot[i].qty
table.remove(loot,i)
end
j = j + 1
end
if (not found) then
table.insert(bag, table.remove(loot,i))
end
else
i = i + 1
end
end
Again, this isn't a 'reverse lookup' solution like you asked for... but I think it is closer to what you are trying to do by letting a user choose to loot something.
My disclaimer is that I don't use IO functions in my own lua usage, so I have to assume that your x = io.read("*l") is correct.
PS. If you only ever want objects to have a name and qty, and never any other properties (like condition, enchantment, or whatever) then you could also simplify my solution by using key/val pairs:
bag = {}
loot = { ["Gold"] = 3, ["Axe"] = 1 }
print("What are you trying to take?")
x = io.read("*l")
for name, qty in pairs(loot) do
if x == name then
bag.name = (bag.name or 0) + qty
loot.name = nil
end
end
I have a few notes to start before I specifically address your question. (I just want to do this before I forget, so please bear with me!)
I recommend printing to the terminal using stderr instead of stdout--the Lua function print uses the latter. When I am writing a Lua script, I often create a C-style function called eprintf to print formatted output to stderr. I implement it like this:
local function eprintf(fmt, ...)
io.stderr:write(string.format(fmt, ...))
return
end
Just be aware that, unlike print, this function does not automatically append a newline character to the output string; to do so, remember to put \n at the end of your fmt string.
Next, it may be useful to define a helper function that calls io.read("*l") to get an entire line of input. In writing some example code to help answer your question, I called my function getline--like the C++ function that has similar behavior--and defined it like this:
local function getline()
local read = tostring(io.read("*l"))
return read
end
If I correctly understand what it is you are trying to do, the player will have an inventory--which you have called bag--and he can put items into it by entering item names into stdin. So, for instance, if the player found a treasure chest with gold, a sword, and a potion in it and he wanted to take the gold, he would type Gold into stdin and it would be placed in his inventory.
Based on what you have so far, it looks like you are using Lua tables to create these items: each table has a name index and another called ap; and, if a player's text input matches an item's name, the player picks that up item.
I would recommend creating an Item class, which you could abstract nicely by placing it in its own script and then loading it as needed with require. This is a very basic Item class module I wrote:
----------------
-- Item class --
----------------
local Item = {__name = "Item"}
Item.__metatable = "metatable"
Item.__index = Item
-- __newindex metamethod.
function Item.__newindex(self, k, v)
local err = string.format(
"type `Item` does not have member `%s`",
tostring(k)
)
return error(err, 2)
end
-- Item constructor
function Item.new(name_in, ap_in)
assert((name_in ~= nil) and (ap_in ~= nil))
local self = {
name = name_in,
ap = ap_in
}
return setmetatable(self, Item)
end
return Item
From there, I wrote a main driver to encapsulate some of the behavior you described in your question. (Yes, I know my Lua code looks more like C.)
#!/usr/bin/lua
-------------
-- Modules --
-------------
local Item = assert(require("Item"))
local function eprintf(fmt, ...)
io.stderr:write(string.format(fmt, ...))
return
end
local function printf(fmt, ...)
io.stdout:write(string.format(fmt, ...))
return
end
local function getline()
local read = tostring(io.read("*l"))
return read
end
local function main(argc, argv)
local gold = Item.new("Gold", 3)
printf("gold.name = %s\ngold.ap = %i\n", gold.name, gold.ap)
return 0
end
main(#arg, arg)
Now, as for the reverse search which you described, at this point all you should have to do is check the user's input against an Item's name. Here it is in the main function:
local function main(argc, argv)
local gold = Item.new("Gold", 3)
local bag = {}
eprintf("What are you trying to take? ")
local input = getline()
if (input == gold.name) then
table.insert(bag, gold)
eprintf("You took the %s.\n", gold.name)
else
eprintf("Unrecognized item `%s`.\n", input)
end
return 0
end
I hope this helps!
So, I want to make a converter GUI, converting Bitcoin to Dollar. I use a textbox to get the user input and a text button to submit. But, when I type number for example 8 to the textbox while test the game and print what is inside the textbox, it printed nothing. Even though I have type 8 to the text box. Thanks for all the answers! Here is the code I use.
-- text variable below
local input = script.Parent
local val = input.Text
-- button variable below
local submit = input:FindFirstChild("btcSubmit")
-- player variable below
local gams = game.Players.LocalPlayer
local ld = gams:WaitForChild("leaderstats")
local bitcoin = ld:WaitForChild("Bitcoin").Value
local dollar = ld:WaitForChild("Dollar").Value
-- function
function btcEx()
val = tonumber(val)
if val > bitcoin then
val = tostring(val)
val = "Sorry, your Bitcoin isn't enough"
wait(4)
val = "Input the number of bitcoin you want to exchange here!"
else
dollar = val * 8000
val = tostring()
end
end
submit.MouseButton1Click:Connect(btcEx)
When you set a variable to a value rather than a reference, it remains that value until you change it.
object.Value = 5
local myValue = object.Value
object.Value = 10
print(myValue) -- Prints 5.
This happens because they are not linked and thus changes do not carry over, like these variables below:
local a = 5
local b = a
a = 10
print(b) -- Prints 5, because b was never changed (but a was).
What you want to do is define your button and your value-objects as references, and simply access .Text or .Value when you need to read the value.
local myButton = button
button.Text = "Howdy!"
print(myButton.Text) -- Prints "Howdy!"
myButton.Text = "Hey there" -- this is the same as button.Text
print(myButton.Text) -- Prints "Hey there"
I am having a lua function to reading and writing a txt file, I need every time lua write in at a new line instead of replacing the previous write in. How do I do that? Do I need to read in and get the lines 1st every time before I write in?
Here is my code:
local function FileOutput(name)
local f = io.open(name, "w+")
local meta = {
__call = function(t, str) f:write(str .. '\n') end,
__gc = function() f:close() end
}
return setmetatable({}, meta)
end
function writeRec()
LOG("writing")
local testfile = FileOutput(getScriptDirectory()..'/textOutput.txt')
testfile('oh yes!')
testfile = nil
end
Have you tried a+ instead of w+?
http://www.lua.org/manual/5.1/manual.html#pdf-io.open