Hello,
I'm looking for something like this:
- When a player types something, if x amount of words match some keywords, specified in a table or two, and is prefixed by "!ask" the bot responds with an answer to such question.
For example:
Player: !ask How do I get VIP?
-scans a table for keywords and finds "How", "VIP", and "get" in one record, so then finds following response from other table:
Bot: ANSWER to Player: Visit our website at [url]www.example.com[/url]
I could see the tables looking something like:
[lua]
local keywords = {
[1] = {"How", "VIP", "Get" },
[2] = {"Something", "else" },
}
local answers = {
[1] = "Visit our website at www.example.com",
[2] = "Something",
}
[/lua]
Not sure if that's the best way to go about it, but I'm not sure exactly how to hook the playersay features, and scan for such keywords.
[b]Server: [/b]
[lua]
local keywords = {
{"How", "VIP", "Get" },
{"Something", "else" },
}
local answers = {
"Visit our website at www.example.com",
"Something",
}
function AskBot( ply, strText, team )
-- Search for '/ask'
local strS = -1
local strE = -1
strS, strE = string.find( strText, "/ask" )
if ( strS==1 ) then
-- If we find '/ask' then search the question keywords
for k, v in pairs( keywords ) do
-- A count we use to match the number finds to the maximum possible results
local x=0
for n, e in pairs( keywords[k] ) do
-- Check first keyword table
-- More temporary string search variables
local strSB=-1
local strEB=-1
-- keywords[k].[n] (?) possible invalid
strSB, strEB = string.find( strText, keywords[k].n )
-- If we found a keyword, add a number to the count
if ( strSB!=-1 ) then x=x+1 end
end
-- If the count is equal to the number of search keywords, we have a match!
if ( x==#keywords[k] ) then
-- Print the answer to everyone ( send this to specifically to the asking client? )
chat.AddText( Color(255,100,100), "[Q/A Bot]: ", Color(240,240,240), answers[k] )
-- Print the original text, and exit this function and these confounding for loops
return strText
end
end
end
-- If we're not searching, or if we found nothing, print the original chat and exit the function
return strText
end
-- Hook this function to the PlayerSay function for access to chat
hook.Add( "PlayerSay", "AskBot", AskBot )[/lua]
Hope that helps!
Very useful. Thanks for the help :)
EDIT: Hmm, line 25 is reporting: '<name>' expected near '['
Using just "e" seems to fix it. :)
Except for PlayerSay hook is serverside and chat.AddText is clientside.
[QUOTE=zzaacckk;29174679]Except for PlayerSay hook is serverside and chat.AddText is clientside.[/QUOTE]
Credits to Overv:
[lua]
if SERVER then
chat = { }
function chat.AddText( ... )
if ( type( arg[1] ) == "Player" ) then ply = arg[1] end
umsg.Start( "AddText", ply )
umsg.Short( #arg )
for _, v in pairs( arg ) do
if ( type( v ) == "string" ) then
umsg.String( v )
elseif ( type ( v ) == "table" ) then
umsg.Short( v.r )
umsg.Short( v.g )
umsg.Short( v.b )
umsg.Short( v.a )
end
end
umsg.End( )
end
else
usermessage.Hook( "AddText", function( um )
local argc = um:ReadShort( )
local args = { }
for i = 1, argc / 2, 1 do
table.insert( args, Color( um:ReadShort( ), um:ReadShort( ), um:ReadShort( ), um:ReadShort( ) ) )
table.insert( args, um:ReadString( ) )
end
chat.AddText( unpack( args ) )
end )
end
[/lua]
EDIT:
Here's the updated code I'm using now. Thanks again TeeHelee :)
[lua]
function AskBot( ply, strText, team )
if ( string.find( strText, "/ask" ) ) then
for k, v in pairs(keywords) do
local x = 0
for n, e in pairs(keywords[k]) do
if ( string.find( strText, e ) ) then
x = x + 1
print(e .. " found")
end
end
if ( x == #keywords[k] ) then
chat.AddText( ply, Color(255,100,100), "[Q/A Bot]: ", Color(240,240,240), answers[k] )
return ""
end
end
chat.AddText( ply, Color(255,100,100), "[Q/A Bot]: ", Color(240,240,240), "No question matched." )
return ""
end
end
hook.Add( "PlayerSay", "AskBot", AskBot )
[/lua]
No offence Tehelee, but your code makes my eyes bleed. Neatness never hurt anyone.
[QUOTE=FlapadarV2;29175350]No offence Tehelee, but your code makes my eyes bleed. Neatness never hurt anyone.[/QUOTE]
I fixed it up, sorry about that, I'm not used to having others look at my code.
Any other tips on cleanliness that I can improve?
I'm very curious to know, and thanks for the constructive criticism btw! :3
imo I think you should put comments next to your code, and not above / below.
If you decide not to, please use -- instead of //, it seems to all blend together.
I wasn't meaning double line spacing, more so meaningful variable names - "strS" is a bit cryptic. Also, you should declare your variable and equal it directly to string.find, rather than declaring it first (Looks way neater, but makes no real difference)
Your method for checking keywords is a bit.. odd. It should work though.
[QUOTE=Derek_SM;29175783]imo I think you should put comments next to your code, and not above / below.
If you decide not to, please use -- instead of //, it seems to all blend together.[/QUOTE]
I kinda prefer the comment to be right before what it does. In my mind it just looks a bit neater to have comments and actual code separated.
Sorry, you need to Log In to post a reply to this thread.