Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion Goto page 1, 2  Next
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Fri Jan 23, 2009 5:53 pm   

Assistance with functions (in lua and zscript) needed
 
For the longest time, I had been looking for a time differential script to tell me the time between two periods. I had one, but it was buggered to pieces because it wasn't smart enough that going from the 31st of one month to the 1st of the next month did not constitute a full month.

Recently, I found a perfect one written in Lua. It came off the lua-users wiki, and is written as so:

Code:
local timeDiff = function(t2,t1)
   local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
   local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
   d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
   for i,v in ipairs({'sec','min','hour','day','month','year'}) do
      diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
      carry = diff[v] < 0
      if carry then diff[v] = diff[v] + colMax[i] end
   end
   return diff
end


The example they provide to show how the script works is:

Code:
local td=timeDiff(os.time{year=2007,month=10,day=5,hour=10,min=10,sec=5},os.time{year=2006,month=11,day=6,hour=10,min=10,sec=5})
for i,v in pairs(td) do print(i,v) end


I figured I'd be able to integrate the script into CMUD, and I had been partially successful, but now require assistance.

What I have right now is an alias that has what's posted in the script verbatim, plus this change in the example:

Code:
local td=timeDiff(os.time{year=zs.param(1),month=zs.param(2),day=zs.param(3),hour=zs.param(4),min=zs.param(5),sec=zs.param(6)},os.time{year=zs.param(7),month=zs.param(8),day=zs.param(9),hour=zs.param(10),min=zs.param(11),sec=zs.param(12)})
zs.var.difference=(td.year .. "yrs " .. td.month .. "mos " .. td.day .. "dys " .. td.hour .. "hrs " .. td.min .. "mns " .. td.sec .. "scs")


Now the alias works nicely, and if I have to go that route, I suppose that's what I'll have to do. I'd rather not, however, and use it as a function. The problem is, I'm not even sure how I'm going to get it into a function. #RETURN {#LUA blahblahblahb} doesn't work, and #RETURN @luafunc(%1,%2,...,%11,%12) doesn't work properly.

So, any ideas how I can turn that alias into a function so that when I do:

gt @timediff(2009,1,23,12,00,00,2009,1,1,12,00,00)

it'll properly show up as:

(Group) Charneus: 0yrs 0mos 23dys 0hrs 0mns 0scs

?

An added bonus would if it could return up to what is populated so I'm not spammed with all that every time (for instance, it'd show 23dys instead of all the 0s in it, although with the hours/mins/secs, I would personally want that left alone).

I greatly appreciate it and look forward to hearing suggestions.

Charneus
Reply with quote
Rahab
Wizard


Joined: 22 Mar 2007
Posts: 2320

PostPosted: Fri Jan 23, 2009 6:57 pm   
 
I can't help with your exact question, but if you can't get it to work, I can give you my zscript function for converting dates into seconds since Jan 1, 2000. I made it so I could get time differences easily.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Sat Jan 24, 2009 9:26 pm   
 
That's the thing - I have a script that does that, except that it doesn't calculate months correctly for some reason. That's why I chose this route... and this one DOES work perfectly, like I said, but I can't get it to work as a function. I thought I had it right before, but when I do things like @timediff(%db(@database, item), %time("yyyy,mm,dd,hh,nn,ss")), it returns something about 'day' or 'month' not being a valid field. *sigh*

Charneus
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sat Jan 24, 2009 10:40 pm   
 
Ok, so this timeDiff() function works entirely correctly in CMUD - the example prints

min 0
day 28
month 10
sec 0
hour 23
year 0

just like you'd expect. The only problem is getting the return from Lua back into zScript. There're a couple of ways of going about this depending on how exactly you want it to be printed - but the main mechanic you're going to be using is the simple lua "return" keyword, which will return a value in Lua back into zScript. Try this:

Code:
<func name="hax" language="Lua" id="1">
  <value>return "lol"</value>
</func>


And then running "#say @hax()" on the command line to see what I mean - the return value is returned from the function just fine. So all you need to do is format the table that timeDiff is returning in some pretty way and then use the return keyword to return it. Perhaps:

local finalstring = ""
for i,v in pairs(td) do finalstring = finalstring .. i .. " " .. v .. " " end
return finalstring

This code will return the string "min 0 day 28 month 10 sec 0 hour 23 year 0 " - you can optionally trim the final space off if you like. Once you've got the right format, you can just do:

guildchat Time Difference: @TimeDifference(balghag)

and presto.

Finally, here is what I did on the command line to mke sure that the above example was correct:

Code:
local timeDiff = function(t2,t1)
   local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
   local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
   d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
   for i,v in ipairs({'sec','min','hour','day','month','year'}) do
      diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
      carry = diff[v] < 0
      if carry then diff[v] = diff[v] + colMax[i] end
   end
   return diff
end
local td=timeDiff(os.time{year=2007,month=10,day=5,hour=10,min=10,sec=5},os.time{year=2006,month=11,day=6,hour=10,min=10,sec=5})
print(td)
local finalstring = ""
for k,v in pairs(td) do finalstring = finalstring .. k .. " " .. v .. " " end
print(finalstring)


Hope this helps.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: Sat Jan 24, 2009 10:50 pm   
 
Not sure what you had trouble with but I was able to fairly easily convert you alias to a function. I did remove the local and make it a global function that I put in an onLoad event. If you going keep calling it, you don't want it being defined each time. I also made sure you don't print when the time unit is 0.

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <event event="onLoad" priority="60" copy="yes">
    <value>function timeDiff(t2,t1)
   local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
   local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
   d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
   for i,v in ipairs({'sec','min','hour','day','month','year'}) do
      diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
      carry = diff[v] < 0
      if carry then diff[v] = diff[v] + colMax[i] end
   end
   return diff
end
</value>
  </event>
  <func name="deltaDate" copy="yes">
    <value>local td=timeDiff(os.time{year=zs.param(1),month=zs.param(2),day=zs.param(3),hour=zs.param(4),min=zs.param(5),sec=zs.param(6)},os.time{year=zs.param(7),month=zs.param(8),day=zs.param(9),hour=zs.param(10),min=zs.param(11),sec=zs.param(12)})

local result = td.year .. "yrs " .. td.month .. "mos " .. td.day .. "dys " .. td.hour .. "hrs " .. td.min .. "mns " .. td.sec .. "scs"

return string.gsub(result, " 0..." , "" ,6)</value>
    <arglist>$year,$mon,$day,$hour,$min,$sec,$year1,$mon1,$day1,$hour1,$min1,$sec1</arglist>
  </func>
</cmud>


I called it like this
Code:
gt @deltaDate(2009,1,13,12,00,00,2002,1,1,2,03,10)


[Edit] Ninjaed by Fang. Doh!!!
_________________
Asati di tempari!
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Sun Jan 25, 2009 1:10 am   
 
Hmm... I tried Tech's with what I had intentions of doing, and it comes up with this:

Using:

#SAY @luatime(%time("yyyy,mm,dd,hh,nn,ss"),%db(@timestats, starttime))

returns:

'field 'year' missing in date table (line 1)'

Same thing returns for:

#say @luatime(%time(yyyy),%time(mm),%time(dd),%time(hh),%time(nn),%time(ss),%db(@afkstats,starttime))

So, apparently it's not going to take a database value (value is "2009,01,23,18,06,23")...

Can anyone think of a workaround for this?

Charneus

By the way, it still prints 0yrs. Also, is there a way to make it still print hours/minutes/seconds even if they are zero? I just don't want to see 0yrs 0mos 0dys. :P


Last edited by charneus on Sun Jan 25, 2009 1:14 am; edited 1 time in total
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sun Jan 25, 2009 1:14 am   
 
Trouble is that the %db function returns a single argument, the string "2009,01,23,18,06,23". This function expects those numbers to be passed individually as separate arguments - use the %word function with the comma as a separator to get them out.

If it was me, though, I'd be using lua's time-related functions to store the start time anyway, so it'd be in the right format to pass straight to the function.

