• Print

Author Topic: Lua n00b questions  (Read 33306 times)

0 Members and 1 Guest are viewing this topic.

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #15 on: January 03, 2013, 09:03:57 am »
Code: Lua
  1. local old = file.Write
  2. function file.Write(...)
  3.   -- Do pre-processing here
  4.   local ret = { old(...) }
  5.   -- Do post-processing here
  6.   return ret
  7. end
  8.  
Ok, tell me if I'm understanding this correctly,

  • "old" becomes a variable, it's contents are the file.Write function.
  • Under it you have the file.Write function itself, in my case I wouldn't need to define this because it's already defined in another game-file.
  • Under this you add variable "old" to a new var "ret", changing the contents of it to my new code.
  • You then call ret, which replaces the default gmod function file.Write, with the new one in ret.
My TTT server. Join the fun!

Offline Stickly Man!

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 1270
  • Karma: 164
  • What even IS software anymore?
    • XGUI
Re: Lua n00b questions
« Reply #16 on: January 03, 2013, 09:36:46 am »
Not quite. Hopefully the following doesn't go too over your head :P Function calls stored in a variable, like file.Write and old are actually REFERENCES to memory locations containing the function. Here's a line-by-line breakdown of what's going on:

Code: [Select]
local old = file.WriteHere, "old" becomes a reference to the memory location that is currently the file.Write function.

Code: [Select]
function file.Write(...)Here, you are changing the file.Write reference to point to a brand new function that you are specifying below. As of now, the only way to reference the original file.Write function is to call old(). Note the ... is a variable number of arguments, you should read about it here if you're not familiar.

Code: [Select]
-- Do pre-processing hereHere you add any code you want to run BEFORE the original file.Write gets called.

Code: [Select]
local ret = { old(...) }Here, you are creating a table named ret that stores all of the return values from the old file.Write function. Note that with the ... you are passing in every variable that's passed to this function.

Code: [Select]
-- Do post-processing hereHere you add any code you want to run AFTER the original file.Write gets called, including changing any of the values that were returned.

Code: [Select]
return unpack(ret)
end
And now you pass the return values onto wherever file.Write was called, and end the function.


.. Uhh.. Hope that makes sense? I'm always quite bad at explaining things :P

Edit: fixed Megiddo's bug
« Last Edit: January 03, 2013, 09:44:00 am by Stickly Man! »
Join our Team Ulysses community discord! https://discord.gg/gR4Uye6

Offline Megiddo

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 6214
  • Karma: 394
  • Project Lead
Re: Lua n00b questions
« Reply #17 on: January 03, 2013, 09:41:56 am »
Just realized "return ret" should have been "return unpack(ret)". What the difference? Ret is a table representing the returned values from the original call. file.Write only returns one thing, but storing it this way helps future-proof our wrapper. But, since ret is a table, we need to convert it back into the list of values. "unpack(ret)" does this.

Example:
Code: Lua
  1. local ret = {1,2,3}
  2. local one, two, three = unpack(ret)

One, two, and three now contain the values they are named after. This hopefully makes sense, but isn't a terribly important point to worry over.
Experiencing God's grace one day at a time.

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #18 on: January 04, 2013, 06:30:24 pm »
Thanks Meg & Stickly, so I looked into tables more, and based on the explanation given by stickly, and what I read in the lua man, I came up with this code to insert the two edited lines of code at the end of the original table that is found inside PANEL:Init, I determined this to be the 12 and 13 position by counting the lines of code inside PANEL:Init

Code: [Select]
local old= PANEL:Init
function PANEL:Init(...)
--pre process
--pre process
local ret = {old(...)}
--post process

table.insert(ret,12,self.cols[5] = vgui.Create("DLabel", self))
table.insert(ret,13,self.cols[5]:SetText(""))

--post process
return unpack(ret)
end

I am getting an error "function arguments expected near..." And I believe this is due to it calling PANEL:Init outside of the file it first appears (sb_row.lua). Do I need to somehow link this file with my addon?

I'm probably so off base here, I'm sorry, but I am seriously trying to understand this.

Here's the original PANEL:Init found inside sb_row.lua. PANEL in itself looks to be a table.
Code: [Select]
local PANEL = {}

