I am trying to create an Lua addon for Garry's Mod but I keep coming across an error in my code.
This is my code:
function say (Player, text, ent)
s = "/misc/custom/"..text
s2 = s..".mp3"
sound.PlayFile(s2)
end
hook.Add("PlayerSay", "Say", say)
And this is the resulting error.
[saysoundtest25] lua/autorun/chatsounds.lua:4: attempt to call field 'PlayFile' (a nil value)
1. v - lua/autorun/chatsounds.lua:4
2. unknown - lua/includes/modules/hook.lua:84
Any ideas?
User Robotboy655 on Facepunch helped me solve this! The final code:
hook.Add( "PlayerSay", "Say", function( ply, text, team )
BroadcastLua( 'surface.PlaySound("misc/custom/' .. text .. '.mp3")' )
end )
Thanks everyone for the help!
The /lua/autorun file is serverside and there is a variable sound server-side Lua, however only in client side does sound.PlayFile exist.
if SERVER then
AddCSLuaFile() -- We're the server running this code! Let's send it to the client
else -- We're a client!
-- Your code here, only ran by the client!
end
See the Garry's Mod wiki for more info and note the orange box on the page which means it's client side.
Please remember to check what the function takes also:
sound.PlayFile( string path, string flags, function callback )
Example (taken from the wiki)
sound.PlayFile( "sound/music/vlvx_song22.mp3", "", function( station )
if ( IsValid( station ) ) then station:Play() end
end )
Also more easy way of searching the docs:
http://glua.me/
http://glua.me/docs/#?q=sound.PlayFile
How DarkRP handles this:
https://github.com/FPtje/DarkRP/blob/master/gamemode/modules/chatsounds.lua#L275
Related
I keep getting this spammed in console:
MENU ERROR: lua/menu/mainmenu.lua:79: attempt to call global 'CanAddServerToFavorites' (a nil value)
lua/menu/mainmenu.lua:79 []
And this whenever I load a map (doesnt even let me play the map, kicks me out)
[ERROR] gamemodes/base/gamemode/animations.lua:333:
attempt to index local 'ply' (a nil value)
unknown - gamemodes/base/gamemode/animations.lua:333
I know the location of the files and I know that 333 or 79 means which line it is on, I just don't know how to fix the problem. Never coded in my life, but I tried changing the TranslateWeaponActivity to just TranslateActivity since I didnt see any other thing called TranslateWeaponActivity, that didn't work. Anyone with lua experience can help? Do I need to send the entire script?
function GM:TranslateActivity( ply, act )
local newact = ply:TranslateWeaponActivity( act )
-- select idle anims if the weapon didn't decide
if ( act == newact ) then
return IdleActivityTranslate[ act ]
end
return newact
end
and the code for favorites:
if ( self.CanAddServerToFavorites != CanAddServerToFavorites() ) then
self.CanAddServerToFavorites = CanAddServerToFavorites()
if ( self.CanAddServerToFavorites ) then
self.HTML:QueueJavascript( "SetShowFavButton( true )" )
else
self.HTML:QueueJavascript( "SetShowFavButton( false )" )
end
end
end
I am trying to make a muting script that doesn't let players talk. At the moment I am at telling which player in the script with no commands but I cant work out or find how to run this function that I created on a specific player, not just mute the entire server.
sv_mute.lua:
util.AddNetworkString( "mute_message" )
ismuted == false
targetPlayer == "Xx_Player_xX"
function checkmute()
function SendMessage( ply, txt, pub )
net.Start( "mute_message" )
net.WriteString( "YOU ARE MUTED, SHUT UP" )
net.Send( ply )
return ""
end
hook.Add( "PlayerSay", "SendMessage", SendMessage, )
end
Player:checkmute(()targetPlayer)
cl_mute.lua:
function ReceiveMessage()
local txt = net.ReadString()
chat.AddText( Color( 0, 255, 0), txt)
end
I have so far got to using Player:checkmute(()targetPlayer) but I assume this is wrong
So at first a few mistakes I have seen on a first quick look.
You defined a function without a parameter but you try to call it with one
You did not used the tools Garry gave you already to send messages to players
Things we will be using to achieve your desired task
GM:PlayerSay( Player sender, string text, boolean teamChat )
Player:PrintMessage( number type, string message )
The solution
-- sv_mute.lua
-- a list of muted players, you need to get them from somewhere (not part of this answer)
mutedPlayers = {
"StupidMan" = true,
"AnnoyingKid" = true,
"ExGirlfriend" = true
}
-- the function that will check if a user is muted
local function checkMuted(--[[ string ]] playername)
return mutedPlayers[playername]
-- you probably need to change the code to something else
-- based on how you store your muted players
end
hook.Add("PlayerSay", "VosemMute_PlayerSay", function(sender, message, teamChat)
if ( checkMuted(sender:GetName()) ) then
sender.PrintMessage(HUD_PRINTTALK, "You are muted!")
return "" -- this will suppress the message
end
end)
Some helpful links
HUD Enumerations (HUD_PRINTTALK)
Player:GetName()
hook.Add( string eventName, any identifier, function func )
Garry's Mod Wiki
Lua Reference Manual (sadly i do not know which lua version is used by gmod)
Disclaimer
This code is completely untested and written of my mind. If this does not work and throws some errors let me know that. I'll correct it then.
Im new to Lua and can only just really read it, mainly just interpreting. I was having an error with a modification for Garrys mod where a lightsaber mod I had installed worked on client side but was invisible on server side. This is because of settings, ect. I asked on his group and he told me this :
You must call these functions on the weapon right after spawning it:
self:SetMaxLength( 42 )
self:SetCrystalColor( Vector( 255, 0, 0 ) )
self:SetDarkInner( false )
self:SetWorldModel( "models/... etc" )
self:SetBladeWidth( 2 )
self.LoopSound = "sound/lightsaber/..."
self.SwingSound = "sound/lightsaber/..."
self:SetOnSound( "sound/lightsaber/..." )
self:SetOffSound( "sound/lightsaber/..." )
self.WeaponSynched = true
Where self is the weapon.
So I put it into the code. All this does is completely remove the lightsaber and give me this error:
[ERROR] lua/weapons/weapon_lightsaber.lua:44: attempt to index global 'self' (a nil value)
1. unknown - lua/weapons/weapon_lightsaber.lua:44
Here is the pastebin of the code : http://pastebin.com/Y8kmivuv
Try using 'SWEP' instead of 'self'. self is usually defined in object-orientated code, which uses metatables in Lua.
I have a WoW/LUA script that I am attempting to start, but it seems to conflict with the Stubby addon, which is a part of the Auctioneer addon, I believe. Here is the message I receive:
Error occured in: Stubby Count: 1 Message: Error: Original call failed
after running hooks for: ChatFrame_OnEvent Usage:
SendChatMessage(text [,type] [,language] [,targetPlayer]) Debug:
(tail call): ? [string ":OnEvent"]:1:
[string ":OnEvent"]:1
Now, the only thing that's happening in the conflicting addon is:
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", partyMsg)
The code within partyMsg is very simple as well:
local function partyMsg(msg,author,language,lineID,senderGUID)
if (store ~= msg) then
SendChatMessage(msg,"SAY",nil,nil);
end
store = msg;
end
Is this error due to two addons both trying to filter the chat frame? If so, how can this be done? It seems odd to me that Blizzard would have such a simple and yet important concept limited to one addon.
I think I see what happened here.
The reference you were using, Events/Communication, shows only the specific parameters for a particular event, regardless of context.
The context is usually an OnEvent handler.
The ChatFrame_AddMessageEventFilter function lets you use the chat frame's OnEvent handler instead of your own for chat frame events, and has well defined parameters for filters you add.
An OnEvent handler might look like:
function Foo_OnEvent(self, event, ...)
A 'ChatFrame' filter must look like this, for the first two parameters:
function Foo_ChatFrameFilter(self, event, msg, ...)
The ChatFrame filter is specific. For OnEvent however, you can make a Lua 'handler' that doesnt care about what frame it came from:
<OnEvent>
MyEventHandler(event, ...)
</OnEvent>
For the sake of completion, I will include the entire source of this addon:
local function partyMsg(someTable,msgType,msg,user,language,...)
if (store ~= msg) then
SendChatMessage(user .. " just said: ".. msg .. " using that sneaky " .. language .. " language.");
end
store = msg;
return false;
end
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY", partyMsg)
ChatFrame_AddMessageEventFilter("CHAT_MSG_PARTY_LEADER",partyMsg)
There were a couple issues with the original code:
1) I was using WoWWiki to get my information, and first, I read it incorrectly. lineID and senderGUID are not the 4th and 5th arguments. Then, beyond this, WoWWiki is incorrect on this page in general. The correct arguments are listed above in the source. The first argument, a table, I am unsure of its purpose. In any case, this code now works fully.
I'm generating some (non-html) documentation for a Lua library that I developed. I will generate the documentation by hand, but I'd appreciate some kind of automation if possible (i.e. generating skeletons for each function so I can fill them in)
I'd like to know if there's a way for lua to know the names of the parameters that a function takes, from outside it.
For example, is there a way to do this in Lua?
function foo(x,y)
... -- any code here
end
print( something ... foo ... something)
-- expected output: "x", "y"
Thanks a lot.
ok,here is the core code:
function getArgs(fun)
local args = {}
local hook = debug.gethook()
local argHook = function( ... )
local info = debug.getinfo(3)
if 'pcall' ~= info.name then return end
for i = 1, math.huge do
local name, value = debug.getlocal(2, i)
if '(*temporary)' == name then
debug.sethook(hook)
error('')
return
end
table.insert(args,name)
end
end
debug.sethook(argHook, "c")
pcall(fun)
return args
end
and you can use like this:
print(getArgs(fun))
Try my bytecode inspector library. In Lua 5.2 you'll be able to use debug.getlocal.
Take a look at debug.getinfo, but you probably need a parser for this task. I don't know of any way to fetch the parameters of a function from within Lua without actually running the function and inspecting its environment table (see debug.debug and debug.getlocal).
function GetArgs(func)
local args = {}
for i = 1, debug.getinfo(func).nparams, 1 do
table.insert(args, debug.getlocal(func, i));
end
return args;
end
function a(bc, de, fg)
end
for k, v in pairs(GetArgs(a)) do
print(k, v)
end
will print
1 bc
2 de
3 fg
Basically we use debug.getinfo to retrieve the nparams attribute (which gives us the information of how many parameters the function takes) and debug.getlocal to access the name of the parameters.
Tested and working with Lua 5.4
Take a look at the luadoc utility. It is sort of like Doxygen, but for Lua. It is intended to allow the documentation to be written in-line with the source code, but it could certainly be used to produce a template of the documentation structure to be fleshed out separately. Of course, the template mechanism will leave you with a maintenance issue down the road...