Also, as it stands this code will print numbers even if they're 0.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
chris-74269
Magician


Joined: 23 Nov 2004
Posts: 364

PostPosted: Sun Jan 25, 2009 1:44 am   
 
I use:

Code:

#lua {zs.var.currenttime=os.time(t)}


You can make an alarm to keep the currenttime updated, so do it whenever you want to call it. To get a time difference, just have the new event set #lua {zs.var.blahblahtime=os.time(t)} Then just do a @currenttime-@blahblahtime to get the number of seconds between, unless you are wanting to know the months/ect b/t the dates and I'm misreading this works.
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Sun Jan 25, 2009 2:21 am   
 
Chris, you are misreading it, because I want the years/months/days/hours/minutes/seconds. :P

Fang, I'll do the %word and get back to you on this. Thanks for that suggestion. I didn't even think of it.

Charneus
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Sun Jan 25, 2009 2:52 am   
 
Heh. So I guess it's going to get really messy whenever I want to do time differences in my scripts...

I say that because I now have to do:

Code:
%time("yyyy"),%time("mm"),%time("dd"),%time("hh"),%time("nn"),%time("ss"),%word(%db(@timestats, starttime),1,","),%word(%db(@timestats, starttime),2,","),%word(%db(@timestats, starttime),3,","),%word(%db(@timestats, starttime),4,","),%word(%db(@timestats, starttime),5,","),%word(%db(@timestats, starttime),6,",")


I tried doing this in a function as well:

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <func name="timedb" copy="yes">
    <value>#RETURN %concat(%time("yyyy"),",",%time("mm"),",",%time("dd"),",",%time("hh"),",",%time("nn"),",",%time("ss"),",",%word(%1,1,","),",",%word(%1,2,","),",",%word(%1,3,","),",",%word(%1,4,","),",",%word(%1,5,","),",",%word(%1,6,","))</value>
  </func>
</cmud>


But even that didn't work when I did @luatime(@timedb(%db(@timestats,starttime)), that didn't work. Even removed the concat and tried it returning the value alone. Nothing. *sigh* Unless I'm missing something here. %word(%db(@timestats,starttime)) didn't work, either.

Charneus
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: Sun Jan 25, 2009 8:04 am   
 
Ok.. you didn't mention how you wanted to used it. Try this code.

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <event event="onLoad" priority="20" copy="yes">
    <value>function timeDiff(t2,t1)
   local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
   local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
   d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
   for i,v in ipairs({'sec','min','hour','day','month','year'}) do
      diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
      carry = diff[v] < 0
      if carry then diff[v] = diff[v] + colMax[i] end
   end
   return diff
end

function buildTable(timeStr)

  tt = {
    year = tonumber(string.sub( timeStr, string.find(timeStr,"%d+")) ),
    month = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",5) )),
    day = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",8 ))),
    hour = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",11) )),
    min = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",14) )),
    sec = tonumber(string.sub( timeStr, string.find(timeStr,"%d+",17) ))
  }
   
  return tt

end</value>
  </event>
  <func name="deltaDate" copy="yes">
    <value>
t1 = os.time(buildTable(zs.param(1)))
t2= os.time(buildTable(zs.param(2)))
td=timeDiff(t1,t2)

local result = td.year .. "yrs " .. td.month .. "mos " .. td.day .. "dys " .. td.hour .. "hrs " .. td.min .. "mns " .. td.sec .. "scs"

return string.gsub(result, "0... ?" , "" ,6)</value>
    <arglist>$time1,$time2</arglist>
  </func>
  <var name="timestats" type="Record" copy="yes">starttime=2009,01,23,18,06,23</var>
</cmud>



I used the following to run it.

Code:
#SAY @deltaDate(%time("yyyy,mm,dd,hh,nn,ss"),%db(@timestats, starttime))
_________________
Asati di tempari!
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Sun Jan 25, 2009 8:53 am   
 
That did it. Thanks a lot, Tech (and Fang, who provided it in the first place!)

I'm still learning lua, so hopefully I'll get much better at it in the future.