function PANEL:Init()
   -- cannot create info card until player state is known
   self.info = nil

   self.open = false

   self.cols = {}
   self.cols[1] = vgui.Create("DLabel", self)
   self.cols[1]:SetText(GetTranslation("sb_ping"))

   self.cols[2] = vgui.Create("DLabel", self)
   self.cols[2]:SetText(GetTranslation("sb_deaths"))

   self.cols[3] = vgui.Create("DLabel", self)
   self.cols[3]:SetText(GetTranslation("sb_score"))

   self.cols[4] = vgui.Create("DLabel", self)
   self.cols[4]:SetText(GetTranslation("sb_karma"))

   for _, c in ipairs(self.cols) do
      c:SetMouseInputEnabled(false)
   end

   self.tag = vgui.Create("DLabel", self)
   self.tag:SetText("")
   self.tag:SetMouseInputEnabled(false)

   self.sresult = vgui.Create("DImage", self)
   self.sresult:SetSize(16,16)
   self.sresult:SetMouseInputEnabled(false)

   self.avatar = vgui.Create( "AvatarImage", self )
   self.avatar:SetSize(SB_ROW_HEIGHT, SB_ROW_HEIGHT)
   self.avatar:SetMouseInputEnabled(false)

   self.nick = vgui.Create("DLabel", self)
   self.nick:SetMouseInputEnabled(false)

   self.voice = vgui.Create("DImageButton", self)
   self.voice:SetSize(16,16)

   self:SetCursor( "hand" )
end
My TTT server. Join the fun!

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
Re: Lua n00b questions
« Reply #19 on: January 04, 2013, 07:46:02 pm »
I'm sure there may end up being more errors, but...
local old= PANEL:Init should probably me something more along the lines of local old= PANEL:Init()
I know our file.Write examples don't show that, but, it's my guess.
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #20 on: January 09, 2013, 10:23:15 pm »
Ok so I think that last question is still over my head, even with the explanation. So I've moved on to something a little more simple, hopefully I will learn something from these other little things that might trigger my understanding. This leads me to my next question:

I've created a ULX plugin that slays a player after a new round starts, it works fine, until I try to print a message globally to everyone, here's my code, and I noted where it fails.
Code: [Select]
function ulx.dksnr(calling_ply, target_plys)
local affected_plys ={}
for i=1, #target_plys do
local v = target_plys[ i ]
if v.snr then
ULib.tsayError( calling_ply, v:Nick() .. " is already being slain by " .. v.snrby, true )
else
v.snr = true
v.snrby = calling_ply:IsValid() and calling_ply:Nick() or "(Console)"
ULib.tsayError( HUD_PRINTTALK, v:Nick() .. " is already being slain the following round for RDM.", true ) --IT FAILS HERE.
end

hook.Add("TTTBeginRound", "DK SNR", function()
if v.snr then
v:Kill()
table.insert( affected_plys, v )
v.snr = nil
v.snrby = nil
end
end)

end
ulx.fancyLogAdmin( calling_ply, "#A is slaying #T the following round for RDM.", affected_plys ) -- THIS DOESN'T FIRE
end
local _dksnr = ulx.command( CATEGORY_NAME, "ulx slay next round", ulx.dksnr, "!snr" )
_dksnr:addParam{ type=ULib.cmds.PlayersArg }
_dksnr:defaultAccess( ULib.ACCESS_ADMIN )
_dksnr:help( "Slays target(s) the following round for RDM." )
Also, another thing to note, the command, when executed, doesn't show up at all in the logs or on screen, but like I said, it does what it should.
« Last Edit: January 09, 2013, 10:24:49 pm by krooks »
My TTT server. Join the fun!

Offline Megiddo

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 6214
  • Karma: 394
  • Project Lead
Re: Lua n00b questions
« Reply #21 on: January 10, 2013, 04:36:19 am »
You want "v" instead of "HUD_PRINTTALK" on line 10

You have an extra, misplaced "end" on line 22

You should move the table.insert on line 16 to inside the "else" statement (make it line 11)

