celeron/devlin's auxbox thread, split from server api thread

Moderator: EUO Moderators

Post Reply
Celerion
LAUGHING OUT LOUD LIKE A MORON
Posts: 64
Joined: Sat Dec 15, 2012 6:29 am

celeron/devlin's auxbox thread, split from server api thread

Post by Celerion » Sat Nov 23, 2013 3:07 am

Hi,

I just cleaned up the Lua-script "auxbox.lua" with texts for the message-box a bit (indentation and whitespace were rather messy). The script used to be in a subdirectory "clientscripts" (which doesn't seem to exist in the recent client-distribution any more, but could still be created again by hand). The script shows real-life-time and session-time in the message-box at the moment (this is my config, stats for damage per second would also be possible):

Code: Select all

filterTextLines = [[Hit the following keys
to filter item types:

w: weapons
W: wearables
p: potions
s: shields
u: usable
j: jewellry
f: food
U: unidentified
h: slot-head
t: slot-torso
l: slot-legs
b: slot-boots
g: slot-gloves
r: slot-rings
n: slot-neck
S: spells & scrolls
G: gems
R: reagants, etc
A: cancel filtering
v: cancel filtering]]

auxbox_next_line = 0
session_time = 0
sessionstart = os.time()

shiftkeys = {"Shift", "Alt", "Ctrl+Shift", "Shift+Alt",
             "Ctrl+Alt", "Ctrl+Alt+Shift"} 

function auxbox()
   
    local w = d:auxbox_get_width()
    local h = d:auxbox_get_height()
 
    d:auxbox_clear()
    auxbox_next_line = 0 
    if not d:ok_to_draw_play_window() then
        return
    end
      
    local cd = d:get_curr_display()
    local mode = d:get_statbox_mode()
    local lineNr = 0
    local txta = explode("\n", filterTextLines)

    if cd == 1 then
  
        if mode == SELECT_ABILITY then
            auxbox_prop_line("Hit F-key to bind currently")
            auxbox_prop_line("selected spell")
            auxbox_blank_line()
            auxbox_ability_binds()
        else
            for i = 1, #txta do
                auxbox_prop_line(txta[i])
            end
            auxbox_blank_line()
            auxbox_prop_line("Search with /")
            if mode == SELECT_READY then
                auxbox_prop_line("Press ENTER to equip")
            elseif mode == SELECT_BUY then  		
                auxbox_prop_line("Press ENTER to buy")
            elseif mode == SELECT_BANK then
                auxbox_prop_line("Press ENTER to transfer one")
                auxbox_prop_line("Press Shift+ENTER for 10")
                auxbox_prop_line("Press TAB for whole stack")
            end
        end
    else
        auxbox_time()	
        auxbox_blank_line()
        -- auxbox_damage_per_second()
        -- auxbox_blank_line()
        -- auxbox_prop_line("Forums: forums.swut.net")
        -- auxbox_prop_line("Manual: euotopia.com/manual")
        if d:numlock() then
            auxbox_blank_line()
            auxbox_prop_line("Please turn numlock off!")
        end
        -- auxbox_prop_line("F12 for main menu.")
        -- auxbox_blank_line()
        -- auxbox_f5_message()			  		 
    end
end

-- explode(seperator, string)
-- from http://lua-users.org/wiki/SplitJoin

function explode(d, p)
    local t, ll
    t = {}
    ll = 0
    if (#p == 1) then
        return p
    end
    while true do
        l = string.find(p, d, ll+1, true)
        if l ~= nil then
            table.insert(t, string.sub(p, ll, l-1))
            ll = l + 1
        else
            table.insert(t, string.sub(p, ll))
            break
        end
    end
    return t
end

-- Real World Time - Duncan (PD) / Zen (Reg) / Brentoboy (forums)
function auxbox_time()
    auxbox_prop_line("Real World Time:", string.format(os.date("%I:%M%p")))
    if os.difftime(os.time(), sessionstart) > session_time then 
        session_time = os.difftime(os.time(), sessionstart)
        session_d_float = session_time / 60 / 60 / 24
        session_d = math.floor(session_d_float)
        session_h = math.floor((session_d_float - session_d) * 24)
        session_m = math.floor(((session_d_float - session_d) * 24 - session_h) * 60)
        session_s = math.floor((((session_d_float - session_d) * 24 - session_h) * 60 - session_m) * 60)
    end    
  
    if session_d ~= nil then
        auxbox_prop_line("Session time:", string.format("%02.f:%02.f:%02.f:%02.f", session_d, session_h, session_m, session_s))	
    end 
end

function auxbox_f5_message()
    auxbox_prop_line("Press Alt-F5 to Reset", "")
end

function auxbox_prop_line(prop_name, prop_val)
    local pvl = 0
    if prop_name == nil then prop_name = "" end
    if prop_val == nil then prop_val = "" end
    local filler = string.rep(" ", 25 - string.len(prop_name) - string.len(prop_val))
    auxbox_next_line = auxbox_next_line + 1
    d:auxbox_set_line(auxbox_next_line, string.format("%s %s %s", prop_name, filler, prop_val))
end

function auxbox_blank_line()
    auxbox_next_line = auxbox_next_line + 1
end

--- Damage Per Second -- original script proveded by LordMortiferus
last_session_seconds = 0
last_4_dpst = {g_dpst, g_dpst, g_dpst, g_dpst}
last_4_dtpst = {g_dtpst, g_dtpst, g_dtpst, g_dtpst}
last_dpst = g_dpst
recent_dmg = {0, 0, 0, 0}

function auxbox_damage_per_second() 
    local session_seconds = os.time() - sessionstart
	
    if session_seconds > last_session_seconds then
        last_session_seconds = session_seconds
        last_4_dpst[4] = last_4_dpst[3] 
        last_4_dpst[3] = last_4_dpst[2] 
        last_4_dpst[2] = last_4_dpst[1] 
        last_4_dpst[1] = g_dpst	
        last_4_dtpst[4] = last_4_dtpst[3] 
        last_4_dtpst[3] = last_4_dtpst[2] 
        last_4_dtpst[2] = last_4_dtpst[1] 
        last_4_dtpst[1] = g_dtpst	
    end
	
    if last_dpst ~= g_dpst then
        recent_dmg[4] = recent_dmg[3]
        recent_dmg[3] = recent_dmg[2]
        recent_dmg[2] = recent_dmg[1]
        recent_dmg[1] = g_dpst - last_dpst
        last_dpst = g_dpst
    end
	
    auxbox_prop_line("Dmg Dealt / Sec", string.format("%d", (last_4_dpst[1] - last_4_dpst[4])  / 4))
    auxbox_prop_line("Dmg Taken / Sec", string.format("%d", (last_4_dtpst[1] - last_4_dtpst[4])  / 4))
    auxbox_prop_line("Recent Dmg Dealt", "")
    auxbox_prop_line("", string.format("%d  %d  %d  %d", recent_dmg[4], recent_dmg[3], recent_dmg[2], recent_dmg[1]))
end
I wonder, what other game-extensions would be possible with Lua. The manual mostly talks about monster-behaviour in MapEd. But I'm no good at MapEd to be honest. ;)

Celerion
LAUGHING OUT LOUD LIKE A MORON
Posts: 64
Joined: Sat Dec 15, 2012 6:29 am

Re: the scripting thread

Post by Celerion » Mon Mar 03, 2014 3:24 am

Hi, in game someone said, it would be nice to have the remaining time of 2xXP-weekend in the auxbox.
With Lua, messages can be posted easily to the box.
Would it be possible to access the server-time from Lua?
Or even better, request the remaining time of 2xXP-weekend in seconds and get 0 if it's not on?

Maybe the main-client should ask the server these things once at start-up and pass it on to Lua somehow. To avoid, that evil people write too many requests to the server from Lua ...
....

Usually I write (at least prototype) in Python (stand-alone). Here would be some functions in Python that could check, if double-XP was on and get the remaining time.
If the functions had the weekday ("SUN", "MON" ... "SAT") and the day of the month (1, 2 ... 28, 29, 30, 31):

Code: Select all

#!/usr/bin/env python
# coding: iso-8859-1

def isDoubleXp(weekday, dayofmonth):
    if weekday == "SAT" and dayofmonth < 8:
        return 1
    if weekday == "SUN" and dayofmonth <= 8 and dayofmonth >= 2:
        return 1
    return 0

def secondsToDaytime(secs):
    a = []
    a.append(int(secs / 3600.))
    rest = secs - a[0] * 3600.
    a.append(int(rest / 60.))
    rest -= a[1] * 60.
    a.append(int(rest))
    for i in range(len(a)):
        if a[i] < 10:
            a[i] = "0" + str(a[i])
        else:
            a[i] = str(a[i])
    return ":".join(a)

def DaytimeToSeconds(daytime):
    a = daytime.split(":")
    for i in range(len(a)):
        a[i] = int(a[i])
    seconds = a[0] * 3600 + a[1] * 60
    if len(a) == 3:
        seconds += a[2]
    return seconds

def getRemainingSeconds(weekday, daytime):
    oneday = 86400
    twodays = 172800 
    elapsed_time = DaytimeToSeconds(daytime)
    if weekday == "SUN":
        elapsed_time += oneday
    return twodays - elapsed_time

print isDoubleXp("SAT", 7)
print isDoubleXp("MON", 7)
print isDoubleXp("SAT", 8)
print isDoubleXp("SUN", 8)
print isDoubleXp("SUN", 9)
print

sec = getRemainingSeconds("SUN", "17:00")
print sec
print secondsToDaytime(sec)

sec = getRemainingSeconds("SAT", "9:25")
print sec
print secondsToDaytime(sec)
I could probably translate this to Lua somehow; then I just needed the server-time (as a date-string) at login-time (provided by the client (!), see above), then I could post the result in the auxbox. ;)

Celerion
LAUGHING OUT LOUD LIKE A MORON
Posts: 64
Joined: Sat Dec 15, 2012 6:29 am

Re: the scripting thread

Post by Celerion » Sat Mar 08, 2014 4:40 am

Completely rewrote the script "auxbox.lua", that should be copied into a directory "clientscripts" in the EUO-directory (so it should be usually "C:\Program Files\euo\clientscripts\auxbox.lua").
You can configure, what's shown, with options at the beginning of the script. This should make it easier for users to activate "Damage Per Second" for example.

Edit: The script has been updated. Please see below.
Last edited by Celerion on Fri Oct 31, 2014 3:01 am, edited 4 times in total.

User avatar
LordMortiferus
MACRO > me
Posts: 850
Joined: Tue Dec 01, 2009 10:23 pm

Re: the scripting thread

Post by LordMortiferus » Sat Mar 08, 2014 5:31 am

Cel you should check out this script by ched - With it you add and remove scripts to the auxbox in game.

Celerion
LAUGHING OUT LOUD LIKE A MORON
Posts: 64
Joined: Sat Dec 15, 2012 6:29 am

Re: the scripting thread

Post by Celerion » Sat Mar 08, 2014 7:08 pm

LordMortiferus wrote:Cel you should check out this script by ched - With it you add and remove scripts to the auxbox in game.
Dang!

On the other hand: Shouldn't this registering-system have gone into the main-distribution, where I probably could have seen it?

Well, to me, the auxbox isn't that interesting after all. It was just a way to learn Lua and interaction with the client. It would be much more interesting to code map-extensions and monster behaviour. When one day an offline-server is released, I may be ready. (At the moment, without the possibility to test anything, it doesn't make much sense to me. I know Mort, you would be willing to help with testing, but this kind of development is a long process, where I need feedback like error-messages all the time. It wouldn't be practical to write you hundreds of Emails about it.)

User avatar
LordMortiferus
MACRO > me
Posts: 850
Joined: Tue Dec 01, 2009 10:23 pm

Re: the scripting thread

Post by LordMortiferus » Sat Mar 08, 2014 8:15 pm

Celerion wrote: I know Mort, you would be willing to help with testing, but this kind of development is a long process, where I need feedback like error-messages all the time. It wouldn't be practical to write you hundreds of Emails about it.)
Totally know what you mean - debugging can be a pain, especially when you try new stuff and want to test it part by part with live feedback. Anyway, good job on the auxbox script! I'll gonna check out the lua page about classes.

Celerion
LAUGHING OUT LOUD LIKE A MORON
Posts: 64
Joined: Sat Dec 15, 2012 6:29 am

Re: the scripting thread

Post by Celerion » Fri May 02, 2014 12:48 am

Here's a Lua-mystery: In my auxbox-script above I use UTC-time, then add 10 hours to get sydney-time (without daylight saving time) like it's shown here.

Strange thing is, when I add for example 3600 seconds to UTC-time and convert to a timetable, two hours are added, not just one. Example (with print, not auxbox):

Code: Select all

#!/usr/bin/lua

-- Get UTC-timetable:
utc = os.date("!*t")
print(string.format("%s:%s", utc.hour, utc.min))

-- Convert to seconds since epoch (1/1/1970):
utcs = os.time(utc)
-- Add one hour:
dsec = utcs + 3600

-- Convert to timetable:
d = os.date("*t", dsec)
print(string.format("%s:%s", d.hour, d.min))

-- Result: Two hours difference. Why not just one???
Output is:

Code: Select all

14:47
16:47
but should be 15:47. Why is that?

(In Python, I'd have control, if things are converted to GM-time or local-time:

Code: Select all

#!/usr/bin/python
# coding: iso-8859-1

import time
import calendar

# Get UTC-Timetuple:
gm = time.gmtime()
print "%s:%s" % (gm[3], gm[4])
# Convert to seconds since epoch:
gms = calendar.timegm(gm)
# Add one hour:
d = gms + 3600
# Convert either to local time-tuple or UTC-timetuple:
dslocal = time.localtime(d)
dsgm = time.gmtime(d)
print "Local: %s:%s" % (dslocal[3], dslocal[4])
print "UTC: %s:%s" % (dsgm[3], dsgm[4])
so no problem there, just in Lua.)
---
Edit 05/05/14: Found some discussions about it here and here.
For my script, I took the code from the function "get_timezone()" here. os.difftime() is probably not what I want, because there are timezones UTC+X (like Sydney) and timezones UTC-X (like New York for example).
I applied this hack to my seconds:

Code: Select all

seconds = seconds - (os.time() - os.time(os.date("!*t")))
So in fact, I don't calculate the seconds since epoch for Sydney, but the number of seconds that os.date() will hopefully convert to Sydney-time.

Celerion
LAUGHING OUT LOUD LIKE A MORON
Posts: 64
Joined: Sat Dec 15, 2012 6:29 am

Re: the scripting thread

Post by Celerion » Fri Oct 31, 2014 2:59 am

The time of the EUO-server has been changed from local Sydney-time to UTC (Coordinated Universal Time). This makes it way easier for my auxbox-script to calculate the remaining time of Double-XP and the days to Double-XP (counting down from 7). So here's the updated version. As always, it's called 'auxbox.lua' and should be copied to "C:\...\euo\clientscripts". Make sure, there's not much other stuff in that folder, i.e. it should be the only script in that folder. (Make a backup of your folder first.)

Code: Select all

-- auxbox.lua with classes, rewritten by Celerion, 10-2014.

-- Configuration: Set the options to either 'true' or 'false':

SHOW_ARRANGE_INFOS                  = true

SHOW_REALWORLD_TIME                 = true
REALWORLD_TIME_24_HOURS_FORMAT      = true
REALWORLD_TIME_WITH_SECONDS         = false

SHOW_SESSION_TIME                   = true
SESSION_TIME_WITH_DAYS              = true
SESSION_TIME_WITH_SECONDS           = false

SHOW_DOUBLE_XP_INFO                 = true
DOUBLE_XP_INFO_WITH_DAYS            = false
DOUBLE_XP_INFO_WITH_SECONDS         = true
SHOW_DAYS_TO_DOUBLE_XP              = true
SHOW_HOURS_TO_DOUBLE_XP             = true

SHOW_DAMAGE_DEALT_PER_SECOND_LINE   = true
SHOW_DAMAGE_TAKEN_PER_SECOND_LINE   = true
SHOW_RECENT_DAMAGE_DEALT_LINES      = false

SHOW_NUMLOCK_WARNING                = true
SHOW_SCRIPT_RELOAD_MESSAGE          = false
SHOW_EUO_MESSAGE                    = false


------------- End of Configuration -----------

AuxboxWriter = {}

    function AuxboxWriter:new()
        -- Some magic to setup a Lua-class here.
        -- See "http://www.lua.org/pil/16.html" for details.
        -- Or better, just don't worry about it ...
        local o = {}
        setmetatable(o, self)
        self.__index = self
        self.clock = Clock:new()
        self.auxbox_next_line = 0
        self.cd = 0
        -- The Lua-script seems to get some variables, objects
        -- and even a function from the EUO-client. I store them
        -- in the "from_EUO"-table to mark their origin:
        self.from_EUO = {}
        self.from_EUO.d = d
        self.from_EUO.SELECT_ABILITY = SELECT_ABILITY
        self.from_EUO.SELECT_READY = SELECT_READY
        self.from_EUO.SELECT_BUY = SELECT_BUY
        self.from_EUO.SELECT_BANK = SELECT_BANK
        self.from_EUO.auxbox_ability_binds = auxbox_ability_binds
        self.from_EUO.g_dpst = g_dpst
        self.from_EUO.g_dtpst = g_dtpst
        -- Data for "Damage per Second":
        self.last_session_seconds = 0
        self.last_4_dpst = {}
        for i = 1, 4 do
            table.insert(self.last_4_dpst, self.from_EUO.g_dpst)
        end
        self.last_4_dtpst = {}
        for i = 1, 4 do
            table.insert(self.last_4_dtpst, self.from_EUO.g_dtpst)
        end
        self.last_dpst = self.from_EUO.g_dpst
        self.recent_dmg = {0, 0, 0, 0}
        return o
    end

    function AuxboxWriter:auxbox_loop()
        local w = self.from_EUO.d:auxbox_get_width()
        local h = self.from_EUO.d:auxbox_get_height()
        self.from_EUO.d:auxbox_clear()
        self.auxbox_next_line = 0
        if not self.from_EUO.d:ok_to_draw_play_window() then
            return
        end
        self.cd = self.from_EUO.d:get_curr_display()
        self:show_contents()
    end

    function AuxboxWriter:auxbox_prop_line(prop_name, prop_val)
        local pvl = 0
        if prop_name == nil then prop_name = "" end
        if prop_val == nil then prop_val = "" end
        local filler = string.rep(" ", 25 - string.len(prop_name) - string.len(prop_val))
        self.auxbox_next_line = self.auxbox_next_line + 1
        self.from_EUO.d:auxbox_set_line(self.auxbox_next_line, string.format("%s %s %s", prop_name, filler, prop_val))
    end

    function AuxboxWriter:auxbox_blank_line()
        self.auxbox_next_line = self.auxbox_next_line + 1
    end

    function AuxboxWriter:show_contents()
        if self.cd == 1 then
            if SHOW_ARRANGE_INFOS == true then
                self:auxbox_arrange_info()
            end
            return
        end
        if SHOW_REALWORLD_TIME == true then self:auxbox_time() end
        if SHOW_SESSION_TIME == true then self:auxbox_session_time() end
        if SHOW_DOUBLE_XP_INFO == true then self:auxbox_double_xp_info() end
        if SHOW_DAMAGE_DEALT_PER_SECOND_LINE == true or
           SHOW_DAMAGE_TAKEN_PER_SECOND_LINE == true or
           SHOW_RECENT_DAMAGE_DEALT_LINES    == true then
            self:auxbox_damage_per_second()
        end
        if SHOW_NUMLOCK_WARNING == true then self:auxbox_numlock_warning() end
        if SHOW_SCRIPT_RELOAD_MESSAGE == true then self:auxbox_f5_message() end
        if SHOW_EUO_MESSAGE == true then self:auxbox_euo_message() end
end

    function AuxboxWriter:auxbox_session_time()
        self:auxbox_prop_line("Session time:", self.clock:get_session_time())
        self:auxbox_blank_line()
    end

    function AuxboxWriter:auxbox_time()
        self:auxbox_prop_line("Real World Time:", self.clock:get_local_time_in_configured_format())
    end

    function AuxboxWriter:auxbox_double_xp_info()
        local info = self.clock:get_double_xp_info()
        if info.days == 0 then
            self:auxbox_prop_line("Double-XP:", info.timestr)
            self:auxbox_blank_line()
            return
        end
        if SHOW_DAYS_TO_DOUBLE_XP == true then
            if info.days == 1 then
                self:auxbox_prop_line("Tomorrow's Double-XP.")
                if SHOW_HOURS_TO_DOUBLE_XP == true then
                    self:auxbox_prop_line("Hours to Double-XP:", info.timestr)
                end
                self:auxbox_blank_line()
                return
            end
            if info.days > 1 and info.days <= self.clock.days_in_advance then
                self:auxbox_prop_line(info.days .. " days until Double-XP.")
                self:auxbox_blank_line()
                return
            end
        end
   end
 
    function AuxboxWriter:auxbox_numlock_warning()
        if self.from_EUO.d:numlock() then
            self:auxbox_blank_line()
            self:auxbox_prop_line("Please turn numlock off!")
        end
    end

    function AuxboxWriter:auxbox_euo_message()
        self:auxbox_blank_line()
        self:auxbox_prop_line("Forums: forums.swut.net")
        self:auxbox_prop_line("Manual: euotopia.com/manual")
        self:auxbox_prop_line("F12 for main menu.")
        self:auxbox_blank_line()
    end

    function AuxboxWriter:auxbox_f5_message()
        self:auxbox_prop_line("Press Alt-F5 to Reset", "")
    end

    function AuxboxWriter:auxbox_damage_per_second()

        -- Damage Per Second -- original script provided by LordMortiferus
        local session_seconds = self.clock:get_session_seconds()

        self.from_EUO.g_dpst = g_dpst
        self.from_EUO.g_dtpst = g_dtpst

        if session_seconds > self.last_session_seconds then
            self.last_session_seconds = session_seconds
            self.last_4_dpst[4] = self.last_4_dpst[3]
            self.last_4_dpst[3] = self.last_4_dpst[2]
            self.last_4_dpst[2] = self.last_4_dpst[1]
            self.last_4_dpst[1] = self.from_EUO.g_dpst   
            self.last_4_dtpst[4] = self.last_4_dtpst[3]
            self.last_4_dtpst[3] = self.last_4_dtpst[2]
            self.last_4_dtpst[2] = self.last_4_dtpst[1]
            self.last_4_dtpst[1] = self.from_EUO.g_dtpst   
        end
   
        if self.last_dpst ~= self.from_EUO.g_dpst then
            self.recent_dmg[4] = self.recent_dmg[3]
            self.recent_dmg[3] = self.recent_dmg[2]
            self.recent_dmg[2] = self.recent_dmg[1]
            self.recent_dmg[1] = self.from_EUO.g_dpst - self.last_dpst
            self.last_dpst = self.from_EUO.g_dpst
        end
   
        if SHOW_DAMAGE_DEALT_PER_SECOND_LINE == true then
            self:auxbox_prop_line("Dmg Dealt / Sec", string.format("%d", (self.last_4_dpst[1] - self.last_4_dpst[4])  / 4))
        end
        if SHOW_DAMAGE_TAKEN_PER_SECOND_LINE == true then
            self:auxbox_prop_line("Dmg Taken / Sec", string.format("%d", (self.last_4_dtpst[1] - self.last_4_dtpst[4])  / 4))
        end
        if SHOW_RECENT_DAMAGE_DEALT_LINES == true then
            self:auxbox_prop_line("Recent Dmg Dealt", "")
            self:auxbox_prop_line("", string.format("%d  %d  %d  %d", self.recent_dmg[4], self.recent_dmg[3], self.recent_dmg[2], self.recent_dmg[1]))
        end
    end

    function AuxboxWriter:auxbox_arrange_info()
        local filterTextLines = [[Hit the following keys
to filter item types:

w: weapons
W: wearables
p: potions
s: shields
u: usable
j: jewellry
f: food
U: unidentified
h: slot-head
t: slot-torso
l: slot-legs
b: slot-boots
g: slot-gloves
r: slot-rings
n: slot-neck
S: spells & scrolls
G: gems
R: reagants, etc
A: cancel filtering
v: cancel filtering]]

        local mode = self.from_EUO.d:get_statbox_mode()
        local txta = self:split(filterTextLines, "\n")

        if mode == self.from_EUO.SELECT_ABILITY then
            self:auxbox_prop_line("Hit F-key to bind currently")
            self:auxbox_prop_line("selected spell")
            self:auxbox_blank_line()
            self.from_EUO.auxbox_ability_binds()
        else
            for i = 1, #txta
            do
                self:auxbox_prop_line(txta[i])
            end
            self:auxbox_blank_line()
            self:auxbox_prop_line("Search with /")
            if mode == self.from_EUO.SELECT_READY then
                self:auxbox_prop_line("Press ENTER to equip")
            elseif mode == self.from_EUO.SELECT_BUY then       
                self:auxbox_prop_line("Press ENTER to buy")
            elseif mode == self.from_EUO.SELECT_BANK then
                self:auxbox_prop_line("Press ENTER to transfer one")
                self:auxbox_prop_line("Press Shift+ENTER for 10")
                self:auxbox_prop_line("Press TAB for whole stack")
            end
        end
    end

    function AuxboxWriter:split(s, plain_sep)
        -- Celerion's split-function (split at plain separator):
        local stringtable = {}
        local start = 1
        local found = string.find(s, plain_sep, start)
        while found ~= nil do
            table.insert(stringtable, string.sub(s, start, found - 1))
            start = found + string.len(plain_sep)
            found = string.find(s, plain_sep, start)
        end
        if start <= string.len(s) then
            table.insert(stringtable, string.sub(s, start))
        end
        return stringtable
    end

-- End of Class "AuxboxWriter"


Clock = {}

    function Clock:new()
        -- The class-magic again:
        local o = {}
        setmetatable(o, self)
        self.__index = self
        self.local_seconds_at_start = os.time()
        self.session_seconds = 0
        self.days_in_advance = 7
        return o
    end

    function Clock:set_sessions_seconds()
        local diff = os.difftime(os.time(), self.local_seconds_at_start)
        if diff > self.session_seconds then
            self.session_seconds = diff
        end
    end

    function Clock:get_local_time_in_configured_format()
        local timeformat = ""
        if REALWORLD_TIME_24_HOURS_FORMAT == true then
            timeformat = "%H:%M"
        else
            timeformat = "%I:%M"
        end
        if REALWORLD_TIME_WITH_SECONDS == true then
            timeformat = timeformat .. ":%S"
        end
        if REALWORLD_TIME_24_HOURS_FORMAT ~= true then
            timeformat = timeformat .. "%p"
        end
        return os.date(timeformat)
    end

    function Clock:get_session_seconds()
        self:set_sessions_seconds()
        return self.session_seconds
    end

    function Clock:get_session_time()
        self:set_sessions_seconds()
        return self:seconds_to_time_string(self.session_seconds, SESSION_TIME_WITH_DAYS, SESSION_TIME_WITH_SECONDS)
    end

    function Clock:get_double_xp_info()
        local oneday = 86400
        local twodays = 172800
        local info = {days = -1, timestr = ""}
        local utcttable = os.date("!*t")
        local restsecs = 0

        -- For testing:
        -- utcttable.wday = 6
        -- utcttable.day = 3
        -- utcttable.hour = 0
        -- utcttable.min = 0
        -- utcttable.sec = 0

        -- Do we have Double-XP? (For wday, Saturday is 7, Sunday is 1):
        if utcttable.wday == 7 and utcttable.day < 8 or
           utcttable.wday == 1 and utcttable.day <= 8 and utcttable.day >= 2
        then
            info.days = 0
            restsecs = twodays - (utcttable.hour * 3600 + utcttable.min * 60 + utcttable.sec)
            -- Sunday - One day has already passed:
            if utcttable.wday == 1 then
                restsecs = restsecs - oneday
            end
            info.timestr = self:seconds_to_time_string(restsecs, DOUBLE_XP_INFO_WITH_DAYS, DOUBLE_XP_INFO_WITH_SECONDS)
            return info
        end

        -- Double-XP in next days?
        if SHOW_DAYS_TO_DOUBLE_XP ~= true then
            return info
        end
        local i = 1
        local secs = 0
        local utcseconds = os.time(utcttable)
        local t = {}
        while i <= self.days_in_advance do
            secs = utcseconds + oneday * i
            t = os.date("*t", secs)
            if t.wday == 7 and t.day < 8 then
                break
            end
            i = i + 1
        end
        info.days = i
        if SHOW_HOURS_TO_DOUBLE_XP ~= true then
            return info
        end
        if info.days == 1 then
            restsecs = oneday - (utcttable.hour * 3600 + utcttable.min * 60 + utcttable.sec)
            info.timestr = self:seconds_to_time_string(restsecs, false, false)
        end
        return info
    end

    function Clock:seconds_to_time_string(secs, show_days, show_secs)
        local oneday = 86400
        local onehour = 3600
        local oneminute = 60
        local rest = 0
        local tstr = ""
        local t = {}
        if show_days == true then
            t.days = math.floor(secs / oneday)
            rest = secs - t.days * oneday
            t.hours = math.floor(rest / onehour)
            rest = rest - t.hours * onehour
            tstr = string.format("%02d:%02d:", t.days, t.hours)
        else
            t.hours = math.floor(secs / onehour)
            rest = secs - t.hours * onehour
            tstr = string.format("%02d:", t.hours)
        end
        t.mins = math.floor(rest / oneminute)
        rest = rest - t.mins * oneminute
        t.secs = math.floor(rest)
        if show_secs == true then
            tstr = tstr .. string.format("%02d:%02d", t.mins, t.secs)
        else
            tstr = tstr .. string.format("%02d", t.mins)
        end
        return tstr
    end

-- End of Class "Clock"


function auxbox()
    auxboxwriter:auxbox_loop()
end

auxboxwriter = AuxboxWriter:new()

User avatar
Devlin
I used to bake rockcakes in my bakery.
Posts: 198
Joined: Tue Jan 22, 2008 12:30 pm
Location: United Kingdom
Contact:

Re: the scripting thread

Post by Devlin » Wed Feb 21, 2018 9:44 pm

Using colours in auxbox causes the right-align padding to break (i suspect because of the string length being artificially padded by the colour codes)

Image

Has anyone got a fix to take the colour codes into account and stop them being counted by the auxbox_prop_line() function?

Chedich
on lolpatrol
Posts: 253
Joined: Wed Jan 14, 2004 12:51 am

Re: the scripting thread

Post by Chedich » Sat Feb 24, 2018 5:40 am

Devlin wrote:Using colours in auxbox causes the right-align padding to break (i suspect because of the string length being artificially padded by the colour codes)

Has anyone got a fix to take the colour codes into account and stop them being counted by the auxbox_prop_line() function?
Threw this together for you. I haven't really tested it properly though, so feel free to give some feedback.

Code: Select all

function auxbox_prop_line(prop_name, prop_val)
	local pvl=0
	if prop_name==nil then prop_name="" end
	if prop_val==nil then prop_val="" end
	local filler = string.rep(" ", 25 - ched_propline_strlen(prop_name) - ched_propline_strlen(prop_val))
	auxbox_next_line = auxbox_next_line + 1
	d:auxbox_set_line(auxbox_next_line, string.format("%s %s %s", prop_name, filler, prop_val))
end

function ched_propline_strlen(prop_strlen)
	local string_length = 0
	if type(prop_strlen) == "number" then
		prop_strlen = tostring(prop_strlen)
	end
	for i=0, #prop_strlen do
		local string_byte = prop_strlen:byte(i)
		if string_byte ~= nil then
			if string_byte == 0x7B then
				string_length = string_length - 4
			else
				string_length = string_length + 1
			end
		end
	end
		
	return string_length
end

User avatar
Devlin
I used to bake rockcakes in my bakery.
Posts: 198
Joined: Tue Jan 22, 2008 12:30 pm
Location: United Kingdom
Contact:

Re: the scripting thread

Post by Devlin » Sat Feb 24, 2018 9:46 am

Chedich wrote:
Devlin wrote:Using colours in auxbox causes the right-align padding to break (i suspect because of the string length being artificially padded by the colour codes)

Has anyone got a fix to take the colour codes into account and stop them being counted by the auxbox_prop_line() function?
Threw this together for you. I haven't really tested it properly though, so feel free to give some feedback.

Code: Select all

function auxbox_prop_line(prop_name, prop_val)
	local pvl=0
	if prop_name==nil then prop_name="" end
	if prop_val==nil then prop_val="" end
	local filler = string.rep(" ", 25 - ched_propline_strlen(prop_name) - ched_propline_strlen(prop_val))
	auxbox_next_line = auxbox_next_line + 1
	d:auxbox_set_line(auxbox_next_line, string.format("%s %s %s", prop_name, filler, prop_val))
end

function ched_propline_strlen(prop_strlen)
	local string_length = 0
	if type(prop_strlen) == "number" then
		prop_strlen = tostring(prop_strlen)
	end
	for i=0, #prop_strlen do
		local string_byte = prop_strlen:byte(i)
		if string_byte ~= nil then
			if string_byte == 0x7B then
				string_length = string_length - 4
			else
				string_length = string_length + 1
			end
		end
	end
		
	return string_length
end
Looks like it's working just fine to me. Will give it something more challenging and see what happens.

Nice work getting that fixed btw. Might try and integrate it directly into auxbox_prop_line() - Not familiar with lua but now I can see how it's done I might be able to optimize it a little more.

Post Reply