Charneus
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Sun Jan 25, 2009 10:01 am   
 
charneus wrote:
Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <func name="timedb" copy="yes">
    <value>#RETURN %concat(%time("yyyy"),",",%time("mm"),",",%time("dd"),",",%time("hh"),",",%time("nn"),",",%time("ss"),",",%word(%1,1,","),",",%word(%1,2,","),",",%word(%1,3,","),",",%word(%1,4,","),",",%word(%1,5,","),",",%word(%1,6,","))</value>
  </func>
</cmud>
But even that didn't work

Just for future reference, the reason for this is because Lua is still expecting multiple arguments, whereas this function returns a single argument, a string. You need to be very careful using comma-separated lists like this to remember what counts as a single argument (the whole string) and what doesn't. The commas need to be outside the string, in the code, for this to work, and zScript doesn't support that syntax.

In lua it'd be easy because you could just have multiple returns:

Code:
func timedb () return zs.time("yyyy"), zs.time("mm"), zs.time("dd") ... etc etc ... zs.time("ss") end


And, because Lua is smart, it'll then understand that each return from that function is a separate argument to whatever it's passed to.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Mon Jan 26, 2009 2:02 am   
 
Ok... this is starting to get annoying. Here's the script I've been setting up with this time difference script. I'm going to add many more, but only if I can solve this problem first.

Code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<cmud>
  <class name="AwayScript" copy="yes">
    <class name="AFKAliases" copy="yes">
      <alias name="away" parsearg="false" copy="yes">
        <value>#IF (%null( %-1) AND @away=1) {
;    #SEND "gt :@Chas just returned from "%concat( "@B<(@W=@Y", %db(@afkstats,afkmsg), "@W=@B)>@C")", gone for "@luatime(%time("yyyy,mm,dd,hh,nn,ss"),%db(@afkstats,afkstarttime))
  away=0
  catchtells
  #T- "AFKTriggers"
  } {
  away=1
  #ADDKEY afkstats afkmsg %-1
;  #SEND "gt :@Cis away. Reason: @B<(@W=@Y"%-1"@W=@B)>@C"
  #T+ "AFKTriggers"
  catchtells
  #ADDKEY afkstats afkstarttime %time( "yyyy,mm,dd,hh,nn,ss")
  }</value>
      </alias>
    </class>
    <class name="AFKTriggers" copy="yes">
      <trigger priority="43130" copy="yes">
        <pattern>^(%w) just sent you a tell.$</pattern>
        <value>#IF (%1!=%db( @afkstats, lastreply)) {
  #SEND "reply @CHi, "%1"! Sorry, but Charneus is not here right now. Reason: @B<(@W=@Y"%db( @afkstats, afkmsg)"@W=@B)>@C. He's been gone for "@luatime(%time("yyyy,mm,dd,hh,nn,ss"), %db(@afkstats, afkstarttime))"."
  #ADDKEY afkstats lastreply %1
  }</value>
      </trigger>
    </class>
    <class name="AFKVariables" copy="yes">
      <var name="away" copy="yes">1</var>
      <var name="afkstats" type="Record" copy="yes">lastreply|afkmsg=Gone for a bit.|afkstarttime=2009,01,25,19,49,40|away=0</var>
    </class>
  </class>
</cmud>


The @luatime and onLoad are in different folders. The problem that I'm getting now is this:

Code:
[string "code"](17) bad argument #2 to 'sub' (number expected, got nil).


Not sure what is going on... I do:

#SAY @luatime(%time("yyyy,mm,dd,hh,nn,ss"),%db(@afkstats, afkstarttime))

and it works perfectly. I can even put phrases around it and it works perfectly. However, in the script itself, it fails to work perfectly. Now, looking over something, I found that if I take out the quotes in %time("blahblahb") and enter it on the command line, it comes back as the same error. Looking at compiled code for the trigger, it's returning %time as literal.