Hooks are uniquely named, so you're only going to be able to slay a single person per round as it's currently written (I'll let you figure out how to fix this one, may possible solutions... ;))
Experiencing God's grace one day at a time.

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #22 on: January 10, 2013, 11:27:06 am »
I'm afraid I don't fully understand exactly how the players are being chosen, please correct my thinking here:
Code: [Select]
function ulx.dksnr(calling_ply, target_plys)
local affected_plys ={}
for i=1, #target_plys do
local v = target_plys[ i ]
"ulx" is a preset table, and "dksnr" is a unique name that I give to it, containing my script. What the args do is dictated by "ulx", but can be named anything so long as they are in the correct place (first will always be calling, second targets, third whatever else ulx is set up to do (is there documentation on what all it does somewhere?))

We then create a table called "affected_plys", we dictate how many rows the table has based on how many "target_plys" are called through "ulx" with "for i=1, #target_plys". Then we assign the called player's name to the table with "do local v=target_plys[ i ]" Making the table look like,
Code: [Select]
affected_plys[1] = John Doe
affected_plys[2] = Jane Doe
and since "v" equals said players, we can call them as a group using "v", and this is how we execute commands on them?

So, by my (flawed?) reasoning using "v" instead of HUD_PRINTTALK, would not alert everyone on the server, just John and Jane, right?

EDIT

Wait, I think I better understand now,
Code: [Select]
for i=1, #target_plys do
local v = target_plys[ i ]
is saying loop through the number of targeted players in the list and each time, v becomes a different targeted player (one by one rather than as a whole as previously thought above). But in the end, v still only refers to players actually targeted, and not everyone connected to the server, correct?
So, by doing:
Code: [Select]
hook.Add("TTTBeginRound", i.."dksnr", function()I could create a unique hook for each player. Correct?
« Last Edit: January 10, 2013, 01:16:31 pm by krooks »
My TTT server. Join the fun!

Offline Megiddo

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 6214
  • Karma: 394
  • Project Lead
Re: Lua n00b questions
« Reply #23 on: January 10, 2013, 01:33:11 pm »
This is quite a bit to explain via writing, and my style of writing is not conducive to clearly answering all your questions... :)

I suggest you hail me on Steam sometime and we can have a voice chat about what all is going on here.
Experiencing God's grace one day at a time.

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #24 on: January 10, 2013, 01:42:37 pm »
I'm guessing that I am extremely off base  ;D
That would be immensely helpful Megiddo, I'll do that.

I feel like I only struggle with a few concepts, otherwise I have a pretty good idea as to how it all works.
My TTT server. Join the fun!

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #25 on: January 16, 2013, 01:51:59 pm »
I've found some lua tutorial videos on youtube that have helped me a lot, and I wrote my first complete script without copy/pasting code bits from other people's work! I still have questions for ya Meg, so you're not out of the woods just yet  ;)

On a side note, I am currently running a dev ttt server off the same gmod installation that my public sandbox server is on, I just point it to a different server.cfg script. This works fine, but I'm getting conflicts with plugins not built for TTT. How do I go about making the plugins SB only?

Currently, I've edited the init.lua with this line:
if SERVER and (gmod.GetGamemode().Name == "Sandbox") then
It seems to work ok, but is there an easier way? Could I maybe add something to addon.txt??
My TTT server. Join the fun!

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
Re: Lua n00b questions
« Reply #26 on: January 16, 2013, 02:34:38 pm »
If you mean 'info.txt', no.
In fact, it seems Garry seems to be moving away from it (Garry's Steam Workshop doesn't even require the file)
Though Meg/Stickly may suggest a better way, I'm pretty sure the way you're doing it is good, if not a pain to edit any addon you get.
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

Offline krooks

  • Sr. Member
  • ****
  • Posts: 382
  • Karma: 32
  • I don't like video games.
    • Diamond Krooks
Re: Lua n00b questions
« Reply #27 on: January 16, 2013, 03:14:29 pm »
info.txt actually changed to addon.txt, but it's the same thing I believe -- more things Garry changed seemingly just to make things hard :P

It's so hard learning glua right now, there's all this mixed info all over the place after GM13  :-[
My TTT server. Join the fun!

Offline Megiddo

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 6214
  • Karma: 394
  • Project Lead
Re: Lua n00b questions
« Reply #28 on: January 16, 2013, 03:47:17 pm »
more things Garry changed seemingly just to make things hard :P

He changed it so old addons would be incompatible. But, he already does this each update by changing the API anyways...
Experiencing God's grace one day at a time.

Offline JamminR

  • Ulysses Team Member
  • Hero Member
  • *****
  • Posts: 8096
  • Karma: 390
  • Sertafide Ulysses Jenius
    • Team Ulysses [ULib/ULX, other fine releases]
Re: Lua n00b questions
« Reply #29 on: January 16, 2013, 03:49:40 pm »
He changed it so old addons would be incompatible. But, he already does this each update by changing the API anyways...
LOL.
Indeed.
And, I was confused. I could have sworn the file name changed from what krooks originally said to what I said.
Guess I was backwards. Not unusual.
"Though a program be but three lines long, someday it will have to be maintained." -- The Tao of Programming

  • Print