Ok, so I am trying to create a text-based adventure game. I am currently creating the attack system. Here is the code
start = io.read()
if start == "start" then
ma1 = "jab your opponent"
ma2 = "hook your oppenent"
fa1 = "kick your oppenent"
ha1 = "headbutt your oppenent"
--Melee weapon
mw1 = "fist1"
mw2 = "fist2"
foot = "Kick"
head = "headbutt"
--Magic attacks
ms1 = "none"
ms2 = "none"
ms3 = "none"
ms4 = "none"
--Gadgets
bow = "none"
gun = "none"
sg = "none"
function atk()
io.write("Do you use melee(1), magic(2), or tech(3)?", "\n")
ac = io.read()
if ac == "1" then
io.write("Do you", ma1,",", ma2, ",",fa1,",or",ha1"?", "\n")
end
end
end
print(atk())
Every time I run this it outputs this:
lua: jdoodle.lua:25: global 'ha1' is not callable (a string value)
stack traceback:
jdoodle.lua:25: in function 'atk'
jdoodle.lua:29: in main chunk
[C]: in ?
So if you have any solutions thank you.
You missed a comma:
start = io.read()
if start == "start" then
--body
if ac == "1" then
io.write("Do you", ma1, ", ", ma2, ", ", fa1, ", or", ha1, "?", "\n")
end
end
print(atk())
Related
I was making custom chat system and I faced this "bug".
just textbox returns "", not nil.
and there is no any error. even without
string.len(script.Parent.Parent.message.Text) > 0
"if" part.
local db = false
local TextService = game:GetService("TextService")
script.Parent.MouseButton1Click:Connect(function ()
local plr = script.Parent.Parent.Parent.Parent.Parent.Parent
local dn = plr.Character.Humanoid.DisplayName
local muted = script.Parent.muted.Value
local mod = script.Parent.moderator.Value
if db == false and muted == false and string.len(script.Parent.Parent.message.Text) > 0 then
db = true
local ts = 16
local msg = script.Parent.Parent.chat.message0:Clone()
--problem line
msg.messageContent.Text = TextService:FilterStringAsync(script.Parent.Parent.message.Text, plr.UserId, "2")
if string.len(script.Parent.Parent.message.Text) > 130 then
ts = 14
end
msg.messageContent.TextSize = ts
--problem ends
local ps = msg.prefixes
ps.bot.Visible = false
local counter = game.ReplicatedStorage.ChatBlockStorage.counter.Value
msg.Name = "message" .. counter
msg.actualName.Text = "#" .. plr.Name
msg.displayName.Text = dn
msg.icon.Image = game.Players:GetUserThumbnailAsync(plr.UserId, Enum.ThumbnailType.HeadShot, Enum.ThumbnailSize.Size420x420)
msg.icon.ResampleMode = "Default"
if script.Parent.Parent.message.customIcon.locked.Visible == false then
msg.icon.Image = "http://www.roblox.com/asset/?id=" .. script.Parent.Parent.message.customIcon.Text
end
if msg.Name == "message1" then
mod = true
end
if mod == true then
ps.mod.Visible = true
end
counter += 1
script.Parent.Parent.message.Text = ""
wait(game.ReplicatedStorage.ChatBlockStorage.waitTime.Value)
db = false
end
end)
any ideas how to fix it?
Use the FocustLost event. Here is the roblox documentation on it.
Example:
script.Parent.FocusLost:Connect(function(enterPressed)
if enterPressed then
print("Focus was lost because enter was pressed!")
end
end)
Near the end of the code, you write
script.Parent.Parent.message.Text = ""
Would this not be the cause?
maybe you can do tostring(msg)?
this prob wont work
tostring("i like beans")
read more on strings here:https://developer.roblox.com/en-us/articles/String
read more on tostring() here: https://devforum.roblox.com/t/what-does-assert-and-tostring-do/1047653
(none are people i know but i looked through them and they have valid info)
good luck my brother
i'm currently using a lua script by taran van hemert,where it save every keypress on text file and autohotkey will detect every keypress based on that text file, and i'm just wondering how i can make shift work on other keys, i mean when i press shift+2 it will display "#" at the text file. does anyone know how to do it?
-- note that some of the code has changed since then (it works better now!)
-- Though, I have since abandoned luamacros, in favor of Interception... which i will abandon in favor of QMK.
-- get luamacros HERE: http://www.hidmacros.eu/forum/viewtopic.php?f=10&t=241#p794
-- plug in your 2nd keyboard, load this script into LUAmacros, and press the triangle PLAY button.
-- Then, press any key on that keyboard to assign logical name ('MACROS') to macro keyboard
clear() --clear the console from last run
local keyboardIdentifier = '0000AAA'
--You need to get the identifier code for the keyboard with name "MACROS"
--This appears about halfway through the SystemID item and looks like 1BB382AF or some other alphanumeric combo.
-- It's usually 7 or 8 characters long.
--Once you have this identifier, replace the value of keyboardIdentifier with it
--Don't ask for keyboard assignment help if the user has manually entered a keyboard identifier
if keyboardIdentifier == '0000AAA' then
lmc_assign_keyboard('MACROS');
else lmc_device_set_name('MACROS', keyboardIdentifier);
end
--This lists connected keyboards
dev = lmc_get_devices()
for key,value in pairs(dev) do
print(key..':')
for key2,value2 in pairs(value) do print(' '..key2..' = '..value2) end
end
print('You need to get the identifier code for the keyboard with name "MACROS"')
print('Then replace the first 0000AAA value in the code with it. This will prevent having to manually identify keyboard every time.')
-- Hide window to tray to keep taskbar tidy
lmc.minimizeToTray = true
--lmc_minimize()
--Start Script
sendToAHK = function (key)
--print('It was assigned string: ' .. key)
local file = io.open("C:\\Users\\Jhon Ryven\\Desktop\\2nd keyboard macros\\keypressed.txt", "w") -- writing this string to a text file on disk is probably NOT the best method. Feel free to program something better!
--If you didn't put your AutoHotKey scripts into C:/AHK, Make sure to substitute the path that leads to your own "keypressed.txt" file, using the double backslashes.
--print("we are inside the text file")
file:write(key)
file:flush() --"flush" means "save." Lol.
file:close()
lmc_send_keys('{F24}') -- This presses F24. Using the F24 key to trigger AutoHotKey is probably NOT the best method. Feel free to program something better!
end
local config = {
[45] = "insert",
[36] = "home",
[33] = "pageup",
[46] = "delete",
[35] = "end",
[34] = "pagedown",
[27] = "escape",
[112] = "F1",
[113] = "F2",
[114] = "F3",
[115] = "F4",
[116] = "F5",
[117] = "F6",
[118] = "F7",
[119] = "F8",
[120] = "F9",
[121] = "F10",
[122] = "F11",
[123] = "F12",
[8] = "backspace",
[220] = "backslash",
[13] = "enter",
[16] = "rShift",
[17] = "rCtrl",
[38] = "up",
[37] = "left",
[40] = "down",
[39] = "right",
[32] = "space",
[186] = "semicolon",
[222] = "singlequote",
[190] = "period",
[191] = "slash",
[188] = "comma",
[219] = "leftbracket",
[221] = "rightbracket",
[189] = "minus",
[187] = "equals",
[96] = "num0",
[97] = "num1",
[98] = "num2",
[99] = "num3",
[100] = "num4",
[101] = "num5",
[102] = "num6",
[103] = "num7",
[104] = "num8",
[105] = "num9",
[106] = "numMult",
[107] = "numPlus",
[108] = "numEnter", --sometimes this is different, check your keyboard
[109] = "numMinus",
[110] = "numDelete",
[111] = "numDiv",
[144] = "numLock", --probably it is best to avoid this key. I keep numlock ON, or it has unexpected effects
[192] = "Sc029", --this is the tilde key just before the number row
[9] = "tab",
[20] = "capslock",
[18] = "alt",
[91] = "winkey",
[string.byte('Q')] = "q",
[string.byte('W')] = "w",
[string.byte('E')] = "e",
[string.byte('R')] = "r",
[string.byte('T')] = "t",
[string.byte('Y')] = "y",
[string.byte('U')] = "u",
[string.byte('I')] = "i",
[string.byte('O')] = "o",
[string.byte('P')] = "p",
[string.byte('A')] = "a",
[string.byte('S')] = "s",
[string.byte('D')] = "d",
[string.byte('F')] = "f",
[string.byte('G')] = "g",
[string.byte('H')] = "h",
[string.byte('J')] = "j",
[string.byte('K')] = "k",
[string.byte('L')] = "l",
[string.byte('Z')] = "z",
[string.byte('X')] = "x",
[string.byte('C')] = "c",
[string.byte('V')] = "v",
[string.byte('B')] = "b",
[string.byte('N')] = "n",
[string.byte('M')] = "m",
[string.byte('0')] = "0",
[string.byte('1')] = "1",
[string.byte('2')] = "2",
[string.byte('3')] = "3",
[string.byte('4')] = "4",
[string.byte('5')] = "5",
[string.byte('6')] = "6",
[string.byte('7')] = "7",
[string.byte('8')] = "8",
[string.byte('9')] = "9",
[255+44] = "printscreen",
[145] = "scrolllock",
}
-- define callback for whole device
lmc_set_handler('MACROS', function(button, direction)
--Ignoring upstrokes ensures keystrokes are not registered twice, but activates faster than ignoring downstrokes. It also allows press and hold behaviour
if (direction == 0) then return end -- ignore key upstrokes.
if type(config[button]) == "string" then
print(' ')
print('Your key ID number is: ' .. button)
print('It was assigned string: ' .. config[button])
sendToAHK(config[button])
else
print(' ')
print('Not yet assigned: ' .. button)
end
end) ```
According to what I have found online there should be a 4th parameter flags that gives you information about modifier keys.
log_handler = function(button, direction, ts, flags)
print('Callback for device: button ' .. button .. ', direction '..direction..', ts '..ts..', flags '..flags)
end
Alternatively you remember if shift is pressed. You handle its downstroke so you know that it is pressed right?
Edit:
Modify the code like so, to get access to the flags parameter.
For further information I'd refer you to the Lua users manual. You cannot modify what you do not understand. Sorry.
lmc_set_handler('MACROS', function(button, direction, ts, flags)
print(flags)
--Ignoring upstrokes ensures keystrokes are not registered twice, but activates faster than ignoring downstrokes. It also allows press and hold behaviour
if (direction == 0) then return end -- ignore key upstrokes.
if type(config[button]) == "string" then
print(' ')
print('Your key ID number is: ' .. button)
print('It was assigned string: ' .. config[button])
sendToAHK(config[button])
else
print(' ')
print('Not yet assigned: ' .. button)
end
end)
If someone could please help, that would be great! I'm fairly new to coding, but am trying to create a basic automated trading strategy in Indicore 3, which uses LUA script. Even if you don't know much about trading, you could probably still recognize where I've gone wrong in this code.
Basically I'm trying to automate a buy into a trade when price, is above the FastEMA, the FastEMA is above the MedEMA, and the MedEMA is above the SlowEMA. And a sell trade in the exactly opposite fashion. I'm then wanting to close the trade when, in a buy situation, the Fast EMA is no longer above the MedEMA, and for a sell, the FastEMA rises above the MedEMA.
Plus, if the currency is already in a trade, I don't want it to put another one on. Hence the idea around the HaveTrades function.
Please if you have any idea, give me a shout. Like I say I'm a beginner, however I feel like this is a pretty basic code.
Picture is to illustrate idea. Blue line is FastEMA, Green line is MedEMA, and Red line is SlowEMA.
I used the original code off a 3EMA Indicore tutorial, and have tried to simplify it to what I need, so if there's inconsistencies with the code, please highlight them to me.
function Init()
strategy:name("3EMA test AMI");
strategy:description("No description");
strategy:requiredSource(core.Bar);
strategy:type(core.both);
strategy.parameters:addInteger("FastEMA", "Fast EMA", "No description", 5);
strategy.parameters:addInteger("MedEMA", "Medium Ema", "No description", 20);
strategy.parameters:addInteger("SlowEMA", "Slow EMA", "No description", 50);
strategy.parameters:addGroup("Trading Parameters");
strategy.parameters:addBoolean("AllowTrade", "Allow strategy to trade", "", false);
strategy.parameters:setFlag("AllowTrade", core.FLAG_ALLOW_TRADE);
strategy.parameters:addString("Account", "Account to trade on", "", "");
strategy.parameters:setFlag("Account", core.FLAG_ACCOUNT);
strategy.parameters:addInteger("Amount", "Trade Amount in Lots", "", 1, 1, 100);
strategy.parameters:addBoolean("SetLimit", "Set Limit Orders", "", false);
strategy.parameters:addInteger("Limit", "Limit Order in pips", "", 30, 1, 10000);
strategy.parameters:addBoolean("SetStop", "Set Stop Orders", "", false);
strategy.parameters:addInteger("Stop", "Stop Order in pips", "", 30, 1, 10000);
strategy.parameters:addBoolean("TrailingStop", "Trailing stop order", "", false);
strategy.parameters:addGroup("Notification");
strategy.parameters:addBoolean("ShowAlert", "Show Alert", "", true);
strategy.parameters:addBoolean("PlaySound", "Play Sound", "", false);
strategy.parameters:addBoolean("RecurrentSound", "Recurrent Sound", "", false);
strategy.parameters:addFile("SoundFile", "Sound File", "", "");
strategy.parameters:setFlag("SoundFile", core.FLAG_SOUND);
strategy.parameters:addBoolean("SendEmail", "Send Email", "", false);
strategy.parameters:addString("Email", "Email", "", "");
strategy.parameters:setFlag("Email", core.FLAG_EMAIL);
end
local FastEMA;
local MedEMA;
local SlowEMA;
local EnableStage1TimeRange;
local TimeRangeStart;
local TimeRangeEnd;
local gSource = nil; -- the source stream
local PlaySound;
local RecurrentSound;
local SoundFile;
local Email;
local SendEmail;
local AllowTrade;
local Account;
local Amount;
local BaseSize;
local SetLimit;
local Limit;
local SetStop;
local Stop;
local TrailingStop;
local Offer;
local CanClose;
local iEMAFast;
local iEMAMed;
local iEMASlow;
function Prepare(nameOnly)
FastEMA = instance.parameters.FastEMA;
MedEMA = instance.parameters.MedEMA;
SlowEMA = instance.parameters.SlowEMA;
LookBack = instance.parameters.LookBack;
EnableStage1TimeRange = instance.parameters.EnableStage1TimeRange;
TimeRangeStart = instance.parameters.TimeRangeStart;
TimeRangeEnd = instance.parameters.TimeRangeEnd;
local name = profile:id() .. "(" .. instance.bid:instrument() .. ", " .. tostring(FastEMA) .. ", " .. tostring(MedEMA) .. ", " .. tostring(SlowEMA) .. ", " .. tostring(LookBack).. ", " .. tostring(EnableStage1TimeRange) .. ")";
instance:name(name);
if nameOnly then
return ;
end
ShowAlert = instance.parameters.ShowAlert;
PlaySound = instance.parameters.PlaySound;
if PlaySound then
RecurrentSound = instance.parameters.RecurrentSound;
SoundFile = instance.parameters.SoundFile;
else
SoundFile = nil;
end
assert(not(PlaySound) or (PlaySound and SoundFile ~= ""), "Sound file must be specified");
SendEmail = instance.parameters.SendEmail;
if SendEmail then
Email = instance.parameters.Email;
else
Email = nil;
end
assert(not(SendEmail) or (SendEmail and Email ~= ""), "E-mail address must be specified");
AllowTrade = instance.parameters.AllowTrade;
if AllowTrade then
Account = instance.parameters.Account;
Amount = instance.parameters.Amount;
BaseSize = core.host:execute("getTradingProperty", "baseUnitSize", instance.bid:instrument(), Account);
Offer = core.host:findTable("offers"):find("Instrument", instance.bid:instrument()).OfferID;
CanClose = core.host:execute("getTradingProperty", "canCreateMarketClose", instance.bid:instrument(), Account);
SetLimit = instance.parameters.SetLimit;
Limit = instance.parameters.Limit * instance.bid:pipSize();
SetStop = instance.parameters.SetStop;
Stop = instance.parameters.Stop * instance.bid:pipSize();
TrailingStop = instance.parameters.TrailingStop;
end
gSource = ExtSubscribe(1, nil, instance.parameters.TF, true, "bar");
tSource = ExtSubscribe(2, nil, "t1", true, "bar");
--TODO: Find indicator's profile, intialize parameters, and create indicator's instance (if needed)
iEMAFast = core.indicators:create("EMA", gSource.close, FastEMA)
iEMAMed = core.indicators:create("EMA", gSource.close, MedEMA)
iEMASlow = core.indicators:create("EMA", gSource.close, SlowEMA)
end
local Stage1Status = "Neutral"; -- possible values are "Neutral", "Buy", "Sell"
-- update indicators
iEMAFast:update(core.UpdateLast);
iEMAMed:update(core.UpdateLast);
iEMASlow:update(core.UpdateLast);
-- check for data
--if not iEMAFast.DATA:hasData(period) or not iEMAMed.DATA:hasData(period) or not
iEMAMed.DATA:hasData(period) then
--core.host:trace("Not Enough Data. Checking Next Bar...")
--return;
--end
-- close of bar, Stage 1, making sure EMAs are lined up.
if not haveTrades() then
-- buy setup, if Price > Fast > Med > Slow
if gSource.close[period] > iEMAFast.DATA[period] and
iEMAFast.DATA[period] > iEMAMed.DATA[period] and
iEMAMed.DATA[period] > iEMASlow.DATA[period] then
Status="Buy"
enter("B")
end
-- sell setup, if Price < Fast < Med < Slow
if gSource.close[period] < iEMAFast.DATA[period] and
iEMAFast.DATA[period] < iEMAMed.DATA[period] and
iEMAMed.DATA[period] < iEMASlow.DATA[period] then
Status="Sell"
enter("S")
end
end
end
-- open positions in direction BuySell
function enter(BuySell)
local valuemap, success, msg;
valuemap = core.valuemap();
valuemap.OrderType = "OM";
valuemap.OfferID = Offer;
valuemap.AcctID = Account;
valuemap.Quantity = Amount * BaseSize;
valuemap.BuySell = BuySell;
valuemap.GTC = "GTC";
if SetLimit then
-- set limit order
valuemap.PegTypeLimit = "O";
if BuySell == "B" then
valuemap.PegPriceOffsetPipsLimit = Limit/instance.bid:pipSize();
else
valuemap.PegPriceOffsetPipsLimit = -Limit/instance.bid:pipSize();
end
end
if SetStop then
-- set stop order
valuemap.PegTypeStop = "O";
if BuySell == "B" then
valuemap.PegPriceOffsetPipsStop = -Stop/instance.bid:pipSize();
else
valuemap.PegPriceOffsetPipsStop = Stop/instance.bid:pipSize();
end
if TrailingStop then
valuemap.TrailStepStop = 1;
end
end
if (not CanClose) and (StopLoss > 0 or TakeProfit > 0) then
valuemap.EntryLimitStop = "Y"
end
success, msg = terminal:execute(100, valuemap);
if not(success) then
terminal:alertMessage(instance.bid:instrument(), instance.bid[instance.bid:size() - 1], "open order failure: " .. msg, instance.bid:date(instance.bid:size() - 1));
return false;
end
return true;
end
-- return true if trade is found (can check single side as well)
function haveTrades(BuySell)
local enum, row;
local found = false;
enum = core.host:findTable("trades"):enumerator();
row = enum:next();
while (not found) and (row ~= nil) do
if row.AccountID == Account and
row.OfferID == Offer and
(row.BS == BuySell or BuySell == nil) then
found = true;
end
row = enum:next();
end
return found;
end
-- Close trigger
function close(CanClose)
if HaveTrades and (Status == "Buy") and FastEMA<MedEMA then
Status = "close"
end
if HaveTrades and (Status == "Sell") and FastEMA>MedEMA then
Status = "close"
end
end
I am trying to make a "shell" in lua.
But the main problem is, I can not define the variable name from user input.
Here is the core of what I currently have. I am having an issue with the what[2] = what[3] line with the comment below.
How can I better implement this?
function lsplit(inputstr, sep)
if sep == nil then
sep = "%s"
end
local t={} ; i=1
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
t[i] = str
i = i + 1
end
return t
end
function def(what)
if (what[1] == "end") then
os.exit(0)
elseif (what[1] == "help") then
print("Commander version 0.0")
elseif (what[1] == "var") then
what[2] = what[3] --Can not define
else
print("[ERR] not a command!")
end
end
while(true) do
io.write("-->")
local usr = io.read("*l")
local cmd = lsplit(usr, " ")
def(cmd)
end
you are overwriting you first parameter with you second one, and not creating a new var... try this code! Should work but it is untested!
local userdefinedVars = { }
function lsplit(inputstr)
words = {}
for word in s:gmatch("%w+") do
table.insert(words, word)
end
end
function def(what)
if (what[1] == "end") then
os.exit(0)
elseif (what[1] == "help") then
print("Commander version 0.0")
elseif (what[1] == "var") then
-- This is how you get your things done!
userdefinedVars[what[2]] = what[3]
else
print("[ERR] not a command!")
end
end
while(true) do
io.write("--> ")
local usr = io.read("*line")
local cmd = lsplit(usr)
def(cmd)
end
I have recently been learning Lua with Love2d, so I decided to start making a simple RPG. It's quite simple. The console is where you play, and the extra window is where you can see your stats, equip items, ect.
But, I have run into a problem! Whenever I run the code, I see this main.lua:15: '=' expected near 'else'
I will include the code (all 3 files) below.
This is main.lua
function love.load()
love.graphics.setBackgroundColor( 255, 255, 255 )
require("player")
print("Enter your name")
pcStats.Name = io.read()
print("What class are you, " .. pcStats.Name .. "?")
pcStats.Class = io.read()
if pcStats.Class == "Ranger" then
os.execute("cls")
pcInv.InvSpace = 10
pcInv.Items.basicBow = Basic Bow
else
print("Error: Invalid Class. Please restart game")
end
print("What would you like to do? CODE END")
input = io.read()
end
function love.draw()
love.graphics.setColor( 0, 0, 0 )
love.graphics.print( "Level: " .. pcStats.Level, 1, 1 )
love.graphics.print( "Inv Space: " .. pcInv.InvSpace, 1, 20 )
love.graphics.print( "Inv: " .. pcInv.Items, 1, 40 )
end
Here is player.lua This is where the game variables are stored
pcStats = {}
pcStats.Level = 1
pcStats.XP = nil
pcStats.Name = nil
pcStats.Class = nil
pcStats.Atk = nil
pcStats.Def = nil
pcInv = {}
pcInv.InvSpace = nil
pcInv.Items.testsword = testing sword
And last but not least, here is the conf.lua used for love2d
function love.conf(t)
t.modules.joystick = true
t.modules.audio = true
t.modules.keyboard = true
t.modules.event = true
t.modules.image = true
t.modules.graphics = true
t.modules.timer = true
t.modules.mouse = true
t.modules.sound = true
t.modules.thread = true
t.modules.physics = true
t.console = true
t.title = "Lua RPG Alpha v0.0.1"
t.author = "Zach Herzer"
end
Line 15 is this:
pcInv.Items.basicBow = Basic Bow
Basic Bow isn't valid Lua code. I am pretty sure you meant something else - perhaps a string?
pcInv.Items.basicBow = "Basic Bow"
While we're at it,
pcInv.Items.testsword = testing sword
has a similar problem.