Code:
0000   PUSHEXP   0016
0008   JUMP   0100
0016   PARAMREF   1
0024   VARREF   @afkstats <afkstats>   (class Aardwolf)   
0052   STR   'lastreply'
0072   FUNCREF   db   (2)
0084   NEQ   
0088   SETEXP   0   0
0100   PUSHLOC   0116
0108   JUMP   0544
0116   LITERAL   "reply @CHi, "
0136   PARAMREF   1
0144   CONCAT   
0148   LITERAL   "! Sorry, but Charneus is not here right now. Reason: @B<(@W=@Y"
0220   CONCAT   
0224   VARREF   @afkstats <afkstats>   (class Aardwolf)   
0252   STR   'afkmsg'
0268   FUNCREF   db   (2)
0280   CONCAT   
0284   LITERAL   "@W=@B)>@C. He's been gone for "
0324   CONCAT   
0328   LITERAL   "yyyy,mm,dd,hh,nn,ss"
0356   FUNCREF   time   (1)
0368   VARREF   @afkstats <afkstats>   (class Aardwolf)   
0396   STR   'afkstarttime'
0416   FUNCREF   db   (2)
0428   USERFUNC   @luatime (2) <luatime>   (class Aardwolf)   
0456   CONCAT   
0460   LITERAL   "."
0472   CONCAT   
0476   CMD   send   (1)
0488   STR   'afkstats'
0504   STR   'lastreply'
0524   PARAMREF   1
0532   CMD   addkey   (3)
0544   CMD   if   (2)


Not sure if that's relevant or not, but it's the only thing I can think of...

Charneus
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Mon Jan 26, 2009 9:49 pm   
 
Now it's doing it on the command line, too... keeps saying the same thing. Not sure what is going on...

Charneus
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Thu Jan 29, 2009 5:06 pm   
 
No one has a clue/answer? Or did everyone just assume the whole thing was fixed? :P

Still looking for help. It'd be much appreciated. Nothing changed except for the fact it doesn't work now.

Charneus
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Thu Jan 29, 2009 6:58 pm   
 
Well, if this is what you're trying to do with this, then I'd make the entire thing from lua - you can store the time you left (as returned by os.time(), the format that the function expects) in a CMUD variable if you want it to be saved across sessions - that complicates things inasmuch as you'd need to use zs.var.somevar = os.time() rather than somevar = os.time(), but it's not too much hassle.

Since the time would already be in the right format that way, you don't need to do anything except pass off the time to the function. Your alias would look something like this:

Code:
if zs.params() and afk then
  local timegone = timeDiff(os.time(),afk.start)
  zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. timegone.year .. "years, " .. timegone.day .. "days, etc etc")
  afk=nil
  zs.send("catchtells")
  zs["t-"]("AFKTriggers")
else
  afk = { msg = zs.params(), start = os.time() }
  zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
  zs["t+"]("AFKTriggers")
  zs.send("catchtells")
end


This script requires the original, unchanged timeDiff function from the first post. I've tested it and it works fine. If you want your afk status to be stored over sessions, just change all references to afk to zs.var.varofyourchoice. Hopefully this is enough to show you how to change the trigger to use the Lua table as well.

Finally, here is the exact alias I used to test this, 100% working:

Code:
<alias name="afk" language="Lua" id="1">
  <value><![CDATA[if not timeDiff then
  timeDiff = function(t2,t1)
    local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
    local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
    d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
    for i,v in ipairs({'sec','min','hour','day','month','year'}) do
      diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
      carry = diff[v] < 0
      if carry then diff[v] = diff[v] + colMax[i] end
    end
    return diff
  end
end
if zs.params() and afk then
  local timegone = timeDiff(os.time(),afk.start)
  zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. timegone.year .. "years, " .. timegone.day .. "days, etc etc")
  afk=nil
  zs.send("catchtells")
  zs["t-"]("AFKTriggers")
else
  afk = { msg = zs.params(), start = os.time() }
  zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
  zs["t+"]("AFKTriggers")
  zs.send("catchtells")
end]]></value>
</alias>
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)

Last edited by Fang Xianfu on Thu Jan 29, 2009 7:07 pm; edited 3 times in total
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Thu Jan 29, 2009 7:01 pm   
 
Oh, and one final thing - you might want to change the logic to include what to do if you type "afk" on its own while you're not afk already. At the moment it'll just put a nil value into afk.msg - you probably want to have some kind of "no message specified" message in that case. The logic tree then, I think, would be:

Code:
if zs.params() == "" and afk then
  first part of existing code
else
  local msg = zs.params() == "" and "no reason given" or zs.params()
  afk = {msg = msg, start = os.time() }
  rest of existing code
end
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)

Last edited by Fang Xianfu on Thu Jan 29, 2009 10:03 pm; edited 3 times in total
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Thu Jan 29, 2009 7:12 pm   
 
Okay, now I'm confused. I can't tell if the first line should be if zs.params() and afk then or if not zs.params() and afk then - neither seems to work how I'd expect.

EDIT: Okay, I realised what it is - zs.params() doesn't return false if it's empty, it returns a null string, which isn't false in Lua. The first line should be if zs.params() == "" and afk then. Here is the corrected alias:

Code:
<alias name="afk" language="Lua" id="1">
  <value><![CDATA[if not timeDiff then
  timeDiff = function(t2,t1)
    local d1,d2,carry,diff = os.date('*t',t1),os.date('*t',t2),false,{}
    local colMax = {60,60,24,os.date('*t',os.time{year=d1.year,month=d1.month+1,day=0}).day,12}
    d2.hour = d2.hour - (d2.isdst and 1 or 0) + (d1.isdst and 1 or 0) -- handle dst
    for i,v in ipairs({'sec','min','hour','day','month','year'}) do
      diff[v] = d2[v] - d1[v] + (carry and -1 or 0)
      carry = diff[v] < 0
      if carry then diff[v] = diff[v] + colMax[i] end
    end
    return diff
  end
end
if zs.params() == "" and afk then
  local timegone = timeDiff(os.time(),afk.start)
  zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. timegone.year .. "years, " .. timegone.day .. "days, etc etc")
  afk=nil
  zs.send("catchtells")
  zs["t-"]("AFKTriggers")
else
  afk = { msg = zs.params(), start = os.time() }
  zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
  zs["t+"]("AFKTriggers")
  zs.send("catchtells")
end]]></value>
</alias>
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Fri Jan 30, 2009 2:22 am   
 
Fang Xianfu wrote:
Oh, and one final thing - you might want to change the logic to include what to do if you type "afk" on its own while you're not afk already. At the moment it'll just put a nil value into afk.msg - you probably want to have some kind of "no message specified" message in that case. The logic tree then, I think, would be:

Code:
if zs.params() == "" and afk then
  first part of existing code
else
  local msg = zs.params() == "" and "no reason given" or zs.params()
  afk = {msg = msg, start = os.time() }
  rest of existing code
end


Awesome. Thanks for the fix on it. My question is, though, will the variables be saved if, for instance, CMUD shut down, or my computer crashed? Like I said, I'm still learning Lua, and don't know if CMUD stores it internally or if it's wiped away after the program closes. If not, then I'll have to go the zs.var route.

The reason I'm quoting this particular part of your posts is because it doesn't appear to be working. Either that, or I'm missing something. I have it set up like this now:

Code:
if zs.params() == "" and afk then
  local timegone = timeDiff(os.time(),afk.start)
  local result = timegone.year .. "y " .. timegone.month .. "m " .. timegone.day .. "d " .. timegone.hour .. "h " .. timegone.min .. "m " .. timegone.sec .. "s"
  zs.send("gt :@Chas just returned from @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C gone for " .. string.gsub(result, "0. ?" , "" ,6) .. ".")
  afk=nil
  zs.send("catchtells")
  zs["t-"]("AFKTriggers")
else
  local msg = zs.params() == "" and "No reason given." or zs.params()
  afk = {msg = msg, start = os.time() }
  afk = { msg = zs.params(), start = os.time() }
  zs.send("gt :@Cis away. Reason: @B<(@W=@Y" .. afk.msg .. "@W=@B)>@C")
  zs["t+"]("AFKTriggers")
  zs.send("catchtells")
end


which mimics the way you said to put it so it'd return 'No reason given' but it doesn't. It just returns:

Charneus is away. Reason: <(==)>.

Any idea on that? Oh, and as you may have noticed, I took Tech's return result and fixed it so that it returns only the populated values. Of course, I still want to do a return where it'll always show minutes and seconds, but only hours/days/months/years if populated. Guess I'll have to do several if/thens unless someone else has a better idea on it.

Charneus
Reply with quote
charneus
Wizard


Joined: 19 Jun 2005
Posts: 1876
Location: California

PostPosted: Fri Jan 30, 2009 2:34 am   
 
As an addition:

I still need to work on the trigger aspect. Not exactly sure how I'm going to go about doing that, though. I suppose I can learn a bit about Lua. It's probably simple enough anyway. I think the trigger itself is why I wanted it to be a function this entire time, too. That way, I don't have to have globs of the same code in every section that utilizes the time difference.

Charneus
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Fri Jan 30, 2009 3:23 am   
 
You've duplicated the line that defines the afk table - remove the second line trying to do that (line 11) and it should work properly.

Incidentally, I hope that you get that the "x and y or z" syntax is sort of like the %if function - it's an inline if command. If x is true it returns y, else z. You can read about why that's the case in programming in lua, or just accept that it is :P
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Fri Jan 30, 2009 3:57 am   
 
And okay, for the trigger, hmm. You're probably going to want to add some code to the timeDiff function like I used in my first post in this thread to make the output from timeDiff a bit prettier. That way you don't have to muck about with all the formatting gubbins in your trigger.

However, it's essentially copying the zs.send("gt... blahblah") line from the alias with some different text around it. afk.msg has the afk reason. You can use something like afk.lastreply to store the name of the person who spoke to you - you might find it worthwhile to store the time they last replied to you and - making handy use of your nice new timeDiff function :P - reply anyway if they last spoke to you a long time ago.

You may want to keep timeDiff as it is and make a new timePretty function that'll take a time table like timeDiff (and also os.date) returns and return a nice string as a result. That way you can use timeDiff for situations where you're not displaying the time, and timePretty for the times when you do. It'd be a good place to keep your code for removing empty ones, too. Something like:

Code:
function timePretty (timetable)
local finalstring
for k,v in timetable do
  if v>0 then finalstring = finalstring .. v .. k .. " "
end
return finalstring or "unknown"

Not tested, but that's what I mean - just a function that'll take the table and make it look nice. Then you can use timePretty in your alias and trigger, and timeDiff itself in actual comparisons of the time.

So yeah, you'll end up just needing something like

Code:
if afk.lastreply ~= zs.param(1) then
  zs.send("reply I'm away right know. Reason: " .. afk.msg .. " Away for: " .. timePretty(timeDiff(afk.start,os.time())))
  afk.lastreply = zs.param(1)
end


The more complex one I was thinking about would look like:

Code:
if (afk.lastreply ~= zs.param(1)) or (os.time()-afk.lastreplytime > 600) then
  zs.send("reply I'm away right know. Reason: " .. afk.msg .. " Away for: " .. timePretty(timeDiff(afk.start,os.time())))
  afk.lastreply = zs.param(1)
  afk.lastreplytime = os.time()
end
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Arde
Enchanter


Joined: 09 Sep 2007
Posts: 605

PostPosted: Fri Jan 30, 2009 6:00 am   
 
charneus wrote:
will the variables be saved if, for instance, CMUD shut down, or my computer crashed?

No, they will not.
Reply with quote
Fang Xianfu
GURU


Joined: 26 Jan 2004
Posts: 5155
Location: United Kingdom

PostPosted: Fri Jan 30, 2009 1:10 pm   
 
Arde is correct in this case, but I don't think it matters - because you'll need to restart CMUD manually, and for you to do that, you need to not be AFK any more.
_________________
Rorso's syntax colouriser.

- Happy bunny is happy! (1/25)
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net